@alcyone-labs/arg-parser 2.2.0 → 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.
- package/README.md +97 -17
- package/dist/config/ConfigurationManager.d.ts.map +1 -1
- package/dist/config/plugins/ConfigPlugin.d.ts.map +1 -1
- package/dist/config/plugins/ConfigPluginRegistry.d.ts +1 -1
- package/dist/config/plugins/ConfigPluginRegistry.d.ts.map +1 -1
- package/dist/config/plugins/TomlConfigPlugin.d.ts +1 -1
- package/dist/config/plugins/TomlConfigPlugin.d.ts.map +1 -1
- package/dist/config/plugins/YamlConfigPlugin.d.ts +1 -1
- package/dist/config/plugins/YamlConfigPlugin.d.ts.map +1 -1
- package/dist/config/plugins/index.d.ts +4 -4
- package/dist/config/plugins/index.d.ts.map +1 -1
- package/dist/core/ArgParser.d.ts +14 -3
- package/dist/core/ArgParser.d.ts.map +1 -1
- package/dist/core/ArgParserBase.d.ts.map +1 -1
- package/dist/core/log-path-utils.d.ts +59 -0
- package/dist/core/log-path-utils.d.ts.map +1 -0
- package/dist/core/types.d.ts +1 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/dxt/DxtGenerator.d.ts +4 -0
- package/dist/dxt/DxtGenerator.d.ts.map +1 -1
- package/dist/index.cjs +722 -168
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.min.mjs +4232 -3738
- package/dist/index.min.mjs.map +1 -1
- package/dist/index.mjs +722 -168
- package/dist/index.mjs.map +1 -1
- package/dist/mcp/ArgParserMcp.d.ts.map +1 -1
- package/dist/mcp/mcp-notifications.d.ts +4 -4
- package/dist/mcp/mcp-notifications.d.ts.map +1 -1
- package/dist/mcp/mcp-prompts.d.ts.map +1 -1
- package/dist/mcp/mcp-protocol-versions.d.ts +11 -11
- package/dist/mcp/mcp-protocol-versions.d.ts.map +1 -1
- package/dist/mcp/mcp-resources.d.ts.map +1 -1
- package/dist/testing/fuzzy-test-cli.d.ts.map +1 -1
- package/dist/testing/fuzzy-tester.d.ts.map +1 -1
- 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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
618
|
+
console.log(
|
|
619
|
+
simpleChalk.gray(`Flags saved: ${Object.keys(parsedArgs.args).length}`)
|
|
620
|
+
);
|
|
605
621
|
} catch (error) {
|
|
606
|
-
console.error(
|
|
607
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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")
|
|
822
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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}"`);
|
|
@@ -1176,24 +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(
|
|
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(
|
|
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
1241
|
const outputDir = processArgs[buildDxtIndex + 1] || "./dxt";
|
|
1187
|
-
console.log(
|
|
1188
|
-
|
|
1242
|
+
console.log(
|
|
1243
|
+
simpleChalk.cyan(
|
|
1244
|
+
`
|
|
1245
|
+
🔧 Building DXT package for entry point: ${path.basename(entryPointFile)}`
|
|
1246
|
+
)
|
|
1247
|
+
);
|
|
1189
1248
|
console.log(simpleChalk.gray(`Output directory: ${outputDir}`));
|
|
1190
1249
|
await this.buildDxtWithTsdown(entryPointFile, outputDir);
|
|
1191
1250
|
console.log(simpleChalk.green(`
|
|
1192
1251
|
✅ DXT package generation completed!`));
|
|
1193
|
-
return this._handleExit(
|
|
1252
|
+
return this._handleExit(
|
|
1253
|
+
0,
|
|
1254
|
+
"DXT package generation completed",
|
|
1255
|
+
"success",
|
|
1256
|
+
{ entryPoint: entryPointFile, outputDir }
|
|
1257
|
+
);
|
|
1194
1258
|
} catch (error) {
|
|
1195
|
-
console.error(
|
|
1196
|
-
|
|
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
|
+
);
|
|
1197
1269
|
}
|
|
1198
1270
|
}
|
|
1199
1271
|
/**
|
|
@@ -1233,7 +1305,10 @@ class DxtGenerator {
|
|
|
1233
1305
|
})),
|
|
1234
1306
|
icon: "logo.jpg"
|
|
1235
1307
|
};
|
|
1236
|
-
fs.writeFileSync(
|
|
1308
|
+
fs.writeFileSync(
|
|
1309
|
+
path.join(buildDir, "manifest.json"),
|
|
1310
|
+
JSON.stringify(manifest, null, 2)
|
|
1311
|
+
);
|
|
1237
1312
|
const packageJson = {
|
|
1238
1313
|
name: serverInfo.name,
|
|
1239
1314
|
version: serverInfo.version,
|
|
@@ -1241,7 +1316,10 @@ class DxtGenerator {
|
|
|
1241
1316
|
main: "index.mjs",
|
|
1242
1317
|
type: "module"
|
|
1243
1318
|
};
|
|
1244
|
-
fs.writeFileSync(
|
|
1319
|
+
fs.writeFileSync(
|
|
1320
|
+
path.join(buildDir, "package.json"),
|
|
1321
|
+
JSON.stringify(packageJson, null, 2)
|
|
1322
|
+
);
|
|
1245
1323
|
const readme = `# ${serverInfo.name}
|
|
1246
1324
|
|
|
1247
1325
|
${serverInfo.description}
|
|
@@ -1250,13 +1328,25 @@ Generated by @alcyone-labs/arg-parser`;
|
|
|
1250
1328
|
fs.writeFileSync(path.join(buildDir, "README.md"), readme);
|
|
1251
1329
|
const buildScript = `#!/bin/bash
|
|
1252
1330
|
echo "Mock DXT build script for ${serverInfo.name}"`;
|
|
1253
|
-
fs.writeFileSync(
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
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
|
+
);
|
|
1258
1344
|
} catch (error) {
|
|
1259
|
-
return this._handleExit(
|
|
1345
|
+
return this._handleExit(
|
|
1346
|
+
1,
|
|
1347
|
+
`Test mode DXT generation failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
1348
|
+
"error"
|
|
1349
|
+
);
|
|
1260
1350
|
}
|
|
1261
1351
|
}
|
|
1262
1352
|
/**
|
|
@@ -1277,9 +1367,17 @@ echo "Mock DXT build script for ${serverInfo.name}"`;
|
|
|
1277
1367
|
fs.mkdirSync(serverDir, { recursive: true });
|
|
1278
1368
|
}
|
|
1279
1369
|
const logoFilename = await this.addLogoToFolder(buildDir, serverInfo);
|
|
1280
|
-
const manifest = this.createDxtManifest(
|
|
1370
|
+
const manifest = this.createDxtManifest(
|
|
1371
|
+
serverInfo,
|
|
1372
|
+
tools,
|
|
1373
|
+
mcpSubCommand,
|
|
1374
|
+
logoFilename
|
|
1375
|
+
);
|
|
1281
1376
|
this.validateDxtManifest(manifest);
|
|
1282
|
-
fs.writeFileSync(
|
|
1377
|
+
fs.writeFileSync(
|
|
1378
|
+
path.join(buildDir, "manifest.json"),
|
|
1379
|
+
JSON.stringify(manifest, null, 2)
|
|
1380
|
+
);
|
|
1283
1381
|
this.addOriginalCliToFolder(buildDir);
|
|
1284
1382
|
const bundledCliPath = await this.bundleOriginalCliWithTsdown(serverDir);
|
|
1285
1383
|
const serverScript = this.createServerScript(serverInfo, bundledCliPath);
|
|
@@ -1288,10 +1386,16 @@ echo "Mock DXT build script for ${serverInfo.name}"`;
|
|
|
1288
1386
|
try {
|
|
1289
1387
|
fs.chmodSync(serverScriptPath, 493);
|
|
1290
1388
|
} catch (error) {
|
|
1291
|
-
console.warn(
|
|
1389
|
+
console.warn(
|
|
1390
|
+
"⚠ Could not set executable permission on server script:",
|
|
1391
|
+
error instanceof Error ? error.message : String(error)
|
|
1392
|
+
);
|
|
1292
1393
|
}
|
|
1293
1394
|
const packageJson = this.createDxtPackageJson(serverInfo);
|
|
1294
|
-
fs.writeFileSync(
|
|
1395
|
+
fs.writeFileSync(
|
|
1396
|
+
path.join(buildDir, "package.json"),
|
|
1397
|
+
JSON.stringify(packageJson, null, 2)
|
|
1398
|
+
);
|
|
1295
1399
|
const readme = this.createDxtReadme(serverInfo);
|
|
1296
1400
|
fs.writeFileSync(path.join(buildDir, "README.md"), readme);
|
|
1297
1401
|
const buildScript = this.createSimpleBuildScript(serverInfo);
|
|
@@ -1303,11 +1407,15 @@ echo "Mock DXT build script for ${serverInfo.name}"`;
|
|
|
1303
1407
|
} catch (error) {
|
|
1304
1408
|
}
|
|
1305
1409
|
console.log(simpleChalk.green(` ✓ Generated DXT package folder: ${folderName}`));
|
|
1306
|
-
console.log(
|
|
1410
|
+
console.log(
|
|
1411
|
+
simpleChalk.gray(` Server: ${serverInfo.name} v${serverInfo.version}`)
|
|
1412
|
+
);
|
|
1307
1413
|
console.log(simpleChalk.gray(` Tools: ${tools.length} tool(s)`));
|
|
1308
1414
|
console.log(simpleChalk.gray(` Location: ${buildDir}`));
|
|
1309
|
-
console.log(
|
|
1310
|
-
|
|
1415
|
+
console.log(
|
|
1416
|
+
simpleChalk.cyan(`
|
|
1417
|
+
📦 Creating DXT package using Anthropic's dxt pack...`)
|
|
1418
|
+
);
|
|
1311
1419
|
console.log(simpleChalk.cyan(`
|
|
1312
1420
|
📋 Manual steps to create your DXT package:`));
|
|
1313
1421
|
console.log(simpleChalk.white(` cd ${path.relative(process.cwd(), buildDir)}`));
|
|
@@ -1370,7 +1478,9 @@ echo "Mock DXT build script for ${serverInfo.name}"`;
|
|
|
1370
1478
|
toolOptions = mcpConfig.toolOptions;
|
|
1371
1479
|
}
|
|
1372
1480
|
}
|
|
1373
|
-
const mcpTools = this.argParserInstance.toMcpTools(
|
|
1481
|
+
const mcpTools = this.argParserInstance.toMcpTools(
|
|
1482
|
+
toolOptions
|
|
1483
|
+
);
|
|
1374
1484
|
return mcpTools.map((tool) => ({
|
|
1375
1485
|
name: tool.name,
|
|
1376
1486
|
description: tool.description
|
|
@@ -1394,16 +1504,24 @@ echo "Mock DXT build script for ${serverInfo.name}"`;
|
|
|
1394
1504
|
});
|
|
1395
1505
|
}
|
|
1396
1506
|
}
|
|
1397
|
-
return tools.length > 0 ? tools : [
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1507
|
+
return tools.length > 0 ? tools : [
|
|
1508
|
+
{
|
|
1509
|
+
name: "main",
|
|
1510
|
+
description: "Main command tool"
|
|
1511
|
+
}
|
|
1512
|
+
];
|
|
1401
1513
|
} catch (error) {
|
|
1402
|
-
console.warn(
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
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
|
+
];
|
|
1407
1525
|
}
|
|
1408
1526
|
}
|
|
1409
1527
|
createDxtManifest(serverInfo, tools, mcpSubCommand, logoFilename) {
|
|
@@ -1426,7 +1544,9 @@ echo "Mock DXT build script for ${serverInfo.name}"`;
|
|
|
1426
1544
|
}
|
|
1427
1545
|
}
|
|
1428
1546
|
if (!author) {
|
|
1429
|
-
throw new Error(
|
|
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
|
+
);
|
|
1430
1550
|
}
|
|
1431
1551
|
const cliArgs = this.generateCliArgsForDxt(mcpSubCommand);
|
|
1432
1552
|
const { envVars, userConfig } = this.generateEnvAndUserConfig();
|
|
@@ -1469,31 +1589,41 @@ echo "Mock DXT build script for ${serverInfo.name}"`;
|
|
|
1469
1589
|
}
|
|
1470
1590
|
validateDxtManifest(manifest) {
|
|
1471
1591
|
const errors = [];
|
|
1472
|
-
if (!manifest.dxt_version)
|
|
1592
|
+
if (!manifest.dxt_version)
|
|
1593
|
+
errors.push("Missing required field: dxt_version");
|
|
1473
1594
|
if (!manifest.name) errors.push("Missing required field: name");
|
|
1474
1595
|
if (!manifest.version) errors.push("Missing required field: version");
|
|
1475
1596
|
if (!manifest.server) errors.push("Missing required field: server");
|
|
1476
1597
|
if (!manifest.author) errors.push("Missing required field: author");
|
|
1477
1598
|
if (manifest.server) {
|
|
1478
|
-
if (!manifest.server.type)
|
|
1479
|
-
|
|
1480
|
-
if (!manifest.server.
|
|
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");
|
|
1481
1605
|
if (manifest.server.mcp_config) {
|
|
1482
|
-
if (!manifest.server.mcp_config.command)
|
|
1606
|
+
if (!manifest.server.mcp_config.command)
|
|
1607
|
+
errors.push("Missing required field: server.mcp_config.command");
|
|
1483
1608
|
if (!manifest.server.mcp_config.args || !Array.isArray(manifest.server.mcp_config.args)) {
|
|
1484
|
-
errors.push(
|
|
1609
|
+
errors.push(
|
|
1610
|
+
"Missing or invalid field: server.mcp_config.args (must be array)"
|
|
1611
|
+
);
|
|
1485
1612
|
}
|
|
1486
1613
|
}
|
|
1487
1614
|
}
|
|
1488
1615
|
if (manifest.author && typeof manifest.author === "object") {
|
|
1489
|
-
if (!manifest.author.name)
|
|
1616
|
+
if (!manifest.author.name)
|
|
1617
|
+
errors.push("Missing required field: author.name");
|
|
1490
1618
|
}
|
|
1491
1619
|
if (manifest.dxt_version && manifest.dxt_version !== "0.1") {
|
|
1492
1620
|
errors.push("Unsupported dxt_version: only '0.1' is currently supported");
|
|
1493
1621
|
}
|
|
1494
1622
|
if (errors.length > 0) {
|
|
1495
|
-
throw new Error(
|
|
1496
|
-
|
|
1623
|
+
throw new Error(
|
|
1624
|
+
`DXT manifest validation failed:
|
|
1625
|
+
${errors.map((e) => ` - ${e}`).join("\n")}`
|
|
1626
|
+
);
|
|
1497
1627
|
}
|
|
1498
1628
|
}
|
|
1499
1629
|
createServerScript(serverInfo, bundledCliPath) {
|
|
@@ -1537,27 +1667,34 @@ originalCli.parse(['--s-mcp-serve']);
|
|
|
1537
1667
|
try {
|
|
1538
1668
|
const originalPackageJsonPath = path.join(process.cwd(), "package.json");
|
|
1539
1669
|
if (fs.existsSync(originalPackageJsonPath)) {
|
|
1540
|
-
const originalPackageJson = JSON.parse(
|
|
1670
|
+
const originalPackageJson = JSON.parse(
|
|
1671
|
+
fs.readFileSync(originalPackageJsonPath, "utf8")
|
|
1672
|
+
);
|
|
1541
1673
|
originalDependencies = originalPackageJson.dependencies || {};
|
|
1542
1674
|
}
|
|
1543
1675
|
} catch (error) {
|
|
1544
|
-
console.warn(
|
|
1676
|
+
console.warn(
|
|
1677
|
+
"⚠ Could not read original package.json for dependencies:",
|
|
1678
|
+
error instanceof Error ? error.message : String(error)
|
|
1679
|
+
);
|
|
1545
1680
|
}
|
|
1546
1681
|
const dependencies2 = {
|
|
1547
1682
|
...originalDependencies,
|
|
1548
1683
|
"@alcyone-labs/arg-parser": argParserDependency,
|
|
1549
1684
|
"@alcyone-labs/simple-mcp-logger": "^1.0.0",
|
|
1550
1685
|
"@modelcontextprotocol/sdk": "^1.15.0",
|
|
1551
|
-
|
|
1686
|
+
zod: "^3.22.4"
|
|
1552
1687
|
};
|
|
1553
1688
|
const devDependencies = {
|
|
1554
|
-
|
|
1689
|
+
tsup: "^8.3.5"
|
|
1555
1690
|
};
|
|
1556
1691
|
Object.keys(dependencies2).forEach((key) => {
|
|
1557
1692
|
const depValue = dependencies2[key];
|
|
1558
1693
|
if (key !== "@alcyone-labs/arg-parser" && typeof depValue === "string" && depValue.startsWith("file:")) {
|
|
1559
1694
|
delete dependencies2[key];
|
|
1560
|
-
console.warn(
|
|
1695
|
+
console.warn(
|
|
1696
|
+
`⚠ Removed file: dependency ${key} from DXT package (not suitable for distribution)`
|
|
1697
|
+
);
|
|
1561
1698
|
}
|
|
1562
1699
|
});
|
|
1563
1700
|
return {
|
|
@@ -1922,17 +2059,24 @@ For autonomous packages, follow the build instructions above.
|
|
|
1922
2059
|
}
|
|
1923
2060
|
console.log("✓ Downloaded logo from URL");
|
|
1924
2061
|
} else {
|
|
1925
|
-
console.warn(
|
|
2062
|
+
console.warn(
|
|
2063
|
+
`⚠ Failed to download logo: HTTP ${response.status}`
|
|
2064
|
+
);
|
|
1926
2065
|
}
|
|
1927
2066
|
} catch (error) {
|
|
1928
|
-
console.warn(
|
|
2067
|
+
console.warn(
|
|
2068
|
+
"⚠ Failed to download logo from URL:",
|
|
2069
|
+
error instanceof Error ? error.message : String(error)
|
|
2070
|
+
);
|
|
1929
2071
|
}
|
|
1930
2072
|
} else {
|
|
1931
2073
|
let logoPath;
|
|
1932
2074
|
if (entryPointFile && !path.isAbsolute(customLogo)) {
|
|
1933
2075
|
const entryDir = path.dirname(entryPointFile);
|
|
1934
2076
|
logoPath = path.resolve(entryDir, customLogo);
|
|
1935
|
-
console.log(
|
|
2077
|
+
console.log(
|
|
2078
|
+
`📍 Resolving logo path relative to entry point: ${logoPath}`
|
|
2079
|
+
);
|
|
1936
2080
|
} else {
|
|
1937
2081
|
logoPath = path.resolve(customLogo);
|
|
1938
2082
|
}
|
|
@@ -1949,17 +2093,32 @@ For autonomous packages, follow the build instructions above.
|
|
|
1949
2093
|
const currentDir = path.dirname(new URL(import.meta.url).pathname);
|
|
1950
2094
|
let logoPath = path.join(currentDir, "assets", "logo_1_small.jpg");
|
|
1951
2095
|
if (!fs.existsSync(logoPath)) {
|
|
1952
|
-
logoPath = path.join(
|
|
2096
|
+
logoPath = path.join(
|
|
2097
|
+
currentDir,
|
|
2098
|
+
"..",
|
|
2099
|
+
"docs",
|
|
2100
|
+
"MCP",
|
|
2101
|
+
"icons",
|
|
2102
|
+
"logo_1_small.jpg"
|
|
2103
|
+
);
|
|
1953
2104
|
}
|
|
1954
2105
|
if (!fs.existsSync(logoPath)) {
|
|
1955
|
-
logoPath = path.join(
|
|
2106
|
+
logoPath = path.join(
|
|
2107
|
+
process.cwd(),
|
|
2108
|
+
"docs",
|
|
2109
|
+
"MCP",
|
|
2110
|
+
"icons",
|
|
2111
|
+
"logo_1_small.jpg"
|
|
2112
|
+
);
|
|
1956
2113
|
}
|
|
1957
2114
|
if (fs.existsSync(logoPath)) {
|
|
1958
2115
|
logoBuffer = fs.readFileSync(logoPath);
|
|
1959
2116
|
logoFilename = "logo.jpg";
|
|
1960
2117
|
console.log("✓ Added default logo to build folder");
|
|
1961
2118
|
} else {
|
|
1962
|
-
console.warn(
|
|
2119
|
+
console.warn(
|
|
2120
|
+
"⚠ No logo found (custom or default), build folder will be created without icon"
|
|
2121
|
+
);
|
|
1963
2122
|
return void 0;
|
|
1964
2123
|
}
|
|
1965
2124
|
}
|
|
@@ -1969,7 +2128,10 @@ For autonomous packages, follow the build instructions above.
|
|
|
1969
2128
|
}
|
|
1970
2129
|
return void 0;
|
|
1971
2130
|
} catch (error) {
|
|
1972
|
-
console.warn(
|
|
2131
|
+
console.warn(
|
|
2132
|
+
"⚠ Failed to add logo to build folder:",
|
|
2133
|
+
error instanceof Error ? error.message : String(error)
|
|
2134
|
+
);
|
|
1973
2135
|
return void 0;
|
|
1974
2136
|
}
|
|
1975
2137
|
}
|
|
@@ -2019,7 +2181,12 @@ globalThis.console = {
|
|
|
2019
2181
|
}
|
|
2020
2182
|
}
|
|
2021
2183
|
if (lastImportIndex >= 0) {
|
|
2022
|
-
lines.splice(
|
|
2184
|
+
lines.splice(
|
|
2185
|
+
lastImportIndex + 1,
|
|
2186
|
+
0,
|
|
2187
|
+
"",
|
|
2188
|
+
...consoleReplacement.trim().split("\n")
|
|
2189
|
+
);
|
|
2023
2190
|
return lines.join("\n");
|
|
2024
2191
|
} else {
|
|
2025
2192
|
return consoleReplacement + cliSource;
|
|
@@ -2044,14 +2211,32 @@ globalThis.console = {
|
|
|
2044
2211
|
path.join(process.cwd(), `${appCommandName}.js`),
|
|
2045
2212
|
path.join(process.cwd(), `${appCommandName}.mjs`),
|
|
2046
2213
|
// Look for files with the app command name (sanitized)
|
|
2047
|
-
path.join(
|
|
2048
|
-
|
|
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
|
+
),
|
|
2049
2222
|
// Look for files with app name patterns
|
|
2050
|
-
path.join(
|
|
2051
|
-
|
|
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
|
+
),
|
|
2052
2231
|
// Look for files with first word of app name + cli
|
|
2053
|
-
path.join(
|
|
2054
|
-
|
|
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
|
+
)
|
|
2055
2240
|
];
|
|
2056
2241
|
let cliSourcePath = null;
|
|
2057
2242
|
for (const filePath of possibleCliFiles) {
|
|
@@ -2071,7 +2256,9 @@ globalThis.console = {
|
|
|
2071
2256
|
"import $1 from '@alcyone-labs/arg-parser';"
|
|
2072
2257
|
);
|
|
2073
2258
|
cliSource = this.processCliSourceForMcp(cliSource);
|
|
2074
|
-
const parserVariableMatch = cliSource.match(
|
|
2259
|
+
const parserVariableMatch = cliSource.match(
|
|
2260
|
+
/const\s+(\w+)\s*=\s*ArgParser\.withMcp\(/
|
|
2261
|
+
);
|
|
2075
2262
|
if (parserVariableMatch) {
|
|
2076
2263
|
const parserVariable = parserVariableMatch[1];
|
|
2077
2264
|
cliSource += `
|
|
@@ -2137,20 +2324,32 @@ if (process.argv.includes('serve')) {
|
|
|
2137
2324
|
}
|
|
2138
2325
|
`;
|
|
2139
2326
|
} else {
|
|
2140
|
-
console.warn(
|
|
2327
|
+
console.warn(
|
|
2328
|
+
"⚠ Could not find ArgParser instance in CLI source, MCP server may not work properly"
|
|
2329
|
+
);
|
|
2141
2330
|
}
|
|
2142
2331
|
const serverDir = path.join(buildDir, "server");
|
|
2143
2332
|
if (!fs.existsSync(serverDir)) {
|
|
2144
2333
|
fs.mkdirSync(serverDir, { recursive: true });
|
|
2145
2334
|
}
|
|
2146
2335
|
fs.writeFileSync(path.join(serverDir, "original-cli.mjs"), cliSource);
|
|
2147
|
-
console.log(
|
|
2336
|
+
console.log(
|
|
2337
|
+
`✓ Added original CLI source to build folder: ${path.basename(cliSourcePath)}`
|
|
2338
|
+
);
|
|
2148
2339
|
} else {
|
|
2149
|
-
console.warn(
|
|
2150
|
-
|
|
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
|
+
);
|
|
2151
2347
|
}
|
|
2152
2348
|
} catch (error) {
|
|
2153
|
-
console.warn(
|
|
2349
|
+
console.warn(
|
|
2350
|
+
"⚠ Failed to add original CLI source:",
|
|
2351
|
+
error instanceof Error ? error.message : String(error)
|
|
2352
|
+
);
|
|
2154
2353
|
}
|
|
2155
2354
|
}
|
|
2156
2355
|
/**
|
|
@@ -2187,13 +2386,35 @@ if (process.argv.includes('serve')) {
|
|
|
2187
2386
|
...(() => {
|
|
2188
2387
|
const possibleLogoPaths = [
|
|
2189
2388
|
// From built library assets
|
|
2190
|
-
path.join(
|
|
2389
|
+
path.join(
|
|
2390
|
+
path.dirname(new URL(import.meta.url).pathname),
|
|
2391
|
+
"..",
|
|
2392
|
+
"assets",
|
|
2393
|
+
"logo_1_small.jpg"
|
|
2394
|
+
),
|
|
2191
2395
|
// From node_modules
|
|
2192
|
-
path.join(
|
|
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
|
+
),
|
|
2193
2405
|
// From package root dist/assets (for local build)
|
|
2194
2406
|
path.join(process.cwd(), "dist", "assets", "logo_1_small.jpg"),
|
|
2195
2407
|
// From library root (development)
|
|
2196
|
-
path.join(
|
|
2408
|
+
path.join(
|
|
2409
|
+
process.cwd(),
|
|
2410
|
+
"..",
|
|
2411
|
+
"..",
|
|
2412
|
+
"..",
|
|
2413
|
+
"docs",
|
|
2414
|
+
"MCP",
|
|
2415
|
+
"icons",
|
|
2416
|
+
"logo_1_small.jpg"
|
|
2417
|
+
)
|
|
2197
2418
|
];
|
|
2198
2419
|
for (const logoPath of possibleLogoPaths) {
|
|
2199
2420
|
if (fs.existsSync(logoPath)) {
|
|
@@ -2201,7 +2422,9 @@ if (process.argv.includes('serve')) {
|
|
|
2201
2422
|
return [{ from: logoPath, to: "logo.jpg" }];
|
|
2202
2423
|
}
|
|
2203
2424
|
}
|
|
2204
|
-
console.log(
|
|
2425
|
+
console.log(
|
|
2426
|
+
simpleChalk.yellow("⚠ Logo not found in any expected location")
|
|
2427
|
+
);
|
|
2205
2428
|
return [];
|
|
2206
2429
|
})()
|
|
2207
2430
|
],
|
|
@@ -2241,20 +2464,39 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2241
2464
|
// To run manually:
|
|
2242
2465
|
// npx tsdown -c tsdown.config.dxt.ts
|
|
2243
2466
|
`;
|
|
2244
|
-
fs.writeFileSync(
|
|
2245
|
-
|
|
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
|
+
);
|
|
2246
2474
|
}
|
|
2247
2475
|
await build(buildConfig);
|
|
2248
2476
|
console.log(simpleChalk.green("✅ TSDown bundling completed"));
|
|
2477
|
+
const actualOutputFilename = this.detectTsdownOutputFile(
|
|
2478
|
+
outputDir,
|
|
2479
|
+
entryFileName
|
|
2480
|
+
);
|
|
2249
2481
|
await this.copyLogoManually(outputDir);
|
|
2250
|
-
await this.setupDxtPackageFiles(
|
|
2482
|
+
await this.setupDxtPackageFiles(
|
|
2483
|
+
entryPointFile,
|
|
2484
|
+
outputDir,
|
|
2485
|
+
actualOutputFilename ?? void 0
|
|
2486
|
+
);
|
|
2251
2487
|
console.log(simpleChalk.cyan("📦 DXT package ready for packing"));
|
|
2252
|
-
console.log(
|
|
2488
|
+
console.log(
|
|
2489
|
+
simpleChalk.gray(
|
|
2490
|
+
`To complete the process, run: npx @anthropic-ai/dxt pack ${outputDir}/`
|
|
2491
|
+
)
|
|
2492
|
+
);
|
|
2253
2493
|
} finally {
|
|
2254
2494
|
process.chdir(originalCwd);
|
|
2255
2495
|
}
|
|
2256
2496
|
} catch (error) {
|
|
2257
|
-
throw new Error(
|
|
2497
|
+
throw new Error(
|
|
2498
|
+
`TSDown DXT build failed: ${error instanceof Error ? error.message : String(error)}`
|
|
2499
|
+
);
|
|
2258
2500
|
}
|
|
2259
2501
|
}
|
|
2260
2502
|
/**
|
|
@@ -2263,13 +2505,17 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2263
2505
|
async bundleOriginalCliWithTsdown(serverDir) {
|
|
2264
2506
|
try {
|
|
2265
2507
|
const { build } = await import("tsdown");
|
|
2266
|
-
console.log(
|
|
2508
|
+
console.log(
|
|
2509
|
+
simpleChalk.cyan("🔧 Bundling CLI with TSDown for autonomous execution...")
|
|
2510
|
+
);
|
|
2267
2511
|
const configContent = this.getTsdownConfigContent();
|
|
2268
2512
|
const localConfigPath = path.join(serverDir, "tsdown.config.mjs");
|
|
2269
2513
|
fs.writeFileSync(localConfigPath, configContent);
|
|
2270
2514
|
const originalCliPath = path.join(serverDir, "original-cli.mjs");
|
|
2271
2515
|
if (!fs.existsSync(originalCliPath)) {
|
|
2272
|
-
console.warn(
|
|
2516
|
+
console.warn(
|
|
2517
|
+
simpleChalk.yellow("⚠ Original CLI not found, skipping TSDown bundling")
|
|
2518
|
+
);
|
|
2273
2519
|
return null;
|
|
2274
2520
|
}
|
|
2275
2521
|
const buildOptions = {
|
|
@@ -2290,7 +2536,10 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2290
2536
|
outExtension: () => ({ js: ".bundled.mjs" }),
|
|
2291
2537
|
alias: {
|
|
2292
2538
|
// Alias chalk to SimpleChalk for autonomous builds
|
|
2293
|
-
chalk: path.resolve(
|
|
2539
|
+
chalk: path.resolve(
|
|
2540
|
+
process.cwd(),
|
|
2541
|
+
"node_modules/@alcyone-labs/arg-parser/dist/SimpleChalk.mjs"
|
|
2542
|
+
)
|
|
2294
2543
|
},
|
|
2295
2544
|
external: [
|
|
2296
2545
|
// Only Node.js built-ins - everything else gets bundled for true autonomy
|
|
@@ -2382,8 +2631,15 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2382
2631
|
}
|
|
2383
2632
|
}
|
|
2384
2633
|
if (bundledPath && bundledFileName) {
|
|
2385
|
-
console.log(
|
|
2386
|
-
|
|
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
|
+
);
|
|
2387
2643
|
if (bundledPath !== expectedBundledPath) {
|
|
2388
2644
|
fs.renameSync(bundledPath, expectedBundledPath);
|
|
2389
2645
|
bundledFileName = "original-cli.bundled.mjs";
|
|
@@ -2395,15 +2651,24 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2395
2651
|
try {
|
|
2396
2652
|
fs.chmodSync(expectedBundledPath, 493);
|
|
2397
2653
|
} catch (error) {
|
|
2398
|
-
console.warn(
|
|
2654
|
+
console.warn(
|
|
2655
|
+
"⚠ Could not set executable permission on bundled file:",
|
|
2656
|
+
error instanceof Error ? error.message : String(error)
|
|
2657
|
+
);
|
|
2399
2658
|
}
|
|
2400
2659
|
return bundledFileName;
|
|
2401
2660
|
} else {
|
|
2402
|
-
console.warn(
|
|
2661
|
+
console.warn(
|
|
2662
|
+
simpleChalk.yellow("⚠ TSDown bundling failed, bundled file not found")
|
|
2663
|
+
);
|
|
2403
2664
|
return null;
|
|
2404
2665
|
}
|
|
2405
2666
|
} catch (error) {
|
|
2406
|
-
console.warn(
|
|
2667
|
+
console.warn(
|
|
2668
|
+
simpleChalk.yellow(
|
|
2669
|
+
`⚠ TSDown bundling failed: ${error instanceof Error ? error.message : String(error)}`
|
|
2670
|
+
)
|
|
2671
|
+
);
|
|
2407
2672
|
console.log(simpleChalk.gray(" Falling back to non-bundled approach"));
|
|
2408
2673
|
return null;
|
|
2409
2674
|
}
|
|
@@ -2458,22 +2723,44 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2458
2723
|
*/
|
|
2459
2724
|
getTsdownConfigContent() {
|
|
2460
2725
|
const currentDir = path.dirname(new URL(import.meta.url).pathname);
|
|
2461
|
-
const assetsConfigPath = path.join(
|
|
2726
|
+
const assetsConfigPath = path.join(
|
|
2727
|
+
currentDir,
|
|
2728
|
+
"..",
|
|
2729
|
+
"assets",
|
|
2730
|
+
"tsdown.dxt.config.ts"
|
|
2731
|
+
);
|
|
2462
2732
|
if (fs.existsSync(assetsConfigPath)) {
|
|
2463
2733
|
try {
|
|
2464
2734
|
const content = fs.readFileSync(assetsConfigPath, "utf-8");
|
|
2465
|
-
return content.replace('/// <reference types="tsdown" />', "").replace(
|
|
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
|
+
);
|
|
2466
2742
|
} catch (error) {
|
|
2467
|
-
console.warn(
|
|
2743
|
+
console.warn(
|
|
2744
|
+
simpleChalk.yellow(
|
|
2745
|
+
"⚠ Could not read TSDown config from assets, using fallback"
|
|
2746
|
+
)
|
|
2747
|
+
);
|
|
2468
2748
|
}
|
|
2469
2749
|
}
|
|
2470
2750
|
const rootConfigPath = path.join(process.cwd(), "tsdown.dxt.config.ts");
|
|
2471
2751
|
if (fs.existsSync(rootConfigPath)) {
|
|
2472
2752
|
try {
|
|
2473
2753
|
const content = fs.readFileSync(rootConfigPath, "utf-8");
|
|
2474
|
-
return content.replace('/// <reference types="tsdown" />', "").replace(
|
|
2754
|
+
return content.replace('/// <reference types="tsdown" />', "").replace(
|
|
2755
|
+
'import { defineConfig } from "tsdown/config";',
|
|
2756
|
+
'import { defineConfig } from "tsdown";'
|
|
2757
|
+
);
|
|
2475
2758
|
} catch (error) {
|
|
2476
|
-
console.warn(
|
|
2759
|
+
console.warn(
|
|
2760
|
+
simpleChalk.yellow(
|
|
2761
|
+
"⚠ Could not read TSDown config from root, using default"
|
|
2762
|
+
)
|
|
2763
|
+
);
|
|
2477
2764
|
}
|
|
2478
2765
|
}
|
|
2479
2766
|
return `import { defineConfig } from "tsdown";
|
|
@@ -2504,9 +2791,22 @@ export default defineConfig({
|
|
|
2504
2791
|
getDxtIgnoreTemplatePath() {
|
|
2505
2792
|
const possiblePaths = [
|
|
2506
2793
|
// 1. From the built library assets (when installed via npm)
|
|
2507
|
-
path.join(
|
|
2794
|
+
path.join(
|
|
2795
|
+
path.dirname(new URL(import.meta.url).pathname),
|
|
2796
|
+
"..",
|
|
2797
|
+
"assets",
|
|
2798
|
+
".dxtignore.template"
|
|
2799
|
+
),
|
|
2508
2800
|
// 2. From node_modules/@alcyone-labs/arg-parser/dist/assets (when installed via npm)
|
|
2509
|
-
path.join(
|
|
2801
|
+
path.join(
|
|
2802
|
+
process.cwd(),
|
|
2803
|
+
"node_modules",
|
|
2804
|
+
"@alcyone-labs",
|
|
2805
|
+
"arg-parser",
|
|
2806
|
+
"dist",
|
|
2807
|
+
"assets",
|
|
2808
|
+
".dxtignore.template"
|
|
2809
|
+
),
|
|
2510
2810
|
// 3. From the root directory (development/local build)
|
|
2511
2811
|
path.join(process.cwd(), ".dxtignore.template"),
|
|
2512
2812
|
// 4. From the library root (when using local file dependency)
|
|
@@ -2524,7 +2824,7 @@ export default defineConfig({
|
|
|
2524
2824
|
/**
|
|
2525
2825
|
* Sets up DXT package files (manifest.json) in the output directory
|
|
2526
2826
|
*/
|
|
2527
|
-
async setupDxtPackageFiles(entryPointFile, outputDir = "./dxt") {
|
|
2827
|
+
async setupDxtPackageFiles(entryPointFile, outputDir = "./dxt", actualOutputFilename) {
|
|
2528
2828
|
var _a, _b, _c, _d, _e;
|
|
2529
2829
|
const dxtDir = path.resolve(process.cwd(), outputDir);
|
|
2530
2830
|
if (!fs.existsSync(dxtDir)) {
|
|
@@ -2547,7 +2847,11 @@ export default defineConfig({
|
|
|
2547
2847
|
description: tool.description
|
|
2548
2848
|
}));
|
|
2549
2849
|
} catch (error) {
|
|
2550
|
-
console.warn(
|
|
2850
|
+
console.warn(
|
|
2851
|
+
simpleChalk.yellow(
|
|
2852
|
+
`Warning: Could not generate unified tool list: ${error instanceof Error ? error.message : String(error)}`
|
|
2853
|
+
)
|
|
2854
|
+
);
|
|
2551
2855
|
const mainFlags2 = this.argParserInstance.flags;
|
|
2552
2856
|
const properties2 = {};
|
|
2553
2857
|
const required2 = [];
|
|
@@ -2568,10 +2872,12 @@ export default defineConfig({
|
|
|
2568
2872
|
}
|
|
2569
2873
|
}
|
|
2570
2874
|
const commandName = this.argParserInstance.getAppCommandName();
|
|
2571
|
-
tools = [
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2875
|
+
tools = [
|
|
2876
|
+
{
|
|
2877
|
+
name: commandName || packageInfo.name || "cli-tool",
|
|
2878
|
+
description: packageInfo.description || this.argParserInstance.getDescription() || "CLI tool"
|
|
2879
|
+
}
|
|
2880
|
+
];
|
|
2575
2881
|
}
|
|
2576
2882
|
const envVars = {};
|
|
2577
2883
|
const userConfig = {};
|
|
@@ -2615,12 +2921,16 @@ export default defineConfig({
|
|
|
2615
2921
|
const serverInfo = this.extractMcpServerInfo();
|
|
2616
2922
|
let logoFilename = "logo.jpg";
|
|
2617
2923
|
if (serverInfo == null ? void 0 : serverInfo.logo) {
|
|
2618
|
-
const customLogoFilename = await this.addLogoToFolder(
|
|
2924
|
+
const customLogoFilename = await this.addLogoToFolder(
|
|
2925
|
+
dxtDir,
|
|
2926
|
+
serverInfo,
|
|
2927
|
+
entryPointFile
|
|
2928
|
+
);
|
|
2619
2929
|
if (customLogoFilename) {
|
|
2620
2930
|
logoFilename = customLogoFilename;
|
|
2621
2931
|
}
|
|
2622
2932
|
}
|
|
2623
|
-
const entryFileName = path.basename(entryPointFile);
|
|
2933
|
+
const entryFileName = actualOutputFilename || path.basename(entryPointFile).replace(/\.ts$/, ".js");
|
|
2624
2934
|
const manifest = {
|
|
2625
2935
|
dxt_version: "0.1",
|
|
2626
2936
|
name: serverInfo.name || packageInfo.name || "mcp-server",
|
|
@@ -2636,10 +2946,7 @@ export default defineConfig({
|
|
|
2636
2946
|
entry_point: entryFileName,
|
|
2637
2947
|
mcp_config: {
|
|
2638
2948
|
command: "node",
|
|
2639
|
-
args: [
|
|
2640
|
-
`\${__dirname}/${entryFileName}`,
|
|
2641
|
-
"--s-mcp-serve"
|
|
2642
|
-
],
|
|
2949
|
+
args: [`\${__dirname}/${entryFileName}`, "--s-mcp-serve"],
|
|
2643
2950
|
env: envVars
|
|
2644
2951
|
}
|
|
2645
2952
|
},
|
|
@@ -2652,7 +2959,10 @@ export default defineConfig({
|
|
|
2652
2959
|
},
|
|
2653
2960
|
license: packageInfo.license || "MIT"
|
|
2654
2961
|
};
|
|
2655
|
-
fs.writeFileSync(
|
|
2962
|
+
fs.writeFileSync(
|
|
2963
|
+
path.join(dxtDir, "manifest.json"),
|
|
2964
|
+
JSON.stringify(manifest, null, 2)
|
|
2965
|
+
);
|
|
2656
2966
|
console.log(simpleChalk.gray("✅ DXT package files set up"));
|
|
2657
2967
|
}
|
|
2658
2968
|
/**
|
|
@@ -2661,18 +2971,44 @@ export default defineConfig({
|
|
|
2661
2971
|
async copyLogoManually(outputDir = "./dxt") {
|
|
2662
2972
|
const dxtDir = path.resolve(process.cwd(), outputDir);
|
|
2663
2973
|
if (!fs.existsSync(dxtDir)) {
|
|
2664
|
-
console.warn(
|
|
2974
|
+
console.warn(
|
|
2975
|
+
simpleChalk.yellow(
|
|
2976
|
+
`⚠ Output directory (${outputDir}) not found, skipping logo copy`
|
|
2977
|
+
)
|
|
2978
|
+
);
|
|
2665
2979
|
return;
|
|
2666
2980
|
}
|
|
2667
2981
|
const possibleLogoPaths = [
|
|
2668
2982
|
// From built library assets
|
|
2669
|
-
path.join(
|
|
2983
|
+
path.join(
|
|
2984
|
+
path.dirname(new URL(import.meta.url).pathname),
|
|
2985
|
+
"..",
|
|
2986
|
+
"assets",
|
|
2987
|
+
"logo_1_small.jpg"
|
|
2988
|
+
),
|
|
2670
2989
|
// From node_modules
|
|
2671
|
-
path.join(
|
|
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
|
+
),
|
|
2672
2999
|
// From package root dist/assets (for local build)
|
|
2673
3000
|
path.join(process.cwd(), "dist", "assets", "logo_1_small.jpg"),
|
|
2674
3001
|
// From library root (development)
|
|
2675
|
-
path.join(
|
|
3002
|
+
path.join(
|
|
3003
|
+
process.cwd(),
|
|
3004
|
+
"..",
|
|
3005
|
+
"..",
|
|
3006
|
+
"..",
|
|
3007
|
+
"docs",
|
|
3008
|
+
"MCP",
|
|
3009
|
+
"icons",
|
|
3010
|
+
"logo_1_small.jpg"
|
|
3011
|
+
)
|
|
2676
3012
|
];
|
|
2677
3013
|
for (const logoPath of possibleLogoPaths) {
|
|
2678
3014
|
if (fs.existsSync(logoPath)) {
|
|
@@ -2681,12 +3017,78 @@ export default defineConfig({
|
|
|
2681
3017
|
console.log(simpleChalk.gray(`✅ Logo copied from: ${logoPath}`));
|
|
2682
3018
|
return;
|
|
2683
3019
|
} catch (error) {
|
|
2684
|
-
console.warn(
|
|
3020
|
+
console.warn(
|
|
3021
|
+
simpleChalk.yellow(`⚠ Failed to copy logo from ${logoPath}: ${error}`)
|
|
3022
|
+
);
|
|
2685
3023
|
}
|
|
2686
3024
|
}
|
|
2687
3025
|
}
|
|
2688
3026
|
console.warn(simpleChalk.yellow("⚠ Logo not found in any expected location"));
|
|
2689
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
|
+
}
|
|
2690
3092
|
}
|
|
2691
3093
|
class McpNotificationsManager {
|
|
2692
3094
|
constructor() {
|
|
@@ -2840,10 +3242,16 @@ class McpNotificationsManager {
|
|
|
2840
3242
|
sendNotificationToClient(client, type2) {
|
|
2841
3243
|
try {
|
|
2842
3244
|
if (client.connection && typeof client.connection.sendNotification === "function") {
|
|
2843
|
-
client.connection.sendNotification(
|
|
3245
|
+
client.connection.sendNotification(
|
|
3246
|
+
`notifications/${type2}/list_changed`,
|
|
3247
|
+
{}
|
|
3248
|
+
);
|
|
2844
3249
|
}
|
|
2845
3250
|
} catch (error) {
|
|
2846
|
-
console.error(
|
|
3251
|
+
console.error(
|
|
3252
|
+
`Error sending notification to client ${client.clientId}:`,
|
|
3253
|
+
error
|
|
3254
|
+
);
|
|
2847
3255
|
this.removeClient(client.clientId);
|
|
2848
3256
|
}
|
|
2849
3257
|
}
|
|
@@ -2932,7 +3340,9 @@ class McpPromptsManager {
|
|
|
2932
3340
|
return await entry.config.handler(validatedArgs);
|
|
2933
3341
|
} catch (error) {
|
|
2934
3342
|
if (error instanceof z.ZodError) {
|
|
2935
|
-
throw new Error(
|
|
3343
|
+
throw new Error(
|
|
3344
|
+
`Invalid arguments for prompt '${name}': ${error.message}`
|
|
3345
|
+
);
|
|
2936
3346
|
}
|
|
2937
3347
|
throw error;
|
|
2938
3348
|
}
|
|
@@ -3132,7 +3542,9 @@ class McpResourcesManager {
|
|
|
3132
3542
|
try {
|
|
3133
3543
|
new ResourceTemplateParser(config.uriTemplate);
|
|
3134
3544
|
} catch (error) {
|
|
3135
|
-
throw new Error(
|
|
3545
|
+
throw new Error(
|
|
3546
|
+
`Invalid URI template '${config.uriTemplate}': ${error instanceof Error ? error.message : String(error)}`
|
|
3547
|
+
);
|
|
3136
3548
|
}
|
|
3137
3549
|
}
|
|
3138
3550
|
/**
|
|
@@ -3237,6 +3649,97 @@ const _FlagManager = class _FlagManager {
|
|
|
3237
3649
|
__flags = new WeakMap();
|
|
3238
3650
|
_throwForDuplicateFlags = new WeakMap();
|
|
3239
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
|
+
}
|
|
3240
3743
|
class ArgParserError extends Error {
|
|
3241
3744
|
constructor(message, cmdChain = []) {
|
|
3242
3745
|
super(message);
|
|
@@ -4634,15 +5137,16 @@ _handleBuildDxtFlag_fn = async function(processArgs, buildDxtIndex) {
|
|
|
4634
5137
|
};
|
|
4635
5138
|
_handleMcpServeFlag_fn = async function(processArgs, _mcpServeIndex) {
|
|
4636
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);
|
|
4637
5144
|
let mcpLogger;
|
|
4638
5145
|
try {
|
|
4639
5146
|
const mcpLoggerModule = await Function(
|
|
4640
5147
|
'return import("@alcyone-labs/simple-mcp-logger")'
|
|
4641
5148
|
)();
|
|
4642
|
-
mcpLogger = mcpLoggerModule.createMcpLogger(
|
|
4643
|
-
"MCP Serve",
|
|
4644
|
-
"./logs/mcp.log"
|
|
4645
|
-
);
|
|
5149
|
+
mcpLogger = mcpLoggerModule.createMcpLogger("MCP Serve", resolvedLogPath);
|
|
4646
5150
|
globalThis.console = mcpLogger;
|
|
4647
5151
|
} catch {
|
|
4648
5152
|
mcpLogger = {
|
|
@@ -4653,7 +5157,6 @@ _handleMcpServeFlag_fn = async function(processArgs, _mcpServeIndex) {
|
|
|
4653
5157
|
mcpLogger.mcpError(
|
|
4654
5158
|
"Starting --s-mcp-serve system flag handler - console hijacked for MCP safety"
|
|
4655
5159
|
);
|
|
4656
|
-
const mcpServerConfig = __privateMethod(this, _ArgParserBase_instances, _getMcpServerConfiguration_fn).call(this);
|
|
4657
5160
|
if (!mcpServerConfig) {
|
|
4658
5161
|
mcpLogger.mcpError(
|
|
4659
5162
|
"No MCP server configuration found. Use withMcp() or addMcpSubCommand() to configure MCP server."
|
|
@@ -4667,13 +5170,16 @@ _handleMcpServeFlag_fn = async function(processArgs, _mcpServeIndex) {
|
|
|
4667
5170
|
mcpLogger.mcpError(
|
|
4668
5171
|
`Found MCP server configuration: ${((_a = mcpServerConfig.serverInfo) == null ? void 0 : _a.name) || "unnamed"}`
|
|
4669
5172
|
);
|
|
4670
|
-
|
|
5173
|
+
mcpLogger.mcpError(`Using log path: ${resolvedLogPath}`);
|
|
4671
5174
|
mcpLogger.mcpError(
|
|
4672
5175
|
`Transport options: ${JSON.stringify(transportOptions)}`
|
|
4673
5176
|
);
|
|
4674
5177
|
try {
|
|
4675
5178
|
mcpLogger.mcpError("Starting unified MCP server with all tools");
|
|
4676
|
-
await __privateMethod(this, _ArgParserBase_instances, _startUnifiedMcpServer_fn).call(this, mcpServerConfig,
|
|
5179
|
+
await __privateMethod(this, _ArgParserBase_instances, _startUnifiedMcpServer_fn).call(this, mcpServerConfig, {
|
|
5180
|
+
...transportOptions,
|
|
5181
|
+
logPath: resolvedLogPath
|
|
5182
|
+
});
|
|
4677
5183
|
mcpLogger.mcpError("Successfully started unified MCP server");
|
|
4678
5184
|
} catch (error) {
|
|
4679
5185
|
mcpLogger.mcpError(
|
|
@@ -4742,7 +5248,8 @@ _startUnifiedMcpServer_fn = async function(mcpServerConfig, transportOptions) {
|
|
|
4742
5248
|
await mcpParser.startMcpServerWithMultipleTransports(
|
|
4743
5249
|
serverInfo,
|
|
4744
5250
|
transportConfigs,
|
|
4745
|
-
toolOptions
|
|
5251
|
+
toolOptions,
|
|
5252
|
+
transportOptions.logPath
|
|
4746
5253
|
);
|
|
4747
5254
|
} catch (error) {
|
|
4748
5255
|
throw new Error(
|
|
@@ -4753,7 +5260,8 @@ _startUnifiedMcpServer_fn = async function(mcpServerConfig, transportOptions) {
|
|
|
4753
5260
|
await mcpParser.startMcpServerWithMultipleTransports(
|
|
4754
5261
|
serverInfo,
|
|
4755
5262
|
defaultTransports,
|
|
4756
|
-
toolOptions
|
|
5263
|
+
toolOptions,
|
|
5264
|
+
transportOptions.logPath
|
|
4757
5265
|
);
|
|
4758
5266
|
} else if (defaultTransport) {
|
|
4759
5267
|
await mcpParser.startMcpServerWithTransport(
|
|
@@ -4765,7 +5273,8 @@ _startUnifiedMcpServer_fn = async function(mcpServerConfig, transportOptions) {
|
|
|
4765
5273
|
path: defaultTransport.path,
|
|
4766
5274
|
sessionIdGenerator: defaultTransport.sessionIdGenerator
|
|
4767
5275
|
},
|
|
4768
|
-
toolOptions
|
|
5276
|
+
toolOptions,
|
|
5277
|
+
transportOptions.logPath
|
|
4769
5278
|
);
|
|
4770
5279
|
} else {
|
|
4771
5280
|
const transportType = transportOptions.transportType || "stdio";
|
|
@@ -4778,7 +5287,8 @@ _startUnifiedMcpServer_fn = async function(mcpServerConfig, transportOptions) {
|
|
|
4778
5287
|
serverInfo,
|
|
4779
5288
|
transportType,
|
|
4780
5289
|
finalTransportOptions,
|
|
4781
|
-
toolOptions
|
|
5290
|
+
toolOptions,
|
|
5291
|
+
transportOptions.logPath
|
|
4782
5292
|
);
|
|
4783
5293
|
}
|
|
4784
5294
|
};
|
|
@@ -4845,6 +5355,12 @@ _parseMcpTransportOptions_fn = function(processArgs) {
|
|
|
4845
5355
|
i++;
|
|
4846
5356
|
}
|
|
4847
5357
|
break;
|
|
5358
|
+
case "--s-mcp-log-path":
|
|
5359
|
+
if (nextArg && !nextArg.startsWith("-")) {
|
|
5360
|
+
options.logPath = nextArg;
|
|
5361
|
+
i++;
|
|
5362
|
+
}
|
|
5363
|
+
break;
|
|
4848
5364
|
// Backward compatibility: support old flags but with deprecation warning
|
|
4849
5365
|
case "--transport":
|
|
4850
5366
|
case "--port":
|
|
@@ -6130,11 +6646,14 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
6130
6646
|
* @param toolOptions Optional MCP tool generation options
|
|
6131
6647
|
* @returns Configured MCP server instance
|
|
6132
6648
|
*/
|
|
6133
|
-
async createMcpServer(serverInfo, toolOptions) {
|
|
6134
|
-
var _a;
|
|
6135
|
-
const
|
|
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);
|
|
6136
6655
|
try {
|
|
6137
|
-
const effectiveServerInfo = serverInfo || ((
|
|
6656
|
+
const effectiveServerInfo = serverInfo || ((_b = this._mcpServerConfig) == null ? void 0 : _b.serverInfo);
|
|
6138
6657
|
if (!effectiveServerInfo) {
|
|
6139
6658
|
throw new Error(
|
|
6140
6659
|
"No MCP server configuration found. Use withMcp() to configure server info or provide serverInfo parameter."
|
|
@@ -6315,11 +6834,11 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
6315
6834
|
* @param toolOptions Optional MCP tool generation options
|
|
6316
6835
|
* @returns Promise that resolves when all servers are started
|
|
6317
6836
|
*/
|
|
6318
|
-
async startMcpServerWithMultipleTransports(serverInfo, transports, toolOptions) {
|
|
6319
|
-
const server = await this.createMcpServer(serverInfo, toolOptions);
|
|
6837
|
+
async startMcpServerWithMultipleTransports(serverInfo, transports, toolOptions, logPath) {
|
|
6838
|
+
const server = await this.createMcpServer(serverInfo, toolOptions, logPath);
|
|
6320
6839
|
const startPromises = [];
|
|
6321
6840
|
for (const transportConfig of transports) {
|
|
6322
|
-
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);
|
|
6323
6842
|
startPromises.push(promise);
|
|
6324
6843
|
}
|
|
6325
6844
|
await Promise.all(startPromises);
|
|
@@ -6332,12 +6851,12 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
6332
6851
|
* @param toolOptions Optional MCP tool generation options
|
|
6333
6852
|
* @returns Promise that resolves when server is connected
|
|
6334
6853
|
*/
|
|
6335
|
-
async startMcpServerWithTransport(serverInfo, transportType, transportOptions = {}, toolOptions) {
|
|
6336
|
-
const server = await this.createMcpServer(serverInfo, toolOptions);
|
|
6854
|
+
async startMcpServerWithTransport(serverInfo, transportType, transportOptions = {}, toolOptions, logPath) {
|
|
6855
|
+
const server = await this.createMcpServer(serverInfo, toolOptions, logPath);
|
|
6337
6856
|
await __privateMethod(this, _ArgParser_instances, _startSingleTransport_fn).call(this, server, serverInfo, {
|
|
6338
6857
|
type: transportType,
|
|
6339
6858
|
...transportOptions
|
|
6340
|
-
});
|
|
6859
|
+
}, logPath);
|
|
6341
6860
|
}
|
|
6342
6861
|
async parse(processArgs, options) {
|
|
6343
6862
|
let result = await ArgParserBase.prototype.parse.call(
|
|
@@ -6599,8 +7118,9 @@ registerToolAsSubCommand_fn = function(toolConfig) {
|
|
|
6599
7118
|
handler: toolConfig.handler
|
|
6600
7119
|
});
|
|
6601
7120
|
};
|
|
6602
|
-
_startSingleTransport_fn = async function(server, serverInfo, transportConfig) {
|
|
6603
|
-
const
|
|
7121
|
+
_startSingleTransport_fn = async function(server, serverInfo, transportConfig, logPath) {
|
|
7122
|
+
const resolvedLogPath = resolveLogPath(logPath || "./logs/mcp.log");
|
|
7123
|
+
const logger2 = createMcpLogger("MCP Transport", resolvedLogPath);
|
|
6604
7124
|
try {
|
|
6605
7125
|
logger2.mcpError(
|
|
6606
7126
|
`Starting ${transportConfig.type} transport for server: ${serverInfo.name}`
|
|
@@ -6776,7 +7296,9 @@ class TomlConfigPlugin extends ConfigPlugin {
|
|
|
6776
7296
|
}
|
|
6777
7297
|
return parsed;
|
|
6778
7298
|
} catch (error) {
|
|
6779
|
-
throw new Error(
|
|
7299
|
+
throw new Error(
|
|
7300
|
+
`Failed to parse TOML: ${error instanceof Error ? error.message : String(error)}`
|
|
7301
|
+
);
|
|
6780
7302
|
}
|
|
6781
7303
|
}
|
|
6782
7304
|
generate(_config, flags, parsedArgs) {
|
|
@@ -6816,7 +7338,9 @@ class TomlConfigPlugin extends ConfigPlugin {
|
|
|
6816
7338
|
const tomlContent = this.tomlModule.stringify(configWithValues);
|
|
6817
7339
|
return lines.join("\n") + "\n" + tomlContent;
|
|
6818
7340
|
} catch (error) {
|
|
6819
|
-
throw new Error(
|
|
7341
|
+
throw new Error(
|
|
7342
|
+
`Failed to generate TOML: ${error instanceof Error ? error.message : String(error)}`
|
|
7343
|
+
);
|
|
6820
7344
|
}
|
|
6821
7345
|
}
|
|
6822
7346
|
/**
|
|
@@ -6852,7 +7376,10 @@ function createTomlPlugin() {
|
|
|
6852
7376
|
try {
|
|
6853
7377
|
return new TomlConfigPlugin();
|
|
6854
7378
|
} catch (error) {
|
|
6855
|
-
console.warn(
|
|
7379
|
+
console.warn(
|
|
7380
|
+
"TOML plugin not available:",
|
|
7381
|
+
error instanceof Error ? error.message : String(error)
|
|
7382
|
+
);
|
|
6856
7383
|
return null;
|
|
6857
7384
|
}
|
|
6858
7385
|
}
|
|
@@ -6868,7 +7395,10 @@ async function createTomlPluginAsync() {
|
|
|
6868
7395
|
const tomlModule = await Promise.resolve().then(() => index$1);
|
|
6869
7396
|
return new TomlConfigPlugin(tomlModule);
|
|
6870
7397
|
} catch (error) {
|
|
6871
|
-
console.warn(
|
|
7398
|
+
console.warn(
|
|
7399
|
+
"TOML plugin not available:",
|
|
7400
|
+
error instanceof Error ? error.message : String(error)
|
|
7401
|
+
);
|
|
6872
7402
|
return null;
|
|
6873
7403
|
}
|
|
6874
7404
|
}
|
|
@@ -6914,7 +7444,9 @@ class YamlConfigPlugin extends ConfigPlugin {
|
|
|
6914
7444
|
}
|
|
6915
7445
|
return parsed;
|
|
6916
7446
|
} catch (error) {
|
|
6917
|
-
throw new Error(
|
|
7447
|
+
throw new Error(
|
|
7448
|
+
`Failed to parse YAML: ${error instanceof Error ? error.message : String(error)}`
|
|
7449
|
+
);
|
|
6918
7450
|
}
|
|
6919
7451
|
}
|
|
6920
7452
|
generate(_config, flags, parsedArgs) {
|
|
@@ -6948,7 +7480,9 @@ class YamlConfigPlugin extends ConfigPlugin {
|
|
|
6948
7480
|
});
|
|
6949
7481
|
return lines.join("\n") + "\n" + yamlContent;
|
|
6950
7482
|
} catch (error) {
|
|
6951
|
-
throw new Error(
|
|
7483
|
+
throw new Error(
|
|
7484
|
+
`Failed to generate YAML: ${error instanceof Error ? error.message : String(error)}`
|
|
7485
|
+
);
|
|
6952
7486
|
}
|
|
6953
7487
|
}
|
|
6954
7488
|
/**
|
|
@@ -6978,7 +7512,10 @@ function createYamlPlugin() {
|
|
|
6978
7512
|
try {
|
|
6979
7513
|
return new YamlConfigPlugin();
|
|
6980
7514
|
} catch (error) {
|
|
6981
|
-
console.warn(
|
|
7515
|
+
console.warn(
|
|
7516
|
+
"YAML plugin not available:",
|
|
7517
|
+
error instanceof Error ? error.message : String(error)
|
|
7518
|
+
);
|
|
6982
7519
|
return null;
|
|
6983
7520
|
}
|
|
6984
7521
|
}
|
|
@@ -6994,7 +7531,10 @@ async function createYamlPluginAsync() {
|
|
|
6994
7531
|
const yamlModule = await import("js-yaml");
|
|
6995
7532
|
return new YamlConfigPlugin(yamlModule);
|
|
6996
7533
|
} catch (error) {
|
|
6997
|
-
console.warn(
|
|
7534
|
+
console.warn(
|
|
7535
|
+
"YAML plugin not available:",
|
|
7536
|
+
error instanceof Error ? error.message : String(error)
|
|
7537
|
+
);
|
|
6998
7538
|
return null;
|
|
6999
7539
|
}
|
|
7000
7540
|
}
|
|
@@ -7023,7 +7563,9 @@ class ArgParserFuzzyTester {
|
|
|
7023
7563
|
const results = [];
|
|
7024
7564
|
if (this.options.verbose) {
|
|
7025
7565
|
console.log(`Discovered ${commandPaths.length} command paths:`);
|
|
7026
|
-
commandPaths.forEach(
|
|
7566
|
+
commandPaths.forEach(
|
|
7567
|
+
(path2) => console.log(` ${path2.join(" ") || "(root)"}`)
|
|
7568
|
+
);
|
|
7027
7569
|
}
|
|
7028
7570
|
for (const commandPath of commandPaths) {
|
|
7029
7571
|
const pathResults = await this.testCommandPath(commandPath);
|
|
@@ -7049,7 +7591,12 @@ class ArgParserFuzzyTester {
|
|
|
7049
7591
|
for (const [subCommandName, subCommand] of subCommands) {
|
|
7050
7592
|
const newPath = [...currentPath, subCommandName];
|
|
7051
7593
|
allPaths.push(newPath);
|
|
7052
|
-
this.discoverSubCommandPaths(
|
|
7594
|
+
this.discoverSubCommandPaths(
|
|
7595
|
+
subCommand.parser,
|
|
7596
|
+
newPath,
|
|
7597
|
+
allPaths,
|
|
7598
|
+
depth + 1
|
|
7599
|
+
);
|
|
7053
7600
|
}
|
|
7054
7601
|
}
|
|
7055
7602
|
/**
|
|
@@ -24941,6 +25488,7 @@ export {
|
|
|
24941
25488
|
simpleChalk as SimpleChalk,
|
|
24942
25489
|
TomlConfigPlugin,
|
|
24943
25490
|
YamlConfigPlugin,
|
|
25491
|
+
absolutePath,
|
|
24944
25492
|
convertFlagToJsonSchemaProperty,
|
|
24945
25493
|
convertFlagsToJsonSchema,
|
|
24946
25494
|
convertFlagsToZodSchema,
|
|
@@ -24954,14 +25502,20 @@ export {
|
|
|
24954
25502
|
createTomlPluginAsync,
|
|
24955
25503
|
createYamlPlugin,
|
|
24956
25504
|
createYamlPluginAsync,
|
|
25505
|
+
cwdRelative,
|
|
25506
|
+
detectEntryPoint,
|
|
24957
25507
|
enableConfigPlugins,
|
|
24958
25508
|
enableOptionalConfigPlugins,
|
|
24959
25509
|
enableOptionalConfigPluginsAsync,
|
|
25510
|
+
entryRelative,
|
|
24960
25511
|
extractSimplifiedResponse,
|
|
24961
25512
|
generateMcpToolsFromArgParser,
|
|
25513
|
+
getEntryPointFromImportMeta,
|
|
24962
25514
|
getJsonSchemaTypeFromFlag,
|
|
24963
25515
|
globalConfigPluginRegistry,
|
|
25516
|
+
legacyCwdPath,
|
|
24964
25517
|
logger,
|
|
25518
|
+
resolveLogPath,
|
|
24965
25519
|
zodFlagSchema
|
|
24966
25520
|
};
|
|
24967
25521
|
//# sourceMappingURL=index.mjs.map
|