@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.cjs
CHANGED
|
@@ -1075,6 +1075,29 @@ class ConfigurationManager {
|
|
|
1075
1075
|
}
|
|
1076
1076
|
}
|
|
1077
1077
|
}
|
|
1078
|
+
const zodDxtOptionsSchema = zod.z.object({
|
|
1079
|
+
sensitive: zod.z.boolean().optional().describe("Whether this field should be marked as sensitive in DXT user_config"),
|
|
1080
|
+
localDefault: zod.z.string().optional().describe("Default value specific to DXT sandbox environment"),
|
|
1081
|
+
type: zod.z.enum(["string", "directory", "file", "boolean", "number"]).optional().describe("DXT input type - determines UI component in DXT clients"),
|
|
1082
|
+
multiple: zod.z.boolean().optional().describe("Allow multiple values (for arrays)"),
|
|
1083
|
+
min: zod.z.number().optional().describe("Minimum value (for number type)"),
|
|
1084
|
+
max: zod.z.number().optional().describe("Maximum value (for number type)"),
|
|
1085
|
+
default: zod.z.any().optional().describe("DXT-specific default value (overrides localDefault if provided)"),
|
|
1086
|
+
title: zod.z.string().optional().describe("Custom title for the user_config field")
|
|
1087
|
+
}).strict().refine(
|
|
1088
|
+
(data2) => {
|
|
1089
|
+
if ((data2.min !== void 0 || data2.max !== void 0) && data2.type !== "number") {
|
|
1090
|
+
return false;
|
|
1091
|
+
}
|
|
1092
|
+
if (data2.min !== void 0 && data2.max !== void 0 && data2.min > data2.max) {
|
|
1093
|
+
return false;
|
|
1094
|
+
}
|
|
1095
|
+
return true;
|
|
1096
|
+
},
|
|
1097
|
+
{
|
|
1098
|
+
message: "Invalid dxtOptions: min/max can only be used with type 'number', and min must be <= max"
|
|
1099
|
+
}
|
|
1100
|
+
);
|
|
1078
1101
|
const zodFlagSchema = zod.z.object({
|
|
1079
1102
|
name: zod.z.string().min(1, "Flag name cannot be empty").describe(
|
|
1080
1103
|
"The output property name, used as a return key `{name: value}`. Must be unique."
|
|
@@ -1111,6 +1134,11 @@ const zodFlagSchema = zod.z.object({
|
|
|
1111
1134
|
"Must be a custom parser function"
|
|
1112
1135
|
),
|
|
1113
1136
|
// Custom parser function (value: string) => any | Promise<any>
|
|
1137
|
+
zod.z.custom(
|
|
1138
|
+
(val) => val && typeof val === "object" && val._def,
|
|
1139
|
+
"Must be a Zod schema"
|
|
1140
|
+
),
|
|
1141
|
+
// Zod schema for structured JSON validation
|
|
1114
1142
|
zod.z.string().refine(
|
|
1115
1143
|
// String literal types
|
|
1116
1144
|
(value) => ["boolean", "string", "number", "array", "object"].includes(
|
|
@@ -1121,7 +1149,7 @@ const zodFlagSchema = zod.z.object({
|
|
|
1121
1149
|
}
|
|
1122
1150
|
)
|
|
1123
1151
|
]).default("string").describe(
|
|
1124
|
-
"Expected data type (constructor
|
|
1152
|
+
"Expected data type (constructor, string literal, custom parser function, or Zod schema). Defaults to 'string'."
|
|
1125
1153
|
),
|
|
1126
1154
|
mandatory: zod.z.union([
|
|
1127
1155
|
zod.z.boolean(),
|
|
@@ -1141,7 +1169,8 @@ const zodFlagSchema = zod.z.object({
|
|
|
1141
1169
|
enum: zod.z.array(zod.z.any()).optional().describe("Array of allowed values for the flag."),
|
|
1142
1170
|
env: zod.z.union([zod.z.string(), zod.z.array(zod.z.string())]).optional().describe(
|
|
1143
1171
|
"Environment variables that should be set from this flag's value in DXT packages."
|
|
1144
|
-
)
|
|
1172
|
+
),
|
|
1173
|
+
dxtOptions: zodDxtOptionsSchema.optional().describe("DXT-specific configuration options for enhanced DXT manifest generation")
|
|
1145
1174
|
}).transform((obj) => {
|
|
1146
1175
|
const newObj = { ...obj };
|
|
1147
1176
|
if ("default" in newObj && newObj["default"] !== void 0 && !("defaultValue" in newObj)) {
|
|
@@ -1153,6 +1182,9 @@ const zodFlagSchema = zod.z.object({
|
|
|
1153
1182
|
return newObj;
|
|
1154
1183
|
});
|
|
1155
1184
|
function getJsonSchemaTypeFromFlag(flagType) {
|
|
1185
|
+
if (flagType && typeof flagType === "object" && flagType._def) {
|
|
1186
|
+
return "object";
|
|
1187
|
+
}
|
|
1156
1188
|
if (typeof flagType === "function") {
|
|
1157
1189
|
if (flagType === String) return "string";
|
|
1158
1190
|
if (flagType === Number) return "number";
|
|
@@ -1336,6 +1368,353 @@ echo "Mock DXT build script for ${serverInfo.name}"`;
|
|
|
1336
1368
|
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"));
|
|
1337
1369
|
}
|
|
1338
1370
|
}
|
|
1371
|
+
function detectEntryPoint() {
|
|
1372
|
+
try {
|
|
1373
|
+
if (process.argv[1] && fs__namespace.existsSync(process.argv[1])) {
|
|
1374
|
+
return process.argv[1];
|
|
1375
|
+
}
|
|
1376
|
+
if (typeof require !== "undefined" && require.main && require.main.filename) {
|
|
1377
|
+
return require.main.filename;
|
|
1378
|
+
}
|
|
1379
|
+
return null;
|
|
1380
|
+
} catch {
|
|
1381
|
+
return null;
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
function getEntryPointFromImportMeta(importMetaUrl) {
|
|
1385
|
+
if (importMetaUrl.startsWith("file://")) {
|
|
1386
|
+
return decodeURIComponent(importMetaUrl.replace("file://", ""));
|
|
1387
|
+
}
|
|
1388
|
+
return importMetaUrl;
|
|
1389
|
+
}
|
|
1390
|
+
function normalizePath(path2) {
|
|
1391
|
+
return path2.trim();
|
|
1392
|
+
}
|
|
1393
|
+
function resolveLogPath(logPath, fallbackEntryPoint) {
|
|
1394
|
+
if (typeof logPath === "string") {
|
|
1395
|
+
const pathWithVariables2 = DxtPathResolver.substituteVariables(
|
|
1396
|
+
logPath,
|
|
1397
|
+
DxtPathResolver.detectContext()
|
|
1398
|
+
);
|
|
1399
|
+
const normalizedPath2 = normalizePath(pathWithVariables2);
|
|
1400
|
+
if (path__namespace.isAbsolute(normalizedPath2)) {
|
|
1401
|
+
return normalizedPath2;
|
|
1402
|
+
}
|
|
1403
|
+
if (normalizedPath2.startsWith("cwd:")) {
|
|
1404
|
+
const relativePath = normalizedPath2.slice(4);
|
|
1405
|
+
return path__namespace.resolve(process.cwd(), relativePath);
|
|
1406
|
+
}
|
|
1407
|
+
const entryPoint = detectEntryPoint() || fallbackEntryPoint;
|
|
1408
|
+
if (entryPoint) {
|
|
1409
|
+
return path__namespace.resolve(path__namespace.dirname(entryPoint), normalizedPath2);
|
|
1410
|
+
}
|
|
1411
|
+
console.warn(
|
|
1412
|
+
`Warning: Could not detect entry point for log path resolution. Using process.cwd() as fallback. Path: ${normalizedPath2}`
|
|
1413
|
+
);
|
|
1414
|
+
return path__namespace.resolve(process.cwd(), normalizedPath2);
|
|
1415
|
+
}
|
|
1416
|
+
const { path: logFilePath, relativeTo = "entry", basePath } = logPath;
|
|
1417
|
+
const pathWithVariables = DxtPathResolver.substituteVariables(
|
|
1418
|
+
logFilePath,
|
|
1419
|
+
DxtPathResolver.detectContext()
|
|
1420
|
+
);
|
|
1421
|
+
const normalizedPath = normalizePath(pathWithVariables);
|
|
1422
|
+
switch (relativeTo) {
|
|
1423
|
+
case "absolute":
|
|
1424
|
+
if (basePath) {
|
|
1425
|
+
const resolvedBasePath = DxtPathResolver.substituteVariables(
|
|
1426
|
+
basePath,
|
|
1427
|
+
DxtPathResolver.detectContext()
|
|
1428
|
+
);
|
|
1429
|
+
return path__namespace.resolve(resolvedBasePath, normalizedPath);
|
|
1430
|
+
}
|
|
1431
|
+
if (path__namespace.isAbsolute(normalizedPath)) {
|
|
1432
|
+
return normalizedPath;
|
|
1433
|
+
}
|
|
1434
|
+
console.warn(
|
|
1435
|
+
`Warning: relativeTo 'absolute' specified but no basePath provided and path is not absolute. Using process.cwd() as fallback. Path: ${normalizedPath}`
|
|
1436
|
+
);
|
|
1437
|
+
return path__namespace.resolve(process.cwd(), normalizedPath);
|
|
1438
|
+
case "cwd":
|
|
1439
|
+
return path__namespace.resolve(process.cwd(), normalizedPath);
|
|
1440
|
+
case "entry":
|
|
1441
|
+
default:
|
|
1442
|
+
const entryPoint = detectEntryPoint() || fallbackEntryPoint;
|
|
1443
|
+
if (entryPoint) {
|
|
1444
|
+
return path__namespace.resolve(path__namespace.dirname(entryPoint), normalizedPath);
|
|
1445
|
+
}
|
|
1446
|
+
console.warn(
|
|
1447
|
+
`Warning: Could not detect entry point for log path resolution. Using process.cwd() as fallback. Path: ${normalizedPath}`
|
|
1448
|
+
);
|
|
1449
|
+
return path__namespace.resolve(process.cwd(), normalizedPath);
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
function entryRelative(path2) {
|
|
1453
|
+
return {
|
|
1454
|
+
path: path2,
|
|
1455
|
+
relativeTo: "entry"
|
|
1456
|
+
};
|
|
1457
|
+
}
|
|
1458
|
+
function cwdRelative(path2) {
|
|
1459
|
+
return {
|
|
1460
|
+
path: path2,
|
|
1461
|
+
relativeTo: "cwd"
|
|
1462
|
+
};
|
|
1463
|
+
}
|
|
1464
|
+
function absolutePath(path2, basePath) {
|
|
1465
|
+
return {
|
|
1466
|
+
path: path2,
|
|
1467
|
+
relativeTo: "absolute",
|
|
1468
|
+
basePath
|
|
1469
|
+
};
|
|
1470
|
+
}
|
|
1471
|
+
function legacyCwdPath(path2) {
|
|
1472
|
+
return `cwd:${path2}`;
|
|
1473
|
+
}
|
|
1474
|
+
const _DxtPathResolver = class _DxtPathResolver {
|
|
1475
|
+
/**
|
|
1476
|
+
* Detects the current execution context
|
|
1477
|
+
* @param forceRefresh - Force refresh of cached context
|
|
1478
|
+
* @returns Path context information
|
|
1479
|
+
*/
|
|
1480
|
+
static detectContext(forceRefresh = false) {
|
|
1481
|
+
if (!forceRefresh && this._cachedContext) {
|
|
1482
|
+
return this._cachedContext;
|
|
1483
|
+
}
|
|
1484
|
+
const context = {
|
|
1485
|
+
isDxt: this.isDxtEnvironment(),
|
|
1486
|
+
userHome: void 0,
|
|
1487
|
+
cwd: typeof process !== "undefined" && typeof process.cwd === "function" ? process.cwd() : void 0
|
|
1488
|
+
};
|
|
1489
|
+
const entryPoint = detectEntryPoint();
|
|
1490
|
+
if (entryPoint) {
|
|
1491
|
+
context.entryDir = path__namespace.dirname(entryPoint);
|
|
1492
|
+
}
|
|
1493
|
+
if (context.isDxt) {
|
|
1494
|
+
context.extensionDir = this.detectDxtExtensionDir();
|
|
1495
|
+
}
|
|
1496
|
+
this._cachedContext = context;
|
|
1497
|
+
return context;
|
|
1498
|
+
}
|
|
1499
|
+
/**
|
|
1500
|
+
* Checks if the current environment is a DXT environment
|
|
1501
|
+
* @returns True if running in DXT, false otherwise
|
|
1502
|
+
*/
|
|
1503
|
+
static isDxtEnvironment() {
|
|
1504
|
+
if (process.env["DXT_EXTENSION_DIR"] || process.env["CLAUDE_DESKTOP_DXT"]) {
|
|
1505
|
+
return true;
|
|
1506
|
+
}
|
|
1507
|
+
const dxtIndicators = [
|
|
1508
|
+
"manifest.json",
|
|
1509
|
+
// DXT packages have manifest.json
|
|
1510
|
+
".dxt"
|
|
1511
|
+
// DXT marker file
|
|
1512
|
+
];
|
|
1513
|
+
for (const indicator of dxtIndicators) {
|
|
1514
|
+
const indicatorPath = path__namespace.join(process.cwd(), indicator);
|
|
1515
|
+
if (fs__namespace.existsSync(indicatorPath)) {
|
|
1516
|
+
if (indicator === "manifest.json") {
|
|
1517
|
+
try {
|
|
1518
|
+
const manifest = JSON.parse(fs__namespace.readFileSync(indicatorPath, "utf-8"));
|
|
1519
|
+
if (manifest.server && manifest.user_config) {
|
|
1520
|
+
return true;
|
|
1521
|
+
}
|
|
1522
|
+
} catch {
|
|
1523
|
+
}
|
|
1524
|
+
} else {
|
|
1525
|
+
return true;
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
const cwd = process.cwd();
|
|
1530
|
+
if (cwd.includes("claude-desktop") || cwd.includes("extensions")) {
|
|
1531
|
+
return true;
|
|
1532
|
+
}
|
|
1533
|
+
return false;
|
|
1534
|
+
}
|
|
1535
|
+
/**
|
|
1536
|
+
* Detects the DXT extension directory
|
|
1537
|
+
* @returns DXT extension directory path or undefined
|
|
1538
|
+
*/
|
|
1539
|
+
static detectDxtExtensionDir() {
|
|
1540
|
+
if (process.env["DXT_EXTENSION_DIR"]) {
|
|
1541
|
+
return process.env["DXT_EXTENSION_DIR"];
|
|
1542
|
+
}
|
|
1543
|
+
const cwd = process.cwd();
|
|
1544
|
+
if (fs__namespace.existsSync(path__namespace.join(cwd, "manifest.json"))) {
|
|
1545
|
+
return cwd;
|
|
1546
|
+
}
|
|
1547
|
+
let currentDir = cwd;
|
|
1548
|
+
for (let i = 0; i < 3; i++) {
|
|
1549
|
+
const parentDir = path__namespace.dirname(currentDir);
|
|
1550
|
+
if (parentDir === currentDir) break;
|
|
1551
|
+
if (fs__namespace.existsSync(path__namespace.join(parentDir, "manifest.json"))) {
|
|
1552
|
+
return parentDir;
|
|
1553
|
+
}
|
|
1554
|
+
currentDir = parentDir;
|
|
1555
|
+
}
|
|
1556
|
+
return void 0;
|
|
1557
|
+
}
|
|
1558
|
+
/**
|
|
1559
|
+
* Resolves a path with DXT variable substitution
|
|
1560
|
+
* @param inputPath - Path that may contain DXT variables
|
|
1561
|
+
* @param context - Optional context (will be detected if not provided)
|
|
1562
|
+
* @param config - Optional configuration for variable substitution
|
|
1563
|
+
* @returns Resolved absolute path
|
|
1564
|
+
*/
|
|
1565
|
+
static resolvePath(inputPath, context, config) {
|
|
1566
|
+
const ctx = context || this.detectContext();
|
|
1567
|
+
const resolvedPath = this.substituteVariables(inputPath, ctx, config);
|
|
1568
|
+
if (path__namespace.isAbsolute(resolvedPath)) {
|
|
1569
|
+
return resolvedPath;
|
|
1570
|
+
}
|
|
1571
|
+
if (ctx.isDxt && ctx.extensionDir) {
|
|
1572
|
+
return path__namespace.resolve(ctx.extensionDir, resolvedPath);
|
|
1573
|
+
} else if (ctx.entryDir) {
|
|
1574
|
+
return path__namespace.resolve(ctx.entryDir, resolvedPath);
|
|
1575
|
+
} else {
|
|
1576
|
+
return path__namespace.resolve(ctx.cwd || process.cwd(), resolvedPath);
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
/**
|
|
1580
|
+
* Substitutes DXT variables in a path string
|
|
1581
|
+
* @param inputPath - Path containing variables like ${HOME}, ${__dirname}, etc.
|
|
1582
|
+
* @param context - Path context
|
|
1583
|
+
* @param config - Variable substitution configuration
|
|
1584
|
+
* @returns Path with variables substituted
|
|
1585
|
+
*/
|
|
1586
|
+
static substituteVariables(inputPath, context, config) {
|
|
1587
|
+
const safeHomedir = () => "/tmp";
|
|
1588
|
+
const homeDir = context.userHome || safeHomedir();
|
|
1589
|
+
const variables = {
|
|
1590
|
+
// Standard DXT variables
|
|
1591
|
+
HOME: homeDir,
|
|
1592
|
+
DOCUMENTS: path__namespace.join(homeDir, "Documents"),
|
|
1593
|
+
DOWNLOADS: path__namespace.join(homeDir, "Downloads"),
|
|
1594
|
+
DESKTOP: path__namespace.join(homeDir, "Desktop"),
|
|
1595
|
+
pathSeparator: path__namespace.sep,
|
|
1596
|
+
// Context-specific variables
|
|
1597
|
+
__dirname: context.isDxt && context.extensionDir ? context.extensionDir : context.entryDir || context.cwd || process.cwd(),
|
|
1598
|
+
// DXT-specific variables
|
|
1599
|
+
...context.isDxt && context.extensionDir && {
|
|
1600
|
+
DXT_DIR: context.extensionDir,
|
|
1601
|
+
EXTENSION_DIR: context.extensionDir
|
|
1602
|
+
},
|
|
1603
|
+
// Custom variables override defaults
|
|
1604
|
+
...config == null ? void 0 : config.customVariables
|
|
1605
|
+
};
|
|
1606
|
+
return inputPath.replace(/\$\{([^}]*)\}/g, (match, variableName) => {
|
|
1607
|
+
if (!variableName.trim()) {
|
|
1608
|
+
if (config == null ? void 0 : config.allowUndefined) {
|
|
1609
|
+
return match;
|
|
1610
|
+
}
|
|
1611
|
+
throw new Error(
|
|
1612
|
+
`Undefined DXT variable: ${variableName}. Available variables: ${Object.keys(variables).join(", ")}`
|
|
1613
|
+
);
|
|
1614
|
+
}
|
|
1615
|
+
const value = variables[variableName];
|
|
1616
|
+
if (value !== void 0) {
|
|
1617
|
+
return value;
|
|
1618
|
+
}
|
|
1619
|
+
if (config == null ? void 0 : config.allowUndefined) {
|
|
1620
|
+
return match;
|
|
1621
|
+
}
|
|
1622
|
+
throw new Error(
|
|
1623
|
+
`Undefined DXT variable: ${variableName}. Available variables: ${Object.keys(variables).join(", ")}`
|
|
1624
|
+
);
|
|
1625
|
+
});
|
|
1626
|
+
}
|
|
1627
|
+
/**
|
|
1628
|
+
* Creates a path for user data storage
|
|
1629
|
+
* @param filename - Name of the file or subdirectory
|
|
1630
|
+
* @param context - Optional context (will be detected if not provided)
|
|
1631
|
+
* @returns Absolute path for user data
|
|
1632
|
+
*/
|
|
1633
|
+
static createUserDataPath(filename, context) {
|
|
1634
|
+
const ctx = context || this.detectContext();
|
|
1635
|
+
if (ctx.isDxt && ctx.extensionDir) {
|
|
1636
|
+
return path__namespace.join(ctx.extensionDir, "data", filename);
|
|
1637
|
+
} else {
|
|
1638
|
+
const safeHomedir = () => "/tmp";
|
|
1639
|
+
const userDataDir = process.env["XDG_DATA_HOME"] || path__namespace.join(ctx.userHome || safeHomedir(), ".local", "share");
|
|
1640
|
+
const appName = this.getAppName(ctx);
|
|
1641
|
+
return path__namespace.join(userDataDir, appName, filename);
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
/**
|
|
1645
|
+
* Creates a path for temporary files
|
|
1646
|
+
* @param filename - Name of the temporary file
|
|
1647
|
+
* @param context - Optional context (will be detected if not provided)
|
|
1648
|
+
* @returns Absolute path for temporary file
|
|
1649
|
+
*/
|
|
1650
|
+
static createTempPath(filename, context) {
|
|
1651
|
+
const ctx = context || this.detectContext();
|
|
1652
|
+
if (ctx.isDxt && ctx.extensionDir) {
|
|
1653
|
+
return path__namespace.join(ctx.extensionDir, "temp", filename);
|
|
1654
|
+
} else {
|
|
1655
|
+
const safeTmpdir = () => "/tmp";
|
|
1656
|
+
const appName = this.getAppName(ctx);
|
|
1657
|
+
return path__namespace.join(safeTmpdir(), appName, filename);
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
/**
|
|
1661
|
+
* Creates a path for configuration files
|
|
1662
|
+
* @param filename - Name of the configuration file
|
|
1663
|
+
* @param context - Optional context (will be detected if not provided)
|
|
1664
|
+
* @returns Absolute path for configuration file
|
|
1665
|
+
*/
|
|
1666
|
+
static createConfigPath(filename, context) {
|
|
1667
|
+
const ctx = context || this.detectContext();
|
|
1668
|
+
if (ctx.isDxt && ctx.extensionDir) {
|
|
1669
|
+
return path__namespace.join(ctx.extensionDir, "config", filename);
|
|
1670
|
+
} else {
|
|
1671
|
+
const safeHomedir = () => "/tmp";
|
|
1672
|
+
const configDir = process.env["XDG_CONFIG_HOME"] || path__namespace.join(ctx.userHome || safeHomedir(), ".config");
|
|
1673
|
+
const appName = this.getAppName(ctx);
|
|
1674
|
+
return path__namespace.join(configDir, appName, filename);
|
|
1675
|
+
}
|
|
1676
|
+
}
|
|
1677
|
+
/**
|
|
1678
|
+
* Gets the application name for directory creation
|
|
1679
|
+
* @param context - Path context
|
|
1680
|
+
* @returns Application name or default
|
|
1681
|
+
*/
|
|
1682
|
+
static getAppName(context) {
|
|
1683
|
+
try {
|
|
1684
|
+
const packageJsonPath = path__namespace.join(context.entryDir || context.cwd || process.cwd(), "package.json");
|
|
1685
|
+
if (fs__namespace.existsSync(packageJsonPath)) {
|
|
1686
|
+
const packageJson = JSON.parse(fs__namespace.readFileSync(packageJsonPath, "utf-8"));
|
|
1687
|
+
return packageJson.name || "argparser-app";
|
|
1688
|
+
}
|
|
1689
|
+
} catch {
|
|
1690
|
+
}
|
|
1691
|
+
return "argparser-app";
|
|
1692
|
+
}
|
|
1693
|
+
/**
|
|
1694
|
+
* Ensures a directory exists, creating it if necessary
|
|
1695
|
+
* @param dirPath - Directory path to ensure
|
|
1696
|
+
* @returns True if directory exists or was created successfully
|
|
1697
|
+
*/
|
|
1698
|
+
static ensureDirectory(dirPath) {
|
|
1699
|
+
try {
|
|
1700
|
+
if (!fs__namespace.existsSync(dirPath)) {
|
|
1701
|
+
fs__namespace.mkdirSync(dirPath, { recursive: true });
|
|
1702
|
+
}
|
|
1703
|
+
return true;
|
|
1704
|
+
} catch (error) {
|
|
1705
|
+
console.warn(`Failed to create directory: ${dirPath}`, error);
|
|
1706
|
+
return false;
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1709
|
+
/**
|
|
1710
|
+
* Clears the cached context (useful for testing)
|
|
1711
|
+
*/
|
|
1712
|
+
static clearCache() {
|
|
1713
|
+
this._cachedContext = null;
|
|
1714
|
+
}
|
|
1715
|
+
};
|
|
1716
|
+
_DxtPathResolver._cachedContext = null;
|
|
1717
|
+
let DxtPathResolver = _DxtPathResolver;
|
|
1339
1718
|
class DxtGenerator {
|
|
1340
1719
|
constructor(argParserInstance) {
|
|
1341
1720
|
this.argParserInstance = argParserInstance;
|
|
@@ -1745,100 +2124,128 @@ class DxtGenerator {
|
|
|
1745
2124
|
silent: process.env["NO_SILENCE"] !== "1",
|
|
1746
2125
|
unbundle: true,
|
|
1747
2126
|
external: (id, importer) => {
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
if (Boolean(process.env["DEBUG"]))
|
|
1754
|
-
console.log(
|
|
1755
|
-
`[${simpleChalk.blue("External")}] ${simpleChalk.yellow(external ? "true" : "false")} for module: (${simpleChalk.green(id)}), path: '${simpleChalk.grey(importer ?? "")}'`
|
|
2127
|
+
try {
|
|
2128
|
+
const external = this.shouldModuleBeExternal(
|
|
2129
|
+
id,
|
|
2130
|
+
importer,
|
|
2131
|
+
withNodeModules
|
|
1756
2132
|
);
|
|
1757
|
-
|
|
2133
|
+
if (Boolean(process.env["DEBUG"]))
|
|
2134
|
+
console.log(
|
|
2135
|
+
`[${simpleChalk.blue("External")}] ${simpleChalk.yellow(external ? "true" : "false")} for module: (${simpleChalk.green(id)}), path: '${simpleChalk.grey(importer ?? "")}'`
|
|
2136
|
+
);
|
|
2137
|
+
return Boolean(external);
|
|
2138
|
+
} catch (error) {
|
|
2139
|
+
console.warn(`Warning: Error in external function for ${id}:`, error);
|
|
2140
|
+
return true;
|
|
2141
|
+
}
|
|
1758
2142
|
},
|
|
1759
2143
|
noExternal: (id, importer) => {
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
if (Boolean(process.env["DEBUG"]))
|
|
1766
|
-
console.log(
|
|
1767
|
-
`[${simpleChalk.yellow("noExternal")}] ${simpleChalk.yellow(external === false ? "true" : "false")} for module: (${simpleChalk.green(id)}), path: '${simpleChalk.grey(importer ?? "")}'`
|
|
2144
|
+
try {
|
|
2145
|
+
const external = this.shouldModuleBeExternal(
|
|
2146
|
+
id,
|
|
2147
|
+
importer,
|
|
2148
|
+
withNodeModules
|
|
1768
2149
|
);
|
|
1769
|
-
|
|
2150
|
+
if (Boolean(process.env["DEBUG"]))
|
|
2151
|
+
console.log(
|
|
2152
|
+
`[${simpleChalk.yellow("noExternal")}] ${simpleChalk.yellow(external === false ? "true" : "false")} for module: (${simpleChalk.green(id)}), path: '${simpleChalk.grey(importer ?? "")}'`
|
|
2153
|
+
);
|
|
2154
|
+
return Boolean(external === false);
|
|
2155
|
+
} catch (error) {
|
|
2156
|
+
console.warn(`Warning: Error in noExternal function for ${id}:`, error);
|
|
2157
|
+
return false;
|
|
2158
|
+
}
|
|
1770
2159
|
},
|
|
1771
2160
|
copy: async (options) => {
|
|
1772
2161
|
var _a2;
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
const dxtPackageRoot = entryDir !== "." && entryDir !== "" ? path__namespace.dirname(options.outDir) : options.outDir;
|
|
1785
|
-
if (logoFilename) {
|
|
1786
|
-
const currentDir = typeof process !== "undefined" ? process.cwd() : "/test";
|
|
1787
|
-
const logoPath = path__namespace.join(currentDir, logoFilename);
|
|
1788
|
-
if (fs__namespace.existsSync(logoPath)) {
|
|
1789
|
-
console.log(simpleChalk.gray(`Adding logo from: ${logoPath}`));
|
|
1790
|
-
outputPaths.push({
|
|
1791
|
-
from: logoPath,
|
|
1792
|
-
to: path__namespace.join(dxtPackageRoot, logoFilename)
|
|
1793
|
-
});
|
|
2162
|
+
try {
|
|
2163
|
+
const outputPaths = [
|
|
2164
|
+
"package.json"
|
|
2165
|
+
];
|
|
2166
|
+
if (withNodeModules) {
|
|
2167
|
+
console.log(
|
|
2168
|
+
simpleChalk.gray(
|
|
2169
|
+
"📦 Including node_modules in bundle (may take longer)..."
|
|
2170
|
+
)
|
|
2171
|
+
);
|
|
2172
|
+
outputPaths.push("node_modules");
|
|
1794
2173
|
}
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
projectRoot,
|
|
1821
|
-
includeItem.from
|
|
1822
|
-
);
|
|
1823
|
-
if (fs__namespace.existsSync(sourcePath)) {
|
|
1824
|
-
console.log(
|
|
1825
|
-
simpleChalk.gray(` • ${includeItem.from} → ${includeItem.to}`)
|
|
2174
|
+
const dxtPackageRoot = entryDir !== "." && entryDir !== "" ? path__namespace.dirname(options.outDir) : options.outDir;
|
|
2175
|
+
if (logoFilename) {
|
|
2176
|
+
const currentDir = typeof process !== "undefined" ? process.cwd() : "/test";
|
|
2177
|
+
const logoPath = path__namespace.join(currentDir, logoFilename);
|
|
2178
|
+
if (fs__namespace.existsSync(logoPath)) {
|
|
2179
|
+
console.log(simpleChalk.gray(`Adding logo from: ${logoPath}`));
|
|
2180
|
+
outputPaths.push({
|
|
2181
|
+
from: logoPath,
|
|
2182
|
+
to: path__namespace.join(dxtPackageRoot, logoFilename)
|
|
2183
|
+
});
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
2186
|
+
if ((_a2 = mcpConfig == null ? void 0 : mcpConfig.dxt) == null ? void 0 : _a2.include) {
|
|
2187
|
+
console.log(
|
|
2188
|
+
simpleChalk.gray(
|
|
2189
|
+
"📁 Including additional files from DXT configuration..."
|
|
2190
|
+
)
|
|
2191
|
+
);
|
|
2192
|
+
for (const includeItem of mcpConfig.dxt.include) {
|
|
2193
|
+
if (typeof includeItem === "string") {
|
|
2194
|
+
const resolvedIncludePath = DxtPathResolver.substituteVariables(
|
|
2195
|
+
includeItem,
|
|
2196
|
+
DxtPathResolver.detectContext(),
|
|
2197
|
+
{ allowUndefined: true }
|
|
2198
|
+
// Allow undefined variables for flexibility
|
|
1826
2199
|
);
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
2200
|
+
const sourcePath = path__namespace.resolve(projectRoot, resolvedIncludePath);
|
|
2201
|
+
if (fs__namespace.existsSync(sourcePath)) {
|
|
2202
|
+
console.log(simpleChalk.gray(` • ${resolvedIncludePath}`));
|
|
2203
|
+
outputPaths.push({
|
|
2204
|
+
from: sourcePath,
|
|
2205
|
+
to: path__namespace.join(dxtPackageRoot, resolvedIncludePath)
|
|
2206
|
+
});
|
|
2207
|
+
} else {
|
|
2208
|
+
console.warn(
|
|
2209
|
+
simpleChalk.yellow(
|
|
2210
|
+
` ⚠ File not found: ${resolvedIncludePath} (resolved to ${sourcePath})`
|
|
2211
|
+
)
|
|
2212
|
+
);
|
|
2213
|
+
}
|
|
1831
2214
|
} else {
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
2215
|
+
const resolvedFromPath = DxtPathResolver.substituteVariables(
|
|
2216
|
+
includeItem.from,
|
|
2217
|
+
DxtPathResolver.detectContext(),
|
|
2218
|
+
{ allowUndefined: true }
|
|
2219
|
+
);
|
|
2220
|
+
const resolvedToPath = DxtPathResolver.substituteVariables(
|
|
2221
|
+
includeItem.to,
|
|
2222
|
+
DxtPathResolver.detectContext(),
|
|
2223
|
+
{ allowUndefined: true }
|
|
1836
2224
|
);
|
|
2225
|
+
const sourcePath = path__namespace.resolve(projectRoot, resolvedFromPath);
|
|
2226
|
+
if (fs__namespace.existsSync(sourcePath)) {
|
|
2227
|
+
console.log(
|
|
2228
|
+
simpleChalk.gray(` • ${resolvedFromPath} → ${resolvedToPath}`)
|
|
2229
|
+
);
|
|
2230
|
+
outputPaths.push({
|
|
2231
|
+
from: sourcePath,
|
|
2232
|
+
to: path__namespace.join(dxtPackageRoot, resolvedToPath)
|
|
2233
|
+
});
|
|
2234
|
+
} else {
|
|
2235
|
+
console.warn(
|
|
2236
|
+
simpleChalk.yellow(
|
|
2237
|
+
` ⚠ File not found: ${resolvedFromPath} (resolved to ${sourcePath})`
|
|
2238
|
+
)
|
|
2239
|
+
);
|
|
2240
|
+
}
|
|
1837
2241
|
}
|
|
1838
2242
|
}
|
|
1839
2243
|
}
|
|
2244
|
+
return outputPaths;
|
|
2245
|
+
} catch (error) {
|
|
2246
|
+
console.warn(`Warning: Error in copy function:`, error);
|
|
2247
|
+
return ["package.json"];
|
|
1840
2248
|
}
|
|
1841
|
-
return outputPaths;
|
|
1842
2249
|
},
|
|
1843
2250
|
platform: "node",
|
|
1844
2251
|
plugins: []
|
|
@@ -1866,8 +2273,18 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
1866
2273
|
simpleChalk.gray("📝 Debug config written to dxt/tsdown.config.dxt.ts")
|
|
1867
2274
|
);
|
|
1868
2275
|
}
|
|
1869
|
-
|
|
1870
|
-
|
|
2276
|
+
try {
|
|
2277
|
+
await build(buildConfig);
|
|
2278
|
+
console.log(simpleChalk.green("✅ TSDown bundling completed"));
|
|
2279
|
+
} catch (buildError) {
|
|
2280
|
+
console.error(simpleChalk.red("❌ TSDown build failed with error:"));
|
|
2281
|
+
console.error(buildError);
|
|
2282
|
+
if (buildError instanceof Error) {
|
|
2283
|
+
console.error(simpleChalk.red("Error message:"), buildError.message);
|
|
2284
|
+
console.error(simpleChalk.red("Error stack:"), buildError.stack);
|
|
2285
|
+
}
|
|
2286
|
+
throw new Error(`TSDown DXT build failed: ${buildError instanceof Error ? buildError.message : String(buildError)}`);
|
|
2287
|
+
}
|
|
1871
2288
|
const detectedOutputFile = this.detectTsdownOutputFile(
|
|
1872
2289
|
outputDir,
|
|
1873
2290
|
relativeEntryPath.replace(/\.ts$/, ".js")
|
|
@@ -2126,7 +2543,7 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2126
2543
|
if (flag.enum) {
|
|
2127
2544
|
properties2[flag.name].enum = flag.enum;
|
|
2128
2545
|
}
|
|
2129
|
-
if (flag.defaultValue !== void 0) {
|
|
2546
|
+
if (flag.defaultValue !== void 0 && typeof flag.defaultValue !== "function") {
|
|
2130
2547
|
properties2[flag.name].default = flag.defaultValue;
|
|
2131
2548
|
}
|
|
2132
2549
|
if (flag.mandatory) {
|
|
@@ -2301,11 +2718,62 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2301
2718
|
`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.`
|
|
2302
2719
|
);
|
|
2303
2720
|
}
|
|
2721
|
+
/**
|
|
2722
|
+
* Validate dxtOptions for common mistakes and security issues
|
|
2723
|
+
* @param flag The flag with dxtOptions to validate
|
|
2724
|
+
* @param envVar The environment variable name for context
|
|
2725
|
+
*/
|
|
2726
|
+
validateDxtOptions(flag, envVar) {
|
|
2727
|
+
const dxtOptions = flag.dxtOptions;
|
|
2728
|
+
if (!dxtOptions) return;
|
|
2729
|
+
if (dxtOptions.min !== void 0 && dxtOptions.max !== void 0) {
|
|
2730
|
+
if (dxtOptions.min > dxtOptions.max) {
|
|
2731
|
+
throw new Error(
|
|
2732
|
+
`Invalid dxtOptions for ${envVar}: min (${dxtOptions.min}) cannot be greater than max (${dxtOptions.max})`
|
|
2733
|
+
);
|
|
2734
|
+
}
|
|
2735
|
+
}
|
|
2736
|
+
if (dxtOptions.type !== void 0) {
|
|
2737
|
+
const validTypes = ["string", "directory", "file", "boolean", "number"];
|
|
2738
|
+
if (!validTypes.includes(dxtOptions.type)) {
|
|
2739
|
+
throw new Error(
|
|
2740
|
+
`Invalid dxtOptions.type for ${envVar}: "${dxtOptions.type}". Must be one of: ${validTypes.join(", ")}`
|
|
2741
|
+
);
|
|
2742
|
+
}
|
|
2743
|
+
}
|
|
2744
|
+
if (dxtOptions.default !== void 0 && dxtOptions.type !== void 0) {
|
|
2745
|
+
const defaultType = typeof dxtOptions.default;
|
|
2746
|
+
if (dxtOptions.type === "number" && defaultType !== "number") {
|
|
2747
|
+
throw new Error(
|
|
2748
|
+
`Invalid dxtOptions.default for ${envVar}: expected number, got ${defaultType}`
|
|
2749
|
+
);
|
|
2750
|
+
}
|
|
2751
|
+
if (dxtOptions.type === "boolean" && defaultType !== "boolean") {
|
|
2752
|
+
throw new Error(
|
|
2753
|
+
`Invalid dxtOptions.default for ${envVar}: expected boolean, got ${defaultType}`
|
|
2754
|
+
);
|
|
2755
|
+
}
|
|
2756
|
+
}
|
|
2757
|
+
const sensitiveKeywords = ["key", "token", "password", "secret", "auth"];
|
|
2758
|
+
const envLower = envVar.toLowerCase();
|
|
2759
|
+
const hasSensitiveKeyword = sensitiveKeywords.some((keyword2) => envLower.includes(keyword2));
|
|
2760
|
+
if (hasSensitiveKeyword && dxtOptions.sensitive === false) {
|
|
2761
|
+
console.warn(
|
|
2762
|
+
`⚠️ Security Warning: ${envVar} contains sensitive keyword but dxtOptions.sensitive is false`
|
|
2763
|
+
);
|
|
2764
|
+
}
|
|
2765
|
+
if (flag.mandatory === true && dxtOptions.sensitive !== false) {
|
|
2766
|
+
console.warn(
|
|
2767
|
+
`⚠️ Security Warning: ${envVar} is required and sensitive - consider providing a secure default or making it optional`
|
|
2768
|
+
);
|
|
2769
|
+
}
|
|
2770
|
+
}
|
|
2304
2771
|
/**
|
|
2305
2772
|
* Generate environment variables and user configuration from ArgParser flags
|
|
2306
2773
|
* @returns Object containing envVars and userConfig
|
|
2307
2774
|
*/
|
|
2308
2775
|
generateEnvAndUserConfig() {
|
|
2776
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
2309
2777
|
const envVars = {};
|
|
2310
2778
|
const userConfig = {};
|
|
2311
2779
|
const shouldBeRequired = (flag) => {
|
|
@@ -2318,23 +2786,78 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2318
2786
|
return false;
|
|
2319
2787
|
};
|
|
2320
2788
|
const shouldBeSensitive = (flag) => {
|
|
2789
|
+
var _a2;
|
|
2790
|
+
if (((_a2 = flag.dxtOptions) == null ? void 0 : _a2.sensitive) !== void 0) {
|
|
2791
|
+
return flag.dxtOptions.sensitive;
|
|
2792
|
+
}
|
|
2321
2793
|
const envVar = flag.env || flag.envVar;
|
|
2322
2794
|
return !!envVar;
|
|
2323
2795
|
};
|
|
2796
|
+
const getDxtType = (flag) => {
|
|
2797
|
+
var _a2;
|
|
2798
|
+
if ((_a2 = flag.dxtOptions) == null ? void 0 : _a2.type) {
|
|
2799
|
+
return flag.dxtOptions.type;
|
|
2800
|
+
}
|
|
2801
|
+
if (typeof flag.type === "string") {
|
|
2802
|
+
const lowerType = flag.type.toLowerCase();
|
|
2803
|
+
if (["string", "boolean", "number"].includes(lowerType)) {
|
|
2804
|
+
return lowerType;
|
|
2805
|
+
}
|
|
2806
|
+
} else if (flag.type === String) {
|
|
2807
|
+
return "string";
|
|
2808
|
+
} else if (flag.type === Boolean) {
|
|
2809
|
+
return "boolean";
|
|
2810
|
+
} else if (flag.type === Number) {
|
|
2811
|
+
return "number";
|
|
2812
|
+
}
|
|
2813
|
+
return "string";
|
|
2814
|
+
};
|
|
2815
|
+
const getDxtTitle = (flag, envVar) => {
|
|
2816
|
+
var _a2;
|
|
2817
|
+
if ((_a2 = flag.dxtOptions) == null ? void 0 : _a2.title) {
|
|
2818
|
+
return flag.dxtOptions.title;
|
|
2819
|
+
}
|
|
2820
|
+
return envVar.replace(/_/g, " ").toLowerCase().replace(/\b\w/g, (l) => l.toUpperCase());
|
|
2821
|
+
};
|
|
2822
|
+
const getDxtDescription = (flag, envVar) => {
|
|
2823
|
+
var _a2, _b2;
|
|
2824
|
+
let baseDescription = flag.description || `${envVar} environment variable`;
|
|
2825
|
+
const defaultValue = ((_a2 = flag.dxtOptions) == null ? void 0 : _a2.default) ?? ((_b2 = flag.dxtOptions) == null ? void 0 : _b2.localDefault) ?? flag.defaultValue;
|
|
2826
|
+
if (defaultValue !== void 0 && typeof defaultValue !== "function") {
|
|
2827
|
+
baseDescription += ` (default: ${defaultValue})`;
|
|
2828
|
+
}
|
|
2829
|
+
return baseDescription;
|
|
2830
|
+
};
|
|
2324
2831
|
const mainFlags = this.argParserInstance.flags;
|
|
2325
2832
|
for (const flag of mainFlags) {
|
|
2326
2833
|
const envVar = flag.env || flag.envVar;
|
|
2327
2834
|
if (envVar) {
|
|
2835
|
+
this.validateDxtOptions(flag, envVar);
|
|
2328
2836
|
envVars[envVar] = `\${user_config.${envVar}}`;
|
|
2329
|
-
|
|
2330
|
-
type:
|
|
2331
|
-
title:
|
|
2332
|
-
description: flag
|
|
2837
|
+
const userConfigEntry = {
|
|
2838
|
+
type: getDxtType(flag),
|
|
2839
|
+
title: getDxtTitle(flag, envVar),
|
|
2840
|
+
description: getDxtDescription(flag, envVar),
|
|
2333
2841
|
required: shouldBeRequired(flag),
|
|
2334
2842
|
// Respect the flag's mandatory setting
|
|
2335
2843
|
sensitive: shouldBeSensitive(flag)
|
|
2336
|
-
//
|
|
2844
|
+
// Use dxtOptions or default logic
|
|
2337
2845
|
};
|
|
2846
|
+
if (((_a = flag.dxtOptions) == null ? void 0 : _a.multiple) !== void 0) {
|
|
2847
|
+
userConfigEntry.multiple = flag.dxtOptions.multiple;
|
|
2848
|
+
}
|
|
2849
|
+
if (((_b = flag.dxtOptions) == null ? void 0 : _b.min) !== void 0) {
|
|
2850
|
+
userConfigEntry.min = flag.dxtOptions.min;
|
|
2851
|
+
}
|
|
2852
|
+
if (((_c = flag.dxtOptions) == null ? void 0 : _c.max) !== void 0) {
|
|
2853
|
+
userConfigEntry.max = flag.dxtOptions.max;
|
|
2854
|
+
}
|
|
2855
|
+
if (((_d = flag.dxtOptions) == null ? void 0 : _d.default) !== void 0 && typeof flag.dxtOptions.default !== "function") {
|
|
2856
|
+
userConfigEntry.default = flag.dxtOptions.default;
|
|
2857
|
+
} else if (((_e = flag.dxtOptions) == null ? void 0 : _e.localDefault) !== void 0 && typeof flag.dxtOptions.localDefault !== "function") {
|
|
2858
|
+
userConfigEntry.default = flag.dxtOptions.localDefault;
|
|
2859
|
+
}
|
|
2860
|
+
userConfig[envVar] = userConfigEntry;
|
|
2338
2861
|
}
|
|
2339
2862
|
}
|
|
2340
2863
|
if (typeof this.argParserInstance.getTools === "function") {
|
|
@@ -2344,16 +2867,32 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2344
2867
|
for (const flag of toolFlags) {
|
|
2345
2868
|
const envVar = flag.env || flag.envVar;
|
|
2346
2869
|
if (envVar && !envVars[envVar]) {
|
|
2870
|
+
this.validateDxtOptions(flag, envVar);
|
|
2347
2871
|
envVars[envVar] = `\${user_config.${envVar}}`;
|
|
2348
|
-
|
|
2349
|
-
type:
|
|
2350
|
-
title:
|
|
2351
|
-
description: flag
|
|
2872
|
+
const userConfigEntry = {
|
|
2873
|
+
type: getDxtType(flag),
|
|
2874
|
+
title: getDxtTitle(flag, envVar),
|
|
2875
|
+
description: getDxtDescription(flag, envVar),
|
|
2352
2876
|
required: shouldBeRequired(flag),
|
|
2353
2877
|
// Respect the flag's mandatory setting
|
|
2354
2878
|
sensitive: shouldBeSensitive(flag)
|
|
2355
|
-
//
|
|
2879
|
+
// Use dxtOptions or default logic
|
|
2356
2880
|
};
|
|
2881
|
+
if (((_f = flag.dxtOptions) == null ? void 0 : _f.multiple) !== void 0) {
|
|
2882
|
+
userConfigEntry.multiple = flag.dxtOptions.multiple;
|
|
2883
|
+
}
|
|
2884
|
+
if (((_g = flag.dxtOptions) == null ? void 0 : _g.min) !== void 0) {
|
|
2885
|
+
userConfigEntry.min = flag.dxtOptions.min;
|
|
2886
|
+
}
|
|
2887
|
+
if (((_h = flag.dxtOptions) == null ? void 0 : _h.max) !== void 0) {
|
|
2888
|
+
userConfigEntry.max = flag.dxtOptions.max;
|
|
2889
|
+
}
|
|
2890
|
+
if (((_i = flag.dxtOptions) == null ? void 0 : _i.default) !== void 0 && typeof flag.dxtOptions.default !== "function") {
|
|
2891
|
+
userConfigEntry.default = flag.dxtOptions.default;
|
|
2892
|
+
} else if (((_j = flag.dxtOptions) == null ? void 0 : _j.localDefault) !== void 0 && typeof flag.dxtOptions.localDefault !== "function") {
|
|
2893
|
+
userConfigEntry.default = flag.dxtOptions.localDefault;
|
|
2894
|
+
}
|
|
2895
|
+
userConfig[envVar] = userConfigEntry;
|
|
2357
2896
|
}
|
|
2358
2897
|
}
|
|
2359
2898
|
}
|
|
@@ -2384,10 +2923,10 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2384
2923
|
);
|
|
2385
2924
|
}
|
|
2386
2925
|
const pathsMatcher = getTsconfig.createPathsMatcher(tsconfig);
|
|
2387
|
-
if (!pathsMatcher) {
|
|
2926
|
+
if (!pathsMatcher || typeof pathsMatcher !== "function") {
|
|
2388
2927
|
if (Boolean(process.env["DEBUG"])) {
|
|
2389
2928
|
console.log(
|
|
2390
|
-
` <${simpleChalk.gray("ts-paths")}> Failed to create paths matcher`
|
|
2929
|
+
` <${simpleChalk.gray("ts-paths")}> Failed to create paths matcher or matcher is not a function`
|
|
2391
2930
|
);
|
|
2392
2931
|
}
|
|
2393
2932
|
} else {
|
|
@@ -3097,7 +3636,8 @@ const _FlagManager = class _FlagManager {
|
|
|
3097
3636
|
validate: parsedFromZod["validate"],
|
|
3098
3637
|
enum: parsedFromZod["enum"],
|
|
3099
3638
|
mandatory: parsedFromZod["mandatory"],
|
|
3100
|
-
env: parsedFromZod["env"]
|
|
3639
|
+
env: parsedFromZod["env"],
|
|
3640
|
+
dxtOptions: parsedFromZod["dxtOptions"]
|
|
3101
3641
|
};
|
|
3102
3642
|
}
|
|
3103
3643
|
addFlag(flag) {
|
|
@@ -3146,97 +3686,6 @@ const _FlagManager = class _FlagManager {
|
|
|
3146
3686
|
__flags = new WeakMap();
|
|
3147
3687
|
_throwForDuplicateFlags = new WeakMap();
|
|
3148
3688
|
let FlagManager = _FlagManager;
|
|
3149
|
-
function detectEntryPoint() {
|
|
3150
|
-
try {
|
|
3151
|
-
if (process.argv[1] && fs__namespace.existsSync(process.argv[1])) {
|
|
3152
|
-
return process.argv[1];
|
|
3153
|
-
}
|
|
3154
|
-
if (typeof require !== "undefined" && require.main && require.main.filename) {
|
|
3155
|
-
return require.main.filename;
|
|
3156
|
-
}
|
|
3157
|
-
return null;
|
|
3158
|
-
} catch {
|
|
3159
|
-
return null;
|
|
3160
|
-
}
|
|
3161
|
-
}
|
|
3162
|
-
function getEntryPointFromImportMeta(importMetaUrl) {
|
|
3163
|
-
if (importMetaUrl.startsWith("file://")) {
|
|
3164
|
-
return decodeURIComponent(importMetaUrl.replace("file://", ""));
|
|
3165
|
-
}
|
|
3166
|
-
return importMetaUrl;
|
|
3167
|
-
}
|
|
3168
|
-
function normalizePath(path2) {
|
|
3169
|
-
return path2.trim();
|
|
3170
|
-
}
|
|
3171
|
-
function resolveLogPath(logPath, fallbackEntryPoint) {
|
|
3172
|
-
if (typeof logPath === "string") {
|
|
3173
|
-
const normalizedPath2 = normalizePath(logPath);
|
|
3174
|
-
if (path__namespace.isAbsolute(normalizedPath2)) {
|
|
3175
|
-
return normalizedPath2;
|
|
3176
|
-
}
|
|
3177
|
-
if (normalizedPath2.startsWith("cwd:")) {
|
|
3178
|
-
const relativePath = normalizedPath2.slice(4);
|
|
3179
|
-
return path__namespace.resolve(process.cwd(), relativePath);
|
|
3180
|
-
}
|
|
3181
|
-
const entryPoint = detectEntryPoint() || fallbackEntryPoint;
|
|
3182
|
-
if (entryPoint) {
|
|
3183
|
-
return path__namespace.resolve(path__namespace.dirname(entryPoint), normalizedPath2);
|
|
3184
|
-
}
|
|
3185
|
-
console.warn(
|
|
3186
|
-
`Warning: Could not detect entry point for log path resolution. Using process.cwd() as fallback. Path: ${normalizedPath2}`
|
|
3187
|
-
);
|
|
3188
|
-
return path__namespace.resolve(process.cwd(), normalizedPath2);
|
|
3189
|
-
}
|
|
3190
|
-
const { path: logFilePath, relativeTo = "entry", basePath } = logPath;
|
|
3191
|
-
const normalizedPath = normalizePath(logFilePath);
|
|
3192
|
-
switch (relativeTo) {
|
|
3193
|
-
case "absolute":
|
|
3194
|
-
if (basePath) {
|
|
3195
|
-
return path__namespace.resolve(basePath, normalizedPath);
|
|
3196
|
-
}
|
|
3197
|
-
if (path__namespace.isAbsolute(normalizedPath)) {
|
|
3198
|
-
return normalizedPath;
|
|
3199
|
-
}
|
|
3200
|
-
console.warn(
|
|
3201
|
-
`Warning: relativeTo 'absolute' specified but no basePath provided and path is not absolute. Using process.cwd() as fallback. Path: ${normalizedPath}`
|
|
3202
|
-
);
|
|
3203
|
-
return path__namespace.resolve(process.cwd(), normalizedPath);
|
|
3204
|
-
case "cwd":
|
|
3205
|
-
return path__namespace.resolve(process.cwd(), normalizedPath);
|
|
3206
|
-
case "entry":
|
|
3207
|
-
default:
|
|
3208
|
-
const entryPoint = detectEntryPoint() || fallbackEntryPoint;
|
|
3209
|
-
if (entryPoint) {
|
|
3210
|
-
return path__namespace.resolve(path__namespace.dirname(entryPoint), normalizedPath);
|
|
3211
|
-
}
|
|
3212
|
-
console.warn(
|
|
3213
|
-
`Warning: Could not detect entry point for log path resolution. Using process.cwd() as fallback. Path: ${normalizedPath}`
|
|
3214
|
-
);
|
|
3215
|
-
return path__namespace.resolve(process.cwd(), normalizedPath);
|
|
3216
|
-
}
|
|
3217
|
-
}
|
|
3218
|
-
function entryRelative(path2) {
|
|
3219
|
-
return {
|
|
3220
|
-
path: path2,
|
|
3221
|
-
relativeTo: "entry"
|
|
3222
|
-
};
|
|
3223
|
-
}
|
|
3224
|
-
function cwdRelative(path2) {
|
|
3225
|
-
return {
|
|
3226
|
-
path: path2,
|
|
3227
|
-
relativeTo: "cwd"
|
|
3228
|
-
};
|
|
3229
|
-
}
|
|
3230
|
-
function absolutePath(path2, basePath) {
|
|
3231
|
-
return {
|
|
3232
|
-
path: path2,
|
|
3233
|
-
relativeTo: "absolute",
|
|
3234
|
-
basePath
|
|
3235
|
-
};
|
|
3236
|
-
}
|
|
3237
|
-
function legacyCwdPath(path2) {
|
|
3238
|
-
return `cwd:${path2}`;
|
|
3239
|
-
}
|
|
3240
3689
|
class ArgParserError extends Error {
|
|
3241
3690
|
constructor(message, cmdChain = []) {
|
|
3242
3691
|
super(message);
|
|
@@ -3379,7 +3828,21 @@ const _ArgParserBase = class _ArgParserBase {
|
|
|
3379
3828
|
const result = flag["type"](value);
|
|
3380
3829
|
value = result && typeof result.then === "function" ? await result : result;
|
|
3381
3830
|
} else if (typeof flag["type"] === "object") {
|
|
3382
|
-
|
|
3831
|
+
if (flag["type"] && flag["type"]._def) {
|
|
3832
|
+
try {
|
|
3833
|
+
const parsedJson = typeof value === "string" ? JSON.parse(value) : value;
|
|
3834
|
+
value = flag["type"].parse(parsedJson);
|
|
3835
|
+
} catch (error) {
|
|
3836
|
+
if (error instanceof SyntaxError) {
|
|
3837
|
+
throw new Error(`Invalid JSON for flag '${flag["name"]}': ${error.message}`);
|
|
3838
|
+
} else {
|
|
3839
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
3840
|
+
throw new Error(`Validation failed for flag '${flag["name"]}': ${errorMessage}`);
|
|
3841
|
+
}
|
|
3842
|
+
}
|
|
3843
|
+
} else {
|
|
3844
|
+
value = new flag["type"](value);
|
|
3845
|
+
}
|
|
3383
3846
|
}
|
|
3384
3847
|
if (flag["enum"] && flag["enum"].length > 0) {
|
|
3385
3848
|
const allowedValues = flag["enum"].map((v) => typeof v === "string" ? `'${v}'` : v).join(", ");
|
|
@@ -3751,7 +4214,28 @@ ${cyan("Flags:")}
|
|
|
3751
4214
|
const descriptionLines = Array.isArray(flag["description"]) ? flag["description"] : [flag["description"]];
|
|
3752
4215
|
const metaLines = [];
|
|
3753
4216
|
let typeName = "unknown";
|
|
3754
|
-
|
|
4217
|
+
let typeDetails = [];
|
|
4218
|
+
if (flag["type"] && typeof flag["type"] === "object" && flag["type"]._def) {
|
|
4219
|
+
typeName = "JSON object";
|
|
4220
|
+
try {
|
|
4221
|
+
const zodSchema = flag["type"];
|
|
4222
|
+
const def = zodSchema._def;
|
|
4223
|
+
if (def.shape) {
|
|
4224
|
+
const shape = typeof def.shape === "function" ? def.shape() : def.shape;
|
|
4225
|
+
const properties2 = Object.keys(shape);
|
|
4226
|
+
if (properties2.length > 0) {
|
|
4227
|
+
if (properties2.length <= 4) {
|
|
4228
|
+
typeDetails.push(`Properties: ${properties2.join(", ")}`);
|
|
4229
|
+
} else {
|
|
4230
|
+
typeDetails.push(`Properties: ${properties2.slice(0, 4).join(", ")}, ... (${properties2.length} total)`);
|
|
4231
|
+
}
|
|
4232
|
+
}
|
|
4233
|
+
}
|
|
4234
|
+
typeDetails.push("Expected: JSON string");
|
|
4235
|
+
} catch (error) {
|
|
4236
|
+
typeDetails.push("Expected: JSON string");
|
|
4237
|
+
}
|
|
4238
|
+
} else if (typeof flag["type"] === "function") {
|
|
3755
4239
|
typeName = flag["type"].name || "custom function";
|
|
3756
4240
|
if (typeName === "Boolean") typeName = "boolean";
|
|
3757
4241
|
if (typeName === "String") typeName = "string";
|
|
@@ -3762,6 +4246,9 @@ ${cyan("Flags:")}
|
|
|
3762
4246
|
typeName = flag["type"];
|
|
3763
4247
|
}
|
|
3764
4248
|
metaLines.push(`Type: ${typeName}`);
|
|
4249
|
+
if (typeDetails.length > 0) {
|
|
4250
|
+
metaLines.push(...typeDetails);
|
|
4251
|
+
}
|
|
3765
4252
|
if (flag["flagOnly"]) {
|
|
3766
4253
|
metaLines.push("Flag only (no value expected)");
|
|
3767
4254
|
}
|
|
@@ -4514,7 +5001,9 @@ _buildRecursiveString_fn = function(parser, level, visited = /* @__PURE__ */ new
|
|
|
4514
5001
|
`${flagIndent} Description: ${Array.isArray(flag["description"]) ? flag["description"].join(" | ") : flag["description"]}`
|
|
4515
5002
|
);
|
|
4516
5003
|
let typeName = "unknown";
|
|
4517
|
-
if (typeof flag["type"] === "
|
|
5004
|
+
if (flag["type"] && typeof flag["type"] === "object" && flag["type"]._def) {
|
|
5005
|
+
typeName = "Zod schema";
|
|
5006
|
+
} else if (typeof flag["type"] === "function") {
|
|
4518
5007
|
typeName = flag["type"].name || "custom function";
|
|
4519
5008
|
} else if (typeof flag["type"] === "string") {
|
|
4520
5009
|
typeName = flag["type"];
|
|
@@ -4581,7 +5070,9 @@ _buildRecursiveJson_fn = function(parser, visited = /* @__PURE__ */ new Set()) {
|
|
|
4581
5070
|
config.flags = flags.map((flag) => {
|
|
4582
5071
|
var _a;
|
|
4583
5072
|
let typeName = "unknown";
|
|
4584
|
-
if (typeof flag["type"] === "
|
|
5073
|
+
if (flag["type"] && typeof flag["type"] === "object" && flag["type"]._def) {
|
|
5074
|
+
typeName = "Zod schema";
|
|
5075
|
+
} else if (typeof flag["type"] === "function") {
|
|
4585
5076
|
typeName = flag["type"].name || "custom function";
|
|
4586
5077
|
} else if (typeof flag["type"] === "string") {
|
|
4587
5078
|
typeName = flag["type"];
|
|
@@ -5004,6 +5495,25 @@ function createMcpErrorResponse(error) {
|
|
|
5004
5495
|
};
|
|
5005
5496
|
}
|
|
5006
5497
|
function convertFlagToJsonSchemaProperty(flag) {
|
|
5498
|
+
if (flag.type && typeof flag.type === "object" && flag.type._def) {
|
|
5499
|
+
const zodSchema = flag.type;
|
|
5500
|
+
try {
|
|
5501
|
+
const property2 = zod.z.toJSONSchema(zodSchema);
|
|
5502
|
+
if (flag.description) {
|
|
5503
|
+
property2.description = flag.description;
|
|
5504
|
+
}
|
|
5505
|
+
const isRequired2 = !!(flag.mandatory || flag.required);
|
|
5506
|
+
return { property: property2, isRequired: isRequired2 };
|
|
5507
|
+
} catch (error) {
|
|
5508
|
+
console.warn(`Failed to convert Zod schema to JSON Schema for flag '${flag.name}':`, error);
|
|
5509
|
+
const property2 = {
|
|
5510
|
+
type: "object",
|
|
5511
|
+
description: flag.description || `${flag.name} parameter (Zod schema)`
|
|
5512
|
+
};
|
|
5513
|
+
const isRequired2 = !!(flag.mandatory || flag.required);
|
|
5514
|
+
return { property: property2, isRequired: isRequired2 };
|
|
5515
|
+
}
|
|
5516
|
+
}
|
|
5007
5517
|
const property = {
|
|
5008
5518
|
type: getJsonSchemaTypeFromFlag(flag.type),
|
|
5009
5519
|
description: flag.description || `${flag.name} parameter`
|
|
@@ -5110,8 +5620,11 @@ function extractSimplifiedResponse(mcpResponse) {
|
|
|
5110
5620
|
};
|
|
5111
5621
|
}
|
|
5112
5622
|
function mapArgParserFlagToZodSchema(flag) {
|
|
5113
|
-
let zodSchema = zod.z.string();
|
|
5114
5623
|
const flagTypeOpt = flag["type"];
|
|
5624
|
+
if (flagTypeOpt && typeof flagTypeOpt === "object" && flagTypeOpt._def) {
|
|
5625
|
+
return flagTypeOpt;
|
|
5626
|
+
}
|
|
5627
|
+
let zodSchema = zod.z.string();
|
|
5115
5628
|
let typeName;
|
|
5116
5629
|
if (typeof flagTypeOpt === "function") {
|
|
5117
5630
|
typeName = flagTypeOpt.name.toLowerCase().replace("constructor", "");
|
|
@@ -24958,6 +25471,7 @@ exports.ArgParserFuzzyTester = ArgParserFuzzyTester;
|
|
|
24958
25471
|
exports.ArgParserMcp = ArgParserMcp;
|
|
24959
25472
|
exports.ConfigPlugin = ConfigPlugin;
|
|
24960
25473
|
exports.ConfigPluginRegistry = ConfigPluginRegistry;
|
|
25474
|
+
exports.DxtPathResolver = DxtPathResolver;
|
|
24961
25475
|
exports.EnvConfigPlugin = EnvConfigPlugin;
|
|
24962
25476
|
exports.JsonConfigPlugin = JsonConfigPlugin;
|
|
24963
25477
|
exports.OutputSchemaPatterns = OutputSchemaPatterns;
|
|
@@ -24992,5 +25506,6 @@ exports.isValidMcpToolName = isValidMcpToolName;
|
|
|
24992
25506
|
exports.legacyCwdPath = legacyCwdPath;
|
|
24993
25507
|
exports.resolveLogPath = resolveLogPath;
|
|
24994
25508
|
exports.sanitizeMcpToolName = sanitizeMcpToolName;
|
|
25509
|
+
exports.zodDxtOptionsSchema = zodDxtOptionsSchema;
|
|
24995
25510
|
exports.zodFlagSchema = zodFlagSchema;
|
|
24996
25511
|
//# sourceMappingURL=index.cjs.map
|