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