@alcyone-labs/arg-parser 2.4.2 → 2.6.0
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 +286 -70
- package/dist/core/ArgParserBase.d.ts.map +1 -1
- package/dist/core/FlagManager.d.ts.map +1 -1
- package/dist/core/dxt-path-resolver.d.ts +100 -0
- package/dist/core/dxt-path-resolver.d.ts.map +1 -0
- package/dist/core/log-path-utils.d.ts.map +1 -1
- package/dist/core/types.d.ts +73 -4
- package/dist/core/types.d.ts.map +1 -1
- package/dist/dxt/DxtGenerator.d.ts +6 -0
- package/dist/dxt/DxtGenerator.d.ts.map +1 -1
- package/dist/index.cjs +708 -193
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.min.mjs +5559 -5175
- package/dist/index.min.mjs.map +1 -1
- package/dist/index.mjs +708 -193
- package/dist/index.mjs.map +1 -1
- package/dist/mcp/mcp-integration.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1034,6 +1034,29 @@ class ConfigurationManager {
|
|
|
1034
1034
|
}
|
|
1035
1035
|
}
|
|
1036
1036
|
}
|
|
1037
|
+
const zodDxtOptionsSchema = z.object({
|
|
1038
|
+
sensitive: z.boolean().optional().describe("Whether this field should be marked as sensitive in DXT user_config"),
|
|
1039
|
+
localDefault: z.string().optional().describe("Default value specific to DXT sandbox environment"),
|
|
1040
|
+
type: z.enum(["string", "directory", "file", "boolean", "number"]).optional().describe("DXT input type - determines UI component in DXT clients"),
|
|
1041
|
+
multiple: z.boolean().optional().describe("Allow multiple values (for arrays)"),
|
|
1042
|
+
min: z.number().optional().describe("Minimum value (for number type)"),
|
|
1043
|
+
max: z.number().optional().describe("Maximum value (for number type)"),
|
|
1044
|
+
default: z.any().optional().describe("DXT-specific default value (overrides localDefault if provided)"),
|
|
1045
|
+
title: z.string().optional().describe("Custom title for the user_config field")
|
|
1046
|
+
}).strict().refine(
|
|
1047
|
+
(data2) => {
|
|
1048
|
+
if ((data2.min !== void 0 || data2.max !== void 0) && data2.type !== "number") {
|
|
1049
|
+
return false;
|
|
1050
|
+
}
|
|
1051
|
+
if (data2.min !== void 0 && data2.max !== void 0 && data2.min > data2.max) {
|
|
1052
|
+
return false;
|
|
1053
|
+
}
|
|
1054
|
+
return true;
|
|
1055
|
+
},
|
|
1056
|
+
{
|
|
1057
|
+
message: "Invalid dxtOptions: min/max can only be used with type 'number', and min must be <= max"
|
|
1058
|
+
}
|
|
1059
|
+
);
|
|
1037
1060
|
const zodFlagSchema = z.object({
|
|
1038
1061
|
name: z.string().min(1, "Flag name cannot be empty").describe(
|
|
1039
1062
|
"The output property name, used as a return key `{name: value}`. Must be unique."
|
|
@@ -1070,6 +1093,11 @@ const zodFlagSchema = z.object({
|
|
|
1070
1093
|
"Must be a custom parser function"
|
|
1071
1094
|
),
|
|
1072
1095
|
// Custom parser function (value: string) => any | Promise<any>
|
|
1096
|
+
z.custom(
|
|
1097
|
+
(val) => val && typeof val === "object" && val._def,
|
|
1098
|
+
"Must be a Zod schema"
|
|
1099
|
+
),
|
|
1100
|
+
// Zod schema for structured JSON validation
|
|
1073
1101
|
z.string().refine(
|
|
1074
1102
|
// String literal types
|
|
1075
1103
|
(value) => ["boolean", "string", "number", "array", "object"].includes(
|
|
@@ -1080,7 +1108,7 @@ const zodFlagSchema = z.object({
|
|
|
1080
1108
|
}
|
|
1081
1109
|
)
|
|
1082
1110
|
]).default("string").describe(
|
|
1083
|
-
"Expected data type (constructor
|
|
1111
|
+
"Expected data type (constructor, string literal, custom parser function, or Zod schema). Defaults to 'string'."
|
|
1084
1112
|
),
|
|
1085
1113
|
mandatory: z.union([
|
|
1086
1114
|
z.boolean(),
|
|
@@ -1100,7 +1128,8 @@ const zodFlagSchema = z.object({
|
|
|
1100
1128
|
enum: z.array(z.any()).optional().describe("Array of allowed values for the flag."),
|
|
1101
1129
|
env: z.union([z.string(), z.array(z.string())]).optional().describe(
|
|
1102
1130
|
"Environment variables that should be set from this flag's value in DXT packages."
|
|
1103
|
-
)
|
|
1131
|
+
),
|
|
1132
|
+
dxtOptions: zodDxtOptionsSchema.optional().describe("DXT-specific configuration options for enhanced DXT manifest generation")
|
|
1104
1133
|
}).transform((obj) => {
|
|
1105
1134
|
const newObj = { ...obj };
|
|
1106
1135
|
if ("default" in newObj && newObj["default"] !== void 0 && !("defaultValue" in newObj)) {
|
|
@@ -1112,6 +1141,9 @@ const zodFlagSchema = z.object({
|
|
|
1112
1141
|
return newObj;
|
|
1113
1142
|
});
|
|
1114
1143
|
function getJsonSchemaTypeFromFlag(flagType) {
|
|
1144
|
+
if (flagType && typeof flagType === "object" && flagType._def) {
|
|
1145
|
+
return "object";
|
|
1146
|
+
}
|
|
1115
1147
|
if (typeof flagType === "function") {
|
|
1116
1148
|
if (flagType === String) return "string";
|
|
1117
1149
|
if (flagType === Number) return "number";
|
|
@@ -1295,6 +1327,353 @@ echo "Mock DXT build script for ${serverInfo.name}"`;
|
|
|
1295
1327
|
return 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"));
|
|
1296
1328
|
}
|
|
1297
1329
|
}
|
|
1330
|
+
function detectEntryPoint() {
|
|
1331
|
+
try {
|
|
1332
|
+
if (process.argv[1] && fs.existsSync(process.argv[1])) {
|
|
1333
|
+
return process.argv[1];
|
|
1334
|
+
}
|
|
1335
|
+
if (typeof require !== "undefined" && require.main && require.main.filename) {
|
|
1336
|
+
return require.main.filename;
|
|
1337
|
+
}
|
|
1338
|
+
return null;
|
|
1339
|
+
} catch {
|
|
1340
|
+
return null;
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
function getEntryPointFromImportMeta(importMetaUrl) {
|
|
1344
|
+
if (importMetaUrl.startsWith("file://")) {
|
|
1345
|
+
return decodeURIComponent(importMetaUrl.replace("file://", ""));
|
|
1346
|
+
}
|
|
1347
|
+
return importMetaUrl;
|
|
1348
|
+
}
|
|
1349
|
+
function normalizePath(path2) {
|
|
1350
|
+
return path2.trim();
|
|
1351
|
+
}
|
|
1352
|
+
function resolveLogPath(logPath, fallbackEntryPoint) {
|
|
1353
|
+
if (typeof logPath === "string") {
|
|
1354
|
+
const pathWithVariables2 = DxtPathResolver.substituteVariables(
|
|
1355
|
+
logPath,
|
|
1356
|
+
DxtPathResolver.detectContext()
|
|
1357
|
+
);
|
|
1358
|
+
const normalizedPath2 = normalizePath(pathWithVariables2);
|
|
1359
|
+
if (path.isAbsolute(normalizedPath2)) {
|
|
1360
|
+
return normalizedPath2;
|
|
1361
|
+
}
|
|
1362
|
+
if (normalizedPath2.startsWith("cwd:")) {
|
|
1363
|
+
const relativePath = normalizedPath2.slice(4);
|
|
1364
|
+
return path.resolve(process.cwd(), relativePath);
|
|
1365
|
+
}
|
|
1366
|
+
const entryPoint = detectEntryPoint() || fallbackEntryPoint;
|
|
1367
|
+
if (entryPoint) {
|
|
1368
|
+
return path.resolve(path.dirname(entryPoint), normalizedPath2);
|
|
1369
|
+
}
|
|
1370
|
+
console.warn(
|
|
1371
|
+
`Warning: Could not detect entry point for log path resolution. Using process.cwd() as fallback. Path: ${normalizedPath2}`
|
|
1372
|
+
);
|
|
1373
|
+
return path.resolve(process.cwd(), normalizedPath2);
|
|
1374
|
+
}
|
|
1375
|
+
const { path: logFilePath, relativeTo = "entry", basePath } = logPath;
|
|
1376
|
+
const pathWithVariables = DxtPathResolver.substituteVariables(
|
|
1377
|
+
logFilePath,
|
|
1378
|
+
DxtPathResolver.detectContext()
|
|
1379
|
+
);
|
|
1380
|
+
const normalizedPath = normalizePath(pathWithVariables);
|
|
1381
|
+
switch (relativeTo) {
|
|
1382
|
+
case "absolute":
|
|
1383
|
+
if (basePath) {
|
|
1384
|
+
const resolvedBasePath = DxtPathResolver.substituteVariables(
|
|
1385
|
+
basePath,
|
|
1386
|
+
DxtPathResolver.detectContext()
|
|
1387
|
+
);
|
|
1388
|
+
return path.resolve(resolvedBasePath, normalizedPath);
|
|
1389
|
+
}
|
|
1390
|
+
if (path.isAbsolute(normalizedPath)) {
|
|
1391
|
+
return normalizedPath;
|
|
1392
|
+
}
|
|
1393
|
+
console.warn(
|
|
1394
|
+
`Warning: relativeTo 'absolute' specified but no basePath provided and path is not absolute. Using process.cwd() as fallback. Path: ${normalizedPath}`
|
|
1395
|
+
);
|
|
1396
|
+
return path.resolve(process.cwd(), normalizedPath);
|
|
1397
|
+
case "cwd":
|
|
1398
|
+
return path.resolve(process.cwd(), normalizedPath);
|
|
1399
|
+
case "entry":
|
|
1400
|
+
default:
|
|
1401
|
+
const entryPoint = detectEntryPoint() || fallbackEntryPoint;
|
|
1402
|
+
if (entryPoint) {
|
|
1403
|
+
return path.resolve(path.dirname(entryPoint), normalizedPath);
|
|
1404
|
+
}
|
|
1405
|
+
console.warn(
|
|
1406
|
+
`Warning: Could not detect entry point for log path resolution. Using process.cwd() as fallback. Path: ${normalizedPath}`
|
|
1407
|
+
);
|
|
1408
|
+
return path.resolve(process.cwd(), normalizedPath);
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
function entryRelative(path2) {
|
|
1412
|
+
return {
|
|
1413
|
+
path: path2,
|
|
1414
|
+
relativeTo: "entry"
|
|
1415
|
+
};
|
|
1416
|
+
}
|
|
1417
|
+
function cwdRelative(path2) {
|
|
1418
|
+
return {
|
|
1419
|
+
path: path2,
|
|
1420
|
+
relativeTo: "cwd"
|
|
1421
|
+
};
|
|
1422
|
+
}
|
|
1423
|
+
function absolutePath(path2, basePath) {
|
|
1424
|
+
return {
|
|
1425
|
+
path: path2,
|
|
1426
|
+
relativeTo: "absolute",
|
|
1427
|
+
basePath
|
|
1428
|
+
};
|
|
1429
|
+
}
|
|
1430
|
+
function legacyCwdPath(path2) {
|
|
1431
|
+
return `cwd:${path2}`;
|
|
1432
|
+
}
|
|
1433
|
+
const _DxtPathResolver = class _DxtPathResolver {
|
|
1434
|
+
/**
|
|
1435
|
+
* Detects the current execution context
|
|
1436
|
+
* @param forceRefresh - Force refresh of cached context
|
|
1437
|
+
* @returns Path context information
|
|
1438
|
+
*/
|
|
1439
|
+
static detectContext(forceRefresh = false) {
|
|
1440
|
+
if (!forceRefresh && this._cachedContext) {
|
|
1441
|
+
return this._cachedContext;
|
|
1442
|
+
}
|
|
1443
|
+
const context = {
|
|
1444
|
+
isDxt: this.isDxtEnvironment(),
|
|
1445
|
+
userHome: void 0,
|
|
1446
|
+
cwd: typeof process !== "undefined" && typeof process.cwd === "function" ? process.cwd() : void 0
|
|
1447
|
+
};
|
|
1448
|
+
const entryPoint = detectEntryPoint();
|
|
1449
|
+
if (entryPoint) {
|
|
1450
|
+
context.entryDir = path.dirname(entryPoint);
|
|
1451
|
+
}
|
|
1452
|
+
if (context.isDxt) {
|
|
1453
|
+
context.extensionDir = this.detectDxtExtensionDir();
|
|
1454
|
+
}
|
|
1455
|
+
this._cachedContext = context;
|
|
1456
|
+
return context;
|
|
1457
|
+
}
|
|
1458
|
+
/**
|
|
1459
|
+
* Checks if the current environment is a DXT environment
|
|
1460
|
+
* @returns True if running in DXT, false otherwise
|
|
1461
|
+
*/
|
|
1462
|
+
static isDxtEnvironment() {
|
|
1463
|
+
if (process.env["DXT_EXTENSION_DIR"] || process.env["CLAUDE_DESKTOP_DXT"]) {
|
|
1464
|
+
return true;
|
|
1465
|
+
}
|
|
1466
|
+
const dxtIndicators = [
|
|
1467
|
+
"manifest.json",
|
|
1468
|
+
// DXT packages have manifest.json
|
|
1469
|
+
".dxt"
|
|
1470
|
+
// DXT marker file
|
|
1471
|
+
];
|
|
1472
|
+
for (const indicator of dxtIndicators) {
|
|
1473
|
+
const indicatorPath = path.join(process.cwd(), indicator);
|
|
1474
|
+
if (fs.existsSync(indicatorPath)) {
|
|
1475
|
+
if (indicator === "manifest.json") {
|
|
1476
|
+
try {
|
|
1477
|
+
const manifest = JSON.parse(fs.readFileSync(indicatorPath, "utf-8"));
|
|
1478
|
+
if (manifest.server && manifest.user_config) {
|
|
1479
|
+
return true;
|
|
1480
|
+
}
|
|
1481
|
+
} catch {
|
|
1482
|
+
}
|
|
1483
|
+
} else {
|
|
1484
|
+
return true;
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
const cwd = process.cwd();
|
|
1489
|
+
if (cwd.includes("claude-desktop") || cwd.includes("extensions")) {
|
|
1490
|
+
return true;
|
|
1491
|
+
}
|
|
1492
|
+
return false;
|
|
1493
|
+
}
|
|
1494
|
+
/**
|
|
1495
|
+
* Detects the DXT extension directory
|
|
1496
|
+
* @returns DXT extension directory path or undefined
|
|
1497
|
+
*/
|
|
1498
|
+
static detectDxtExtensionDir() {
|
|
1499
|
+
if (process.env["DXT_EXTENSION_DIR"]) {
|
|
1500
|
+
return process.env["DXT_EXTENSION_DIR"];
|
|
1501
|
+
}
|
|
1502
|
+
const cwd = process.cwd();
|
|
1503
|
+
if (fs.existsSync(path.join(cwd, "manifest.json"))) {
|
|
1504
|
+
return cwd;
|
|
1505
|
+
}
|
|
1506
|
+
let currentDir = cwd;
|
|
1507
|
+
for (let i = 0; i < 3; i++) {
|
|
1508
|
+
const parentDir = path.dirname(currentDir);
|
|
1509
|
+
if (parentDir === currentDir) break;
|
|
1510
|
+
if (fs.existsSync(path.join(parentDir, "manifest.json"))) {
|
|
1511
|
+
return parentDir;
|
|
1512
|
+
}
|
|
1513
|
+
currentDir = parentDir;
|
|
1514
|
+
}
|
|
1515
|
+
return void 0;
|
|
1516
|
+
}
|
|
1517
|
+
/**
|
|
1518
|
+
* Resolves a path with DXT variable substitution
|
|
1519
|
+
* @param inputPath - Path that may contain DXT variables
|
|
1520
|
+
* @param context - Optional context (will be detected if not provided)
|
|
1521
|
+
* @param config - Optional configuration for variable substitution
|
|
1522
|
+
* @returns Resolved absolute path
|
|
1523
|
+
*/
|
|
1524
|
+
static resolvePath(inputPath, context, config) {
|
|
1525
|
+
const ctx = context || this.detectContext();
|
|
1526
|
+
const resolvedPath = this.substituteVariables(inputPath, ctx, config);
|
|
1527
|
+
if (path.isAbsolute(resolvedPath)) {
|
|
1528
|
+
return resolvedPath;
|
|
1529
|
+
}
|
|
1530
|
+
if (ctx.isDxt && ctx.extensionDir) {
|
|
1531
|
+
return path.resolve(ctx.extensionDir, resolvedPath);
|
|
1532
|
+
} else if (ctx.entryDir) {
|
|
1533
|
+
return path.resolve(ctx.entryDir, resolvedPath);
|
|
1534
|
+
} else {
|
|
1535
|
+
return path.resolve(ctx.cwd || process.cwd(), resolvedPath);
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1538
|
+
/**
|
|
1539
|
+
* Substitutes DXT variables in a path string
|
|
1540
|
+
* @param inputPath - Path containing variables like ${HOME}, ${__dirname}, etc.
|
|
1541
|
+
* @param context - Path context
|
|
1542
|
+
* @param config - Variable substitution configuration
|
|
1543
|
+
* @returns Path with variables substituted
|
|
1544
|
+
*/
|
|
1545
|
+
static substituteVariables(inputPath, context, config) {
|
|
1546
|
+
const safeHomedir = () => "/tmp";
|
|
1547
|
+
const homeDir = context.userHome || safeHomedir();
|
|
1548
|
+
const variables = {
|
|
1549
|
+
// Standard DXT variables
|
|
1550
|
+
HOME: homeDir,
|
|
1551
|
+
DOCUMENTS: path.join(homeDir, "Documents"),
|
|
1552
|
+
DOWNLOADS: path.join(homeDir, "Downloads"),
|
|
1553
|
+
DESKTOP: path.join(homeDir, "Desktop"),
|
|
1554
|
+
pathSeparator: path.sep,
|
|
1555
|
+
// Context-specific variables
|
|
1556
|
+
__dirname: context.isDxt && context.extensionDir ? context.extensionDir : context.entryDir || context.cwd || process.cwd(),
|
|
1557
|
+
// DXT-specific variables
|
|
1558
|
+
...context.isDxt && context.extensionDir && {
|
|
1559
|
+
DXT_DIR: context.extensionDir,
|
|
1560
|
+
EXTENSION_DIR: context.extensionDir
|
|
1561
|
+
},
|
|
1562
|
+
// Custom variables override defaults
|
|
1563
|
+
...config == null ? void 0 : config.customVariables
|
|
1564
|
+
};
|
|
1565
|
+
return inputPath.replace(/\$\{([^}]*)\}/g, (match, variableName) => {
|
|
1566
|
+
if (!variableName.trim()) {
|
|
1567
|
+
if (config == null ? void 0 : config.allowUndefined) {
|
|
1568
|
+
return match;
|
|
1569
|
+
}
|
|
1570
|
+
throw new Error(
|
|
1571
|
+
`Undefined DXT variable: ${variableName}. Available variables: ${Object.keys(variables).join(", ")}`
|
|
1572
|
+
);
|
|
1573
|
+
}
|
|
1574
|
+
const value = variables[variableName];
|
|
1575
|
+
if (value !== void 0) {
|
|
1576
|
+
return value;
|
|
1577
|
+
}
|
|
1578
|
+
if (config == null ? void 0 : config.allowUndefined) {
|
|
1579
|
+
return match;
|
|
1580
|
+
}
|
|
1581
|
+
throw new Error(
|
|
1582
|
+
`Undefined DXT variable: ${variableName}. Available variables: ${Object.keys(variables).join(", ")}`
|
|
1583
|
+
);
|
|
1584
|
+
});
|
|
1585
|
+
}
|
|
1586
|
+
/**
|
|
1587
|
+
* Creates a path for user data storage
|
|
1588
|
+
* @param filename - Name of the file or subdirectory
|
|
1589
|
+
* @param context - Optional context (will be detected if not provided)
|
|
1590
|
+
* @returns Absolute path for user data
|
|
1591
|
+
*/
|
|
1592
|
+
static createUserDataPath(filename, context) {
|
|
1593
|
+
const ctx = context || this.detectContext();
|
|
1594
|
+
if (ctx.isDxt && ctx.extensionDir) {
|
|
1595
|
+
return path.join(ctx.extensionDir, "data", filename);
|
|
1596
|
+
} else {
|
|
1597
|
+
const safeHomedir = () => "/tmp";
|
|
1598
|
+
const userDataDir = process.env["XDG_DATA_HOME"] || path.join(ctx.userHome || safeHomedir(), ".local", "share");
|
|
1599
|
+
const appName = this.getAppName(ctx);
|
|
1600
|
+
return path.join(userDataDir, appName, filename);
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
/**
|
|
1604
|
+
* Creates a path for temporary files
|
|
1605
|
+
* @param filename - Name of the temporary file
|
|
1606
|
+
* @param context - Optional context (will be detected if not provided)
|
|
1607
|
+
* @returns Absolute path for temporary file
|
|
1608
|
+
*/
|
|
1609
|
+
static createTempPath(filename, context) {
|
|
1610
|
+
const ctx = context || this.detectContext();
|
|
1611
|
+
if (ctx.isDxt && ctx.extensionDir) {
|
|
1612
|
+
return path.join(ctx.extensionDir, "temp", filename);
|
|
1613
|
+
} else {
|
|
1614
|
+
const safeTmpdir = () => "/tmp";
|
|
1615
|
+
const appName = this.getAppName(ctx);
|
|
1616
|
+
return path.join(safeTmpdir(), appName, filename);
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
/**
|
|
1620
|
+
* Creates a path for configuration files
|
|
1621
|
+
* @param filename - Name of the configuration file
|
|
1622
|
+
* @param context - Optional context (will be detected if not provided)
|
|
1623
|
+
* @returns Absolute path for configuration file
|
|
1624
|
+
*/
|
|
1625
|
+
static createConfigPath(filename, context) {
|
|
1626
|
+
const ctx = context || this.detectContext();
|
|
1627
|
+
if (ctx.isDxt && ctx.extensionDir) {
|
|
1628
|
+
return path.join(ctx.extensionDir, "config", filename);
|
|
1629
|
+
} else {
|
|
1630
|
+
const safeHomedir = () => "/tmp";
|
|
1631
|
+
const configDir = process.env["XDG_CONFIG_HOME"] || path.join(ctx.userHome || safeHomedir(), ".config");
|
|
1632
|
+
const appName = this.getAppName(ctx);
|
|
1633
|
+
return path.join(configDir, appName, filename);
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
/**
|
|
1637
|
+
* Gets the application name for directory creation
|
|
1638
|
+
* @param context - Path context
|
|
1639
|
+
* @returns Application name or default
|
|
1640
|
+
*/
|
|
1641
|
+
static getAppName(context) {
|
|
1642
|
+
try {
|
|
1643
|
+
const packageJsonPath = path.join(context.entryDir || context.cwd || process.cwd(), "package.json");
|
|
1644
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
1645
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
1646
|
+
return packageJson.name || "argparser-app";
|
|
1647
|
+
}
|
|
1648
|
+
} catch {
|
|
1649
|
+
}
|
|
1650
|
+
return "argparser-app";
|
|
1651
|
+
}
|
|
1652
|
+
/**
|
|
1653
|
+
* Ensures a directory exists, creating it if necessary
|
|
1654
|
+
* @param dirPath - Directory path to ensure
|
|
1655
|
+
* @returns True if directory exists or was created successfully
|
|
1656
|
+
*/
|
|
1657
|
+
static ensureDirectory(dirPath) {
|
|
1658
|
+
try {
|
|
1659
|
+
if (!fs.existsSync(dirPath)) {
|
|
1660
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
1661
|
+
}
|
|
1662
|
+
return true;
|
|
1663
|
+
} catch (error) {
|
|
1664
|
+
console.warn(`Failed to create directory: ${dirPath}`, error);
|
|
1665
|
+
return false;
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
/**
|
|
1669
|
+
* Clears the cached context (useful for testing)
|
|
1670
|
+
*/
|
|
1671
|
+
static clearCache() {
|
|
1672
|
+
this._cachedContext = null;
|
|
1673
|
+
}
|
|
1674
|
+
};
|
|
1675
|
+
_DxtPathResolver._cachedContext = null;
|
|
1676
|
+
let DxtPathResolver = _DxtPathResolver;
|
|
1298
1677
|
class DxtGenerator {
|
|
1299
1678
|
constructor(argParserInstance) {
|
|
1300
1679
|
this.argParserInstance = argParserInstance;
|
|
@@ -1704,100 +2083,128 @@ class DxtGenerator {
|
|
|
1704
2083
|
silent: process.env["NO_SILENCE"] !== "1",
|
|
1705
2084
|
unbundle: true,
|
|
1706
2085
|
external: (id, importer) => {
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
if (Boolean(process.env["DEBUG"]))
|
|
1713
|
-
console.log(
|
|
1714
|
-
`[${simpleChalk.blue("External")}] ${simpleChalk.yellow(external ? "true" : "false")} for module: (${simpleChalk.green(id)}), path: '${simpleChalk.grey(importer ?? "")}'`
|
|
2086
|
+
try {
|
|
2087
|
+
const external = this.shouldModuleBeExternal(
|
|
2088
|
+
id,
|
|
2089
|
+
importer,
|
|
2090
|
+
withNodeModules
|
|
1715
2091
|
);
|
|
1716
|
-
|
|
2092
|
+
if (Boolean(process.env["DEBUG"]))
|
|
2093
|
+
console.log(
|
|
2094
|
+
`[${simpleChalk.blue("External")}] ${simpleChalk.yellow(external ? "true" : "false")} for module: (${simpleChalk.green(id)}), path: '${simpleChalk.grey(importer ?? "")}'`
|
|
2095
|
+
);
|
|
2096
|
+
return Boolean(external);
|
|
2097
|
+
} catch (error) {
|
|
2098
|
+
console.warn(`Warning: Error in external function for ${id}:`, error);
|
|
2099
|
+
return true;
|
|
2100
|
+
}
|
|
1717
2101
|
},
|
|
1718
2102
|
noExternal: (id, importer) => {
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
if (Boolean(process.env["DEBUG"]))
|
|
1725
|
-
console.log(
|
|
1726
|
-
`[${simpleChalk.yellow("noExternal")}] ${simpleChalk.yellow(external === false ? "true" : "false")} for module: (${simpleChalk.green(id)}), path: '${simpleChalk.grey(importer ?? "")}'`
|
|
2103
|
+
try {
|
|
2104
|
+
const external = this.shouldModuleBeExternal(
|
|
2105
|
+
id,
|
|
2106
|
+
importer,
|
|
2107
|
+
withNodeModules
|
|
1727
2108
|
);
|
|
1728
|
-
|
|
2109
|
+
if (Boolean(process.env["DEBUG"]))
|
|
2110
|
+
console.log(
|
|
2111
|
+
`[${simpleChalk.yellow("noExternal")}] ${simpleChalk.yellow(external === false ? "true" : "false")} for module: (${simpleChalk.green(id)}), path: '${simpleChalk.grey(importer ?? "")}'`
|
|
2112
|
+
);
|
|
2113
|
+
return Boolean(external === false);
|
|
2114
|
+
} catch (error) {
|
|
2115
|
+
console.warn(`Warning: Error in noExternal function for ${id}:`, error);
|
|
2116
|
+
return false;
|
|
2117
|
+
}
|
|
1729
2118
|
},
|
|
1730
2119
|
copy: async (options) => {
|
|
1731
2120
|
var _a2;
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
const dxtPackageRoot = entryDir !== "." && entryDir !== "" ? path.dirname(options.outDir) : options.outDir;
|
|
1744
|
-
if (logoFilename) {
|
|
1745
|
-
const currentDir = typeof process !== "undefined" ? process.cwd() : "/test";
|
|
1746
|
-
const logoPath = path.join(currentDir, logoFilename);
|
|
1747
|
-
if (fs.existsSync(logoPath)) {
|
|
1748
|
-
console.log(simpleChalk.gray(`Adding logo from: ${logoPath}`));
|
|
1749
|
-
outputPaths.push({
|
|
1750
|
-
from: logoPath,
|
|
1751
|
-
to: path.join(dxtPackageRoot, logoFilename)
|
|
1752
|
-
});
|
|
2121
|
+
try {
|
|
2122
|
+
const outputPaths = [
|
|
2123
|
+
"package.json"
|
|
2124
|
+
];
|
|
2125
|
+
if (withNodeModules) {
|
|
2126
|
+
console.log(
|
|
2127
|
+
simpleChalk.gray(
|
|
2128
|
+
"📦 Including node_modules in bundle (may take longer)..."
|
|
2129
|
+
)
|
|
2130
|
+
);
|
|
2131
|
+
outputPaths.push("node_modules");
|
|
1753
2132
|
}
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
projectRoot,
|
|
1780
|
-
includeItem.from
|
|
1781
|
-
);
|
|
1782
|
-
if (fs.existsSync(sourcePath)) {
|
|
1783
|
-
console.log(
|
|
1784
|
-
simpleChalk.gray(` • ${includeItem.from} → ${includeItem.to}`)
|
|
2133
|
+
const dxtPackageRoot = entryDir !== "." && entryDir !== "" ? path.dirname(options.outDir) : options.outDir;
|
|
2134
|
+
if (logoFilename) {
|
|
2135
|
+
const currentDir = typeof process !== "undefined" ? process.cwd() : "/test";
|
|
2136
|
+
const logoPath = path.join(currentDir, logoFilename);
|
|
2137
|
+
if (fs.existsSync(logoPath)) {
|
|
2138
|
+
console.log(simpleChalk.gray(`Adding logo from: ${logoPath}`));
|
|
2139
|
+
outputPaths.push({
|
|
2140
|
+
from: logoPath,
|
|
2141
|
+
to: path.join(dxtPackageRoot, logoFilename)
|
|
2142
|
+
});
|
|
2143
|
+
}
|
|
2144
|
+
}
|
|
2145
|
+
if ((_a2 = mcpConfig == null ? void 0 : mcpConfig.dxt) == null ? void 0 : _a2.include) {
|
|
2146
|
+
console.log(
|
|
2147
|
+
simpleChalk.gray(
|
|
2148
|
+
"📁 Including additional files from DXT configuration..."
|
|
2149
|
+
)
|
|
2150
|
+
);
|
|
2151
|
+
for (const includeItem of mcpConfig.dxt.include) {
|
|
2152
|
+
if (typeof includeItem === "string") {
|
|
2153
|
+
const resolvedIncludePath = DxtPathResolver.substituteVariables(
|
|
2154
|
+
includeItem,
|
|
2155
|
+
DxtPathResolver.detectContext(),
|
|
2156
|
+
{ allowUndefined: true }
|
|
2157
|
+
// Allow undefined variables for flexibility
|
|
1785
2158
|
);
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
2159
|
+
const sourcePath = path.resolve(projectRoot, resolvedIncludePath);
|
|
2160
|
+
if (fs.existsSync(sourcePath)) {
|
|
2161
|
+
console.log(simpleChalk.gray(` • ${resolvedIncludePath}`));
|
|
2162
|
+
outputPaths.push({
|
|
2163
|
+
from: sourcePath,
|
|
2164
|
+
to: path.join(dxtPackageRoot, resolvedIncludePath)
|
|
2165
|
+
});
|
|
2166
|
+
} else {
|
|
2167
|
+
console.warn(
|
|
2168
|
+
simpleChalk.yellow(
|
|
2169
|
+
` ⚠ File not found: ${resolvedIncludePath} (resolved to ${sourcePath})`
|
|
2170
|
+
)
|
|
2171
|
+
);
|
|
2172
|
+
}
|
|
1790
2173
|
} else {
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
2174
|
+
const resolvedFromPath = DxtPathResolver.substituteVariables(
|
|
2175
|
+
includeItem.from,
|
|
2176
|
+
DxtPathResolver.detectContext(),
|
|
2177
|
+
{ allowUndefined: true }
|
|
2178
|
+
);
|
|
2179
|
+
const resolvedToPath = DxtPathResolver.substituteVariables(
|
|
2180
|
+
includeItem.to,
|
|
2181
|
+
DxtPathResolver.detectContext(),
|
|
2182
|
+
{ allowUndefined: true }
|
|
1795
2183
|
);
|
|
2184
|
+
const sourcePath = path.resolve(projectRoot, resolvedFromPath);
|
|
2185
|
+
if (fs.existsSync(sourcePath)) {
|
|
2186
|
+
console.log(
|
|
2187
|
+
simpleChalk.gray(` • ${resolvedFromPath} → ${resolvedToPath}`)
|
|
2188
|
+
);
|
|
2189
|
+
outputPaths.push({
|
|
2190
|
+
from: sourcePath,
|
|
2191
|
+
to: path.join(dxtPackageRoot, resolvedToPath)
|
|
2192
|
+
});
|
|
2193
|
+
} else {
|
|
2194
|
+
console.warn(
|
|
2195
|
+
simpleChalk.yellow(
|
|
2196
|
+
` ⚠ File not found: ${resolvedFromPath} (resolved to ${sourcePath})`
|
|
2197
|
+
)
|
|
2198
|
+
);
|
|
2199
|
+
}
|
|
1796
2200
|
}
|
|
1797
2201
|
}
|
|
1798
2202
|
}
|
|
2203
|
+
return outputPaths;
|
|
2204
|
+
} catch (error) {
|
|
2205
|
+
console.warn(`Warning: Error in copy function:`, error);
|
|
2206
|
+
return ["package.json"];
|
|
1799
2207
|
}
|
|
1800
|
-
return outputPaths;
|
|
1801
2208
|
},
|
|
1802
2209
|
platform: "node",
|
|
1803
2210
|
plugins: []
|
|
@@ -1825,8 +2232,18 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
1825
2232
|
simpleChalk.gray("📝 Debug config written to dxt/tsdown.config.dxt.ts")
|
|
1826
2233
|
);
|
|
1827
2234
|
}
|
|
1828
|
-
|
|
1829
|
-
|
|
2235
|
+
try {
|
|
2236
|
+
await build(buildConfig);
|
|
2237
|
+
console.log(simpleChalk.green("✅ TSDown bundling completed"));
|
|
2238
|
+
} catch (buildError) {
|
|
2239
|
+
console.error(simpleChalk.red("❌ TSDown build failed with error:"));
|
|
2240
|
+
console.error(buildError);
|
|
2241
|
+
if (buildError instanceof Error) {
|
|
2242
|
+
console.error(simpleChalk.red("Error message:"), buildError.message);
|
|
2243
|
+
console.error(simpleChalk.red("Error stack:"), buildError.stack);
|
|
2244
|
+
}
|
|
2245
|
+
throw new Error(`TSDown DXT build failed: ${buildError instanceof Error ? buildError.message : String(buildError)}`);
|
|
2246
|
+
}
|
|
1830
2247
|
const detectedOutputFile = this.detectTsdownOutputFile(
|
|
1831
2248
|
outputDir,
|
|
1832
2249
|
relativeEntryPath.replace(/\.ts$/, ".js")
|
|
@@ -2085,7 +2502,7 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2085
2502
|
if (flag.enum) {
|
|
2086
2503
|
properties2[flag.name].enum = flag.enum;
|
|
2087
2504
|
}
|
|
2088
|
-
if (flag.defaultValue !== void 0) {
|
|
2505
|
+
if (flag.defaultValue !== void 0 && typeof flag.defaultValue !== "function") {
|
|
2089
2506
|
properties2[flag.name].default = flag.defaultValue;
|
|
2090
2507
|
}
|
|
2091
2508
|
if (flag.mandatory) {
|
|
@@ -2260,11 +2677,62 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2260
2677
|
`Could not find package.json within ${maxAttempts} directories up from ${entryPointFile}. Please ensure your entry point is within a project that has a package.json file.`
|
|
2261
2678
|
);
|
|
2262
2679
|
}
|
|
2680
|
+
/**
|
|
2681
|
+
* Validate dxtOptions for common mistakes and security issues
|
|
2682
|
+
* @param flag The flag with dxtOptions to validate
|
|
2683
|
+
* @param envVar The environment variable name for context
|
|
2684
|
+
*/
|
|
2685
|
+
validateDxtOptions(flag, envVar) {
|
|
2686
|
+
const dxtOptions = flag.dxtOptions;
|
|
2687
|
+
if (!dxtOptions) return;
|
|
2688
|
+
if (dxtOptions.min !== void 0 && dxtOptions.max !== void 0) {
|
|
2689
|
+
if (dxtOptions.min > dxtOptions.max) {
|
|
2690
|
+
throw new Error(
|
|
2691
|
+
`Invalid dxtOptions for ${envVar}: min (${dxtOptions.min}) cannot be greater than max (${dxtOptions.max})`
|
|
2692
|
+
);
|
|
2693
|
+
}
|
|
2694
|
+
}
|
|
2695
|
+
if (dxtOptions.type !== void 0) {
|
|
2696
|
+
const validTypes = ["string", "directory", "file", "boolean", "number"];
|
|
2697
|
+
if (!validTypes.includes(dxtOptions.type)) {
|
|
2698
|
+
throw new Error(
|
|
2699
|
+
`Invalid dxtOptions.type for ${envVar}: "${dxtOptions.type}". Must be one of: ${validTypes.join(", ")}`
|
|
2700
|
+
);
|
|
2701
|
+
}
|
|
2702
|
+
}
|
|
2703
|
+
if (dxtOptions.default !== void 0 && dxtOptions.type !== void 0) {
|
|
2704
|
+
const defaultType = typeof dxtOptions.default;
|
|
2705
|
+
if (dxtOptions.type === "number" && defaultType !== "number") {
|
|
2706
|
+
throw new Error(
|
|
2707
|
+
`Invalid dxtOptions.default for ${envVar}: expected number, got ${defaultType}`
|
|
2708
|
+
);
|
|
2709
|
+
}
|
|
2710
|
+
if (dxtOptions.type === "boolean" && defaultType !== "boolean") {
|
|
2711
|
+
throw new Error(
|
|
2712
|
+
`Invalid dxtOptions.default for ${envVar}: expected boolean, got ${defaultType}`
|
|
2713
|
+
);
|
|
2714
|
+
}
|
|
2715
|
+
}
|
|
2716
|
+
const sensitiveKeywords = ["key", "token", "password", "secret", "auth"];
|
|
2717
|
+
const envLower = envVar.toLowerCase();
|
|
2718
|
+
const hasSensitiveKeyword = sensitiveKeywords.some((keyword2) => envLower.includes(keyword2));
|
|
2719
|
+
if (hasSensitiveKeyword && dxtOptions.sensitive === false) {
|
|
2720
|
+
console.warn(
|
|
2721
|
+
`⚠️ Security Warning: ${envVar} contains sensitive keyword but dxtOptions.sensitive is false`
|
|
2722
|
+
);
|
|
2723
|
+
}
|
|
2724
|
+
if (flag.mandatory === true && dxtOptions.sensitive !== false) {
|
|
2725
|
+
console.warn(
|
|
2726
|
+
`⚠️ Security Warning: ${envVar} is required and sensitive - consider providing a secure default or making it optional`
|
|
2727
|
+
);
|
|
2728
|
+
}
|
|
2729
|
+
}
|
|
2263
2730
|
/**
|
|
2264
2731
|
* Generate environment variables and user configuration from ArgParser flags
|
|
2265
2732
|
* @returns Object containing envVars and userConfig
|
|
2266
2733
|
*/
|
|
2267
2734
|
generateEnvAndUserConfig() {
|
|
2735
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
2268
2736
|
const envVars = {};
|
|
2269
2737
|
const userConfig = {};
|
|
2270
2738
|
const shouldBeRequired = (flag) => {
|
|
@@ -2277,23 +2745,78 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2277
2745
|
return false;
|
|
2278
2746
|
};
|
|
2279
2747
|
const shouldBeSensitive = (flag) => {
|
|
2748
|
+
var _a2;
|
|
2749
|
+
if (((_a2 = flag.dxtOptions) == null ? void 0 : _a2.sensitive) !== void 0) {
|
|
2750
|
+
return flag.dxtOptions.sensitive;
|
|
2751
|
+
}
|
|
2280
2752
|
const envVar = flag.env || flag.envVar;
|
|
2281
2753
|
return !!envVar;
|
|
2282
2754
|
};
|
|
2755
|
+
const getDxtType = (flag) => {
|
|
2756
|
+
var _a2;
|
|
2757
|
+
if ((_a2 = flag.dxtOptions) == null ? void 0 : _a2.type) {
|
|
2758
|
+
return flag.dxtOptions.type;
|
|
2759
|
+
}
|
|
2760
|
+
if (typeof flag.type === "string") {
|
|
2761
|
+
const lowerType = flag.type.toLowerCase();
|
|
2762
|
+
if (["string", "boolean", "number"].includes(lowerType)) {
|
|
2763
|
+
return lowerType;
|
|
2764
|
+
}
|
|
2765
|
+
} else if (flag.type === String) {
|
|
2766
|
+
return "string";
|
|
2767
|
+
} else if (flag.type === Boolean) {
|
|
2768
|
+
return "boolean";
|
|
2769
|
+
} else if (flag.type === Number) {
|
|
2770
|
+
return "number";
|
|
2771
|
+
}
|
|
2772
|
+
return "string";
|
|
2773
|
+
};
|
|
2774
|
+
const getDxtTitle = (flag, envVar) => {
|
|
2775
|
+
var _a2;
|
|
2776
|
+
if ((_a2 = flag.dxtOptions) == null ? void 0 : _a2.title) {
|
|
2777
|
+
return flag.dxtOptions.title;
|
|
2778
|
+
}
|
|
2779
|
+
return envVar.replace(/_/g, " ").toLowerCase().replace(/\b\w/g, (l) => l.toUpperCase());
|
|
2780
|
+
};
|
|
2781
|
+
const getDxtDescription = (flag, envVar) => {
|
|
2782
|
+
var _a2, _b2;
|
|
2783
|
+
let baseDescription = flag.description || `${envVar} environment variable`;
|
|
2784
|
+
const defaultValue = ((_a2 = flag.dxtOptions) == null ? void 0 : _a2.default) ?? ((_b2 = flag.dxtOptions) == null ? void 0 : _b2.localDefault) ?? flag.defaultValue;
|
|
2785
|
+
if (defaultValue !== void 0 && typeof defaultValue !== "function") {
|
|
2786
|
+
baseDescription += ` (default: ${defaultValue})`;
|
|
2787
|
+
}
|
|
2788
|
+
return baseDescription;
|
|
2789
|
+
};
|
|
2283
2790
|
const mainFlags = this.argParserInstance.flags;
|
|
2284
2791
|
for (const flag of mainFlags) {
|
|
2285
2792
|
const envVar = flag.env || flag.envVar;
|
|
2286
2793
|
if (envVar) {
|
|
2794
|
+
this.validateDxtOptions(flag, envVar);
|
|
2287
2795
|
envVars[envVar] = `\${user_config.${envVar}}`;
|
|
2288
|
-
|
|
2289
|
-
type:
|
|
2290
|
-
title:
|
|
2291
|
-
description: flag
|
|
2796
|
+
const userConfigEntry = {
|
|
2797
|
+
type: getDxtType(flag),
|
|
2798
|
+
title: getDxtTitle(flag, envVar),
|
|
2799
|
+
description: getDxtDescription(flag, envVar),
|
|
2292
2800
|
required: shouldBeRequired(flag),
|
|
2293
2801
|
// Respect the flag's mandatory setting
|
|
2294
2802
|
sensitive: shouldBeSensitive(flag)
|
|
2295
|
-
//
|
|
2803
|
+
// Use dxtOptions or default logic
|
|
2296
2804
|
};
|
|
2805
|
+
if (((_a = flag.dxtOptions) == null ? void 0 : _a.multiple) !== void 0) {
|
|
2806
|
+
userConfigEntry.multiple = flag.dxtOptions.multiple;
|
|
2807
|
+
}
|
|
2808
|
+
if (((_b = flag.dxtOptions) == null ? void 0 : _b.min) !== void 0) {
|
|
2809
|
+
userConfigEntry.min = flag.dxtOptions.min;
|
|
2810
|
+
}
|
|
2811
|
+
if (((_c = flag.dxtOptions) == null ? void 0 : _c.max) !== void 0) {
|
|
2812
|
+
userConfigEntry.max = flag.dxtOptions.max;
|
|
2813
|
+
}
|
|
2814
|
+
if (((_d = flag.dxtOptions) == null ? void 0 : _d.default) !== void 0 && typeof flag.dxtOptions.default !== "function") {
|
|
2815
|
+
userConfigEntry.default = flag.dxtOptions.default;
|
|
2816
|
+
} else if (((_e = flag.dxtOptions) == null ? void 0 : _e.localDefault) !== void 0 && typeof flag.dxtOptions.localDefault !== "function") {
|
|
2817
|
+
userConfigEntry.default = flag.dxtOptions.localDefault;
|
|
2818
|
+
}
|
|
2819
|
+
userConfig[envVar] = userConfigEntry;
|
|
2297
2820
|
}
|
|
2298
2821
|
}
|
|
2299
2822
|
if (typeof this.argParserInstance.getTools === "function") {
|
|
@@ -2303,16 +2826,32 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2303
2826
|
for (const flag of toolFlags) {
|
|
2304
2827
|
const envVar = flag.env || flag.envVar;
|
|
2305
2828
|
if (envVar && !envVars[envVar]) {
|
|
2829
|
+
this.validateDxtOptions(flag, envVar);
|
|
2306
2830
|
envVars[envVar] = `\${user_config.${envVar}}`;
|
|
2307
|
-
|
|
2308
|
-
type:
|
|
2309
|
-
title:
|
|
2310
|
-
description: flag
|
|
2831
|
+
const userConfigEntry = {
|
|
2832
|
+
type: getDxtType(flag),
|
|
2833
|
+
title: getDxtTitle(flag, envVar),
|
|
2834
|
+
description: getDxtDescription(flag, envVar),
|
|
2311
2835
|
required: shouldBeRequired(flag),
|
|
2312
2836
|
// Respect the flag's mandatory setting
|
|
2313
2837
|
sensitive: shouldBeSensitive(flag)
|
|
2314
|
-
//
|
|
2838
|
+
// Use dxtOptions or default logic
|
|
2315
2839
|
};
|
|
2840
|
+
if (((_f = flag.dxtOptions) == null ? void 0 : _f.multiple) !== void 0) {
|
|
2841
|
+
userConfigEntry.multiple = flag.dxtOptions.multiple;
|
|
2842
|
+
}
|
|
2843
|
+
if (((_g = flag.dxtOptions) == null ? void 0 : _g.min) !== void 0) {
|
|
2844
|
+
userConfigEntry.min = flag.dxtOptions.min;
|
|
2845
|
+
}
|
|
2846
|
+
if (((_h = flag.dxtOptions) == null ? void 0 : _h.max) !== void 0) {
|
|
2847
|
+
userConfigEntry.max = flag.dxtOptions.max;
|
|
2848
|
+
}
|
|
2849
|
+
if (((_i = flag.dxtOptions) == null ? void 0 : _i.default) !== void 0 && typeof flag.dxtOptions.default !== "function") {
|
|
2850
|
+
userConfigEntry.default = flag.dxtOptions.default;
|
|
2851
|
+
} else if (((_j = flag.dxtOptions) == null ? void 0 : _j.localDefault) !== void 0 && typeof flag.dxtOptions.localDefault !== "function") {
|
|
2852
|
+
userConfigEntry.default = flag.dxtOptions.localDefault;
|
|
2853
|
+
}
|
|
2854
|
+
userConfig[envVar] = userConfigEntry;
|
|
2316
2855
|
}
|
|
2317
2856
|
}
|
|
2318
2857
|
}
|
|
@@ -2343,10 +2882,10 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2343
2882
|
);
|
|
2344
2883
|
}
|
|
2345
2884
|
const pathsMatcher = createPathsMatcher(tsconfig);
|
|
2346
|
-
if (!pathsMatcher) {
|
|
2885
|
+
if (!pathsMatcher || typeof pathsMatcher !== "function") {
|
|
2347
2886
|
if (Boolean(process.env["DEBUG"])) {
|
|
2348
2887
|
console.log(
|
|
2349
|
-
` <${simpleChalk.gray("ts-paths")}> Failed to create paths matcher`
|
|
2888
|
+
` <${simpleChalk.gray("ts-paths")}> Failed to create paths matcher or matcher is not a function`
|
|
2350
2889
|
);
|
|
2351
2890
|
}
|
|
2352
2891
|
} else {
|
|
@@ -3056,7 +3595,8 @@ const _FlagManager = class _FlagManager {
|
|
|
3056
3595
|
validate: parsedFromZod["validate"],
|
|
3057
3596
|
enum: parsedFromZod["enum"],
|
|
3058
3597
|
mandatory: parsedFromZod["mandatory"],
|
|
3059
|
-
env: parsedFromZod["env"]
|
|
3598
|
+
env: parsedFromZod["env"],
|
|
3599
|
+
dxtOptions: parsedFromZod["dxtOptions"]
|
|
3060
3600
|
};
|
|
3061
3601
|
}
|
|
3062
3602
|
addFlag(flag) {
|
|
@@ -3105,97 +3645,6 @@ const _FlagManager = class _FlagManager {
|
|
|
3105
3645
|
__flags = new WeakMap();
|
|
3106
3646
|
_throwForDuplicateFlags = new WeakMap();
|
|
3107
3647
|
let FlagManager = _FlagManager;
|
|
3108
|
-
function detectEntryPoint() {
|
|
3109
|
-
try {
|
|
3110
|
-
if (process.argv[1] && fs.existsSync(process.argv[1])) {
|
|
3111
|
-
return process.argv[1];
|
|
3112
|
-
}
|
|
3113
|
-
if (typeof require !== "undefined" && require.main && require.main.filename) {
|
|
3114
|
-
return require.main.filename;
|
|
3115
|
-
}
|
|
3116
|
-
return null;
|
|
3117
|
-
} catch {
|
|
3118
|
-
return null;
|
|
3119
|
-
}
|
|
3120
|
-
}
|
|
3121
|
-
function getEntryPointFromImportMeta(importMetaUrl) {
|
|
3122
|
-
if (importMetaUrl.startsWith("file://")) {
|
|
3123
|
-
return decodeURIComponent(importMetaUrl.replace("file://", ""));
|
|
3124
|
-
}
|
|
3125
|
-
return importMetaUrl;
|
|
3126
|
-
}
|
|
3127
|
-
function normalizePath(path2) {
|
|
3128
|
-
return path2.trim();
|
|
3129
|
-
}
|
|
3130
|
-
function resolveLogPath(logPath, fallbackEntryPoint) {
|
|
3131
|
-
if (typeof logPath === "string") {
|
|
3132
|
-
const normalizedPath2 = normalizePath(logPath);
|
|
3133
|
-
if (path.isAbsolute(normalizedPath2)) {
|
|
3134
|
-
return normalizedPath2;
|
|
3135
|
-
}
|
|
3136
|
-
if (normalizedPath2.startsWith("cwd:")) {
|
|
3137
|
-
const relativePath = normalizedPath2.slice(4);
|
|
3138
|
-
return path.resolve(process.cwd(), relativePath);
|
|
3139
|
-
}
|
|
3140
|
-
const entryPoint = detectEntryPoint() || fallbackEntryPoint;
|
|
3141
|
-
if (entryPoint) {
|
|
3142
|
-
return path.resolve(path.dirname(entryPoint), normalizedPath2);
|
|
3143
|
-
}
|
|
3144
|
-
console.warn(
|
|
3145
|
-
`Warning: Could not detect entry point for log path resolution. Using process.cwd() as fallback. Path: ${normalizedPath2}`
|
|
3146
|
-
);
|
|
3147
|
-
return path.resolve(process.cwd(), normalizedPath2);
|
|
3148
|
-
}
|
|
3149
|
-
const { path: logFilePath, relativeTo = "entry", basePath } = logPath;
|
|
3150
|
-
const normalizedPath = normalizePath(logFilePath);
|
|
3151
|
-
switch (relativeTo) {
|
|
3152
|
-
case "absolute":
|
|
3153
|
-
if (basePath) {
|
|
3154
|
-
return path.resolve(basePath, normalizedPath);
|
|
3155
|
-
}
|
|
3156
|
-
if (path.isAbsolute(normalizedPath)) {
|
|
3157
|
-
return normalizedPath;
|
|
3158
|
-
}
|
|
3159
|
-
console.warn(
|
|
3160
|
-
`Warning: relativeTo 'absolute' specified but no basePath provided and path is not absolute. Using process.cwd() as fallback. Path: ${normalizedPath}`
|
|
3161
|
-
);
|
|
3162
|
-
return path.resolve(process.cwd(), normalizedPath);
|
|
3163
|
-
case "cwd":
|
|
3164
|
-
return path.resolve(process.cwd(), normalizedPath);
|
|
3165
|
-
case "entry":
|
|
3166
|
-
default:
|
|
3167
|
-
const entryPoint = detectEntryPoint() || fallbackEntryPoint;
|
|
3168
|
-
if (entryPoint) {
|
|
3169
|
-
return path.resolve(path.dirname(entryPoint), normalizedPath);
|
|
3170
|
-
}
|
|
3171
|
-
console.warn(
|
|
3172
|
-
`Warning: Could not detect entry point for log path resolution. Using process.cwd() as fallback. Path: ${normalizedPath}`
|
|
3173
|
-
);
|
|
3174
|
-
return path.resolve(process.cwd(), normalizedPath);
|
|
3175
|
-
}
|
|
3176
|
-
}
|
|
3177
|
-
function entryRelative(path2) {
|
|
3178
|
-
return {
|
|
3179
|
-
path: path2,
|
|
3180
|
-
relativeTo: "entry"
|
|
3181
|
-
};
|
|
3182
|
-
}
|
|
3183
|
-
function cwdRelative(path2) {
|
|
3184
|
-
return {
|
|
3185
|
-
path: path2,
|
|
3186
|
-
relativeTo: "cwd"
|
|
3187
|
-
};
|
|
3188
|
-
}
|
|
3189
|
-
function absolutePath(path2, basePath) {
|
|
3190
|
-
return {
|
|
3191
|
-
path: path2,
|
|
3192
|
-
relativeTo: "absolute",
|
|
3193
|
-
basePath
|
|
3194
|
-
};
|
|
3195
|
-
}
|
|
3196
|
-
function legacyCwdPath(path2) {
|
|
3197
|
-
return `cwd:${path2}`;
|
|
3198
|
-
}
|
|
3199
3648
|
class ArgParserError extends Error {
|
|
3200
3649
|
constructor(message, cmdChain = []) {
|
|
3201
3650
|
super(message);
|
|
@@ -3338,7 +3787,21 @@ const _ArgParserBase = class _ArgParserBase {
|
|
|
3338
3787
|
const result = flag["type"](value);
|
|
3339
3788
|
value = result && typeof result.then === "function" ? await result : result;
|
|
3340
3789
|
} else if (typeof flag["type"] === "object") {
|
|
3341
|
-
|
|
3790
|
+
if (flag["type"] && flag["type"]._def) {
|
|
3791
|
+
try {
|
|
3792
|
+
const parsedJson = typeof value === "string" ? JSON.parse(value) : value;
|
|
3793
|
+
value = flag["type"].parse(parsedJson);
|
|
3794
|
+
} catch (error) {
|
|
3795
|
+
if (error instanceof SyntaxError) {
|
|
3796
|
+
throw new Error(`Invalid JSON for flag '${flag["name"]}': ${error.message}`);
|
|
3797
|
+
} else {
|
|
3798
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
3799
|
+
throw new Error(`Validation failed for flag '${flag["name"]}': ${errorMessage}`);
|
|
3800
|
+
}
|
|
3801
|
+
}
|
|
3802
|
+
} else {
|
|
3803
|
+
value = new flag["type"](value);
|
|
3804
|
+
}
|
|
3342
3805
|
}
|
|
3343
3806
|
if (flag["enum"] && flag["enum"].length > 0) {
|
|
3344
3807
|
const allowedValues = flag["enum"].map((v) => typeof v === "string" ? `'${v}'` : v).join(", ");
|
|
@@ -3710,7 +4173,28 @@ ${cyan("Flags:")}
|
|
|
3710
4173
|
const descriptionLines = Array.isArray(flag["description"]) ? flag["description"] : [flag["description"]];
|
|
3711
4174
|
const metaLines = [];
|
|
3712
4175
|
let typeName = "unknown";
|
|
3713
|
-
|
|
4176
|
+
let typeDetails = [];
|
|
4177
|
+
if (flag["type"] && typeof flag["type"] === "object" && flag["type"]._def) {
|
|
4178
|
+
typeName = "JSON object";
|
|
4179
|
+
try {
|
|
4180
|
+
const zodSchema = flag["type"];
|
|
4181
|
+
const def = zodSchema._def;
|
|
4182
|
+
if (def.shape) {
|
|
4183
|
+
const shape = typeof def.shape === "function" ? def.shape() : def.shape;
|
|
4184
|
+
const properties2 = Object.keys(shape);
|
|
4185
|
+
if (properties2.length > 0) {
|
|
4186
|
+
if (properties2.length <= 4) {
|
|
4187
|
+
typeDetails.push(`Properties: ${properties2.join(", ")}`);
|
|
4188
|
+
} else {
|
|
4189
|
+
typeDetails.push(`Properties: ${properties2.slice(0, 4).join(", ")}, ... (${properties2.length} total)`);
|
|
4190
|
+
}
|
|
4191
|
+
}
|
|
4192
|
+
}
|
|
4193
|
+
typeDetails.push("Expected: JSON string");
|
|
4194
|
+
} catch (error) {
|
|
4195
|
+
typeDetails.push("Expected: JSON string");
|
|
4196
|
+
}
|
|
4197
|
+
} else if (typeof flag["type"] === "function") {
|
|
3714
4198
|
typeName = flag["type"].name || "custom function";
|
|
3715
4199
|
if (typeName === "Boolean") typeName = "boolean";
|
|
3716
4200
|
if (typeName === "String") typeName = "string";
|
|
@@ -3721,6 +4205,9 @@ ${cyan("Flags:")}
|
|
|
3721
4205
|
typeName = flag["type"];
|
|
3722
4206
|
}
|
|
3723
4207
|
metaLines.push(`Type: ${typeName}`);
|
|
4208
|
+
if (typeDetails.length > 0) {
|
|
4209
|
+
metaLines.push(...typeDetails);
|
|
4210
|
+
}
|
|
3724
4211
|
if (flag["flagOnly"]) {
|
|
3725
4212
|
metaLines.push("Flag only (no value expected)");
|
|
3726
4213
|
}
|
|
@@ -4473,7 +4960,9 @@ _buildRecursiveString_fn = function(parser, level, visited = /* @__PURE__ */ new
|
|
|
4473
4960
|
`${flagIndent} Description: ${Array.isArray(flag["description"]) ? flag["description"].join(" | ") : flag["description"]}`
|
|
4474
4961
|
);
|
|
4475
4962
|
let typeName = "unknown";
|
|
4476
|
-
if (typeof flag["type"] === "
|
|
4963
|
+
if (flag["type"] && typeof flag["type"] === "object" && flag["type"]._def) {
|
|
4964
|
+
typeName = "Zod schema";
|
|
4965
|
+
} else if (typeof flag["type"] === "function") {
|
|
4477
4966
|
typeName = flag["type"].name || "custom function";
|
|
4478
4967
|
} else if (typeof flag["type"] === "string") {
|
|
4479
4968
|
typeName = flag["type"];
|
|
@@ -4540,7 +5029,9 @@ _buildRecursiveJson_fn = function(parser, visited = /* @__PURE__ */ new Set()) {
|
|
|
4540
5029
|
config.flags = flags.map((flag) => {
|
|
4541
5030
|
var _a;
|
|
4542
5031
|
let typeName = "unknown";
|
|
4543
|
-
if (typeof flag["type"] === "
|
|
5032
|
+
if (flag["type"] && typeof flag["type"] === "object" && flag["type"]._def) {
|
|
5033
|
+
typeName = "Zod schema";
|
|
5034
|
+
} else if (typeof flag["type"] === "function") {
|
|
4544
5035
|
typeName = flag["type"].name || "custom function";
|
|
4545
5036
|
} else if (typeof flag["type"] === "string") {
|
|
4546
5037
|
typeName = flag["type"];
|
|
@@ -4963,6 +5454,25 @@ function createMcpErrorResponse(error) {
|
|
|
4963
5454
|
};
|
|
4964
5455
|
}
|
|
4965
5456
|
function convertFlagToJsonSchemaProperty(flag) {
|
|
5457
|
+
if (flag.type && typeof flag.type === "object" && flag.type._def) {
|
|
5458
|
+
const zodSchema = flag.type;
|
|
5459
|
+
try {
|
|
5460
|
+
const property2 = z.toJSONSchema(zodSchema);
|
|
5461
|
+
if (flag.description) {
|
|
5462
|
+
property2.description = flag.description;
|
|
5463
|
+
}
|
|
5464
|
+
const isRequired2 = !!(flag.mandatory || flag.required);
|
|
5465
|
+
return { property: property2, isRequired: isRequired2 };
|
|
5466
|
+
} catch (error) {
|
|
5467
|
+
console.warn(`Failed to convert Zod schema to JSON Schema for flag '${flag.name}':`, error);
|
|
5468
|
+
const property2 = {
|
|
5469
|
+
type: "object",
|
|
5470
|
+
description: flag.description || `${flag.name} parameter (Zod schema)`
|
|
5471
|
+
};
|
|
5472
|
+
const isRequired2 = !!(flag.mandatory || flag.required);
|
|
5473
|
+
return { property: property2, isRequired: isRequired2 };
|
|
5474
|
+
}
|
|
5475
|
+
}
|
|
4966
5476
|
const property = {
|
|
4967
5477
|
type: getJsonSchemaTypeFromFlag(flag.type),
|
|
4968
5478
|
description: flag.description || `${flag.name} parameter`
|
|
@@ -5069,8 +5579,11 @@ function extractSimplifiedResponse(mcpResponse) {
|
|
|
5069
5579
|
};
|
|
5070
5580
|
}
|
|
5071
5581
|
function mapArgParserFlagToZodSchema(flag) {
|
|
5072
|
-
let zodSchema = z.string();
|
|
5073
5582
|
const flagTypeOpt = flag["type"];
|
|
5583
|
+
if (flagTypeOpt && typeof flagTypeOpt === "object" && flagTypeOpt._def) {
|
|
5584
|
+
return flagTypeOpt;
|
|
5585
|
+
}
|
|
5586
|
+
let zodSchema = z.string();
|
|
5074
5587
|
let typeName;
|
|
5075
5588
|
if (typeof flagTypeOpt === "function") {
|
|
5076
5589
|
typeName = flagTypeOpt.name.toLowerCase().replace("constructor", "");
|
|
@@ -24902,6 +25415,7 @@ export {
|
|
|
24902
25415
|
ArgParserMcp,
|
|
24903
25416
|
ConfigPlugin,
|
|
24904
25417
|
ConfigPluginRegistry,
|
|
25418
|
+
DxtPathResolver,
|
|
24905
25419
|
EnvConfigPlugin,
|
|
24906
25420
|
JsonConfigPlugin,
|
|
24907
25421
|
Logger,
|
|
@@ -24940,6 +25454,7 @@ export {
|
|
|
24940
25454
|
logger,
|
|
24941
25455
|
resolveLogPath,
|
|
24942
25456
|
sanitizeMcpToolName,
|
|
25457
|
+
zodDxtOptionsSchema,
|
|
24943
25458
|
zodFlagSchema
|
|
24944
25459
|
};
|
|
24945
25460
|
//# sourceMappingURL=index.mjs.map
|