agent-bober 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/.claude-plugin/plugin.json +9 -0
- package/LICENSE +21 -0
- package/README.md +495 -0
- package/agents/bober-evaluator.md +323 -0
- package/agents/bober-generator.md +245 -0
- package/agents/bober-planner.md +248 -0
- package/dist/cli/commands/eval.d.ts +6 -0
- package/dist/cli/commands/eval.d.ts.map +1 -0
- package/dist/cli/commands/eval.js +129 -0
- package/dist/cli/commands/eval.js.map +1 -0
- package/dist/cli/commands/init.d.ts +5 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +547 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/plan.d.ts +5 -0
- package/dist/cli/commands/plan.d.ts.map +1 -0
- package/dist/cli/commands/plan.js +87 -0
- package/dist/cli/commands/plan.js.map +1 -0
- package/dist/cli/commands/run.d.ts +5 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +120 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/sprint.d.ts +6 -0
- package/dist/cli/commands/sprint.d.ts.map +1 -0
- package/dist/cli/commands/sprint.js +206 -0
- package/dist/cli/commands/sprint.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +124 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config/defaults.d.ts +15 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +226 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/index.d.ts +4 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +8 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +18 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +189 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +904 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +181 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/contracts/eval-result.d.ts +205 -0
- package/dist/contracts/eval-result.d.ts.map +1 -0
- package/dist/contracts/eval-result.js +87 -0
- package/dist/contracts/eval-result.js.map +1 -0
- package/dist/contracts/index.d.ts +4 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +16 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/contracts/spec.d.ts +101 -0
- package/dist/contracts/spec.d.ts.map +1 -0
- package/dist/contracts/spec.js +51 -0
- package/dist/contracts/spec.js.map +1 -0
- package/dist/contracts/sprint-contract.d.ts +141 -0
- package/dist/contracts/sprint-contract.d.ts.map +1 -0
- package/dist/contracts/sprint-contract.js +80 -0
- package/dist/contracts/sprint-contract.js.map +1 -0
- package/dist/evaluators/builtin/api-check.d.ts +13 -0
- package/dist/evaluators/builtin/api-check.d.ts.map +1 -0
- package/dist/evaluators/builtin/api-check.js +152 -0
- package/dist/evaluators/builtin/api-check.js.map +1 -0
- package/dist/evaluators/builtin/build-check.d.ts +17 -0
- package/dist/evaluators/builtin/build-check.d.ts.map +1 -0
- package/dist/evaluators/builtin/build-check.js +155 -0
- package/dist/evaluators/builtin/build-check.js.map +1 -0
- package/dist/evaluators/builtin/command-runner.d.ts +26 -0
- package/dist/evaluators/builtin/command-runner.d.ts.map +1 -0
- package/dist/evaluators/builtin/command-runner.js +114 -0
- package/dist/evaluators/builtin/command-runner.js.map +1 -0
- package/dist/evaluators/builtin/lint.d.ts +17 -0
- package/dist/evaluators/builtin/lint.d.ts.map +1 -0
- package/dist/evaluators/builtin/lint.js +264 -0
- package/dist/evaluators/builtin/lint.js.map +1 -0
- package/dist/evaluators/builtin/playwright.d.ts +16 -0
- package/dist/evaluators/builtin/playwright.d.ts.map +1 -0
- package/dist/evaluators/builtin/playwright.js +238 -0
- package/dist/evaluators/builtin/playwright.js.map +1 -0
- package/dist/evaluators/builtin/typescript-check.d.ts +12 -0
- package/dist/evaluators/builtin/typescript-check.d.ts.map +1 -0
- package/dist/evaluators/builtin/typescript-check.js +155 -0
- package/dist/evaluators/builtin/typescript-check.js.map +1 -0
- package/dist/evaluators/builtin/unit-test.d.ts +18 -0
- package/dist/evaluators/builtin/unit-test.d.ts.map +1 -0
- package/dist/evaluators/builtin/unit-test.js +279 -0
- package/dist/evaluators/builtin/unit-test.js.map +1 -0
- package/dist/evaluators/index.d.ts +11 -0
- package/dist/evaluators/index.d.ts.map +1 -0
- package/dist/evaluators/index.js +13 -0
- package/dist/evaluators/index.js.map +1 -0
- package/dist/evaluators/plugin-interface.d.ts +50 -0
- package/dist/evaluators/plugin-interface.d.ts.map +1 -0
- package/dist/evaluators/plugin-interface.js +2 -0
- package/dist/evaluators/plugin-interface.js.map +1 -0
- package/dist/evaluators/plugin-loader.d.ts +18 -0
- package/dist/evaluators/plugin-loader.d.ts.map +1 -0
- package/dist/evaluators/plugin-loader.js +107 -0
- package/dist/evaluators/plugin-loader.js.map +1 -0
- package/dist/evaluators/registry.d.ts +78 -0
- package/dist/evaluators/registry.d.ts.map +1 -0
- package/dist/evaluators/registry.js +238 -0
- package/dist/evaluators/registry.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/orchestrator/context-handoff.d.ts +543 -0
- package/dist/orchestrator/context-handoff.d.ts.map +1 -0
- package/dist/orchestrator/context-handoff.js +133 -0
- package/dist/orchestrator/context-handoff.js.map +1 -0
- package/dist/orchestrator/evaluator-agent.d.ts +15 -0
- package/dist/orchestrator/evaluator-agent.d.ts.map +1 -0
- package/dist/orchestrator/evaluator-agent.js +233 -0
- package/dist/orchestrator/evaluator-agent.js.map +1 -0
- package/dist/orchestrator/generator-agent.d.ts +16 -0
- package/dist/orchestrator/generator-agent.d.ts.map +1 -0
- package/dist/orchestrator/generator-agent.js +147 -0
- package/dist/orchestrator/generator-agent.js.map +1 -0
- package/dist/orchestrator/pipeline.d.ts +24 -0
- package/dist/orchestrator/pipeline.d.ts.map +1 -0
- package/dist/orchestrator/pipeline.js +290 -0
- package/dist/orchestrator/pipeline.js.map +1 -0
- package/dist/orchestrator/planner-agent.d.ts +10 -0
- package/dist/orchestrator/planner-agent.d.ts.map +1 -0
- package/dist/orchestrator/planner-agent.js +187 -0
- package/dist/orchestrator/planner-agent.js.map +1 -0
- package/dist/state/helpers.d.ts +5 -0
- package/dist/state/helpers.d.ts.map +1 -0
- package/dist/state/helpers.js +8 -0
- package/dist/state/helpers.js.map +1 -0
- package/dist/state/history.d.ts +39 -0
- package/dist/state/history.d.ts.map +1 -0
- package/dist/state/history.js +162 -0
- package/dist/state/history.js.map +1 -0
- package/dist/state/index.d.ts +8 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +22 -0
- package/dist/state/index.js.map +1 -0
- package/dist/state/plan-state.d.ts +21 -0
- package/dist/state/plan-state.d.ts.map +1 -0
- package/dist/state/plan-state.js +108 -0
- package/dist/state/plan-state.js.map +1 -0
- package/dist/state/sprint-state.d.ts +20 -0
- package/dist/state/sprint-state.d.ts.map +1 -0
- package/dist/state/sprint-state.js +98 -0
- package/dist/state/sprint-state.js.map +1 -0
- package/dist/utils/fs.d.ts +31 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +67 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/git.d.ts +35 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +84 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +45 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +73 -0
- package/dist/utils/logger.js.map +1 -0
- package/hooks/hooks.json +10 -0
- package/package.json +67 -0
- package/scripts/detect-stack.sh +287 -0
- package/scripts/init-project.sh +206 -0
- package/scripts/run-eval.sh +175 -0
- package/skills/bober.anchor/SKILL.md +365 -0
- package/skills/bober.anchor/references/anchor-guide.md +567 -0
- package/skills/bober.brownfield/SKILL.md +422 -0
- package/skills/bober.brownfield/references/codebase-analysis.md +304 -0
- package/skills/bober.eval/SKILL.md +235 -0
- package/skills/bober.eval/references/eval-strategies.md +407 -0
- package/skills/bober.eval/references/feedback-format.md +182 -0
- package/skills/bober.plan/SKILL.md +244 -0
- package/skills/bober.plan/references/clarification-guide.md +124 -0
- package/skills/bober.plan/references/spec-schema.md +253 -0
- package/skills/bober.react/SKILL.md +330 -0
- package/skills/bober.react/references/react-scaffold.md +344 -0
- package/skills/bober.run/SKILL.md +303 -0
- package/skills/bober.solidity/SKILL.md +416 -0
- package/skills/bober.solidity/references/solidity-guide.md +487 -0
- package/skills/bober.sprint/SKILL.md +280 -0
- package/skills/bober.sprint/references/contract-schema.md +251 -0
- package/templates/base/CLAUDE.md +20 -0
- package/templates/base/bober.config.json +35 -0
- package/templates/brownfield/CLAUDE.md +34 -0
- package/templates/brownfield/bober.config.json +37 -0
- package/templates/presets/anchor/CLAUDE.md +163 -0
- package/templates/presets/anchor/bober.config.json +9 -0
- package/templates/presets/api-node/CLAUDE.md +153 -0
- package/templates/presets/api-node/bober.config.json +10 -0
- package/templates/presets/nextjs/CLAUDE.md +82 -0
- package/templates/presets/nextjs/bober.config.json +14 -0
- package/templates/presets/python-api/CLAUDE.md +202 -0
- package/templates/presets/python-api/bober.config.json +9 -0
- package/templates/presets/react-vite/CLAUDE.md +71 -0
- package/templates/presets/react-vite/bober.config.json +53 -0
- package/templates/presets/react-vite/scaffold/package.json +45 -0
- package/templates/presets/react-vite/scaffold/server/index.ts +38 -0
- package/templates/presets/react-vite/scaffold/server/tsconfig.json +24 -0
- package/templates/presets/react-vite/scaffold/src/App.tsx +37 -0
- package/templates/presets/react-vite/scaffold/src/index.html +12 -0
- package/templates/presets/react-vite/scaffold/src/main.tsx +12 -0
- package/templates/presets/react-vite/scaffold/tsconfig.json +27 -0
- package/templates/presets/react-vite/scaffold/vite.config.ts +34 -0
- package/templates/presets/solidity/CLAUDE.md +106 -0
- package/templates/presets/solidity/bober.config.json +9 -0
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
import { createContract, updateContractStatus, } from "../contracts/sprint-contract.js";
|
|
2
|
+
import { createHandoff, summarizeOlderSprints, } from "./context-handoff.js";
|
|
3
|
+
import { runPlanner } from "./planner-agent.js";
|
|
4
|
+
import { runGenerator } from "./generator-agent.js";
|
|
5
|
+
import { runEvaluatorAgent } from "./evaluator-agent.js";
|
|
6
|
+
import { ensureBoberDir, saveContract, updateContract, appendHistory, } from "../state/index.js";
|
|
7
|
+
import { commitAll, getCurrentBranch, getChangedFiles } from "../utils/git.js";
|
|
8
|
+
import { logger } from "../utils/logger.js";
|
|
9
|
+
// ── Interrupt handling ─────────────────────────────────────────────
|
|
10
|
+
let interrupted = false;
|
|
11
|
+
function setupInterruptHandler() {
|
|
12
|
+
interrupted = false;
|
|
13
|
+
const handler = () => {
|
|
14
|
+
if (interrupted) {
|
|
15
|
+
// Second SIGINT — force exit
|
|
16
|
+
logger.error("Force interrupted. Exiting immediately.");
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
interrupted = true;
|
|
20
|
+
logger.warn("Interrupt received. Finishing current sprint, then stopping...");
|
|
21
|
+
};
|
|
22
|
+
process.on("SIGINT", handler);
|
|
23
|
+
return () => {
|
|
24
|
+
process.removeListener("SIGINT", handler);
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
// ── Project context helper ─────────────────────────────────────────
|
|
28
|
+
async function buildProjectContext(projectRoot, config) {
|
|
29
|
+
let currentBranch;
|
|
30
|
+
try {
|
|
31
|
+
currentBranch = await getCurrentBranch(projectRoot);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
currentBranch = "unknown";
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
name: config.project.name,
|
|
38
|
+
type: config.project.mode,
|
|
39
|
+
techStack: [],
|
|
40
|
+
entryPoints: [],
|
|
41
|
+
currentBranch,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
// ── Sprint cycle ───────────────────────────────────────────────────
|
|
45
|
+
async function runSprintCycle(contract, spec, completedContracts, projectRoot, config, projectContext) {
|
|
46
|
+
const maxIterations = config.evaluator.maxIterations;
|
|
47
|
+
let currentContract = updateContractStatus(contract, "in-progress");
|
|
48
|
+
await updateContract(projectRoot, currentContract);
|
|
49
|
+
let lastEvaluation;
|
|
50
|
+
let lastGeneratorResult;
|
|
51
|
+
for (let iteration = 1; iteration <= maxIterations; iteration++) {
|
|
52
|
+
if (interrupted) {
|
|
53
|
+
logger.warn(`Sprint ${currentContract.id} interrupted at iteration ${iteration}.`);
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
logger.progress(iteration, maxIterations, `Sprint ${currentContract.id} iteration`);
|
|
57
|
+
// Build evaluation feedback from prior round
|
|
58
|
+
const evalFeedback = lastEvaluation
|
|
59
|
+
? lastEvaluation.summary
|
|
60
|
+
: "";
|
|
61
|
+
// Summarize older sprints to save context
|
|
62
|
+
const completedSummaryHandoff = createHandoff({
|
|
63
|
+
from: iteration === 1 ? "planner" : "evaluator",
|
|
64
|
+
to: "generator",
|
|
65
|
+
projectContext,
|
|
66
|
+
spec,
|
|
67
|
+
currentContract,
|
|
68
|
+
sprintHistory: completedContracts,
|
|
69
|
+
instructions: `Implement sprint: ${currentContract.feature}\n\n${currentContract.description}`,
|
|
70
|
+
changedFiles: lastGeneratorResult?.filesChanged ?? [],
|
|
71
|
+
issues: evalFeedback ? [evalFeedback] : [],
|
|
72
|
+
});
|
|
73
|
+
// Compact older sprint history if needed
|
|
74
|
+
const compactedHandoff = summarizeOlderSprints(completedSummaryHandoff, 3);
|
|
75
|
+
// ── Generate ───────────────────────────────────────────────
|
|
76
|
+
logger.phase(`Sprint ${currentContract.id} - Generate (Round ${iteration})`);
|
|
77
|
+
await appendHistory(projectRoot, {
|
|
78
|
+
timestamp: new Date().toISOString(),
|
|
79
|
+
event: "generator-start",
|
|
80
|
+
phase: "generating",
|
|
81
|
+
sprintId: currentContract.id,
|
|
82
|
+
details: { iteration },
|
|
83
|
+
});
|
|
84
|
+
const generatorResult = await runGenerator(compactedHandoff, projectRoot, config);
|
|
85
|
+
lastGeneratorResult = generatorResult;
|
|
86
|
+
if (!generatorResult.success) {
|
|
87
|
+
logger.warn(`Generator reported failure: ${generatorResult.notes}`);
|
|
88
|
+
currentContract = {
|
|
89
|
+
...currentContract,
|
|
90
|
+
generatorNotes: generatorResult.notes,
|
|
91
|
+
};
|
|
92
|
+
await updateContract(projectRoot, currentContract);
|
|
93
|
+
if (iteration < maxIterations) {
|
|
94
|
+
logger.info("Retrying generation...");
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
// Max iterations reached, mark as needs-rework
|
|
98
|
+
currentContract = updateContractStatus(currentContract, "needs-rework");
|
|
99
|
+
currentContract = {
|
|
100
|
+
...currentContract,
|
|
101
|
+
evaluatorFeedback: "Generator failed to complete the implementation.",
|
|
102
|
+
};
|
|
103
|
+
await updateContract(projectRoot, currentContract);
|
|
104
|
+
return { contract: currentContract, generatorResult };
|
|
105
|
+
}
|
|
106
|
+
currentContract = {
|
|
107
|
+
...currentContract,
|
|
108
|
+
generatorNotes: generatorResult.notes,
|
|
109
|
+
};
|
|
110
|
+
// Auto-commit if enabled
|
|
111
|
+
if (config.generator.autoCommit) {
|
|
112
|
+
try {
|
|
113
|
+
const commitHash = await commitAll(projectRoot, `bober: ${currentContract.feature} (sprint ${currentContract.id}, round ${iteration})`);
|
|
114
|
+
logger.success(`Committed: ${commitHash}`);
|
|
115
|
+
lastGeneratorResult = { ...generatorResult, commitHash };
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
logger.debug(`Auto-commit skipped: ${err instanceof Error ? err.message : String(err)}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// ── Evaluate ──────────────────────────────────────────────
|
|
122
|
+
logger.phase(`Sprint ${currentContract.id} - Evaluate (Round ${iteration})`);
|
|
123
|
+
currentContract = updateContractStatus(currentContract, "evaluating");
|
|
124
|
+
await updateContract(projectRoot, currentContract);
|
|
125
|
+
await appendHistory(projectRoot, {
|
|
126
|
+
timestamp: new Date().toISOString(),
|
|
127
|
+
event: "evaluator-start",
|
|
128
|
+
phase: "evaluating",
|
|
129
|
+
sprintId: currentContract.id,
|
|
130
|
+
details: { iteration },
|
|
131
|
+
});
|
|
132
|
+
// Build handoff for evaluator
|
|
133
|
+
let changedFiles;
|
|
134
|
+
try {
|
|
135
|
+
changedFiles = await getChangedFiles(projectRoot);
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
changedFiles = generatorResult.filesChanged;
|
|
139
|
+
}
|
|
140
|
+
const evalHandoff = {
|
|
141
|
+
...compactedHandoff,
|
|
142
|
+
from: "generator",
|
|
143
|
+
to: "evaluator",
|
|
144
|
+
changedFiles,
|
|
145
|
+
};
|
|
146
|
+
const evaluation = await runEvaluatorAgent(evalHandoff, projectRoot, config);
|
|
147
|
+
lastEvaluation = evaluation;
|
|
148
|
+
if (evaluation.passed) {
|
|
149
|
+
logger.success(`Sprint ${currentContract.id} passed all evaluations!`);
|
|
150
|
+
currentContract = updateContractStatus(currentContract, "passed");
|
|
151
|
+
currentContract = {
|
|
152
|
+
...currentContract,
|
|
153
|
+
evaluatorFeedback: evaluation.summary,
|
|
154
|
+
};
|
|
155
|
+
await updateContract(projectRoot, currentContract);
|
|
156
|
+
await appendHistory(projectRoot, {
|
|
157
|
+
timestamp: new Date().toISOString(),
|
|
158
|
+
event: "sprint-passed",
|
|
159
|
+
phase: "complete",
|
|
160
|
+
sprintId: currentContract.id,
|
|
161
|
+
details: { iteration, feedback: evaluation.summary },
|
|
162
|
+
});
|
|
163
|
+
return { contract: currentContract, evaluation, generatorResult: lastGeneratorResult };
|
|
164
|
+
}
|
|
165
|
+
// Evaluation failed
|
|
166
|
+
logger.warn(`Evaluation failed (round ${iteration}/${maxIterations}): ${evaluation.summary.slice(0, 200)}`);
|
|
167
|
+
currentContract = {
|
|
168
|
+
...currentContract,
|
|
169
|
+
evaluatorFeedback: evaluation.summary,
|
|
170
|
+
};
|
|
171
|
+
await updateContract(projectRoot, currentContract);
|
|
172
|
+
await appendHistory(projectRoot, {
|
|
173
|
+
timestamp: new Date().toISOString(),
|
|
174
|
+
event: "evaluation-failed",
|
|
175
|
+
phase: "rework",
|
|
176
|
+
sprintId: currentContract.id,
|
|
177
|
+
details: { iteration, feedback: evaluation.summary },
|
|
178
|
+
});
|
|
179
|
+
if (iteration >= maxIterations) {
|
|
180
|
+
logger.error(`Sprint ${currentContract.id} exceeded max iterations (${maxIterations}).`);
|
|
181
|
+
currentContract = updateContractStatus(currentContract, "needs-rework");
|
|
182
|
+
await updateContract(projectRoot, currentContract);
|
|
183
|
+
return { contract: currentContract, evaluation };
|
|
184
|
+
}
|
|
185
|
+
logger.info("Feeding evaluation feedback into next iteration...");
|
|
186
|
+
}
|
|
187
|
+
// Should not normally reach here
|
|
188
|
+
return { contract: currentContract, evaluation: lastEvaluation };
|
|
189
|
+
}
|
|
190
|
+
// ── Main pipeline ──────────────────────────────────────────────────
|
|
191
|
+
/**
|
|
192
|
+
* Run the complete orchestration pipeline:
|
|
193
|
+
*
|
|
194
|
+
* 1. **Plan** — Call the planner agent to produce a PlanSpec
|
|
195
|
+
* 2. **Sprint loop** — For each feature, create sprint contracts and
|
|
196
|
+
* run the generate-evaluate-iterate cycle
|
|
197
|
+
* 3. **Result** — Return aggregated results
|
|
198
|
+
*
|
|
199
|
+
* Each agent invocation is a FRESH call (new message thread). Context
|
|
200
|
+
* is carried via the ContextHandoff document.
|
|
201
|
+
*/
|
|
202
|
+
export async function runPipeline(userPrompt, projectRoot, config) {
|
|
203
|
+
const startTime = Date.now();
|
|
204
|
+
const cleanup = setupInterruptHandler();
|
|
205
|
+
try {
|
|
206
|
+
// Ensure .bober/ directory structure exists
|
|
207
|
+
await ensureBoberDir(projectRoot);
|
|
208
|
+
await appendHistory(projectRoot, {
|
|
209
|
+
timestamp: new Date().toISOString(),
|
|
210
|
+
event: "pipeline-start",
|
|
211
|
+
phase: "init",
|
|
212
|
+
details: { userPrompt: userPrompt.slice(0, 200) },
|
|
213
|
+
});
|
|
214
|
+
// ── Phase 1: Planning ────────────────────────────────────────
|
|
215
|
+
const spec = await runPlanner(userPrompt, projectRoot, config);
|
|
216
|
+
logger.info(`Plan: "${spec.title}" with ${spec.features.length} features`);
|
|
217
|
+
await appendHistory(projectRoot, {
|
|
218
|
+
timestamp: new Date().toISOString(),
|
|
219
|
+
event: "planning-complete",
|
|
220
|
+
phase: "planning",
|
|
221
|
+
details: {
|
|
222
|
+
specId: spec.id,
|
|
223
|
+
featureCount: spec.features.length,
|
|
224
|
+
},
|
|
225
|
+
});
|
|
226
|
+
// ── Phase 2: Sprint loop ─────────────────────────────────────
|
|
227
|
+
logger.phase("Sprint Execution");
|
|
228
|
+
// Create sprint contracts from features
|
|
229
|
+
const contracts = [];
|
|
230
|
+
for (const feature of spec.features) {
|
|
231
|
+
const contract = createContract(feature.title, feature.description, feature.acceptanceCriteria.map((ac, idx) => ({
|
|
232
|
+
id: `${feature.id}-criterion-${idx + 1}`,
|
|
233
|
+
description: ac,
|
|
234
|
+
verificationMethod: "agent-evaluation",
|
|
235
|
+
})));
|
|
236
|
+
contracts.push(contract);
|
|
237
|
+
await saveContract(projectRoot, contract);
|
|
238
|
+
}
|
|
239
|
+
const completedSprints = [];
|
|
240
|
+
const failedSprints = [];
|
|
241
|
+
const projectContext = await buildProjectContext(projectRoot, config);
|
|
242
|
+
const maxSprints = Math.min(contracts.length, config.sprint.maxSprints);
|
|
243
|
+
for (let i = 0; i < maxSprints; i++) {
|
|
244
|
+
if (interrupted) {
|
|
245
|
+
logger.warn("Pipeline interrupted by user.");
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
const contract = contracts[i];
|
|
249
|
+
logger.progress(i + 1, maxSprints, contract.feature);
|
|
250
|
+
const result = await runSprintCycle(contract, spec, completedSprints, projectRoot, config, projectContext);
|
|
251
|
+
if (result.contract.status === "passed") {
|
|
252
|
+
completedSprints.push(result.contract);
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
failedSprints.push(result.contract);
|
|
256
|
+
// Check if we should continue after failure
|
|
257
|
+
if (config.sprint.requireContracts &&
|
|
258
|
+
result.contract.status !== "needs-rework") {
|
|
259
|
+
logger.error(`Sprint ${result.contract.id} failed and contracts are required. Stopping pipeline.`);
|
|
260
|
+
break;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
// ── Phase 3: Results ─────────────────────────────────────────
|
|
265
|
+
logger.phase("Pipeline Complete");
|
|
266
|
+
const duration = Date.now() - startTime;
|
|
267
|
+
const success = failedSprints.length === 0 && completedSprints.length > 0;
|
|
268
|
+
await appendHistory(projectRoot, {
|
|
269
|
+
timestamp: new Date().toISOString(),
|
|
270
|
+
event: "pipeline-complete",
|
|
271
|
+
phase: success ? "complete" : "failed",
|
|
272
|
+
details: {
|
|
273
|
+
completed: completedSprints.length,
|
|
274
|
+
failed: failedSprints.length,
|
|
275
|
+
durationMs: duration,
|
|
276
|
+
},
|
|
277
|
+
});
|
|
278
|
+
return {
|
|
279
|
+
success,
|
|
280
|
+
spec,
|
|
281
|
+
completedSprints,
|
|
282
|
+
failedSprints,
|
|
283
|
+
duration,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
finally {
|
|
287
|
+
cleanup();
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
//# sourceMappingURL=pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/orchestrator/pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { BoberConfig } from "../config/schema.js";
|
|
2
|
+
import type { PlanSpec } from "../contracts/spec.js";
|
|
3
|
+
/**
|
|
4
|
+
* Run the planner agent to produce a PlanSpec from a user prompt.
|
|
5
|
+
*
|
|
6
|
+
* Uses the Anthropic SDK to create a single-turn message with the
|
|
7
|
+
* planner system prompt and project context.
|
|
8
|
+
*/
|
|
9
|
+
export declare function runPlanner(userPrompt: string, projectRoot: string, config: BoberConfig): Promise<PlanSpec>;
|
|
10
|
+
//# sourceMappingURL=planner-agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planner-agent.d.ts","sourceRoot":"","sources":["../../src/orchestrator/planner-agent.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AA0GrD;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,QAAQ,CAAC,CAkDnB"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import Anthropic from "@anthropic-ai/sdk";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { PlanSpecSchema } from "../contracts/spec.js";
|
|
5
|
+
import { saveSpec } from "../state/index.js";
|
|
6
|
+
import { fileExists } from "../utils/fs.js";
|
|
7
|
+
import { logger } from "../utils/logger.js";
|
|
8
|
+
// ── Model mapping ──────────────────────────────────────────────────
|
|
9
|
+
function resolveModel(choice) {
|
|
10
|
+
switch (choice) {
|
|
11
|
+
case "opus":
|
|
12
|
+
return "claude-sonnet-4-20250514";
|
|
13
|
+
case "sonnet":
|
|
14
|
+
return "claude-sonnet-4-20250514";
|
|
15
|
+
case "haiku":
|
|
16
|
+
return "claude-haiku-4-20250414";
|
|
17
|
+
default:
|
|
18
|
+
return "claude-sonnet-4-20250514";
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
// ── System prompt ──────────────────────────────────────────────────
|
|
22
|
+
const PLANNER_SYSTEM_PROMPT = `You are the Bober Planner agent. Your job is to take a user's project description and produce a detailed plan specification (PlanSpec) as JSON.
|
|
23
|
+
|
|
24
|
+
You must output ONLY valid JSON matching this schema:
|
|
25
|
+
{
|
|
26
|
+
"id": "spec-<timestamp>",
|
|
27
|
+
"title": "Short plan title",
|
|
28
|
+
"description": "Detailed description of what will be built",
|
|
29
|
+
"projectType": "<mode>[ / <preset>]",
|
|
30
|
+
"techStack": ["list", "of", "technologies"],
|
|
31
|
+
"features": [
|
|
32
|
+
{
|
|
33
|
+
"id": "feature-1",
|
|
34
|
+
"title": "Feature title",
|
|
35
|
+
"description": "What this feature does",
|
|
36
|
+
"priority": "must" | "should" | "could",
|
|
37
|
+
"estimatedSprints": 1,
|
|
38
|
+
"acceptanceCriteria": ["Criterion 1", "Criterion 2"]
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"nonFunctional": ["NFR 1", "NFR 2"],
|
|
42
|
+
"constraints": ["Constraint 1"],
|
|
43
|
+
"createdAt": "<ISO datetime>",
|
|
44
|
+
"updatedAt": "<ISO datetime>"
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
Guidelines:
|
|
48
|
+
- Break the project into small, independently testable features.
|
|
49
|
+
- Each feature should be completable in 1-3 sprints.
|
|
50
|
+
- Order features by dependency — foundational features first.
|
|
51
|
+
- "must" priority features are the MVP. "should" are important. "could" are nice-to-have.
|
|
52
|
+
- Acceptance criteria must be specific and verifiable.
|
|
53
|
+
- Consider the project's existing tech stack and configuration.
|
|
54
|
+
- Keep sprint sizes reasonable — each sprint should produce a working increment.
|
|
55
|
+
|
|
56
|
+
Output ONLY the JSON object. No markdown fences, no explanation, just the JSON.`;
|
|
57
|
+
// ── Context gathering ──────────────────────────────────────────────
|
|
58
|
+
async function gatherProjectContext(projectRoot, config) {
|
|
59
|
+
const sections = [];
|
|
60
|
+
// Package.json
|
|
61
|
+
const pkgPath = join(projectRoot, "package.json");
|
|
62
|
+
if (await fileExists(pkgPath)) {
|
|
63
|
+
const content = await readFile(pkgPath, "utf-8");
|
|
64
|
+
sections.push(`## package.json\n\`\`\`json\n${content}\n\`\`\``);
|
|
65
|
+
}
|
|
66
|
+
// CLAUDE.md
|
|
67
|
+
const claudeMdPath = join(projectRoot, "CLAUDE.md");
|
|
68
|
+
if (await fileExists(claudeMdPath)) {
|
|
69
|
+
const content = await readFile(claudeMdPath, "utf-8");
|
|
70
|
+
sections.push(`## CLAUDE.md\n${content}`);
|
|
71
|
+
}
|
|
72
|
+
// bober.config.json
|
|
73
|
+
sections.push(`## bober.config.json\n\`\`\`json\n${JSON.stringify(config, null, 2)}\n\`\`\``);
|
|
74
|
+
// Additional context files from config
|
|
75
|
+
if (config.planner.contextFiles) {
|
|
76
|
+
for (const relPath of config.planner.contextFiles) {
|
|
77
|
+
const fullPath = join(projectRoot, relPath);
|
|
78
|
+
if (await fileExists(fullPath)) {
|
|
79
|
+
try {
|
|
80
|
+
const content = await readFile(fullPath, "utf-8");
|
|
81
|
+
sections.push(`## ${relPath}\n\`\`\`\n${content}\n\`\`\``);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// Skip unreadable files
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return sections.join("\n\n");
|
|
90
|
+
}
|
|
91
|
+
// ── Main ───────────────────────────────────────────────────────────
|
|
92
|
+
/**
|
|
93
|
+
* Run the planner agent to produce a PlanSpec from a user prompt.
|
|
94
|
+
*
|
|
95
|
+
* Uses the Anthropic SDK to create a single-turn message with the
|
|
96
|
+
* planner system prompt and project context.
|
|
97
|
+
*/
|
|
98
|
+
export async function runPlanner(userPrompt, projectRoot, config) {
|
|
99
|
+
logger.phase("Planning Phase");
|
|
100
|
+
logger.info("Gathering project context...");
|
|
101
|
+
const context = await gatherProjectContext(projectRoot, config);
|
|
102
|
+
const model = resolveModel(config.planner.model);
|
|
103
|
+
const client = new Anthropic();
|
|
104
|
+
const userMessage = `# Task Description
|
|
105
|
+
${userPrompt}
|
|
106
|
+
|
|
107
|
+
# Project Context
|
|
108
|
+
${context}
|
|
109
|
+
|
|
110
|
+
Produce a PlanSpec JSON for this project. Remember: output ONLY valid JSON, no markdown fences.`;
|
|
111
|
+
logger.info(`Calling planner model (${config.planner.model})...`);
|
|
112
|
+
logger.debug(`Using model: ${model}`);
|
|
113
|
+
const response = await client.messages.create({
|
|
114
|
+
model,
|
|
115
|
+
max_tokens: 8192,
|
|
116
|
+
system: PLANNER_SYSTEM_PROMPT,
|
|
117
|
+
messages: [
|
|
118
|
+
{
|
|
119
|
+
role: "user",
|
|
120
|
+
content: userMessage,
|
|
121
|
+
},
|
|
122
|
+
],
|
|
123
|
+
});
|
|
124
|
+
// Extract text content from the response
|
|
125
|
+
let responseText = "";
|
|
126
|
+
for (const block of response.content) {
|
|
127
|
+
if (block.type === "text") {
|
|
128
|
+
responseText += block.text;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
logger.debug("Raw planner response received, parsing...");
|
|
132
|
+
// Try to extract JSON from the response
|
|
133
|
+
const spec = parsePlanSpec(responseText);
|
|
134
|
+
// Save to .bober/specs/
|
|
135
|
+
await saveSpec(projectRoot, spec);
|
|
136
|
+
logger.success(`Plan saved: ${spec.title} (${spec.features.length} features)`);
|
|
137
|
+
return spec;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Parse the planner response text into a validated PlanSpec.
|
|
141
|
+
*/
|
|
142
|
+
function parsePlanSpec(text) {
|
|
143
|
+
// Try direct parse first
|
|
144
|
+
let parsed;
|
|
145
|
+
try {
|
|
146
|
+
parsed = JSON.parse(text.trim());
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
// Try extracting JSON from markdown code fences
|
|
150
|
+
const fenceMatch = /```(?:json)?\s*\n?([\s\S]*?)\n?\s*```/.exec(text);
|
|
151
|
+
if (fenceMatch) {
|
|
152
|
+
try {
|
|
153
|
+
parsed = JSON.parse(fenceMatch[1].trim());
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
// Fall through to error
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// Try finding the first { ... } block
|
|
160
|
+
if (!parsed) {
|
|
161
|
+
const braceStart = text.indexOf("{");
|
|
162
|
+
const braceEnd = text.lastIndexOf("}");
|
|
163
|
+
if (braceStart !== -1 && braceEnd > braceStart) {
|
|
164
|
+
try {
|
|
165
|
+
parsed = JSON.parse(text.slice(braceStart, braceEnd + 1));
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
throw new Error("Failed to parse planner response as JSON. Raw response:\n" +
|
|
169
|
+
text.slice(0, 500));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
throw new Error("No JSON object found in planner response. Raw response:\n" +
|
|
174
|
+
text.slice(0, 500));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const result = PlanSpecSchema.safeParse(parsed);
|
|
179
|
+
if (!result.success) {
|
|
180
|
+
const issues = result.error.issues
|
|
181
|
+
.map((i) => ` - ${i.path.join(".")}: ${i.message}`)
|
|
182
|
+
.join("\n");
|
|
183
|
+
throw new Error(`Planner produced invalid PlanSpec:\n${issues}\n\nRaw:\n${JSON.stringify(parsed, null, 2).slice(0, 1000)}`);
|
|
184
|
+
}
|
|
185
|
+
return result.data;
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=planner-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planner-agent.js","sourceRoot":"","sources":["../../src/orchestrator/planner-agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/state/helpers.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/state/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEzC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAe;IAC7C,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { SprintContract } from "../contracts/sprint-contract.js";
|
|
3
|
+
import type { PlanSpec } from "../contracts/spec.js";
|
|
4
|
+
export declare const PhaseSchema: z.ZodEnum<["init", "planning", "generating", "evaluating", "rework", "complete", "failed"]>;
|
|
5
|
+
export type Phase = z.infer<typeof PhaseSchema>;
|
|
6
|
+
export declare const HistoryEntrySchema: z.ZodObject<{
|
|
7
|
+
timestamp: z.ZodString;
|
|
8
|
+
event: z.ZodString;
|
|
9
|
+
phase: z.ZodEnum<["init", "planning", "generating", "evaluating", "rework", "complete", "failed"]>;
|
|
10
|
+
sprintId: z.ZodOptional<z.ZodString>;
|
|
11
|
+
details: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
12
|
+
}, "strip", z.ZodTypeAny, {
|
|
13
|
+
timestamp: string;
|
|
14
|
+
details: Record<string, unknown>;
|
|
15
|
+
event: string;
|
|
16
|
+
phase: "evaluating" | "failed" | "init" | "planning" | "generating" | "rework" | "complete";
|
|
17
|
+
sprintId?: string | undefined;
|
|
18
|
+
}, {
|
|
19
|
+
timestamp: string;
|
|
20
|
+
details: Record<string, unknown>;
|
|
21
|
+
event: string;
|
|
22
|
+
phase: "evaluating" | "failed" | "init" | "planning" | "generating" | "rework" | "complete";
|
|
23
|
+
sprintId?: string | undefined;
|
|
24
|
+
}>;
|
|
25
|
+
export type HistoryEntry = z.infer<typeof HistoryEntrySchema>;
|
|
26
|
+
/**
|
|
27
|
+
* Append a history entry to the JSONL log file.
|
|
28
|
+
*/
|
|
29
|
+
export declare function appendHistory(projectRoot: string, entry: HistoryEntry): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Load all history entries from the JSONL log.
|
|
32
|
+
* Skips malformed lines.
|
|
33
|
+
*/
|
|
34
|
+
export declare function loadHistory(projectRoot: string): Promise<HistoryEntry[]>;
|
|
35
|
+
/**
|
|
36
|
+
* Update the human-readable progress.md file with current state.
|
|
37
|
+
*/
|
|
38
|
+
export declare function updateProgress(projectRoot: string, contracts: SprintContract[], spec: PlanSpec | null): Promise<void>;
|
|
39
|
+
//# sourceMappingURL=history.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/state/history.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAmBrD,eAAO,MAAM,WAAW,6FAQtB,CAAC;AACH,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEhD,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;EAM7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI9D;;GAEG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,CAAC,CAcf;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,EAAE,CAAC,CAyBzB;AAID;;GAEG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,cAAc,EAAE,EAC3B,IAAI,EAAE,QAAQ,GAAG,IAAI,GACpB,OAAO,CAAC,IAAI,CAAC,CAqFf"}
|