/** * buildDispatchSystemPrompt — pure-function prompt composer for sub-agent dispatch. * * dispatch flow (`src/cli/commands/dispatch-commands.ts`) calls * `MemoryPreflightService.fetchBlock` and feeds the result into this builder * so the memory block, when available, is prepended BEFORE the task brief. * * Keeping the builder a pure function (no IO) makes the three acceptance * cases easy to test in isolation: * 1. returns the original prompt (sans memory block) when unavailable * 2. prepends the memory block when available * 3. never pushes the memory block below the task brief */ import type { MemoryPreflightResult } from './memory-preflight-service.js'; import type { ContextPercentProbe } from './auto-compact-types.js'; export interface DispatchPromptInput { taskTitle: string; taskBody: string; memoryBlock: MemoryPreflightResult; /** * context-fill probe. When provided, the composer prepends * a `## Context window` block with the authoritative ratio so * the dispatched sub-agent does NOT estimate context from * message length. The ratio comes from the IDE adapter's * `compact` env-var / statusline (token-counted), NOT from * a byte-counted estimate. */ contextProbe?: ContextPercentProbe | null; /** * `## Codegraph structure` markdown block, read from the codegraph * index BEFORE the RD sub-agent's task body is composed so the RD * plans against real module/file topology, not LLM memory. * * - `undefined` → no codegraph block (legacy callers unchanged). * - `null` → codegraph was attempted and no reason was obtained; the * composer renders the fallback that SAYS the reason is missing. * - `string` → the structure block, or the preflight's failure NOTE when the * index could not be read — the composer turns the note into an unavailable * block that QUOTES it, so the reason cannot be dropped on its own. */ codegraphBlock?: string | null; /** * `## Project stack` markdown block, rendered from the detected * project context (component library + CSS framework + build tool) by * the dispatch site BEFORE the sub-agent's task body is composed so * the RD/UI sub-agent sees the library-first directive in-context. * * - `undefined` → no project-stack block (legacy callers unchanged). * - `null` → the project has no detected component library; the * composer renders nothing (byte-identical degradation). * - `string` → the block, rendered verbatim between the codegraph * block and the memory/task content. */ projectStackBlock?: string | null; /** * `## Fresh context` block (≤5 binding directives from a Context7 → * WebSearch preflight), read from `.peaks/_runtime//fresh-context.md`. * * - `undefined` → no fresh-context block (legacy callers unchanged). * - `null` → the block is unavailable (missing file / no `## Fresh context` * heading); the composer renders nothing (byte-identical degradation). * - `string` → the block, rendered verbatim after the project-stack block * and before the memory/task content. */ freshContextBlock?: string | null; /** * published by the orchestrator through `peaks sub-agent share`. * * - `undefined` / `null` → no capsule pointer, no precedence line * (byte-identical legacy prompt). * - `{ batchId, key, bytes }` → a `shared-read` pointer plus the * mandatory precedence line: the capsule is ADVISORY BACKGROUND only * and the task spec wins on conflict. Nothing the sub-agent must act * on may live only in the capsule. */ capsule?: { readonly batchId: string; readonly key: string; readonly bytes: number; } | null; } /** * defence. The block below is prepended to every sub-agent dispatch system * prompt so the LLM sees the superpowers-chain refusal BEFORE any task * content. The block mirrors the prose in * `skills/bee/peaks-rd/references/rd-sub-agent-dispatch.md` (and the * corresponding peaks-qa / peaks-ui templates); all 4 surfaces MUST stay * in lockstep — drift between them is the failure mode this slice closes. * * Why this lives here (and not just in markdown): * - The dispatch composer is the ONE place every dispatch prompt passes * through. Adding the block here guarantees coverage even when the * orchestrator synthesizes a prompt without reading the per-role * template (the orchestrator may run peaks-rd on a different rid and * reuse the task body verbatim). * trivially testable. * * fallback path is the command the auth-grant CLI declares: * `peaks worktree auth grant --operation --reason `. */ export declare const L1_WORKTREE_GOVERNANCE_BLOCK = "## Superpowers chain refusal (L1 worktree governance \u2014 locked 2026-07-29)\n\nYou MUST NOT follow the superpowers chain for worktree decisions:\n\n- superpowers:brainstorming \u2192 superpowers:writing-plans \u2192\n superpowers:subagent-driven-development \u2192 superpowers:using-git-worktrees\n\nThat chain ends with `git worktree add` (superpowers:using-git-worktrees SKILL.md line 96), which bypasses peaks-loop's L2 hook gate and L3 IDE `permissions.deny`. L3 denial is NOT sufficient \u2014 by then the chain has already taught raw `git worktree add`.\n\nFor worktree operations, use ONLY:\n\n- `peaks worktree spawn --rid --role --purpose ` (after rid-L2-extended ships)\n- until then: `peaks worktree auth grant --operation --reason ` (``, e.g. `git-worktree` | `agent-isolation-worktree`)\n\nSuperpowers skills remain REFERENCE material for brainstorming / planning techniques, but MUST NOT be used as a workflow. peaks-rd's own PRD/RD artifacts (`.peaks/_runtime//rd/requests/.md`) are authoritative.\n\nIf the upstream superpowers chain suggests raw `git worktree add`:\n\n1. STOP\n2. Re-author the plan as a peaks-rd artifact\n3. Continue with the `spawn` command above (or the auth-grant fallback)\n"; /** * system prompt gains three lifecycle rules. The sub-agent must: * * 1. Register any long-lived local process it starts (vite dev, * mock API, docker proxy, etc.) with * `peaks sub-agent shutdown register --pid --name