forge-cc 0.1.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.
- package/.forge.json +5 -0
- package/AGENTS.md +42 -0
- package/README.md +283 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +148 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/loader.d.ts +2 -0
- package/dist/config/loader.js +44 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +57 -0
- package/dist/config/schema.js +15 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/gates/index.d.ts +11 -0
- package/dist/gates/index.js +106 -0
- package/dist/gates/index.js.map +1 -0
- package/dist/gates/lint-gate.d.ts +2 -0
- package/dist/gates/lint-gate.js +66 -0
- package/dist/gates/lint-gate.js.map +1 -0
- package/dist/gates/prd-gate.d.ts +7 -0
- package/dist/gates/prd-gate.js +193 -0
- package/dist/gates/prd-gate.js.map +1 -0
- package/dist/gates/runtime-gate.d.ts +5 -0
- package/dist/gates/runtime-gate.js +99 -0
- package/dist/gates/runtime-gate.js.map +1 -0
- package/dist/gates/tests-gate.d.ts +2 -0
- package/dist/gates/tests-gate.js +116 -0
- package/dist/gates/tests-gate.js.map +1 -0
- package/dist/gates/types-gate.d.ts +2 -0
- package/dist/gates/types-gate.js +59 -0
- package/dist/gates/types-gate.js.map +1 -0
- package/dist/gates/visual-gate.d.ts +6 -0
- package/dist/gates/visual-gate.js +118 -0
- package/dist/gates/visual-gate.js.map +1 -0
- package/dist/go/auto-chain.d.ts +107 -0
- package/dist/go/auto-chain.js +303 -0
- package/dist/go/auto-chain.js.map +1 -0
- package/dist/go/executor.d.ts +130 -0
- package/dist/go/executor.js +409 -0
- package/dist/go/executor.js.map +1 -0
- package/dist/go/finalize.d.ts +58 -0
- package/dist/go/finalize.js +200 -0
- package/dist/go/finalize.js.map +1 -0
- package/dist/go/linear-sync.d.ts +75 -0
- package/dist/go/linear-sync.js +239 -0
- package/dist/go/linear-sync.js.map +1 -0
- package/dist/go/verify-loop.d.ts +47 -0
- package/dist/go/verify-loop.js +172 -0
- package/dist/go/verify-loop.js.map +1 -0
- package/dist/hooks/pre-commit.d.ts +5 -0
- package/dist/hooks/pre-commit.js +69 -0
- package/dist/hooks/pre-commit.js.map +1 -0
- package/dist/linear/client.d.ts +108 -0
- package/dist/linear/client.js +388 -0
- package/dist/linear/client.js.map +1 -0
- package/dist/linear/issues.d.ts +20 -0
- package/dist/linear/issues.js +39 -0
- package/dist/linear/issues.js.map +1 -0
- package/dist/linear/milestones.d.ts +11 -0
- package/dist/linear/milestones.js +32 -0
- package/dist/linear/milestones.js.map +1 -0
- package/dist/linear/projects.d.ts +16 -0
- package/dist/linear/projects.js +50 -0
- package/dist/linear/projects.js.map +1 -0
- package/dist/reporter/human.d.ts +2 -0
- package/dist/reporter/human.js +63 -0
- package/dist/reporter/human.js.map +1 -0
- package/dist/reporter/json.d.ts +2 -0
- package/dist/reporter/json.js +4 -0
- package/dist/reporter/json.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +109 -0
- package/dist/server.js.map +1 -0
- package/dist/spec/generator.d.ts +14 -0
- package/dist/spec/generator.js +206 -0
- package/dist/spec/generator.js.map +1 -0
- package/dist/spec/interview.d.ts +104 -0
- package/dist/spec/interview.js +342 -0
- package/dist/spec/interview.js.map +1 -0
- package/dist/spec/linear-sync.d.ts +48 -0
- package/dist/spec/linear-sync.js +125 -0
- package/dist/spec/linear-sync.js.map +1 -0
- package/dist/spec/scanner.d.ts +45 -0
- package/dist/spec/scanner.js +473 -0
- package/dist/spec/scanner.js.map +1 -0
- package/dist/spec/templates.d.ts +345 -0
- package/dist/spec/templates.js +86 -0
- package/dist/spec/templates.js.map +1 -0
- package/dist/state/reader.d.ts +29 -0
- package/dist/state/reader.js +116 -0
- package/dist/state/reader.js.map +1 -0
- package/dist/state/writer.d.ts +60 -0
- package/dist/state/writer.js +222 -0
- package/dist/state/writer.js.map +1 -0
- package/dist/types.d.ts +64 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/browser.d.ts +10 -0
- package/dist/utils/browser.js +89 -0
- package/dist/utils/browser.js.map +1 -0
- package/hooks/pre-commit-verify.js +103 -0
- package/package.json +68 -0
- package/skills/README.md +33 -0
- package/skills/forge-go.md +332 -0
- package/skills/forge-spec.md +251 -0
- package/skills/forge-triage.md +133 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Milestone Execution Engine
|
|
3
|
+
*
|
|
4
|
+
* Programmatic module that reads a PRD milestone definition, prepares
|
|
5
|
+
* wave-based agent prompts, tracks results, runs verification between
|
|
6
|
+
* waves, and produces structured output.
|
|
7
|
+
*
|
|
8
|
+
* This module does NOT spawn agents — that is the skill file's job
|
|
9
|
+
* (via Claude Code's Task tool). The executor is the data/logic layer.
|
|
10
|
+
*/
|
|
11
|
+
import type { SessionContext } from "../state/reader.js";
|
|
12
|
+
import type { ForgeConfig, PipelineResult } from "../types.js";
|
|
13
|
+
import type { MilestoneWave } from "../spec/templates.js";
|
|
14
|
+
export interface ExecuteMilestoneOptions {
|
|
15
|
+
projectDir: string;
|
|
16
|
+
prdPath: string;
|
|
17
|
+
milestoneNumber: number;
|
|
18
|
+
config: ForgeConfig;
|
|
19
|
+
/** Log prompts but don't run verification (for testing) */
|
|
20
|
+
dryRun?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface AgentPrompt {
|
|
23
|
+
name: string;
|
|
24
|
+
task: string;
|
|
25
|
+
files: string[];
|
|
26
|
+
prompt: string;
|
|
27
|
+
}
|
|
28
|
+
export interface WaveExecution {
|
|
29
|
+
waveNumber: number;
|
|
30
|
+
agents: AgentPrompt[];
|
|
31
|
+
}
|
|
32
|
+
export interface AgentResult {
|
|
33
|
+
name: string;
|
|
34
|
+
task: string;
|
|
35
|
+
success: boolean;
|
|
36
|
+
error?: string;
|
|
37
|
+
filesCreated: string[];
|
|
38
|
+
filesModified: string[];
|
|
39
|
+
}
|
|
40
|
+
export interface WaveResult {
|
|
41
|
+
waveNumber: number;
|
|
42
|
+
agents: AgentResult[];
|
|
43
|
+
verification: PipelineResult | null;
|
|
44
|
+
}
|
|
45
|
+
export interface ExecutionResult {
|
|
46
|
+
milestoneNumber: number;
|
|
47
|
+
milestoneName: string;
|
|
48
|
+
success: boolean;
|
|
49
|
+
waves: WaveResult[];
|
|
50
|
+
totalFilesCreated: number;
|
|
51
|
+
totalFilesModified: number;
|
|
52
|
+
errors: string[];
|
|
53
|
+
}
|
|
54
|
+
export interface MilestoneContext {
|
|
55
|
+
milestoneNumber: number;
|
|
56
|
+
milestoneName: string;
|
|
57
|
+
milestoneGoal: string;
|
|
58
|
+
milestoneSection: string;
|
|
59
|
+
waves: MilestoneWave[];
|
|
60
|
+
verificationCommands: string[];
|
|
61
|
+
sessionContext: SessionContext;
|
|
62
|
+
lessons: string;
|
|
63
|
+
claudeMd: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Build the full context needed to execute a milestone.
|
|
67
|
+
* Reads STATE.md, ROADMAP.md, PRD milestone section, CLAUDE.md, and lessons.
|
|
68
|
+
*/
|
|
69
|
+
export declare function buildMilestoneContext(options: ExecuteMilestoneOptions): Promise<MilestoneContext>;
|
|
70
|
+
/**
|
|
71
|
+
* Build a prompt for a single agent within a milestone wave.
|
|
72
|
+
*
|
|
73
|
+
* The prompt includes:
|
|
74
|
+
* - The agent's specific task and files
|
|
75
|
+
* - Milestone goal and context
|
|
76
|
+
* - Key existing code (inlined, not just paths)
|
|
77
|
+
* - Lessons from tasks/lessons.md
|
|
78
|
+
* - CLAUDE.md rules (abbreviated)
|
|
79
|
+
*/
|
|
80
|
+
export declare function buildAgentPrompt(agent: MilestoneWave["agents"][number], context: MilestoneContext, existingCode?: string): string;
|
|
81
|
+
/**
|
|
82
|
+
* Prepare all waves for execution.
|
|
83
|
+
* Returns structured wave data with agent prompts ready for the skill
|
|
84
|
+
* to pass to Claude Code's Task tool.
|
|
85
|
+
*/
|
|
86
|
+
export declare function prepareWaves(context: MilestoneContext, existingCodeMap?: Map<string, string>): WaveExecution[];
|
|
87
|
+
/**
|
|
88
|
+
* Run forge verification pipeline after a wave completes.
|
|
89
|
+
* Returns the pipeline result with human-readable report.
|
|
90
|
+
*/
|
|
91
|
+
export declare function runWaveVerification(options: ExecuteMilestoneOptions): Promise<PipelineResult>;
|
|
92
|
+
/**
|
|
93
|
+
* Create an empty execution result for a milestone.
|
|
94
|
+
*/
|
|
95
|
+
export declare function createExecutionResult(context: MilestoneContext): ExecutionResult;
|
|
96
|
+
/**
|
|
97
|
+
* Record a completed wave's results into the execution result.
|
|
98
|
+
*/
|
|
99
|
+
export declare function recordWaveResult(execution: ExecutionResult, waveResult: WaveResult): ExecutionResult;
|
|
100
|
+
/**
|
|
101
|
+
* Execute a single milestone end-to-end.
|
|
102
|
+
*
|
|
103
|
+
* In dryRun mode: builds context and prompts, runs no verification, returns
|
|
104
|
+
* the prepared execution plan.
|
|
105
|
+
*
|
|
106
|
+
* In normal mode: the caller (skill file) should use this module's functions
|
|
107
|
+
* step by step:
|
|
108
|
+
* 1. `buildMilestoneContext()` — read PRD and build context
|
|
109
|
+
* 2. `prepareWaves()` — get agent prompts for each wave
|
|
110
|
+
* 3. For each wave: spawn agents, collect results
|
|
111
|
+
* 4. `runWaveVerification()` — verify after each wave
|
|
112
|
+
* 5. `recordWaveResult()` — track results
|
|
113
|
+
*
|
|
114
|
+
* This `executeMilestone` function is the simplified orchestrator for
|
|
115
|
+
* programmatic/testing use. For real execution, the skill drives each step.
|
|
116
|
+
*/
|
|
117
|
+
export declare function executeMilestone(options: ExecuteMilestoneOptions): Promise<{
|
|
118
|
+
context: MilestoneContext;
|
|
119
|
+
waves: WaveExecution[];
|
|
120
|
+
result: ExecutionResult;
|
|
121
|
+
}>;
|
|
122
|
+
/**
|
|
123
|
+
* Format an execution result as a human-readable summary.
|
|
124
|
+
*/
|
|
125
|
+
export declare function formatExecutionSummary(result: ExecutionResult): string;
|
|
126
|
+
/**
|
|
127
|
+
* Format verification errors into a structured prompt for fix agents.
|
|
128
|
+
* Used by the self-healing verify loop.
|
|
129
|
+
*/
|
|
130
|
+
export declare function formatErrorsForFixAgent(verification: PipelineResult): string;
|
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Milestone Execution Engine
|
|
3
|
+
*
|
|
4
|
+
* Programmatic module that reads a PRD milestone definition, prepares
|
|
5
|
+
* wave-based agent prompts, tracks results, runs verification between
|
|
6
|
+
* waves, and produces structured output.
|
|
7
|
+
*
|
|
8
|
+
* This module does NOT spawn agents — that is the skill file's job
|
|
9
|
+
* (via Claude Code's Task tool). The executor is the data/logic layer.
|
|
10
|
+
*/
|
|
11
|
+
import { readFile } from "node:fs/promises";
|
|
12
|
+
import { join } from "node:path";
|
|
13
|
+
import { readSessionContext } from "../state/reader.js";
|
|
14
|
+
import { runPipeline } from "../gates/index.js";
|
|
15
|
+
import { formatHumanReport } from "../reporter/human.js";
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Helpers
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
async function safeRead(filePath) {
|
|
20
|
+
try {
|
|
21
|
+
return await readFile(filePath, "utf-8");
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return "";
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Parse a milestone section from PRD markdown into structured wave data.
|
|
29
|
+
*
|
|
30
|
+
* The PRD milestone section has this structure:
|
|
31
|
+
* ```
|
|
32
|
+
* ### Milestone N: Name
|
|
33
|
+
* **Assigned To:** ...
|
|
34
|
+
* **Goal:** ...
|
|
35
|
+
*
|
|
36
|
+
* **Wave 1 (N agents parallel):**
|
|
37
|
+
* 1. **agent-name**: task description
|
|
38
|
+
* - Files: file1, file2
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* If a structured Milestone object is available (from templates.ts schema),
|
|
42
|
+
* prefer using it directly. This parser handles the markdown fallback.
|
|
43
|
+
*/
|
|
44
|
+
function parseMilestoneSection(section) {
|
|
45
|
+
// Extract milestone name
|
|
46
|
+
const nameMatch = section.match(/###\s*Milestone\s+\d+\s*[:\u2014\u2013-]\s*(.+)/);
|
|
47
|
+
const name = nameMatch ? nameMatch[1].trim() : "Unknown Milestone";
|
|
48
|
+
// Extract goal
|
|
49
|
+
const goalMatch = section.match(/\*\*Goal:\*\*\s*(.+)/);
|
|
50
|
+
const goal = goalMatch ? goalMatch[1].trim() : "";
|
|
51
|
+
// Parse waves
|
|
52
|
+
const waves = [];
|
|
53
|
+
const wavePattern = /\*\*Wave\s+(\d+)\s*[^*]*\*\*:\s*\n([\s\S]*?)(?=\*\*Wave\s+\d+|\*\*Verification|\*\*Acceptance|$)/g;
|
|
54
|
+
let waveMatch;
|
|
55
|
+
while ((waveMatch = wavePattern.exec(section)) !== null) {
|
|
56
|
+
const waveNumber = parseInt(waveMatch[1], 10);
|
|
57
|
+
const waveBody = waveMatch[2];
|
|
58
|
+
const agents = [];
|
|
59
|
+
// Parse agent entries: "1. **agent-name**: task description"
|
|
60
|
+
const agentPattern = /\d+\.\s+\*\*([^*]+)\*\*[:\s]+([^\n]+)\n(?:\s+-\s+(?:Files|Creates|Modifies|Deletes):\s*([^\n]+)\n?)*/g;
|
|
61
|
+
let agentMatch;
|
|
62
|
+
while ((agentMatch = agentPattern.exec(waveBody)) !== null) {
|
|
63
|
+
const agentName = agentMatch[1].trim();
|
|
64
|
+
const agentTask = agentMatch[2].trim();
|
|
65
|
+
// Collect all file references from sub-items
|
|
66
|
+
const files = [];
|
|
67
|
+
const fileLinePattern = /\s+-\s+(?:Files|Creates|Modifies|Deletes):\s*([^\n]+)/g;
|
|
68
|
+
const agentBlock = waveBody.slice(agentMatch.index, agentPattern.lastIndex);
|
|
69
|
+
let fileMatch;
|
|
70
|
+
while ((fileMatch = fileLinePattern.exec(agentBlock)) !== null) {
|
|
71
|
+
const fileList = fileMatch[1]
|
|
72
|
+
.split(",")
|
|
73
|
+
.map((f) => f.trim())
|
|
74
|
+
.filter(Boolean);
|
|
75
|
+
files.push(...fileList);
|
|
76
|
+
}
|
|
77
|
+
agents.push({ name: agentName, task: agentTask, files });
|
|
78
|
+
}
|
|
79
|
+
if (agents.length > 0) {
|
|
80
|
+
waves.push({ waveNumber, agents });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Parse verification commands
|
|
84
|
+
const verificationCommands = [];
|
|
85
|
+
const verifySection = section.match(/\*\*Verification:\*\*\s*\n```(?:bash)?\s*\n([\s\S]*?)```/);
|
|
86
|
+
if (verifySection) {
|
|
87
|
+
const lines = verifySection[1].split("\n");
|
|
88
|
+
for (const line of lines) {
|
|
89
|
+
const trimmed = line.trim();
|
|
90
|
+
if (trimmed && !trimmed.startsWith("#")) {
|
|
91
|
+
verificationCommands.push(trimmed);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return { name, goal, waves, verificationCommands };
|
|
96
|
+
}
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
// Context Building
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
/**
|
|
101
|
+
* Build the full context needed to execute a milestone.
|
|
102
|
+
* Reads STATE.md, ROADMAP.md, PRD milestone section, CLAUDE.md, and lessons.
|
|
103
|
+
*/
|
|
104
|
+
export async function buildMilestoneContext(options) {
|
|
105
|
+
const { projectDir, prdPath, milestoneNumber } = options;
|
|
106
|
+
// Read session context (STATE.md, ROADMAP.md, milestone section)
|
|
107
|
+
const sessionContext = await readSessionContext(projectDir, prdPath, milestoneNumber);
|
|
108
|
+
const milestoneSection = sessionContext.currentMilestoneSection;
|
|
109
|
+
if (!milestoneSection) {
|
|
110
|
+
throw new Error(`Milestone ${milestoneNumber} not found in PRD at ${prdPath}`);
|
|
111
|
+
}
|
|
112
|
+
// Parse the milestone section into structured data
|
|
113
|
+
const parsed = parseMilestoneSection(milestoneSection);
|
|
114
|
+
// Read supporting files
|
|
115
|
+
const [lessons, claudeMd] = await Promise.all([
|
|
116
|
+
safeRead(join(projectDir, "tasks", "lessons.md")),
|
|
117
|
+
safeRead(join(projectDir, "CLAUDE.md")),
|
|
118
|
+
]);
|
|
119
|
+
return {
|
|
120
|
+
milestoneNumber,
|
|
121
|
+
milestoneName: parsed.name,
|
|
122
|
+
milestoneGoal: parsed.goal,
|
|
123
|
+
milestoneSection,
|
|
124
|
+
waves: parsed.waves,
|
|
125
|
+
verificationCommands: parsed.verificationCommands,
|
|
126
|
+
sessionContext,
|
|
127
|
+
lessons,
|
|
128
|
+
claudeMd,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
// Agent Prompt Building
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
/**
|
|
135
|
+
* Build a prompt for a single agent within a milestone wave.
|
|
136
|
+
*
|
|
137
|
+
* The prompt includes:
|
|
138
|
+
* - The agent's specific task and files
|
|
139
|
+
* - Milestone goal and context
|
|
140
|
+
* - Key existing code (inlined, not just paths)
|
|
141
|
+
* - Lessons from tasks/lessons.md
|
|
142
|
+
* - CLAUDE.md rules (abbreviated)
|
|
143
|
+
*/
|
|
144
|
+
export function buildAgentPrompt(agent, context, existingCode) {
|
|
145
|
+
const lines = [];
|
|
146
|
+
// Header
|
|
147
|
+
lines.push(`# Agent: ${agent.name}`);
|
|
148
|
+
lines.push("");
|
|
149
|
+
lines.push(`You are working on **Milestone ${context.milestoneNumber}: ${context.milestoneName}**.`);
|
|
150
|
+
lines.push("");
|
|
151
|
+
lines.push(`**Milestone Goal:** ${context.milestoneGoal}`);
|
|
152
|
+
lines.push("");
|
|
153
|
+
// Agent-specific task
|
|
154
|
+
lines.push("## Your Task");
|
|
155
|
+
lines.push("");
|
|
156
|
+
lines.push(agent.task);
|
|
157
|
+
lines.push("");
|
|
158
|
+
// Files to create/modify
|
|
159
|
+
if (agent.files.length > 0) {
|
|
160
|
+
lines.push("## Files");
|
|
161
|
+
lines.push("");
|
|
162
|
+
for (const file of agent.files) {
|
|
163
|
+
lines.push(`- ${file}`);
|
|
164
|
+
}
|
|
165
|
+
lines.push("");
|
|
166
|
+
}
|
|
167
|
+
// Inline existing code if provided
|
|
168
|
+
if (existingCode) {
|
|
169
|
+
lines.push("## Existing Code (Reference)");
|
|
170
|
+
lines.push("");
|
|
171
|
+
lines.push(existingCode);
|
|
172
|
+
lines.push("");
|
|
173
|
+
}
|
|
174
|
+
// Lessons
|
|
175
|
+
if (context.lessons) {
|
|
176
|
+
lines.push("## Lessons (Follow These)");
|
|
177
|
+
lines.push("");
|
|
178
|
+
lines.push(context.lessons);
|
|
179
|
+
lines.push("");
|
|
180
|
+
}
|
|
181
|
+
// Rules from CLAUDE.md (abbreviated to key rules only)
|
|
182
|
+
if (context.claudeMd) {
|
|
183
|
+
// Extract just the critical rules section if present
|
|
184
|
+
const rulesMatch = context.claudeMd.match(/## Critical Rules\s*\n([\s\S]*?)(?=\n##\s|$)/);
|
|
185
|
+
if (rulesMatch) {
|
|
186
|
+
lines.push("## Rules");
|
|
187
|
+
lines.push("");
|
|
188
|
+
lines.push(rulesMatch[1].trim());
|
|
189
|
+
lines.push("");
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// Verification
|
|
193
|
+
lines.push("## Verification");
|
|
194
|
+
lines.push("");
|
|
195
|
+
lines.push("After completing your work, verify:");
|
|
196
|
+
lines.push("- `npx tsc --noEmit` passes");
|
|
197
|
+
if (context.verificationCommands.length > 0) {
|
|
198
|
+
for (const cmd of context.verificationCommands) {
|
|
199
|
+
lines.push(`- \`${cmd}\``);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
lines.push("");
|
|
203
|
+
// Git rules
|
|
204
|
+
lines.push("## Git Rules");
|
|
205
|
+
lines.push("");
|
|
206
|
+
lines.push("- Stage only the files you created/modified (never use `git add .`)");
|
|
207
|
+
lines.push("- Do not commit — the orchestrator handles commits");
|
|
208
|
+
lines.push("- Use ES module imports with `.js` extension in import paths");
|
|
209
|
+
lines.push("");
|
|
210
|
+
return lines.join("\n");
|
|
211
|
+
}
|
|
212
|
+
// ---------------------------------------------------------------------------
|
|
213
|
+
// Wave Execution Preparation
|
|
214
|
+
// ---------------------------------------------------------------------------
|
|
215
|
+
/**
|
|
216
|
+
* Prepare all waves for execution.
|
|
217
|
+
* Returns structured wave data with agent prompts ready for the skill
|
|
218
|
+
* to pass to Claude Code's Task tool.
|
|
219
|
+
*/
|
|
220
|
+
export function prepareWaves(context, existingCodeMap) {
|
|
221
|
+
return context.waves.map((wave) => ({
|
|
222
|
+
waveNumber: wave.waveNumber,
|
|
223
|
+
agents: wave.agents.map((agent) => ({
|
|
224
|
+
name: agent.name,
|
|
225
|
+
task: agent.task,
|
|
226
|
+
files: agent.files,
|
|
227
|
+
prompt: buildAgentPrompt(agent, context, existingCodeMap?.get(agent.name)),
|
|
228
|
+
})),
|
|
229
|
+
}));
|
|
230
|
+
}
|
|
231
|
+
// ---------------------------------------------------------------------------
|
|
232
|
+
// Verification
|
|
233
|
+
// ---------------------------------------------------------------------------
|
|
234
|
+
/**
|
|
235
|
+
* Run forge verification pipeline after a wave completes.
|
|
236
|
+
* Returns the pipeline result with human-readable report.
|
|
237
|
+
*/
|
|
238
|
+
export async function runWaveVerification(options) {
|
|
239
|
+
const { projectDir, config, prdPath } = options;
|
|
240
|
+
const pipelineInput = {
|
|
241
|
+
projectDir,
|
|
242
|
+
gates: config.gates,
|
|
243
|
+
prdPath: config.prdPath ?? prdPath,
|
|
244
|
+
maxIterations: config.maxIterations,
|
|
245
|
+
devServerCommand: config.devServer?.command,
|
|
246
|
+
devServerPort: config.devServer?.port,
|
|
247
|
+
};
|
|
248
|
+
const result = await runPipeline(pipelineInput);
|
|
249
|
+
// Attach human-readable report
|
|
250
|
+
if (!result.report) {
|
|
251
|
+
result.report = formatHumanReport(result);
|
|
252
|
+
}
|
|
253
|
+
return result;
|
|
254
|
+
}
|
|
255
|
+
// ---------------------------------------------------------------------------
|
|
256
|
+
// Result Tracking
|
|
257
|
+
// ---------------------------------------------------------------------------
|
|
258
|
+
/**
|
|
259
|
+
* Create an empty execution result for a milestone.
|
|
260
|
+
*/
|
|
261
|
+
export function createExecutionResult(context) {
|
|
262
|
+
return {
|
|
263
|
+
milestoneNumber: context.milestoneNumber,
|
|
264
|
+
milestoneName: context.milestoneName,
|
|
265
|
+
success: false,
|
|
266
|
+
waves: [],
|
|
267
|
+
totalFilesCreated: 0,
|
|
268
|
+
totalFilesModified: 0,
|
|
269
|
+
errors: [],
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Record a completed wave's results into the execution result.
|
|
274
|
+
*/
|
|
275
|
+
export function recordWaveResult(execution, waveResult) {
|
|
276
|
+
const updatedWaves = [...execution.waves, waveResult];
|
|
277
|
+
let totalCreated = 0;
|
|
278
|
+
let totalModified = 0;
|
|
279
|
+
const allErrors = [];
|
|
280
|
+
for (const wave of updatedWaves) {
|
|
281
|
+
for (const agent of wave.agents) {
|
|
282
|
+
totalCreated += agent.filesCreated.length;
|
|
283
|
+
totalModified += agent.filesModified.length;
|
|
284
|
+
if (agent.error) {
|
|
285
|
+
allErrors.push(`[${agent.name}] ${agent.error}`);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
if (wave.verification && !wave.verification.passed) {
|
|
289
|
+
const failedGates = wave.verification.gates
|
|
290
|
+
.filter((g) => !g.passed)
|
|
291
|
+
.map((g) => g.gate);
|
|
292
|
+
allErrors.push(`Wave ${wave.waveNumber} verification failed: ${failedGates.join(", ")}`);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
// Success = all waves complete + last wave verification passed (if any)
|
|
296
|
+
const lastWave = updatedWaves[updatedWaves.length - 1];
|
|
297
|
+
const lastVerificationPassed = lastWave?.verification?.passed ?? true;
|
|
298
|
+
const allAgentsSucceeded = updatedWaves.every((w) => w.agents.every((a) => a.success));
|
|
299
|
+
const success = allAgentsSucceeded && lastVerificationPassed;
|
|
300
|
+
return {
|
|
301
|
+
...execution,
|
|
302
|
+
waves: updatedWaves,
|
|
303
|
+
success,
|
|
304
|
+
totalFilesCreated: totalCreated,
|
|
305
|
+
totalFilesModified: totalModified,
|
|
306
|
+
errors: allErrors,
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
// ---------------------------------------------------------------------------
|
|
310
|
+
// Execution Orchestrator
|
|
311
|
+
// ---------------------------------------------------------------------------
|
|
312
|
+
/**
|
|
313
|
+
* Execute a single milestone end-to-end.
|
|
314
|
+
*
|
|
315
|
+
* In dryRun mode: builds context and prompts, runs no verification, returns
|
|
316
|
+
* the prepared execution plan.
|
|
317
|
+
*
|
|
318
|
+
* In normal mode: the caller (skill file) should use this module's functions
|
|
319
|
+
* step by step:
|
|
320
|
+
* 1. `buildMilestoneContext()` — read PRD and build context
|
|
321
|
+
* 2. `prepareWaves()` — get agent prompts for each wave
|
|
322
|
+
* 3. For each wave: spawn agents, collect results
|
|
323
|
+
* 4. `runWaveVerification()` — verify after each wave
|
|
324
|
+
* 5. `recordWaveResult()` — track results
|
|
325
|
+
*
|
|
326
|
+
* This `executeMilestone` function is the simplified orchestrator for
|
|
327
|
+
* programmatic/testing use. For real execution, the skill drives each step.
|
|
328
|
+
*/
|
|
329
|
+
export async function executeMilestone(options) {
|
|
330
|
+
// 1. Build context
|
|
331
|
+
const context = await buildMilestoneContext(options);
|
|
332
|
+
// 2. Prepare waves
|
|
333
|
+
const waves = prepareWaves(context);
|
|
334
|
+
// 3. Create result tracker
|
|
335
|
+
const result = createExecutionResult(context);
|
|
336
|
+
if (options.dryRun) {
|
|
337
|
+
// In dry run, return the plan without executing
|
|
338
|
+
return { context, waves, result };
|
|
339
|
+
}
|
|
340
|
+
// In non-dry-run mode, the executor only runs verification.
|
|
341
|
+
// Agent spawning is the caller's (skill's) responsibility.
|
|
342
|
+
// This path is for programmatic testing only.
|
|
343
|
+
return { context, waves, result };
|
|
344
|
+
}
|
|
345
|
+
// ---------------------------------------------------------------------------
|
|
346
|
+
// Formatting
|
|
347
|
+
// ---------------------------------------------------------------------------
|
|
348
|
+
/**
|
|
349
|
+
* Format an execution result as a human-readable summary.
|
|
350
|
+
*/
|
|
351
|
+
export function formatExecutionSummary(result) {
|
|
352
|
+
const lines = [];
|
|
353
|
+
const status = result.success ? "COMPLETE" : "FAILED";
|
|
354
|
+
lines.push(`## Milestone ${result.milestoneNumber}: ${result.milestoneName} -- ${status}`);
|
|
355
|
+
lines.push("");
|
|
356
|
+
// Wave summary
|
|
357
|
+
for (const wave of result.waves) {
|
|
358
|
+
const agentStatus = wave.agents
|
|
359
|
+
.map((a) => `${a.name}: ${a.success ? "OK" : "FAIL"}`)
|
|
360
|
+
.join(", ");
|
|
361
|
+
const verifyStatus = wave.verification
|
|
362
|
+
? wave.verification.passed
|
|
363
|
+
? "PASSED"
|
|
364
|
+
: "FAILED"
|
|
365
|
+
: "SKIPPED";
|
|
366
|
+
lines.push(`**Wave ${wave.waveNumber}:** ${agentStatus} | Verify: ${verifyStatus}`);
|
|
367
|
+
}
|
|
368
|
+
lines.push("");
|
|
369
|
+
// Stats
|
|
370
|
+
lines.push(`**Files Created:** ${result.totalFilesCreated}`);
|
|
371
|
+
lines.push(`**Files Modified:** ${result.totalFilesModified}`);
|
|
372
|
+
lines.push("");
|
|
373
|
+
// Errors
|
|
374
|
+
if (result.errors.length > 0) {
|
|
375
|
+
lines.push("### Errors");
|
|
376
|
+
for (const error of result.errors) {
|
|
377
|
+
lines.push(`- ${error}`);
|
|
378
|
+
}
|
|
379
|
+
lines.push("");
|
|
380
|
+
}
|
|
381
|
+
return lines.join("\n");
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Format verification errors into a structured prompt for fix agents.
|
|
385
|
+
* Used by the self-healing verify loop.
|
|
386
|
+
*/
|
|
387
|
+
export function formatErrorsForFixAgent(verification) {
|
|
388
|
+
const lines = [];
|
|
389
|
+
lines.push("## Verification Errors to Fix");
|
|
390
|
+
lines.push("");
|
|
391
|
+
for (const gate of verification.gates) {
|
|
392
|
+
if (gate.passed)
|
|
393
|
+
continue;
|
|
394
|
+
lines.push(`### ${gate.gate} Gate — FAILED`);
|
|
395
|
+
for (const error of gate.errors) {
|
|
396
|
+
const loc = error.file
|
|
397
|
+
? `${error.file}${error.line ? `:${error.line}` : ""}`
|
|
398
|
+
: "";
|
|
399
|
+
const prefix = loc ? `**${loc}:** ` : "";
|
|
400
|
+
lines.push(`- ${prefix}${error.message}`);
|
|
401
|
+
if (error.remediation) {
|
|
402
|
+
lines.push(` > Fix: ${error.remediation}`);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
lines.push("");
|
|
406
|
+
}
|
|
407
|
+
return lines.join("\n");
|
|
408
|
+
}
|
|
409
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/go/executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAwB,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE9E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAkEzD,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,KAAK,UAAU,QAAQ,CAAC,QAAgB;IACtC,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,SAAS,qBAAqB,CAAC,OAAe;IAM5C,yBAAyB;IACzB,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAC7B,iDAAiD,CAClD,CAAC;IACF,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,mBAAmB,CAAC;IAEnE,eAAe;IACf,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAElD,cAAc;IACd,MAAM,KAAK,GAAoB,EAAE,CAAC;IAClC,MAAM,WAAW,GACf,mGAAmG,CAAC;IAEtG,IAAI,SAAiC,CAAC;IACtC,OAAO,CAAC,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACxD,MAAM,UAAU,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC9C,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QAE9B,MAAM,MAAM,GAAsC,EAAE,CAAC;QAErD,6DAA6D;QAC7D,MAAM,YAAY,GAChB,uGAAuG,CAAC;QAE1G,IAAI,UAAkC,CAAC;QACvC,OAAO,CAAC,UAAU,GAAG,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAC3D,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACvC,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAEvC,6CAA6C;YAC7C,MAAM,KAAK,GAAa,EAAE,CAAC;YAC3B,MAAM,eAAe,GACnB,wDAAwD,CAAC;YAC3D,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAC/B,UAAU,CAAC,KAAK,EAChB,YAAY,CAAC,SAAS,CACvB,CAAC;YACF,IAAI,SAAiC,CAAC;YACtC,OAAO,CAAC,SAAS,GAAG,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC/D,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC;qBAC1B,KAAK,CAAC,GAAG,CAAC;qBACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;qBACpB,MAAM,CAAC,OAAO,CAAC,CAAC;gBACnB,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;YAC1B,CAAC;YAED,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3D,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,KAAK,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,8BAA8B;IAC9B,MAAM,oBAAoB,GAAa,EAAE,CAAC;IAC1C,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CACjC,0DAA0D,CAC3D,CAAC;IACF,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxC,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACrC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC;AACrD,CAAC;AAED,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAAgC;IAEhC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC;IAEzD,iEAAiE;IACjE,MAAM,cAAc,GAAG,MAAM,kBAAkB,CAC7C,UAAU,EACV,OAAO,EACP,eAAe,CAChB,CAAC;IAEF,MAAM,gBAAgB,GAAG,cAAc,CAAC,uBAAuB,CAAC;IAChE,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CACb,aAAa,eAAe,wBAAwB,OAAO,EAAE,CAC9D,CAAC;IACJ,CAAC;IAED,mDAAmD;IACnD,MAAM,MAAM,GAAG,qBAAqB,CAAC,gBAAgB,CAAC,CAAC;IAEvD,wBAAwB;IACxB,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC5C,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;QACjD,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;KACxC,CAAC,CAAC;IAEH,OAAO;QACL,eAAe;QACf,aAAa,EAAE,MAAM,CAAC,IAAI;QAC1B,aAAa,EAAE,MAAM,CAAC,IAAI;QAC1B,gBAAgB;QAChB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,oBAAoB,EAAE,MAAM,CAAC,oBAAoB;QACjD,cAAc;QACd,OAAO;QACP,QAAQ;KACT,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAC9B,KAAsC,EACtC,OAAyB,EACzB,YAAqB;IAErB,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,SAAS;IACT,KAAK,CAAC,IAAI,CAAC,YAAY,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CACR,kCAAkC,OAAO,CAAC,eAAe,KAAK,OAAO,CAAC,aAAa,KAAK,CACzF,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,uBAAuB,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IAC3D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,sBAAsB;IACtB,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,yBAAyB;IACzB,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAC/B,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QAC1B,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,mCAAmC;IACnC,IAAI,YAAY,EAAE,CAAC;QACjB,KAAK,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;QAC3C,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,UAAU;IACV,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;QACxC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,uDAAuD;IACvD,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,qDAAqD;QACrD,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CACvC,8CAA8C,CAC/C,CAAC;QACF,IAAI,UAAU,EAAE,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IAED,eAAe;IACf,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAC9B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;IAClD,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAC1C,IAAI,OAAO,CAAC,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5C,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,oBAAoB,EAAE,CAAC;YAC/C,KAAK,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,YAAY;IACZ,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CACR,qEAAqE,CACtE,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC;IACjE,KAAK,CAAC,IAAI,CACR,8DAA8D,CAC/D,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,8EAA8E;AAC9E,6BAA6B;AAC7B,8EAA8E;AAE9E;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAC1B,OAAyB,EACzB,eAAqC;IAErC,OAAO,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAClC,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAClC,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,MAAM,EAAE,gBAAgB,CACtB,KAAK,EACL,OAAO,EACP,eAAe,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CACjC;SACF,CAAC,CAAC;KACJ,CAAC,CAAC,CAAC;AACN,CAAC;AAED,8EAA8E;AAC9E,eAAe;AACf,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,OAAgC;IAEhC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAEhD,MAAM,aAAa,GAAkB;QACnC,UAAU;QACV,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,OAAO;QAClC,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,gBAAgB,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO;QAC3C,aAAa,EAAE,MAAM,CAAC,SAAS,EAAE,IAAI;KACtC,CAAC;IAEF,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,aAAa,CAAC,CAAC;IAEhD,+BAA+B;IAC/B,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,CAAC,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,OAAyB;IAEzB,OAAO;QACL,eAAe,EAAE,OAAO,CAAC,eAAe;QACxC,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,EAAE;QACT,iBAAiB,EAAE,CAAC;QACpB,kBAAkB,EAAE,CAAC;QACrB,MAAM,EAAE,EAAE;KACX,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAC9B,SAA0B,EAC1B,UAAsB;IAEtB,MAAM,YAAY,GAAG,CAAC,GAAG,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IAEtD,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,MAAM,SAAS,GAAa,EAAE,CAAC;IAE/B,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;QAChC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChC,YAAY,IAAI,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC;YAC1C,aAAa,IAAI,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC;YAC5C,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBAChB,SAAS,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;QACD,IAAI,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;YACnD,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK;iBACxC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;iBACxB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACtB,SAAS,CAAC,IAAI,CACZ,QAAQ,IAAI,CAAC,UAAU,yBAAyB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACzE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,wEAAwE;IACxE,MAAM,QAAQ,GAAG,YAAY,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACvD,MAAM,sBAAsB,GAC1B,QAAQ,EAAE,YAAY,EAAE,MAAM,IAAI,IAAI,CAAC;IACzC,MAAM,kBAAkB,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAClD,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CACjC,CAAC;IACF,MAAM,OAAO,GAAG,kBAAkB,IAAI,sBAAsB,CAAC;IAE7D,OAAO;QACL,GAAG,SAAS;QACZ,KAAK,EAAE,YAAY;QACnB,OAAO;QACP,iBAAiB,EAAE,YAAY;QAC/B,kBAAkB,EAAE,aAAa;QACjC,MAAM,EAAE,SAAS;KAClB,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,yBAAyB;AACzB,8EAA8E;AAE9E;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAgC;IAMhC,mBAAmB;IACnB,MAAM,OAAO,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAErD,mBAAmB;IACnB,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IAEpC,2BAA2B;IAC3B,MAAM,MAAM,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAE9C,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,gDAAgD;QAChD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IACpC,CAAC;IAED,4DAA4D;IAC5D,2DAA2D;IAC3D,8CAA8C;IAC9C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACpC,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAuB;IAC5D,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC;IAEtD,KAAK,CAAC,IAAI,CACR,gBAAgB,MAAM,CAAC,eAAe,KAAK,MAAM,CAAC,aAAa,OAAO,MAAM,EAAE,CAC/E,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,eAAe;IACf,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAChC,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM;aAC5B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;aACrD,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY;YACpC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM;gBACxB,CAAC,CAAC,QAAQ;gBACV,CAAC,CAAC,QAAQ;YACZ,CAAC,CAAC,SAAS,CAAC;QAEd,KAAK,CAAC,IAAI,CACR,UAAU,IAAI,CAAC,UAAU,OAAO,WAAW,cAAc,YAAY,EAAE,CACxE,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,QAAQ;IACR,KAAK,CAAC,IAAI,CAAC,sBAAsB,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAC7D,KAAK,CAAC,IAAI,CAAC,uBAAuB,MAAM,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAC/D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,SAAS;IACT,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACzB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClC,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;QAC3B,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CACrC,YAA4B;IAE5B,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;IAC5C,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,MAAM,IAAI,IAAI,YAAY,CAAC,KAAK,EAAE,CAAC;QACtC,IAAI,IAAI,CAAC,MAAM;YAAE,SAAS;QAE1B,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,gBAAgB,CAAC,CAAC;QAC7C,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChC,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI;gBACpB,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;gBACtD,CAAC,CAAC,EAAE,CAAC;YACP,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YACzC,KAAK,CAAC,IAAI,CAAC,KAAK,MAAM,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAC1C,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;gBACtB,KAAK,CAAC,IAAI,CAAC,YAAY,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Final Milestone Detection and PR Creation
|
|
3
|
+
*
|
|
4
|
+
* Handles the transition from "last milestone complete" to "PR ready for review".
|
|
5
|
+
* Uses `gh pr create` to open a pull request with a forge verification report
|
|
6
|
+
* in the body. Designed to be called by the execution engine after the final
|
|
7
|
+
* milestone passes verification.
|
|
8
|
+
*/
|
|
9
|
+
import type { PipelineResult } from "../types.js";
|
|
10
|
+
export interface CreatePROptions {
|
|
11
|
+
projectDir: string;
|
|
12
|
+
branch: string;
|
|
13
|
+
baseBranch?: string;
|
|
14
|
+
title: string;
|
|
15
|
+
milestones: Array<{
|
|
16
|
+
number: number;
|
|
17
|
+
name: string;
|
|
18
|
+
success: boolean;
|
|
19
|
+
}>;
|
|
20
|
+
verificationReport?: string;
|
|
21
|
+
commitSha?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface PRResult {
|
|
24
|
+
url: string;
|
|
25
|
+
number: number;
|
|
26
|
+
title: string;
|
|
27
|
+
created: boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface PRError {
|
|
30
|
+
url: "";
|
|
31
|
+
number: 0;
|
|
32
|
+
title: string;
|
|
33
|
+
created: false;
|
|
34
|
+
error: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Generate a PR title summarizing all completed milestones.
|
|
38
|
+
*
|
|
39
|
+
* Examples:
|
|
40
|
+
* - `feat: my-project — Milestone 1 complete`
|
|
41
|
+
* - `feat: my-project — Milestones 1-5 complete`
|
|
42
|
+
*/
|
|
43
|
+
export declare function buildPRTitle(project: string, milestoneCount: number): string;
|
|
44
|
+
/**
|
|
45
|
+
* Format a PipelineResult into a PR-ready verification section.
|
|
46
|
+
*
|
|
47
|
+
* Includes gate-level pass/fail status with error counts and
|
|
48
|
+
* duration information. Designed to be embedded in a PR body.
|
|
49
|
+
*/
|
|
50
|
+
export declare function buildVerificationSection(result: PipelineResult): string;
|
|
51
|
+
/**
|
|
52
|
+
* Create a GitHub pull request using the `gh` CLI.
|
|
53
|
+
*
|
|
54
|
+
* Builds a structured PR body with milestone status, verification report,
|
|
55
|
+
* and metadata, then calls `gh pr create`. If `gh` is not installed or the
|
|
56
|
+
* command fails, returns a descriptive error result instead of throwing.
|
|
57
|
+
*/
|
|
58
|
+
export declare function createPullRequest(options: CreatePROptions): PRResult | PRError;
|