@slowcook-ai/cli 0.13.0-alpha.3 → 0.13.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.
Files changed (41) hide show
  1. package/dist/cli.js +16 -0
  2. package/dist/cli.js.map +1 -1
  3. package/dist/commands/chef/classify.d.ts +65 -0
  4. package/dist/commands/chef/classify.d.ts.map +1 -0
  5. package/dist/commands/chef/classify.js +102 -0
  6. package/dist/commands/chef/classify.js.map +1 -0
  7. package/dist/commands/chef/index.d.ts +22 -0
  8. package/dist/commands/chef/index.d.ts.map +1 -0
  9. package/dist/commands/chef/index.js +287 -0
  10. package/dist/commands/chef/index.js.map +1 -0
  11. package/dist/commands/investigate/agent.d.ts.map +1 -1
  12. package/dist/commands/investigate/agent.js +39 -1
  13. package/dist/commands/investigate/agent.js.map +1 -1
  14. package/dist/commands/investigate/index.d.ts.map +1 -1
  15. package/dist/commands/investigate/index.js +126 -9
  16. package/dist/commands/investigate/index.js.map +1 -1
  17. package/dist/commands/investigate/prompts.d.ts +1 -1
  18. package/dist/commands/investigate/prompts.d.ts.map +1 -1
  19. package/dist/commands/investigate/prompts.js +48 -1
  20. package/dist/commands/investigate/prompts.js.map +1 -1
  21. package/dist/commands/recipe-regression/agent.d.ts +94 -0
  22. package/dist/commands/recipe-regression/agent.d.ts.map +1 -0
  23. package/dist/commands/recipe-regression/agent.js +442 -0
  24. package/dist/commands/recipe-regression/agent.js.map +1 -0
  25. package/dist/commands/recipe-regression/index.d.ts +12 -1
  26. package/dist/commands/recipe-regression/index.d.ts.map +1 -1
  27. package/dist/commands/recipe-regression/index.js +45 -8
  28. package/dist/commands/recipe-regression/index.js.map +1 -1
  29. package/dist/commands/sift/agent.d.ts +52 -0
  30. package/dist/commands/sift/agent.d.ts.map +1 -0
  31. package/dist/commands/sift/agent.js +392 -0
  32. package/dist/commands/sift/agent.js.map +1 -0
  33. package/dist/commands/sift/index.d.ts +23 -0
  34. package/dist/commands/sift/index.d.ts.map +1 -0
  35. package/dist/commands/sift/index.js +314 -0
  36. package/dist/commands/sift/index.js.map +1 -0
  37. package/dist/commands/sift/prompts.d.ts +114 -0
  38. package/dist/commands/sift/prompts.d.ts.map +1 -0
  39. package/dist/commands/sift/prompts.js +193 -0
  40. package/dist/commands/sift/prompts.js.map +1 -0
  41. package/package.json +2 -2
@@ -0,0 +1,314 @@
1
+ /**
2
+ * `slowcook sift --bug B-N` — bug-flow brew analogue.
3
+ *
4
+ * Reads a bug-profile + the regression test, runs an LLM ratchet to
5
+ * make the regression go green, halts when:
6
+ * - regression test passes (green = success)
7
+ * - budget cap hit
8
+ * - max iterations hit
9
+ * - agent halts voluntarily
10
+ *
11
+ * Usage:
12
+ * slowcook sift --bug B-1 [--cwd <path>] [--model <id>]
13
+ * [--max-iterations <n>] [--budget-usd <n>]
14
+ * [--dry-run]
15
+ */
16
+ import { existsSync, readFileSync, readdirSync } from "node:fs";
17
+ import { join } from "node:path";
18
+ import { execSync } from "node:child_process";
19
+ import { GitHubAdapter } from "@slowcook-ai/forge-github";
20
+ import { runSift } from "./agent.js";
21
+ import { loadBugProfile } from "../recipe-regression/index.js";
22
+ import { validateStackConfig } from "@slowcook-ai/stack-ts";
23
+ function parseArgs(argv) {
24
+ const args = {
25
+ bugId: "",
26
+ repoRoot: process.cwd(),
27
+ model: "claude-sonnet-4-6", // Sift defaults to Sonnet — narrow fixes shouldn't need Opus.
28
+ maxIterations: 3,
29
+ budgetUsd: 0.5,
30
+ dryRun: false,
31
+ noPr: false,
32
+ };
33
+ for (let i = 0; i < argv.length; i++) {
34
+ const arg = argv[i];
35
+ const next = argv[i + 1];
36
+ if (arg === "--bug" && next) {
37
+ args.bugId = normaliseBugId(next);
38
+ i++;
39
+ }
40
+ else if (arg === "--cwd" && next) {
41
+ args.repoRoot = next;
42
+ i++;
43
+ }
44
+ else if (arg === "--model" && next) {
45
+ args.model = next;
46
+ i++;
47
+ }
48
+ else if ((arg === "--max-iterations" || arg === "--iters") && next) {
49
+ args.maxIterations = parseInt(next, 10);
50
+ i++;
51
+ }
52
+ else if (arg === "--budget-usd" && next) {
53
+ args.budgetUsd = parseFloat(next);
54
+ i++;
55
+ }
56
+ else if (arg === "--dry-run") {
57
+ args.dryRun = true;
58
+ }
59
+ else if (arg === "--no-pr") {
60
+ args.noPr = true;
61
+ }
62
+ else if (arg === "--owner" && next) {
63
+ args.owner = next;
64
+ i++;
65
+ }
66
+ else if (arg === "--repo" && next) {
67
+ args.repo = next;
68
+ i++;
69
+ }
70
+ else if (arg === "--help" || arg === "-h") {
71
+ printHelp();
72
+ process.exit(0);
73
+ }
74
+ }
75
+ return args;
76
+ }
77
+ function normaliseBugId(raw) {
78
+ const m = raw.trim().match(/^B?-?(\d+)$/i);
79
+ if (!m || !m[1])
80
+ return raw;
81
+ return `B-${m[1]}`;
82
+ }
83
+ function printHelp() {
84
+ console.log(`
85
+ slowcook sift — narrow red→green ratchet for a bug fix
86
+
87
+ Reads .brewing/bug-profiles/B-N.yaml + the matching regression test
88
+ under tests/regression/B-N-*.test.ts, runs an LLM agent in a tight
89
+ loop to flip the regression to green with minimum-diff edits scoped
90
+ to the bug profile's fix_scope.
91
+
92
+ Usage:
93
+ slowcook sift --bug B-1 [options]
94
+
95
+ Options:
96
+ --bug <id> Bug id (B-N or just N).
97
+ --cwd <path> Repo root (default: cwd).
98
+ --model <id> LLM model (default: claude-sonnet-4-6).
99
+ --max-iterations <n> Max iterations (default: 3).
100
+ --budget-usd <n> Spend cap in USD (default: 0.5).
101
+ --dry-run Print plan + exit; don't make LLM calls.
102
+
103
+ Environment:
104
+ ANTHROPIC_API_KEY (required unless --dry-run)
105
+ GITHUB_TOKEN (optional; not used by sift directly today)
106
+
107
+ Exit codes:
108
+ 0 regression went green
109
+ 1 halted (budget / iters / voluntary halt / no-progress)
110
+ 2 setup error (missing profile / regression test / stack config)
111
+ `);
112
+ }
113
+ export async function sift(argv, cliVersion) {
114
+ const args = parseArgs(argv);
115
+ if (!args.bugId) {
116
+ console.error("slowcook sift: --bug <id> is required");
117
+ printHelp();
118
+ process.exit(64);
119
+ }
120
+ // Load bug profile + regression test + stack config.
121
+ let bugProfile;
122
+ try {
123
+ bugProfile = loadBugProfile(args.repoRoot, args.bugId);
124
+ }
125
+ catch (e) {
126
+ console.error(`slowcook sift: ${e.message}`);
127
+ process.exit(2);
128
+ }
129
+ const regressionTestPath = findRegressionTestForBug(args.repoRoot, args.bugId);
130
+ if (!regressionTestPath) {
131
+ console.error(`slowcook sift: no regression test found at tests/regression/${args.bugId}-*.test.ts. ` +
132
+ `Run 'slowcook recipe --regression --bug ${args.bugId}' first.`);
133
+ process.exit(2);
134
+ }
135
+ const regressionTestSrc = readFileSync(join(args.repoRoot, regressionTestPath), "utf8");
136
+ let stackConfig;
137
+ try {
138
+ const raw = JSON.parse(readFileSync(join(args.repoRoot, ".brewing/stack.json"), "utf8"));
139
+ stackConfig = validateStackConfig(raw);
140
+ }
141
+ catch (e) {
142
+ console.error(`slowcook sift: stack.json missing or invalid: ${e.message}`);
143
+ process.exit(2);
144
+ }
145
+ console.error(`slowcook sift (${cliVersion}) — ${args.bugId}, model ${args.model}, max ${args.maxIterations} iter, budget $${args.budgetUsd.toFixed(2)}.`);
146
+ console.error(` bug profile : .brewing/bug-profiles/${args.bugId}.yaml`);
147
+ console.error(` regression : ${regressionTestPath}`);
148
+ console.error(` fix_scope : ${bugProfile.fix_scope.join(", ")}`);
149
+ if (args.dryRun) {
150
+ console.error("\n(dry-run: would invoke runSift; not making LLM calls)");
151
+ process.exit(0);
152
+ }
153
+ const apiKey = process.env["ANTHROPIC_API_KEY"];
154
+ if (!apiKey) {
155
+ console.error("slowcook sift: ANTHROPIC_API_KEY is required");
156
+ process.exit(78);
157
+ }
158
+ const ctx = {
159
+ repoRoot: args.repoRoot,
160
+ anthropicApiKey: apiKey,
161
+ model: args.model,
162
+ bugProfile,
163
+ regressionTestPath,
164
+ regressionTestSrc,
165
+ stackConfig,
166
+ maxIterations: args.maxIterations,
167
+ budgetUsd: args.budgetUsd,
168
+ };
169
+ const branchName = `slowcook/sift/${args.bugId}-${Date.now()}`;
170
+ // Create the branch BEFORE the agent edits so the diff lands on
171
+ // the sift branch, not on whatever branch was checked out.
172
+ try {
173
+ execSync(`git -C "${args.repoRoot}" checkout -b ${branchName}`, {
174
+ stdio: ["ignore", "pipe", "pipe"],
175
+ });
176
+ }
177
+ catch (e) {
178
+ console.error(`slowcook sift: could not create branch ${branchName}: ${e.message}`);
179
+ process.exit(2);
180
+ }
181
+ const result = await runSift(ctx);
182
+ console.error("");
183
+ if (result.green) {
184
+ console.error(`✓ Sift succeeded — regression green after ${result.iterations} iter(s), $${result.spendUsd.toFixed(4)} spent.`);
185
+ console.error(` Files touched: ${result.filesTouched.join(", ") || "(none)"}`);
186
+ }
187
+ else {
188
+ console.error(`✗ Sift halted: ${result.haltReason}. ${result.iterations} iter(s), $${result.spendUsd.toFixed(4)} spent.`);
189
+ if (result.filesTouched.length > 0) {
190
+ console.error(` Files touched: ${result.filesTouched.join(", ")}`);
191
+ }
192
+ }
193
+ // Commit + push + open PR even on halt — the operator wants to see
194
+ // partial progress when sift halts mid-fix. Skipped only on
195
+ // --no-pr or when no files were edited.
196
+ if (args.noPr) {
197
+ console.error(`(--no-pr: branch ${branchName} kept locally; commit/push/PR skipped.)`);
198
+ process.exit(result.green ? 0 : 1);
199
+ }
200
+ if (result.filesTouched.length === 0) {
201
+ console.error(`(no files edited; nothing to push.)`);
202
+ process.exit(result.green ? 0 : 1);
203
+ }
204
+ await openSiftPr({
205
+ repoRoot: args.repoRoot,
206
+ bugId: args.bugId,
207
+ branchName,
208
+ profile: bugProfile,
209
+ result,
210
+ owner: args.owner,
211
+ repo: args.repo,
212
+ cliVersion,
213
+ });
214
+ process.exit(result.green ? 0 : 1);
215
+ }
216
+ async function openSiftPr(args) {
217
+ const githubToken = process.env["GITHUB_TOKEN"];
218
+ if (!githubToken) {
219
+ console.error(`GITHUB_TOKEN not set — branch ${args.branchName} kept locally with edits but PR not opened.`);
220
+ return;
221
+ }
222
+ const detected = detectOwnerRepo(args.repoRoot);
223
+ const owner = args.owner ?? detected?.owner;
224
+ const repo = args.repo ?? detected?.repo;
225
+ if (!owner || !repo) {
226
+ console.error("Could not detect owner/repo from git remote — pass --owner + --repo to open the PR.");
227
+ return;
228
+ }
229
+ const forge = new GitHubAdapter({ owner, repo, token: githubToken });
230
+ try {
231
+ // Stage all touched files + commit + push.
232
+ for (const f of args.result.filesTouched) {
233
+ await forge.git.stage(f);
234
+ }
235
+ await forge.git.commit(`slowcook sift ${args.result.green ? "✓" : "(partial)"} ${args.bugId}: ${args.result.iterations} iter(s) · $${args.result.spendUsd.toFixed(2)}`);
236
+ await forge.git.push(args.branchName);
237
+ }
238
+ catch (e) {
239
+ console.error(`Push failed: ${e.message}. Branch is local; commit/push manually.`);
240
+ return;
241
+ }
242
+ try {
243
+ const titlePrefix = args.result.green ? "sift ✓" : "sift (partial)";
244
+ const pr = await forge.createPullRequest({
245
+ title: `${titlePrefix} ${args.bugId}: ${args.profile.title}`,
246
+ body: buildSiftPrBody(args),
247
+ base: "main",
248
+ head: args.branchName,
249
+ draft: !args.result.green,
250
+ labels: ["slowcook-sift", "bug"],
251
+ });
252
+ console.error(`Opened PR ${pr.url}.`);
253
+ }
254
+ catch (e) {
255
+ console.error(`Pushed branch ${args.branchName} but PR open failed: ${e.message}\n Open manually at https://github.com/${owner}/${repo}/pull/new/${args.branchName}`);
256
+ }
257
+ }
258
+ function detectOwnerRepo(repoRoot) {
259
+ try {
260
+ const url = execSync("git remote get-url origin", {
261
+ cwd: repoRoot,
262
+ encoding: "utf8",
263
+ stdio: ["ignore", "pipe", "ignore"],
264
+ }).trim();
265
+ const m = url.match(/github\.com[:/]([^/]+)\/([^/.]+)(?:\.git)?$/);
266
+ if (m && m[1] && m[2])
267
+ return { owner: m[1], repo: m[2] };
268
+ }
269
+ catch {
270
+ /* not a git repo */
271
+ }
272
+ return null;
273
+ }
274
+ function buildSiftPrBody(args) {
275
+ const lines = [];
276
+ lines.push(`Auto-emitted by \`slowcook sift\` (${args.cliVersion}) for bug profile \`${args.bugId}\`.`);
277
+ lines.push("");
278
+ lines.push(`Closes related: ${args.profile.source_issue}`);
279
+ lines.push("");
280
+ lines.push("## Result");
281
+ lines.push(`- **${args.result.green ? "Regression GREEN" : "Halted: " + (args.result.haltReason ?? "(unknown)")}**`);
282
+ lines.push(`- Iterations: ${args.result.iterations}`);
283
+ lines.push(`- Spend: $${args.result.spendUsd.toFixed(4)}`);
284
+ lines.push(`- Files: ${args.result.filesTouched.map((f) => "`" + f + "`").join(", ") || "(none)"}`);
285
+ lines.push("");
286
+ lines.push("## Bug profile (summary)");
287
+ lines.push(`**Symptom:** ${args.profile.symptom.join(" / ")}`);
288
+ lines.push("");
289
+ lines.push(`**Failure locus:** \`${args.profile.failure_locus.file}\`${args.profile.failure_locus.line ? `:${args.profile.failure_locus.line}` : ""}`);
290
+ lines.push(`> ${args.profile.failure_locus.diagnosis.split("\n").join("\n> ")}`);
291
+ lines.push("");
292
+ lines.push("## Verification");
293
+ lines.push(`Sift's ratchet ran the regression test (\`tests/regression/${args.bugId}-*.test.ts\`) after each iteration; ` +
294
+ `it ${args.result.green ? "passed on iteration " + args.result.iterations : "remained red — see haltReason"}.`);
295
+ return lines.join("\n");
296
+ }
297
+ /**
298
+ * Find the regression test file for a bug. Looks for
299
+ * `tests/regression/B-N-<slug>.test.ts` (matching what
300
+ * recipe --regression emits).
301
+ */
302
+ export function findRegressionTestForBug(repoRoot, bugId) {
303
+ const dir = join(repoRoot, "tests/regression");
304
+ if (!existsSync(dir))
305
+ return null;
306
+ const prefix = `${bugId}-`;
307
+ for (const entry of readdirSync(dir)) {
308
+ if (entry.startsWith(prefix) && entry.endsWith(".test.ts")) {
309
+ return `tests/regression/${entry}`;
310
+ }
311
+ }
312
+ return null;
313
+ }
314
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/sift/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Prompts for the `slowcook sift` agent.
3
+ *
4
+ * Sift is the bug-flow analogue of brew. Where brew is exploratory
5
+ * and ratchets across many iterations to flip many tests green, sift
6
+ * is **narrow**: one bug, one regression test, minimum-diff fix.
7
+ *
8
+ * The system prompt has a different orientation from brew's:
9
+ * - "the regression test is the contract" (not "the spec")
10
+ * - "the bug profile names the failure locus — go there first"
11
+ * - "touch the named file and nothing else; halt voluntarily if
12
+ * the fix needs more"
13
+ * - "this is restoration, not feature work — match existing patterns
14
+ * instead of inventing"
15
+ */
16
+ export declare const SIFT_SYSTEM = "You are the sift agent for slowcook \u2014 a TDD-first bug-fix flow.\n\n## Your role\n\nYou receive a bug profile (from investigate) and a regression test (from recipe --regression). The regression test is currently RED against the codebase. Your job: make a minimum-diff code change that flips it to GREEN, without disturbing anything else.\n\nYou are NOT brew. Brew implements features from a fresh spec \u2014 you implement fixes for known regressions. Different posture:\n\n- **The regression test IS the contract.** You don't read the spec; you read the test. The test names exactly what behavior must hold; your fix makes that behavior hold.\n- **The bug profile names the failure locus.** The investigate agent already did the diagnostic work \u2014 `failure_locus.file`, `.line`, `.function`, `.diagnosis`. Trust that. Open the file, find the named function, see why the test is failing.\n- **Stay inside fix_scope.** The bug profile lists `fix_scope` paths \u2014 those are your allowed_paths. If your edit needs to touch something outside, halt voluntarily and let the operator widen scope (the locus is probably wrong).\n- **Restoration, not invention.** Match the patterns already in the file. If you're tempted to introduce a new pattern, halt \u2014 that's a story-shaped change, not a bug fix.\n- **Minimum diff.** Bug fixes that look like refactors are bug fixes that have lost the plot. If your diff is more than ~30 lines across more than 2 files, you've drifted. Halt.\n\n## Tools\n\n- **read_file(path)** \u2014 read a file in full.\n- **outline_file(path)** \u2014 compact ~200-token outline (imports, exports, signatures with line numbers). Use first.\n- **list_directory(path)** \u2014 see what's in a dir.\n- **find_references(symbol)** \u2014 find all use sites of a symbol; useful before renaming or extending an existing function.\n- **find_definition(symbol)** \u2014 find where a symbol is declared.\n- **grep(pattern, glob?)** \u2014 repo-wide ripgrep.\n- **write_file(path, contents)** \u2014 replace a file with new contents. Read first, then write the COMPLETE updated contents.\n\nYou do NOT have `run_tests` \u2014 slowcook runs the regression test between your turns and tells you the result in the next prompt. Your only output per turn is read calls + at most one write call.\n\n## Halting voluntarily\n\nIf after one turn of investigation the fix doesn't look minimum-diff\nwithin the bug profile's `fix_scope`, end your turn with:\n\n```\n<halt>\n<reason>One-line reason \u2014 e.g., \"fix requires touching files outside fix_scope\" or \"regression test asserts behavior the named locus doesn't actually control\".</reason>\n</halt>\n```\n\nThe operator picks up your halt, edits the bug profile or widens the scope, and re-runs sift. **Don't guess.** A wrong fix that flips the regression test green by accident is worse than a clean halt \u2014 sift's mistake compounds into the next bug.\n\n## Iteration limits\n\nDefault budget: 3 iterations, ~$0.50 spend cap. The harness halts you automatically beyond that. If you can't fix it in 3 turns, the bug profile is wrong or the scope is too narrow \u2014 halt voluntarily on iteration 2 with a diagnostic.\n";
17
+ /**
18
+ * Anthropic-shape tool definitions sift presents to the LLM. Subset
19
+ * of brew's: read tools + write_file. Excludes brew's
20
+ * \`justify_diff_overflow\` (sift halts instead of overflowing) and
21
+ * \`find_handler\` (sift's failure locus is already named).
22
+ */
23
+ export declare const SIFT_TOOLS: ({
24
+ name: string;
25
+ description: string;
26
+ input_schema: {
27
+ type: "object";
28
+ properties: {
29
+ path: {
30
+ type: "string";
31
+ description: string;
32
+ };
33
+ symbol?: undefined;
34
+ pattern?: undefined;
35
+ glob?: undefined;
36
+ contents?: undefined;
37
+ };
38
+ required: string[];
39
+ };
40
+ } | {
41
+ name: string;
42
+ description: string;
43
+ input_schema: {
44
+ type: "object";
45
+ properties: {
46
+ symbol: {
47
+ type: "string";
48
+ description: string;
49
+ };
50
+ path?: undefined;
51
+ pattern?: undefined;
52
+ glob?: undefined;
53
+ contents?: undefined;
54
+ };
55
+ required: string[];
56
+ };
57
+ } | {
58
+ name: string;
59
+ description: string;
60
+ input_schema: {
61
+ type: "object";
62
+ properties: {
63
+ pattern: {
64
+ type: "string";
65
+ description: string;
66
+ };
67
+ glob: {
68
+ type: "string";
69
+ description: string;
70
+ };
71
+ path?: undefined;
72
+ symbol?: undefined;
73
+ contents?: undefined;
74
+ };
75
+ required: string[];
76
+ };
77
+ } | {
78
+ name: string;
79
+ description: string;
80
+ input_schema: {
81
+ type: "object";
82
+ properties: {
83
+ path: {
84
+ type: "string";
85
+ description: string;
86
+ };
87
+ contents: {
88
+ type: "string";
89
+ description: string;
90
+ };
91
+ symbol?: undefined;
92
+ pattern?: undefined;
93
+ glob?: undefined;
94
+ };
95
+ required: string[];
96
+ };
97
+ })[];
98
+ export interface SiftTurnPromptArgs {
99
+ iteration: number;
100
+ maxIterations: number;
101
+ bugProfileYaml: string;
102
+ regressionTestPath: string;
103
+ regressionTestSrc: string;
104
+ /** Latest test run result. Empty on iter 1. */
105
+ testResult?: {
106
+ status: "red" | "green";
107
+ /** Vitest failure message for the regression test (when red). */
108
+ failureMessage?: string;
109
+ };
110
+ /** Files sift has touched in prior iters. Empty on iter 1. */
111
+ priorEdits?: string[];
112
+ }
113
+ export declare function buildSiftTurnPrompt(args: SiftTurnPromptArgs): string;
114
+ //# sourceMappingURL=prompts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/commands/sift/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,eAAO,MAAM,WAAW,moGA0CvB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAwFtB,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,+CAA+C;IAC/C,UAAU,CAAC,EAAE;QACX,MAAM,EAAE,KAAK,GAAG,OAAO,CAAC;QACxB,iEAAiE;QACjE,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CA4CpE"}
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Prompts for the `slowcook sift` agent.
3
+ *
4
+ * Sift is the bug-flow analogue of brew. Where brew is exploratory
5
+ * and ratchets across many iterations to flip many tests green, sift
6
+ * is **narrow**: one bug, one regression test, minimum-diff fix.
7
+ *
8
+ * The system prompt has a different orientation from brew's:
9
+ * - "the regression test is the contract" (not "the spec")
10
+ * - "the bug profile names the failure locus — go there first"
11
+ * - "touch the named file and nothing else; halt voluntarily if
12
+ * the fix needs more"
13
+ * - "this is restoration, not feature work — match existing patterns
14
+ * instead of inventing"
15
+ */
16
+ export const SIFT_SYSTEM = `You are the sift agent for slowcook — a TDD-first bug-fix flow.
17
+
18
+ ## Your role
19
+
20
+ You receive a bug profile (from investigate) and a regression test (from recipe --regression). The regression test is currently RED against the codebase. Your job: make a minimum-diff code change that flips it to GREEN, without disturbing anything else.
21
+
22
+ You are NOT brew. Brew implements features from a fresh spec — you implement fixes for known regressions. Different posture:
23
+
24
+ - **The regression test IS the contract.** You don't read the spec; you read the test. The test names exactly what behavior must hold; your fix makes that behavior hold.
25
+ - **The bug profile names the failure locus.** The investigate agent already did the diagnostic work — \`failure_locus.file\`, \`.line\`, \`.function\`, \`.diagnosis\`. Trust that. Open the file, find the named function, see why the test is failing.
26
+ - **Stay inside fix_scope.** The bug profile lists \`fix_scope\` paths — those are your allowed_paths. If your edit needs to touch something outside, halt voluntarily and let the operator widen scope (the locus is probably wrong).
27
+ - **Restoration, not invention.** Match the patterns already in the file. If you're tempted to introduce a new pattern, halt — that's a story-shaped change, not a bug fix.
28
+ - **Minimum diff.** Bug fixes that look like refactors are bug fixes that have lost the plot. If your diff is more than ~30 lines across more than 2 files, you've drifted. Halt.
29
+
30
+ ## Tools
31
+
32
+ - **read_file(path)** — read a file in full.
33
+ - **outline_file(path)** — compact ~200-token outline (imports, exports, signatures with line numbers). Use first.
34
+ - **list_directory(path)** — see what's in a dir.
35
+ - **find_references(symbol)** — find all use sites of a symbol; useful before renaming or extending an existing function.
36
+ - **find_definition(symbol)** — find where a symbol is declared.
37
+ - **grep(pattern, glob?)** — repo-wide ripgrep.
38
+ - **write_file(path, contents)** — replace a file with new contents. Read first, then write the COMPLETE updated contents.
39
+
40
+ You do NOT have \`run_tests\` — slowcook runs the regression test between your turns and tells you the result in the next prompt. Your only output per turn is read calls + at most one write call.
41
+
42
+ ## Halting voluntarily
43
+
44
+ If after one turn of investigation the fix doesn't look minimum-diff
45
+ within the bug profile's \`fix_scope\`, end your turn with:
46
+
47
+ \`\`\`
48
+ <halt>
49
+ <reason>One-line reason — e.g., "fix requires touching files outside fix_scope" or "regression test asserts behavior the named locus doesn't actually control".</reason>
50
+ </halt>
51
+ \`\`\`
52
+
53
+ The operator picks up your halt, edits the bug profile or widens the scope, and re-runs sift. **Don't guess.** A wrong fix that flips the regression test green by accident is worse than a clean halt — sift's mistake compounds into the next bug.
54
+
55
+ ## Iteration limits
56
+
57
+ Default budget: 3 iterations, ~$0.50 spend cap. The harness halts you automatically beyond that. If you can't fix it in 3 turns, the bug profile is wrong or the scope is too narrow — halt voluntarily on iteration 2 with a diagnostic.
58
+ `;
59
+ /**
60
+ * Anthropic-shape tool definitions sift presents to the LLM. Subset
61
+ * of brew's: read tools + write_file. Excludes brew's
62
+ * \`justify_diff_overflow\` (sift halts instead of overflowing) and
63
+ * \`find_handler\` (sift's failure locus is already named).
64
+ */
65
+ export const SIFT_TOOLS = [
66
+ {
67
+ name: "read_file",
68
+ description: "Read a file's full contents. Always read before write_file on the same path.",
69
+ input_schema: {
70
+ type: "object",
71
+ properties: {
72
+ path: { type: "string", description: "Repo-relative path." },
73
+ },
74
+ required: ["path"],
75
+ },
76
+ },
77
+ {
78
+ name: "outline_file",
79
+ description: "Compact outline (imports, top-level exports, signatures with line numbers). Use first to scope.",
80
+ input_schema: {
81
+ type: "object",
82
+ properties: {
83
+ path: { type: "string", description: "Repo-relative path." },
84
+ },
85
+ required: ["path"],
86
+ },
87
+ },
88
+ {
89
+ name: "list_directory",
90
+ description: "List entries in a directory.",
91
+ input_schema: {
92
+ type: "object",
93
+ properties: {
94
+ path: { type: "string", description: "Repo-relative path." },
95
+ },
96
+ required: ["path"],
97
+ },
98
+ },
99
+ {
100
+ name: "find_references",
101
+ description: "All use sites of a symbol across the repo (file:line entries).",
102
+ input_schema: {
103
+ type: "object",
104
+ properties: {
105
+ symbol: { type: "string", description: "Identifier name." },
106
+ },
107
+ required: ["symbol"],
108
+ },
109
+ },
110
+ {
111
+ name: "find_definition",
112
+ description: "Where a symbol is declared.",
113
+ input_schema: {
114
+ type: "object",
115
+ properties: {
116
+ symbol: { type: "string", description: "Identifier name." },
117
+ },
118
+ required: ["symbol"],
119
+ },
120
+ },
121
+ {
122
+ name: "grep",
123
+ description: "Repo-wide ripgrep. Use when find_references is too narrow (e.g. searching column names in SQL files).",
124
+ input_schema: {
125
+ type: "object",
126
+ properties: {
127
+ pattern: { type: "string", description: "Pattern to search." },
128
+ glob: {
129
+ type: "string",
130
+ description: "Optional glob (e.g., 'supabase/migrations/*.sql').",
131
+ },
132
+ },
133
+ required: ["pattern"],
134
+ },
135
+ },
136
+ {
137
+ name: "write_file",
138
+ description: "Create or fully replace a file. ALWAYS read first, then write the complete updated contents. Restricted to paths inside the bug profile's fix_scope.",
139
+ input_schema: {
140
+ type: "object",
141
+ properties: {
142
+ path: { type: "string", description: "Repo-relative path." },
143
+ contents: { type: "string", description: "Full new file contents." },
144
+ },
145
+ required: ["path", "contents"],
146
+ },
147
+ },
148
+ ];
149
+ export function buildSiftTurnPrompt(args) {
150
+ const lines = [];
151
+ lines.push(`# Sift iteration ${args.iteration} of ${args.maxIterations}`);
152
+ lines.push("");
153
+ lines.push("## Bug profile");
154
+ lines.push("```yaml");
155
+ lines.push(args.bugProfileYaml);
156
+ lines.push("```");
157
+ lines.push("");
158
+ lines.push("## Regression test (the contract)");
159
+ lines.push(`File: \`${args.regressionTestPath}\``);
160
+ lines.push("```ts");
161
+ lines.push(args.regressionTestSrc);
162
+ lines.push("```");
163
+ lines.push("");
164
+ if (args.testResult) {
165
+ if (args.testResult.status === "green") {
166
+ lines.push("## Last run: GREEN");
167
+ lines.push("");
168
+ lines.push("The regression test now passes. You're done — emit a `<halt>` with `<reason>regression green</reason>` so the harness can wrap up.");
169
+ }
170
+ else {
171
+ lines.push("## Last run: RED");
172
+ if (args.testResult.failureMessage) {
173
+ lines.push("```");
174
+ lines.push(args.testResult.failureMessage.slice(0, 1500));
175
+ lines.push("```");
176
+ }
177
+ else {
178
+ lines.push("(no failure message captured — run the regression file by hand to see why)");
179
+ }
180
+ }
181
+ lines.push("");
182
+ }
183
+ if (args.priorEdits && args.priorEdits.length > 0) {
184
+ lines.push("## Prior edits this run");
185
+ for (const e of args.priorEdits)
186
+ lines.push(`- \`${e}\``);
187
+ lines.push("");
188
+ }
189
+ lines.push("## Your turn");
190
+ lines.push("Read the failure_locus file, identify why the regression assertion fails, write the minimum diff that flips it. Stay inside fix_scope. Halt voluntarily if the fix needs more.");
191
+ return lines.join("\n");
192
+ }
193
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/commands/sift/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0C1B,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB;QACE,IAAI,EAAE,WAAW;QACjB,WAAW,EACT,8EAA8E;QAChF,YAAY,EAAE;YACZ,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE;gBACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAiB,EAAE,WAAW,EAAE,qBAAqB,EAAE;aACtE;YACD,QAAQ,EAAE,CAAC,MAAM,CAAC;SACnB;KACF;IACD;QACE,IAAI,EAAE,cAAc;QACpB,WAAW,EACT,iGAAiG;QACnG,YAAY,EAAE;YACZ,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE;gBACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAiB,EAAE,WAAW,EAAE,qBAAqB,EAAE;aACtE;YACD,QAAQ,EAAE,CAAC,MAAM,CAAC;SACnB;KACF;IACD;QACE,IAAI,EAAE,gBAAgB;QACtB,WAAW,EAAE,8BAA8B;QAC3C,YAAY,EAAE;YACZ,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE;gBACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAiB,EAAE,WAAW,EAAE,qBAAqB,EAAE;aACtE;YACD,QAAQ,EAAE,CAAC,MAAM,CAAC;SACnB;KACF;IACD;QACE,IAAI,EAAE,iBAAiB;QACvB,WAAW,EACT,gEAAgE;QAClE,YAAY,EAAE;YACZ,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE;gBACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAiB,EAAE,WAAW,EAAE,kBAAkB,EAAE;aACrE;YACD,QAAQ,EAAE,CAAC,QAAQ,CAAC;SACrB;KACF;IACD;QACE,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,6BAA6B;QAC1C,YAAY,EAAE;YACZ,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE;gBACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAiB,EAAE,WAAW,EAAE,kBAAkB,EAAE;aACrE;YACD,QAAQ,EAAE,CAAC,QAAQ,CAAC;SACrB;KACF;IACD;QACE,IAAI,EAAE,MAAM;QACZ,WAAW,EACT,uGAAuG;QACzG,YAAY,EAAE;YACZ,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE;gBACV,OAAO,EAAE,EAAE,IAAI,EAAE,QAAiB,EAAE,WAAW,EAAE,oBAAoB,EAAE;gBACvE,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAiB;oBACvB,WAAW,EAAE,oDAAoD;iBAClE;aACF;YACD,QAAQ,EAAE,CAAC,SAAS,CAAC;SACtB;KACF;IACD;QACE,IAAI,EAAE,YAAY;QAClB,WAAW,EACT,sJAAsJ;QACxJ,YAAY,EAAE;YACZ,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE;gBACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAiB,EAAE,WAAW,EAAE,qBAAqB,EAAE;gBACrE,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAiB,EAAE,WAAW,EAAE,yBAAyB,EAAE;aAC9E;YACD,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC;SAC/B;KACF;CACF,CAAC;AAkBF,MAAM,UAAU,mBAAmB,CAAC,IAAwB;IAC1D,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,oBAAoB,IAAI,CAAC,SAAS,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;IAC1E,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC7B,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACtB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAChC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IAChD,KAAK,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,kBAAkB,IAAI,CAAC,CAAC;IACnD,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACnC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;YACvC,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CACR,oIAAoI,CACrI,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YAC/B,IAAI,IAAI,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC;gBACnC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAClB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;gBAC1D,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACpB,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,IAAI,CAAC,4EAA4E,CAAC,CAAC;YAC3F,CAAC;QACH,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IACD,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QACtC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,UAAU;YAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC3B,KAAK,CAAC,IAAI,CACR,gLAAgL,CACjL,CAAC;IACF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}