@slowcook-ai/cli 0.19.0-alpha.41 → 0.19.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/AGENTS.md +2 -2
- package/dist/cli.js +19 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/brand/index.d.ts +3 -35
- package/dist/commands/brand/index.d.ts.map +1 -1
- package/dist/commands/brew/agent.d.ts +7 -2
- package/dist/commands/brew/agent.d.ts.map +1 -1
- package/dist/commands/brew/agent.js +9 -0
- package/dist/commands/brew/agent.js.map +1 -1
- package/dist/commands/brew/halt.d.ts +26 -0
- package/dist/commands/brew/halt.d.ts.map +1 -1
- package/dist/commands/brew/halt.js.map +1 -1
- package/dist/commands/brew/index.d.ts.map +1 -1
- package/dist/commands/brew/index.js +81 -29
- package/dist/commands/brew/index.js.map +1 -1
- package/dist/commands/brew/pair-navigator.d.ts +7 -0
- package/dist/commands/brew/pair-navigator.d.ts.map +1 -1
- package/dist/commands/brew/pair-navigator.js +4 -0
- package/dist/commands/brew/pair-navigator.js.map +1 -1
- package/dist/commands/chef/drift-fix.d.ts +32 -3
- package/dist/commands/chef/drift-fix.d.ts.map +1 -1
- package/dist/commands/chef/drift-fix.js +381 -14
- package/dist/commands/chef/drift-fix.js.map +1 -1
- package/dist/commands/dev-env/config.d.ts +18 -97
- package/dist/commands/dev-env/config.d.ts.map +1 -1
- package/dist/commands/eval/index.d.ts.map +1 -1
- package/dist/commands/eval/index.js +13 -2
- package/dist/commands/eval/index.js.map +1 -1
- package/dist/commands/init/index.d.ts.map +1 -1
- package/dist/commands/init/index.js +33 -0
- package/dist/commands/init/index.js.map +1 -1
- package/dist/commands/init/mock-vite.d.ts.map +1 -1
- package/dist/commands/init/mock-vite.js +2 -0
- package/dist/commands/init/mock-vite.js.map +1 -1
- package/dist/commands/knowledge-add.d.ts +52 -0
- package/dist/commands/knowledge-add.d.ts.map +1 -0
- package/dist/commands/knowledge-add.js +232 -0
- package/dist/commands/knowledge-add.js.map +1 -0
- package/dist/commands/recon/index.d.ts +14 -1
- package/dist/commands/recon/index.d.ts.map +1 -1
- package/dist/commands/recon/index.js +43 -2
- package/dist/commands/recon/index.js.map +1 -1
- package/dist/commands/refine/agent.d.ts +11 -0
- package/dist/commands/refine/agent.d.ts.map +1 -1
- package/dist/commands/refine/agent.js +72 -2
- package/dist/commands/refine/agent.js.map +1 -1
- package/dist/commands/refine/context.d.ts +27 -1
- package/dist/commands/refine/context.d.ts.map +1 -1
- package/dist/commands/refine/context.js +425 -11
- package/dist/commands/refine/context.js.map +1 -1
- package/dist/commands/refine/git-attention.d.ts +123 -0
- package/dist/commands/refine/git-attention.d.ts.map +1 -0
- package/dist/commands/refine/git-attention.js +378 -0
- package/dist/commands/refine/git-attention.js.map +1 -0
- package/dist/commands/refine/history-index.d.ts +7 -0
- package/dist/commands/refine/history-index.d.ts.map +1 -1
- package/dist/commands/refine/history-index.js.map +1 -1
- package/dist/commands/refine/index.d.ts.map +1 -1
- package/dist/commands/refine/index.js +76 -20
- package/dist/commands/refine/index.js.map +1 -1
- package/dist/commands/refine/multifurcate.d.ts +129 -0
- package/dist/commands/refine/multifurcate.d.ts.map +1 -0
- package/dist/commands/refine/multifurcate.js +247 -0
- package/dist/commands/refine/multifurcate.js.map +1 -0
- package/dist/commands/refine/spec-yaml.d.ts +211 -1231
- package/dist/commands/refine/spec-yaml.d.ts.map +1 -1
- package/dist/commands/refresh-knowledge.d.ts +126 -0
- package/dist/commands/refresh-knowledge.d.ts.map +1 -0
- package/dist/commands/refresh-knowledge.js +1010 -0
- package/dist/commands/refresh-knowledge.js.map +1 -0
- package/dist/commands/testgen/agent.d.ts +13 -0
- package/dist/commands/testgen/agent.d.ts.map +1 -1
- package/dist/commands/testgen/agent.js +103 -2
- package/dist/commands/testgen/agent.js.map +1 -1
- package/dist/commands/upsert-agent-docs.d.ts +48 -0
- package/dist/commands/upsert-agent-docs.d.ts.map +1 -0
- package/dist/commands/upsert-agent-docs.js +298 -0
- package/dist/commands/upsert-agent-docs.js.map +1 -0
- package/dist/lib/budget.d.ts +2 -52
- package/dist/lib/budget.d.ts.map +1 -1
- package/dist/lib/mock-shape.d.ts +5 -20
- package/dist/lib/mock-shape.d.ts.map +1 -1
- package/package.json +9 -6
|
@@ -6,6 +6,7 @@ import { LlmCreditExhaustedError } from "@slowcook-ai/core";
|
|
|
6
6
|
import { AnthropicClient } from "./llm.js";
|
|
7
7
|
import { runRefinement, runResubmitRefinement, } from "./agent.js";
|
|
8
8
|
import { buildHistoryIndex } from "./history-index.js";
|
|
9
|
+
import { computeGitAttention } from "./git-attention.js";
|
|
9
10
|
function parseArgs(argv) {
|
|
10
11
|
const args = {
|
|
11
12
|
issueNumber: 0,
|
|
@@ -169,16 +170,9 @@ export async function refine(argv, cliVersion) {
|
|
|
169
170
|
console.log(`slowcook refine · resubmit on PR #${args.prNumber} on ${owner}/${repo} (refine model: ${args.refineModel})`);
|
|
170
171
|
// 0.17.0 — refresh history-index for the resubmit path too;
|
|
171
172
|
// brownfield context may have changed since the last refine.
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
mkdirSync(dirname(indexPath), { recursive: true });
|
|
176
|
-
writeFileSync(indexPath, JSON.stringify(idx, null, 2), "utf8");
|
|
177
|
-
console.log(` history-index: ${idx.components.length} components · ${idx.api_routes.length} api routes · ${idx.migrations.length} migrations`);
|
|
178
|
-
}
|
|
179
|
-
catch (e) {
|
|
180
|
-
console.warn(` (history-index emit failed: ${e.message})`);
|
|
181
|
-
}
|
|
173
|
+
// 0.19.0-α.43 — also enrich with git-history attention (renames,
|
|
174
|
+
// co-changes, recent PRs, PR+spec corpus).
|
|
175
|
+
emitHistoryIndex(args.repoRoot);
|
|
182
176
|
const outcome = await runResubmitRefinement(ctx);
|
|
183
177
|
switch (outcome.kind) {
|
|
184
178
|
case "resubmitted":
|
|
@@ -211,16 +205,8 @@ export async function refine(argv, cliVersion) {
|
|
|
211
205
|
// 0.17.0 — emit history-index.json for downstream agents (vibe,
|
|
212
206
|
// testgen, brew, recon) to consume. Pure mechanical scan; no LLM.
|
|
213
207
|
// The agent will read this in its prompt to be brownfield-aware.
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
const indexPath = join(args.repoRoot, ".brewing/history-index.json");
|
|
217
|
-
mkdirSync(dirname(indexPath), { recursive: true });
|
|
218
|
-
writeFileSync(indexPath, JSON.stringify(idx, null, 2), "utf8");
|
|
219
|
-
console.log(` history-index: ${idx.components.length} components · ${idx.api_routes.length} api routes · ${idx.migrations.length} migrations · ${idx.test_helpers.length} test helpers · ${idx.test_files.length} test files`);
|
|
220
|
-
}
|
|
221
|
-
catch (e) {
|
|
222
|
-
console.warn(` (history-index emit failed; refine will run without it: ${e.message})`);
|
|
223
|
-
}
|
|
208
|
+
// 0.19.0-α.43 — also enrich with git-history attention layer.
|
|
209
|
+
emitHistoryIndex(args.repoRoot);
|
|
224
210
|
let outcome;
|
|
225
211
|
try {
|
|
226
212
|
outcome = await runRefinement(ctx);
|
|
@@ -269,6 +255,9 @@ export async function refine(argv, cliVersion) {
|
|
|
269
255
|
case "change-of-mind-accepted":
|
|
270
256
|
console.log(`Change-of-mind accepted; will supersede ${outcome.supersedes.join(", ")}.`);
|
|
271
257
|
break;
|
|
258
|
+
case "multifurcation-proposed":
|
|
259
|
+
console.log(`Multifurcation proposal posted (comment ${outcome.commentId}): ${outcome.subIssueCount} sub-issues. Awaiting PM split decision.`);
|
|
260
|
+
break;
|
|
272
261
|
case "noop":
|
|
273
262
|
console.log(`Noop: ${outcome.reason}.`);
|
|
274
263
|
break;
|
|
@@ -282,4 +271,71 @@ export async function refine(argv, cliVersion) {
|
|
|
282
271
|
process.exit(2);
|
|
283
272
|
}
|
|
284
273
|
}
|
|
274
|
+
/**
|
|
275
|
+
* 0.19.0-α.43 — single source for emitting `.brewing/history-index.json`
|
|
276
|
+
* with both the filesystem scan AND the git-history attention layer.
|
|
277
|
+
*
|
|
278
|
+
* Failure-class handling:
|
|
279
|
+
* - filesystem scan fails → log + skip the whole emit (the refine agent
|
|
280
|
+
* can run without it, just with degraded brownfield awareness).
|
|
281
|
+
* - git enrichment fails → emit the index without `git_attention`; the
|
|
282
|
+
* warnings already log inside computeGitAttention.
|
|
283
|
+
*
|
|
284
|
+
* Both refine paths (issue + resubmit) call this; one site of truth.
|
|
285
|
+
*/
|
|
286
|
+
function emitHistoryIndex(repoRoot) {
|
|
287
|
+
let idx;
|
|
288
|
+
try {
|
|
289
|
+
idx = buildHistoryIndex({ repoRoot });
|
|
290
|
+
}
|
|
291
|
+
catch (e) {
|
|
292
|
+
console.warn(` (history-index emit failed; refine will run without it: ${e.message})`);
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
// 0.19.0-α.43 — collect tracked files from every entry that has a file
|
|
296
|
+
// path. Refine's git-attention is keyed by these. Excludes mock surface
|
|
297
|
+
// by design — mock files are design artifacts, not the brownfield
|
|
298
|
+
// history we want to attend to.
|
|
299
|
+
const trackedFiles = [
|
|
300
|
+
...idx.components.map((c) => c.file),
|
|
301
|
+
...idx.api_routes.map((r) => r.file),
|
|
302
|
+
...idx.test_helpers.map((h) => h.file),
|
|
303
|
+
...idx.test_files.map((t) => t.file),
|
|
304
|
+
];
|
|
305
|
+
// Migrations are listed by basename in the index; reconstruct the
|
|
306
|
+
// most-likely full path (we don't know which migration dir was used,
|
|
307
|
+
// so include them via supabase/migrations/ which is the default scan
|
|
308
|
+
// path). The git-attention layer will silently drop ones that aren't
|
|
309
|
+
// tracked by git.
|
|
310
|
+
for (const m of idx.migrations) {
|
|
311
|
+
trackedFiles.push(`supabase/migrations/${m.file}`);
|
|
312
|
+
}
|
|
313
|
+
try {
|
|
314
|
+
idx.git_attention = computeGitAttention({
|
|
315
|
+
repoRoot,
|
|
316
|
+
trackedFiles: Array.from(new Set(trackedFiles)),
|
|
317
|
+
});
|
|
318
|
+
if (idx.git_attention.warnings.length > 0) {
|
|
319
|
+
for (const w of idx.git_attention.warnings) {
|
|
320
|
+
console.warn(` (git-attention: ${w})`);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
catch (e) {
|
|
325
|
+
console.warn(` (git-attention enrichment failed; emitting index without it: ${e.message})`);
|
|
326
|
+
}
|
|
327
|
+
try {
|
|
328
|
+
const indexPath = join(repoRoot, ".brewing/history-index.json");
|
|
329
|
+
mkdirSync(dirname(indexPath), { recursive: true });
|
|
330
|
+
writeFileSync(indexPath, JSON.stringify(idx, null, 2), "utf8");
|
|
331
|
+
const ga = idx.git_attention;
|
|
332
|
+
const gaLine = ga
|
|
333
|
+
? ` · git-attention: ${Object.keys(ga.rename_chains).length} renames · ${Object.keys(ga.co_changes).length} co-change buckets · ${Object.keys(ga.recent_prs_by_file).length} files with PRs · corpus ${ga.pr_spec_corpus.length}`
|
|
334
|
+
: "";
|
|
335
|
+
console.log(` history-index: ${idx.components.length} components · ${idx.api_routes.length} api routes · ${idx.migrations.length} migrations · ${idx.test_helpers.length} test helpers · ${idx.test_files.length} test files${gaLine}`);
|
|
336
|
+
}
|
|
337
|
+
catch (e) {
|
|
338
|
+
console.warn(` (history-index write failed: ${e.message})`);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
285
341
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/refine/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EACL,aAAa,EACb,qBAAqB,GAGtB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/refine/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @slowcook 0.19.0-α.44 — multifurcation pre-step.
|
|
3
|
+
*
|
|
4
|
+
* Some GitHub issues are not stories. They are programs of work disguised
|
|
5
|
+
* as tickets ("everything according to mock", "rewrite the patient app",
|
|
6
|
+
* "wire X to Y" where X and Y are whole subsystems). Forcing those
|
|
7
|
+
* through refine produces a fuzzy mega-spec that no downstream agent can
|
|
8
|
+
* reasonably implement.
|
|
9
|
+
*
|
|
10
|
+
* This module runs a cheap LLM pass BEFORE refine's relationship +
|
|
11
|
+
* refinement calls. It returns either:
|
|
12
|
+
*
|
|
13
|
+
* - { kind: "one", rationale } — refine proceeds normally
|
|
14
|
+
* - { kind: "many", sub_issues, rationale } — refine posts a
|
|
15
|
+
* PM-facing proposal listing the proposed sub-issues + halts; the
|
|
16
|
+
* PM decides whether to file the split. The original issue is
|
|
17
|
+
* marked `slowcook-multifurcation-proposed` so refine doesn't loop.
|
|
18
|
+
*
|
|
19
|
+
* Sub-issue titles + summaries are PM-style by contract (see prompt
|
|
20
|
+
* rules): intent-shaped, no file paths or pipeline names, ≤ 80 char
|
|
21
|
+
* titles, 1-3 sentence summaries. Quality of the proposal is the
|
|
22
|
+
* PM's call — the comment template makes editing easy.
|
|
23
|
+
*/
|
|
24
|
+
import type { LlmClient, Spec } from "@slowcook-ai/core";
|
|
25
|
+
/**
|
|
26
|
+
* One existing spec the model needs to be aware of when proposing a
|
|
27
|
+
* split, so it can mark sub-issues that overlap with active scope
|
|
28
|
+
* INSTEAD of silently omitting them. The PM needs to see the full
|
|
29
|
+
* picture, not a hidden side-channel.
|
|
30
|
+
*
|
|
31
|
+
* Built from `listActiveSpecs(repoRoot)` — a single line of Spec.
|
|
32
|
+
*/
|
|
33
|
+
export interface ActiveSpecDigest {
|
|
34
|
+
story_id: string;
|
|
35
|
+
title: string;
|
|
36
|
+
summary: string;
|
|
37
|
+
}
|
|
38
|
+
export interface MultifurcationSubIssue {
|
|
39
|
+
title: string;
|
|
40
|
+
summary: string;
|
|
41
|
+
/** Optional — titles of OTHER sub-issues this one depends on landing first. */
|
|
42
|
+
depends_on?: string[];
|
|
43
|
+
/**
|
|
44
|
+
* cli α.45 — set when the proposed sub-issue's scope is already covered
|
|
45
|
+
* by an active spec. The PM still sees the sub-issue (so the parent
|
|
46
|
+
* issue's full scope is visible), but the comment renders an "Already
|
|
47
|
+
* covered by story-NNN" annotation and the PM can fold it into the
|
|
48
|
+
* existing story rather than opening a duplicate.
|
|
49
|
+
*/
|
|
50
|
+
existing_spec_id?: string;
|
|
51
|
+
}
|
|
52
|
+
export type MultifurcationVerdict = {
|
|
53
|
+
kind: "one";
|
|
54
|
+
rationale: string;
|
|
55
|
+
} | {
|
|
56
|
+
kind: "many";
|
|
57
|
+
rationale: string;
|
|
58
|
+
sub_issues: MultifurcationSubIssue[];
|
|
59
|
+
};
|
|
60
|
+
export interface MultifurcationInputs {
|
|
61
|
+
issueTitle: string;
|
|
62
|
+
issueBody: string;
|
|
63
|
+
/**
|
|
64
|
+
* cli α.45 — list of currently active specs in this repo. The
|
|
65
|
+
* multifurcation prompt uses them to annotate sub-issues that
|
|
66
|
+
* overlap with existing scope (story_id is the PM-visible
|
|
67
|
+
* reference; title + summary give the model enough context to
|
|
68
|
+
* decide whether overlap is real).
|
|
69
|
+
*
|
|
70
|
+
* Empty array is fine — model just won't tag anything.
|
|
71
|
+
*/
|
|
72
|
+
activeSpecs?: ActiveSpecDigest[];
|
|
73
|
+
}
|
|
74
|
+
export interface MultifurcationResult {
|
|
75
|
+
verdict: MultifurcationVerdict;
|
|
76
|
+
costUsd: number;
|
|
77
|
+
usage: {
|
|
78
|
+
inputTokens: number;
|
|
79
|
+
outputTokens: number;
|
|
80
|
+
cacheReadTokens: number;
|
|
81
|
+
cacheCreateTokens: number;
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export declare function assessMultifurcation(inputs: MultifurcationInputs, opts: {
|
|
85
|
+
llm: LlmClient;
|
|
86
|
+
model: string;
|
|
87
|
+
}): Promise<MultifurcationResult>;
|
|
88
|
+
/**
|
|
89
|
+
* Compose the user-side message. Exported for tests so the snapshot can
|
|
90
|
+
* assert active-specs context lands where the model expects it.
|
|
91
|
+
*/
|
|
92
|
+
export declare function buildMultifurcationUserMessage(inputs: MultifurcationInputs): string;
|
|
93
|
+
/**
|
|
94
|
+
* Compact a Spec list down to the digest shape the multifurcation
|
|
95
|
+
* prompt consumes. Summary is the first ~150 chars of the first
|
|
96
|
+
* acceptance scenario (the most spec-like prose); falls back to a
|
|
97
|
+
* non_goal or empty string.
|
|
98
|
+
*/
|
|
99
|
+
export declare function digestActiveSpecs(specs: Spec[]): ActiveSpecDigest[];
|
|
100
|
+
/**
|
|
101
|
+
* Parse the JSON verdict. Tolerant of leading/trailing prose (some
|
|
102
|
+
* models still wrap JSON in fences despite the prompt). Defaults to
|
|
103
|
+
* `{ kind: "one", rationale: "(parser fallback — model output unparseable)" }`
|
|
104
|
+
* so that an LLM hiccup never blocks refine.
|
|
105
|
+
*/
|
|
106
|
+
export declare function parseMultifurcationJson(text: string): MultifurcationVerdict;
|
|
107
|
+
/**
|
|
108
|
+
* PM-facing comment body listing the proposed sub-issues. The template
|
|
109
|
+
* mirrors the refine "questions-first" layout — proposal up top, agent's
|
|
110
|
+
* rationale folded into a <details> block, action prompts at the bottom.
|
|
111
|
+
*
|
|
112
|
+
* The HTML comment `<!-- slowcook:multifurcation -->` is a sentinel
|
|
113
|
+
* future refine runs grep for to skip re-proposing on the same issue.
|
|
114
|
+
*/
|
|
115
|
+
export declare function multifurcationCommentBody(proposal: {
|
|
116
|
+
rationale: string;
|
|
117
|
+
sub_issues: MultifurcationSubIssue[];
|
|
118
|
+
}, opts: {
|
|
119
|
+
issueTitle: string;
|
|
120
|
+
}): string;
|
|
121
|
+
/**
|
|
122
|
+
* Detect whether a multifurcation proposal has already been posted on
|
|
123
|
+
* an issue's comment thread. Used by the agent to skip re-running the
|
|
124
|
+
* LLM pass when the PM is still deciding.
|
|
125
|
+
*/
|
|
126
|
+
export declare function hasExistingMultifurcationComment(comments: Array<{
|
|
127
|
+
body: string;
|
|
128
|
+
}>): boolean;
|
|
129
|
+
//# sourceMappingURL=multifurcate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multifurcate.d.ts","sourceRoot":"","sources":["../../../src/commands/refine/multifurcate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAGzD;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,MAAM,qBAAqB,GAC7B;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,sBAAsB,EAAE,CAAA;CAAE,CAAC;AAE9E,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,qBAAqB,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE;QACL,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;QACxB,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC;CACH;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,oBAAoB,EAC5B,IAAI,EAAE;IAAE,GAAG,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACtC,OAAO,CAAC,oBAAoB,CAAC,CAe/B;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAwBnF;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,gBAAgB,EAAE,CAQnE;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,CA2E3E;AAyBD;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,sBAAsB,EAAE,CAAA;CAAE,EACrE,IAAI,EAAE;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,GAC3B,MAAM,CAkDR;AAMD;;;;GAIG;AACH,wBAAgB,gCAAgC,CAC9C,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAChC,OAAO,CAET"}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @slowcook 0.19.0-α.44 — multifurcation pre-step.
|
|
3
|
+
*
|
|
4
|
+
* Some GitHub issues are not stories. They are programs of work disguised
|
|
5
|
+
* as tickets ("everything according to mock", "rewrite the patient app",
|
|
6
|
+
* "wire X to Y" where X and Y are whole subsystems). Forcing those
|
|
7
|
+
* through refine produces a fuzzy mega-spec that no downstream agent can
|
|
8
|
+
* reasonably implement.
|
|
9
|
+
*
|
|
10
|
+
* This module runs a cheap LLM pass BEFORE refine's relationship +
|
|
11
|
+
* refinement calls. It returns either:
|
|
12
|
+
*
|
|
13
|
+
* - { kind: "one", rationale } — refine proceeds normally
|
|
14
|
+
* - { kind: "many", sub_issues, rationale } — refine posts a
|
|
15
|
+
* PM-facing proposal listing the proposed sub-issues + halts; the
|
|
16
|
+
* PM decides whether to file the split. The original issue is
|
|
17
|
+
* marked `slowcook-multifurcation-proposed` so refine doesn't loop.
|
|
18
|
+
*
|
|
19
|
+
* Sub-issue titles + summaries are PM-style by contract (see prompt
|
|
20
|
+
* rules): intent-shaped, no file paths or pipeline names, ≤ 80 char
|
|
21
|
+
* titles, 1-3 sentence summaries. Quality of the proposal is the
|
|
22
|
+
* PM's call — the comment template makes editing easy.
|
|
23
|
+
*/
|
|
24
|
+
import { MULTIFURCATION_SYSTEM } from "@slowcook-ai/llm-anthropic";
|
|
25
|
+
export async function assessMultifurcation(inputs, opts) {
|
|
26
|
+
const userMessage = buildMultifurcationUserMessage(inputs);
|
|
27
|
+
const response = await opts.llm.complete({
|
|
28
|
+
system: MULTIFURCATION_SYSTEM,
|
|
29
|
+
cacheSystem: false,
|
|
30
|
+
model: opts.model,
|
|
31
|
+
messages: [{ role: "user", content: userMessage }],
|
|
32
|
+
maxTokens: 2048,
|
|
33
|
+
});
|
|
34
|
+
return {
|
|
35
|
+
verdict: parseMultifurcationJson(response.text),
|
|
36
|
+
costUsd: response.costUsd,
|
|
37
|
+
usage: response.usage,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Compose the user-side message. Exported for tests so the snapshot can
|
|
42
|
+
* assert active-specs context lands where the model expects it.
|
|
43
|
+
*/
|
|
44
|
+
export function buildMultifurcationUserMessage(inputs) {
|
|
45
|
+
const sections = [];
|
|
46
|
+
sections.push("## Issue under review");
|
|
47
|
+
sections.push(`### Title\n${inputs.issueTitle}`);
|
|
48
|
+
sections.push(`### Body\n${inputs.issueBody || "(empty body)"}`);
|
|
49
|
+
const specs = inputs.activeSpecs ?? [];
|
|
50
|
+
if (specs.length > 0) {
|
|
51
|
+
sections.push("## Active specs in this repo");
|
|
52
|
+
sections.push("If any proposed sub-issue's scope is ALREADY covered by one of these, " +
|
|
53
|
+
"set `existing_spec_id` to that story_id in the sub-issue object. " +
|
|
54
|
+
"Still include the sub-issue in the proposal — the PM needs the full picture, " +
|
|
55
|
+
"the annotation tells them this slice is already on the ratchet. " +
|
|
56
|
+
"Do NOT silently omit overlapping sub-issues.");
|
|
57
|
+
for (const s of specs) {
|
|
58
|
+
const summary = s.summary && s.summary.length > 0 ? ` — ${s.summary}` : "";
|
|
59
|
+
sections.push(`- **story-${s.story_id}** "${s.title}"${summary}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
sections.push("Return the JSON verdict per the system prompt.");
|
|
63
|
+
return sections.join("\n\n");
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Compact a Spec list down to the digest shape the multifurcation
|
|
67
|
+
* prompt consumes. Summary is the first ~150 chars of the first
|
|
68
|
+
* acceptance scenario (the most spec-like prose); falls back to a
|
|
69
|
+
* non_goal or empty string.
|
|
70
|
+
*/
|
|
71
|
+
export function digestActiveSpecs(specs) {
|
|
72
|
+
return specs.map((s) => {
|
|
73
|
+
const firstScenario = s.acceptance_scenarios[0] ?? "";
|
|
74
|
+
const firstInvariant = s.invariants[0] ?? "";
|
|
75
|
+
const raw = firstScenario || firstInvariant || s.non_goals[0] || "";
|
|
76
|
+
const summary = raw.replace(/\s+/g, " ").trim().slice(0, 150);
|
|
77
|
+
return { story_id: s.story_id, title: s.title, summary };
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Parse the JSON verdict. Tolerant of leading/trailing prose (some
|
|
82
|
+
* models still wrap JSON in fences despite the prompt). Defaults to
|
|
83
|
+
* `{ kind: "one", rationale: "(parser fallback — model output unparseable)" }`
|
|
84
|
+
* so that an LLM hiccup never blocks refine.
|
|
85
|
+
*/
|
|
86
|
+
export function parseMultifurcationJson(text) {
|
|
87
|
+
const json = extractJsonBlob(text);
|
|
88
|
+
if (!json) {
|
|
89
|
+
return {
|
|
90
|
+
kind: "one",
|
|
91
|
+
rationale: "(parser fallback — model output unparseable, treating as single story)",
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
let raw;
|
|
95
|
+
try {
|
|
96
|
+
raw = JSON.parse(json);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return {
|
|
100
|
+
kind: "one",
|
|
101
|
+
rationale: "(parser fallback — JSON parse failed)",
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
if (!raw || typeof raw !== "object") {
|
|
105
|
+
return { kind: "one", rationale: "(parser fallback — non-object verdict)" };
|
|
106
|
+
}
|
|
107
|
+
const o = raw;
|
|
108
|
+
const verdict = typeof o.verdict === "string" ? o.verdict.toLowerCase() : "";
|
|
109
|
+
const rationale = typeof o.rationale === "string" ? o.rationale.trim() : "";
|
|
110
|
+
if (verdict === "one") {
|
|
111
|
+
return { kind: "one", rationale: rationale || "(no rationale provided)" };
|
|
112
|
+
}
|
|
113
|
+
if (verdict === "many") {
|
|
114
|
+
const subRaw = Array.isArray(o.sub_issues) ? o.sub_issues : [];
|
|
115
|
+
const sub_issues = [];
|
|
116
|
+
for (const entry of subRaw) {
|
|
117
|
+
if (!entry || typeof entry !== "object")
|
|
118
|
+
continue;
|
|
119
|
+
const e = entry;
|
|
120
|
+
const title = typeof e.title === "string" ? e.title.trim() : "";
|
|
121
|
+
const summary = typeof e.summary === "string" ? e.summary.trim() : "";
|
|
122
|
+
if (!title || !summary)
|
|
123
|
+
continue;
|
|
124
|
+
const depRaw = Array.isArray(e.depends_on) ? e.depends_on : [];
|
|
125
|
+
const depends_on = depRaw
|
|
126
|
+
.filter((d) => typeof d === "string" && d.trim().length > 0)
|
|
127
|
+
.map((d) => d.trim());
|
|
128
|
+
const item = { title, summary };
|
|
129
|
+
if (depends_on.length > 0)
|
|
130
|
+
item.depends_on = depends_on;
|
|
131
|
+
// cli α.45 — overlap annotation. Accept variants the model may
|
|
132
|
+
// emit (existing_spec_id, story_id, covered_by_story) and
|
|
133
|
+
// normalize to plain digit-suffix form ("002" not "story-002").
|
|
134
|
+
const rawId = (typeof e.existing_spec_id === "string" && e.existing_spec_id) ||
|
|
135
|
+
(typeof e.covered_by_story === "string" && e.covered_by_story) ||
|
|
136
|
+
(typeof e.story_id === "string" && e.story_id) ||
|
|
137
|
+
"";
|
|
138
|
+
const normalised = rawId.trim().replace(/^story-/i, "");
|
|
139
|
+
if (normalised.length > 0)
|
|
140
|
+
item.existing_spec_id = normalised;
|
|
141
|
+
sub_issues.push(item);
|
|
142
|
+
}
|
|
143
|
+
// Guardrail: if the model said "many" but failed to produce ≥2 valid
|
|
144
|
+
// sub-issues, fall back to "one" rather than emit a broken proposal.
|
|
145
|
+
// Always tag the rationale so downstream logs reveal the downgrade.
|
|
146
|
+
if (sub_issues.length < 2) {
|
|
147
|
+
const prefix = "(parser fallback — verdict was many but fewer than 2 valid sub-issues parsed)";
|
|
148
|
+
return {
|
|
149
|
+
kind: "one",
|
|
150
|
+
rationale: rationale ? `${prefix} · original rationale: ${rationale}` : prefix,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
kind: "many",
|
|
155
|
+
rationale: rationale || "(no rationale provided)",
|
|
156
|
+
sub_issues,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
kind: "one",
|
|
161
|
+
rationale: rationale || `(parser fallback — unknown verdict "${verdict}")`,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Extract the first balanced { ... } JSON blob from raw model text.
|
|
166
|
+
* Strips common decorations: leading prose, ```json fences, trailing
|
|
167
|
+
* commentary. Returns null if no balanced object is found.
|
|
168
|
+
*/
|
|
169
|
+
function extractJsonBlob(text) {
|
|
170
|
+
const fenced = text.match(/```(?:json)?\s*(\{[\s\S]*?\})\s*```/);
|
|
171
|
+
if (fenced && fenced[1])
|
|
172
|
+
return fenced[1];
|
|
173
|
+
const start = text.indexOf("{");
|
|
174
|
+
if (start === -1)
|
|
175
|
+
return null;
|
|
176
|
+
let depth = 0;
|
|
177
|
+
for (let i = start; i < text.length; i++) {
|
|
178
|
+
const ch = text[i];
|
|
179
|
+
if (ch === "{")
|
|
180
|
+
depth++;
|
|
181
|
+
else if (ch === "}") {
|
|
182
|
+
depth--;
|
|
183
|
+
if (depth === 0)
|
|
184
|
+
return text.slice(start, i + 1);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* PM-facing comment body listing the proposed sub-issues. The template
|
|
191
|
+
* mirrors the refine "questions-first" layout — proposal up top, agent's
|
|
192
|
+
* rationale folded into a <details> block, action prompts at the bottom.
|
|
193
|
+
*
|
|
194
|
+
* The HTML comment `<!-- slowcook:multifurcation -->` is a sentinel
|
|
195
|
+
* future refine runs grep for to skip re-proposing on the same issue.
|
|
196
|
+
*/
|
|
197
|
+
export function multifurcationCommentBody(proposal, opts) {
|
|
198
|
+
const lines = [];
|
|
199
|
+
lines.push("<!-- slowcook:multifurcation -->");
|
|
200
|
+
lines.push("### slowcook · refinement agent 🍲");
|
|
201
|
+
lines.push("");
|
|
202
|
+
lines.push(`This issue looks like **more than one story** to me. Before I produce a spec, please confirm the split below — refine ships one PR per story, and a single mega-spec usually misses the things that matter at each user-facing slice.`);
|
|
203
|
+
lines.push("");
|
|
204
|
+
const overlapCount = proposal.sub_issues.filter((s) => s.existing_spec_id).length;
|
|
205
|
+
lines.push(`#### Proposed sub-issues (${proposal.sub_issues.length}${overlapCount > 0 ? `, ${overlapCount} overlap existing specs` : ""})`);
|
|
206
|
+
lines.push("");
|
|
207
|
+
for (let i = 0; i < proposal.sub_issues.length; i++) {
|
|
208
|
+
const s = proposal.sub_issues[i];
|
|
209
|
+
const overlapBadge = s.existing_spec_id
|
|
210
|
+
? ` _(already covered by story-${escapeMd(s.existing_spec_id)})_`
|
|
211
|
+
: "";
|
|
212
|
+
lines.push(`**${i + 1}. ${escapeMd(s.title)}**${overlapBadge}`);
|
|
213
|
+
lines.push("");
|
|
214
|
+
lines.push(escapeMd(s.summary));
|
|
215
|
+
if (s.depends_on && s.depends_on.length > 0) {
|
|
216
|
+
lines.push("");
|
|
217
|
+
lines.push(`_Depends on: ${s.depends_on.map((d) => `"${d}"`).join(", ")}_`);
|
|
218
|
+
}
|
|
219
|
+
lines.push("");
|
|
220
|
+
}
|
|
221
|
+
lines.push("<details><summary>Why I think this should split</summary>");
|
|
222
|
+
lines.push("");
|
|
223
|
+
lines.push(proposal.rationale);
|
|
224
|
+
lines.push("");
|
|
225
|
+
lines.push("</details>");
|
|
226
|
+
lines.push("");
|
|
227
|
+
lines.push("#### What to do");
|
|
228
|
+
lines.push("");
|
|
229
|
+
lines.push("- 👍 **Looks right** → file each sub-issue that DOESN'T have an _already covered by_ tag. For tagged ones, decide per row whether to fold them into the existing story (comment on that story) or skip. Then close this one or remove `needs-refinement` from it.");
|
|
230
|
+
lines.push("- ✏️ **Needs tweaking** → reply with the edited list (edit titles, drop or add entries, change overlap calls). Remove the `slowcook-multifurcation-proposed` label and I'll re-propose.");
|
|
231
|
+
lines.push("- 👎 **Keep as one** → reply \"keep as one\" and remove both labels (`slowcook-multifurcation-proposed` and `needs-refinement`, then re-add `needs-refinement`). I'll proceed with a single spec.");
|
|
232
|
+
lines.push("");
|
|
233
|
+
lines.push(`_For context, the original title was: **${escapeMd(opts.issueTitle)}**_`);
|
|
234
|
+
return lines.join("\n");
|
|
235
|
+
}
|
|
236
|
+
function escapeMd(s) {
|
|
237
|
+
return s.replace(/</g, "<").replace(/>/g, ">");
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Detect whether a multifurcation proposal has already been posted on
|
|
241
|
+
* an issue's comment thread. Used by the agent to skip re-running the
|
|
242
|
+
* LLM pass when the PM is still deciding.
|
|
243
|
+
*/
|
|
244
|
+
export function hasExistingMultifurcationComment(comments) {
|
|
245
|
+
return comments.some((c) => c.body.includes("<!-- slowcook:multifurcation -->"));
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=multifurcate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multifurcate.js","sourceRoot":"","sources":["../../../src/commands/refine/multifurcate.ts"],"names":[],"mappings":"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"}
|