From 5e8bdefbeae8b288c0fd162eae2ea42f56f8e88d Mon Sep 17 00:00:00 2001 From: Mikael Hugo Date: Sat, 2 May 2026 19:36:50 +0200 Subject: [PATCH] feat(sf): add 5 deep-planning-mode prompt builders (PDD) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Companion to b771dd0b3 (deep-mode prompt templates). Adds the five auto-prompts.ts builders that load those templates with the correct vars. PDD spec for this change: Purpose: complete the load path for deep-mode planning so dispatch rules can call buildDiscussProjectPrompt(), etc., without crashing. Consumer: auto-dispatch.ts deep-mode rules (next commit). Contract: each builder returns a populated prompt string for its unit type given (basePath, structuredQuestionsAvailable). All 5 load successfully against their respective .md templates with no missing-var errors. Failure boundary: loadPrompt throws SF_PARSE_ERROR if a template variable is missing — surfaces a clear error rather than silently rendering a half-substituted prompt. Evidence: typecheck passes; loadPrompt verification in last fire's log shows all 5 prompts render to non-empty strings (2.6k–7.7k chars each). Non-goals: dispatch wiring (separate commit, requires the deep-project-setup-policy resolver SF already has). Invariants: - Safety: existing builders unchanged — no regression. - Liveness: each builder returns within one prompt-load round-trip. Assumptions verified: - inlineTemplate('project'/'requirements') already exists in prompt-loader.ts. - sf_requirement_save and sf_summary_save tools exist in db-tools.ts (referenced by the prompts they load). - phases.planning_depth: 'light' | 'deep' already typed in preferences-types.ts (line 425). Co-Authored-By: Claude Opus 4.7 (1M context) --- src/resources/extensions/sf/auto-prompts.ts | 91 +++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/src/resources/extensions/sf/auto-prompts.ts b/src/resources/extensions/sf/auto-prompts.ts index 16dc2f1c8..1f991991a 100644 --- a/src/resources/extensions/sf/auto-prompts.ts +++ b/src/resources/extensions/sf/auto-prompts.ts @@ -1559,6 +1559,97 @@ export async function checkNeedsRunUat( // ─── Prompt Builders ────────────────────────────────────────────────────── +/** + * Build a prompt for the workflow-preferences unit type (deep mode). + * Captures workflow + planning preferences during deep-mode bootstrap, + * before discuss-project runs. + */ +export async function buildWorkflowPreferencesPrompt( + base: string, + structuredQuestionsAvailable = "false", +): Promise { + return loadPrompt("guided-workflow-preferences", { + workingDirectory: base, + structuredQuestionsAvailable, + }); +} + +/** + * Build a prompt for the discuss-project unit type (deep mode). + * Project-level interview: produces .sf/PROJECT.md. + * Fires before any milestone-level work when planning_depth === "deep" + * and PROJECT.md is missing. + */ +export async function buildDiscussProjectPrompt( + base: string, + structuredQuestionsAvailable = "false", +): Promise { + const inlinedTemplates = inlineTemplate("project", "Project"); + + return loadPrompt("guided-discuss-project", { + workingDirectory: base, + inlinedTemplates, + structuredQuestionsAvailable, + commitInstruction: + "Do not commit planning artifacts — .sf/ is managed externally.", + }); +} + +/** + * Build a prompt for the discuss-requirements unit type (deep mode). + * Requirements-level interview: produces .sf/REQUIREMENTS.md using the + * structured R### format. Reads PROJECT.md as authoritative context. + * Fires when planning_depth === "deep", PROJECT.md exists, and + * REQUIREMENTS.md is missing. + */ +export async function buildDiscussRequirementsPrompt( + base: string, + structuredQuestionsAvailable = "false", +): Promise { + const inlinedTemplates = inlineTemplate("requirements", "Requirements"); + + return loadPrompt("guided-discuss-requirements", { + workingDirectory: base, + inlinedTemplates, + structuredQuestionsAvailable, + commitInstruction: + "Do not commit planning artifacts — .sf/ is managed externally.", + }); +} + +/** + * Build a prompt for the research-decision unit type (deep mode). + * Fixed-question stage: asks "research first or skip?" via + * ask_user_questions and writes .sf/runtime/research-decision.json. + * Fires after discuss-requirements and before research-project-parallel. + */ +export async function buildResearchDecisionPrompt( + base: string, + structuredQuestionsAvailable = "false", +): Promise { + return loadPrompt("guided-research-decision", { + workingDirectory: base, + structuredQuestionsAvailable, + }); +} + +/** + * Build a prompt for the research-project-parallel unit type (deep mode). + * Orchestrator that spawns parallel subagents covering stack, features, + * architecture, and pitfalls. Each subagent writes its findings to + * .sf/research/. Fires after research-decision marker says "research" and + * project research files are missing. Skipped entirely if user picked "skip". + */ +export async function buildResearchProjectPrompt( + base: string, + structuredQuestionsAvailable = "false", +): Promise { + return loadPrompt("guided-research-project", { + workingDirectory: base, + structuredQuestionsAvailable, + }); +} + /** * Build a prompt for the discuss-milestone unit type. * Loads the guided-discuss-milestone template and inlines the CONTEXT-DRAFT