import path from 'node:path'; import { cancel, intro, isCancel, outro, select, text } from '@clack/prompts'; import { createPrd, savePrd } from './prd.js'; import type { CreatePrdOptions, PrdDocument } from './types.js'; interface WizardAnswers { goals: string; constraints: string; milestones: string; } function updateSectionField(doc: PrdDocument, sectionKeyword: string, value: string): void { const section = doc.sections.find((candidate) => candidate.id.includes(sectionKeyword)); if (section === undefined) { return; } const fieldName = Object.keys(section.fields).find((field) => field.toLowerCase().includes(sectionKeyword)) ?? Object.keys(section.fields)[0]; if (fieldName !== undefined) { section.fields[fieldName] = value; } } async function promptText(message: string, initialValue = ''): Promise { const response = await text({ message, initialValue, }); if (isCancel(response)) { cancel('PRD wizard cancelled.'); throw new Error('PRD wizard cancelled'); } return response.trim(); } async function promptTemplate(template?: string): Promise { if (template !== undefined && template.trim().length > 0) { return template; } const choice = await select({ message: 'PRD type', options: [ { value: 'software', label: 'Software project' }, { value: 'feature', label: 'Feature' }, { value: 'spike', label: 'Research spike' }, ], }); if (isCancel(choice)) { cancel('PRD wizard cancelled.'); throw new Error('PRD wizard cancelled'); } return choice; } function applyWizardAnswers(doc: PrdDocument, answers: WizardAnswers): PrdDocument { updateSectionField(doc, 'goal', answers.goals); updateSectionField(doc, 'constraint', answers.constraints); updateSectionField(doc, 'milestone', answers.milestones); doc.updatedAt = new Date().toISOString(); return doc; } export async function runPrdWizard(options: CreatePrdOptions): Promise { intro('Mosaic PRD wizard'); const name = options.name.trim().length > 0 ? options.name.trim() : await promptText('Project name'); const template = await promptTemplate(options.template); const goals = await promptText('Primary goals'); const constraints = await promptText('Key constraints'); const milestones = await promptText('Planned milestones'); const doc = await createPrd({ ...options, name, template, interactive: true, }); const updated = applyWizardAnswers(doc, { goals, constraints, milestones, }); await savePrd(updated); outro(`PRD created: ${path.join(updated.projectPath, 'docs', 'prdy', `${updated.id}.yaml`)}`); return updated; }