@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/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 or string literal) or a custom parser function. Defaults to 'string'."
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
- const external = this.shouldModuleBeExternal(
1749
- id,
1750
- importer,
1751
- withNodeModules
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
- return external;
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
- const external = this.shouldModuleBeExternal(
1761
- id,
1762
- importer,
1763
- withNodeModules
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
- return external === false;
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
- const outputPaths = [
1774
- "package.json"
1775
- ];
1776
- if (withNodeModules) {
1777
- console.log(
1778
- simpleChalk.gray(
1779
- "📦 Including node_modules in bundle (may take longer)..."
1780
- )
1781
- );
1782
- outputPaths.push("node_modules");
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
- if ((_a2 = mcpConfig == null ? void 0 : mcpConfig.dxt) == null ? void 0 : _a2.include) {
1797
- console.log(
1798
- simpleChalk.gray(
1799
- "📁 Including additional files from DXT configuration..."
1800
- )
1801
- );
1802
- for (const includeItem of mcpConfig.dxt.include) {
1803
- if (typeof includeItem === "string") {
1804
- const sourcePath = path__namespace.resolve(projectRoot, includeItem);
1805
- if (fs__namespace.existsSync(sourcePath)) {
1806
- console.log(simpleChalk.gray(` • ${includeItem}`));
1807
- outputPaths.push({
1808
- from: sourcePath,
1809
- to: path__namespace.join(dxtPackageRoot, includeItem)
1810
- });
1811
- } else {
1812
- console.warn(
1813
- simpleChalk.yellow(
1814
- ` ⚠ File not found: ${includeItem} (resolved to ${sourcePath})`
1815
- )
1816
- );
1817
- }
1818
- } else {
1819
- const sourcePath = path__namespace.resolve(
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
- outputPaths.push({
1828
- from: sourcePath,
1829
- to: path__namespace.join(dxtPackageRoot, includeItem.to)
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
- console.warn(
1833
- simpleChalk.yellow(
1834
- ` ⚠ File not found: ${includeItem.from} (resolved to ${sourcePath})`
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
- await build(buildConfig);
1870
- console.log(simpleChalk.green("✅ TSDown bundling completed"));
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
- userConfig[envVar] = {
2330
- type: "string",
2331
- title: envVar.replace(/_/g, " ").replace(/\b\w/g, (l) => l.toUpperCase()),
2332
- description: flag.description || `${envVar} environment variable`,
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
- // Set to sensitive if tied to ENV
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
- userConfig[envVar] = {
2349
- type: "string",
2350
- title: envVar.replace(/_/g, " ").replace(/\b\w/g, (l) => l.toUpperCase()),
2351
- description: flag.description || `${envVar} environment variable`,
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
- // Set to sensitive if tied to ENV
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
- value = new flag["type"](value);
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
- if (typeof flag["type"] === "function") {
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"] === "function") {
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"] === "function") {
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