@@ -258,6 +258,84 @@ describe("DXT CLI", () => {
258258 expect ( originalFile2 ) . toEqual ( unpackedFile2 ) ;
259259 } ) ;
260260
261+ it ( "should pack with --manifest pointing to a separate directory" , ( ) => {
262+ const projectDir = join ( __dirname , "temp-manifest-project" ) ;
263+ const manifestDir = join ( __dirname , "temp-manifest-separate" ) ;
264+ const manifestPackedPath = join ( __dirname , "test-manifest-flag.mcpb" ) ;
265+
266+ try {
267+ // Create project directory with source files (no manifest)
268+ fs . mkdirSync ( join ( projectDir , "server" ) , { recursive : true } ) ;
269+ fs . writeFileSync (
270+ join ( projectDir , "server" , "index.js" ) ,
271+ "console.log('hello');" ,
272+ ) ;
273+
274+ // Create separate manifest directory
275+ fs . mkdirSync ( manifestDir , { recursive : true } ) ;
276+ fs . writeFileSync (
277+ join ( manifestDir , "manifest.json" ) ,
278+ JSON . stringify ( {
279+ manifest_version : DEFAULT_MANIFEST_VERSION ,
280+ name : "Test Separate Manifest" ,
281+ version : "1.0.0" ,
282+ description : "Test with separate manifest" ,
283+ author : { name : "MCPB" } ,
284+ server : {
285+ type : "node" ,
286+ entry_point : "server/index.js" ,
287+ mcp_config : { command : "node" } ,
288+ } ,
289+ } ) ,
290+ ) ;
291+
292+ const result = execSync (
293+ `node ${ cliPath } pack ${ projectDir } ${ manifestPackedPath } --manifest ${ join ( manifestDir , "manifest.json" ) } ` ,
294+ { encoding : "utf-8" } ,
295+ ) ;
296+
297+ expect ( fs . existsSync ( manifestPackedPath ) ) . toBe ( true ) ;
298+ expect ( result ) . toContain ( "Validating manifest" ) ;
299+ } finally {
300+ fs . rmSync ( projectDir , { recursive : true , force : true } ) ;
301+ fs . rmSync ( manifestDir , { recursive : true , force : true } ) ;
302+ if ( fs . existsSync ( manifestPackedPath ) ) {
303+ fs . unlinkSync ( manifestPackedPath ) ;
304+ }
305+ }
306+ } ) ;
307+
308+ it ( "should fail with --manifest pointing to nonexistent file" , ( ) => {
309+ const projectDir = join ( __dirname , "temp-manifest-missing-project" ) ;
310+
311+ try {
312+ fs . mkdirSync ( projectDir , { recursive : true } ) ;
313+ fs . writeFileSync ( join ( projectDir , "index.js" ) , "console.log('hello');" ) ;
314+
315+ expect ( ( ) => {
316+ execSync (
317+ `node ${ cliPath } pack ${ projectDir } /tmp/out.mcpb --manifest /nonexistent/manifest.json` ,
318+ { encoding : "utf-8" , stdio : "pipe" } ,
319+ ) ;
320+ } ) . toThrow ( ) ;
321+
322+ try {
323+ execSync (
324+ `node ${ cliPath } pack ${ projectDir } /tmp/out.mcpb --manifest /nonexistent/manifest.json` ,
325+ { encoding : "utf-8" , stdio : "pipe" } ,
326+ ) ;
327+ } catch ( error : unknown ) {
328+ const execError = error as { stdout ?: Buffer ; stderr ?: Buffer } ;
329+ const output =
330+ ( execError . stdout ?. toString ( ) || "" ) +
331+ ( execError . stderr ?. toString ( ) || "" ) ;
332+ expect ( output ) . toContain ( "Manifest file not found" ) ;
333+ }
334+ } finally {
335+ fs . rmSync ( projectDir , { recursive : true , force : true } ) ;
336+ }
337+ } ) ;
338+
261339 it ( "should preserve executable file permissions after packing and unpacking" , ( ) => {
262340 // Skip this test on Windows since it doesn't support Unix permissions
263341 if ( process . platform === "win32" ) {
0 commit comments