politty 0.4.15 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/dist/{arg-registry-Dw0f11Zc.d.ts → arg-registry--NRaNFJM.d.cts} +238 -6
  2. package/dist/arg-registry--NRaNFJM.d.cts.map +1 -0
  3. package/dist/{arg-registry-CB5gGtzp.d.cts → arg-registry-6E0WHOh_.d.ts} +238 -6
  4. package/dist/arg-registry-6E0WHOh_.d.ts.map +1 -0
  5. package/dist/augment.d.cts +1 -1
  6. package/dist/augment.d.cts.map +1 -1
  7. package/dist/augment.d.ts +1 -1
  8. package/dist/augment.d.ts.map +1 -1
  9. package/dist/completion/index.cjs +2 -1
  10. package/dist/completion/index.d.cts +3 -2
  11. package/dist/completion/index.d.ts +3 -2
  12. package/dist/completion/index.js +2 -2
  13. package/dist/completion-BA5JMvVG.js +4067 -0
  14. package/dist/completion-BA5JMvVG.js.map +1 -0
  15. package/dist/completion-Cqs1Ja7C.cjs +4169 -0
  16. package/dist/completion-Cqs1Ja7C.cjs.map +1 -0
  17. package/dist/docs/index.cjs +89 -29
  18. package/dist/docs/index.cjs.map +1 -1
  19. package/dist/docs/index.d.cts +1 -1
  20. package/dist/docs/index.d.cts.map +1 -1
  21. package/dist/docs/index.d.ts +1 -1
  22. package/dist/docs/index.d.ts.map +1 -1
  23. package/dist/docs/index.js +92 -31
  24. package/dist/docs/index.js.map +1 -1
  25. package/dist/{index-C1gGgUeB.d.cts → index-DBMfKZ34.d.ts} +189 -17
  26. package/dist/index-DBMfKZ34.d.ts.map +1 -0
  27. package/dist/{index-Dg9Fpz0R.d.ts → index-DJp8k5Bq.d.cts} +189 -17
  28. package/dist/index-DJp8k5Bq.d.cts.map +1 -0
  29. package/dist/index.cjs +12 -10
  30. package/dist/index.d.cts +36 -4
  31. package/dist/index.d.cts.map +1 -1
  32. package/dist/index.d.ts +36 -4
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +4 -4
  35. package/dist/log-collector-Cd2_mv87.cjs.map +1 -1
  36. package/dist/log-collector-Cu6MCtAx.js.map +1 -1
  37. package/dist/prompt/clack/index.cjs.map +1 -1
  38. package/dist/prompt/clack/index.d.cts +1 -1
  39. package/dist/prompt/clack/index.d.cts.map +1 -1
  40. package/dist/prompt/clack/index.d.ts +1 -1
  41. package/dist/prompt/clack/index.d.ts.map +1 -1
  42. package/dist/prompt/clack/index.js.map +1 -1
  43. package/dist/prompt/index.d.cts +1 -1
  44. package/dist/prompt/index.d.cts.map +1 -1
  45. package/dist/prompt/index.d.ts +1 -1
  46. package/dist/prompt/index.d.ts.map +1 -1
  47. package/dist/prompt/inquirer/index.cjs.map +1 -1
  48. package/dist/prompt/inquirer/index.d.cts +1 -1
  49. package/dist/prompt/inquirer/index.d.cts.map +1 -1
  50. package/dist/prompt/inquirer/index.d.ts +1 -1
  51. package/dist/prompt/inquirer/index.d.ts.map +1 -1
  52. package/dist/prompt/inquirer/index.js.map +1 -1
  53. package/dist/prompt-BKHqGrFw.js.map +1 -1
  54. package/dist/prompt-aXfSf27y.cjs.map +1 -1
  55. package/dist/{runner-DKAQBNNh.js → runner-BmSEiD9A.js} +319 -52
  56. package/dist/runner-BmSEiD9A.js.map +1 -0
  57. package/dist/{runner-CriXJlm4.cjs → runner-CRZ_7Y9i.cjs} +366 -87
  58. package/dist/runner-CRZ_7Y9i.cjs.map +1 -0
  59. package/dist/{subcommand-router-ENeCymvX.js → schema-extractor-C50R-1re.js} +175 -137
  60. package/dist/schema-extractor-C50R-1re.js.map +1 -0
  61. package/dist/{subcommand-router-CqZX3orq.cjs → schema-extractor-SLPgBNgZ.cjs} +174 -136
  62. package/dist/schema-extractor-SLPgBNgZ.cjs.map +1 -0
  63. package/package.json +16 -16
  64. package/dist/arg-registry-CB5gGtzp.d.cts.map +0 -1
  65. package/dist/arg-registry-Dw0f11Zc.d.ts.map +0 -1
  66. package/dist/completion-B5fgnUGm.cjs +0 -1940
  67. package/dist/completion-B5fgnUGm.cjs.map +0 -1
  68. package/dist/completion-Ca5ESJlG.js +0 -1844
  69. package/dist/completion-Ca5ESJlG.js.map +0 -1
  70. package/dist/index-C1gGgUeB.d.cts.map +0 -1
  71. package/dist/index-Dg9Fpz0R.d.ts.map +0 -1
  72. package/dist/runner-CriXJlm4.cjs.map +0 -1
  73. package/dist/runner-DKAQBNNh.js.map +0 -1
  74. package/dist/subcommand-router-CqZX3orq.cjs.map +0 -1
  75. package/dist/subcommand-router-ENeCymvX.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-BKHqGrFw.js","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
+ {"version":3,"file":"prompt-BKHqGrFw.js","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 +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
+ {"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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"}