@alcyone-labs/arg-parser 2.1.1 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +251 -29
  2. package/dist/config/ConfigurationManager.d.ts.map +1 -1
  3. package/dist/config/plugins/ConfigPlugin.d.ts.map +1 -1
  4. package/dist/config/plugins/ConfigPluginRegistry.d.ts +1 -1
  5. package/dist/config/plugins/ConfigPluginRegistry.d.ts.map +1 -1
  6. package/dist/config/plugins/TomlConfigPlugin.d.ts +1 -1
  7. package/dist/config/plugins/TomlConfigPlugin.d.ts.map +1 -1
  8. package/dist/config/plugins/YamlConfigPlugin.d.ts +1 -1
  9. package/dist/config/plugins/YamlConfigPlugin.d.ts.map +1 -1
  10. package/dist/config/plugins/index.d.ts +4 -4
  11. package/dist/config/plugins/index.d.ts.map +1 -1
  12. package/dist/core/ArgParser.d.ts +17 -6
  13. package/dist/core/ArgParser.d.ts.map +1 -1
  14. package/dist/core/ArgParserBase.d.ts +8 -2
  15. package/dist/core/ArgParserBase.d.ts.map +1 -1
  16. package/dist/core/log-path-utils.d.ts +59 -0
  17. package/dist/core/log-path-utils.d.ts.map +1 -0
  18. package/dist/core/types.d.ts +6 -6
  19. package/dist/core/types.d.ts.map +1 -1
  20. package/dist/dxt/DxtGenerator.d.ts +5 -1
  21. package/dist/dxt/DxtGenerator.d.ts.map +1 -1
  22. package/dist/index.cjs +785 -195
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.ts +5 -4
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.min.mjs +5375 -4848
  27. package/dist/index.min.mjs.map +1 -1
  28. package/dist/index.mjs +785 -195
  29. package/dist/index.mjs.map +1 -1
  30. package/dist/mcp/ArgParserMcp.d.ts.map +1 -1
  31. package/dist/mcp/mcp-notifications.d.ts +4 -4
  32. package/dist/mcp/mcp-notifications.d.ts.map +1 -1
  33. package/dist/mcp/mcp-prompts.d.ts.map +1 -1
  34. package/dist/mcp/mcp-protocol-versions.d.ts +11 -11
  35. package/dist/mcp/mcp-protocol-versions.d.ts.map +1 -1
  36. package/dist/mcp/mcp-resources.d.ts.map +1 -1
  37. package/dist/testing/fuzzy-test-cli.d.ts.map +1 -1
  38. package/dist/testing/fuzzy-tester.d.ts.map +1 -1
  39. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -284,7 +284,9 @@ class JsonConfigPlugin extends ConfigPlugin {
284
284
  const { _meta, ...config } = parsed;
285
285
  return config;
286
286
  } catch (error) {
287
- throw new Error(`Failed to parse JSON: ${error instanceof Error ? error.message : String(error)}`);
287
+ throw new Error(
288
+ `Failed to parse JSON: ${error instanceof Error ? error.message : String(error)}`
289
+ );
288
290
  }
289
291
  }
290
292
  generate(_config, flags, parsedArgs) {
@@ -500,7 +502,9 @@ function enableConfigPlugins(pluginNames) {
500
502
  globalConfigPluginRegistry.registerPlugin(tomlPlugin);
501
503
  }
502
504
  } catch (error) {
503
- console.warn(`Failed to enable TOML plugin: ${error instanceof Error ? error.message : String(error)}`);
505
+ console.warn(
506
+ `Failed to enable TOML plugin: ${error instanceof Error ? error.message : String(error)}`
507
+ );
504
508
  }
505
509
  break;
506
510
  case "yaml":
@@ -511,7 +515,9 @@ function enableConfigPlugins(pluginNames) {
511
515
  globalConfigPluginRegistry.registerPlugin(yamlPlugin);
512
516
  }
513
517
  } catch (error) {
514
- console.warn(`Failed to enable YAML plugin: ${error instanceof Error ? error.message : String(error)}`);
518
+ console.warn(
519
+ `Failed to enable YAML plugin: ${error instanceof Error ? error.message : String(error)}`
520
+ );
515
521
  }
516
522
  break;
517
523
  default:
@@ -535,14 +541,18 @@ class ConfigurationManager {
535
541
  } else if (appName && appName !== "Argument Parser") {
536
542
  baseName = appName;
537
543
  }
538
- baseName = baseName.split(/[\s-_]+/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join("");
544
+ baseName = baseName.split(/[\s-_]+/).map(
545
+ (word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()
546
+ ).join("");
539
547
  return `${baseName}.env`;
540
548
  }
541
549
  /**
542
550
  * Handles the --s-save-to-env system flag at the final parser level
543
551
  */
544
552
  handleSaveToEnvFlag(processArgs, parserChain) {
545
- const saveToEnvIndex = processArgs.findIndex((arg) => arg === "--s-save-to-env");
553
+ const saveToEnvIndex = processArgs.findIndex(
554
+ (arg) => arg === "--s-save-to-env"
555
+ );
546
556
  if (saveToEnvIndex !== -1) {
547
557
  let filePath;
548
558
  if (saveToEnvIndex + 1 < processArgs.length) {
@@ -568,7 +578,11 @@ class ConfigurationManager {
568
578
  const finalParser = parserChain[parserChain.length - 1];
569
579
  const parsedArgs = finalParser.getLastParseResult();
570
580
  if (!parsedArgs) {
571
- console.log(simpleChalk.yellow("No parsed arguments available. Run the command first to generate configuration."));
581
+ console.log(
582
+ simpleChalk.yellow(
583
+ "No parsed arguments available. Run the command first to generate configuration."
584
+ )
585
+ );
572
586
  return;
573
587
  }
574
588
  const allFlags = [];
@@ -601,10 +615,18 @@ class ConfigurationManager {
601
615
  fs.writeFileSync(filePath, content, "utf8");
602
616
  console.log(simpleChalk.green(`✅ Configuration saved to: ${filePath}`));
603
617
  console.log(simpleChalk.gray(`Format: ${ext || ".env"}`));
604
- console.log(simpleChalk.gray(`Flags saved: ${Object.keys(parsedArgs.args).length}`));
618
+ console.log(
619
+ simpleChalk.gray(`Flags saved: ${Object.keys(parsedArgs.args).length}`)
620
+ );
605
621
  } catch (error) {
606
- console.error(simpleChalk.red(`❌ Failed to save configuration: ${error instanceof Error ? error.message : String(error)}`));
607
- throw new Error(`Failed to save configuration: ${error instanceof Error ? error.message : String(error)}`);
622
+ console.error(
623
+ simpleChalk.red(
624
+ `❌ Failed to save configuration: ${error instanceof Error ? error.message : String(error)}`
625
+ )
626
+ );
627
+ throw new Error(
628
+ `Failed to save configuration: ${error instanceof Error ? error.message : String(error)}`
629
+ );
608
630
  }
609
631
  }
610
632
  /**
@@ -641,7 +663,11 @@ class ConfigurationManager {
641
663
  }
642
664
  return this.convertConfigToFlagValues(rawConfig, parserChain);
643
665
  } catch (error) {
644
- console.warn(simpleChalk.yellow(`Warning: Could not load config file ${filePath}: ${error instanceof Error ? error.message : String(error)}`));
666
+ console.warn(
667
+ simpleChalk.yellow(
668
+ `Warning: Could not load config file ${filePath}: ${error instanceof Error ? error.message : String(error)}`
669
+ )
670
+ );
645
671
  return {};
646
672
  }
647
673
  }
@@ -675,7 +701,9 @@ class ConfigurationManager {
675
701
  if (plugin) {
676
702
  return plugin.parse(content);
677
703
  }
678
- console.warn("YAML plugin not available, using simple parser. Install js-yaml and enable YAML plugin for full support.");
704
+ console.warn(
705
+ "YAML plugin not available, using simple parser. Install js-yaml and enable YAML plugin for full support."
706
+ );
679
707
  const config = {};
680
708
  const lines = content.split("\n");
681
709
  let currentKey = null;
@@ -726,7 +754,9 @@ class ConfigurationManager {
726
754
  try {
727
755
  return JSON.parse(content) || {};
728
756
  } catch (error) {
729
- throw new Error(`Failed to parse JSON: ${error instanceof Error ? error.message : String(error)}`);
757
+ throw new Error(
758
+ `Failed to parse JSON: ${error instanceof Error ? error.message : String(error)}`
759
+ );
730
760
  }
731
761
  }
732
762
  /**
@@ -737,7 +767,9 @@ class ConfigurationManager {
737
767
  if (plugin) {
738
768
  return plugin.parse(content);
739
769
  }
740
- console.warn("TOML plugin not available, using simple parser. Install smol-toml and enable TOML plugin for full support.");
770
+ console.warn(
771
+ "TOML plugin not available, using simple parser. Install smol-toml and enable TOML plugin for full support."
772
+ );
741
773
  const config = {};
742
774
  const lines = content.split("\n");
743
775
  for (const line of lines) {
@@ -768,13 +800,19 @@ class ConfigurationManager {
768
800
  for (const [key, value] of Object.entries(rawConfig)) {
769
801
  let flag = allFlags.find((f) => f["name"] === key);
770
802
  if (!flag) {
771
- flag = allFlags.find((f) => f["name"].toLowerCase() === key.toLowerCase());
803
+ flag = allFlags.find(
804
+ (f) => f["name"].toLowerCase() === key.toLowerCase()
805
+ );
772
806
  }
773
807
  if (flag) {
774
808
  try {
775
809
  flagValues[flag["name"]] = this.convertValueToFlagType(value, flag);
776
810
  } catch (error) {
777
- console.warn(simpleChalk.yellow(`Warning: Could not convert config value for flag '${key}': ${error instanceof Error ? error.message : String(error)}`));
811
+ console.warn(
812
+ simpleChalk.yellow(
813
+ `Warning: Could not convert config value for flag '${key}': ${error instanceof Error ? error.message : String(error)}`
814
+ )
815
+ );
778
816
  }
779
817
  }
780
818
  }
@@ -811,17 +849,23 @@ class ConfigurationManager {
811
849
  }
812
850
  const num = Number(value);
813
851
  if (isNaN(num)) {
814
- throw new Error(`Cannot convert '${value}' to number for flag '${flag["name"]}'`);
852
+ throw new Error(
853
+ `Cannot convert '${value}' to number for flag '${flag["name"]}'`
854
+ );
815
855
  }
816
856
  return num;
817
857
  } else if (isBooleanType) {
818
858
  if (typeof value === "boolean") return value;
819
859
  if (typeof value === "string") {
820
860
  const lower = value.toLowerCase();
821
- if (lower === "true" || lower === "1" || lower === "yes" || lower === "on") return true;
822
- if (lower === "false" || lower === "0" || lower === "no" || lower === "off") return false;
861
+ if (lower === "true" || lower === "1" || lower === "yes" || lower === "on")
862
+ return true;
863
+ if (lower === "false" || lower === "0" || lower === "no" || lower === "off")
864
+ return false;
823
865
  }
824
- throw new Error(`Cannot convert '${value}' to boolean for flag '${flag["name"]}'`);
866
+ throw new Error(
867
+ `Cannot convert '${value}' to boolean for flag '${flag["name"]}'`
868
+ );
825
869
  } else if (flagType === "table") {
826
870
  if (Array.isArray(value)) return value;
827
871
  if (typeof value === "string") {
@@ -832,13 +876,17 @@ class ConfigurationManager {
832
876
  return value.split(",").map((v) => v.trim());
833
877
  }
834
878
  }
835
- throw new Error(`Cannot convert '${value}' to table for flag '${flag["name"]}'`);
879
+ throw new Error(
880
+ `Cannot convert '${value}' to table for flag '${flag["name"]}'`
881
+ );
836
882
  } else {
837
883
  if (typeof flagType === "function") {
838
884
  try {
839
885
  return flagType(value);
840
886
  } catch (error) {
841
- throw new Error(`Custom type conversion failed for flag '${flag["name"]}': ${error instanceof Error ? error.message : String(error)}`);
887
+ throw new Error(
888
+ `Custom type conversion failed for flag '${flag["name"]}': ${error instanceof Error ? error.message : String(error)}`
889
+ );
842
890
  }
843
891
  }
844
892
  return String(value);
@@ -913,7 +961,9 @@ class ConfigurationManager {
913
961
  if (Array.isArray(value)) {
914
962
  lines.push(`${flag["name"]}:`);
915
963
  for (const item of value) {
916
- lines.push(` - ${typeof item === "string" && item.includes(" ") ? `"${item}"` : item}`);
964
+ lines.push(
965
+ ` - ${typeof item === "string" && item.includes(" ") ? `"${item}"` : item}`
966
+ );
917
967
  }
918
968
  } else if (typeof value === "string" && value.includes(" ")) {
919
969
  lines.push(`${flag["name"]}: "${value}"`);
@@ -1014,8 +1064,8 @@ const zodFlagSchema = z.object({
1014
1064
  // Native Object constructor
1015
1065
  message: "Must be Object constructor"
1016
1066
  }),
1017
- z.function().args(z.string()).returns(z.any()),
1018
- // Custom parser function (value: string) => any
1067
+ z.function().args(z.string()).returns(z.union([z.any(), z.promise(z.any())])),
1068
+ // Custom parser function (value: string) => any | Promise<any>
1019
1069
  z.string().refine(
1020
1070
  // String literal types
1021
1071
  (value) => ["boolean", "string", "number", "array", "object"].includes(
@@ -1176,22 +1226,46 @@ class DxtGenerator {
1176
1226
  try {
1177
1227
  const isTestMode = process.env["NODE_ENV"] === "test" || ((_a = process.argv[0]) == null ? void 0 : _a.includes("vitest")) || ((_b = process.argv[1]) == null ? void 0 : _b.includes("vitest")) || ((_c = process.argv[1]) == null ? void 0 : _c.includes("tinypool"));
1178
1228
  if (isTestMode) {
1179
- return await this.handleTestModeDxtGeneration(processArgs, buildDxtIndex);
1229
+ return await this.handleTestModeDxtGeneration(
1230
+ processArgs,
1231
+ buildDxtIndex
1232
+ );
1180
1233
  }
1181
1234
  const entryPointFile = process.argv[1];
1182
1235
  if (!entryPointFile || !fs.existsSync(entryPointFile)) {
1183
- console.error(simpleChalk.red(`Error: Entry point file not found: ${entryPointFile}`));
1236
+ console.error(
1237
+ simpleChalk.red(`Error: Entry point file not found: ${entryPointFile}`)
1238
+ );
1184
1239
  return this._handleExit(1, "Entry point file not found", "error");
1185
1240
  }
1186
- console.log(simpleChalk.cyan(`
1187
- 🔧 Building DXT package for entry point: ${path.basename(entryPointFile)}`));
1188
- await this.buildDxtWithTsdown(entryPointFile);
1241
+ const outputDir = processArgs[buildDxtIndex + 1] || "./dxt";
1242
+ console.log(
1243
+ simpleChalk.cyan(
1244
+ `
1245
+ 🔧 Building DXT package for entry point: ${path.basename(entryPointFile)}`
1246
+ )
1247
+ );
1248
+ console.log(simpleChalk.gray(`Output directory: ${outputDir}`));
1249
+ await this.buildDxtWithTsdown(entryPointFile, outputDir);
1189
1250
  console.log(simpleChalk.green(`
1190
1251
  ✅ DXT package generation completed!`));
1191
- return this._handleExit(0, "DXT package generation completed", "success", { entryPoint: entryPointFile });
1252
+ return this._handleExit(
1253
+ 0,
1254
+ "DXT package generation completed",
1255
+ "success",
1256
+ { entryPoint: entryPointFile, outputDir }
1257
+ );
1192
1258
  } catch (error) {
1193
- console.error(simpleChalk.red(`Error generating DXT package: ${error instanceof Error ? error.message : String(error)}`));
1194
- return this._handleExit(1, `Error generating DXT package: ${error instanceof Error ? error.message : String(error)}`, "error");
1259
+ console.error(
1260
+ simpleChalk.red(
1261
+ `Error generating DXT package: ${error instanceof Error ? error.message : String(error)}`
1262
+ )
1263
+ );
1264
+ return this._handleExit(
1265
+ 1,
1266
+ `Error generating DXT package: ${error instanceof Error ? error.message : String(error)}`,
1267
+ "error"
1268
+ );
1195
1269
  }
1196
1270
  }
1197
1271
  /**
@@ -1231,7 +1305,10 @@ class DxtGenerator {
1231
1305
  })),
1232
1306
  icon: "logo.jpg"
1233
1307
  };
1234
- fs.writeFileSync(path.join(buildDir, "manifest.json"), JSON.stringify(manifest, null, 2));
1308
+ fs.writeFileSync(
1309
+ path.join(buildDir, "manifest.json"),
1310
+ JSON.stringify(manifest, null, 2)
1311
+ );
1235
1312
  const packageJson = {
1236
1313
  name: serverInfo.name,
1237
1314
  version: serverInfo.version,
@@ -1239,7 +1316,10 @@ class DxtGenerator {
1239
1316
  main: "index.mjs",
1240
1317
  type: "module"
1241
1318
  };
1242
- fs.writeFileSync(path.join(buildDir, "package.json"), JSON.stringify(packageJson, null, 2));
1319
+ fs.writeFileSync(
1320
+ path.join(buildDir, "package.json"),
1321
+ JSON.stringify(packageJson, null, 2)
1322
+ );
1243
1323
  const readme = `# ${serverInfo.name}
1244
1324
 
1245
1325
  ${serverInfo.description}
@@ -1248,13 +1328,25 @@ Generated by @alcyone-labs/arg-parser`;
1248
1328
  fs.writeFileSync(path.join(buildDir, "README.md"), readme);
1249
1329
  const buildScript = `#!/bin/bash
1250
1330
  echo "Mock DXT build script for ${serverInfo.name}"`;
1251
- fs.writeFileSync(path.join(buildDir, "build-dxt-package.sh"), buildScript);
1252
- return this._handleExit(0, "DXT package generation completed", "success", {
1253
- entryPoint: "test-mode",
1254
- outputDir: buildDir
1255
- });
1331
+ fs.writeFileSync(
1332
+ path.join(buildDir, "build-dxt-package.sh"),
1333
+ buildScript
1334
+ );
1335
+ return this._handleExit(
1336
+ 0,
1337
+ "DXT package generation completed",
1338
+ "success",
1339
+ {
1340
+ entryPoint: "test-mode",
1341
+ outputDir: buildDir
1342
+ }
1343
+ );
1256
1344
  } catch (error) {
1257
- return this._handleExit(1, `Test mode DXT generation failed: ${error instanceof Error ? error.message : String(error)}`, "error");
1345
+ return this._handleExit(
1346
+ 1,
1347
+ `Test mode DXT generation failed: ${error instanceof Error ? error.message : String(error)}`,
1348
+ "error"
1349
+ );
1258
1350
  }
1259
1351
  }
1260
1352
  /**
@@ -1275,9 +1367,17 @@ echo "Mock DXT build script for ${serverInfo.name}"`;
1275
1367
  fs.mkdirSync(serverDir, { recursive: true });
1276
1368
  }
1277
1369
  const logoFilename = await this.addLogoToFolder(buildDir, serverInfo);
1278
- const manifest = this.createDxtManifest(serverInfo, tools, mcpSubCommand, logoFilename);
1370
+ const manifest = this.createDxtManifest(
1371
+ serverInfo,
1372
+ tools,
1373
+ mcpSubCommand,
1374
+ logoFilename
1375
+ );
1279
1376
  this.validateDxtManifest(manifest);
1280
- fs.writeFileSync(path.join(buildDir, "manifest.json"), JSON.stringify(manifest, null, 2));
1377
+ fs.writeFileSync(
1378
+ path.join(buildDir, "manifest.json"),
1379
+ JSON.stringify(manifest, null, 2)
1380
+ );
1281
1381
  this.addOriginalCliToFolder(buildDir);
1282
1382
  const bundledCliPath = await this.bundleOriginalCliWithTsdown(serverDir);
1283
1383
  const serverScript = this.createServerScript(serverInfo, bundledCliPath);
@@ -1286,10 +1386,16 @@ echo "Mock DXT build script for ${serverInfo.name}"`;
1286
1386
  try {
1287
1387
  fs.chmodSync(serverScriptPath, 493);
1288
1388
  } catch (error) {
1289
- console.warn("⚠ Could not set executable permission on server script:", error instanceof Error ? error.message : String(error));
1389
+ console.warn(
1390
+ "⚠ Could not set executable permission on server script:",
1391
+ error instanceof Error ? error.message : String(error)
1392
+ );
1290
1393
  }
1291
1394
  const packageJson = this.createDxtPackageJson(serverInfo);
1292
- fs.writeFileSync(path.join(buildDir, "package.json"), JSON.stringify(packageJson, null, 2));
1395
+ fs.writeFileSync(
1396
+ path.join(buildDir, "package.json"),
1397
+ JSON.stringify(packageJson, null, 2)
1398
+ );
1293
1399
  const readme = this.createDxtReadme(serverInfo);
1294
1400
  fs.writeFileSync(path.join(buildDir, "README.md"), readme);
1295
1401
  const buildScript = this.createSimpleBuildScript(serverInfo);
@@ -1301,11 +1407,15 @@ echo "Mock DXT build script for ${serverInfo.name}"`;
1301
1407
  } catch (error) {
1302
1408
  }
1303
1409
  console.log(simpleChalk.green(` ✓ Generated DXT package folder: ${folderName}`));
1304
- console.log(simpleChalk.gray(` Server: ${serverInfo.name} v${serverInfo.version}`));
1410
+ console.log(
1411
+ simpleChalk.gray(` Server: ${serverInfo.name} v${serverInfo.version}`)
1412
+ );
1305
1413
  console.log(simpleChalk.gray(` Tools: ${tools.length} tool(s)`));
1306
1414
  console.log(simpleChalk.gray(` Location: ${buildDir}`));
1307
- console.log(simpleChalk.cyan(`
1308
- 📦 Creating DXT package using Anthropic's dxt pack...`));
1415
+ console.log(
1416
+ simpleChalk.cyan(`
1417
+ 📦 Creating DXT package using Anthropic's dxt pack...`)
1418
+ );
1309
1419
  console.log(simpleChalk.cyan(`
1310
1420
  📋 Manual steps to create your DXT package:`));
1311
1421
  console.log(simpleChalk.white(` cd ${path.relative(process.cwd(), buildDir)}`));
@@ -1368,7 +1478,9 @@ echo "Mock DXT build script for ${serverInfo.name}"`;
1368
1478
  toolOptions = mcpConfig.toolOptions;
1369
1479
  }
1370
1480
  }
1371
- const mcpTools = this.argParserInstance.toMcpTools(toolOptions);
1481
+ const mcpTools = this.argParserInstance.toMcpTools(
1482
+ toolOptions
1483
+ );
1372
1484
  return mcpTools.map((tool) => ({
1373
1485
  name: tool.name,
1374
1486
  description: tool.description
@@ -1392,16 +1504,24 @@ echo "Mock DXT build script for ${serverInfo.name}"`;
1392
1504
  });
1393
1505
  }
1394
1506
  }
1395
- return tools.length > 0 ? tools : [{
1396
- name: "main",
1397
- description: "Main command tool"
1398
- }];
1507
+ return tools.length > 0 ? tools : [
1508
+ {
1509
+ name: "main",
1510
+ description: "Main command tool"
1511
+ }
1512
+ ];
1399
1513
  } catch (error) {
1400
- console.warn(simpleChalk.yellow(`Warning: Could not generate detailed tool list: ${error instanceof Error ? error.message : String(error)}`));
1401
- return [{
1402
- name: "main",
1403
- description: "Main command tool"
1404
- }];
1514
+ console.warn(
1515
+ simpleChalk.yellow(
1516
+ `Warning: Could not generate detailed tool list: ${error instanceof Error ? error.message : String(error)}`
1517
+ )
1518
+ );
1519
+ return [
1520
+ {
1521
+ name: "main",
1522
+ description: "Main command tool"
1523
+ }
1524
+ ];
1405
1525
  }
1406
1526
  }
1407
1527
  createDxtManifest(serverInfo, tools, mcpSubCommand, logoFilename) {
@@ -1424,7 +1544,9 @@ echo "Mock DXT build script for ${serverInfo.name}"`;
1424
1544
  }
1425
1545
  }
1426
1546
  if (!author) {
1427
- throw new Error("DXT manifest requires author information. Please provide it via withMcp() serverInfo.author, addMcpSubCommand serverInfo.author, or in package.json");
1547
+ throw new Error(
1548
+ "DXT manifest requires author information. Please provide it via withMcp() serverInfo.author, addMcpSubCommand serverInfo.author, or in package.json"
1549
+ );
1428
1550
  }
1429
1551
  const cliArgs = this.generateCliArgsForDxt(mcpSubCommand);
1430
1552
  const { envVars, userConfig } = this.generateEnvAndUserConfig();
@@ -1467,31 +1589,41 @@ echo "Mock DXT build script for ${serverInfo.name}"`;
1467
1589
  }
1468
1590
  validateDxtManifest(manifest) {
1469
1591
  const errors = [];
1470
- if (!manifest.dxt_version) errors.push("Missing required field: dxt_version");
1592
+ if (!manifest.dxt_version)
1593
+ errors.push("Missing required field: dxt_version");
1471
1594
  if (!manifest.name) errors.push("Missing required field: name");
1472
1595
  if (!manifest.version) errors.push("Missing required field: version");
1473
1596
  if (!manifest.server) errors.push("Missing required field: server");
1474
1597
  if (!manifest.author) errors.push("Missing required field: author");
1475
1598
  if (manifest.server) {
1476
- if (!manifest.server.type) errors.push("Missing required field: server.type");
1477
- if (!manifest.server.entry_point) errors.push("Missing required field: server.entry_point");
1478
- if (!manifest.server.mcp_config) errors.push("Missing required field: server.mcp_config");
1599
+ if (!manifest.server.type)
1600
+ errors.push("Missing required field: server.type");
1601
+ if (!manifest.server.entry_point)
1602
+ errors.push("Missing required field: server.entry_point");
1603
+ if (!manifest.server.mcp_config)
1604
+ errors.push("Missing required field: server.mcp_config");
1479
1605
  if (manifest.server.mcp_config) {
1480
- if (!manifest.server.mcp_config.command) errors.push("Missing required field: server.mcp_config.command");
1606
+ if (!manifest.server.mcp_config.command)
1607
+ errors.push("Missing required field: server.mcp_config.command");
1481
1608
  if (!manifest.server.mcp_config.args || !Array.isArray(manifest.server.mcp_config.args)) {
1482
- errors.push("Missing or invalid field: server.mcp_config.args (must be array)");
1609
+ errors.push(
1610
+ "Missing or invalid field: server.mcp_config.args (must be array)"
1611
+ );
1483
1612
  }
1484
1613
  }
1485
1614
  }
1486
1615
  if (manifest.author && typeof manifest.author === "object") {
1487
- if (!manifest.author.name) errors.push("Missing required field: author.name");
1616
+ if (!manifest.author.name)
1617
+ errors.push("Missing required field: author.name");
1488
1618
  }
1489
1619
  if (manifest.dxt_version && manifest.dxt_version !== "0.1") {
1490
1620
  errors.push("Unsupported dxt_version: only '0.1' is currently supported");
1491
1621
  }
1492
1622
  if (errors.length > 0) {
1493
- throw new Error(`DXT manifest validation failed:
1494
- ${errors.map((e) => ` - ${e}`).join("\n")}`);
1623
+ throw new Error(
1624
+ `DXT manifest validation failed:
1625
+ ${errors.map((e) => ` - ${e}`).join("\n")}`
1626
+ );
1495
1627
  }
1496
1628
  }
1497
1629
  createServerScript(serverInfo, bundledCliPath) {
@@ -1535,27 +1667,34 @@ originalCli.parse(['--s-mcp-serve']);
1535
1667
  try {
1536
1668
  const originalPackageJsonPath = path.join(process.cwd(), "package.json");
1537
1669
  if (fs.existsSync(originalPackageJsonPath)) {
1538
- const originalPackageJson = JSON.parse(fs.readFileSync(originalPackageJsonPath, "utf8"));
1670
+ const originalPackageJson = JSON.parse(
1671
+ fs.readFileSync(originalPackageJsonPath, "utf8")
1672
+ );
1539
1673
  originalDependencies = originalPackageJson.dependencies || {};
1540
1674
  }
1541
1675
  } catch (error) {
1542
- console.warn("⚠ Could not read original package.json for dependencies:", error instanceof Error ? error.message : String(error));
1676
+ console.warn(
1677
+ "⚠ Could not read original package.json for dependencies:",
1678
+ error instanceof Error ? error.message : String(error)
1679
+ );
1543
1680
  }
1544
1681
  const dependencies2 = {
1545
1682
  ...originalDependencies,
1546
1683
  "@alcyone-labs/arg-parser": argParserDependency,
1547
1684
  "@alcyone-labs/simple-mcp-logger": "^1.0.0",
1548
1685
  "@modelcontextprotocol/sdk": "^1.15.0",
1549
- "zod": "^3.22.4"
1686
+ zod: "^3.22.4"
1550
1687
  };
1551
1688
  const devDependencies = {
1552
- "tsup": "^8.3.5"
1689
+ tsup: "^8.3.5"
1553
1690
  };
1554
1691
  Object.keys(dependencies2).forEach((key) => {
1555
1692
  const depValue = dependencies2[key];
1556
1693
  if (key !== "@alcyone-labs/arg-parser" && typeof depValue === "string" && depValue.startsWith("file:")) {
1557
1694
  delete dependencies2[key];
1558
- console.warn(`⚠ Removed file: dependency ${key} from DXT package (not suitable for distribution)`);
1695
+ console.warn(
1696
+ `⚠ Removed file: dependency ${key} from DXT package (not suitable for distribution)`
1697
+ );
1559
1698
  }
1560
1699
  });
1561
1700
  return {
@@ -1901,7 +2040,7 @@ For autonomous packages, follow the build instructions above.
1901
2040
  * Adds the logo to the build folder if available
1902
2041
  * @returns The filename of the logo that was added, or undefined if no logo was added
1903
2042
  */
1904
- async addLogoToFolder(buildDir, serverInfo) {
2043
+ async addLogoToFolder(buildDir, serverInfo, entryPointFile) {
1905
2044
  try {
1906
2045
  let logoBuffer = null;
1907
2046
  let logoFilename = "logo.jpg";
@@ -1920,13 +2059,27 @@ For autonomous packages, follow the build instructions above.
1920
2059
  }
1921
2060
  console.log("✓ Downloaded logo from URL");
1922
2061
  } else {
1923
- console.warn(`⚠ Failed to download logo: HTTP ${response.status}`);
2062
+ console.warn(
2063
+ `⚠ Failed to download logo: HTTP ${response.status}`
2064
+ );
1924
2065
  }
1925
2066
  } catch (error) {
1926
- console.warn("⚠ Failed to download logo from URL:", error instanceof Error ? error.message : String(error));
2067
+ console.warn(
2068
+ "⚠ Failed to download logo from URL:",
2069
+ error instanceof Error ? error.message : String(error)
2070
+ );
1927
2071
  }
1928
2072
  } else {
1929
- const logoPath = path.resolve(customLogo);
2073
+ let logoPath;
2074
+ if (entryPointFile && !path.isAbsolute(customLogo)) {
2075
+ const entryDir = path.dirname(entryPointFile);
2076
+ logoPath = path.resolve(entryDir, customLogo);
2077
+ console.log(
2078
+ `📍 Resolving logo path relative to entry point: ${logoPath}`
2079
+ );
2080
+ } else {
2081
+ logoPath = path.resolve(customLogo);
2082
+ }
1930
2083
  if (fs.existsSync(logoPath)) {
1931
2084
  logoBuffer = fs.readFileSync(logoPath);
1932
2085
  logoFilename = path.basename(logoPath);
@@ -1940,17 +2093,32 @@ For autonomous packages, follow the build instructions above.
1940
2093
  const currentDir = path.dirname(new URL(import.meta.url).pathname);
1941
2094
  let logoPath = path.join(currentDir, "assets", "logo_1_small.jpg");
1942
2095
  if (!fs.existsSync(logoPath)) {
1943
- logoPath = path.join(currentDir, "..", "docs", "MCP", "icons", "logo_1_small.jpg");
2096
+ logoPath = path.join(
2097
+ currentDir,
2098
+ "..",
2099
+ "docs",
2100
+ "MCP",
2101
+ "icons",
2102
+ "logo_1_small.jpg"
2103
+ );
1944
2104
  }
1945
2105
  if (!fs.existsSync(logoPath)) {
1946
- logoPath = path.join(process.cwd(), "docs", "MCP", "icons", "logo_1_small.jpg");
2106
+ logoPath = path.join(
2107
+ process.cwd(),
2108
+ "docs",
2109
+ "MCP",
2110
+ "icons",
2111
+ "logo_1_small.jpg"
2112
+ );
1947
2113
  }
1948
2114
  if (fs.existsSync(logoPath)) {
1949
2115
  logoBuffer = fs.readFileSync(logoPath);
1950
2116
  logoFilename = "logo.jpg";
1951
2117
  console.log("✓ Added default logo to build folder");
1952
2118
  } else {
1953
- console.warn("⚠ No logo found (custom or default), build folder will be created without icon");
2119
+ console.warn(
2120
+ "⚠ No logo found (custom or default), build folder will be created without icon"
2121
+ );
1954
2122
  return void 0;
1955
2123
  }
1956
2124
  }
@@ -1960,7 +2128,10 @@ For autonomous packages, follow the build instructions above.
1960
2128
  }
1961
2129
  return void 0;
1962
2130
  } catch (error) {
1963
- console.warn("⚠ Failed to add logo to build folder:", error instanceof Error ? error.message : String(error));
2131
+ console.warn(
2132
+ "⚠ Failed to add logo to build folder:",
2133
+ error instanceof Error ? error.message : String(error)
2134
+ );
1964
2135
  return void 0;
1965
2136
  }
1966
2137
  }
@@ -2010,7 +2181,12 @@ globalThis.console = {
2010
2181
  }
2011
2182
  }
2012
2183
  if (lastImportIndex >= 0) {
2013
- lines.splice(lastImportIndex + 1, 0, "", ...consoleReplacement.trim().split("\n"));
2184
+ lines.splice(
2185
+ lastImportIndex + 1,
2186
+ 0,
2187
+ "",
2188
+ ...consoleReplacement.trim().split("\n")
2189
+ );
2014
2190
  return lines.join("\n");
2015
2191
  } else {
2016
2192
  return consoleReplacement + cliSource;
@@ -2035,14 +2211,32 @@ globalThis.console = {
2035
2211
  path.join(process.cwd(), `${appCommandName}.js`),
2036
2212
  path.join(process.cwd(), `${appCommandName}.mjs`),
2037
2213
  // Look for files with the app command name (sanitized)
2038
- path.join(process.cwd(), `${appCommandName.replace(/[^a-zA-Z0-9-]/g, "-")}.js`),
2039
- path.join(process.cwd(), `${appCommandName.replace(/[^a-zA-Z0-9-]/g, "-")}.mjs`),
2214
+ path.join(
2215
+ process.cwd(),
2216
+ `${appCommandName.replace(/[^a-zA-Z0-9-]/g, "-")}.js`
2217
+ ),
2218
+ path.join(
2219
+ process.cwd(),
2220
+ `${appCommandName.replace(/[^a-zA-Z0-9-]/g, "-")}.mjs`
2221
+ ),
2040
2222
  // Look for files with app name patterns
2041
- path.join(process.cwd(), `${appName.toLowerCase().replace(/\s+/g, "-")}-cli.js`),
2042
- path.join(process.cwd(), `${appName.toLowerCase().replace(/\s+/g, "-")}-cli.mjs`),
2223
+ path.join(
2224
+ process.cwd(),
2225
+ `${appName.toLowerCase().replace(/\s+/g, "-")}-cli.js`
2226
+ ),
2227
+ path.join(
2228
+ process.cwd(),
2229
+ `${appName.toLowerCase().replace(/\s+/g, "-")}-cli.mjs`
2230
+ ),
2043
2231
  // Look for files with first word of app name + cli
2044
- path.join(process.cwd(), `${appName.split(" ")[0].toLowerCase()}-cli.js`),
2045
- path.join(process.cwd(), `${appName.split(" ")[0].toLowerCase()}-cli.mjs`)
2232
+ path.join(
2233
+ process.cwd(),
2234
+ `${appName.split(" ")[0].toLowerCase()}-cli.js`
2235
+ ),
2236
+ path.join(
2237
+ process.cwd(),
2238
+ `${appName.split(" ")[0].toLowerCase()}-cli.mjs`
2239
+ )
2046
2240
  ];
2047
2241
  let cliSourcePath = null;
2048
2242
  for (const filePath of possibleCliFiles) {
@@ -2062,7 +2256,9 @@ globalThis.console = {
2062
2256
  "import $1 from '@alcyone-labs/arg-parser';"
2063
2257
  );
2064
2258
  cliSource = this.processCliSourceForMcp(cliSource);
2065
- const parserVariableMatch = cliSource.match(/const\s+(\w+)\s*=\s*ArgParser\.withMcp\(/);
2259
+ const parserVariableMatch = cliSource.match(
2260
+ /const\s+(\w+)\s*=\s*ArgParser\.withMcp\(/
2261
+ );
2066
2262
  if (parserVariableMatch) {
2067
2263
  const parserVariable = parserVariableMatch[1];
2068
2264
  cliSource += `
@@ -2128,26 +2324,38 @@ if (process.argv.includes('serve')) {
2128
2324
  }
2129
2325
  `;
2130
2326
  } else {
2131
- console.warn("⚠ Could not find ArgParser instance in CLI source, MCP server may not work properly");
2327
+ console.warn(
2328
+ "⚠ Could not find ArgParser instance in CLI source, MCP server may not work properly"
2329
+ );
2132
2330
  }
2133
2331
  const serverDir = path.join(buildDir, "server");
2134
2332
  if (!fs.existsSync(serverDir)) {
2135
2333
  fs.mkdirSync(serverDir, { recursive: true });
2136
2334
  }
2137
2335
  fs.writeFileSync(path.join(serverDir, "original-cli.mjs"), cliSource);
2138
- console.log(`✓ Added original CLI source to build folder: ${path.basename(cliSourcePath)}`);
2336
+ console.log(
2337
+ `✓ Added original CLI source to build folder: ${path.basename(cliSourcePath)}`
2338
+ );
2139
2339
  } else {
2140
- console.warn("⚠ Original CLI source not found, handlers may not work properly");
2141
- console.warn(" Searched for:", possibleCliFiles.map((f) => path.basename(f)).join(", "));
2340
+ console.warn(
2341
+ " Original CLI source not found, handlers may not work properly"
2342
+ );
2343
+ console.warn(
2344
+ " Searched for:",
2345
+ possibleCliFiles.map((f) => path.basename(f)).join(", ")
2346
+ );
2142
2347
  }
2143
2348
  } catch (error) {
2144
- console.warn("⚠ Failed to add original CLI source:", error instanceof Error ? error.message : String(error));
2349
+ console.warn(
2350
+ "⚠ Failed to add original CLI source:",
2351
+ error instanceof Error ? error.message : String(error)
2352
+ );
2145
2353
  }
2146
2354
  }
2147
2355
  /**
2148
2356
  * Builds a complete DXT package using TSDown CLI for autonomous execution
2149
2357
  */
2150
- async buildDxtWithTsdown(entryPointFile) {
2358
+ async buildDxtWithTsdown(entryPointFile, outputDir = "./dxt") {
2151
2359
  try {
2152
2360
  console.log(simpleChalk.cyan("🔧 Building DXT package with TSDown..."));
2153
2361
  const entryDir = path.dirname(entryPointFile);
@@ -2165,7 +2373,7 @@ if (process.argv.includes('serve')) {
2165
2373
  console.log(simpleChalk.gray(`Building with TSDown: ${entryFileName}`));
2166
2374
  const buildConfig = {
2167
2375
  entry: [entryFileName],
2168
- outDir: "dxt",
2376
+ outDir: path.resolve(process.cwd(), outputDir),
2169
2377
  format: ["esm"],
2170
2378
  target: "node22",
2171
2379
  noExternal: () => true,
@@ -2178,13 +2386,35 @@ if (process.argv.includes('serve')) {
2178
2386
  ...(() => {
2179
2387
  const possibleLogoPaths = [
2180
2388
  // From built library assets
2181
- path.join(path.dirname(new URL(import.meta.url).pathname), "..", "assets", "logo_1_small.jpg"),
2389
+ path.join(
2390
+ path.dirname(new URL(import.meta.url).pathname),
2391
+ "..",
2392
+ "assets",
2393
+ "logo_1_small.jpg"
2394
+ ),
2182
2395
  // From node_modules
2183
- path.join(process.cwd(), "node_modules", "@alcyone-labs", "arg-parser", "dist", "assets", "logo_1_small.jpg"),
2396
+ path.join(
2397
+ process.cwd(),
2398
+ "node_modules",
2399
+ "@alcyone-labs",
2400
+ "arg-parser",
2401
+ "dist",
2402
+ "assets",
2403
+ "logo_1_small.jpg"
2404
+ ),
2184
2405
  // From package root dist/assets (for local build)
2185
2406
  path.join(process.cwd(), "dist", "assets", "logo_1_small.jpg"),
2186
2407
  // From library root (development)
2187
- path.join(process.cwd(), "..", "..", "..", "docs", "MCP", "icons", "logo_1_small.jpg")
2408
+ path.join(
2409
+ process.cwd(),
2410
+ "..",
2411
+ "..",
2412
+ "..",
2413
+ "docs",
2414
+ "MCP",
2415
+ "icons",
2416
+ "logo_1_small.jpg"
2417
+ )
2188
2418
  ];
2189
2419
  for (const logoPath of possibleLogoPaths) {
2190
2420
  if (fs.existsSync(logoPath)) {
@@ -2192,7 +2422,9 @@ if (process.argv.includes('serve')) {
2192
2422
  return [{ from: logoPath, to: "logo.jpg" }];
2193
2423
  }
2194
2424
  }
2195
- console.log(simpleChalk.yellow("⚠ Logo not found in any expected location"));
2425
+ console.log(
2426
+ simpleChalk.yellow("⚠ Logo not found in any expected location")
2427
+ );
2196
2428
  return [];
2197
2429
  })()
2198
2430
  ],
@@ -2232,20 +2464,39 @@ export default ${JSON.stringify(buildConfig, null, 2)};
2232
2464
  // To run manually:
2233
2465
  // npx tsdown -c tsdown.config.dxt.ts
2234
2466
  `;
2235
- fs.writeFileSync(path.join("dxt", "tsdown.config.dxt.ts"), configContent);
2236
- console.log(simpleChalk.gray("📝 Debug config written to dxt/tsdown.config.dxt.ts"));
2467
+ fs.writeFileSync(
2468
+ path.join("dxt", "tsdown.config.dxt.ts"),
2469
+ configContent
2470
+ );
2471
+ console.log(
2472
+ simpleChalk.gray("📝 Debug config written to dxt/tsdown.config.dxt.ts")
2473
+ );
2237
2474
  }
2238
2475
  await build(buildConfig);
2239
2476
  console.log(simpleChalk.green("✅ TSDown bundling completed"));
2240
- await this.copyLogoManually();
2241
- await this.setupDxtPackageFiles(entryPointFile);
2477
+ const actualOutputFilename = this.detectTsdownOutputFile(
2478
+ outputDir,
2479
+ entryFileName
2480
+ );
2481
+ await this.copyLogoManually(outputDir);
2482
+ await this.setupDxtPackageFiles(
2483
+ entryPointFile,
2484
+ outputDir,
2485
+ actualOutputFilename ?? void 0
2486
+ );
2242
2487
  console.log(simpleChalk.cyan("📦 DXT package ready for packing"));
2243
- console.log(simpleChalk.gray("To complete the process, run: npx @anthropic-ai/dxt pack dxt/"));
2488
+ console.log(
2489
+ simpleChalk.gray(
2490
+ `To complete the process, run: npx @anthropic-ai/dxt pack ${outputDir}/`
2491
+ )
2492
+ );
2244
2493
  } finally {
2245
2494
  process.chdir(originalCwd);
2246
2495
  }
2247
2496
  } catch (error) {
2248
- throw new Error(`TSDown DXT build failed: ${error instanceof Error ? error.message : String(error)}`);
2497
+ throw new Error(
2498
+ `TSDown DXT build failed: ${error instanceof Error ? error.message : String(error)}`
2499
+ );
2249
2500
  }
2250
2501
  }
2251
2502
  /**
@@ -2254,13 +2505,17 @@ export default ${JSON.stringify(buildConfig, null, 2)};
2254
2505
  async bundleOriginalCliWithTsdown(serverDir) {
2255
2506
  try {
2256
2507
  const { build } = await import("tsdown");
2257
- console.log(simpleChalk.cyan("🔧 Bundling CLI with TSDown for autonomous execution..."));
2508
+ console.log(
2509
+ simpleChalk.cyan("🔧 Bundling CLI with TSDown for autonomous execution...")
2510
+ );
2258
2511
  const configContent = this.getTsdownConfigContent();
2259
2512
  const localConfigPath = path.join(serverDir, "tsdown.config.mjs");
2260
2513
  fs.writeFileSync(localConfigPath, configContent);
2261
2514
  const originalCliPath = path.join(serverDir, "original-cli.mjs");
2262
2515
  if (!fs.existsSync(originalCliPath)) {
2263
- console.warn(simpleChalk.yellow("⚠ Original CLI not found, skipping TSDown bundling"));
2516
+ console.warn(
2517
+ simpleChalk.yellow("⚠ Original CLI not found, skipping TSDown bundling")
2518
+ );
2264
2519
  return null;
2265
2520
  }
2266
2521
  const buildOptions = {
@@ -2281,7 +2536,10 @@ export default ${JSON.stringify(buildConfig, null, 2)};
2281
2536
  outExtension: () => ({ js: ".bundled.mjs" }),
2282
2537
  alias: {
2283
2538
  // Alias chalk to SimpleChalk for autonomous builds
2284
- chalk: path.resolve(process.cwd(), "node_modules/@alcyone-labs/arg-parser/dist/SimpleChalk.mjs")
2539
+ chalk: path.resolve(
2540
+ process.cwd(),
2541
+ "node_modules/@alcyone-labs/arg-parser/dist/SimpleChalk.mjs"
2542
+ )
2285
2543
  },
2286
2544
  external: [
2287
2545
  // Only Node.js built-ins - everything else gets bundled for true autonomy
@@ -2373,8 +2631,15 @@ export default ${JSON.stringify(buildConfig, null, 2)};
2373
2631
  }
2374
2632
  }
2375
2633
  if (bundledPath && bundledFileName) {
2376
- console.log(simpleChalk.green(`✅ TSDown bundling completed successfully: ${bundledFileName}`));
2377
- const expectedBundledPath = path.join(serverDir, "original-cli.bundled.mjs");
2634
+ console.log(
2635
+ simpleChalk.green(
2636
+ `✅ TSDown bundling completed successfully: ${bundledFileName}`
2637
+ )
2638
+ );
2639
+ const expectedBundledPath = path.join(
2640
+ serverDir,
2641
+ "original-cli.bundled.mjs"
2642
+ );
2378
2643
  if (bundledPath !== expectedBundledPath) {
2379
2644
  fs.renameSync(bundledPath, expectedBundledPath);
2380
2645
  bundledFileName = "original-cli.bundled.mjs";
@@ -2386,15 +2651,24 @@ export default ${JSON.stringify(buildConfig, null, 2)};
2386
2651
  try {
2387
2652
  fs.chmodSync(expectedBundledPath, 493);
2388
2653
  } catch (error) {
2389
- console.warn("⚠ Could not set executable permission on bundled file:", error instanceof Error ? error.message : String(error));
2654
+ console.warn(
2655
+ "⚠ Could not set executable permission on bundled file:",
2656
+ error instanceof Error ? error.message : String(error)
2657
+ );
2390
2658
  }
2391
2659
  return bundledFileName;
2392
2660
  } else {
2393
- console.warn(simpleChalk.yellow("⚠ TSDown bundling failed, bundled file not found"));
2661
+ console.warn(
2662
+ simpleChalk.yellow("⚠ TSDown bundling failed, bundled file not found")
2663
+ );
2394
2664
  return null;
2395
2665
  }
2396
2666
  } catch (error) {
2397
- console.warn(simpleChalk.yellow(`⚠ TSDown bundling failed: ${error instanceof Error ? error.message : String(error)}`));
2667
+ console.warn(
2668
+ simpleChalk.yellow(
2669
+ `⚠ TSDown bundling failed: ${error instanceof Error ? error.message : String(error)}`
2670
+ )
2671
+ );
2398
2672
  console.log(simpleChalk.gray(" Falling back to non-bundled approach"));
2399
2673
  return null;
2400
2674
  }
@@ -2449,22 +2723,44 @@ export default ${JSON.stringify(buildConfig, null, 2)};
2449
2723
  */
2450
2724
  getTsdownConfigContent() {
2451
2725
  const currentDir = path.dirname(new URL(import.meta.url).pathname);
2452
- const assetsConfigPath = path.join(currentDir, "..", "assets", "tsdown.dxt.config.ts");
2726
+ const assetsConfigPath = path.join(
2727
+ currentDir,
2728
+ "..",
2729
+ "assets",
2730
+ "tsdown.dxt.config.ts"
2731
+ );
2453
2732
  if (fs.existsSync(assetsConfigPath)) {
2454
2733
  try {
2455
2734
  const content = fs.readFileSync(assetsConfigPath, "utf-8");
2456
- return content.replace('/// <reference types="tsdown" />', "").replace('import { defineConfig } from "tsdown/config";', 'import { defineConfig } from "tsdown";').replace("export default defineConfig(", "export default defineConfig(");
2735
+ return content.replace('/// <reference types="tsdown" />', "").replace(
2736
+ 'import { defineConfig } from "tsdown/config";',
2737
+ 'import { defineConfig } from "tsdown";'
2738
+ ).replace(
2739
+ "export default defineConfig(",
2740
+ "export default defineConfig("
2741
+ );
2457
2742
  } catch (error) {
2458
- console.warn(simpleChalk.yellow("⚠ Could not read TSDown config from assets, using fallback"));
2743
+ console.warn(
2744
+ simpleChalk.yellow(
2745
+ "⚠ Could not read TSDown config from assets, using fallback"
2746
+ )
2747
+ );
2459
2748
  }
2460
2749
  }
2461
2750
  const rootConfigPath = path.join(process.cwd(), "tsdown.dxt.config.ts");
2462
2751
  if (fs.existsSync(rootConfigPath)) {
2463
2752
  try {
2464
2753
  const content = fs.readFileSync(rootConfigPath, "utf-8");
2465
- return content.replace('/// <reference types="tsdown" />', "").replace('import { defineConfig } from "tsdown/config";', 'import { defineConfig } from "tsdown";');
2754
+ return content.replace('/// <reference types="tsdown" />', "").replace(
2755
+ 'import { defineConfig } from "tsdown/config";',
2756
+ 'import { defineConfig } from "tsdown";'
2757
+ );
2466
2758
  } catch (error) {
2467
- console.warn(simpleChalk.yellow("⚠ Could not read TSDown config from root, using default"));
2759
+ console.warn(
2760
+ simpleChalk.yellow(
2761
+ "⚠ Could not read TSDown config from root, using default"
2762
+ )
2763
+ );
2468
2764
  }
2469
2765
  }
2470
2766
  return `import { defineConfig } from "tsdown";
@@ -2495,9 +2791,22 @@ export default defineConfig({
2495
2791
  getDxtIgnoreTemplatePath() {
2496
2792
  const possiblePaths = [
2497
2793
  // 1. From the built library assets (when installed via npm)
2498
- path.join(path.dirname(new URL(import.meta.url).pathname), "..", "assets", ".dxtignore.template"),
2794
+ path.join(
2795
+ path.dirname(new URL(import.meta.url).pathname),
2796
+ "..",
2797
+ "assets",
2798
+ ".dxtignore.template"
2799
+ ),
2499
2800
  // 2. From node_modules/@alcyone-labs/arg-parser/dist/assets (when installed via npm)
2500
- path.join(process.cwd(), "node_modules", "@alcyone-labs", "arg-parser", "dist", "assets", ".dxtignore.template"),
2801
+ path.join(
2802
+ process.cwd(),
2803
+ "node_modules",
2804
+ "@alcyone-labs",
2805
+ "arg-parser",
2806
+ "dist",
2807
+ "assets",
2808
+ ".dxtignore.template"
2809
+ ),
2501
2810
  // 3. From the root directory (development/local build)
2502
2811
  path.join(process.cwd(), ".dxtignore.template"),
2503
2812
  // 4. From the library root (when using local file dependency)
@@ -2513,13 +2822,13 @@ export default defineConfig({
2513
2822
  return "";
2514
2823
  }
2515
2824
  /**
2516
- * Sets up DXT package files (manifest.json) in the dxt output directory
2825
+ * Sets up DXT package files (manifest.json) in the output directory
2517
2826
  */
2518
- async setupDxtPackageFiles(entryPointFile) {
2827
+ async setupDxtPackageFiles(entryPointFile, outputDir = "./dxt", actualOutputFilename) {
2519
2828
  var _a, _b, _c, _d, _e;
2520
- const dxtDir = "./dxt";
2829
+ const dxtDir = path.resolve(process.cwd(), outputDir);
2521
2830
  if (!fs.existsSync(dxtDir)) {
2522
- throw new Error("TSDown output directory (dxt) not found");
2831
+ throw new Error(`TSDown output directory (${outputDir}) not found`);
2523
2832
  }
2524
2833
  const packageJsonPath = path.join(process.cwd(), "package.json");
2525
2834
  let packageInfo = {};
@@ -2538,7 +2847,11 @@ export default defineConfig({
2538
2847
  description: tool.description
2539
2848
  }));
2540
2849
  } catch (error) {
2541
- console.warn(simpleChalk.yellow(`Warning: Could not generate unified tool list: ${error instanceof Error ? error.message : String(error)}`));
2850
+ console.warn(
2851
+ simpleChalk.yellow(
2852
+ `Warning: Could not generate unified tool list: ${error instanceof Error ? error.message : String(error)}`
2853
+ )
2854
+ );
2542
2855
  const mainFlags2 = this.argParserInstance.flags;
2543
2856
  const properties2 = {};
2544
2857
  const required2 = [];
@@ -2559,10 +2872,12 @@ export default defineConfig({
2559
2872
  }
2560
2873
  }
2561
2874
  const commandName = this.argParserInstance.getAppCommandName();
2562
- tools = [{
2563
- name: commandName || packageInfo.name || "cli-tool",
2564
- description: packageInfo.description || this.argParserInstance.getDescription() || "CLI tool"
2565
- }];
2875
+ tools = [
2876
+ {
2877
+ name: commandName || packageInfo.name || "cli-tool",
2878
+ description: packageInfo.description || this.argParserInstance.getDescription() || "CLI tool"
2879
+ }
2880
+ ];
2566
2881
  }
2567
2882
  const envVars = {};
2568
2883
  const userConfig = {};
@@ -2604,7 +2919,18 @@ export default defineConfig({
2604
2919
  }
2605
2920
  }
2606
2921
  const serverInfo = this.extractMcpServerInfo();
2607
- const entryFileName = path.basename(entryPointFile);
2922
+ let logoFilename = "logo.jpg";
2923
+ if (serverInfo == null ? void 0 : serverInfo.logo) {
2924
+ const customLogoFilename = await this.addLogoToFolder(
2925
+ dxtDir,
2926
+ serverInfo,
2927
+ entryPointFile
2928
+ );
2929
+ if (customLogoFilename) {
2930
+ logoFilename = customLogoFilename;
2931
+ }
2932
+ }
2933
+ const entryFileName = actualOutputFilename || path.basename(entryPointFile).replace(/\.ts$/, ".js");
2608
2934
  const manifest = {
2609
2935
  dxt_version: "0.1",
2610
2936
  name: serverInfo.name || packageInfo.name || "mcp-server",
@@ -2620,15 +2946,12 @@ export default defineConfig({
2620
2946
  entry_point: entryFileName,
2621
2947
  mcp_config: {
2622
2948
  command: "node",
2623
- args: [
2624
- `\${__dirname}/${entryFileName}`,
2625
- "--s-mcp-serve"
2626
- ],
2949
+ args: [`\${__dirname}/${entryFileName}`, "--s-mcp-serve"],
2627
2950
  env: envVars
2628
2951
  }
2629
2952
  },
2630
2953
  tools,
2631
- icon: "logo.jpg",
2954
+ icon: logoFilename,
2632
2955
  ...Object.keys(userConfig).length > 0 && { user_config: userConfig },
2633
2956
  repository: {
2634
2957
  type: "git",
@@ -2636,27 +2959,56 @@ export default defineConfig({
2636
2959
  },
2637
2960
  license: packageInfo.license || "MIT"
2638
2961
  };
2639
- fs.writeFileSync(path.join(dxtDir, "manifest.json"), JSON.stringify(manifest, null, 2));
2962
+ fs.writeFileSync(
2963
+ path.join(dxtDir, "manifest.json"),
2964
+ JSON.stringify(manifest, null, 2)
2965
+ );
2640
2966
  console.log(simpleChalk.gray("✅ DXT package files set up"));
2641
2967
  }
2642
2968
  /**
2643
2969
  * Manually copy logo since TSDown's copy option doesn't work programmatically
2644
2970
  */
2645
- async copyLogoManually() {
2646
- const dxtDir = "./dxt";
2971
+ async copyLogoManually(outputDir = "./dxt") {
2972
+ const dxtDir = path.resolve(process.cwd(), outputDir);
2647
2973
  if (!fs.existsSync(dxtDir)) {
2648
- console.warn(simpleChalk.yellow("⚠ DXT directory not found, skipping logo copy"));
2974
+ console.warn(
2975
+ simpleChalk.yellow(
2976
+ `⚠ Output directory (${outputDir}) not found, skipping logo copy`
2977
+ )
2978
+ );
2649
2979
  return;
2650
2980
  }
2651
2981
  const possibleLogoPaths = [
2652
2982
  // From built library assets
2653
- path.join(path.dirname(new URL(import.meta.url).pathname), "..", "assets", "logo_1_small.jpg"),
2983
+ path.join(
2984
+ path.dirname(new URL(import.meta.url).pathname),
2985
+ "..",
2986
+ "assets",
2987
+ "logo_1_small.jpg"
2988
+ ),
2654
2989
  // From node_modules
2655
- path.join(process.cwd(), "node_modules", "@alcyone-labs", "arg-parser", "dist", "assets", "logo_1_small.jpg"),
2990
+ path.join(
2991
+ process.cwd(),
2992
+ "node_modules",
2993
+ "@alcyone-labs",
2994
+ "arg-parser",
2995
+ "dist",
2996
+ "assets",
2997
+ "logo_1_small.jpg"
2998
+ ),
2656
2999
  // From package root dist/assets (for local build)
2657
3000
  path.join(process.cwd(), "dist", "assets", "logo_1_small.jpg"),
2658
3001
  // From library root (development)
2659
- path.join(process.cwd(), "..", "..", "..", "docs", "MCP", "icons", "logo_1_small.jpg")
3002
+ path.join(
3003
+ process.cwd(),
3004
+ "..",
3005
+ "..",
3006
+ "..",
3007
+ "docs",
3008
+ "MCP",
3009
+ "icons",
3010
+ "logo_1_small.jpg"
3011
+ )
2660
3012
  ];
2661
3013
  for (const logoPath of possibleLogoPaths) {
2662
3014
  if (fs.existsSync(logoPath)) {
@@ -2665,12 +3017,78 @@ export default defineConfig({
2665
3017
  console.log(simpleChalk.gray(`✅ Logo copied from: ${logoPath}`));
2666
3018
  return;
2667
3019
  } catch (error) {
2668
- console.warn(simpleChalk.yellow(`⚠ Failed to copy logo from ${logoPath}: ${error}`));
3020
+ console.warn(
3021
+ simpleChalk.yellow(`⚠ Failed to copy logo from ${logoPath}: ${error}`)
3022
+ );
2669
3023
  }
2670
3024
  }
2671
3025
  }
2672
3026
  console.warn(simpleChalk.yellow("⚠ Logo not found in any expected location"));
2673
3027
  }
3028
+ /**
3029
+ * Detects the actual output filename generated by TSDown
3030
+ */
3031
+ detectTsdownOutputFile(outputDir, expectedBaseName) {
3032
+ try {
3033
+ const dxtDir = path.resolve(process.cwd(), outputDir);
3034
+ if (!fs.existsSync(dxtDir)) {
3035
+ console.warn(
3036
+ simpleChalk.yellow(`⚠ Output directory (${outputDir}) not found`)
3037
+ );
3038
+ return null;
3039
+ }
3040
+ const files = fs.readdirSync(dxtDir).filter(
3041
+ (file) => (file.endsWith(".js") || file.endsWith(".mjs")) && !file.includes("chunk-") && !file.includes("dist-") && !file.startsWith(".")
3042
+ );
3043
+ const baseNameWithoutExt = path.parse(expectedBaseName).name;
3044
+ for (const ext of [".js", ".mjs"]) {
3045
+ const exactMatch = `${baseNameWithoutExt}${ext}`;
3046
+ if (files.includes(exactMatch)) {
3047
+ console.log(simpleChalk.gray(`✓ Detected TSDown output: ${exactMatch}`));
3048
+ return exactMatch;
3049
+ }
3050
+ }
3051
+ const mainFiles = files.filter(
3052
+ (file) => !file.includes("chunk") && !file.includes("dist") && file !== "logo.jpg" && file !== "manifest.json"
3053
+ );
3054
+ if (mainFiles.length === 1) {
3055
+ console.log(simpleChalk.gray(`✓ Detected TSDown output: ${mainFiles[0]}`));
3056
+ return mainFiles[0];
3057
+ }
3058
+ if (mainFiles.length > 1) {
3059
+ let bestMatch = mainFiles[0];
3060
+ let bestScore = 0;
3061
+ for (const file of mainFiles) {
3062
+ const filePath = path.join(dxtDir, file);
3063
+ const stats = fs.statSync(filePath);
3064
+ const nameScore = file.includes(baseNameWithoutExt) ? 100 : 0;
3065
+ const sizeScore = Math.min(stats.size / 1e3, 50);
3066
+ const totalScore = nameScore + sizeScore;
3067
+ if (totalScore > bestScore) {
3068
+ bestScore = totalScore;
3069
+ bestMatch = file;
3070
+ }
3071
+ }
3072
+ console.log(
3073
+ simpleChalk.gray(
3074
+ `✓ Detected TSDown output: ${bestMatch} (best match from ${mainFiles.length} candidates)`
3075
+ )
3076
+ );
3077
+ return bestMatch;
3078
+ }
3079
+ console.warn(
3080
+ simpleChalk.yellow(`⚠ Could not detect TSDown output file in ${outputDir}`)
3081
+ );
3082
+ return null;
3083
+ } catch (error) {
3084
+ console.warn(
3085
+ simpleChalk.yellow(
3086
+ `⚠ Error detecting TSDown output: ${error instanceof Error ? error.message : String(error)}`
3087
+ )
3088
+ );
3089
+ return null;
3090
+ }
3091
+ }
2674
3092
  }
2675
3093
  class McpNotificationsManager {
2676
3094
  constructor() {
@@ -2824,10 +3242,16 @@ class McpNotificationsManager {
2824
3242
  sendNotificationToClient(client, type2) {
2825
3243
  try {
2826
3244
  if (client.connection && typeof client.connection.sendNotification === "function") {
2827
- client.connection.sendNotification(`notifications/${type2}/list_changed`, {});
3245
+ client.connection.sendNotification(
3246
+ `notifications/${type2}/list_changed`,
3247
+ {}
3248
+ );
2828
3249
  }
2829
3250
  } catch (error) {
2830
- console.error(`Error sending notification to client ${client.clientId}:`, error);
3251
+ console.error(
3252
+ `Error sending notification to client ${client.clientId}:`,
3253
+ error
3254
+ );
2831
3255
  this.removeClient(client.clientId);
2832
3256
  }
2833
3257
  }
@@ -2916,7 +3340,9 @@ class McpPromptsManager {
2916
3340
  return await entry.config.handler(validatedArgs);
2917
3341
  } catch (error) {
2918
3342
  if (error instanceof z.ZodError) {
2919
- throw new Error(`Invalid arguments for prompt '${name}': ${error.message}`);
3343
+ throw new Error(
3344
+ `Invalid arguments for prompt '${name}': ${error.message}`
3345
+ );
2920
3346
  }
2921
3347
  throw error;
2922
3348
  }
@@ -3116,7 +3542,9 @@ class McpResourcesManager {
3116
3542
  try {
3117
3543
  new ResourceTemplateParser(config.uriTemplate);
3118
3544
  } catch (error) {
3119
- throw new Error(`Invalid URI template '${config.uriTemplate}': ${error instanceof Error ? error.message : String(error)}`);
3545
+ throw new Error(
3546
+ `Invalid URI template '${config.uriTemplate}': ${error instanceof Error ? error.message : String(error)}`
3547
+ );
3120
3548
  }
3121
3549
  }
3122
3550
  /**
@@ -3221,6 +3649,97 @@ const _FlagManager = class _FlagManager {
3221
3649
  __flags = new WeakMap();
3222
3650
  _throwForDuplicateFlags = new WeakMap();
3223
3651
  let FlagManager = _FlagManager;
3652
+ function detectEntryPoint() {
3653
+ try {
3654
+ if (process.argv[1] && fs.existsSync(process.argv[1])) {
3655
+ return process.argv[1];
3656
+ }
3657
+ if (typeof require !== "undefined" && require.main && require.main.filename) {
3658
+ return require.main.filename;
3659
+ }
3660
+ return null;
3661
+ } catch {
3662
+ return null;
3663
+ }
3664
+ }
3665
+ function getEntryPointFromImportMeta(importMetaUrl) {
3666
+ if (importMetaUrl.startsWith("file://")) {
3667
+ return decodeURIComponent(importMetaUrl.replace("file://", ""));
3668
+ }
3669
+ return importMetaUrl;
3670
+ }
3671
+ function normalizePath(path2) {
3672
+ return path2.trim();
3673
+ }
3674
+ function resolveLogPath(logPath, fallbackEntryPoint) {
3675
+ if (typeof logPath === "string") {
3676
+ const normalizedPath2 = normalizePath(logPath);
3677
+ if (path.isAbsolute(normalizedPath2)) {
3678
+ return normalizedPath2;
3679
+ }
3680
+ if (normalizedPath2.startsWith("cwd:")) {
3681
+ const relativePath = normalizedPath2.slice(4);
3682
+ return path.resolve(process.cwd(), relativePath);
3683
+ }
3684
+ const entryPoint = detectEntryPoint() || fallbackEntryPoint;
3685
+ if (entryPoint) {
3686
+ return path.resolve(path.dirname(entryPoint), normalizedPath2);
3687
+ }
3688
+ console.warn(
3689
+ `Warning: Could not detect entry point for log path resolution. Using process.cwd() as fallback. Path: ${normalizedPath2}`
3690
+ );
3691
+ return path.resolve(process.cwd(), normalizedPath2);
3692
+ }
3693
+ const { path: logFilePath, relativeTo = "entry", basePath } = logPath;
3694
+ const normalizedPath = normalizePath(logFilePath);
3695
+ switch (relativeTo) {
3696
+ case "absolute":
3697
+ if (basePath) {
3698
+ return path.resolve(basePath, normalizedPath);
3699
+ }
3700
+ if (path.isAbsolute(normalizedPath)) {
3701
+ return normalizedPath;
3702
+ }
3703
+ console.warn(
3704
+ `Warning: relativeTo 'absolute' specified but no basePath provided and path is not absolute. Using process.cwd() as fallback. Path: ${normalizedPath}`
3705
+ );
3706
+ return path.resolve(process.cwd(), normalizedPath);
3707
+ case "cwd":
3708
+ return path.resolve(process.cwd(), normalizedPath);
3709
+ case "entry":
3710
+ default:
3711
+ const entryPoint = detectEntryPoint() || fallbackEntryPoint;
3712
+ if (entryPoint) {
3713
+ return path.resolve(path.dirname(entryPoint), normalizedPath);
3714
+ }
3715
+ console.warn(
3716
+ `Warning: Could not detect entry point for log path resolution. Using process.cwd() as fallback. Path: ${normalizedPath}`
3717
+ );
3718
+ return path.resolve(process.cwd(), normalizedPath);
3719
+ }
3720
+ }
3721
+ function entryRelative(path2) {
3722
+ return {
3723
+ path: path2,
3724
+ relativeTo: "entry"
3725
+ };
3726
+ }
3727
+ function cwdRelative(path2) {
3728
+ return {
3729
+ path: path2,
3730
+ relativeTo: "cwd"
3731
+ };
3732
+ }
3733
+ function absolutePath(path2, basePath) {
3734
+ return {
3735
+ path: path2,
3736
+ relativeTo: "absolute",
3737
+ basePath
3738
+ };
3739
+ }
3740
+ function legacyCwdPath(path2) {
3741
+ return `cwd:${path2}`;
3742
+ }
3224
3743
  class ArgParserError extends Error {
3225
3744
  constructor(message, cmdChain = []) {
3226
3745
  super(message);
@@ -3349,7 +3868,7 @@ const _ArgParserBase = class _ArgParserBase {
3349
3868
  getSubCommands() {
3350
3869
  return __privateGet(this, _subCommands);
3351
3870
  }
3352
- _addToOutput(flag, arg, output, _parseOptions) {
3871
+ async _addToOutput(flag, arg, output, _parseOptions) {
3353
3872
  let value = arg;
3354
3873
  if (flag["type"] === Boolean) {
3355
3874
  if (typeof arg === "boolean") {
@@ -3360,7 +3879,8 @@ const _ArgParserBase = class _ArgParserBase {
3360
3879
  value = new flag["type"](value);
3361
3880
  }
3362
3881
  } else if (typeof flag["type"] === "function") {
3363
- value = flag["type"](value);
3882
+ const result = flag["type"](value);
3883
+ value = result && typeof result.then === "function" ? await result : result;
3364
3884
  } else if (typeof flag["type"] === "object") {
3365
3885
  value = new flag["type"](value);
3366
3886
  }
@@ -3473,7 +3993,26 @@ const _ArgParserBase = class _ArgParserBase {
3473
3993
  }
3474
3994
  }
3475
3995
  async parse(processArgs, options) {
3476
- var _a;
3996
+ var _a, _b;
3997
+ if (processArgs === void 0) {
3998
+ if (typeof process !== "undefined" && process.argv && Array.isArray(process.argv)) {
3999
+ processArgs = process.argv.slice(2);
4000
+ const isCliMode = !__privateGet(this, _parentParser) && !!__privateGet(this, _appCommandName);
4001
+ const isMcpMode = (options == null ? void 0 : options.isMcp) || ((_a = globalThis.console) == null ? void 0 : _a.mcpError);
4002
+ if (isCliMode && !isMcpMode) {
4003
+ console.warn(
4004
+ `Warning: parse() called without arguments. Auto-detected Node.js environment and using process.argv.slice(2).`
4005
+ );
4006
+ console.warn(
4007
+ `For explicit control, call parse(process.argv.slice(2)) instead.`
4008
+ );
4009
+ }
4010
+ } else {
4011
+ throw new Error(
4012
+ "parse() called without arguments in non-Node.js environment. Please provide arguments explicitly: parse(['--flag', 'value'])"
4013
+ );
4014
+ }
4015
+ }
3477
4016
  const originalProcessArgs = [...processArgs];
3478
4017
  const shouldPreventExecution = typeof process !== "undefined" && (process.env["ARGPARSER_FUZZY_MODE"] === "true" || process.argv && process.argv.includes("--s-enable-fuzzy") && !processArgs.includes("--s-enable-fuzzy")) && !(options == null ? void 0 : options.skipHelpHandling);
3479
4018
  if (shouldPreventExecution) {
@@ -3492,11 +4031,11 @@ const _ArgParserBase = class _ArgParserBase {
3492
4031
  commandChain: identifiedCommandChain,
3493
4032
  parserChain: identifiedParserChain
3494
4033
  } = __privateMethod(this, _ArgParserBase_instances, _identifyCommandChainAndParsers_fn).call(this, processArgs, this, [], [this]);
3495
- const saveToEnvResult = __privateMethod(_a = identifiedFinalParser, _ArgParserBase_instances, _handleSaveToEnvFlag_fn).call(_a, processArgs, identifiedParserChain);
4034
+ const saveToEnvResult = __privateMethod(_b = identifiedFinalParser, _ArgParserBase_instances, _handleSaveToEnvFlag_fn).call(_b, processArgs, identifiedParserChain);
3496
4035
  if (saveToEnvResult !== false) {
3497
4036
  return saveToEnvResult === true ? {} : saveToEnvResult;
3498
4037
  }
3499
- const { finalArgs, handlerToExecute } = this._parseRecursive(
4038
+ const { finalArgs, handlerToExecute } = await this._parseRecursive(
3500
4039
  processArgs,
3501
4040
  this,
3502
4041
  {},
@@ -3560,7 +4099,7 @@ const _ArgParserBase = class _ArgParserBase {
3560
4099
  * Recursive helper for parsing arguments and handling sub-commands.
3561
4100
  * This method assumes the global help check has already been performed in `parse`.
3562
4101
  */
3563
- _parseRecursive(argsToParse, currentParser, accumulatedParentArgs, commandChainSoFar, options, parentParser) {
4102
+ async _parseRecursive(argsToParse, currentParser, accumulatedParentArgs, commandChainSoFar, options, parentParser) {
3564
4103
  var _a, _b;
3565
4104
  let subCommandIndex = -1;
3566
4105
  let subCommandName = null;
@@ -3573,7 +4112,7 @@ const _ArgParserBase = class _ArgParserBase {
3573
4112
  }
3574
4113
  }
3575
4114
  const argsForCurrentLevel = subCommandIndex === -1 ? argsToParse : argsToParse.slice(0, subCommandIndex);
3576
- const { parsedArgs: currentLevelArgs, firstUnconsumedIndex } = __privateMethod(_a = currentParser, _ArgParserBase_instances, parseFlags_fn).call(_a, argsForCurrentLevel, options);
4115
+ const { parsedArgs: currentLevelArgs, firstUnconsumedIndex } = await __privateMethod(_a = currentParser, _ArgParserBase_instances, parseFlags_fn).call(_a, argsForCurrentLevel, options);
3577
4116
  __privateMethod(_b = currentParser, _ArgParserBase_instances, _applyDefaultValues_fn).call(_b, currentLevelArgs, currentParser);
3578
4117
  const combinedArgsFromThisAndParents = {
3579
4118
  ...accumulatedParentArgs,
@@ -3627,7 +4166,7 @@ const _ArgParserBase = class _ArgParserBase {
3627
4166
  ...accumulatedParentArgs,
3628
4167
  ...currentLevelArgs
3629
4168
  };
3630
- return this._parseRecursive(
4169
+ return await this._parseRecursive(
3631
4170
  nextArgs,
3632
4171
  nextParser,
3633
4172
  combinedArgsForNextLevel,
@@ -4030,7 +4569,7 @@ _handleGlobalChecks_fn = async function(processArgs, options) {
4030
4569
  const rootArgsSlice = rootSubCommandIndex === -1 ? remainingArgs : remainingArgs.slice(0, rootSubCommandIndex);
4031
4570
  parsingSteps.push({ level: "(root)", argsSlice: rootArgsSlice });
4032
4571
  try {
4033
- const { parsedArgs: rootParsedArgs } = __privateMethod(_a = currentParser, _ArgParserBase_instances, parseFlags_fn).call(_a, rootArgsSlice, { skipHelpHandling: true });
4572
+ const { parsedArgs: rootParsedArgs } = await __privateMethod(_a = currentParser, _ArgParserBase_instances, parseFlags_fn).call(_a, rootArgsSlice, { skipHelpHandling: true });
4034
4573
  parsingSteps[0].parsed = rootParsedArgs;
4035
4574
  accumulatedArgs = { ...accumulatedArgs, ...rootParsedArgs };
4036
4575
  } catch (e) {
@@ -4059,7 +4598,7 @@ _handleGlobalChecks_fn = async function(processArgs, options) {
4059
4598
  };
4060
4599
  parsingSteps.push(stepInfo);
4061
4600
  try {
4062
- const { parsedArgs: currentLevelParsedArgs } = __privateMethod(_c = currentParser, _ArgParserBase_instances, parseFlags_fn).call(_c, currentLevelArgsSlice, {
4601
+ const { parsedArgs: currentLevelParsedArgs } = await __privateMethod(_c = currentParser, _ArgParserBase_instances, parseFlags_fn).call(_c, currentLevelArgsSlice, {
4063
4602
  skipHelpHandling: true
4064
4603
  });
4065
4604
  stepInfo.parsed = currentLevelParsedArgs;
@@ -4245,7 +4784,7 @@ _prepareAndExecuteHandler_fn = function(handlerToExecute, finalArgs, skipHandler
4245
4784
  }
4246
4785
  }
4247
4786
  };
4248
- parseFlags_fn = function(args, options) {
4787
+ parseFlags_fn = async function(args, options) {
4249
4788
  var _a, _b;
4250
4789
  const flags = __privateGet(this, _flagManager).flags;
4251
4790
  const output = Object.fromEntries(
@@ -4268,7 +4807,7 @@ parseFlags_fn = function(args, options) {
4268
4807
  const itemToCheck = args[i];
4269
4808
  const matches = regex.exec(`${itemToCheck}`);
4270
4809
  if ((_a = matches == null ? void 0 : matches.groups) == null ? void 0 : _a["arg"]) {
4271
- this._addToOutput(
4810
+ await this._addToOutput(
4272
4811
  flagToCheck,
4273
4812
  (_b = matches == null ? void 0 : matches.groups) == null ? void 0 : _b["arg"],
4274
4813
  output,
@@ -4291,12 +4830,12 @@ parseFlags_fn = function(args, options) {
4291
4830
  if (flagToCheck["options"].includes(value)) {
4292
4831
  consumedIndices.add(index2);
4293
4832
  if (flagToCheck["flagOnly"]) {
4294
- this._addToOutput(flagToCheck, true, output, options);
4833
+ await this._addToOutput(flagToCheck, true, output, options);
4295
4834
  } else if (nextValueExists && !nextValueIsFlag) {
4296
- this._addToOutput(flagToCheck, nextValue, output, options);
4835
+ await this._addToOutput(flagToCheck, nextValue, output, options);
4297
4836
  consumedIndices.add(nextIndex);
4298
4837
  } else if (flagToCheck["type"] === Boolean) {
4299
- this._addToOutput(flagToCheck, true, output, options);
4838
+ await this._addToOutput(flagToCheck, true, output, options);
4300
4839
  }
4301
4840
  if (!flagToCheck["allowMultiple"]) break;
4302
4841
  }
@@ -4598,15 +5137,16 @@ _handleBuildDxtFlag_fn = async function(processArgs, buildDxtIndex) {
4598
5137
  };
4599
5138
  _handleMcpServeFlag_fn = async function(processArgs, _mcpServeIndex) {
4600
5139
  var _a;
5140
+ const transportOptions = __privateMethod(this, _ArgParserBase_instances, _parseMcpTransportOptions_fn).call(this, processArgs);
5141
+ const mcpServerConfig = __privateMethod(this, _ArgParserBase_instances, _getMcpServerConfiguration_fn).call(this);
5142
+ const effectiveLogPath = transportOptions.logPath || (mcpServerConfig == null ? void 0 : mcpServerConfig.logPath) || "./logs/mcp.log";
5143
+ const resolvedLogPath = resolveLogPath(effectiveLogPath);
4601
5144
  let mcpLogger;
4602
5145
  try {
4603
5146
  const mcpLoggerModule = await Function(
4604
5147
  'return import("@alcyone-labs/simple-mcp-logger")'
4605
5148
  )();
4606
- mcpLogger = mcpLoggerModule.createMcpLogger(
4607
- "MCP Serve",
4608
- "./logs/mcp.log"
4609
- );
5149
+ mcpLogger = mcpLoggerModule.createMcpLogger("MCP Serve", resolvedLogPath);
4610
5150
  globalThis.console = mcpLogger;
4611
5151
  } catch {
4612
5152
  mcpLogger = {
@@ -4617,7 +5157,6 @@ _handleMcpServeFlag_fn = async function(processArgs, _mcpServeIndex) {
4617
5157
  mcpLogger.mcpError(
4618
5158
  "Starting --s-mcp-serve system flag handler - console hijacked for MCP safety"
4619
5159
  );
4620
- const mcpServerConfig = __privateMethod(this, _ArgParserBase_instances, _getMcpServerConfiguration_fn).call(this);
4621
5160
  if (!mcpServerConfig) {
4622
5161
  mcpLogger.mcpError(
4623
5162
  "No MCP server configuration found. Use withMcp() or addMcpSubCommand() to configure MCP server."
@@ -4631,13 +5170,16 @@ _handleMcpServeFlag_fn = async function(processArgs, _mcpServeIndex) {
4631
5170
  mcpLogger.mcpError(
4632
5171
  `Found MCP server configuration: ${((_a = mcpServerConfig.serverInfo) == null ? void 0 : _a.name) || "unnamed"}`
4633
5172
  );
4634
- const transportOptions = __privateMethod(this, _ArgParserBase_instances, _parseMcpTransportOptions_fn).call(this, processArgs);
5173
+ mcpLogger.mcpError(`Using log path: ${resolvedLogPath}`);
4635
5174
  mcpLogger.mcpError(
4636
5175
  `Transport options: ${JSON.stringify(transportOptions)}`
4637
5176
  );
4638
5177
  try {
4639
5178
  mcpLogger.mcpError("Starting unified MCP server with all tools");
4640
- await __privateMethod(this, _ArgParserBase_instances, _startUnifiedMcpServer_fn).call(this, mcpServerConfig, transportOptions);
5179
+ await __privateMethod(this, _ArgParserBase_instances, _startUnifiedMcpServer_fn).call(this, mcpServerConfig, {
5180
+ ...transportOptions,
5181
+ logPath: resolvedLogPath
5182
+ });
4641
5183
  mcpLogger.mcpError("Successfully started unified MCP server");
4642
5184
  } catch (error) {
4643
5185
  mcpLogger.mcpError(
@@ -4706,7 +5248,8 @@ _startUnifiedMcpServer_fn = async function(mcpServerConfig, transportOptions) {
4706
5248
  await mcpParser.startMcpServerWithMultipleTransports(
4707
5249
  serverInfo,
4708
5250
  transportConfigs,
4709
- toolOptions
5251
+ toolOptions,
5252
+ transportOptions.logPath
4710
5253
  );
4711
5254
  } catch (error) {
4712
5255
  throw new Error(
@@ -4717,7 +5260,8 @@ _startUnifiedMcpServer_fn = async function(mcpServerConfig, transportOptions) {
4717
5260
  await mcpParser.startMcpServerWithMultipleTransports(
4718
5261
  serverInfo,
4719
5262
  defaultTransports,
4720
- toolOptions
5263
+ toolOptions,
5264
+ transportOptions.logPath
4721
5265
  );
4722
5266
  } else if (defaultTransport) {
4723
5267
  await mcpParser.startMcpServerWithTransport(
@@ -4729,7 +5273,8 @@ _startUnifiedMcpServer_fn = async function(mcpServerConfig, transportOptions) {
4729
5273
  path: defaultTransport.path,
4730
5274
  sessionIdGenerator: defaultTransport.sessionIdGenerator
4731
5275
  },
4732
- toolOptions
5276
+ toolOptions,
5277
+ transportOptions.logPath
4733
5278
  );
4734
5279
  } else {
4735
5280
  const transportType = transportOptions.transportType || "stdio";
@@ -4742,7 +5287,8 @@ _startUnifiedMcpServer_fn = async function(mcpServerConfig, transportOptions) {
4742
5287
  serverInfo,
4743
5288
  transportType,
4744
5289
  finalTransportOptions,
4745
- toolOptions
5290
+ toolOptions,
5291
+ transportOptions.logPath
4746
5292
  );
4747
5293
  }
4748
5294
  };
@@ -4809,6 +5355,12 @@ _parseMcpTransportOptions_fn = function(processArgs) {
4809
5355
  i++;
4810
5356
  }
4811
5357
  break;
5358
+ case "--s-mcp-log-path":
5359
+ if (nextArg && !nextArg.startsWith("-")) {
5360
+ options.logPath = nextArg;
5361
+ i++;
5362
+ }
5363
+ break;
4812
5364
  // Backward compatibility: support old flags but with deprecation warning
4813
5365
  case "--transport":
4814
5366
  case "--port":
@@ -6094,11 +6646,14 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
6094
6646
  * @param toolOptions Optional MCP tool generation options
6095
6647
  * @returns Configured MCP server instance
6096
6648
  */
6097
- async createMcpServer(serverInfo, toolOptions) {
6098
- var _a;
6099
- const logger2 = createMcpLogger("MCP Server Creation", "./logs/mcp.log");
6649
+ async createMcpServer(serverInfo, toolOptions, logPath) {
6650
+ var _a, _b;
6651
+ const resolvedLogPath = resolveLogPath(
6652
+ logPath || ((_a = this._mcpServerConfig) == null ? void 0 : _a.logPath) || "./logs/mcp.log"
6653
+ );
6654
+ const logger2 = createMcpLogger("MCP Server Creation", resolvedLogPath);
6100
6655
  try {
6101
- const effectiveServerInfo = serverInfo || ((_a = this._mcpServerConfig) == null ? void 0 : _a.serverInfo);
6656
+ const effectiveServerInfo = serverInfo || ((_b = this._mcpServerConfig) == null ? void 0 : _b.serverInfo);
6102
6657
  if (!effectiveServerInfo) {
6103
6658
  throw new Error(
6104
6659
  "No MCP server configuration found. Use withMcp() to configure server info or provide serverInfo parameter."
@@ -6279,11 +6834,11 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
6279
6834
  * @param toolOptions Optional MCP tool generation options
6280
6835
  * @returns Promise that resolves when all servers are started
6281
6836
  */
6282
- async startMcpServerWithMultipleTransports(serverInfo, transports, toolOptions) {
6283
- const server = await this.createMcpServer(serverInfo, toolOptions);
6837
+ async startMcpServerWithMultipleTransports(serverInfo, transports, toolOptions, logPath) {
6838
+ const server = await this.createMcpServer(serverInfo, toolOptions, logPath);
6284
6839
  const startPromises = [];
6285
6840
  for (const transportConfig of transports) {
6286
- const promise = __privateMethod(this, _ArgParser_instances, _startSingleTransport_fn).call(this, server, serverInfo, transportConfig);
6841
+ const promise = __privateMethod(this, _ArgParser_instances, _startSingleTransport_fn).call(this, server, serverInfo, transportConfig, logPath);
6287
6842
  startPromises.push(promise);
6288
6843
  }
6289
6844
  await Promise.all(startPromises);
@@ -6296,12 +6851,12 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
6296
6851
  * @param toolOptions Optional MCP tool generation options
6297
6852
  * @returns Promise that resolves when server is connected
6298
6853
  */
6299
- async startMcpServerWithTransport(serverInfo, transportType, transportOptions = {}, toolOptions) {
6300
- const server = await this.createMcpServer(serverInfo, toolOptions);
6854
+ async startMcpServerWithTransport(serverInfo, transportType, transportOptions = {}, toolOptions, logPath) {
6855
+ const server = await this.createMcpServer(serverInfo, toolOptions, logPath);
6301
6856
  await __privateMethod(this, _ArgParser_instances, _startSingleTransport_fn).call(this, server, serverInfo, {
6302
6857
  type: transportType,
6303
6858
  ...transportOptions
6304
- });
6859
+ }, logPath);
6305
6860
  }
6306
6861
  async parse(processArgs, options) {
6307
6862
  let result = await ArgParserBase.prototype.parse.call(
@@ -6563,8 +7118,9 @@ registerToolAsSubCommand_fn = function(toolConfig) {
6563
7118
  handler: toolConfig.handler
6564
7119
  });
6565
7120
  };
6566
- _startSingleTransport_fn = async function(server, serverInfo, transportConfig) {
6567
- const logger2 = createMcpLogger("MCP Transport", "./logs/mcp.log");
7121
+ _startSingleTransport_fn = async function(server, serverInfo, transportConfig, logPath) {
7122
+ const resolvedLogPath = resolveLogPath(logPath || "./logs/mcp.log");
7123
+ const logger2 = createMcpLogger("MCP Transport", resolvedLogPath);
6568
7124
  try {
6569
7125
  logger2.mcpError(
6570
7126
  `Starting ${transportConfig.type} transport for server: ${serverInfo.name}`
@@ -6740,7 +7296,9 @@ class TomlConfigPlugin extends ConfigPlugin {
6740
7296
  }
6741
7297
  return parsed;
6742
7298
  } catch (error) {
6743
- throw new Error(`Failed to parse TOML: ${error instanceof Error ? error.message : String(error)}`);
7299
+ throw new Error(
7300
+ `Failed to parse TOML: ${error instanceof Error ? error.message : String(error)}`
7301
+ );
6744
7302
  }
6745
7303
  }
6746
7304
  generate(_config, flags, parsedArgs) {
@@ -6780,7 +7338,9 @@ class TomlConfigPlugin extends ConfigPlugin {
6780
7338
  const tomlContent = this.tomlModule.stringify(configWithValues);
6781
7339
  return lines.join("\n") + "\n" + tomlContent;
6782
7340
  } catch (error) {
6783
- throw new Error(`Failed to generate TOML: ${error instanceof Error ? error.message : String(error)}`);
7341
+ throw new Error(
7342
+ `Failed to generate TOML: ${error instanceof Error ? error.message : String(error)}`
7343
+ );
6784
7344
  }
6785
7345
  }
6786
7346
  /**
@@ -6816,7 +7376,10 @@ function createTomlPlugin() {
6816
7376
  try {
6817
7377
  return new TomlConfigPlugin();
6818
7378
  } catch (error) {
6819
- console.warn("TOML plugin not available:", error instanceof Error ? error.message : String(error));
7379
+ console.warn(
7380
+ "TOML plugin not available:",
7381
+ error instanceof Error ? error.message : String(error)
7382
+ );
6820
7383
  return null;
6821
7384
  }
6822
7385
  }
@@ -6832,7 +7395,10 @@ async function createTomlPluginAsync() {
6832
7395
  const tomlModule = await Promise.resolve().then(() => index$1);
6833
7396
  return new TomlConfigPlugin(tomlModule);
6834
7397
  } catch (error) {
6835
- console.warn("TOML plugin not available:", error instanceof Error ? error.message : String(error));
7398
+ console.warn(
7399
+ "TOML plugin not available:",
7400
+ error instanceof Error ? error.message : String(error)
7401
+ );
6836
7402
  return null;
6837
7403
  }
6838
7404
  }
@@ -6878,7 +7444,9 @@ class YamlConfigPlugin extends ConfigPlugin {
6878
7444
  }
6879
7445
  return parsed;
6880
7446
  } catch (error) {
6881
- throw new Error(`Failed to parse YAML: ${error instanceof Error ? error.message : String(error)}`);
7447
+ throw new Error(
7448
+ `Failed to parse YAML: ${error instanceof Error ? error.message : String(error)}`
7449
+ );
6882
7450
  }
6883
7451
  }
6884
7452
  generate(_config, flags, parsedArgs) {
@@ -6912,7 +7480,9 @@ class YamlConfigPlugin extends ConfigPlugin {
6912
7480
  });
6913
7481
  return lines.join("\n") + "\n" + yamlContent;
6914
7482
  } catch (error) {
6915
- throw new Error(`Failed to generate YAML: ${error instanceof Error ? error.message : String(error)}`);
7483
+ throw new Error(
7484
+ `Failed to generate YAML: ${error instanceof Error ? error.message : String(error)}`
7485
+ );
6916
7486
  }
6917
7487
  }
6918
7488
  /**
@@ -6942,7 +7512,10 @@ function createYamlPlugin() {
6942
7512
  try {
6943
7513
  return new YamlConfigPlugin();
6944
7514
  } catch (error) {
6945
- console.warn("YAML plugin not available:", error instanceof Error ? error.message : String(error));
7515
+ console.warn(
7516
+ "YAML plugin not available:",
7517
+ error instanceof Error ? error.message : String(error)
7518
+ );
6946
7519
  return null;
6947
7520
  }
6948
7521
  }
@@ -6958,7 +7531,10 @@ async function createYamlPluginAsync() {
6958
7531
  const yamlModule = await import("js-yaml");
6959
7532
  return new YamlConfigPlugin(yamlModule);
6960
7533
  } catch (error) {
6961
- console.warn("YAML plugin not available:", error instanceof Error ? error.message : String(error));
7534
+ console.warn(
7535
+ "YAML plugin not available:",
7536
+ error instanceof Error ? error.message : String(error)
7537
+ );
6962
7538
  return null;
6963
7539
  }
6964
7540
  }
@@ -6987,7 +7563,9 @@ class ArgParserFuzzyTester {
6987
7563
  const results = [];
6988
7564
  if (this.options.verbose) {
6989
7565
  console.log(`Discovered ${commandPaths.length} command paths:`);
6990
- commandPaths.forEach((path2) => console.log(` ${path2.join(" ") || "(root)"}`));
7566
+ commandPaths.forEach(
7567
+ (path2) => console.log(` ${path2.join(" ") || "(root)"}`)
7568
+ );
6991
7569
  }
6992
7570
  for (const commandPath of commandPaths) {
6993
7571
  const pathResults = await this.testCommandPath(commandPath);
@@ -7013,7 +7591,12 @@ class ArgParserFuzzyTester {
7013
7591
  for (const [subCommandName, subCommand] of subCommands) {
7014
7592
  const newPath = [...currentPath, subCommandName];
7015
7593
  allPaths.push(newPath);
7016
- this.discoverSubCommandPaths(subCommand.parser, newPath, allPaths, depth + 1);
7594
+ this.discoverSubCommandPaths(
7595
+ subCommand.parser,
7596
+ newPath,
7597
+ allPaths,
7598
+ depth + 1
7599
+ );
7017
7600
  }
7018
7601
  }
7019
7602
  /**
@@ -24905,6 +25488,7 @@ export {
24905
25488
  simpleChalk as SimpleChalk,
24906
25489
  TomlConfigPlugin,
24907
25490
  YamlConfigPlugin,
25491
+ absolutePath,
24908
25492
  convertFlagToJsonSchemaProperty,
24909
25493
  convertFlagsToJsonSchema,
24910
25494
  convertFlagsToZodSchema,
@@ -24918,14 +25502,20 @@ export {
24918
25502
  createTomlPluginAsync,
24919
25503
  createYamlPlugin,
24920
25504
  createYamlPluginAsync,
25505
+ cwdRelative,
25506
+ detectEntryPoint,
24921
25507
  enableConfigPlugins,
24922
25508
  enableOptionalConfigPlugins,
24923
25509
  enableOptionalConfigPluginsAsync,
25510
+ entryRelative,
24924
25511
  extractSimplifiedResponse,
24925
25512
  generateMcpToolsFromArgParser,
25513
+ getEntryPointFromImportMeta,
24926
25514
  getJsonSchemaTypeFromFlag,
24927
25515
  globalConfigPluginRegistry,
25516
+ legacyCwdPath,
24928
25517
  logger,
25518
+ resolveLogPath,
24929
25519
  zodFlagSchema
24930
25520
  };
24931
25521
  //# sourceMappingURL=index.mjs.map