@syntesseraai/opencode-feature-factory 0.6.20 → 0.7.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.
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Response parsers that extract structured data from LLM text output.
3
+ *
4
+ * These are intentionally tolerant — they fall back to raw text when
5
+ * structured sections cannot be found. The gate evaluators work on
6
+ * the parsed numbers/booleans, not on freeform text.
7
+ */
8
+ // ---------------------------------------------------------------------------
9
+ // Generic helpers
10
+ // ---------------------------------------------------------------------------
11
+ /** Extract the first integer found after a label in the text. */
12
+ export function extractNumber(text, label, fallback = 0) {
13
+ // Try patterns like "CONSENSUS_SCORE: 85", "confidence: 92", "CONFIDENCE=95"
14
+ const patterns = [
15
+ new RegExp(`${label}[=:\\s]+([0-9]+)`, 'i'),
16
+ new RegExp(`${label}[^0-9]*([0-9]+)`, 'i'),
17
+ ];
18
+ for (const re of patterns) {
19
+ const m = text.match(re);
20
+ if (m)
21
+ return parseInt(m[1], 10);
22
+ }
23
+ return fallback;
24
+ }
25
+ /** Extract text between two section headers (markdown-style). */
26
+ export function extractSection(text, heading) {
27
+ // Try numbered list style: "1. HEADING" or "## HEADING" or "**HEADING**"
28
+ const patterns = [
29
+ new RegExp(`(?:^|\\n)(?:\\d+\\.\\s*)?\\*{0,2}${heading}\\*{0,2}[:\\s]*\\n([\\s\\S]*?)(?=\\n(?:\\d+\\.\\s*)?\\*{0,2}[A-Z_]+|$)`, 'i'),
30
+ new RegExp(`(?:^|\\n)#{1,3}\\s*${heading}[:\\s]*\\n([\\s\\S]*?)(?=\\n#{1,3}\\s|$)`, 'i'),
31
+ ];
32
+ for (const re of patterns) {
33
+ const m = text.match(re);
34
+ if (m)
35
+ return m[1].trim();
36
+ }
37
+ return '';
38
+ }
39
+ /** Check if a YES/NO field is YES. */
40
+ export function isYes(text, label) {
41
+ const m = text.match(new RegExp(`${label}[=:\\s]*(YES|NO)`, 'i'));
42
+ return m ? m[1].toUpperCase() === 'YES' : false;
43
+ }
44
+ // ---------------------------------------------------------------------------
45
+ // Planning parsers
46
+ // ---------------------------------------------------------------------------
47
+ export function parsePlanProposal(tag, raw) {
48
+ return {
49
+ tag,
50
+ requirementsSummary: extractSection(raw, 'REQUIREMENTS_SUMMARY') || raw.slice(0, 200),
51
+ architectureValidation: extractSection(raw, 'ARCHITECTURE_VALIDATION'),
52
+ implementationSteps: extractSection(raw, 'IMPLEMENTATION_STEPS'),
53
+ risksAndMitigations: extractSection(raw, 'RISKS_AND_MITIGATIONS'),
54
+ testingStrategy: extractSection(raw, 'TESTING_AND_VALIDATION_STRATEGY'),
55
+ raw,
56
+ };
57
+ }
58
+ export function parseConsensusPlan(raw) {
59
+ return {
60
+ consensusScore: extractNumber(raw, 'CONSENSUS_SCORE'),
61
+ agreedElements: extractSection(raw, 'AGREED_ELEMENTS'),
62
+ divergentElements: extractSection(raw, 'DIVERGENT_ELEMENTS'),
63
+ synthesizedPlan: extractSection(raw, 'SYNTHESIZED_PLAN'),
64
+ openQuestions: extractSection(raw, 'OPEN_QUESTIONS'),
65
+ raw,
66
+ };
67
+ }
68
+ // ---------------------------------------------------------------------------
69
+ // Review parsers
70
+ // ---------------------------------------------------------------------------
71
+ export function parseReviewReport(tag, raw) {
72
+ return {
73
+ tag,
74
+ findings: raw,
75
+ confidence: extractNumber(raw, 'confidence'),
76
+ raw,
77
+ };
78
+ }
79
+ export function parseReviewSynthesis(raw) {
80
+ const confidence = extractNumber(raw, 'confidence');
81
+ const unresolvedIssues = extractNumber(raw, 'unresolved');
82
+ const verdictMatch = raw.match(/verdict[=:\s]*(APPROVED|REWORK_REQUIRED)/i);
83
+ const verdict = (verdictMatch?.[1]?.toUpperCase() === 'APPROVED' ? 'APPROVED' : 'REWORK_REQUIRED');
84
+ const reworkSection = extractSection(raw, 'rework');
85
+ return {
86
+ overallConfidence: confidence,
87
+ consolidatedFindings: raw,
88
+ unresolvedIssues,
89
+ verdict,
90
+ reworkInstructions: reworkSection || undefined,
91
+ raw,
92
+ };
93
+ }
94
+ // ---------------------------------------------------------------------------
95
+ // Doc parsers
96
+ // ---------------------------------------------------------------------------
97
+ export function parseDocUpdate(raw) {
98
+ return {
99
+ filesChanged: [], // The LLM lists these in the raw text; we keep the raw for the gate
100
+ rationale: raw,
101
+ raw,
102
+ };
103
+ }
104
+ export function parseDocReview(raw) {
105
+ const confidence = extractNumber(raw, 'confidence');
106
+ const unresolvedIssues = extractNumber(raw, 'unresolved');
107
+ const verdictMatch = raw.match(/verdict[=:\s]*(APPROVED|REWORK_REQUIRED)/i);
108
+ const verdict = (verdictMatch?.[1]?.toUpperCase() === 'APPROVED' ? 'APPROVED' : 'REWORK_REQUIRED');
109
+ const reworkSection = extractSection(raw, 'rework');
110
+ return {
111
+ verdict,
112
+ unresolvedIssues,
113
+ confidence,
114
+ reworkInstructions: reworkSection || undefined,
115
+ raw,
116
+ };
117
+ }
118
+ // ---------------------------------------------------------------------------
119
+ // Implementation parsers
120
+ // ---------------------------------------------------------------------------
121
+ export function parseImplementationReport(raw) {
122
+ return {
123
+ filesChanged: [],
124
+ testsRun: [],
125
+ testsPassed: !raw.toLowerCase().includes('failed'),
126
+ openIssues: [],
127
+ raw,
128
+ };
129
+ }
130
+ // ---------------------------------------------------------------------------
131
+ // Mini-loop review parser
132
+ // ---------------------------------------------------------------------------
133
+ export function parseMiniReview(raw) {
134
+ return {
135
+ confidence: extractNumber(raw, 'CONFIDENCE'),
136
+ changeRequested: isYes(raw, 'CHANGE_REQUESTED'),
137
+ unresolvedIssues: extractNumber(raw, 'UNRESOLVED_BLOCKING_ISSUES') ||
138
+ extractNumber(raw, 'UNRESOLVED_DOCUMENTATION_ISSUES'),
139
+ reworkInstructions: extractSection(raw, 'rework') || undefined,
140
+ raw,
141
+ };
142
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * ff_pipeline — Full plan → build → review → document workflow tool.
3
+ *
4
+ * This is an entrypoint tool exposed to the LLM. It orchestrates the
5
+ * complete Feature Factory pipeline using deterministic control flow
6
+ * (TypeScript loops and gates) while delegating creative work to
7
+ * model-specific prompts via the SDK client.
8
+ */
9
+ import { type Client } from '../workflow/orchestrator.js';
10
+ export declare function createPipelineTool(client: Client): {
11
+ description: string;
12
+ args: {
13
+ requirements: import("zod").ZodString;
14
+ planning_models: import("zod").ZodOptional<import("zod").ZodString>;
15
+ review_models: import("zod").ZodOptional<import("zod").ZodString>;
16
+ orchestrator_model: import("zod").ZodOptional<import("zod").ZodString>;
17
+ build_model: import("zod").ZodOptional<import("zod").ZodString>;
18
+ validate_model: import("zod").ZodOptional<import("zod").ZodString>;
19
+ doc_model: import("zod").ZodOptional<import("zod").ZodString>;
20
+ doc_review_model: import("zod").ZodOptional<import("zod").ZodString>;
21
+ };
22
+ execute(args: {
23
+ requirements: string;
24
+ planning_models?: string | undefined;
25
+ review_models?: string | undefined;
26
+ orchestrator_model?: string | undefined;
27
+ build_model?: string | undefined;
28
+ validate_model?: string | undefined;
29
+ doc_model?: string | undefined;
30
+ doc_review_model?: string | undefined;
31
+ }, context: import("@opencode-ai/plugin/tool").ToolContext): Promise<string>;
32
+ };
@@ -0,0 +1,227 @@
1
+ /**
2
+ * ff_pipeline — Full plan → build → review → document workflow tool.
3
+ *
4
+ * This is an entrypoint tool exposed to the LLM. It orchestrates the
5
+ * complete Feature Factory pipeline using deterministic control flow
6
+ * (TypeScript loops and gates) while delegating creative work to
7
+ * model-specific prompts via the SDK client.
8
+ */
9
+ import { tool } from '@opencode-ai/plugin/tool';
10
+ import { fanOut, promptSession, evaluatePlanningGate, evaluateReviewGate, evaluateDocGate, PLANNING_MODELS, REVIEW_MODELS, ORCHESTRATOR_MODEL, BUILD_MODEL, DOC_MODEL, VALIDATE_MODEL, DOC_REVIEW_MODEL, parseModelString, parseNamedModels, } from '../workflow/orchestrator.js';
11
+ import { planningPrompt, synthesisPrompt, breakdownPrompt, validateBatchPrompt, implementBatchPrompt, triagePrompt, reviewPrompt, reviewSynthesisPrompt, documentPrompt, docReviewPrompt, } from './prompts.js';
12
+ import { parseConsensusPlan, parseReviewSynthesis, parseImplementationReport, parseDocReview, } from './parsers.js';
13
+ // ---------------------------------------------------------------------------
14
+ // Tool factory — needs the SDK client from plugin init
15
+ // ---------------------------------------------------------------------------
16
+ export function createPipelineTool(client) {
17
+ return tool({
18
+ description: 'Run the full Feature Factory pipeline: multi-model planning → build → review → documentation. ' +
19
+ 'Returns a structured completion report. All model parameters are optional and use sensible defaults.',
20
+ args: {
21
+ requirements: tool.schema
22
+ .string()
23
+ .describe('The feature requirements or task description to implement'),
24
+ planning_models: tool.schema
25
+ .string()
26
+ .optional()
27
+ .describe('Comma-separated list of tag:provider/model for planning fan-out. ' +
28
+ 'Example: "opus:anthropic/claude-opus-4-6, gemini:google/gemini-2.5-pro". ' +
29
+ 'Defaults to opus + gemini + codex.'),
30
+ review_models: tool.schema
31
+ .string()
32
+ .optional()
33
+ .describe('Comma-separated list of tag:provider/model for review fan-out. ' +
34
+ 'Defaults to the same models as planning_models.'),
35
+ orchestrator_model: tool.schema
36
+ .string()
37
+ .optional()
38
+ .describe('provider/model for synthesis and triage steps. Defaults to openai/gpt-5.4.'),
39
+ build_model: tool.schema
40
+ .string()
41
+ .optional()
42
+ .describe('provider/model for building and implementation. Defaults to openai/gpt-5.3-codex.'),
43
+ validate_model: tool.schema
44
+ .string()
45
+ .optional()
46
+ .describe('provider/model for batch validation. Defaults to opencode/gemini-3.1-pro.'),
47
+ doc_model: tool.schema
48
+ .string()
49
+ .optional()
50
+ .describe('provider/model for documentation writing. Defaults to the build model.'),
51
+ doc_review_model: tool.schema
52
+ .string()
53
+ .optional()
54
+ .describe('provider/model for documentation review. Defaults to the validate model.'),
55
+ },
56
+ async execute(args, context) {
57
+ const sessionId = context.sessionID;
58
+ const { requirements } = args;
59
+ // Resolve models — use provided overrides or fall back to defaults
60
+ const planModels = args.planning_models
61
+ ? parseNamedModels(args.planning_models)
62
+ : PLANNING_MODELS;
63
+ const revModels = args.review_models
64
+ ? parseNamedModels(args.review_models)
65
+ : args.planning_models
66
+ ? planModels
67
+ : REVIEW_MODELS;
68
+ const orchestratorModel = args.orchestrator_model
69
+ ? parseModelString(args.orchestrator_model)
70
+ : ORCHESTRATOR_MODEL;
71
+ const buildModel = args.build_model
72
+ ? parseModelString(args.build_model)
73
+ : BUILD_MODEL;
74
+ const validateModel = args.validate_model
75
+ ? parseModelString(args.validate_model)
76
+ : VALIDATE_MODEL;
77
+ const docModel = args.doc_model
78
+ ? parseModelString(args.doc_model)
79
+ : args.build_model
80
+ ? buildModel
81
+ : DOC_MODEL;
82
+ const docReviewModel = args.doc_review_model
83
+ ? parseModelString(args.doc_review_model)
84
+ : args.validate_model
85
+ ? validateModel
86
+ : DOC_REVIEW_MODEL;
87
+ const report = [];
88
+ const addReport = (phase, msg) => {
89
+ report.push(`## ${phase}\n${msg}`);
90
+ };
91
+ // ===================================================================
92
+ // PHASE 1: PLANNING (fan-out → synthesize → gate, loop up to 5)
93
+ // ===================================================================
94
+ let planningGate = { decision: 'REWORK', feedback: requirements };
95
+ let finalPlan = '';
96
+ for (let planIter = 0; planIter < 5 && planningGate.decision === 'REWORK'; planIter++) {
97
+ const planInput = planIter === 0
98
+ ? requirements
99
+ : `${requirements}\n\nPrevious feedback:\n${planningGate.feedback}`;
100
+ // Fan-out: N models plan in parallel
101
+ const fanOutResults = await fanOut(client, sessionId, planModels, (tag) => planningPrompt(planInput, tag), 'planning');
102
+ // Synthesize consensus
103
+ const synthesisRaw = await promptSession(client, sessionId, synthesisPrompt(fanOutResults), {
104
+ model: orchestratorModel,
105
+ agent: 'planning',
106
+ title: `ff-plan-synthesis-${planIter + 1}`,
107
+ });
108
+ const consensus = parseConsensusPlan(synthesisRaw);
109
+ // Gate (deterministic)
110
+ planningGate = evaluatePlanningGate(consensus);
111
+ if (planningGate.decision === 'APPROVED') {
112
+ finalPlan = consensus.synthesizedPlan || synthesisRaw;
113
+ addReport('Planning', `APPROVED (score: ${consensus.consensusScore}, iteration: ${planIter + 1})`);
114
+ }
115
+ else if (planningGate.decision === 'BLOCKED') {
116
+ addReport('Planning', `BLOCKED: ${planningGate.reason}`);
117
+ return report.join('\n\n');
118
+ }
119
+ // REWORK continues the loop
120
+ }
121
+ if (planningGate.decision !== 'APPROVED') {
122
+ addReport('Planning', `REWORK exhausted (5 iterations). Last feedback:\n${planningGate.feedback}`);
123
+ return report.join('\n\n');
124
+ }
125
+ // ===================================================================
126
+ // PHASE 2: BUILDING (breakdown → validate → implement)
127
+ // ===================================================================
128
+ // Breakdown
129
+ const tasksRaw = await promptSession(client, sessionId, breakdownPrompt(finalPlan), {
130
+ model: buildModel,
131
+ agent: 'building',
132
+ title: 'ff-build-breakdown',
133
+ });
134
+ // Validate batches
135
+ const batchesRaw = await promptSession(client, sessionId, validateBatchPrompt(tasksRaw), {
136
+ model: validateModel,
137
+ agent: 'building',
138
+ title: 'ff-build-validate',
139
+ });
140
+ // Implement
141
+ const implRaw = await promptSession(client, sessionId, implementBatchPrompt(batchesRaw), {
142
+ model: buildModel,
143
+ agent: 'building',
144
+ title: 'ff-build-implement',
145
+ });
146
+ const implementation = parseImplementationReport(implRaw);
147
+ addReport('Building', `Implementation completed. Tests passed: ${implementation.testsPassed}`);
148
+ // ===================================================================
149
+ // PHASE 3: REVIEWING (triage → fan-out review → synthesize → gate, loop up to 10)
150
+ // ===================================================================
151
+ let reviewInput = implRaw;
152
+ let reviewGate = { decision: 'REWORK' };
153
+ for (let revIter = 0; revIter < 10 && reviewGate.decision === 'REWORK'; revIter++) {
154
+ // Triage
155
+ const brief = await promptSession(client, sessionId, triagePrompt(reviewInput), {
156
+ model: orchestratorModel,
157
+ agent: 'reviewing',
158
+ title: `ff-review-triage-${revIter + 1}`,
159
+ });
160
+ // Fan-out review
161
+ const reviewResults = await fanOut(client, sessionId, revModels, (tag) => reviewPrompt(brief, tag), 'reviewing');
162
+ // Synthesize
163
+ const synthRaw = await promptSession(client, sessionId, reviewSynthesisPrompt(reviewResults), {
164
+ model: orchestratorModel,
165
+ agent: 'reviewing',
166
+ title: `ff-review-synthesis-${revIter + 1}`,
167
+ });
168
+ const synthesis = parseReviewSynthesis(synthRaw);
169
+ // Gate (deterministic)
170
+ reviewGate = evaluateReviewGate(synthesis, revIter + 1);
171
+ if (reviewGate.decision === 'APPROVED') {
172
+ addReport('Reviewing', `APPROVED (confidence: ${synthesis.overallConfidence}, iteration: ${revIter + 1})`);
173
+ }
174
+ else if (reviewGate.decision === 'ESCALATE') {
175
+ addReport('Reviewing', `ESCALATE: ${reviewGate.reason}`);
176
+ return report.join('\n\n');
177
+ }
178
+ else {
179
+ // REWORK — apply fixes, then re-review
180
+ const fixRaw = await promptSession(client, sessionId, implementBatchPrompt(`Rework required:\n${reviewGate.feedback}\n\nOriginal batches:\n${batchesRaw}`), { model: buildModel, agent: 'building', title: `ff-review-rework-${revIter + 1}` });
181
+ reviewInput = fixRaw;
182
+ }
183
+ }
184
+ if (reviewGate.decision !== 'APPROVED') {
185
+ addReport('Reviewing', `REWORK exhausted (10 iterations). Last feedback:\n${reviewGate.feedback}`);
186
+ return report.join('\n\n');
187
+ }
188
+ // ===================================================================
189
+ // PHASE 4: DOCUMENTATION (document → review → gate, loop up to 5)
190
+ // ===================================================================
191
+ let docInput = `Implementation report:\n${implRaw}\n\nReview synthesis:\n${reviewInput}`;
192
+ let docGate = { decision: 'REWORK' };
193
+ for (let docIter = 0; docIter < 5 && docGate.decision === 'REWORK'; docIter++) {
194
+ // Write docs
195
+ const docRaw = await promptSession(client, sessionId, documentPrompt(docInput), {
196
+ model: docModel,
197
+ agent: 'documenting',
198
+ title: `ff-doc-write-${docIter + 1}`,
199
+ });
200
+ // Review docs
201
+ const docRevRaw = await promptSession(client, sessionId, docReviewPrompt(docRaw), {
202
+ model: docReviewModel,
203
+ agent: 'reviewing',
204
+ title: `ff-doc-review-${docIter + 1}`,
205
+ });
206
+ const docReview = parseDocReview(docRevRaw);
207
+ // Gate (deterministic)
208
+ docGate = evaluateDocGate(docReview, docIter + 1);
209
+ if (docGate.decision === 'APPROVED') {
210
+ addReport('Documentation', `APPROVED (confidence: ${docReview.confidence}, iteration: ${docIter + 1})`);
211
+ }
212
+ else if (docGate.decision === 'ESCALATE') {
213
+ addReport('Documentation', `ESCALATE: ${docGate.reason}`);
214
+ }
215
+ else {
216
+ // Feed feedback into the next iteration
217
+ docInput = `${docInput}\n\nDocumentation review feedback:\n${docGate.feedback}`;
218
+ }
219
+ }
220
+ // ===================================================================
221
+ // FINAL REPORT
222
+ // ===================================================================
223
+ addReport('Complete', 'Pipeline finished.');
224
+ return report.join('\n\n');
225
+ },
226
+ });
227
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Prompt templates for workflow tools.
3
+ *
4
+ * Centralised here so that tools stay lean and prompts are easy to review
5
+ * and tune independently.
6
+ */
7
+ export declare function planningPrompt(requirements: string, modelTag: string): string;
8
+ export declare function synthesisPrompt(proposals: Array<{
9
+ tag: string;
10
+ raw: string;
11
+ }>): string;
12
+ export declare function breakdownPrompt(finalPlan: string): string;
13
+ export declare function validateBatchPrompt(tasks: string): string;
14
+ export declare function implementBatchPrompt(batches: string): string;
15
+ export declare function triagePrompt(implementationReport: string): string;
16
+ export declare function reviewPrompt(brief: string, modelTag: string): string;
17
+ export declare function reviewSynthesisPrompt(reviews: Array<{
18
+ tag: string;
19
+ raw: string;
20
+ }>): string;
21
+ export declare function documentPrompt(input: string): string;
22
+ export declare function docReviewPrompt(docUpdate: string): string;
23
+ export declare function miniBuildPrompt(requirements: string, reworkFeedback?: string): string;
24
+ export declare function miniReviewPrompt(implementationReport: string): string;
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Prompt templates for workflow tools.
3
+ *
4
+ * Centralised here so that tools stay lean and prompts are easy to review
5
+ * and tune independently.
6
+ */
7
+ // ---------------------------------------------------------------------------
8
+ // Planning
9
+ // ---------------------------------------------------------------------------
10
+ export function planningPrompt(requirements, modelTag) {
11
+ return `[MODEL_TAG:${modelTag}]
12
+
13
+ Create a comprehensive implementation plan from the requirements below.
14
+
15
+ Requirements:
16
+ ${requirements}
17
+
18
+ Return a structured proposal with these sections:
19
+
20
+ 1. REQUIREMENTS_SUMMARY
21
+ 2. ARCHITECTURE_VALIDATION
22
+ 3. IMPLEMENTATION_STEPS
23
+ 4. RISKS_AND_MITIGATIONS
24
+ 5. TESTING_AND_VALIDATION_STRATEGY`;
25
+ }
26
+ export function synthesisPrompt(proposals) {
27
+ const formatted = proposals.map((p) => `--- ${p.tag} ---\n${p.raw}`).join('\n\n');
28
+ return `Synthesize the following model planning outputs into a consensus report.
29
+
30
+ ${formatted}
31
+
32
+ Produce a consensus report with these sections:
33
+
34
+ 1. CONSENSUS_SCORE (0-100)
35
+ 2. AGREED_ELEMENTS
36
+ 3. DIVERGENT_ELEMENTS
37
+ 4. SYNTHESIZED_PLAN
38
+ 5. OPEN_QUESTIONS`;
39
+ }
40
+ // ---------------------------------------------------------------------------
41
+ // Building
42
+ // ---------------------------------------------------------------------------
43
+ export function breakdownPrompt(finalPlan) {
44
+ return `Read the approved final plan below and produce atomic tasks.
45
+
46
+ ${finalPlan}
47
+
48
+ Each task must include:
49
+ - task id
50
+ - title and description
51
+ - target files
52
+ - dependencies
53
+ - acceptance criteria
54
+
55
+ Return structured TASKS output.`;
56
+ }
57
+ export function validateBatchPrompt(tasks) {
58
+ return `Read the TASKS input below and create dependency-safe batches.
59
+
60
+ ${tasks}
61
+
62
+ For each batch:
63
+ 1. validate architecture and codebase fit
64
+ 2. confirm or adjust file targets
65
+ 3. flag architectural risks
66
+ 4. mark whether tasks can run in parallel
67
+
68
+ Return structured BATCHES output.`;
69
+ }
70
+ export function implementBatchPrompt(batches) {
71
+ return `Read the BATCHES input below and implement each batch.
72
+
73
+ ${batches}
74
+
75
+ Execution strategy:
76
+ 1. Process batches in dependency order.
77
+ 2. Within each batch, implement tasks that have no mutual dependency edges.
78
+ 3. Tasks that share file targets or have explicit dependency edges must run sequentially.
79
+ 4. Wait for all tasks in a batch to complete before starting the next batch.
80
+
81
+ For each task:
82
+ 1. implement code changes
83
+ 2. add/update tests
84
+ 3. run lint/typecheck/tests for impacted scope
85
+ 4. return a structured completion report
86
+
87
+ After all batches complete, merge the per-task completion reports into a single IMPLEMENTATION_REPORT output.`;
88
+ }
89
+ // ---------------------------------------------------------------------------
90
+ // Reviewing
91
+ // ---------------------------------------------------------------------------
92
+ export function triagePrompt(implementationReport) {
93
+ return `Prepare a review brief for the completed implementation.
94
+
95
+ ${implementationReport}
96
+
97
+ Include:
98
+ - summary of implemented changes
99
+ - files changed
100
+ - focus areas and risk points
101
+
102
+ Return a structured REVIEW_BRIEF output.`;
103
+ }
104
+ export function reviewPrompt(brief, modelTag) {
105
+ return `[MODEL_TAG:${modelTag}]
106
+
107
+ Review the current task from the triage brief below for correctness, quality, architecture validity, testing, security, and edge cases.
108
+
109
+ ${brief}
110
+
111
+ Classify findings as critical/high/medium/low and include a confidence score (0-100).
112
+
113
+ Return a structured review report.`;
114
+ }
115
+ export function reviewSynthesisPrompt(reviews) {
116
+ const formatted = reviews.map((r) => `--- ${r.tag} ---\n${r.raw}`).join('\n\n');
117
+ return `Read the three review inputs below and synthesize a single authoritative output.
118
+
119
+ ${formatted}
120
+
121
+ Required output:
122
+ 1. overall confidence (0-100)
123
+ 2. consolidated deduplicated findings
124
+ 3. unresolved issues list (count)
125
+ 4. verdict APPROVED or REWORK_REQUIRED
126
+ 5. explicit rework instructions when needed`;
127
+ }
128
+ // ---------------------------------------------------------------------------
129
+ // Documentation
130
+ // ---------------------------------------------------------------------------
131
+ export function documentPrompt(input) {
132
+ return `Document the approved code changes and update repository documentation.
133
+
134
+ ${input}
135
+
136
+ Requirements:
137
+ 1. Use the latest approved review outputs and implementation artifacts as source of truth.
138
+ 2. Update all affected docs so behavior and operational steps match shipped code.
139
+ 3. If this is a rework iteration, incorporate documentation reviewer feedback from the previous documentation review.
140
+ 4. Summarize what docs were changed and why.
141
+
142
+ Return a structured documentation update summary.`;
143
+ }
144
+ export function docReviewPrompt(docUpdate) {
145
+ return `Review the latest documentation pass for completeness, correctness, and repository doc consistency.
146
+
147
+ ${docUpdate}
148
+
149
+ Required output:
150
+ 1. verdict APPROVED or REWORK_REQUIRED
151
+ 2. unresolved documentation issues (count, integer)
152
+ 3. explicit rework instructions
153
+ 4. confidence score (0-100)`;
154
+ }
155
+ // ---------------------------------------------------------------------------
156
+ // Mini-loop specific
157
+ // ---------------------------------------------------------------------------
158
+ export function miniBuildPrompt(requirements, reworkFeedback) {
159
+ const rework = reworkFeedback
160
+ ? `\n\nPrevious review feedback to address:\n${reworkFeedback}`
161
+ : '';
162
+ return `Implement the current mini-loop requirements below.
163
+
164
+ ${requirements}${rework}
165
+
166
+ Requirements:
167
+ 1. Apply requested code rework when present.
168
+ 2. Add or update tests for behavioral changes.
169
+ 3. Run lint/typecheck/tests only for impacted scope.
170
+ 4. Return a concise implementation report with changed files, tests run, and known open issues.`;
171
+ }
172
+ export function miniReviewPrompt(implementationReport) {
173
+ return `Review the latest mini-loop implementation output below.
174
+
175
+ ${implementationReport}
176
+
177
+ Required output fields:
178
+ 1. CHANGE_REQUESTED=YES|NO
179
+ 2. UNRESOLVED_BLOCKING_ISSUES=<integer>
180
+ 3. CONFIDENCE=<0-100>
181
+ 4. concise rework instructions when change is requested`;
182
+ }