politty 0.4.11 → 0.4.13

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 (86) hide show
  1. package/README.md +11 -8
  2. package/dist/{arg-registry-BDybpyo5.d.cts → arg-registry-6E4C5MTC.d.ts} +188 -2
  3. package/dist/arg-registry-6E4C5MTC.d.ts.map +1 -0
  4. package/dist/{arg-registry-CHmAzJOM.d.ts → arg-registry-CeIRoLaB.d.cts} +188 -2
  5. package/dist/arg-registry-CeIRoLaB.d.cts.map +1 -0
  6. package/dist/augment.d.cts +1 -1
  7. package/dist/augment.d.ts +1 -1
  8. package/dist/completion/index.cjs +1 -2
  9. package/dist/completion/index.d.cts +1 -1
  10. package/dist/completion/index.d.ts +1 -1
  11. package/dist/completion/index.js +1 -2
  12. package/dist/{completion-BADAzqT9.cjs → completion-D3LUac1o.cjs} +3 -3
  13. package/dist/completion-D3LUac1o.cjs.map +1 -0
  14. package/dist/{completion-Dj7ytbLu.js → completion-DzaT2YCN.js} +2 -2
  15. package/dist/completion-DzaT2YCN.js.map +1 -0
  16. package/dist/docs/index.cjs +89 -14
  17. package/dist/docs/index.cjs.map +1 -1
  18. package/dist/docs/index.d.cts +8 -3
  19. package/dist/docs/index.d.cts.map +1 -1
  20. package/dist/docs/index.d.ts +8 -3
  21. package/dist/docs/index.d.ts.map +1 -1
  22. package/dist/docs/index.js +89 -15
  23. package/dist/docs/index.js.map +1 -1
  24. package/dist/{index-DcwMaTvt.d.ts → index-BW02tH1-.d.cts} +2 -3
  25. package/dist/index-BW02tH1-.d.cts.map +1 -0
  26. package/dist/{index-DjU9BErU.d.cts → index-C3UtsvgY.d.ts} +2 -3
  27. package/dist/index-C3UtsvgY.d.ts.map +1 -0
  28. package/dist/index.cjs +3 -3
  29. package/dist/index.d.cts +3 -4
  30. package/dist/index.d.cts.map +1 -1
  31. package/dist/index.d.ts +3 -4
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +3 -3
  34. package/dist/{lazy-B_E2X0KR.cjs → lazy-qPy4cMnv.cjs} +8 -3
  35. package/dist/lazy-qPy4cMnv.cjs.map +1 -0
  36. package/dist/{lazy-D6nL_iKJ.js → lazy-xrzxwnru.js} +7 -2
  37. package/dist/lazy-xrzxwnru.js.map +1 -0
  38. package/dist/prompt/clack/index.cjs +34 -0
  39. package/dist/prompt/clack/index.cjs.map +1 -0
  40. package/dist/prompt/clack/index.d.cts +18 -0
  41. package/dist/prompt/clack/index.d.cts.map +1 -0
  42. package/dist/prompt/clack/index.d.ts +18 -0
  43. package/dist/prompt/clack/index.d.ts.map +1 -0
  44. package/dist/prompt/clack/index.js +32 -0
  45. package/dist/prompt/clack/index.js.map +1 -0
  46. package/dist/prompt/index.cjs +7 -0
  47. package/dist/prompt/index.d.cts +108 -0
  48. package/dist/prompt/index.d.cts.map +1 -0
  49. package/dist/prompt/index.d.ts +108 -0
  50. package/dist/prompt/index.d.ts.map +1 -0
  51. package/dist/prompt/index.js +3 -0
  52. package/dist/prompt/inquirer/index.cjs +49 -0
  53. package/dist/prompt/inquirer/index.cjs.map +1 -0
  54. package/dist/prompt/inquirer/index.d.cts +18 -0
  55. package/dist/prompt/inquirer/index.d.cts.map +1 -0
  56. package/dist/prompt/inquirer/index.d.ts +18 -0
  57. package/dist/prompt/inquirer/index.d.ts.map +1 -0
  58. package/dist/prompt/inquirer/index.js +47 -0
  59. package/dist/prompt/inquirer/index.js.map +1 -0
  60. package/dist/prompt-BKHqGrFw.js +172 -0
  61. package/dist/prompt-BKHqGrFw.js.map +1 -0
  62. package/dist/prompt-aXfSf27y.cjs +196 -0
  63. package/dist/prompt-aXfSf27y.cjs.map +1 -0
  64. package/dist/{runner-JZRo4pYu.js → runner-CnG-Ncz0.js} +33 -70
  65. package/dist/runner-CnG-Ncz0.js.map +1 -0
  66. package/dist/{runner-BgW1XWJw.cjs → runner-DA48D-3K.cjs} +33 -70
  67. package/dist/runner-DA48D-3K.cjs.map +1 -0
  68. package/dist/{subcommand-router-Bu3YTw_f.js → subcommand-router-BhYVuS83.js} +2 -2
  69. package/dist/{subcommand-router-Bu3YTw_f.js.map → subcommand-router-BhYVuS83.js.map} +1 -1
  70. package/dist/{subcommand-router-BTOzDQnY.cjs → subcommand-router-BnHpqyRk.cjs} +2 -2
  71. package/dist/{subcommand-router-BTOzDQnY.cjs.map → subcommand-router-BnHpqyRk.cjs.map} +1 -1
  72. package/package.json +51 -9
  73. package/dist/arg-registry-BDybpyo5.d.cts.map +0 -1
  74. package/dist/arg-registry-CHmAzJOM.d.ts.map +0 -1
  75. package/dist/completion-BADAzqT9.cjs.map +0 -1
  76. package/dist/completion-Dj7ytbLu.js.map +0 -1
  77. package/dist/index-DcwMaTvt.d.ts.map +0 -1
  78. package/dist/index-DjU9BErU.d.cts.map +0 -1
  79. package/dist/lazy-B_E2X0KR.cjs.map +0 -1
  80. package/dist/lazy-D6nL_iKJ.js.map +0 -1
  81. package/dist/runner-BgW1XWJw.cjs.map +0 -1
  82. package/dist/runner-JZRo4pYu.js.map +0 -1
  83. package/dist/schema-extractor-D1sJW-sc.d.ts +0 -117
  84. package/dist/schema-extractor-D1sJW-sc.d.ts.map +0 -1
  85. package/dist/schema-extractor-RainqdRn.d.cts +0 -117
  86. package/dist/schema-extractor-RainqdRn.d.cts.map +0 -1
@@ -0,0 +1,196 @@
1
+
2
+ //#region src/prompt/prompt-resolver.ts
3
+ /**
4
+ * Resolve prompt configuration for a field.
5
+ *
6
+ * Priority for prompt type:
7
+ * 1. Explicit type from prompt.type
8
+ * 2. Explicit choices from prompt.choices (forces "select")
9
+ * 3. Inherited from completion metadata (file/directory -> "text")
10
+ * 4. Auto-detected from Zod schema type:
11
+ * - enum (has enumValues) -> "select"
12
+ * - boolean -> "confirm"
13
+ * - string/number/unknown -> "text"
14
+ *
15
+ * Returns null if the field has no prompt metadata or prompting is disabled.
16
+ */
17
+ function resolvePromptConfig(field) {
18
+ const promptMeta = field.prompt;
19
+ if (!promptMeta || promptMeta.enabled === false) return null;
20
+ const message = promptMeta.message ?? field.description ?? field.name;
21
+ const rawType = resolvePromptType(field, promptMeta);
22
+ const choices = resolveChoices(field, promptMeta, rawType);
23
+ return {
24
+ field,
25
+ type: rawType === "select" && !choices ? "text" : rawType,
26
+ message,
27
+ ...choices && { choices }
28
+ };
29
+ }
30
+ function hasChoices(list) {
31
+ return list !== void 0 && list.length > 0;
32
+ }
33
+ function resolvePromptType(field, promptMeta) {
34
+ if (promptMeta.type) return promptMeta.type === "file" || promptMeta.type === "directory" ? "text" : promptMeta.type;
35
+ if (hasChoices(promptMeta.choices)) return "select";
36
+ if (field.completion?.type === "file" || field.completion?.type === "directory") return "text";
37
+ if (hasChoices(field.enumValues)) return "select";
38
+ if (field.type === "boolean") return "confirm";
39
+ return "text";
40
+ }
41
+ function resolveChoices(field, promptMeta, type) {
42
+ if (hasChoices(promptMeta.choices)) return promptMeta.choices.map((c) => typeof c === "string" ? {
43
+ label: c,
44
+ value: c
45
+ } : c);
46
+ if (type === "select" && hasChoices(field.enumValues)) return field.enumValues.map((v) => ({
47
+ label: v,
48
+ value: v
49
+ }));
50
+ }
51
+ /**
52
+ * Filter fields that need prompting (missing value + prompt configured).
53
+ *
54
+ * For discriminatedUnion schemas, variant-aware narrowing is handled by the
55
+ * caller (promptMissingArgs) which prompts the discriminator first and then
56
+ * passes only the active variant's fields. For plain union schemas, this
57
+ * iterates all fields across every variant without narrowing.
58
+ *
59
+ * Fields with Zod defaults that also have prompt metadata will be prompted
60
+ * when the raw value is undefined. This is intentional: `prompt: {}` is an
61
+ * explicit opt-in to interactive input. Omit prompt metadata to let the
62
+ * default apply silently.
63
+ */
64
+ function getFieldsToPrompt(fields, rawArgs) {
65
+ const configs = [];
66
+ for (const field of fields) {
67
+ if (rawArgs[field.name] !== void 0) continue;
68
+ if (field.type === "array") continue;
69
+ const config = resolvePromptConfig(field);
70
+ if (config) configs.push(config);
71
+ }
72
+ return configs;
73
+ }
74
+
75
+ //#endregion
76
+ //#region src/prompt/tty-detector.ts
77
+ /**
78
+ * Detect whether the current environment supports interactive prompts.
79
+ * Returns false in CI, piped input, or non-TTY environments.
80
+ */
81
+ function isInteractive() {
82
+ if (!process.stdin.isTTY) return false;
83
+ if (!process.stdout.isTTY) return false;
84
+ if (process.env.CI) return false;
85
+ if (process.env.POLITTY_NO_PROMPT) return false;
86
+ return true;
87
+ }
88
+
89
+ //#endregion
90
+ //#region src/prompt/index.ts
91
+ /**
92
+ * Prompt for missing argument values interactively.
93
+ *
94
+ * Only prompts for fields that have `prompt` metadata set via `arg()` and
95
+ * whose values are still undefined after CLI and env resolution.
96
+ * Returns rawArgs unchanged in non-interactive environments.
97
+ */
98
+ async function promptMissingArgs(rawArgs, extracted, options) {
99
+ if (!(options.interactive ?? isInteractive())) return rawArgs;
100
+ const adapter = options.adapter;
101
+ const result = { ...rawArgs };
102
+ if (extracted.schemaType === "discriminatedUnion" && extracted.discriminator && extracted.variants) await promptDiscriminatedUnion(adapter, result, extracted);
103
+ else if (extracted.schemaType === "union" || extracted.schemaType === "xor") {} else await promptAllFields(adapter, result, extracted.fields);
104
+ return result;
105
+ }
106
+ async function promptDiscriminatedUnion(adapter, result, extracted) {
107
+ const { discriminator, variants } = extracted;
108
+ if (!discriminator || !variants) return;
109
+ if (result[discriminator] === void 0) {
110
+ const discField = findDiscriminatorField(extracted.fields, variants, discriminator);
111
+ const discConfig = discField ? resolvePromptConfig(discField) : null;
112
+ if (discConfig) {
113
+ const allValues = variants.map((v) => v.discriminatorValue).filter(Boolean);
114
+ if (allValues.length > 0) {
115
+ discConfig.type = "select";
116
+ discConfig.choices = allValues.map((v) => ({
117
+ label: v,
118
+ value: v
119
+ }));
120
+ }
121
+ await promptAndCollect(adapter, result, discConfig);
122
+ }
123
+ }
124
+ const discValue = String(result[discriminator] ?? "");
125
+ const activeVariant = variants.find((v) => v.discriminatorValue === discValue);
126
+ if (activeVariant) await promptAllFields(adapter, result, activeVariant.fields.filter((f) => f.name !== discriminator));
127
+ }
128
+ /**
129
+ * Find the discriminator field with prompt metadata, checking the
130
+ * deduplicated top-level fields first, then scanning per-variant fields.
131
+ */
132
+ function findDiscriminatorField(fields, variants, discriminator) {
133
+ const topLevel = fields.find((f) => f.name === discriminator);
134
+ if (topLevel?.prompt) return topLevel;
135
+ for (const variant of variants) {
136
+ const field = variant.fields.find((f) => f.name === discriminator);
137
+ if (field?.prompt) return field;
138
+ }
139
+ }
140
+ async function promptAllFields(adapter, result, fields) {
141
+ const fieldsToPrompt = getFieldsToPrompt(fields, result);
142
+ for (const config of fieldsToPrompt) await promptAndCollect(adapter, result, config);
143
+ }
144
+ async function promptAndCollect(adapter, result, config) {
145
+ const { message } = config;
146
+ let value;
147
+ switch (config.type) {
148
+ case "text":
149
+ value = await adapter.text({
150
+ message,
151
+ placeholder: config.field.placeholder
152
+ });
153
+ break;
154
+ case "password":
155
+ value = await adapter.password({ message });
156
+ break;
157
+ case "confirm":
158
+ value = await adapter.confirm({ message });
159
+ break;
160
+ case "select":
161
+ value = await adapter.select({
162
+ message,
163
+ options: config.choices ?? []
164
+ });
165
+ break;
166
+ }
167
+ if (adapter.isCancelled(value)) throw new Error("Prompt cancelled by user");
168
+ result[config.field.name] = value;
169
+ }
170
+
171
+ //#endregion
172
+ Object.defineProperty(exports, 'getFieldsToPrompt', {
173
+ enumerable: true,
174
+ get: function () {
175
+ return getFieldsToPrompt;
176
+ }
177
+ });
178
+ Object.defineProperty(exports, 'isInteractive', {
179
+ enumerable: true,
180
+ get: function () {
181
+ return isInteractive;
182
+ }
183
+ });
184
+ Object.defineProperty(exports, 'promptMissingArgs', {
185
+ enumerable: true,
186
+ get: function () {
187
+ return promptMissingArgs;
188
+ }
189
+ });
190
+ Object.defineProperty(exports, 'resolvePromptConfig', {
191
+ enumerable: true,
192
+ get: function () {
193
+ return resolvePromptConfig;
194
+ }
195
+ });
196
+ //# sourceMappingURL=prompt-aXfSf27y.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-aXfSf27y.cjs","names":[],"sources":["../src/prompt/prompt-resolver.ts","../src/prompt/tty-detector.ts","../src/prompt/index.ts"],"sourcesContent":["import type { ResolvedFieldMeta } from \"../core/schema-extractor.js\";\nimport type { ResolvedPromptConfig } from \"./types.js\";\n\n/**\n * Resolve prompt configuration for a field.\n *\n * Priority for prompt type:\n * 1. Explicit type from prompt.type\n * 2. Explicit choices from prompt.choices (forces \"select\")\n * 3. Inherited from completion metadata (file/directory -> \"text\")\n * 4. Auto-detected from Zod schema type:\n * - enum (has enumValues) -> \"select\"\n * - boolean -> \"confirm\"\n * - string/number/unknown -> \"text\"\n *\n * Returns null if the field has no prompt metadata or prompting is disabled.\n */\nexport function resolvePromptConfig(field: ResolvedFieldMeta): ResolvedPromptConfig | null {\n const promptMeta = field.prompt;\n if (!promptMeta || promptMeta.enabled === false) return null;\n\n const message = promptMeta.message ?? field.description ?? field.name;\n const rawType = resolvePromptType(field, promptMeta);\n const choices = resolveChoices(field, promptMeta, rawType);\n // Fall back to text when select has no choices to avoid adapter crash\n const type = rawType === \"select\" && !choices ? \"text\" : rawType;\n\n return { field, type, message, ...(choices && { choices }) };\n}\n\nfunction hasChoices(list: unknown[] | undefined): list is unknown[] {\n return list !== undefined && list.length > 0;\n}\n\nfunction resolvePromptType(\n field: ResolvedFieldMeta,\n promptMeta: NonNullable<ResolvedFieldMeta[\"prompt\"]>,\n): ResolvedPromptConfig[\"type\"] {\n // Priority 1: Explicit type\n if (promptMeta.type) {\n return promptMeta.type === \"file\" || promptMeta.type === \"directory\" ? \"text\" : promptMeta.type;\n }\n // Priority 2: Explicit choices\n if (hasChoices(promptMeta.choices)) return \"select\";\n // Priority 3: Inherited from completion type\n if (field.completion?.type === \"file\" || field.completion?.type === \"directory\") {\n return \"text\";\n }\n // Priority 4: Auto-detect from schema\n if (hasChoices(field.enumValues)) return \"select\";\n if (field.type === \"boolean\") return \"confirm\";\n return \"text\";\n}\n\nfunction resolveChoices(\n field: ResolvedFieldMeta,\n promptMeta: NonNullable<ResolvedFieldMeta[\"prompt\"]>,\n type: ResolvedPromptConfig[\"type\"],\n): ResolvedPromptConfig[\"choices\"] | undefined {\n // Explicit choices always win\n if (hasChoices(promptMeta.choices)) {\n return promptMeta.choices.map((c) => (typeof c === \"string\" ? { label: c, value: c } : c));\n }\n // Auto-populate from enum values for select type\n if (type === \"select\" && hasChoices(field.enumValues)) {\n return field.enumValues.map((v) => ({ label: v, value: v }));\n }\n return undefined;\n}\n\n/**\n * Filter fields that need prompting (missing value + prompt configured).\n *\n * For discriminatedUnion schemas, variant-aware narrowing is handled by the\n * caller (promptMissingArgs) which prompts the discriminator first and then\n * passes only the active variant's fields. For plain union schemas, this\n * iterates all fields across every variant without narrowing.\n *\n * Fields with Zod defaults that also have prompt metadata will be prompted\n * when the raw value is undefined. This is intentional: `prompt: {}` is an\n * explicit opt-in to interactive input. Omit prompt metadata to let the\n * default apply silently.\n */\nexport function getFieldsToPrompt(\n fields: ResolvedFieldMeta[],\n rawArgs: Record<string, unknown>,\n): ResolvedPromptConfig[] {\n const configs: ResolvedPromptConfig[] = [];\n for (const field of fields) {\n if (rawArgs[field.name] !== undefined) continue;\n // Array fields are not supported for interactive prompting yet;\n // a scalar text response would fail Zod array validation.\n // Object-valued fields (detected as type \"unknown\") are also unsupported\n // but share the \"unknown\" bucket with literals, so they are not filtered\n // here. Putting prompt metadata on object fields yields a Zod validation\n // error at parse time, which is an acceptable misconfiguration signal.\n if (field.type === \"array\") continue;\n const config = resolvePromptConfig(field);\n if (config) configs.push(config);\n }\n return configs;\n}\n","/**\n * Detect whether the current environment supports interactive prompts.\n * Returns false in CI, piped input, or non-TTY environments.\n */\nexport function isInteractive(): boolean {\n if (!process.stdin.isTTY) return false;\n if (!process.stdout.isTTY) return false;\n if (process.env.CI) return false;\n if (process.env.POLITTY_NO_PROMPT) return false;\n return true;\n}\n","import type { ExtractedFields, ResolvedFieldMeta } from \"../core/schema-extractor.js\";\nimport { getFieldsToPrompt, resolvePromptConfig } from \"./prompt-resolver.js\";\nimport { isInteractive } from \"./tty-detector.js\";\nimport type { PromptAdapter, ResolvedPromptConfig } from \"./types.js\";\n\nexport { getFieldsToPrompt, resolvePromptConfig } from \"./prompt-resolver.js\";\nexport { isInteractive } from \"./tty-detector.js\";\nexport type { PromptAdapter, ResolvedPromptConfig } from \"./types.js\";\n\n/**\n * Options for promptMissingArgs behavior\n */\nexport interface PromptOptions {\n /** Prompt adapter to use for rendering prompts */\n adapter: PromptAdapter;\n /** Override interactive detection (force enable/disable prompts) */\n interactive?: boolean;\n}\n\n/**\n * Prompt for missing argument values interactively.\n *\n * Only prompts for fields that have `prompt` metadata set via `arg()` and\n * whose values are still undefined after CLI and env resolution.\n * Returns rawArgs unchanged in non-interactive environments.\n */\nexport async function promptMissingArgs(\n rawArgs: Record<string, unknown>,\n extracted: ExtractedFields,\n options: PromptOptions,\n): Promise<Record<string, unknown>> {\n const interactive = options.interactive ?? isInteractive();\n if (!interactive) return rawArgs;\n\n const adapter = options.adapter;\n const result = { ...rawArgs };\n\n // For discriminatedUnion schemas, prompt the discriminator first then\n // narrow to the active variant to avoid prompting irrelevant fields.\n if (\n extracted.schemaType === \"discriminatedUnion\" &&\n extracted.discriminator &&\n extracted.variants\n ) {\n await promptDiscriminatedUnion(adapter, result, extracted);\n } else if (extracted.schemaType === \"union\" || extracted.schemaType === \"xor\") {\n // Plain unions have no discriminator to narrow by. Prompting the merged\n // field set would collect answers for incompatible branches, causing\n // silent data loss (strip mode) or validation errors (strict mode).\n // Skip prompting and let Zod validation handle it.\n } else {\n // For object and intersection schemas, prompt all fields as a flat list.\n // Limitation: intersection schemas that compose a discriminatedUnion\n // (e.g. sharedOptions.and(z.discriminatedUnion(...))) lose variant\n // structure here because extractFields flattens both operands. Variant-\n // aware prompting for intersections requires architectural changes to\n // preserve sub-schema structure through extraction.\n await promptAllFields(adapter, result, extracted.fields);\n }\n\n return result;\n}\n\nasync function promptDiscriminatedUnion(\n adapter: PromptAdapter,\n result: Record<string, unknown>,\n extracted: ExtractedFields,\n): Promise<void> {\n const { discriminator, variants } = extracted;\n if (!discriminator || !variants) return;\n\n // Prompt for discriminator if not already provided.\n // The deduplicated extracted.fields only keeps the first variant's\n // discriminator, so scan all variants for prompt metadata and build\n // choices from every variant's discriminator value.\n if (result[discriminator] === undefined) {\n const discField = findDiscriminatorField(extracted.fields, variants, discriminator);\n const discConfig = discField ? resolvePromptConfig(discField) : null;\n if (discConfig) {\n const allValues = variants.map((v) => v.discriminatorValue).filter(Boolean);\n if (allValues.length > 0) {\n discConfig.type = \"select\";\n discConfig.choices = allValues.map((v) => ({ label: v, value: v }));\n }\n await promptAndCollect(adapter, result, discConfig);\n }\n }\n\n // Find the active variant based on discriminator value\n const discValue = String(result[discriminator] ?? \"\");\n const activeVariant = variants.find((v) => v.discriminatorValue === discValue);\n\n if (activeVariant) {\n // Prompt only the active variant's fields (excluding discriminator)\n const variantFields = activeVariant.fields.filter((f) => f.name !== discriminator);\n await promptAllFields(adapter, result, variantFields);\n }\n // When no variant matches (invalid value or unextracted discriminator),\n // skip prompting and let Zod validation surface the error.\n}\n\n/**\n * Find the discriminator field with prompt metadata, checking the\n * deduplicated top-level fields first, then scanning per-variant fields.\n */\nfunction findDiscriminatorField(\n fields: ResolvedFieldMeta[],\n variants: NonNullable<ExtractedFields[\"variants\"]>,\n discriminator: string,\n): ResolvedFieldMeta | undefined {\n const topLevel = fields.find((f) => f.name === discriminator);\n if (topLevel?.prompt) return topLevel;\n for (const variant of variants) {\n const field = variant.fields.find((f) => f.name === discriminator);\n if (field?.prompt) return field;\n }\n return undefined;\n}\n\nasync function promptAllFields(\n adapter: PromptAdapter,\n result: Record<string, unknown>,\n fields: ResolvedFieldMeta[],\n): Promise<void> {\n const fieldsToPrompt = getFieldsToPrompt(fields, result);\n for (const config of fieldsToPrompt) {\n await promptAndCollect(adapter, result, config);\n }\n}\n\nasync function promptAndCollect(\n adapter: PromptAdapter,\n result: Record<string, unknown>,\n config: ResolvedPromptConfig,\n): Promise<void> {\n const { message } = config;\n let value: unknown;\n switch (config.type) {\n case \"text\":\n value = await adapter.text({ message, placeholder: config.field.placeholder });\n break;\n case \"password\":\n value = await adapter.password({ message });\n break;\n case \"confirm\":\n value = await adapter.confirm({ message });\n break;\n case \"select\":\n value = await adapter.select({ message, options: config.choices ?? [] });\n break;\n }\n if (adapter.isCancelled(value)) {\n throw new Error(\"Prompt cancelled by user\");\n }\n result[config.field.name] = value;\n}\n"],"mappings":"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"}
@@ -1,6 +1,5 @@
1
- import { a as getExtractedFields, c as toKebabCase, i as extractFields, r as resolveSubCommandMeta, s as toCamelCase } from "./lazy-D6nL_iKJ.js";
2
- import { a as emptyLogs, i as createLogCollector, n as resolveLazyCommand, o as mergeLogs, r as resolveSubcommand, t as listSubCommands } from "./subcommand-router-Bu3YTw_f.js";
3
- import { z } from "zod";
1
+ import { a as getExtractedFields, c as toKebabCase, i as extractFields, r as resolveSubCommandMeta, s as toCamelCase } from "./lazy-xrzxwnru.js";
2
+ import { a as emptyLogs, i as createLogCollector, n as resolveLazyCommand, o as mergeLogs, r as resolveSubcommand, t as listSubCommands } from "./subcommand-router-BhYVuS83.js";
4
3
  import { styleText } from "node:util";
5
4
  import stringWidth from "string-width";
6
5
 
@@ -1771,37 +1770,6 @@ function findSimilar(target, candidates) {
1771
1770
  })).filter(({ distance }) => distance <= threshold).sort((a, b) => a.distance - b.distance).map(({ candidate }) => candidate).slice(0, 3);
1772
1771
  }
1773
1772
  /**
1774
- * Format validation errors into a human-readable message
1775
- *
1776
- * @param errors - Array of validation errors
1777
- * @returns Formatted error message
1778
- */
1779
- function formatValidationErrors$1(errors) {
1780
- if (errors.length === 0) return "";
1781
- const lines = [styles.error("Validation errors:")];
1782
- for (const error of errors) {
1783
- const path = error.path.join(".");
1784
- lines.push(` ${symbols.bullet} ${styles.bold(path)}: ${error.message}`);
1785
- }
1786
- return lines.join("\n");
1787
- }
1788
- /**
1789
- * Format unknown flag error with suggestions
1790
- *
1791
- * @param flag - The unknown flag (e.g., "--verbos")
1792
- * @param knownFlags - List of known flag names
1793
- * @returns Formatted error message with suggestions
1794
- */
1795
- function formatUnknownFlag(flag, knownFlags) {
1796
- const similar = findSimilar(flag.replace(/^-{1,2}/, ""), knownFlags);
1797
- let message = `${styles.error("Unknown option:")} ${styles.bold(flag)}`;
1798
- if (similar.length > 0) {
1799
- message += `\n\n${styles.info("Did you mean?")}`;
1800
- for (const suggestion of similar) message += `\n ${symbols.arrow} ${styles.option(`--${suggestion}`)}`;
1801
- }
1802
- return message;
1803
- }
1804
- /**
1805
1773
  * Format unknown flag warning with suggestions (for strip mode)
1806
1774
  *
1807
1775
  * @param flag - The unknown flag (e.g., "--verbos")
@@ -1828,22 +1796,6 @@ function formatRuntimeError(error, debug) {
1828
1796
  if (debug && error.stack) return `${styles.error("Error:")} ${error.message}\n\n${styles.dim(error.stack)}`;
1829
1797
  return `${styles.error("Error:")} ${error.message}`;
1830
1798
  }
1831
- /**
1832
- * Format unknown subcommand error with suggestions
1833
- *
1834
- * @param subcommand - The unknown subcommand name
1835
- * @param knownSubcommands - List of known subcommand names
1836
- * @returns Formatted error message with suggestions
1837
- */
1838
- function formatUnknownSubcommand(subcommand, knownSubcommands) {
1839
- const similar = findSimilar(subcommand, knownSubcommands);
1840
- let message = `${styles.error("Unknown command:")} ${styles.bold(subcommand)}`;
1841
- if (similar.length > 0) {
1842
- message += `\n\n${styles.info("Did you mean?")}`;
1843
- for (const suggestion of similar) message += `\n ${symbols.arrow} ${styles.command(suggestion)}`;
1844
- }
1845
- return message;
1846
- }
1847
1799
 
1848
1800
  //#endregion
1849
1801
  //#region src/validator/zod-validator.ts
@@ -2046,6 +1998,7 @@ async function runMain(command, options = {}) {
2046
1998
  handleSignals: true,
2047
1999
  logger: options.logger,
2048
2000
  globalArgs: options.globalArgs,
2001
+ prompt: options.prompt,
2049
2002
  _globalExtracted: globalExtracted,
2050
2003
  _globalCleanup: options.cleanup,
2051
2004
  _context: {
@@ -2055,6 +2008,7 @@ async function runMain(command, options = {}) {
2055
2008
  globalExtracted
2056
2009
  }
2057
2010
  });
2011
+ if ((options.displayErrors ?? true) && !result.success && result.error) (options.logger ?? defaultLogger).error(formatRuntimeError(result.error, options.debug ?? false));
2058
2012
  if (options.cleanup) {
2059
2013
  const cleanupCtx = { error: !result.success ? result.error : void 0 };
2060
2014
  try {
@@ -2062,6 +2016,7 @@ async function runMain(command, options = {}) {
2062
2016
  } catch {}
2063
2017
  }
2064
2018
  if (process.stdout.writableLength > 0) await new Promise((resolve) => process.stdout.once("drain", resolve));
2019
+ if (process.stderr.writableLength > 0) await new Promise((resolve) => process.stderr.once("drain", resolve));
2065
2020
  process.exit(result.exitCode);
2066
2021
  }
2067
2022
  /**
@@ -2093,11 +2048,7 @@ async function runCommandInternal(command, argv, options = {}) {
2093
2048
  const subCmdNames = listSubCommands(command);
2094
2049
  if (subCmdNames.length > 0) {
2095
2050
  const potentialSubCmd = findFirstPositional(argv, context.globalExtracted);
2096
- if (potentialSubCmd && !subCmdNames.includes(potentialSubCmd)) {
2097
- logger.error(formatUnknownSubcommand(potentialSubCmd, subCmdNames));
2098
- logger.error("");
2099
- hasUnknownSubcommand = true;
2100
- }
2051
+ if (potentialSubCmd && !subCmdNames.includes(potentialSubCmd)) hasUnknownSubcommand = true;
2101
2052
  }
2102
2053
  const help = generateHelp(command, {
2103
2054
  showSubcommands: options.showSubcommands ?? true,
@@ -2106,12 +2057,17 @@ async function runCommandInternal(command, argv, options = {}) {
2106
2057
  });
2107
2058
  logger.log(help);
2108
2059
  collector?.stop();
2109
- if (hasUnknownSubcommand) return {
2110
- success: false,
2111
- error: /* @__PURE__ */ new Error(`Unknown subcommand: ${argv.find((arg) => !arg.startsWith("-"))}`),
2112
- exitCode: 1,
2113
- logs: getCurrentLogs()
2114
- };
2060
+ if (hasUnknownSubcommand) {
2061
+ const unknownCmd = findFirstPositional(argv, context.globalExtracted) ?? "";
2062
+ const similar = findSimilar(unknownCmd, subCmdNames);
2063
+ const suggestion = similar.length > 0 ? ` Did you mean: ${similar.join(", ")}?` : "";
2064
+ return {
2065
+ success: false,
2066
+ error: /* @__PURE__ */ new Error(`Unknown subcommand: ${unknownCmd}${suggestion ? `.${suggestion}` : ""}`),
2067
+ exitCode: 1,
2068
+ logs: getCurrentLogs()
2069
+ };
2070
+ }
2115
2071
  return {
2116
2072
  success: true,
2117
2073
  result: void 0,
@@ -2166,7 +2122,6 @@ async function runCommandInternal(command, argv, options = {}) {
2166
2122
  const unknownKeysMode = parseResult.extractedFields?.unknownKeysMode ?? "strip";
2167
2123
  const knownFlags = parseResult.extractedFields?.fields.map((f) => f.name) ?? [];
2168
2124
  if (unknownKeysMode === "strict") {
2169
- for (const flag of parseResult.unknownFlags) logger.error(formatUnknownFlag(flag, knownFlags));
2170
2125
  collector?.stop();
2171
2126
  return {
2172
2127
  success: false,
@@ -2188,14 +2143,16 @@ async function runCommandInternal(command, argv, options = {}) {
2188
2143
  }
2189
2144
  }
2190
2145
  }
2146
+ if (options.prompt) {
2147
+ const resolved = await options.prompt(accumulatedGlobalArgs, options._globalExtracted);
2148
+ Object.assign(accumulatedGlobalArgs, resolved);
2149
+ }
2191
2150
  const globalValidation = validateArgs(accumulatedGlobalArgs, options.globalArgs);
2192
2151
  if (!globalValidation.success) {
2193
- const errorMessage = formatValidationErrors$1(globalValidation.errors);
2194
- logger.error(errorMessage);
2195
2152
  collector?.stop();
2196
2153
  return {
2197
2154
  success: false,
2198
- error: new Error(errorMessage),
2155
+ error: new Error(formatValidationErrors(globalValidation.errors)),
2199
2156
  exitCode: 1,
2200
2157
  logs: getCurrentLogs()
2201
2158
  };
@@ -2213,13 +2170,20 @@ async function runCommandInternal(command, argv, options = {}) {
2213
2170
  globalCleanup: options._globalCleanup
2214
2171
  });
2215
2172
  }
2216
- const validationResult = validateArgs(parseResult.rawArgs, command.args);
2173
+ let argsToValidate = parseResult.rawArgs;
2174
+ if (options.prompt && parseResult.extractedFields) {
2175
+ const resolved = await options.prompt(argsToValidate, parseResult.extractedFields);
2176
+ argsToValidate = {
2177
+ ...argsToValidate,
2178
+ ...resolved
2179
+ };
2180
+ }
2181
+ const validationResult = validateArgs(argsToValidate, command.args);
2217
2182
  if (!validationResult.success) {
2218
- logger.error(formatValidationErrors$1(validationResult.errors));
2219
2183
  collector?.stop();
2220
2184
  return {
2221
2185
  success: false,
2222
- error: new Error(formatValidationErrors$1(validationResult.errors)),
2186
+ error: new Error(formatValidationErrors(validationResult.errors)),
2223
2187
  exitCode: 1,
2224
2188
  logs: getCurrentLogs()
2225
2189
  };
@@ -2241,7 +2205,6 @@ async function runCommandInternal(command, argv, options = {}) {
2241
2205
  });
2242
2206
  } catch (error) {
2243
2207
  const err = error instanceof Error ? error : new Error(String(error));
2244
- logger.error(formatRuntimeError(err, options.debug ?? false));
2245
2208
  collector?.stop();
2246
2209
  return {
2247
2210
  success: false,
@@ -2272,4 +2235,4 @@ function extractAndValidateGlobal(options) {
2272
2235
 
2273
2236
  //#endregion
2274
2237
  export { logger as C, createDualCaseProxy as D, symbols as E, isColorEnabled as S, styles as T, PositionalConfigError as _, parseArgv as a, renderInline as b, validateCommand as c, validateDuplicateFields as d, validatePositionalConfig as f, DuplicateFieldError as g, DuplicateAliasError as h, formatValidationErrors as i, validateCrossSchemaCollisions as l, CaseVariantCollisionError as m, runMain as n, formatCommandValidationErrors as o, validateReservedAliases as p, runner_exports as r, validateCaseVariantCollisions as s, runCommand as t, validateDuplicateAliases as u, ReservedAliasError as v, setColorEnabled as w, renderMarkdown as x, generateHelp as y };
2275
- //# sourceMappingURL=runner-JZRo4pYu.js.map
2238
+ //# sourceMappingURL=runner-CnG-Ncz0.js.map