politty 0.4.3 → 0.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/dist/{arg-registry-BUUhZ7JR.d.ts → arg-registry-2m40k1Et.d.ts} +1 -1
  2. package/dist/{arg-registry-BUUhZ7JR.d.ts.map → arg-registry-2m40k1Et.d.ts.map} +1 -1
  3. package/dist/augment.d.ts +1 -1
  4. package/dist/completion/index.cjs +16 -168
  5. package/dist/completion/index.d.cts +2 -77
  6. package/dist/completion/index.d.ts +2 -77
  7. package/dist/completion/index.js +3 -154
  8. package/dist/{zsh-CASZWn0o.cjs → completion-Df0eZ70u.cjs} +326 -37
  9. package/dist/completion-Df0eZ70u.cjs.map +1 -0
  10. package/dist/{zsh-hjvdI8uZ.js → completion-_AnQsWh9.js} +298 -27
  11. package/dist/completion-_AnQsWh9.js.map +1 -0
  12. package/dist/docs/index.cjs +276 -29
  13. package/dist/docs/index.cjs.map +1 -1
  14. package/dist/docs/index.d.cts +62 -7
  15. package/dist/docs/index.d.cts.map +1 -1
  16. package/dist/docs/index.d.ts +62 -7
  17. package/dist/docs/index.d.ts.map +1 -1
  18. package/dist/docs/index.js +271 -30
  19. package/dist/docs/index.js.map +1 -1
  20. package/dist/{value-completion-resolver-BQgHsX7b.d.cts → index-BZalbMeu.d.ts} +83 -4
  21. package/dist/index-BZalbMeu.d.ts.map +1 -0
  22. package/dist/{value-completion-resolver-C9LTGr0O.d.ts → index-C5-0RXiH.d.cts} +83 -4
  23. package/dist/index-C5-0RXiH.d.cts.map +1 -0
  24. package/dist/index.cjs +8 -7
  25. package/dist/index.d.cts +67 -13
  26. package/dist/index.d.cts.map +1 -1
  27. package/dist/index.d.ts +68 -14
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +4 -5
  30. package/dist/{lazy-BEDnSR0m.cjs → lazy-DHlvJiQQ.cjs} +44 -8
  31. package/dist/lazy-DHlvJiQQ.cjs.map +1 -0
  32. package/dist/{lazy-BrEg8SgI.js → lazy-DSyfzR-F.js} +38 -8
  33. package/dist/lazy-DSyfzR-F.js.map +1 -0
  34. package/dist/{runner-C4fSHJMe.cjs → runner-C1Aah5c5.cjs} +365 -23
  35. package/dist/runner-C1Aah5c5.cjs.map +1 -0
  36. package/dist/{runner-D6k4BgB4.js → runner-DjG0uBxQ.js} +365 -23
  37. package/dist/runner-DjG0uBxQ.js.map +1 -0
  38. package/dist/{schema-extractor-n9288WJ6.d.ts → schema-extractor-C9APqeSL.d.ts} +30 -3
  39. package/dist/schema-extractor-C9APqeSL.d.ts.map +1 -0
  40. package/dist/{schema-extractor-DFaAZzaY.d.cts → schema-extractor-CVf0J4An.d.cts} +29 -2
  41. package/dist/schema-extractor-CVf0J4An.d.cts.map +1 -0
  42. package/dist/{subcommand-router-CAzBsLSI.js → subcommand-router-CKuy6D2b.js} +2 -2
  43. package/dist/{subcommand-router-CAzBsLSI.js.map → subcommand-router-CKuy6D2b.js.map} +1 -1
  44. package/dist/{subcommand-router-ZjNjFaUL.cjs → subcommand-router-sZHhUP7b.cjs} +2 -2
  45. package/dist/{subcommand-router-ZjNjFaUL.cjs.map → subcommand-router-sZHhUP7b.cjs.map} +1 -1
  46. package/package.json +9 -9
  47. package/dist/completion/index.cjs.map +0 -1
  48. package/dist/completion/index.d.cts.map +0 -1
  49. package/dist/completion/index.d.ts.map +0 -1
  50. package/dist/completion/index.js.map +0 -1
  51. package/dist/lazy-BEDnSR0m.cjs.map +0 -1
  52. package/dist/lazy-BrEg8SgI.js.map +0 -1
  53. package/dist/runner-C4fSHJMe.cjs.map +0 -1
  54. package/dist/runner-D6k4BgB4.js.map +0 -1
  55. package/dist/schema-extractor-DFaAZzaY.d.cts.map +0 -1
  56. package/dist/schema-extractor-n9288WJ6.d.ts.map +0 -1
  57. package/dist/value-completion-resolver-BQgHsX7b.d.cts.map +0 -1
  58. package/dist/value-completion-resolver-C9LTGr0O.d.ts.map +0 -1
  59. package/dist/zsh-CASZWn0o.cjs.map +0 -1
  60. package/dist/zsh-hjvdI8uZ.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"subcommand-router-ZjNjFaUL.cjs","names":["isLazyCommand"],"sources":["../src/executor/log-collector.ts","../src/executor/subcommand-router.ts"],"sourcesContent":["import type { CollectedLogs, LogEntry, LogLevel, LogStream } from \"../types.js\";\n\n/**\n * Mapping from log level to output stream\n */\nconst LOG_STREAM_MAP: Record<LogLevel, LogStream> = {\n log: \"stdout\",\n info: \"stdout\",\n debug: \"stdout\",\n warn: \"stderr\",\n error: \"stderr\",\n};\n\n/**\n * All log levels\n */\nconst ALL_LOG_LEVELS: LogLevel[] = [\"log\", \"info\", \"debug\", \"warn\", \"error\"];\n\n/**\n * Options for log collector\n */\nexport interface LogCollectorOptions {\n /** Log levels to capture (default: all) */\n levels?: LogLevel[];\n /** Whether to call original console methods (default: true) */\n passthrough?: boolean;\n}\n\n/**\n * Log collector that intercepts console methods\n */\nexport interface LogCollector {\n /** Get collected logs */\n getLogs: () => CollectedLogs;\n /** Start collecting logs */\n start: () => void;\n /** Stop collecting and restore original console methods */\n stop: () => void;\n}\n\n/**\n * Format console arguments to string\n */\nexport function formatArgs(args: unknown[]): string {\n return args\n .map((arg) => {\n if (arg instanceof Error) {\n return arg.message;\n }\n if (typeof arg === \"object\" && arg !== null) {\n try {\n return JSON.stringify(arg);\n } catch {\n return String(arg);\n }\n }\n return String(arg);\n })\n .join(\" \");\n}\n\n/**\n * Create a log collector that intercepts console methods\n *\n * @param options - Options for the log collector\n * @returns A log collector instance\n *\n * @example\n * ```ts\n * const collector = createLogCollector();\n * collector.start();\n *\n * console.log(\"Info message\");\n * console.error(\"Something went wrong\");\n * console.warn(\"This is a warning\");\n *\n * collector.stop();\n * const logs = collector.getLogs();\n * // {\n * // entries: [\n * // { message: \"Info message\", level: \"log\", stream: \"stdout\", timestamp: ... },\n * // { message: \"Something went wrong\", level: \"error\", stream: \"stderr\", timestamp: ... },\n * // { message: \"This is a warning\", level: \"warn\", stream: \"stderr\", timestamp: ... }\n * // ]\n * // }\n * ```\n */\nexport function createLogCollector(options: LogCollectorOptions = {}): LogCollector {\n const entries: LogEntry[] = [];\n const levels = options.levels ?? ALL_LOG_LEVELS;\n const passthrough = options.passthrough ?? true;\n\n let originals: Record<LogLevel, typeof console.log> | null = null;\n\n const createInterceptor = (level: LogLevel, original: typeof console.log) => {\n return (...args: unknown[]) => {\n entries.push({\n message: formatArgs(args),\n timestamp: new Date(),\n level,\n stream: LOG_STREAM_MAP[level],\n });\n if (passthrough) {\n original.apply(console, args);\n }\n };\n };\n\n return {\n getLogs() {\n return { entries: [...entries] };\n },\n start() {\n if (originals !== null) {\n // Already started\n return;\n }\n originals = {\n log: console.log,\n info: console.info,\n debug: console.debug,\n warn: console.warn,\n error: console.error,\n };\n for (const level of levels) {\n console[level] = createInterceptor(level, originals[level]);\n }\n },\n stop() {\n if (originals === null) {\n return;\n }\n for (const level of levels) {\n console[level] = originals[level];\n }\n originals = null;\n },\n };\n}\n\n/**\n * Merge multiple CollectedLogs into one (sorted by timestamp)\n */\nexport function mergeLogs(...logsArray: CollectedLogs[]): CollectedLogs {\n return {\n entries: logsArray\n .flatMap((l) => l.entries)\n .sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime()),\n };\n}\n\n/**\n * Create an empty CollectedLogs object\n */\nexport function emptyLogs(): CollectedLogs {\n return { entries: [] };\n}\n","import { isLazyCommand } from \"../lazy.js\";\nimport type { AnyCommand, SubCommandValue } from \"../types.js\";\n\n/**\n * Resolve a lazy-loaded command (sync or async)\n *\n * @param cmd - The command or lazy loader function\n * @returns The resolved command\n */\nexport async function resolveLazyCommand(cmd: SubCommandValue): Promise<AnyCommand> {\n if (isLazyCommand(cmd)) {\n return await cmd.load();\n }\n if (typeof cmd === \"function\") {\n return await cmd();\n }\n return cmd;\n}\n\n/**\n * Resolve a subcommand by name\n *\n * Handles both sync and async (lazy-loaded) subcommands.\n *\n * @param command - The parent command\n * @param name - The subcommand name to resolve\n * @returns The resolved subcommand, or undefined if not found\n */\nexport async function resolveSubcommand(\n command: AnyCommand,\n name: string,\n): Promise<AnyCommand | undefined> {\n if (!command.subCommands) {\n return undefined;\n }\n\n const subCmd = command.subCommands[name];\n\n if (!subCmd) {\n return undefined;\n }\n\n return resolveLazyCommand(subCmd);\n}\n\n/**\n * List all subcommand names for a command\n *\n * @param command - The parent command\n * @returns Array of subcommand names\n */\nexport function listSubCommands(command: AnyCommand): string[] {\n if (!command.subCommands) {\n return [];\n }\n\n return Object.keys(command.subCommands);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,MAAM,iBAA8C;CAClD,KAAK;CACL,MAAM;CACN,OAAO;CACP,MAAM;CACN,OAAO;CACR;;;;AAKD,MAAM,iBAA6B;CAAC;CAAO;CAAQ;CAAS;CAAQ;CAAQ;;;;AA2B5E,SAAgB,WAAW,MAAyB;AAClD,QAAO,KACJ,KAAK,QAAQ;AACZ,MAAI,eAAe,MACjB,QAAO,IAAI;AAEb,MAAI,OAAO,QAAQ,YAAY,QAAQ,KACrC,KAAI;AACF,UAAO,KAAK,UAAU,IAAI;UACpB;AACN,UAAO,OAAO,IAAI;;AAGtB,SAAO,OAAO,IAAI;GAClB,CACD,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6Bd,SAAgB,mBAAmB,UAA+B,EAAE,EAAgB;CAClF,MAAM,UAAsB,EAAE;CAC9B,MAAM,SAAS,QAAQ,UAAU;CACjC,MAAM,cAAc,QAAQ,eAAe;CAE3C,IAAI,YAAyD;CAE7D,MAAM,qBAAqB,OAAiB,aAAiC;AAC3E,UAAQ,GAAG,SAAoB;AAC7B,WAAQ,KAAK;IACX,SAAS,WAAW,KAAK;IACzB,2BAAW,IAAI,MAAM;IACrB;IACA,QAAQ,eAAe;IACxB,CAAC;AACF,OAAI,YACF,UAAS,MAAM,SAAS,KAAK;;;AAKnC,QAAO;EACL,UAAU;AACR,UAAO,EAAE,SAAS,CAAC,GAAG,QAAQ,EAAE;;EAElC,QAAQ;AACN,OAAI,cAAc,KAEhB;AAEF,eAAY;IACV,KAAK,QAAQ;IACb,MAAM,QAAQ;IACd,OAAO,QAAQ;IACf,MAAM,QAAQ;IACd,OAAO,QAAQ;IAChB;AACD,QAAK,MAAM,SAAS,OAClB,SAAQ,SAAS,kBAAkB,OAAO,UAAU,OAAO;;EAG/D,OAAO;AACL,OAAI,cAAc,KAChB;AAEF,QAAK,MAAM,SAAS,OAClB,SAAQ,SAAS,UAAU;AAE7B,eAAY;;EAEf;;;;;AAMH,SAAgB,UAAU,GAAG,WAA2C;AACtE,QAAO,EACL,SAAS,UACN,SAAS,MAAM,EAAE,QAAQ,CACzB,MAAM,GAAG,MAAM,EAAE,UAAU,SAAS,GAAG,EAAE,UAAU,SAAS,CAAC,EACjE;;;;;AAMH,SAAgB,YAA2B;AACzC,QAAO,EAAE,SAAS,EAAE,EAAE;;;;;;;;;;;AClJxB,eAAsB,mBAAmB,KAA2C;AAClF,KAAIA,2BAAc,IAAI,CACpB,QAAO,MAAM,IAAI,MAAM;AAEzB,KAAI,OAAO,QAAQ,WACjB,QAAO,MAAM,KAAK;AAEpB,QAAO;;;;;;;;;;;AAYT,eAAsB,kBACpB,SACA,MACiC;AACjC,KAAI,CAAC,QAAQ,YACX;CAGF,MAAM,SAAS,QAAQ,YAAY;AAEnC,KAAI,CAAC,OACH;AAGF,QAAO,mBAAmB,OAAO;;;;;;;;AASnC,SAAgB,gBAAgB,SAA+B;AAC7D,KAAI,CAAC,QAAQ,YACX,QAAO,EAAE;AAGX,QAAO,OAAO,KAAK,QAAQ,YAAY"}
1
+ {"version":3,"file":"subcommand-router-sZHhUP7b.cjs","names":["isLazyCommand"],"sources":["../src/executor/log-collector.ts","../src/executor/subcommand-router.ts"],"sourcesContent":["import type { CollectedLogs, LogEntry, LogLevel, LogStream } from \"../types.js\";\n\n/**\n * Mapping from log level to output stream\n */\nconst LOG_STREAM_MAP: Record<LogLevel, LogStream> = {\n log: \"stdout\",\n info: \"stdout\",\n debug: \"stdout\",\n warn: \"stderr\",\n error: \"stderr\",\n};\n\n/**\n * All log levels\n */\nconst ALL_LOG_LEVELS: LogLevel[] = [\"log\", \"info\", \"debug\", \"warn\", \"error\"];\n\n/**\n * Options for log collector\n */\nexport interface LogCollectorOptions {\n /** Log levels to capture (default: all) */\n levels?: LogLevel[];\n /** Whether to call original console methods (default: true) */\n passthrough?: boolean;\n}\n\n/**\n * Log collector that intercepts console methods\n */\nexport interface LogCollector {\n /** Get collected logs */\n getLogs: () => CollectedLogs;\n /** Start collecting logs */\n start: () => void;\n /** Stop collecting and restore original console methods */\n stop: () => void;\n}\n\n/**\n * Format console arguments to string\n */\nexport function formatArgs(args: unknown[]): string {\n return args\n .map((arg) => {\n if (arg instanceof Error) {\n return arg.message;\n }\n if (typeof arg === \"object\" && arg !== null) {\n try {\n return JSON.stringify(arg);\n } catch {\n return String(arg);\n }\n }\n return String(arg);\n })\n .join(\" \");\n}\n\n/**\n * Create a log collector that intercepts console methods\n *\n * @param options - Options for the log collector\n * @returns A log collector instance\n *\n * @example\n * ```ts\n * const collector = createLogCollector();\n * collector.start();\n *\n * console.log(\"Info message\");\n * console.error(\"Something went wrong\");\n * console.warn(\"This is a warning\");\n *\n * collector.stop();\n * const logs = collector.getLogs();\n * // {\n * // entries: [\n * // { message: \"Info message\", level: \"log\", stream: \"stdout\", timestamp: ... },\n * // { message: \"Something went wrong\", level: \"error\", stream: \"stderr\", timestamp: ... },\n * // { message: \"This is a warning\", level: \"warn\", stream: \"stderr\", timestamp: ... }\n * // ]\n * // }\n * ```\n */\nexport function createLogCollector(options: LogCollectorOptions = {}): LogCollector {\n const entries: LogEntry[] = [];\n const levels = options.levels ?? ALL_LOG_LEVELS;\n const passthrough = options.passthrough ?? true;\n\n let originals: Record<LogLevel, typeof console.log> | null = null;\n\n const createInterceptor = (level: LogLevel, original: typeof console.log) => {\n return (...args: unknown[]) => {\n entries.push({\n message: formatArgs(args),\n timestamp: new Date(),\n level,\n stream: LOG_STREAM_MAP[level],\n });\n if (passthrough) {\n original.apply(console, args);\n }\n };\n };\n\n return {\n getLogs() {\n return { entries: [...entries] };\n },\n start() {\n if (originals !== null) {\n // Already started\n return;\n }\n originals = {\n log: console.log,\n info: console.info,\n debug: console.debug,\n warn: console.warn,\n error: console.error,\n };\n for (const level of levels) {\n console[level] = createInterceptor(level, originals[level]);\n }\n },\n stop() {\n if (originals === null) {\n return;\n }\n for (const level of levels) {\n console[level] = originals[level];\n }\n originals = null;\n },\n };\n}\n\n/**\n * Merge multiple CollectedLogs into one (sorted by timestamp)\n */\nexport function mergeLogs(...logsArray: CollectedLogs[]): CollectedLogs {\n return {\n entries: logsArray\n .flatMap((l) => l.entries)\n .sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime()),\n };\n}\n\n/**\n * Create an empty CollectedLogs object\n */\nexport function emptyLogs(): CollectedLogs {\n return { entries: [] };\n}\n","import { isLazyCommand } from \"../lazy.js\";\nimport type { AnyCommand, SubCommandValue } from \"../types.js\";\n\n/**\n * Resolve a lazy-loaded command (sync or async)\n *\n * @param cmd - The command or lazy loader function\n * @returns The resolved command\n */\nexport async function resolveLazyCommand(cmd: SubCommandValue): Promise<AnyCommand> {\n if (isLazyCommand(cmd)) {\n return await cmd.load();\n }\n if (typeof cmd === \"function\") {\n return await cmd();\n }\n return cmd;\n}\n\n/**\n * Resolve a subcommand by name\n *\n * Handles both sync and async (lazy-loaded) subcommands.\n *\n * @param command - The parent command\n * @param name - The subcommand name to resolve\n * @returns The resolved subcommand, or undefined if not found\n */\nexport async function resolveSubcommand(\n command: AnyCommand,\n name: string,\n): Promise<AnyCommand | undefined> {\n if (!command.subCommands) {\n return undefined;\n }\n\n const subCmd = command.subCommands[name];\n\n if (!subCmd) {\n return undefined;\n }\n\n return resolveLazyCommand(subCmd);\n}\n\n/**\n * List all subcommand names for a command\n *\n * @param command - The parent command\n * @returns Array of subcommand names\n */\nexport function listSubCommands(command: AnyCommand): string[] {\n if (!command.subCommands) {\n return [];\n }\n\n return Object.keys(command.subCommands);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,MAAM,iBAA8C;CAClD,KAAK;CACL,MAAM;CACN,OAAO;CACP,MAAM;CACN,OAAO;CACR;;;;AAKD,MAAM,iBAA6B;CAAC;CAAO;CAAQ;CAAS;CAAQ;CAAQ;;;;AA2B5E,SAAgB,WAAW,MAAyB;AAClD,QAAO,KACJ,KAAK,QAAQ;AACZ,MAAI,eAAe,MACjB,QAAO,IAAI;AAEb,MAAI,OAAO,QAAQ,YAAY,QAAQ,KACrC,KAAI;AACF,UAAO,KAAK,UAAU,IAAI;UACpB;AACN,UAAO,OAAO,IAAI;;AAGtB,SAAO,OAAO,IAAI;GAClB,CACD,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6Bd,SAAgB,mBAAmB,UAA+B,EAAE,EAAgB;CAClF,MAAM,UAAsB,EAAE;CAC9B,MAAM,SAAS,QAAQ,UAAU;CACjC,MAAM,cAAc,QAAQ,eAAe;CAE3C,IAAI,YAAyD;CAE7D,MAAM,qBAAqB,OAAiB,aAAiC;AAC3E,UAAQ,GAAG,SAAoB;AAC7B,WAAQ,KAAK;IACX,SAAS,WAAW,KAAK;IACzB,2BAAW,IAAI,MAAM;IACrB;IACA,QAAQ,eAAe;IACxB,CAAC;AACF,OAAI,YACF,UAAS,MAAM,SAAS,KAAK;;;AAKnC,QAAO;EACL,UAAU;AACR,UAAO,EAAE,SAAS,CAAC,GAAG,QAAQ,EAAE;;EAElC,QAAQ;AACN,OAAI,cAAc,KAEhB;AAEF,eAAY;IACV,KAAK,QAAQ;IACb,MAAM,QAAQ;IACd,OAAO,QAAQ;IACf,MAAM,QAAQ;IACd,OAAO,QAAQ;IAChB;AACD,QAAK,MAAM,SAAS,OAClB,SAAQ,SAAS,kBAAkB,OAAO,UAAU,OAAO;;EAG/D,OAAO;AACL,OAAI,cAAc,KAChB;AAEF,QAAK,MAAM,SAAS,OAClB,SAAQ,SAAS,UAAU;AAE7B,eAAY;;EAEf;;;;;AAMH,SAAgB,UAAU,GAAG,WAA2C;AACtE,QAAO,EACL,SAAS,UACN,SAAS,MAAM,EAAE,QAAQ,CACzB,MAAM,GAAG,MAAM,EAAE,UAAU,SAAS,GAAG,EAAE,UAAU,SAAS,CAAC,EACjE;;;;;AAMH,SAAgB,YAA2B;AACzC,QAAO,EAAE,SAAS,EAAE,EAAE;;;;;;;;;;;AClJxB,eAAsB,mBAAmB,KAA2C;AAClF,KAAIA,2BAAc,IAAI,CACpB,QAAO,MAAM,IAAI,MAAM;AAEzB,KAAI,OAAO,QAAQ,WACjB,QAAO,MAAM,KAAK;AAEpB,QAAO;;;;;;;;;;;AAYT,eAAsB,kBACpB,SACA,MACiC;AACjC,KAAI,CAAC,QAAQ,YACX;CAGF,MAAM,SAAS,QAAQ,YAAY;AAEnC,KAAI,CAAC,OACH;AAGF,QAAO,mBAAmB,OAAO;;;;;;;;AASnC,SAAgB,gBAAgB,SAA+B;AAC7D,KAAI,CAAC,QAAQ,YACX,QAAO,EAAE;AAGX,QAAO,OAAO,KAAK,QAAQ,YAAY"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "politty",
3
- "version": "0.4.3",
3
+ "version": "0.4.6",
4
4
  "description": "A lightweight CLI framework inspired by citty with zod v4 registry integration for type-safe metadata management",
5
5
  "keywords": [
6
6
  "argument-parser",
@@ -69,18 +69,18 @@
69
69
  "string-width": "^8.2.0"
70
70
  },
71
71
  "devDependencies": {
72
- "@changesets/cli": "2.29.8",
72
+ "@changesets/cli": "2.30.0",
73
73
  "@quansync/fs": "1.0.0",
74
- "@types/node": "25.3.2",
75
- "@typescript/native-preview": "7.0.0-dev.20260226.1",
74
+ "@types/node": "25.3.5",
75
+ "@typescript/native-preview": "7.0.0-dev.20260307.1",
76
76
  "@vitest/coverage-v8": "4.0.18",
77
- "knip": "5.85.0",
78
- "lefthook": "2.1.1",
77
+ "knip": "5.86.0",
78
+ "lefthook": "2.1.3",
79
79
  "organize-imports-cli": "0.10.0",
80
- "oxfmt": "0.35.0",
81
- "oxlint": "1.50.0",
80
+ "oxfmt": "0.36.0",
81
+ "oxlint": "1.51.0",
82
82
  "quansync": "1.0.0",
83
- "tsdown": "0.20.3",
83
+ "tsdown": "0.21.0",
84
84
  "tsx": "4.21.0",
85
85
  "typescript": "5.9.3",
86
86
  "vitest": "4.0.18",
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs","names":["generateBashCompletion","generateZshCompletion","generateFishCompletion","z","arg","createDynamicCompleteCommand","defineCommand"],"sources":["../../src/completion/index.ts"],"sourcesContent":["/**\n * Shell completion generation module\n *\n * Provides utilities to generate shell completion scripts for bash, zsh, and fish.\n *\n * @example\n * ```typescript\n * import { generateCompletion, createCompletionCommand } from \"politty/completion\";\n *\n * // Generate completion script directly\n * const result = generateCompletion(myCommand, {\n * shell: \"bash\",\n * programName: \"mycli\"\n * });\n * console.log(result.script);\n *\n * // Or add a completion subcommand to your CLI\n * const mainCommand = withCompletionCommand(\n * defineCommand({\n * name: \"mycli\",\n * subCommands: { ... },\n * }),\n * );\n * ```\n */\n\nimport { z } from \"zod\";\nimport { arg } from \"../core/arg-registry.js\";\nimport { defineCommand } from \"../core/command.js\";\nimport type { AnyCommand, Command } from \"../types.js\";\nimport { generateBashCompletion } from \"./bash.js\";\nimport { createDynamicCompleteCommand } from \"./dynamic/index.js\";\nimport { generateFishCompletion } from \"./fish.js\";\nimport type { CompletionOptions, CompletionResult, ShellType } from \"./types.js\";\nimport { generateZshCompletion } from \"./zsh.js\";\n\n// Re-export dynamic completion\nexport {\n CompletionDirective,\n createDynamicCompleteCommand,\n formatForShell,\n generateCandidates,\n hasCompleteCommand,\n parseCompletionContext,\n type CandidateResult,\n type CompletionCandidate,\n type CompletionContext,\n type CompletionType,\n type ShellFormatOptions,\n} from \"./dynamic/index.js\";\n// Re-export extractor\nexport { extractCompletionData, extractPositionals } from \"./extractor.js\";\n// Re-export types\nexport type {\n CompletableOption,\n CompletableSubcommand,\n CompletionData,\n CompletionGenerator,\n CompletionOptions,\n CompletionResult,\n ShellType,\n} from \"./types.js\";\n// Re-export value completion resolver\nexport { resolveValueCompletion, type ValueCompletionField } from \"./value-completion-resolver.js\";\n\n/**\n * Generate completion script for the specified shell\n */\nexport function generateCompletion(\n command: AnyCommand,\n options: CompletionOptions,\n): CompletionResult {\n switch (options.shell) {\n case \"bash\":\n return generateBashCompletion(command, options);\n case \"zsh\":\n return generateZshCompletion(command, options);\n case \"fish\":\n return generateFishCompletion(command, options);\n default:\n throw new Error(`Unsupported shell: ${options.shell}`);\n }\n}\n\n/**\n * Get the list of supported shells\n */\nexport function getSupportedShells(): ShellType[] {\n return [\"bash\", \"zsh\", \"fish\"];\n}\n\n/**\n * Detect the current shell from environment\n */\nexport function detectShell(): ShellType | null {\n const shell = process.env.SHELL || \"\";\n const shellName = shell.split(\"/\").pop()?.toLowerCase() || \"\";\n\n if (shellName.includes(\"bash\")) {\n return \"bash\";\n }\n if (shellName.includes(\"zsh\")) {\n return \"zsh\";\n }\n if (shellName.includes(\"fish\")) {\n return \"fish\";\n }\n\n return null;\n}\n\n/**\n * Schema for the completion command arguments\n */\nconst completionArgsSchema = z.object({\n shell: arg(\n z\n .enum([\"bash\", \"zsh\", \"fish\"])\n .optional()\n .describe(\"Shell type (auto-detected if not specified)\"),\n {\n positional: true,\n description: \"Shell type (bash, zsh, or fish)\",\n placeholder: \"SHELL\",\n },\n ),\n instructions: arg(z.boolean().default(false), {\n alias: \"i\",\n description: \"Show installation instructions\",\n }),\n});\n\ntype CompletionArgs = z.infer<typeof completionArgsSchema>;\n\n/**\n * Create a completion subcommand for your CLI\n *\n * This creates a ready-to-use subcommand that generates completion scripts.\n *\n * @example\n * ```typescript\n * const mainCommand = defineCommand({\n * name: \"mycli\",\n * subCommands: {\n * completion: createCompletionCommand(mainCommand)\n * }\n * });\n * ```\n */\nexport function createCompletionCommand(\n rootCommand: AnyCommand,\n programName?: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): Command<typeof completionArgsSchema, CompletionArgs, any> {\n const resolvedProgramName = programName ?? rootCommand.name;\n\n if (!rootCommand.subCommands?.__complete) {\n rootCommand.subCommands = {\n ...rootCommand.subCommands,\n __complete: createDynamicCompleteCommand(rootCommand, resolvedProgramName),\n };\n }\n\n return defineCommand({\n name: \"completion\",\n description: \"Generate shell completion script\",\n args: completionArgsSchema,\n run(args) {\n // Detect shell if not specified\n const shellType = args.shell || detectShell();\n\n if (!shellType) {\n console.error(\"Could not detect shell type. Please specify one of: bash, zsh, fish\");\n process.exitCode = 1;\n return;\n }\n\n const result = generateCompletion(rootCommand, {\n shell: shellType,\n programName: resolvedProgramName,\n includeDescriptions: true,\n });\n\n if (args.instructions) {\n console.log(result.installInstructions);\n } else {\n console.log(result.script);\n }\n },\n });\n}\n\n/**\n * Options for withCompletionCommand\n */\nexport interface WithCompletionOptions {\n /** Override the program name (defaults to command.name) */\n programName?: string;\n}\n\n/**\n * Wrap a command with a completion subcommand\n *\n * This avoids circular references that occur when a command references itself\n * in its subCommands (e.g., for completion generation).\n *\n * @param command - The command to wrap\n * @param options - Options including programName\n * @returns A new command with the completion subcommand added\n *\n * @example\n * ```typescript\n * const mainCommand = withCompletionCommand(\n * defineCommand({\n * name: \"mycli\",\n * subCommands: { ... },\n * }),\n * );\n * ```\n */\nexport function withCompletionCommand<T extends AnyCommand>(\n command: T,\n options?: string | WithCompletionOptions,\n): T {\n // Support both string (programName) and options object for backwards compatibility\n const opts: WithCompletionOptions =\n typeof options === \"string\" ? { programName: options } : (options ?? {});\n\n const { programName } = opts;\n\n const wrappedCommand = {\n ...command,\n } as T;\n\n wrappedCommand.subCommands = {\n ...command.subCommands,\n completion: createCompletionCommand(wrappedCommand, programName),\n __complete: createDynamicCompleteCommand(wrappedCommand, programName),\n };\n\n return wrappedCommand;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoEA,SAAgB,mBACd,SACA,SACkB;AAClB,SAAQ,QAAQ,OAAhB;EACE,KAAK,OACH,QAAOA,mCAAuB,SAAS,QAAQ;EACjD,KAAK,MACH,QAAOC,kCAAsB,SAAS,QAAQ;EAChD,KAAK,OACH,QAAOC,mCAAuB,SAAS,QAAQ;EACjD,QACE,OAAM,IAAI,MAAM,sBAAsB,QAAQ,QAAQ;;;;;;AAO5D,SAAgB,qBAAkC;AAChD,QAAO;EAAC;EAAQ;EAAO;EAAO;;;;;AAMhC,SAAgB,cAAgC;CAE9C,MAAM,aADQ,QAAQ,IAAI,SAAS,IACX,MAAM,IAAI,CAAC,KAAK,EAAE,aAAa,IAAI;AAE3D,KAAI,UAAU,SAAS,OAAO,CAC5B,QAAO;AAET,KAAI,UAAU,SAAS,MAAM,CAC3B,QAAO;AAET,KAAI,UAAU,SAAS,OAAO,CAC5B,QAAO;AAGT,QAAO;;;;;AAMT,MAAM,uBAAuBC,MAAE,OAAO;CACpC,OAAOC,iBACLD,MACG,KAAK;EAAC;EAAQ;EAAO;EAAO,CAAC,CAC7B,UAAU,CACV,SAAS,8CAA8C,EAC1D;EACE,YAAY;EACZ,aAAa;EACb,aAAa;EACd,CACF;CACD,cAAcC,iBAAID,MAAE,SAAS,CAAC,QAAQ,MAAM,EAAE;EAC5C,OAAO;EACP,aAAa;EACd,CAAC;CACH,CAAC;;;;;;;;;;;;;;;;AAmBF,SAAgB,wBACd,aACA,aAE2D;CAC3D,MAAM,sBAAsB,eAAe,YAAY;AAEvD,KAAI,CAAC,YAAY,aAAa,WAC5B,aAAY,cAAc;EACxB,GAAG,YAAY;EACf,YAAYE,yCAA6B,aAAa,oBAAoB;EAC3E;AAGH,QAAOC,0BAAc;EACnB,MAAM;EACN,aAAa;EACb,MAAM;EACN,IAAI,MAAM;GAER,MAAM,YAAY,KAAK,SAAS,aAAa;AAE7C,OAAI,CAAC,WAAW;AACd,YAAQ,MAAM,sEAAsE;AACpF,YAAQ,WAAW;AACnB;;GAGF,MAAM,SAAS,mBAAmB,aAAa;IAC7C,OAAO;IACP,aAAa;IACb,qBAAqB;IACtB,CAAC;AAEF,OAAI,KAAK,aACP,SAAQ,IAAI,OAAO,oBAAoB;OAEvC,SAAQ,IAAI,OAAO,OAAO;;EAG/B,CAAC;;;;;;;;;;;;;;;;;;;;;;AA+BJ,SAAgB,sBACd,SACA,SACG;CAKH,MAAM,EAAE,gBAFN,OAAO,YAAY,WAAW,EAAE,aAAa,SAAS,GAAI,WAAW,EAAE;CAIzE,MAAM,iBAAiB,EACrB,GAAG,SACJ;AAED,gBAAe,cAAc;EAC3B,GAAG,QAAQ;EACX,YAAY,wBAAwB,gBAAgB,YAAY;EAChE,YAAYD,yCAA6B,gBAAgB,YAAY;EACtE;AAED,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/completion/index.ts"],"mappings":";;;;;;;;;iBAoEgB,kBAAA,CACd,OAAA,EAAS,UAAA,EACT,OAAA,EAAS,iBAAA,GACR,gBAAA;;;;iBAgBa,kBAAA,CAAA,GAAsB,SAAA;;;;iBAOtB,WAAA,CAAA,GAAe,SAAA;;;;cAoBzB,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;;;;;KAkBrB,cAAA,GAAiB,CAAA,CAAE,KAAA,QAAa,oBAAA;;;;;;;;;;;;;;;;iBAiBrB,uBAAA,CACd,WAAA,EAAa,UAAA,EACb,WAAA,YAEC,OAAA,QAAe,oBAAA,EAAsB,cAAA;;;;UA0CvB,qBAAA;EA1CuB;EA4CtC,WAAA;AAAA;;;;;;;;;;AAFF;;;;;AAyBA;;;;;;iBAAgB,qBAAA,WAAgC,UAAA,CAAA,CAC9C,OAAA,EAAS,CAAA,EACT,OAAA,YAAmB,qBAAA,GAClB,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/completion/index.ts"],"mappings":";;;;;;;;;iBAoEgB,kBAAA,CACd,OAAA,EAAS,UAAA,EACT,OAAA,EAAS,iBAAA,GACR,gBAAA;;;;iBAgBa,kBAAA,CAAA,GAAsB,SAAA;;;;iBAOtB,WAAA,CAAA,GAAe,SAAA;;;;cAoBzB,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;;;;;KAkBrB,cAAA,GAAiB,CAAA,CAAE,KAAA,QAAa,oBAAA;;;;;;;;;;;;;;;;iBAiBrB,uBAAA,CACd,WAAA,EAAa,UAAA,EACb,WAAA,YAEC,OAAA,QAAe,oBAAA,EAAsB,cAAA;;;;UA0CvB,qBAAA;EA1CuB;EA4CtC,WAAA;AAAA;;;;;;;;;;AAFF;;;;;AAyBA;;;;;;iBAAgB,qBAAA,WAAgC,UAAA,CAAA,CAC9C,OAAA,EAAS,CAAA,EACT,OAAA,YAAmB,qBAAA,GAClB,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/completion/index.ts"],"sourcesContent":["/**\n * Shell completion generation module\n *\n * Provides utilities to generate shell completion scripts for bash, zsh, and fish.\n *\n * @example\n * ```typescript\n * import { generateCompletion, createCompletionCommand } from \"politty/completion\";\n *\n * // Generate completion script directly\n * const result = generateCompletion(myCommand, {\n * shell: \"bash\",\n * programName: \"mycli\"\n * });\n * console.log(result.script);\n *\n * // Or add a completion subcommand to your CLI\n * const mainCommand = withCompletionCommand(\n * defineCommand({\n * name: \"mycli\",\n * subCommands: { ... },\n * }),\n * );\n * ```\n */\n\nimport { z } from \"zod\";\nimport { arg } from \"../core/arg-registry.js\";\nimport { defineCommand } from \"../core/command.js\";\nimport type { AnyCommand, Command } from \"../types.js\";\nimport { generateBashCompletion } from \"./bash.js\";\nimport { createDynamicCompleteCommand } from \"./dynamic/index.js\";\nimport { generateFishCompletion } from \"./fish.js\";\nimport type { CompletionOptions, CompletionResult, ShellType } from \"./types.js\";\nimport { generateZshCompletion } from \"./zsh.js\";\n\n// Re-export dynamic completion\nexport {\n CompletionDirective,\n createDynamicCompleteCommand,\n formatForShell,\n generateCandidates,\n hasCompleteCommand,\n parseCompletionContext,\n type CandidateResult,\n type CompletionCandidate,\n type CompletionContext,\n type CompletionType,\n type ShellFormatOptions,\n} from \"./dynamic/index.js\";\n// Re-export extractor\nexport { extractCompletionData, extractPositionals } from \"./extractor.js\";\n// Re-export types\nexport type {\n CompletableOption,\n CompletableSubcommand,\n CompletionData,\n CompletionGenerator,\n CompletionOptions,\n CompletionResult,\n ShellType,\n} from \"./types.js\";\n// Re-export value completion resolver\nexport { resolveValueCompletion, type ValueCompletionField } from \"./value-completion-resolver.js\";\n\n/**\n * Generate completion script for the specified shell\n */\nexport function generateCompletion(\n command: AnyCommand,\n options: CompletionOptions,\n): CompletionResult {\n switch (options.shell) {\n case \"bash\":\n return generateBashCompletion(command, options);\n case \"zsh\":\n return generateZshCompletion(command, options);\n case \"fish\":\n return generateFishCompletion(command, options);\n default:\n throw new Error(`Unsupported shell: ${options.shell}`);\n }\n}\n\n/**\n * Get the list of supported shells\n */\nexport function getSupportedShells(): ShellType[] {\n return [\"bash\", \"zsh\", \"fish\"];\n}\n\n/**\n * Detect the current shell from environment\n */\nexport function detectShell(): ShellType | null {\n const shell = process.env.SHELL || \"\";\n const shellName = shell.split(\"/\").pop()?.toLowerCase() || \"\";\n\n if (shellName.includes(\"bash\")) {\n return \"bash\";\n }\n if (shellName.includes(\"zsh\")) {\n return \"zsh\";\n }\n if (shellName.includes(\"fish\")) {\n return \"fish\";\n }\n\n return null;\n}\n\n/**\n * Schema for the completion command arguments\n */\nconst completionArgsSchema = z.object({\n shell: arg(\n z\n .enum([\"bash\", \"zsh\", \"fish\"])\n .optional()\n .describe(\"Shell type (auto-detected if not specified)\"),\n {\n positional: true,\n description: \"Shell type (bash, zsh, or fish)\",\n placeholder: \"SHELL\",\n },\n ),\n instructions: arg(z.boolean().default(false), {\n alias: \"i\",\n description: \"Show installation instructions\",\n }),\n});\n\ntype CompletionArgs = z.infer<typeof completionArgsSchema>;\n\n/**\n * Create a completion subcommand for your CLI\n *\n * This creates a ready-to-use subcommand that generates completion scripts.\n *\n * @example\n * ```typescript\n * const mainCommand = defineCommand({\n * name: \"mycli\",\n * subCommands: {\n * completion: createCompletionCommand(mainCommand)\n * }\n * });\n * ```\n */\nexport function createCompletionCommand(\n rootCommand: AnyCommand,\n programName?: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): Command<typeof completionArgsSchema, CompletionArgs, any> {\n const resolvedProgramName = programName ?? rootCommand.name;\n\n if (!rootCommand.subCommands?.__complete) {\n rootCommand.subCommands = {\n ...rootCommand.subCommands,\n __complete: createDynamicCompleteCommand(rootCommand, resolvedProgramName),\n };\n }\n\n return defineCommand({\n name: \"completion\",\n description: \"Generate shell completion script\",\n args: completionArgsSchema,\n run(args) {\n // Detect shell if not specified\n const shellType = args.shell || detectShell();\n\n if (!shellType) {\n console.error(\"Could not detect shell type. Please specify one of: bash, zsh, fish\");\n process.exitCode = 1;\n return;\n }\n\n const result = generateCompletion(rootCommand, {\n shell: shellType,\n programName: resolvedProgramName,\n includeDescriptions: true,\n });\n\n if (args.instructions) {\n console.log(result.installInstructions);\n } else {\n console.log(result.script);\n }\n },\n });\n}\n\n/**\n * Options for withCompletionCommand\n */\nexport interface WithCompletionOptions {\n /** Override the program name (defaults to command.name) */\n programName?: string;\n}\n\n/**\n * Wrap a command with a completion subcommand\n *\n * This avoids circular references that occur when a command references itself\n * in its subCommands (e.g., for completion generation).\n *\n * @param command - The command to wrap\n * @param options - Options including programName\n * @returns A new command with the completion subcommand added\n *\n * @example\n * ```typescript\n * const mainCommand = withCompletionCommand(\n * defineCommand({\n * name: \"mycli\",\n * subCommands: { ... },\n * }),\n * );\n * ```\n */\nexport function withCompletionCommand<T extends AnyCommand>(\n command: T,\n options?: string | WithCompletionOptions,\n): T {\n // Support both string (programName) and options object for backwards compatibility\n const opts: WithCompletionOptions =\n typeof options === \"string\" ? { programName: options } : (options ?? {});\n\n const { programName } = opts;\n\n const wrappedCommand = {\n ...command,\n } as T;\n\n wrappedCommand.subCommands = {\n ...command.subCommands,\n completion: createCompletionCommand(wrappedCommand, programName),\n __complete: createDynamicCompleteCommand(wrappedCommand, programName),\n };\n\n return wrappedCommand;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoEA,SAAgB,mBACd,SACA,SACkB;AAClB,SAAQ,QAAQ,OAAhB;EACE,KAAK,OACH,QAAO,uBAAuB,SAAS,QAAQ;EACjD,KAAK,MACH,QAAO,sBAAsB,SAAS,QAAQ;EAChD,KAAK,OACH,QAAO,uBAAuB,SAAS,QAAQ;EACjD,QACE,OAAM,IAAI,MAAM,sBAAsB,QAAQ,QAAQ;;;;;;AAO5D,SAAgB,qBAAkC;AAChD,QAAO;EAAC;EAAQ;EAAO;EAAO;;;;;AAMhC,SAAgB,cAAgC;CAE9C,MAAM,aADQ,QAAQ,IAAI,SAAS,IACX,MAAM,IAAI,CAAC,KAAK,EAAE,aAAa,IAAI;AAE3D,KAAI,UAAU,SAAS,OAAO,CAC5B,QAAO;AAET,KAAI,UAAU,SAAS,MAAM,CAC3B,QAAO;AAET,KAAI,UAAU,SAAS,OAAO,CAC5B,QAAO;AAGT,QAAO;;;;;AAMT,MAAM,uBAAuB,EAAE,OAAO;CACpC,OAAO,IACL,EACG,KAAK;EAAC;EAAQ;EAAO;EAAO,CAAC,CAC7B,UAAU,CACV,SAAS,8CAA8C,EAC1D;EACE,YAAY;EACZ,aAAa;EACb,aAAa;EACd,CACF;CACD,cAAc,IAAI,EAAE,SAAS,CAAC,QAAQ,MAAM,EAAE;EAC5C,OAAO;EACP,aAAa;EACd,CAAC;CACH,CAAC;;;;;;;;;;;;;;;;AAmBF,SAAgB,wBACd,aACA,aAE2D;CAC3D,MAAM,sBAAsB,eAAe,YAAY;AAEvD,KAAI,CAAC,YAAY,aAAa,WAC5B,aAAY,cAAc;EACxB,GAAG,YAAY;EACf,YAAY,6BAA6B,aAAa,oBAAoB;EAC3E;AAGH,QAAO,cAAc;EACnB,MAAM;EACN,aAAa;EACb,MAAM;EACN,IAAI,MAAM;GAER,MAAM,YAAY,KAAK,SAAS,aAAa;AAE7C,OAAI,CAAC,WAAW;AACd,YAAQ,MAAM,sEAAsE;AACpF,YAAQ,WAAW;AACnB;;GAGF,MAAM,SAAS,mBAAmB,aAAa;IAC7C,OAAO;IACP,aAAa;IACb,qBAAqB;IACtB,CAAC;AAEF,OAAI,KAAK,aACP,SAAQ,IAAI,OAAO,oBAAoB;OAEvC,SAAQ,IAAI,OAAO,OAAO;;EAG/B,CAAC;;;;;;;;;;;;;;;;;;;;;;AA+BJ,SAAgB,sBACd,SACA,SACG;CAKH,MAAM,EAAE,gBAFN,OAAO,YAAY,WAAW,EAAE,aAAa,SAAS,GAAI,WAAW,EAAE;CAIzE,MAAM,iBAAiB,EACrB,GAAG,SACJ;AAED,gBAAe,cAAc;EAC3B,GAAG,QAAQ;EACX,YAAY,wBAAwB,gBAAgB,YAAY;EAChE,YAAY,6BAA6B,gBAAgB,YAAY;EACtE;AAED,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"lazy-BEDnSR0m.cjs","names":["z","getArgMeta","getArgMetaFromRegistry"],"sources":["../src/core/arg-registry.ts","../src/core/schema-extractor.ts","../src/lazy.ts"],"sourcesContent":["import { z } from \"zod\";\n\n/**\n * Built-in completion types\n */\nexport type CompletionType = \"file\" | \"directory\" | \"none\";\n\n/**\n * Custom completion specification\n */\nexport interface CustomCompletion {\n /** Static list of choices for completion */\n choices?: string[];\n /** Shell command to execute for dynamic completion */\n shellCommand?: string;\n}\n\n/**\n * Completion metadata for an argument\n *\n * @example\n * ```ts\n * // File completion with extension filter\n * input: arg(z.string(), {\n * completion: { type: \"file\", extensions: [\"json\", \"yaml\"] }\n * })\n *\n * // Directory completion\n * outputDir: arg(z.string(), {\n * completion: { type: \"directory\" }\n * })\n *\n * // Custom static choices\n * logLevel: arg(z.string(), {\n * completion: { custom: { choices: [\"debug\", \"info\", \"warn\", \"error\"] } }\n * })\n *\n * // Dynamic completion from shell command\n * branch: arg(z.string(), {\n * completion: { custom: { shellCommand: \"git branch --format='%(refname:short)'\" } }\n * })\n *\n * // File completion with glob pattern matcher\n * envFile: arg(z.string(), {\n * completion: { type: \"file\", matcher: [\".env.*\"] }\n * })\n * ```\n */\nexport type CompletionMeta = {\n /** Built-in completion type */\n type?: CompletionType;\n /** Custom completion (takes precedence over type if both specified) */\n custom?: CustomCompletion;\n} & (\n | {\n /** File extension filter (only applies when type is \"file\") */ extensions?: string[];\n matcher?: never;\n }\n | {\n /** Glob patterns for file matching (only applies when type is \"file\") */ matcher?: string[];\n extensions?: never;\n }\n);\n\n/**\n * Base metadata shared by all argument types\n */\nexport interface BaseArgMeta {\n /** Argument description */\n description?: string;\n /** Treat as positional argument */\n positional?: boolean;\n /** Placeholder for help display */\n placeholder?: string;\n /**\n * Environment variable name(s) to read value from.\n * If an array is provided, earlier entries take priority.\n * CLI arguments always take precedence over environment variables.\n *\n * @example\n * ```ts\n * // Single env var\n * port: arg(z.coerce.number(), { env: \"PORT\" })\n *\n * // Multiple env vars (PORT takes priority over SERVER_PORT)\n * port: arg(z.coerce.number(), { env: [\"PORT\", \"SERVER_PORT\"] })\n * ```\n */\n env?: string | string[];\n /** Completion configuration for shell tab-completion */\n completion?: CompletionMeta;\n}\n\n/**\n * Metadata for regular arguments (non-builtin aliases)\n */\nexport interface RegularArgMeta extends BaseArgMeta {\n /** Short alias (e.g., 'v' for --verbose) */\n alias?: string;\n}\n\n/**\n * Metadata for overriding built-in aliases (-h, -H)\n */\nexport interface BuiltinOverrideArgMeta extends BaseArgMeta {\n /** Built-in alias to override ('h' or 'H') */\n alias: \"h\" | \"H\";\n /** Must be true to override built-in aliases */\n overrideBuiltinAlias: true;\n}\n\n/**\n * Metadata options for argument definition\n */\nexport type ArgMeta = RegularArgMeta | BuiltinOverrideArgMeta;\n\n/**\n * Custom registry for politty argument metadata\n * This avoids polluting Zod's GlobalMeta\n */\nexport const argRegistry = z.registry<ArgMeta>();\n\n/**\n * Register metadata for a Zod schema\n *\n * @param schema - The Zod schema\n * @param meta - Argument metadata\n * @returns The same schema (for chaining)\n *\n * @example\n * ```ts\n * import { z } from \"zod\";\n * import { arg, defineCommand } from \"politty\";\n *\n * const cmd = defineCommand({\n * args: z.object({\n * name: arg(z.string(), { description: \"User name\", positional: true }),\n * verbose: arg(z.boolean().default(false), { alias: \"v\" }),\n * }),\n * run: (args) => {\n * console.log(args.name, args.verbose);\n * },\n * });\n * ```\n */\n/**\n * Type helper to validate ArgMeta\n * Forces a type error if alias is \"h\" or \"H\" without overrideBuiltinAlias: true\n */\ntype ValidateArgMeta<M> = M extends { alias: \"h\" | \"H\" }\n ? M extends { overrideBuiltinAlias: true }\n ? M\n : {\n [K in keyof M]: M[K];\n } & {\n __typeError: \"Alias 'h' or 'H' requires overrideBuiltinAlias: true\";\n }\n : M;\n\nexport function arg<T extends z.ZodType>(schema: T): T;\nexport function arg<T extends z.ZodType, M extends ArgMeta>(schema: T, meta: ValidateArgMeta<M>): T;\nexport function arg<T extends z.ZodType, M extends ArgMeta>(\n schema: T,\n meta?: ValidateArgMeta<M>,\n): T {\n if (meta) {\n argRegistry.add(schema, meta as ArgMeta);\n }\n return schema;\n}\n\n/**\n * Get metadata for a schema from the registry\n *\n * @param schema - The Zod schema\n * @returns The metadata if registered, undefined otherwise\n */\nexport function getArgMeta(schema: z.ZodType): ArgMeta | undefined {\n return argRegistry.get(schema);\n}\n","import { z } from \"zod\";\nimport type { AnyCommand, ArgsSchema } from \"../types.js\";\nimport {\n getArgMeta as getArgMetaFromRegistry,\n type ArgMeta,\n type CompletionMeta,\n} from \"./arg-registry.js\";\n\n/**\n * Get ArgMeta from both the custom registry and Zod's _def\n * Priority: custom registry > _def.argMeta\n */\nfunction getArgMeta(schema: z.ZodType): ArgMeta | undefined {\n // First check custom registry\n const fromRegistry = getArgMetaFromRegistry(schema);\n if (fromRegistry) return fromRegistry;\n // Check Zod native meta\n // Some Zod versions or extensions use a global registry accessed via .meta()\n if (typeof (schema as any).meta === \"function\") {\n const meta = (schema as any).meta();\n if (meta && typeof meta === \"object\") {\n return meta as ArgMeta;\n }\n }\n\n // Then check _def.argMeta (for augmented Zod types)\n const def = (schema as any)._def;\n if (def?.argMeta) return def.argMeta;\n\n // Also check _def.meta just in case\n if (def?.meta) return def.meta as ArgMeta;\n\n return undefined;\n}\n\n/**\n * Resolved metadata for an argument field\n */\nexport interface ResolvedFieldMeta {\n /** Field name (camelCase, as defined in schema) */\n name: string;\n /** CLI option name (kebab-case, for command line usage) */\n cliName: string;\n /** Short alias (e.g., 'v' for --verbose) */\n alias?: string | undefined;\n /** Argument description */\n description?: string | undefined;\n /** Whether this is a positional argument */\n positional: boolean;\n /** Placeholder for help display */\n placeholder?: string | undefined;\n /**\n * Environment variable name(s) to read value from.\n * If an array, earlier entries take priority.\n */\n env?: string | string[] | undefined;\n /** Whether this argument is required */\n required: boolean;\n /** Default value if any */\n defaultValue?: unknown;\n /** Detected type from schema */\n type: \"string\" | \"number\" | \"boolean\" | \"array\" | \"unknown\";\n /** Original Zod schema */\n schema: z.ZodType;\n /** True if this overrides built-in aliases (-h, -H) */\n overrideBuiltinAlias?: true;\n /** Enum values if detected from schema (z.enum) */\n enumValues?: string[] | undefined;\n /** Completion metadata from arg() */\n completion?: CompletionMeta | undefined;\n}\n\n/**\n * Extracted fields from a schema\n */\nexport interface ExtractedFields {\n /** All field definitions */\n fields: ResolvedFieldMeta[];\n /** Original schema for validation */\n schema: ArgsSchema;\n /** Schema type */\n schemaType: \"object\" | \"discriminatedUnion\" | \"union\" | \"xor\" | \"intersection\";\n /** Discriminator key (for discriminatedUnion) */\n discriminator?: string;\n /** Variants (for discriminatedUnion) */\n variants?: Array<{\n discriminatorValue: string;\n fields: ResolvedFieldMeta[];\n description?: string;\n }>;\n /** Options (for union) */\n unionOptions?: ExtractedFields[];\n /** Schema description */\n description?: string;\n /**\n * Unknown keys handling mode\n * - \"strict\": Unknown keys cause validation errors (z.strictObject or z.object().strict())\n * - \"strip\": Unknown keys trigger warnings (default, z.object())\n * - \"passthrough\": Unknown keys are silently ignored (z.looseObject or z.object().passthrough())\n */\n unknownKeysMode: UnknownKeysMode;\n}\n\n/**\n * Unknown keys handling mode for object schemas\n * - \"strict\": Unknown keys cause validation errors\n * - \"strip\": Unknown keys are silently ignored (default)\n * - \"passthrough\": Unknown keys are passed through\n */\nexport type UnknownKeysMode = \"strict\" | \"strip\" | \"passthrough\";\n\n// Internal type for accessing zod v4 internals\ninterface ZodV4Def {\n type?: string;\n innerType?: z.ZodType;\n schema?: z.ZodType;\n defaultValue?: unknown;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n shape?: Record<string, any>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n options?: any[];\n discriminator?: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n left?: any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n right?: any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n catchall?: any;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype ZodSchemaWithDef = z.ZodType & { def?: ZodV4Def; _def?: ZodV4Def; type?: string; shape?: any };\n\n/**\n * Get the type name from a zod schema (v4 compatible)\n */\nfunction getTypeName(schema: z.ZodType): string | undefined {\n const s = schema as ZodSchemaWithDef;\n return s.def?.type ?? s._def?.type ?? s.type;\n}\n\n/**\n * Detect unknown keys handling mode from a Zod object schema\n *\n * In Zod v4:\n * - Default (strip): _def.catchall is undefined\n * - strict: _def.catchall is ZodNever (type = \"never\")\n * - passthrough: _def.catchall is ZodUnknown (type = \"unknown\")\n */\nexport function getUnknownKeysMode(schema: z.ZodType): UnknownKeysMode {\n const s = schema as ZodSchemaWithDef;\n const def = s.def ?? s._def;\n const catchall = def?.catchall;\n\n if (!catchall) {\n // Default behavior: strip unknown keys (but we want to warn)\n return \"strip\";\n }\n\n const catchallType = getTypeName(catchall);\n\n if (catchallType === \"never\") {\n // z.strictObject() or z.object().strict() - reject unknown keys\n return \"strict\";\n }\n\n if (catchallType === \"unknown\" || catchallType === \"any\") {\n // z.looseObject() or z.object().passthrough() - allow unknown keys\n return \"passthrough\";\n }\n\n // Unknown catchall type, default to strip behavior\n return \"strip\";\n}\n\n/**\n * Get the inner schema, unwrapping optional, nullable, default, etc.\n */\nfunction unwrapSchema(schema: z.ZodType): z.ZodType {\n const typeName = getTypeName(schema);\n const s = schema as ZodSchemaWithDef;\n const def = s.def ?? s._def;\n\n if (typeName === \"optional\" || typeName === \"nullable\" || typeName === \"default\") {\n const innerSchema = def?.innerType;\n if (innerSchema) {\n return unwrapSchema(innerSchema);\n }\n }\n\n // Handle effects (transform, refine, etc.)\n if (typeName === \"pipe\") {\n const innerSchema = def?.schema;\n if (innerSchema) {\n return unwrapSchema(innerSchema);\n }\n }\n\n return schema;\n}\n\n/**\n * Detect the base type of a schema\n */\nfunction detectType(schema: z.ZodType): \"string\" | \"number\" | \"boolean\" | \"array\" | \"unknown\" {\n const innerSchema = unwrapSchema(schema);\n const typeName = getTypeName(innerSchema);\n\n switch (typeName) {\n case \"string\":\n case \"enum\":\n return \"string\";\n case \"number\":\n case \"int\":\n return \"number\";\n case \"boolean\":\n return \"boolean\";\n case \"array\":\n return \"array\";\n default:\n return \"unknown\";\n }\n}\n\n/**\n * Extract enum values from a schema if it's an enum type\n *\n * @param schema - The Zod schema to extract enum values from\n * @returns Array of enum values if schema is an enum, undefined otherwise\n */\nexport function extractEnumValues(schema: z.ZodType): string[] | undefined {\n const innerSchema = unwrapSchema(schema);\n const typeName = getTypeName(innerSchema);\n const s = innerSchema as ZodSchemaWithDef;\n const def = s.def ?? s._def;\n\n if (typeName === \"enum\") {\n // Zod v4: enum values are in def.entries or def.values\n const entries = (def as { entries?: Record<string, string> })?.entries;\n if (entries && typeof entries === \"object\") {\n return Object.values(entries);\n }\n\n // Check for values array (some Zod versions)\n const values = (def as { values?: string[] })?.values;\n if (Array.isArray(values)) {\n return values;\n }\n\n // Fallback: check for options property on schema\n const options = (s as { options?: string[] }).options;\n if (Array.isArray(options)) {\n return options;\n }\n }\n\n // Handle array types: extract enum values from the element type\n if (typeName === \"array\") {\n const element = (def as { element?: z.ZodType })?.element;\n if (element) {\n return extractEnumValues(element);\n }\n }\n\n // Also handle literal union patterns (z.literal(\"a\").or(z.literal(\"b\")))\n if (typeName === \"union\") {\n const options = def?.options;\n if (Array.isArray(options)) {\n const literalValues: string[] = [];\n for (const option of options) {\n const optionTypeName = getTypeName(option);\n if (optionTypeName === \"literal\") {\n const optionDef = (option as ZodSchemaWithDef).def ?? (option as ZodSchemaWithDef)._def;\n const value = (optionDef as { value?: unknown; values?: unknown[] })?.value;\n const values = (optionDef as { value?: unknown; values?: unknown[] })?.values;\n const literalValue = value ?? values?.[0];\n if (typeof literalValue === \"string\") {\n literalValues.push(literalValue);\n }\n }\n }\n // Only return if all options are string literals\n if (literalValues.length === options.length && literalValues.length > 0) {\n return literalValues;\n }\n }\n }\n\n return undefined;\n}\n\n/**\n * Convert camelCase to kebab-case\n * @example toKebabCase(\"dryRun\") => \"dry-run\"\n * @example toKebabCase(\"outputDir\") => \"output-dir\"\n * @example toKebabCase(\"XMLParser\") => \"xml-parser\"\n */\nexport function toKebabCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, \"$1-$2\")\n .replace(/([A-Z]+)([A-Z][a-z])/g, \"$1-$2\")\n .toLowerCase();\n}\n\n/**\n * Check if a schema is required (not optional or has default)\n *\n * Note: We only check isOptional(), not isNullable(), because CLI arguments\n * are either present (string value) or absent (undefined), never null.\n * Also, some coerce types incorrectly report isNullable()=true.\n */\nfunction isRequired(schema: z.ZodType): boolean {\n return !schema.isOptional();\n}\n\n/**\n * Extract default value from schema if present\n */\nfunction extractDefaultValue(schema: z.ZodType): unknown {\n const typeName = getTypeName(schema);\n const s = schema as ZodSchemaWithDef;\n const def = s.def ?? s._def;\n\n if (typeName === \"default\") {\n const defaultValue = def?.defaultValue;\n // In zod v4, defaultValue can be a direct value or a function\n if (typeof defaultValue === \"function\") {\n return defaultValue();\n }\n return defaultValue;\n }\n\n // Check for nested default in optional/nullable\n if (typeName === \"optional\" || typeName === \"nullable\") {\n const innerSchema = def?.innerType;\n if (innerSchema) {\n return extractDefaultValue(innerSchema);\n }\n }\n\n return undefined;\n}\n\n/**\n * Extract description from schema\n */\nfunction extractDescription(schema: z.ZodType): string | undefined {\n // Check direct description\n if (schema.description) {\n return schema.description;\n }\n\n // Check inner schema for wrapped types\n const typeName = getTypeName(schema);\n const s = schema as ZodSchemaWithDef;\n const def = s.def ?? s._def;\n\n if (typeName === \"optional\" || typeName === \"nullable\" || typeName === \"default\") {\n const innerSchema = def?.innerType;\n if (innerSchema) {\n return extractDescription(innerSchema);\n }\n }\n\n return undefined;\n}\n\n/**\n * Resolve field metadata from schema and argRegistry\n */\nfunction resolveFieldMeta(name: string, schema: z.ZodType): ResolvedFieldMeta {\n // Get metadata from argRegistry\n const argMeta = getArgMeta(schema) ?? getArgMeta(unwrapSchema(schema));\n\n // Priority: argRegistry > schema.describe()\n const description = argMeta?.description ?? extractDescription(schema);\n\n // Convert camelCase field name to kebab-case for CLI usage\n const cliName = toKebabCase(name);\n\n // Extract enum values from schema\n const enumValues = extractEnumValues(schema);\n\n const meta: ResolvedFieldMeta = {\n name,\n cliName,\n alias: argMeta?.alias,\n description,\n positional: argMeta?.positional ?? false,\n placeholder: argMeta?.placeholder,\n env: argMeta?.env,\n required: isRequired(schema),\n defaultValue: extractDefaultValue(schema),\n type: detectType(schema),\n schema,\n enumValues,\n completion: argMeta?.completion,\n };\n\n // Add overrideBuiltinAlias only if it's true\n if (argMeta && \"overrideBuiltinAlias\" in argMeta && argMeta.overrideBuiltinAlias === true) {\n meta.overrideBuiltinAlias = true;\n }\n\n return meta;\n}\n\n/**\n * Get shape from a ZodObject\n */\nfunction getObjectShape(schema: z.ZodType): Record<string, z.ZodType> {\n const s = schema as ZodSchemaWithDef;\n const def = s.def ?? s._def;\n return def?.shape ?? s.shape ?? {};\n}\n\n/**\n * Extract fields from a ZodObject\n */\nfunction extractFromObject(schema: z.ZodType): ResolvedFieldMeta[] {\n const shape = getObjectShape(schema);\n return Object.entries(shape).map(([name, fieldSchema]) => resolveFieldMeta(name, fieldSchema));\n}\n\n/**\n * Extract fields from a discriminated union\n */\nfunction extractFromDiscriminatedUnion(schema: z.ZodType): ExtractedFields {\n const s = schema as ZodSchemaWithDef;\n const def = s.def ?? s._def;\n const discriminator = def?.discriminator ?? \"\";\n const options = def?.options ?? [];\n\n // Collect all unique fields across all variants\n const allFieldsMap = new Map<string, ResolvedFieldMeta>();\n const variants: ExtractedFields[\"variants\"] = [];\n\n for (const option of options) {\n const shape = getObjectShape(option as z.ZodObject<z.ZodRawShape>);\n const variantFields: ResolvedFieldMeta[] = [];\n\n // Get discriminator value\n let discriminatorValue = \"\";\n const discriminatorSchema = shape[discriminator];\n if (discriminatorSchema) {\n const typeName = getTypeName(discriminatorSchema);\n if (typeName === \"literal\") {\n const litDef =\n (discriminatorSchema as ZodSchemaWithDef).def ??\n (discriminatorSchema as ZodSchemaWithDef)._def;\n // In Zod v4, literal values are in _def.values array\n const value = (litDef as { value?: unknown; values?: unknown[] })?.value;\n const values = (litDef as { value?: unknown; values?: unknown[] })?.values;\n discriminatorValue = String(value ?? values?.[0] ?? \"\");\n }\n }\n\n for (const [name, fieldSchema] of Object.entries(shape)) {\n const fieldMeta = resolveFieldMeta(name, fieldSchema);\n variantFields.push(fieldMeta);\n\n // Add to all fields map (first occurrence wins for metadata)\n if (!allFieldsMap.has(name)) {\n allFieldsMap.set(name, fieldMeta);\n }\n }\n\n // Extract description from the variant option\n const variantDescription = extractDescription(option as z.ZodType);\n\n variants.push({\n discriminatorValue,\n fields: variantFields,\n ...(variantDescription ? { description: variantDescription } : {}),\n });\n }\n\n const description = extractDescription(schema);\n return {\n fields: Array.from(allFieldsMap.values()),\n schema: schema as ArgsSchema,\n schemaType: \"discriminatedUnion\",\n unknownKeysMode: getUnknownKeysMode(schema),\n discriminator,\n variants,\n ...(description ? { description } : {}),\n };\n}\n\n/**\n * Extract fields from a union-like schema (union or xor)\n */\nfunction extractFromUnionLike(schema: z.ZodType, schemaType: \"union\" | \"xor\"): ExtractedFields {\n const s = schema as ZodSchemaWithDef;\n const def = s.def ?? s._def;\n const options = def?.options ?? [];\n\n // Collect all unique fields across all options\n const allFieldsMap = new Map<string, ResolvedFieldMeta>();\n const unionOptions: ExtractedFields[] = [];\n\n for (const option of options) {\n // Extract fields for this option recursively\n // We cast to ArgsSchema because we expect options to be objects or other supported types\n const extracted = extractFields(option as ArgsSchema);\n unionOptions.push(extracted);\n\n // Add to combined fields map\n for (const field of extracted.fields) {\n if (!allFieldsMap.has(field.name)) {\n allFieldsMap.set(field.name, field);\n }\n }\n }\n\n const description = extractDescription(schema);\n return {\n fields: Array.from(allFieldsMap.values()),\n schema: schema as ArgsSchema,\n schemaType,\n unknownKeysMode: getUnknownKeysMode(schema),\n unionOptions,\n ...(description ? { description } : {}),\n };\n}\n\n/**\n * Extract fields from an intersection\n */\nfunction extractFromIntersection(schema: z.ZodType): ExtractedFields {\n const s = schema as ZodSchemaWithDef;\n const def = s.def ?? s._def;\n const left = def?.left;\n const right = def?.right;\n\n const allFieldsMap = new Map<string, ResolvedFieldMeta>();\n\n // Helper to extract fields from a sub-schema\n const extractSubFields = (subSchema: z.ZodType | undefined) => {\n if (!subSchema) return;\n\n const extracted = extractFields(subSchema as ArgsSchema);\n for (const field of extracted.fields) {\n if (!allFieldsMap.has(field.name)) {\n allFieldsMap.set(field.name, field);\n }\n }\n };\n\n extractSubFields(left);\n extractSubFields(right);\n\n const description = extractDescription(schema);\n return {\n fields: Array.from(allFieldsMap.values()),\n schema: schema as ArgsSchema,\n schemaType: \"intersection\",\n unknownKeysMode: getUnknownKeysMode(schema),\n ...(description ? { description } : {}),\n };\n}\n\n/**\n * Extract all fields from a schema\n *\n * @param schema - The args schema (ZodObject, ZodDiscriminatedUnion, etc.)\n * @returns Extracted field information\n */\nexport function extractFields(schema: ArgsSchema): ExtractedFields {\n const typeName = getTypeName(schema);\n const s = schema as ZodSchemaWithDef;\n const def = s.def ?? s._def;\n\n switch (typeName) {\n case \"object\": {\n const description = extractDescription(schema);\n return {\n fields: extractFromObject(schema),\n schema,\n schemaType: \"object\",\n unknownKeysMode: getUnknownKeysMode(schema),\n ...(description ? { description } : {}),\n };\n }\n\n case \"union\":\n // In Zod v4, discriminatedUnion has type \"union\" with a discriminator property\n if (def?.discriminator) {\n return extractFromDiscriminatedUnion(schema);\n }\n return extractFromUnionLike(schema, \"union\");\n\n case \"xor\":\n return extractFromUnionLike(schema, \"xor\");\n\n case \"intersection\":\n return extractFromIntersection(schema);\n\n default: {\n const description = extractDescription(schema);\n // Fallback: try to treat as object\n return {\n fields: [],\n schema,\n schemaType: \"object\",\n unknownKeysMode: getUnknownKeysMode(schema),\n ...(description ? { description } : {}),\n };\n }\n }\n}\n\n/**\n * Get extracted fields from a command\n *\n * @param command - The command to extract fields from\n * @returns Extracted field information, or null if command has no args schema\n */\nexport function getExtractedFields(command: AnyCommand): ExtractedFields | null {\n if (!command.args) {\n return null;\n }\n return extractFields(command.args);\n}\n","/**\n * Lazy-loaded subcommand with synchronous metadata\n */\n\nimport type { AnyCommand, SubCommandValue } from \"./types.js\";\n\n/**\n * Marker property for LazyCommand identification\n */\nconst LAZY_BRAND = \"__politty_lazy__\" as const;\n\n/**\n * A lazily-loaded command that carries synchronous metadata for\n * static analysis (completion, help) while deferring full module\n * loading to execution time.\n */\nexport interface LazyCommand<T extends AnyCommand = AnyCommand> {\n readonly __politty_lazy__: true;\n readonly meta: T;\n readonly load: () => Promise<AnyCommand>;\n}\n\n/**\n * Type guard: check if a value is a LazyCommand\n */\nexport function isLazyCommand(value: unknown): value is LazyCommand {\n return (\n typeof value === \"object\" && value !== null && LAZY_BRAND in value && value[LAZY_BRAND] === true\n );\n}\n\n/**\n * Create a lazily-loaded subcommand with synchronous metadata.\n *\n * The `meta` command provides names, descriptions, and args schema\n * for static analysis (completion scripts, help text) without loading\n * the full command module.\n *\n * The `load` function is called only at execution time.\n *\n * @example\n * ```ts\n * import { lazy, defineCommand } from \"politty\";\n *\n * const cli = defineCommand({\n * name: \"mycli\",\n * subCommands: {\n * deploy: lazy(\n * defineCommand({\n * name: \"deploy\",\n * description: \"Deploy the application\",\n * args: z.object({ env: arg(z.string()) }),\n * }),\n * () => import(\"./deploy.js\").then((m) => m.deployCommand),\n * ),\n * },\n * });\n * ```\n */\nexport function lazy<T extends AnyCommand>(\n meta: T,\n load: () => Promise<AnyCommand>,\n): LazyCommand<T> {\n return {\n [LAZY_BRAND]: true as const,\n meta,\n load,\n };\n}\n\n/**\n * Resolve synchronous metadata from a SubCommandValue.\n * Returns null for legacy async subcommands whose metadata is unavailable.\n */\nexport function resolveSubCommandMeta(subCmd: SubCommandValue): AnyCommand | null {\n if (isLazyCommand(subCmd)) return subCmd.meta;\n if (typeof subCmd === \"function\") return null;\n return subCmd;\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"lazy-BrEg8SgI.js","names":["getArgMeta","getArgMetaFromRegistry"],"sources":["../src/core/arg-registry.ts","../src/core/schema-extractor.ts","../src/lazy.ts"],"sourcesContent":["import { z } from \"zod\";\n\n/**\n * Built-in completion types\n */\nexport type CompletionType = \"file\" | \"directory\" | \"none\";\n\n/**\n * Custom completion specification\n */\nexport interface CustomCompletion {\n /** Static list of choices for completion */\n choices?: string[];\n /** Shell command to execute for dynamic completion */\n shellCommand?: string;\n}\n\n/**\n * Completion metadata for an argument\n *\n * @example\n * ```ts\n * // File completion with extension filter\n * input: arg(z.string(), {\n * completion: { type: \"file\", extensions: [\"json\", \"yaml\"] }\n * })\n *\n * // Directory completion\n * outputDir: arg(z.string(), {\n * completion: { type: \"directory\" }\n * })\n *\n * // Custom static choices\n * logLevel: arg(z.string(), {\n * completion: { custom: { choices: [\"debug\", \"info\", \"warn\", \"error\"] } }\n * })\n *\n * // Dynamic completion from shell command\n * branch: arg(z.string(), {\n * completion: { custom: { shellCommand: \"git branch --format='%(refname:short)'\" } }\n * })\n *\n * // File completion with glob pattern matcher\n * envFile: arg(z.string(), {\n * completion: { type: \"file\", matcher: [\".env.*\"] }\n * })\n * ```\n */\nexport type CompletionMeta = {\n /** Built-in completion type */\n type?: CompletionType;\n /** Custom completion (takes precedence over type if both specified) */\n custom?: CustomCompletion;\n} & (\n | {\n /** File extension filter (only applies when type is \"file\") */ extensions?: string[];\n matcher?: never;\n }\n | {\n /** Glob patterns for file matching (only applies when type is \"file\") */ matcher?: string[];\n extensions?: never;\n }\n);\n\n/**\n * Base metadata shared by all argument types\n */\nexport interface BaseArgMeta {\n /** Argument description */\n description?: string;\n /** Treat as positional argument */\n positional?: boolean;\n /** Placeholder for help display */\n placeholder?: string;\n /**\n * Environment variable name(s) to read value from.\n * If an array is provided, earlier entries take priority.\n * CLI arguments always take precedence over environment variables.\n *\n * @example\n * ```ts\n * // Single env var\n * port: arg(z.coerce.number(), { env: \"PORT\" })\n *\n * // Multiple env vars (PORT takes priority over SERVER_PORT)\n * port: arg(z.coerce.number(), { env: [\"PORT\", \"SERVER_PORT\"] })\n * ```\n */\n env?: string | string[];\n /** Completion configuration for shell tab-completion */\n completion?: CompletionMeta;\n}\n\n/**\n * Metadata for regular arguments (non-builtin aliases)\n */\nexport interface RegularArgMeta extends BaseArgMeta {\n /** Short alias (e.g., 'v' for --verbose) */\n alias?: string;\n}\n\n/**\n * Metadata for overriding built-in aliases (-h, -H)\n */\nexport interface BuiltinOverrideArgMeta extends BaseArgMeta {\n /** Built-in alias to override ('h' or 'H') */\n alias: \"h\" | \"H\";\n /** Must be true to override built-in aliases */\n overrideBuiltinAlias: true;\n}\n\n/**\n * Metadata options for argument definition\n */\nexport type ArgMeta = RegularArgMeta | BuiltinOverrideArgMeta;\n\n/**\n * Custom registry for politty argument metadata\n * This avoids polluting Zod's GlobalMeta\n */\nexport const argRegistry = z.registry<ArgMeta>();\n\n/**\n * Register metadata for a Zod schema\n *\n * @param schema - The Zod schema\n * @param meta - Argument metadata\n * @returns The same schema (for chaining)\n *\n * @example\n * ```ts\n * import { z } from \"zod\";\n * import { arg, defineCommand } from \"politty\";\n *\n * const cmd = defineCommand({\n * args: z.object({\n * name: arg(z.string(), { description: \"User name\", positional: true }),\n * verbose: arg(z.boolean().default(false), { alias: \"v\" }),\n * }),\n * run: (args) => {\n * console.log(args.name, args.verbose);\n * },\n * });\n * ```\n */\n/**\n * Type helper to validate ArgMeta\n * Forces a type error if alias is \"h\" or \"H\" without overrideBuiltinAlias: true\n */\ntype ValidateArgMeta<M> = M extends { alias: \"h\" | \"H\" }\n ? M extends { overrideBuiltinAlias: true }\n ? M\n : {\n [K in keyof M]: M[K];\n } & {\n __typeError: \"Alias 'h' or 'H' requires overrideBuiltinAlias: true\";\n }\n : M;\n\nexport function arg<T extends z.ZodType>(schema: T): T;\nexport function arg<T extends z.ZodType, M extends ArgMeta>(schema: T, meta: ValidateArgMeta<M>): T;\nexport function arg<T extends z.ZodType, M extends ArgMeta>(\n schema: T,\n meta?: ValidateArgMeta<M>,\n): T {\n if (meta) {\n argRegistry.add(schema, meta as ArgMeta);\n }\n return schema;\n}\n\n/**\n * Get metadata for a schema from the registry\n *\n * @param schema - The Zod schema\n * @returns The metadata if registered, undefined otherwise\n */\nexport function getArgMeta(schema: z.ZodType): ArgMeta | undefined {\n return argRegistry.get(schema);\n}\n","import { z } from \"zod\";\nimport type { AnyCommand, ArgsSchema } from \"../types.js\";\nimport {\n getArgMeta as getArgMetaFromRegistry,\n type ArgMeta,\n type CompletionMeta,\n} from \"./arg-registry.js\";\n\n/**\n * Get ArgMeta from both the custom registry and Zod's _def\n * Priority: custom registry > _def.argMeta\n */\nfunction getArgMeta(schema: z.ZodType): ArgMeta | undefined {\n // First check custom registry\n const fromRegistry = getArgMetaFromRegistry(schema);\n if (fromRegistry) return fromRegistry;\n // Check Zod native meta\n // Some Zod versions or extensions use a global registry accessed via .meta()\n if (typeof (schema as any).meta === \"function\") {\n const meta = (schema as any).meta();\n if (meta && typeof meta === \"object\") {\n return meta as ArgMeta;\n }\n }\n\n // Then check _def.argMeta (for augmented Zod types)\n const def = (schema as any)._def;\n if (def?.argMeta) return def.argMeta;\n\n // Also check _def.meta just in case\n if (def?.meta) return def.meta as ArgMeta;\n\n return undefined;\n}\n\n/**\n * Resolved metadata for an argument field\n */\nexport interface ResolvedFieldMeta {\n /** Field name (camelCase, as defined in schema) */\n name: string;\n /** CLI option name (kebab-case, for command line usage) */\n cliName: string;\n /** Short alias (e.g., 'v' for --verbose) */\n alias?: string | undefined;\n /** Argument description */\n description?: string | undefined;\n /** Whether this is a positional argument */\n positional: boolean;\n /** Placeholder for help display */\n placeholder?: string | undefined;\n /**\n * Environment variable name(s) to read value from.\n * If an array, earlier entries take priority.\n */\n env?: string | string[] | undefined;\n /** Whether this argument is required */\n required: boolean;\n /** Default value if any */\n defaultValue?: unknown;\n /** Detected type from schema */\n type: \"string\" | \"number\" | \"boolean\" | \"array\" | \"unknown\";\n /** Original Zod schema */\n schema: z.ZodType;\n /** True if this overrides built-in aliases (-h, -H) */\n overrideBuiltinAlias?: true;\n /** Enum values if detected from schema (z.enum) */\n enumValues?: string[] | undefined;\n /** Completion metadata from arg() */\n completion?: CompletionMeta | undefined;\n}\n\n/**\n * Extracted fields from a schema\n */\nexport interface ExtractedFields {\n /** All field definitions */\n fields: ResolvedFieldMeta[];\n /** Original schema for validation */\n schema: ArgsSchema;\n /** Schema type */\n schemaType: \"object\" | \"discriminatedUnion\" | \"union\" | \"xor\" | \"intersection\";\n /** Discriminator key (for discriminatedUnion) */\n discriminator?: string;\n /** Variants (for discriminatedUnion) */\n variants?: Array<{\n discriminatorValue: string;\n fields: ResolvedFieldMeta[];\n description?: string;\n }>;\n /** Options (for union) */\n unionOptions?: ExtractedFields[];\n /** Schema description */\n description?: string;\n /**\n * Unknown keys handling mode\n * - \"strict\": Unknown keys cause validation errors (z.strictObject or z.object().strict())\n * - \"strip\": Unknown keys trigger warnings (default, z.object())\n * - \"passthrough\": Unknown keys are silently ignored (z.looseObject or z.object().passthrough())\n */\n unknownKeysMode: UnknownKeysMode;\n}\n\n/**\n * Unknown keys handling mode for object schemas\n * - \"strict\": Unknown keys cause validation errors\n * - \"strip\": Unknown keys are silently ignored (default)\n * - \"passthrough\": Unknown keys are passed through\n */\nexport type UnknownKeysMode = \"strict\" | \"strip\" | \"passthrough\";\n\n// Internal type for accessing zod v4 internals\ninterface ZodV4Def {\n type?: string;\n innerType?: z.ZodType;\n schema?: z.ZodType;\n defaultValue?: unknown;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n shape?: Record<string, any>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n options?: any[];\n discriminator?: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n left?: any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n right?: any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n catchall?: any;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype ZodSchemaWithDef = z.ZodType & { def?: ZodV4Def; _def?: ZodV4Def; type?: string; shape?: any };\n\n/**\n * Get the type name from a zod schema (v4 compatible)\n */\nfunction getTypeName(schema: z.ZodType): string | undefined {\n const s = schema as ZodSchemaWithDef;\n return s.def?.type ?? s._def?.type ?? s.type;\n}\n\n/**\n * Detect unknown keys handling mode from a Zod object schema\n *\n * In Zod v4:\n * - Default (strip): _def.catchall is undefined\n * - strict: _def.catchall is ZodNever (type = \"never\")\n * - passthrough: _def.catchall is ZodUnknown (type = \"unknown\")\n */\nexport function getUnknownKeysMode(schema: z.ZodType): UnknownKeysMode {\n const s = schema as ZodSchemaWithDef;\n const def = s.def ?? s._def;\n const catchall = def?.catchall;\n\n if (!catchall) {\n // Default behavior: strip unknown keys (but we want to warn)\n return \"strip\";\n }\n\n const catchallType = getTypeName(catchall);\n\n if (catchallType === \"never\") {\n // z.strictObject() or z.object().strict() - reject unknown keys\n return \"strict\";\n }\n\n if (catchallType === \"unknown\" || catchallType === \"any\") {\n // z.looseObject() or z.object().passthrough() - allow unknown keys\n return \"passthrough\";\n }\n\n // Unknown catchall type, default to strip behavior\n return \"strip\";\n}\n\n/**\n * Get the inner schema, unwrapping optional, nullable, default, etc.\n */\nfunction unwrapSchema(schema: z.ZodType): z.ZodType {\n const typeName = getTypeName(schema);\n const s = schema as ZodSchemaWithDef;\n const def = s.def ?? s._def;\n\n if (typeName === \"optional\" || typeName === \"nullable\" || typeName === \"default\") {\n const innerSchema = def?.innerType;\n if (innerSchema) {\n return unwrapSchema(innerSchema);\n }\n }\n\n // Handle effects (transform, refine, etc.)\n if (typeName === \"pipe\") {\n const innerSchema = def?.schema;\n if (innerSchema) {\n return unwrapSchema(innerSchema);\n }\n }\n\n return schema;\n}\n\n/**\n * Detect the base type of a schema\n */\nfunction detectType(schema: z.ZodType): \"string\" | \"number\" | \"boolean\" | \"array\" | \"unknown\" {\n const innerSchema = unwrapSchema(schema);\n const typeName = getTypeName(innerSchema);\n\n switch (typeName) {\n case \"string\":\n case \"enum\":\n return \"string\";\n case \"number\":\n case \"int\":\n return \"number\";\n case \"boolean\":\n return \"boolean\";\n case \"array\":\n return \"array\";\n default:\n return \"unknown\";\n }\n}\n\n/**\n * Extract enum values from a schema if it's an enum type\n *\n * @param schema - The Zod schema to extract enum values from\n * @returns Array of enum values if schema is an enum, undefined otherwise\n */\nexport function extractEnumValues(schema: z.ZodType): string[] | undefined {\n const innerSchema = unwrapSchema(schema);\n const typeName = getTypeName(innerSchema);\n const s = innerSchema as ZodSchemaWithDef;\n const def = s.def ?? s._def;\n\n if (typeName === \"enum\") {\n // Zod v4: enum values are in def.entries or def.values\n const entries = (def as { entries?: Record<string, string> })?.entries;\n if (entries && typeof entries === \"object\") {\n return Object.values(entries);\n }\n\n // Check for values array (some Zod versions)\n const values = (def as { values?: string[] })?.values;\n if (Array.isArray(values)) {\n return values;\n }\n\n // Fallback: check for options property on schema\n const options = (s as { options?: string[] }).options;\n if (Array.isArray(options)) {\n return options;\n }\n }\n\n // Handle array types: extract enum values from the element type\n if (typeName === \"array\") {\n const element = (def as { element?: z.ZodType })?.element;\n if (element) {\n return extractEnumValues(element);\n }\n }\n\n // Also handle literal union patterns (z.literal(\"a\").or(z.literal(\"b\")))\n if (typeName === \"union\") {\n const options = def?.options;\n if (Array.isArray(options)) {\n const literalValues: string[] = [];\n for (const option of options) {\n const optionTypeName = getTypeName(option);\n if (optionTypeName === \"literal\") {\n const optionDef = (option as ZodSchemaWithDef).def ?? (option as ZodSchemaWithDef)._def;\n const value = (optionDef as { value?: unknown; values?: unknown[] })?.value;\n const values = (optionDef as { value?: unknown; values?: unknown[] })?.values;\n const literalValue = value ?? values?.[0];\n if (typeof literalValue === \"string\") {\n literalValues.push(literalValue);\n }\n }\n }\n // Only return if all options are string literals\n if (literalValues.length === options.length && literalValues.length > 0) {\n return literalValues;\n }\n }\n }\n\n return undefined;\n}\n\n/**\n * Convert camelCase to kebab-case\n * @example toKebabCase(\"dryRun\") => \"dry-run\"\n * @example toKebabCase(\"outputDir\") => \"output-dir\"\n * @example toKebabCase(\"XMLParser\") => \"xml-parser\"\n */\nexport function toKebabCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, \"$1-$2\")\n .replace(/([A-Z]+)([A-Z][a-z])/g, \"$1-$2\")\n .toLowerCase();\n}\n\n/**\n * Check if a schema is required (not optional or has default)\n *\n * Note: We only check isOptional(), not isNullable(), because CLI arguments\n * are either present (string value) or absent (undefined), never null.\n * Also, some coerce types incorrectly report isNullable()=true.\n */\nfunction isRequired(schema: z.ZodType): boolean {\n return !schema.isOptional();\n}\n\n/**\n * Extract default value from schema if present\n */\nfunction extractDefaultValue(schema: z.ZodType): unknown {\n const typeName = getTypeName(schema);\n const s = schema as ZodSchemaWithDef;\n const def = s.def ?? s._def;\n\n if (typeName === \"default\") {\n const defaultValue = def?.defaultValue;\n // In zod v4, defaultValue can be a direct value or a function\n if (typeof defaultValue === \"function\") {\n return defaultValue();\n }\n return defaultValue;\n }\n\n // Check for nested default in optional/nullable\n if (typeName === \"optional\" || typeName === \"nullable\") {\n const innerSchema = def?.innerType;\n if (innerSchema) {\n return extractDefaultValue(innerSchema);\n }\n }\n\n return undefined;\n}\n\n/**\n * Extract description from schema\n */\nfunction extractDescription(schema: z.ZodType): string | undefined {\n // Check direct description\n if (schema.description) {\n return schema.description;\n }\n\n // Check inner schema for wrapped types\n const typeName = getTypeName(schema);\n const s = schema as ZodSchemaWithDef;\n const def = s.def ?? s._def;\n\n if (typeName === \"optional\" || typeName === \"nullable\" || typeName === \"default\") {\n const innerSchema = def?.innerType;\n if (innerSchema) {\n return extractDescription(innerSchema);\n }\n }\n\n return undefined;\n}\n\n/**\n * Resolve field metadata from schema and argRegistry\n */\nfunction resolveFieldMeta(name: string, schema: z.ZodType): ResolvedFieldMeta {\n // Get metadata from argRegistry\n const argMeta = getArgMeta(schema) ?? getArgMeta(unwrapSchema(schema));\n\n // Priority: argRegistry > schema.describe()\n const description = argMeta?.description ?? extractDescription(schema);\n\n // Convert camelCase field name to kebab-case for CLI usage\n const cliName = toKebabCase(name);\n\n // Extract enum values from schema\n const enumValues = extractEnumValues(schema);\n\n const meta: ResolvedFieldMeta = {\n name,\n cliName,\n alias: argMeta?.alias,\n description,\n positional: argMeta?.positional ?? false,\n placeholder: argMeta?.placeholder,\n env: argMeta?.env,\n required: isRequired(schema),\n defaultValue: extractDefaultValue(schema),\n type: detectType(schema),\n schema,\n enumValues,\n completion: argMeta?.completion,\n };\n\n // Add overrideBuiltinAlias only if it's true\n if (argMeta && \"overrideBuiltinAlias\" in argMeta && argMeta.overrideBuiltinAlias === true) {\n meta.overrideBuiltinAlias = true;\n }\n\n return meta;\n}\n\n/**\n * Get shape from a ZodObject\n */\nfunction getObjectShape(schema: z.ZodType): Record<string, z.ZodType> {\n const s = schema as ZodSchemaWithDef;\n const def = s.def ?? s._def;\n return def?.shape ?? s.shape ?? {};\n}\n\n/**\n * Extract fields from a ZodObject\n */\nfunction extractFromObject(schema: z.ZodType): ResolvedFieldMeta[] {\n const shape = getObjectShape(schema);\n return Object.entries(shape).map(([name, fieldSchema]) => resolveFieldMeta(name, fieldSchema));\n}\n\n/**\n * Extract fields from a discriminated union\n */\nfunction extractFromDiscriminatedUnion(schema: z.ZodType): ExtractedFields {\n const s = schema as ZodSchemaWithDef;\n const def = s.def ?? s._def;\n const discriminator = def?.discriminator ?? \"\";\n const options = def?.options ?? [];\n\n // Collect all unique fields across all variants\n const allFieldsMap = new Map<string, ResolvedFieldMeta>();\n const variants: ExtractedFields[\"variants\"] = [];\n\n for (const option of options) {\n const shape = getObjectShape(option as z.ZodObject<z.ZodRawShape>);\n const variantFields: ResolvedFieldMeta[] = [];\n\n // Get discriminator value\n let discriminatorValue = \"\";\n const discriminatorSchema = shape[discriminator];\n if (discriminatorSchema) {\n const typeName = getTypeName(discriminatorSchema);\n if (typeName === \"literal\") {\n const litDef =\n (discriminatorSchema as ZodSchemaWithDef).def ??\n (discriminatorSchema as ZodSchemaWithDef)._def;\n // In Zod v4, literal values are in _def.values array\n const value = (litDef as { value?: unknown; values?: unknown[] })?.value;\n const values = (litDef as { value?: unknown; values?: unknown[] })?.values;\n discriminatorValue = String(value ?? values?.[0] ?? \"\");\n }\n }\n\n for (const [name, fieldSchema] of Object.entries(shape)) {\n const fieldMeta = resolveFieldMeta(name, fieldSchema);\n variantFields.push(fieldMeta);\n\n // Add to all fields map (first occurrence wins for metadata)\n if (!allFieldsMap.has(name)) {\n allFieldsMap.set(name, fieldMeta);\n }\n }\n\n // Extract description from the variant option\n const variantDescription = extractDescription(option as z.ZodType);\n\n variants.push({\n discriminatorValue,\n fields: variantFields,\n ...(variantDescription ? { description: variantDescription } : {}),\n });\n }\n\n const description = extractDescription(schema);\n return {\n fields: Array.from(allFieldsMap.values()),\n schema: schema as ArgsSchema,\n schemaType: \"discriminatedUnion\",\n unknownKeysMode: getUnknownKeysMode(schema),\n discriminator,\n variants,\n ...(description ? { description } : {}),\n };\n}\n\n/**\n * Extract fields from a union-like schema (union or xor)\n */\nfunction extractFromUnionLike(schema: z.ZodType, schemaType: \"union\" | \"xor\"): ExtractedFields {\n const s = schema as ZodSchemaWithDef;\n const def = s.def ?? s._def;\n const options = def?.options ?? [];\n\n // Collect all unique fields across all options\n const allFieldsMap = new Map<string, ResolvedFieldMeta>();\n const unionOptions: ExtractedFields[] = [];\n\n for (const option of options) {\n // Extract fields for this option recursively\n // We cast to ArgsSchema because we expect options to be objects or other supported types\n const extracted = extractFields(option as ArgsSchema);\n unionOptions.push(extracted);\n\n // Add to combined fields map\n for (const field of extracted.fields) {\n if (!allFieldsMap.has(field.name)) {\n allFieldsMap.set(field.name, field);\n }\n }\n }\n\n const description = extractDescription(schema);\n return {\n fields: Array.from(allFieldsMap.values()),\n schema: schema as ArgsSchema,\n schemaType,\n unknownKeysMode: getUnknownKeysMode(schema),\n unionOptions,\n ...(description ? { description } : {}),\n };\n}\n\n/**\n * Extract fields from an intersection\n */\nfunction extractFromIntersection(schema: z.ZodType): ExtractedFields {\n const s = schema as ZodSchemaWithDef;\n const def = s.def ?? s._def;\n const left = def?.left;\n const right = def?.right;\n\n const allFieldsMap = new Map<string, ResolvedFieldMeta>();\n\n // Helper to extract fields from a sub-schema\n const extractSubFields = (subSchema: z.ZodType | undefined) => {\n if (!subSchema) return;\n\n const extracted = extractFields(subSchema as ArgsSchema);\n for (const field of extracted.fields) {\n if (!allFieldsMap.has(field.name)) {\n allFieldsMap.set(field.name, field);\n }\n }\n };\n\n extractSubFields(left);\n extractSubFields(right);\n\n const description = extractDescription(schema);\n return {\n fields: Array.from(allFieldsMap.values()),\n schema: schema as ArgsSchema,\n schemaType: \"intersection\",\n unknownKeysMode: getUnknownKeysMode(schema),\n ...(description ? { description } : {}),\n };\n}\n\n/**\n * Extract all fields from a schema\n *\n * @param schema - The args schema (ZodObject, ZodDiscriminatedUnion, etc.)\n * @returns Extracted field information\n */\nexport function extractFields(schema: ArgsSchema): ExtractedFields {\n const typeName = getTypeName(schema);\n const s = schema as ZodSchemaWithDef;\n const def = s.def ?? s._def;\n\n switch (typeName) {\n case \"object\": {\n const description = extractDescription(schema);\n return {\n fields: extractFromObject(schema),\n schema,\n schemaType: \"object\",\n unknownKeysMode: getUnknownKeysMode(schema),\n ...(description ? { description } : {}),\n };\n }\n\n case \"union\":\n // In Zod v4, discriminatedUnion has type \"union\" with a discriminator property\n if (def?.discriminator) {\n return extractFromDiscriminatedUnion(schema);\n }\n return extractFromUnionLike(schema, \"union\");\n\n case \"xor\":\n return extractFromUnionLike(schema, \"xor\");\n\n case \"intersection\":\n return extractFromIntersection(schema);\n\n default: {\n const description = extractDescription(schema);\n // Fallback: try to treat as object\n return {\n fields: [],\n schema,\n schemaType: \"object\",\n unknownKeysMode: getUnknownKeysMode(schema),\n ...(description ? { description } : {}),\n };\n }\n }\n}\n\n/**\n * Get extracted fields from a command\n *\n * @param command - The command to extract fields from\n * @returns Extracted field information, or null if command has no args schema\n */\nexport function getExtractedFields(command: AnyCommand): ExtractedFields | null {\n if (!command.args) {\n return null;\n }\n return extractFields(command.args);\n}\n","/**\n * Lazy-loaded subcommand with synchronous metadata\n */\n\nimport type { AnyCommand, SubCommandValue } from \"./types.js\";\n\n/**\n * Marker property for LazyCommand identification\n */\nconst LAZY_BRAND = \"__politty_lazy__\" as const;\n\n/**\n * A lazily-loaded command that carries synchronous metadata for\n * static analysis (completion, help) while deferring full module\n * loading to execution time.\n */\nexport interface LazyCommand<T extends AnyCommand = AnyCommand> {\n readonly __politty_lazy__: true;\n readonly meta: T;\n readonly load: () => Promise<AnyCommand>;\n}\n\n/**\n * Type guard: check if a value is a LazyCommand\n */\nexport function isLazyCommand(value: unknown): value is LazyCommand {\n return (\n typeof value === \"object\" && value !== null && LAZY_BRAND in value && value[LAZY_BRAND] === true\n );\n}\n\n/**\n * Create a lazily-loaded subcommand with synchronous metadata.\n *\n * The `meta` command provides names, descriptions, and args schema\n * for static analysis (completion scripts, help text) without loading\n * the full command module.\n *\n * The `load` function is called only at execution time.\n *\n * @example\n * ```ts\n * import { lazy, defineCommand } from \"politty\";\n *\n * const cli = defineCommand({\n * name: \"mycli\",\n * subCommands: {\n * deploy: lazy(\n * defineCommand({\n * name: \"deploy\",\n * description: \"Deploy the application\",\n * args: z.object({ env: arg(z.string()) }),\n * }),\n * () => import(\"./deploy.js\").then((m) => m.deployCommand),\n * ),\n * },\n * });\n * ```\n */\nexport function lazy<T extends AnyCommand>(\n meta: T,\n load: () => Promise<AnyCommand>,\n): LazyCommand<T> {\n return {\n [LAZY_BRAND]: true as const,\n meta,\n load,\n };\n}\n\n/**\n * Resolve synchronous metadata from a SubCommandValue.\n * Returns null for legacy async subcommands whose metadata is unavailable.\n */\nexport function resolveSubCommandMeta(subCmd: SubCommandValue): AnyCommand | null {\n if (isLazyCommand(subCmd)) return subCmd.meta;\n if (typeof subCmd === \"function\") return null;\n return subCmd;\n}\n"],"mappings":"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"}