# `prompts` ## Purpose Runs the plugin's optional `prompts` stage and validates the answers against the schema the plugin returns. This is where `--answers ` flows in (via `answersFromFile`) and where `--no-interactive` is enforced. Validation failures surface as `INSTALLER.PROMPT_VALIDATION_FAILED` with the underlying Zod (or other compatible) error attached as `cause` and field-level issues attached as `context.issues`. ## Features - Accepts both explicit `answers` (programmatic harness) and `answersFromFile` (loaded from a JSON file by the bin). - Fails fast under `noInteractive` when a plugin demands answers that weren't pre-supplied — prevents silent prompts in CI. - No-op when the plugin omits `prompts` — explicit answers pass through, otherwise an empty `{}` is supplied to plan. Plugins that need answers must declare a schema. - Wrapped in OTel span `installer.prompts` so prompt validation timing is observable. ## Basic Example ```ts import { runPrompts } from "@suaveplan/installer"; import z from "zod"; const schema = z.object({ name: z.string().min(1) }); const plugin = { id: "demo", version: "0.1.0", prompts: () => schema, plan: async () => [], apply: async () => undefined, }; const answers = await runPrompts({ plugin, ctx, explicitAnswers: { name: "alice" }, }); ``` ## Advanced Example ```ts import { runPrompts, InstallerError } from "@suaveplan/installer"; try { const answers = await runPrompts({ plugin, ctx, answersFromFile: JSON.parse(await fileContent), }); // ... pass to plan } catch (err) { if ( err instanceof InstallerError && err.code === "INSTALLER.PROMPT_VALIDATION_FAILED" ) { const issues = err.context?.["issues"]; console.error("Invalid answers:", issues); process.exit(2); } throw err; } ``` ## API Reference - `runPrompts(options): Promise` - `interface RunPromptsOptions` — `{ plugin, ctx, explicitAnswers?, answersFromFile? }`. - Errors: `INSTALLER.PROMPT_VALIDATION_FAILED` for missing answers, validation failures, or non-interactive without answers. ## Implementation Notes `explicitAnswers` is preferred over `answersFromFile` when both are supplied — the testing harness uses `explicitAnswers` and we want it to take precedence when callers also pass a file. `safeParse` is used instead of `parse` so the host can attach the Zod issues as structured context rather than letting them bubble as raw `ZodError`. The schema returned by `plugin.prompts` is treated structurally (`PromptSchema`), not nominally — any object with `parse` and `safeParse` is acceptable, which lets plugins swap validators without breaking the host contract.