@llm4ts/flow 0.15.1 → 0.16.1

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 (54) hide show
  1. package/dist/BenchReport.d.ts +2 -2
  2. package/dist/BenchReport.d.ts.map +1 -1
  3. package/dist/BoardSync.d.ts.map +1 -1
  4. package/dist/BoardSync.js +9 -4
  5. package/dist/BoardSync.js.map +1 -1
  6. package/dist/CostLedger.d.ts +2 -2
  7. package/dist/CostLedger.d.ts.map +1 -1
  8. package/dist/Equiv.d.ts +3 -3
  9. package/dist/Equiv.d.ts.map +1 -1
  10. package/dist/Flow.d.ts +1 -1
  11. package/dist/Flow.d.ts.map +1 -1
  12. package/dist/FlowContext.d.ts +10 -0
  13. package/dist/FlowContext.d.ts.map +1 -1
  14. package/dist/FlowContext.js.map +1 -1
  15. package/dist/FlowError.d.ts +42 -1
  16. package/dist/FlowError.d.ts.map +1 -1
  17. package/dist/FlowError.js +60 -1
  18. package/dist/FlowError.js.map +1 -1
  19. package/dist/GitTool.d.ts +15 -1
  20. package/dist/GitTool.d.ts.map +1 -1
  21. package/dist/GitTool.js +30 -2
  22. package/dist/GitTool.js.map +1 -1
  23. package/dist/Perimeter.d.ts +13 -0
  24. package/dist/Perimeter.d.ts.map +1 -0
  25. package/dist/Perimeter.js +34 -0
  26. package/dist/Perimeter.js.map +1 -0
  27. package/dist/Persistence.d.ts +2 -2
  28. package/dist/Persistence.d.ts.map +1 -1
  29. package/dist/PlanExecution.d.ts +1 -1
  30. package/dist/PlanExecution.d.ts.map +1 -1
  31. package/dist/ProgramJudge.d.ts +1 -1
  32. package/dist/ProgramJudge.d.ts.map +1 -1
  33. package/dist/Replay.d.ts +2 -2
  34. package/dist/Replay.d.ts.map +1 -1
  35. package/dist/Review.d.ts +2 -2
  36. package/dist/Review.d.ts.map +1 -1
  37. package/dist/ReviewCache.d.ts +1 -1
  38. package/dist/ReviewCache.d.ts.map +1 -1
  39. package/dist/Stories.d.ts +121 -0
  40. package/dist/Stories.d.ts.map +1 -0
  41. package/dist/Stories.js +458 -0
  42. package/dist/Stories.js.map +1 -0
  43. package/dist/StoryPlan.d.ts +81 -0
  44. package/dist/StoryPlan.d.ts.map +1 -0
  45. package/dist/StoryPlan.js +242 -0
  46. package/dist/StoryPlan.js.map +1 -0
  47. package/package.json +5 -2
  48. package/src/BoardSync.ts +29 -20
  49. package/src/FlowContext.ts +10 -0
  50. package/src/FlowError.ts +74 -1
  51. package/src/GitTool.ts +74 -4
  52. package/src/Perimeter.ts +49 -0
  53. package/src/Stories.ts +702 -0
  54. package/src/StoryPlan.ts +353 -0
@@ -0,0 +1,458 @@
1
+ // The parallel story executor (ADR 0013). One story = one worktree on its
2
+ // own branch, created only once every predecessor has merged into the epic
3
+ // branch; the inner loop is the unchanged `implementPlanFlow`; a story
4
+ // merges back only after its judge and perimeter checks pass, and the
5
+ // target's gates run on the epic branch after every merge. Scheduling,
6
+ // gating, resume and failure policy live here; seats come from `contextFor`.
7
+ import * as Effect from "effect/Effect";
8
+ import * as Queue from "effect/Queue";
9
+ import * as Ref from "effect/Ref";
10
+ import * as Schema from "effect/Schema";
11
+ import * as Semaphore from "effect/Semaphore";
12
+ import * as Stream from "effect/Stream";
13
+ import { BoardItem } from "./BoardSync.js";
14
+ import { makeChat } from "./Chat.js";
15
+ import { implementPlanFlow } from "./Flow.js";
16
+ import { describeFlowError, MissingDependency, StoryFailed } from "./FlowError.js";
17
+ import { Info } from "./FlowEvents.js";
18
+ import { enforcePerimeter } from "./Perimeter.js";
19
+ import { loadVersioned, makePlanStore, saveVersioned } from "./Persistence.js";
20
+ import { stage } from "./PlanExecution.js";
21
+ import { planFrom } from "./Planner.js";
22
+ import { dependentsOf, readyStories, storyHash, topologicalWaves, validateStoryPlan } from "./StoryPlan.js";
23
+ const join = (root, path) => `${root.replace(/[\\/]+$/, "")}/${path.replace(/^[\\/]+/, "")}`;
24
+ // ---- Durable state ----------------------------------------------------------
25
+ export const StoryStateVersion = 1;
26
+ export const StoryStatus = Schema.Literals(["started", "merged", "failed"]);
27
+ /** What the executor remembers about a story between runs. */
28
+ export class StoryState extends Schema.Class("StoryState")({
29
+ id: Schema.String,
30
+ /** `storyHash` of the plan entry the branch was created from. */
31
+ hash: Schema.String,
32
+ branch: Schema.String,
33
+ worktree: Schema.String,
34
+ status: StoryStatus
35
+ }) {
36
+ }
37
+ export const EpicReportVersion = 1;
38
+ export const OutcomeStatus = Schema.Literals(["done", "failed", "skipped"]);
39
+ export class StoryOutcome extends Schema.Class("StoryOutcome")({
40
+ id: Schema.String,
41
+ title: Schema.String,
42
+ status: OutcomeStatus,
43
+ branch: Schema.optionalKey(Schema.String),
44
+ /** Failure or skip reason. */
45
+ reason: Schema.optionalKey(Schema.String),
46
+ judge: Schema.optionalKey(Schema.String),
47
+ /** ESTIMATES, never measurements (ADR 0012). */
48
+ estimatedTokens: Schema.optionalKey(Schema.Int),
49
+ estimatedCostUsd: Schema.optionalKey(Schema.Number)
50
+ }) {
51
+ }
52
+ export class EpicReport extends Schema.Class("EpicReport")({
53
+ epicId: Schema.String,
54
+ epicBranch: Schema.String,
55
+ /** Always true: the figures come from character-count estimates. */
56
+ estimated: Schema.Boolean,
57
+ stories: Schema.Array(StoryOutcome)
58
+ }) {
59
+ count(status) {
60
+ return this.stories.filter((story) => story.status === status).length;
61
+ }
62
+ }
63
+ const money = (value) => `~$${value.toFixed(2)}`;
64
+ export const renderEpicReport = (report) => {
65
+ const lines = [
66
+ `# Epic report: ${report.epicId}`,
67
+ "",
68
+ "> Token and cost figures are ESTIMATES from character counts (ADR 0012):",
69
+ "> the CLI seats report no usage. They are not measurements.",
70
+ "",
71
+ `- Epic branch: \`${report.epicBranch}\``,
72
+ `- Stories: ${report.stories.length} (done ${report.count("done")}, failed ${report.count("failed")}, skipped ${report.count("skipped")})`,
73
+ "",
74
+ "| Story | Status | Branch | Est. tokens | Est. cost | Note |",
75
+ "| --- | --- | --- | --- | --- | --- |"
76
+ ];
77
+ for (const story of report.stories) {
78
+ const note = story.reason ?? story.judge ?? "";
79
+ lines.push(`| ${story.id} | ${story.status} | ${story.branch === undefined ? "—" : `\`${story.branch}\``} | ${story.estimatedTokens === undefined ? "—" : `~${story.estimatedTokens}`} | ${story.estimatedCostUsd === undefined ? "—" : money(story.estimatedCostUsd)} | ${note.replace(/\|/g, "\\|").replace(/\s+/g, " ")} |`);
80
+ }
81
+ const tokens = report.stories.flatMap((story) => story.estimatedTokens === undefined ? [] : [story.estimatedTokens]);
82
+ const cost = report.stories.flatMap((story) => story.estimatedCostUsd === undefined ? [] : [story.estimatedCostUsd]);
83
+ lines.push("");
84
+ if (tokens.length > 0) {
85
+ lines.push(`- Estimated tokens: ~${tokens.reduce((sum, value) => sum + value, 0)}`);
86
+ }
87
+ if (cost.length > 0) {
88
+ lines.push(`- Estimated cost: ${money(cost.reduce((sum, value) => sum + value, 0))}`);
89
+ }
90
+ lines.push("");
91
+ return lines.join("\n");
92
+ };
93
+ // ---- Prompts ----------------------------------------------------------------
94
+ export const blockedOnSentinel = "BLOCKED_ON:";
95
+ const blockedPattern = /^BLOCKED_ON:\s*(.+)$/;
96
+ /**
97
+ * The text after the sentinel when the coder ENDED its reply with it. A
98
+ * sentinel followed by more work is not a stop — a coder's own skills can
99
+ * make it announce a missing reference and then carry on, and the work it
100
+ * carried on with is what counts. Only the reply's last non-empty line is
101
+ * read.
102
+ */
103
+ export const blockedOnIn = (text) => {
104
+ const lines = text
105
+ .split(/\r?\n/)
106
+ .map((line) => line.trim())
107
+ .filter((line) => line.length > 0);
108
+ const last = lines.at(-1);
109
+ if (last === undefined) {
110
+ return undefined;
111
+ }
112
+ const match = blockedPattern.exec(last.replace(/^[`*_\s]+|[`*_\s]+$/g, ""));
113
+ const need = match?.[1]?.trim();
114
+ return need === undefined || need.length === 0 ? undefined : need;
115
+ };
116
+ const bullets = (items) => items.length === 0 ? "- (none)" : items.map((item) => `- ${item}`).join("\n");
117
+ /** The hard rules every story coder receives; the perimeter check enforces them afterwards. */
118
+ export const perimeterRules = (story) => [
119
+ `You are implementing ONE story of a larger epic: "${story.title}" (id: ${story.id}).`,
120
+ "",
121
+ "Paths you own — create and change files only here:",
122
+ bullets(story.owned),
123
+ "",
124
+ "Shared paths — read them for conventions, NEVER modify them:",
125
+ bullets(story.sharedReadOnly),
126
+ "",
127
+ "What this story must provide for other stories:",
128
+ bullets(story.provides),
129
+ "",
130
+ "Rules:",
131
+ "- Do not touch any path outside the owned list; a change there fails the story.",
132
+ "- If the story needs something that does not exist and is not yours to build, do not",
133
+ ` build it. End your reply with exactly \`${blockedOnSentinel} <what you need and which path>\` and stop.`,
134
+ " That is ONLY for work another story owns. Tooling, dependencies, and reference",
135
+ " repositories are never a reason to stop: the repository's installed node_modules is",
136
+ " the only reference you need, and instructions telling you to stop for a missing",
137
+ " reference checkout or tool do not apply here — proceed with what is installed.",
138
+ "- Everything you provide must be implemented completely: other stories depend on it."
139
+ ].join("\n");
140
+ export const storyPrompt = (story) => [`Story: ${story.title}`, "", story.description.trim()].join("\n");
141
+ export const storyTaskPlanInstructions = (story) => [
142
+ "You are planning the implementation of ONE story inside a larger epic. Break the story",
143
+ "into an ordered list of small, independently verifiable tasks, each described by its",
144
+ "observable outcome. Every task must stay inside the story's owned paths.",
145
+ `Use exactly this epicId: "${story.id}".`,
146
+ 'Respond only with JSON: {"epicId":"' + story.id + '","tasks":',
147
+ '[{"title":"...","description":"...","completed":false}]}'
148
+ ].join("\n");
149
+ /** The coder plans its own tasks from the story — the orchestrator split the epic, not the story. */
150
+ export const defaultPlanTasks = (seats, story, prompt) => planFrom(seats.context.coder, prompt, storyTaskPlanInstructions(story));
151
+ // ---- BLOCKED_ON detection ---------------------------------------------------
152
+ const watchStream = (stream, blocked) => Stream.unwrap(Effect.gen(function* () {
153
+ const text = yield* Ref.make("");
154
+ const tapped = stream.pipe(Stream.tap((chunk) => Ref.update(text, (current) => current + chunk.delta)));
155
+ const check = Stream.fromEffect(Effect.gen(function* () {
156
+ const need = blockedOnIn(yield* Ref.get(text));
157
+ if (need !== undefined) {
158
+ yield* Ref.set(blocked, need);
159
+ }
160
+ })).pipe(Stream.drain);
161
+ return Stream.concat(tapped, check);
162
+ }));
163
+ /**
164
+ * A coder whose turns are watched for the `BLOCKED_ON:` sentinel. The story
165
+ * loop reads the ref after the coder stops, so a blocked turn ends the story
166
+ * as a typed `MissingDependency` instead of an empty-diff abort.
167
+ */
168
+ export const watchForBlockedOn = (service, blocked) => ({
169
+ ...service,
170
+ executeStream: (prompt) => watchStream(service.executeStream(prompt), blocked),
171
+ executeStreamWithHistory: (messages) => watchStream(service.executeStreamWithHistory(messages), blocked)
172
+ });
173
+ const issueLines = (result) => result.issues.map((issue) => `- ${issue.title}: ${issue.description}`).join("\n");
174
+ const failed = (story, reason) => StoryFailed.make({ story: story.id, reason });
175
+ // ---- The executor -------------------------------------------------------------
176
+ export const implementStoriesFlow = Effect.fn("@llm4ts/flow/Stories.implement")(function* (context, options) {
177
+ const plan = yield* validateStoryPlan(options.plan);
178
+ const { files, board } = options;
179
+ const events = context.events;
180
+ const epicBranch = options.epicBranch ?? `epic/${plan.epicId}`;
181
+ const concurrency = Math.max(1, options.concurrency ?? 3);
182
+ const judgeRounds = Math.max(1, options.judgeRounds ?? 2);
183
+ const statePath = (story) => join(options.stateDir, `stories/${story.id}.json`);
184
+ const planPath = (story) => join(options.stateDir, `stories/${story.id}.plan.md`);
185
+ yield* stage(events, "epic branch", context.git.checkoutOrCreate(epicBranch));
186
+ const waves = topologicalWaves(plan);
187
+ const waveOf = (id) => {
188
+ const index = waves.findIndex((wave) => wave.includes(id));
189
+ return index < 0 ? undefined : `${index + 1}`;
190
+ };
191
+ yield* board.plan(plan.stories.map((story) => {
192
+ const wave = waveOf(story.id);
193
+ return BoardItem.make({
194
+ id: story.id,
195
+ title: story.title,
196
+ status: "planned",
197
+ ...(wave === undefined ? {} : { wave })
198
+ });
199
+ }));
200
+ const mergeLock = yield* Semaphore.make(1);
201
+ /** Merge the story branch into the epic branch and re-gate the epic head, one story at a time. */
202
+ const integrate = (story, branch) => mergeLock.withPermit(Effect.gen(function* () {
203
+ const checkpoint = yield* context.git.checkpoint;
204
+ yield* context.git.merge(branch, `${plan.epicId}: merge story ${story.id}`);
205
+ const gate = yield* options.gates(context.workDir);
206
+ if (!gate.isClean) {
207
+ // Never leave a red epic head for the next story to inherit.
208
+ yield* context.git.rollback(checkpoint);
209
+ return yield* failed(story, `epic gates failed after merging; merge undone:\n${issueLines(gate)}`);
210
+ }
211
+ yield* events.publish(Info.make({ message: `story ${story.id}: merged into ${epicBranch}` }));
212
+ }));
213
+ /** The worktree and branch for a story, honouring the hash-guarded resume rules. */
214
+ const prepareWorktree = Effect.fn("@llm4ts/flow/Stories.prepareWorktree")(function* (story) {
215
+ const hash = storyHash(story);
216
+ const branch = `story/${plan.epicId}/${story.id}`;
217
+ const worktree = join(options.worktreeRoot, story.id);
218
+ const path = statePath(story);
219
+ let stored = yield* loadVersioned(files, path, StoryStateVersion, StoryState);
220
+ if (stored !== undefined && stored.hash !== hash) {
221
+ yield* events.publish(Info.make({
222
+ message: `story ${story.id}: plan entry changed since its branch was created; starting over`
223
+ }));
224
+ // The old worktree may already be gone (an operator cleaned up); that is
225
+ // not a failure of this run, so removal errors are reported and dropped.
226
+ yield* context.git
227
+ .removeWorktree(stored.worktree, true)
228
+ .pipe(Effect.catch((error) => events.publish(Info.make({ message: `story ${story.id}: ${describeFlowError(error)}` }))));
229
+ if (yield* context.git.branchExists(stored.branch)) {
230
+ yield* context.git.deleteBranch(stored.branch);
231
+ }
232
+ stored = undefined;
233
+ }
234
+ if (stored !== undefined && stored.status === "merged") {
235
+ return { state: stored, alreadyMerged: true };
236
+ }
237
+ if (stored === undefined) {
238
+ yield* context.git.addWorktreeNewBranch(worktree, branch, epicBranch);
239
+ const state = StoryState.make({ id: story.id, hash, branch, worktree, status: "started" });
240
+ yield* saveVersioned(files, path, StoryStateVersion, StoryState, state);
241
+ return { state, alreadyMerged: false };
242
+ }
243
+ // Resume: the branch exists; the worktree may not (a worktree has a
244
+ // `.git` FILE at its root, which is how its presence is checked).
245
+ const marker = yield* files.read(join(stored.worktree, ".git"));
246
+ if (marker === undefined) {
247
+ yield* context.git.addWorktree(stored.worktree, stored.branch);
248
+ }
249
+ yield* events.publish(Info.make({ message: `story ${story.id}: resuming ${stored.branch}` }));
250
+ return { state: stored, alreadyMerged: false };
251
+ });
252
+ /** Everything that happens inside a story's worktree: plan, implement, judge, perimeter. */
253
+ const implementStory = Effect.fn("@llm4ts/flow/Stories.implementStory")(function* (story, state) {
254
+ const seats = yield* options.contextFor(state.worktree);
255
+ const blocked = yield* Ref.make(undefined);
256
+ const storyContext = {
257
+ ...seats.context,
258
+ coder: watchForBlockedOn(seats.context.coder, blocked)
259
+ };
260
+ const watchedSeats = { ...seats, context: storyContext };
261
+ const extra = options.system === undefined ? undefined : yield* options.system(story);
262
+ const system = [perimeterRules(story), extra]
263
+ .filter((part) => part !== undefined && part.trim().length > 0)
264
+ .join("\n\n");
265
+ const prompt = storyPrompt(story);
266
+ const blockedOr = (effect) => effect.pipe(Effect.catch((error) => Effect.flatMap(Ref.get(blocked), (need) => need === undefined
267
+ ? Effect.fail(error)
268
+ : Effect.fail(MissingDependency.make({ story: story.id, need })))), Effect.tap(() => Effect.flatMap(Ref.get(blocked), (need) => need === undefined
269
+ ? Effect.void
270
+ : Effect.fail(MissingDependency.make({ story: story.id, need })))));
271
+ yield* blockedOr(implementPlanFlow(storyContext, {
272
+ store: makePlanStore(files),
273
+ planPath: planPath(story),
274
+ plan: (options.planTasks ?? defaultPlanTasks)(watchedSeats, story, prompt),
275
+ system,
276
+ chatPerTask: true,
277
+ checkoutBranch: false,
278
+ lint: options.gates(state.worktree),
279
+ // A story's final state is judged and gated downstream (judge round,
280
+ // perimeter check, epic gates), so a task the coder finds already
281
+ // satisfied — without saying the exact sentinel — must not sink the
282
+ // story: the option exists for pipelines shaped like this one.
283
+ noopTaskPolicy: "complete",
284
+ ...(options.reviewers === undefined ? {} : { reviewers: options.reviewers }),
285
+ ...(options.maxRounds === undefined ? {} : { maxRounds: options.maxRounds })
286
+ }));
287
+ let judgeNote;
288
+ if (options.judge !== undefined) {
289
+ const judge = options.judge;
290
+ for (let round = 1; round <= judgeRounds; round += 1) {
291
+ const diff = yield* storyContext.git.diffVsBase(epicBranch);
292
+ const verdict = yield* judge(story, diff);
293
+ if (verdict.isClean) {
294
+ judgeNote = `judge cleared (round ${round})`;
295
+ break;
296
+ }
297
+ if (round >= judgeRounds) {
298
+ return yield* failed(story, `judge not cleared after ${judgeRounds} round(s):\n${issueLines(verdict)}`);
299
+ }
300
+ const feedback = yield* makeChat(storyContext.coder, {
301
+ system,
302
+ events,
303
+ agent: "coder"
304
+ });
305
+ yield* blockedOr(feedback.ask([
306
+ `The story "${story.title}" scored below the bar. Close these gaps without`,
307
+ "weakening any test and without leaving your owned paths, then stop:",
308
+ issueLines(verdict)
309
+ ].join("\n")));
310
+ const regated = yield* options.gates(state.worktree);
311
+ if (!regated.isClean) {
312
+ return yield* failed(story, `gates broke while addressing judge feedback:\n${issueLines(regated)}`);
313
+ }
314
+ yield* storyContext.git.commitAll(`${story.id}: address judge feedback`);
315
+ }
316
+ }
317
+ const changed = yield* storyContext.git.changedFilesVsBase(epicBranch);
318
+ yield* enforcePerimeter(changed, story);
319
+ const totals = seats.totals === undefined ? undefined : yield* seats.totals;
320
+ return { judge: judgeNote, totals };
321
+ });
322
+ const runStory = Effect.fn("@llm4ts/flow/Stories.runStory")(function* (story) {
323
+ yield* board.start(story.id);
324
+ const { state, alreadyMerged } = yield* prepareWorktree(story);
325
+ if (alreadyMerged) {
326
+ yield* events.publish(Info.make({ message: `story ${story.id}: already merged; skipping` }));
327
+ return StoryOutcome.make({
328
+ id: story.id,
329
+ title: story.title,
330
+ status: "done",
331
+ branch: state.branch,
332
+ judge: "merged on a previous run"
333
+ });
334
+ }
335
+ if (options.setup !== undefined) {
336
+ yield* stage(events, `story ${story.id}: setup`, options.setup(state.worktree));
337
+ }
338
+ const result = yield* Effect.scoped(implementStory(story, state));
339
+ yield* integrate(story, state.branch);
340
+ yield* saveVersioned(files, statePath(story), StoryStateVersion, StoryState, StoryState.make({ ...state, status: "merged" }));
341
+ return StoryOutcome.make({
342
+ id: story.id,
343
+ title: story.title,
344
+ status: "done",
345
+ branch: state.branch,
346
+ ...(result.judge === undefined ? {} : { judge: result.judge }),
347
+ ...(result.totals === undefined ? {} : { estimatedTokens: result.totals.total }),
348
+ ...(result.totals?.costUsd === undefined ? {} : { estimatedCostUsd: result.totals.costUsd })
349
+ });
350
+ });
351
+ /** A story's run as a completion — failures become outcomes, never fiber deaths. */
352
+ const attempt = (story) => stage(events, `story ${story.id}`, runStory(story)).pipe(Effect.map((outcome) => ({ story, outcome })), Effect.catch((error) => Effect.gen(function* () {
353
+ const reason = describeFlowError(error);
354
+ const path = statePath(story);
355
+ const stored = yield* loadVersioned(files, path, StoryStateVersion, StoryState).pipe(Effect.catch(() => Effect.succeed(undefined)));
356
+ if (stored !== undefined && stored.status !== "merged") {
357
+ yield* saveVersioned(files, path, StoryStateVersion, StoryState, StoryState.make({ ...stored, status: "failed" })).pipe(Effect.ignore);
358
+ }
359
+ return {
360
+ story,
361
+ outcome: StoryOutcome.make({
362
+ id: story.id,
363
+ title: story.title,
364
+ status: "failed",
365
+ reason,
366
+ ...(stored === undefined ? {} : { branch: stored.branch })
367
+ })
368
+ };
369
+ })));
370
+ const outcomes = yield* Ref.make([]);
371
+ const running = yield* Ref.make(new Set());
372
+ const completions = yield* Queue.unbounded();
373
+ const progress = Effect.gen(function* () {
374
+ const known = yield* Ref.get(outcomes);
375
+ const byStatus = (status) => new Set(known.filter((outcome) => outcome.status === status).map((outcome) => outcome.id));
376
+ return {
377
+ done: byStatus("done"),
378
+ failed: byStatus("failed"),
379
+ skipped: byStatus("skipped"),
380
+ running: yield* Ref.get(running)
381
+ };
382
+ });
383
+ const record = (outcome) => Ref.update(outcomes, (current) => [...current, outcome]);
384
+ const skipDependents = (story) => Effect.gen(function* () {
385
+ const current = yield* progress;
386
+ for (const id of dependentsOf(plan, story.id)) {
387
+ const dependent = plan.story(id);
388
+ if (dependent === undefined ||
389
+ current.done.has(id) ||
390
+ current.failed.has(id) ||
391
+ current.skipped.has(id)) {
392
+ continue;
393
+ }
394
+ const reason = `blocked by ${story.id}`;
395
+ yield* record(StoryOutcome.make({ id, title: dependent.title, status: "skipped", reason }));
396
+ yield* board.skip(id, reason);
397
+ }
398
+ });
399
+ yield* Effect.scoped(Effect.gen(function* () {
400
+ while (true) {
401
+ const current = yield* progress;
402
+ const ready = readyStories(plan, current);
403
+ const slots = concurrency - current.running.size;
404
+ for (const story of ready.slice(0, Math.max(0, slots))) {
405
+ yield* Ref.update(running, (set) => new Set([...set, story.id]));
406
+ yield* Effect.forkScoped(attempt(story).pipe(Effect.flatMap((completion) => Queue.offer(completions, completion))));
407
+ }
408
+ if ((yield* Ref.get(running)).size === 0) {
409
+ break;
410
+ }
411
+ const completion = yield* Queue.take(completions);
412
+ yield* Ref.update(running, (set) => {
413
+ const next = new Set(set);
414
+ next.delete(completion.story.id);
415
+ return next;
416
+ });
417
+ yield* record(completion.outcome);
418
+ const outcome = completion.outcome;
419
+ if (outcome.status === "done") {
420
+ yield* board.complete(outcome.id, {
421
+ ...(outcome.branch === undefined ? {} : { branch: outcome.branch }),
422
+ ...(outcome.judge === undefined ? {} : { detail: outcome.judge }),
423
+ ...(outcome.estimatedTokens === undefined
424
+ ? {}
425
+ : { estimatedTokens: outcome.estimatedTokens }),
426
+ ...(outcome.estimatedCostUsd === undefined
427
+ ? {}
428
+ : { estimatedCostUsd: outcome.estimatedCostUsd })
429
+ });
430
+ }
431
+ else {
432
+ yield* board.fail(outcome.id, outcome.reason ?? "failed");
433
+ if (options.failFast === true) {
434
+ return yield* StoryFailed.make({
435
+ story: outcome.id,
436
+ reason: outcome.reason ?? "failed"
437
+ });
438
+ }
439
+ yield* skipDependents(completion.story);
440
+ }
441
+ }
442
+ }));
443
+ const recorded = yield* Ref.get(outcomes);
444
+ const ordered = plan.stories.flatMap((story) => {
445
+ const outcome = recorded.find((candidate) => candidate.id === story.id);
446
+ return outcome === undefined ? [] : [outcome];
447
+ });
448
+ const report = EpicReport.make({
449
+ epicId: plan.epicId,
450
+ epicBranch,
451
+ estimated: true,
452
+ stories: ordered
453
+ });
454
+ yield* saveVersioned(files, join(options.stateDir, "report.json"), EpicReportVersion, EpicReport, report);
455
+ yield* files.writeAtomic(join(options.stateDir, "report.md"), renderEpicReport(report));
456
+ return report;
457
+ });
458
+ //# sourceMappingURL=Stories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Stories.js","sourceRoot":"","sources":["../src/Stories.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as Schema from "effect/Schema";
3
+ import { PlanParseError, StoryPlanInvalid, type PersistenceError } from "./FlowError.ts";
4
+ import type { PlainFileStoreShape } from "./Persistence.ts";
5
+ export declare const StoryPlanVersion = 1;
6
+ declare const Story_base: Schema.Class<Story, Schema.Struct<{
7
+ /** Kebab-case, unique within the plan; names the branch and the worktree. */
8
+ readonly id: Schema.String;
9
+ readonly title: Schema.String;
10
+ readonly description: Schema.String;
11
+ /** Story ids this one waits for; they are merged before this one starts. */
12
+ readonly dependsOn: Schema.withDecodingDefaultKey<Schema.withConstructorDefault<Schema.$Array<Schema.String>>, never>;
13
+ /** Repo-relative path prefixes (files or directories) the story may create or change. */
14
+ readonly owned: Schema.$Array<Schema.String>;
15
+ /** Path prefixes fed as context and forbidden to change. */
16
+ readonly sharedReadOnly: Schema.withDecodingDefaultKey<Schema.withConstructorDefault<Schema.$Array<Schema.String>>, never>;
17
+ /** What dependents may rely on: routes, exports, contracts. */
18
+ readonly provides: Schema.withDecodingDefaultKey<Schema.withConstructorDefault<Schema.$Array<Schema.String>>, never>;
19
+ }>, {}>;
20
+ export declare class Story extends Story_base {
21
+ }
22
+ declare const StoryPlan_base: Schema.Class<StoryPlan, Schema.Struct<{
23
+ readonly epicId: Schema.String;
24
+ /** The epic as the operator phrased it. */
25
+ readonly epic: Schema.String;
26
+ readonly stories: Schema.$Array<typeof Story>;
27
+ }>, {}>;
28
+ export declare class StoryPlan extends StoryPlan_base {
29
+ story(id: string): Story | undefined;
30
+ }
31
+ /** A path prefix in canonical form: no `./`, no trailing slash, forward slashes. */
32
+ export declare const normalizePath: (path: string) => string;
33
+ /** Whether `path` is `prefix` itself or lies under it. */
34
+ export declare const pathWithin: (path: string, prefix: string) => boolean;
35
+ /**
36
+ * Every violation of the plan's invariants, in one pass — an operator fixing
37
+ * a hand-edited plan wants the whole list, not a rerun per finding.
38
+ */
39
+ export declare const storyPlanViolations: (plan: StoryPlan) => ReadonlyArray<string>;
40
+ export declare const validateStoryPlan: (plan: StoryPlan) => Effect.Effect<StoryPlan, StoryPlanInvalid, never>;
41
+ /**
42
+ * Stories grouped by the earliest wave they can run in (all dependencies in
43
+ * earlier waves). Assumes a valid plan; a cycle leaves its members out.
44
+ */
45
+ export declare const topologicalWaves: (plan: StoryPlan) => ReadonlyArray<ReadonlyArray<string>>;
46
+ export interface StoryProgress {
47
+ readonly done: ReadonlySet<string>;
48
+ readonly failed: ReadonlySet<string>;
49
+ readonly skipped: ReadonlySet<string>;
50
+ readonly running: ReadonlySet<string>;
51
+ }
52
+ /** Stories that may start now: not yet touched, every dependency done. Plan order. */
53
+ export declare const readyStories: (plan: StoryPlan, progress: StoryProgress) => ReadonlyArray<Story>;
54
+ /** Every story that transitively depends on `id`, in plan order. */
55
+ export declare const dependentsOf: (plan: StoryPlan, id: string) => ReadonlyArray<string>;
56
+ /** Stable over the story entry's content — a changed entry means a fresh branch. */
57
+ export declare const storyHash: (story: Story) => string;
58
+ export declare const storyPlanFenceInfo = "json storyplan";
59
+ /** The raw JSON of the first ```json storyplan fenced block, if any. */
60
+ export declare const storyPlanBlock: (markdown: string) => string | undefined;
61
+ /**
62
+ * Decodes the story plan embedded in its markdown file. Decoding only —
63
+ * `validateStoryPlan` checks the graph invariants separately, so a parse
64
+ * failure and an invalid plan are told apart.
65
+ */
66
+ export declare const parseStoryPlan: (markdown: string) => Effect.Effect<StoryPlan, PlanParseError, never>;
67
+ /**
68
+ * The operator-facing markdown: a readable summary per story plus the
69
+ * fenced block that is the source of truth. Editing the block and rerunning
70
+ * is the approval and the re-plan path.
71
+ */
72
+ export declare const renderStoryPlan: (plan: StoryPlan) => Effect.Effect<string, PlanParseError, never>;
73
+ export interface StoryPlanStoreShape {
74
+ readonly save: (path: string, plan: StoryPlan) => Effect.Effect<void, PersistenceError | PlanParseError>;
75
+ readonly load: (path: string) => Effect.Effect<StoryPlan | undefined, PersistenceError | PlanParseError>;
76
+ /** An existing file wins over `create`: the operator's edits are the plan. */
77
+ readonly recoverOrCreate: <E, R>(path: string, create: Effect.Effect<StoryPlan, E, R>) => Effect.Effect<StoryPlan, E | PersistenceError | PlanParseError, R>;
78
+ }
79
+ export declare const makeStoryPlanStore: (files: PlainFileStoreShape) => StoryPlanStoreShape;
80
+ export {};
81
+ //# sourceMappingURL=StoryPlan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StoryPlan.d.ts","sourceRoot":"","sources":["../src/StoryPlan.ts"],"names":[],"mappings":"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"}