compounding-loop 0.2.0 → 0.5.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 (149) hide show
  1. package/README.md +19 -3
  2. package/dist/cli/claim.js +84 -0
  3. package/dist/cli/claim.js.map +1 -0
  4. package/dist/cli/draft.js +69 -0
  5. package/dist/cli/draft.js.map +1 -0
  6. package/dist/cli/index.js +284 -1
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/cli/laneRound.js +96 -0
  9. package/dist/cli/laneRound.js.map +1 -0
  10. package/dist/cli/laneStatus.js +3 -1
  11. package/dist/cli/laneStatus.js.map +1 -1
  12. package/dist/cli/lanesInit.js +8 -2
  13. package/dist/cli/lanesInit.js.map +1 -1
  14. package/dist/cli/lock.js +22 -2
  15. package/dist/cli/lock.js.map +1 -1
  16. package/dist/cli/loops.js +7 -0
  17. package/dist/cli/loops.js.map +1 -1
  18. package/dist/cli/next.js +18 -0
  19. package/dist/cli/next.js.map +1 -0
  20. package/dist/cli/pace.js +41 -0
  21. package/dist/cli/pace.js.map +1 -0
  22. package/dist/cli/pause.js +81 -0
  23. package/dist/cli/pause.js.map +1 -0
  24. package/dist/cli/run.js +18 -6
  25. package/dist/cli/run.js.map +1 -1
  26. package/dist/cli/runs.js +118 -0
  27. package/dist/cli/runs.js.map +1 -0
  28. package/dist/cli/schedule.js +177 -0
  29. package/dist/cli/schedule.js.map +1 -0
  30. package/dist/cli/shipCheck.js +59 -0
  31. package/dist/cli/shipCheck.js.map +1 -0
  32. package/dist/core/brief.js +35 -12
  33. package/dist/core/brief.js.map +1 -1
  34. package/dist/core/draftBrief.js +68 -0
  35. package/dist/core/draftBrief.js.map +1 -0
  36. package/dist/core/laneRound.js +63 -0
  37. package/dist/core/laneRound.js.map +1 -0
  38. package/dist/core/lanes.js +15 -2
  39. package/dist/core/lanes.js.map +1 -1
  40. package/dist/core/lanesInit.js +19 -0
  41. package/dist/core/lanesInit.js.map +1 -1
  42. package/dist/core/next.js +34 -0
  43. package/dist/core/next.js.map +1 -0
  44. package/dist/core/parse/changelog.js +41 -0
  45. package/dist/core/parse/changelog.js.map +1 -0
  46. package/dist/core/parse/claim.js +24 -0
  47. package/dist/core/parse/claim.js.map +1 -0
  48. package/dist/core/parse/controlRoom.js +38 -0
  49. package/dist/core/parse/controlRoom.js.map +1 -0
  50. package/dist/core/parse/index.js +17 -0
  51. package/dist/core/parse/index.js.map +1 -0
  52. package/dist/core/parse/markers.js +20 -0
  53. package/dist/core/parse/markers.js.map +1 -0
  54. package/dist/core/parse/outcomes.js +51 -0
  55. package/dist/core/parse/outcomes.js.map +1 -0
  56. package/dist/core/parse/paused.js +26 -0
  57. package/dist/core/parse/paused.js.map +1 -0
  58. package/dist/core/parse/policy.js +56 -0
  59. package/dist/core/parse/policy.js.map +1 -0
  60. package/dist/core/parse/runs.js +132 -0
  61. package/dist/core/parse/runs.js.map +1 -0
  62. package/dist/core/parse/schedule.js +101 -0
  63. package/dist/core/parse/schedule.js.map +1 -0
  64. package/dist/core/parse/steer.js +68 -0
  65. package/dist/core/parse/steer.js.map +1 -0
  66. package/dist/core/parse/task.js +96 -0
  67. package/dist/core/parse/task.js.map +1 -0
  68. package/dist/core/repo.js +18 -8
  69. package/dist/core/repo.js.map +1 -1
  70. package/dist/core/runPrompt.js +8 -2
  71. package/dist/core/runPrompt.js.map +1 -1
  72. package/dist/core/shipCheck.js +45 -0
  73. package/dist/core/shipCheck.js.map +1 -0
  74. package/dist/core/table.js +3 -1
  75. package/dist/core/table.js.map +1 -1
  76. package/dist/server/actionBody.js +54 -0
  77. package/dist/server/actionBody.js.map +1 -0
  78. package/dist/server/checkLabels.js +32 -0
  79. package/dist/server/checkLabels.js.map +1 -0
  80. package/dist/server/claude.js +18 -0
  81. package/dist/server/claude.js.map +1 -0
  82. package/dist/server/controls.js +99 -0
  83. package/dist/server/controls.js.map +1 -0
  84. package/dist/server/data.js +9 -3
  85. package/dist/server/data.js.map +1 -1
  86. package/dist/server/draftInputs.js +33 -0
  87. package/dist/server/draftInputs.js.map +1 -0
  88. package/dist/server/health.js +9 -30
  89. package/dist/server/health.js.map +1 -1
  90. package/dist/server/index.js +77 -0
  91. package/dist/server/index.js.map +1 -1
  92. package/dist/server/laneChecks.js +25 -0
  93. package/dist/server/laneChecks.js.map +1 -0
  94. package/dist/server/laneSchedule.js +15 -0
  95. package/dist/server/laneSchedule.js.map +1 -0
  96. package/dist/server/live/build.js +178 -0
  97. package/dist/server/live/build.js.map +1 -0
  98. package/dist/server/live/github.js +54 -0
  99. package/dist/server/live/github.js.map +1 -0
  100. package/dist/server/live/index.js +11 -0
  101. package/dist/server/live/index.js.map +1 -0
  102. package/dist/server/live/merge.js +16 -0
  103. package/dist/server/live/merge.js.map +1 -0
  104. package/dist/server/live/urls.js +61 -0
  105. package/dist/server/live/urls.js.map +1 -0
  106. package/dist/server/loops.js +263 -41
  107. package/dist/server/loops.js.map +1 -1
  108. package/dist/server/paceNote.js +13 -0
  109. package/dist/server/paceNote.js.map +1 -0
  110. package/dist/server/roundState.js +51 -0
  111. package/dist/server/roundState.js.map +1 -0
  112. package/dist/server/runs.js +144 -0
  113. package/dist/server/runs.js.map +1 -0
  114. package/dist/server/shipped.js +35 -0
  115. package/dist/server/shipped.js.map +1 -0
  116. package/dist/server/static-export.js +22 -1
  117. package/dist/server/static-export.js.map +1 -1
  118. package/dist/server/taskBullets.js +33 -0
  119. package/dist/server/taskBullets.js.map +1 -0
  120. package/dist/server/this-repo.json +2818 -106
  121. package/dist/web/assets/index-BozIcdeb.js +88 -0
  122. package/dist/web/assets/index-Te_olhNA.css +2 -0
  123. package/dist/web/index.html +2 -2
  124. package/method/COMPOUNDING_LOOP.md +26 -0
  125. package/method/retro.md +7 -0
  126. package/package.json +1 -1
  127. package/plugin/.claude-plugin/plugin.json +1 -1
  128. package/plugin/commands/loop-lanes.md +11 -0
  129. package/plugin/commands/loop-next.md +11 -0
  130. package/plugin/commands/loop-pause.md +10 -0
  131. package/runners/github-actions/lanes.yml +55 -2
  132. package/runners/local/README.md +3 -1
  133. package/runners/local/compounding-loop.service +20 -0
  134. package/runners/local/compounding-loop.timer +11 -0
  135. package/runners/routine/README.md +5 -1
  136. package/runners/routine/control-room-prompt.md +4 -14
  137. package/runners/routine/lane-prompt.md +4 -10
  138. package/runners/routine/prompt.md +2 -2
  139. package/templates/lanes/README.md +5 -1
  140. package/templates/lanes/claude-section.md +5 -1
  141. package/templates/lanes/control-run.md +37 -0
  142. package/templates/lanes/lane-run.md +33 -0
  143. package/templates/lanes/schedule.json +4 -0
  144. package/templates/lanes/steer.md +3 -0
  145. package/templates/lanes/task.md +1 -1
  146. package/templates/static-site/.ai/loop-prompt.md +1 -1
  147. package/templates/static-site/CLAUDE.md +2 -0
  148. package/dist/web/assets/index-B16QCSnY.css +0 -2
  149. package/dist/web/assets/index-CS82DKbF.js +0 -49
package/dist/cli/run.js CHANGED
@@ -3,10 +3,13 @@ import { appendFile, mkdir, readFile, stat } from 'node:fs/promises';
3
3
  import path from 'node:path';
4
4
  import { parseLockTime } from '../core/repo.js';
5
5
  import { LOCK_MINUTES } from '../core/status.js';
6
- import { buildClaudeArgs, buildRunPrompt, DEFAULT_PROMPT } from '../core/runPrompt.js';
6
+ import { buildClaudeArgs, buildRunPrompt, claimRule, DEFAULT_PROMPT, PAUSED_RULE } from '../core/runPrompt.js';
7
7
  import { parseLanesConfig } from '../core/lanes.js';
8
8
  import { packageRoot } from './init.js';
9
- import { withSessionLock } from './lock.js';
9
+ import { hostname } from 'node:os';
10
+ import { describePaused } from '../core/parse/paused.js';
11
+ import { readPaused } from './pause.js';
12
+ import { lockHolderHost, lockHolderPid, pidAlive, withSessionLock } from './lock.js';
10
13
  const exists = (file) => stat(file).then(() => true, () => false);
11
14
  /** First readable prompt: the repo's own, then the routine prompt in the repo, then the package's, then the built-in. */
12
15
  export async function loadPromptText(dir, root = packageRoot, lane) {
@@ -28,7 +31,7 @@ export async function loadPromptText(dir, root = packageRoot, lane) {
28
31
  }
29
32
  /** Used when no lane prompt file exists: points the generic round prompt at this lane's files. */
30
33
  export function laneIntro(lane) {
31
- return `You are the **${lane}** lane of a multi-lane loop. Your lane's task file is \`.ai/lanes/${lane}/task.md\` (wherever this prompt says \`.ai/task.md\`, use it), your outbox is \`.ai/lanes/${lane}/outbox.md\`, your lock is \`.ai/lanes/${lane}/session.lock\`, and your stop files are \`.ai/lanes/${lane}/DONE.md\` and \`BLOCKED.md\`. Edit only the paths \`${lane}\` owns in \`.ai/lanes.json\` (plus shared ones), and end every commit message with the trailer line \`Lane: ${lane}\`.`;
34
+ return `You are the **${lane}** lane of a multi-lane loop. Your lane's task file is \`.ai/lanes/${lane}/task.md\` (wherever this prompt says \`.ai/task.md\`, use it), your outbox is \`.ai/lanes/${lane}/outbox.md\`, your lock is \`.ai/lanes/${lane}/session.lock\`, and your stop files are \`.ai/lanes/${lane}/DONE.md\` and \`BLOCKED.md\`. Edit only the paths \`${lane}\` owns in \`.ai/lanes.json\` (plus shared ones), and end every commit message with the trailer line \`Lane: ${lane}\`. ${PAUSED_RULE} ${claimRule(lane)}`;
32
35
  }
33
36
  /** Fails early, with the valid names, when `--lane` is not in `.ai/lanes.json`. */
34
37
  export async function assertKnownLane(dir, lane) {
@@ -124,9 +127,14 @@ const realSpawn = async (command, rawArgs, cwd) => {
124
127
  });
125
128
  };
126
129
  /** Minutes left on a fresh `.ai/session.lock`, or undefined when no session holds the repo. */
127
- export function lockMinutesLeft(lockText, now) {
130
+ export function lockMinutesLeft(lockText, now, isAlive = pidAlive, host = hostname()) {
128
131
  const at = lockText === undefined ? undefined : parseLockTime(lockText);
129
- if (!at)
132
+ if (!at || lockText === undefined)
133
+ return undefined;
134
+ // A lock whose holder was killed (SIGKILL skips the cleanup) is stale at once instead of after 90 minutes.
135
+ const pid = lockHolderPid(lockText);
136
+ // Only on the writing machine: in another pid namespace (WSL, a container, a shared drive) a live holder looks dead.
137
+ if (pid !== undefined && lockHolderHost(lockText) === host && !isAlive(pid))
130
138
  return undefined;
131
139
  const left = LOCK_MINUTES - (now.getTime() - at.getTime()) / 60_000;
132
140
  return left > 0 ? Math.ceil(left) : undefined;
@@ -145,7 +153,11 @@ export async function runRound(dir, options, spawner = realSpawn) {
145
153
  const { text, source } = await loadPromptText(dir, packageRoot, lane);
146
154
  const lockFile = path.join(dir, laneDir, 'session.lock');
147
155
  const lockNote = `Note from \`loop run\`: it created \`${path.posix.join(...laneDir.split(path.sep), 'session.lock')}\` for this very session. That lock is yours, not another session's: ignore it in the lock step and do not delete it.`;
148
- const prompt = `${buildRunPrompt(text, { name: path.basename(path.resolve(dir)), lane: lane ?? '' })}\n${lockNote}\n`;
156
+ const asNote = options.as ? `\nNote from \`loop run\`: you are running as \`${options.as}\`. A claim naming \`${options.as}\` is yours, not a teammate's: ignore it in the claim step.` : '';
157
+ const prompt = `${buildRunPrompt(text, { name: path.basename(path.resolve(dir)), lane: lane ?? '' })}\n${lockNote}${asNote}\n`;
158
+ const paused = await readPaused(dir);
159
+ if (paused)
160
+ return { skipped: `${describePaused(paused)}: nothing to do. Run \`loop resume\` to continue.`, prompt, source };
149
161
  const stopFiles = [...(lane ? [path.join(laneDir, 'DONE.md'), path.join(laneDir, 'BLOCKED.md')] : []), 'DONE.md', 'BLOCKED.md'];
150
162
  for (const stop of stopFiles) {
151
163
  if (await exists(path.join(dir, stop)))
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/cli/run.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/cli/run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,118 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { access, appendFile, mkdir, readFile } from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { promisify } from 'node:util';
5
+ import { parseLanesConfig } from '../core/lanes.js';
6
+ import { classifyRunSlots, missedRun } from '../core/parse/outcomes.js';
7
+ import { formatRunEntry, parseRunLog, runLogPath } from '../core/parse/runs.js';
8
+ import { parseSchedule, SCHEDULE_FILE } from '../core/parse/schedule.js';
9
+ const execFileAsync = promisify(execFile);
10
+ async function laneNames(dir) {
11
+ const text = await readFile(path.join(dir, '.ai', 'lanes.json'), 'utf8').catch(() => undefined);
12
+ if (text === undefined)
13
+ throw new Error('No .ai/lanes.json here. Create one with `loop init --lanes a,b,c`.');
14
+ const { config, errors } = parseLanesConfig(text);
15
+ if (!config)
16
+ throw new Error(`.ai/lanes.json is invalid:\n- ${errors.join('\n- ')}`);
17
+ return { names: config.lanes.map((l) => l.name), crons: new Map(config.lanes.flatMap((l) => (l.cron ? [[l.name, l.cron]] : []))) };
18
+ }
19
+ /** `loop runs log`: appends one line to the lane's own runs.jsonl. The caller commits it with its last commit. */
20
+ export async function logRun(dir, lane, options) {
21
+ const { names } = await laneNames(dir);
22
+ if (!names.includes(lane))
23
+ throw new Error(`No lane "${lane}". Lanes here: ${names.join(', ')}.`);
24
+ if ((options.passed === undefined) !== (options.failed === undefined))
25
+ throw new Error('Pass --passed and --failed together.');
26
+ for (const n of [options.passed, options.failed])
27
+ if (n !== undefined && (!Number.isInteger(n) || n < 0))
28
+ throw new Error('--passed and --failed must be whole numbers, 0 or more.');
29
+ const entry = {
30
+ at: (options.now ?? new Date()).toISOString(),
31
+ lane,
32
+ ...(options.session && { session: options.session }),
33
+ units: options.units ?? [],
34
+ ...(options.passed !== undefined && options.failed !== undefined && { tests: { passed: options.passed, failed: options.failed } }),
35
+ pushed: options.pushed,
36
+ ...(options.note && { note: options.note.replace(/\s+/g, ' ').trim() }),
37
+ };
38
+ const file = path.join(dir, ...runLogPath(lane).split('/'));
39
+ await mkdir(path.dirname(file), { recursive: true });
40
+ await appendFile(file, formatRunEntry(entry));
41
+ return entry;
42
+ }
43
+ /** Commit times carrying `Lane: <lane>` since `since`; empty when git cannot say (no repo, no commits). */
44
+ async function laneCommitTimes(dir, lane, since) {
45
+ try {
46
+ const { stdout } = await execFileAsync('git', ['log', `--since=${since.toISOString()}`, '--format=%cI%x09%(trailers:key=Lane,valueonly,separator=%x2C)'], { cwd: dir });
47
+ return stdout.split('\n').flatMap((line) => {
48
+ const [time, trailer] = line.split('\t');
49
+ return time && trailer?.trim() === lane ? [new Date(time)] : [];
50
+ });
51
+ }
52
+ catch {
53
+ return [];
54
+ }
55
+ }
56
+ const exists = (dir, rel) => access(path.join(dir, ...rel.split('/'))).then(() => true, () => false);
57
+ /** `loop runs`: each lane's logged runs plus what happened at each scheduled slot in the window (see classifyRunSlots). */
58
+ export async function readRuns(dir, options = {}) {
59
+ const now = options.now ?? new Date();
60
+ const from = new Date(now.getTime() - (options.hours ?? 24) * 3_600_000);
61
+ const { names, crons } = await laneNames(dir);
62
+ const runs = new Map();
63
+ const commits = new Map();
64
+ const laneDone = new Set();
65
+ for (const lane of names) {
66
+ runs.set(lane, parseRunLog(await readFile(path.join(dir, ...runLogPath(lane).split('/')), 'utf8').catch(() => '')));
67
+ commits.set(lane, await laneCommitTimes(dir, lane, from));
68
+ if ((await exists(dir, `.ai/lanes/${lane}/DONE.md`)) || (await exists(dir, `.ai/lanes/${lane}/BLOCKED.md`)))
69
+ laneDone.add(lane);
70
+ }
71
+ const paused = await exists(dir, '.ai/PAUSED');
72
+ const classified = classifyRunSlots({
73
+ lanes: names.map((name) => ({ name, ...(crons.get(name) && { cron: crons.get(name) }) })),
74
+ runs,
75
+ schedule: parseSchedule(await readFile(path.join(dir, ...SCHEDULE_FILE.split('/')), 'utf8').catch(() => '')),
76
+ paused,
77
+ rootDone: (await exists(dir, 'DONE.md')) || (await exists(dir, 'BLOCKED.md')),
78
+ laneDone,
79
+ now,
80
+ from,
81
+ commits,
82
+ });
83
+ const lanes = classified.lanes.map(({ lane, slots }) => ({
84
+ lane,
85
+ ...(crons.get(lane) && { cron: crons.get(lane) }),
86
+ entries: (runs.get(lane) ?? []).filter((e) => new Date(e.at) > from),
87
+ slots,
88
+ missedInARow: missedRun(slots),
89
+ }));
90
+ return { from: from.toISOString(), to: now.toISOString(), lanes, routinesLookOff: classified.routinesLookOff, paused };
91
+ }
92
+ const LABEL = {
93
+ worked: 'worked',
94
+ idle: 'ran, nothing to do',
95
+ 'tests-failed': 'tests failed',
96
+ 'not-due': 'not due (schedule.json)',
97
+ running: 'likely running',
98
+ missed: 'no run recorded (usage limit or failed start)',
99
+ paused: 'paused',
100
+ done: 'nothing expected (done)',
101
+ };
102
+ const stamp = (iso) => iso.slice(0, 16).replace('T', ' ');
103
+ export function formatRuns(report) {
104
+ const out = [`Runs ${stamp(report.from)} to ${stamp(report.to)} UTC`];
105
+ if (report.routinesLookOff)
106
+ out.push('', '! Routines look off: nothing has run for 6 hours although runs were due. Check the routines and your plan\'s usage limit.');
107
+ for (const l of report.lanes) {
108
+ out.push('', `${l.lane}${l.cron ? ` (cron ${l.cron})` : ''}${l.missedInARow >= 3 ? ` ! ${l.missedInARow} scheduled runs in a row left no trace: check your plan's usage limit` : ''}`);
109
+ if (l.slots.length === 0 && l.entries.length === 0)
110
+ out.push(' nothing logged');
111
+ for (const s of l.slots) {
112
+ const e = s.entry;
113
+ out.push(` ${stamp(s.slot)} ${LABEL[s.kind]}${e ? ` ${e.units.length} unit${e.units.length === 1 ? '' : 's'}${e.tests ? `, tests ${e.tests.passed} passed ${e.tests.failed} failed` : ''}${e.note ? ` ${e.note}` : ''}` : ''}`);
114
+ }
115
+ }
116
+ return out.join('\n');
117
+ }
118
+ //# sourceMappingURL=runs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runs.js","sourceRoot":"","sources":["../../src/cli/runs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,177 @@
1
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { CONTROL_LANE, parseLanesConfig } from '../core/lanes.js';
4
+ import { parseOutbox } from '../core/laneStatus.js';
5
+ import { SCHEDULE_FILE, applyBackoff, dueEntry, formatSchedule, notDueReason, parseSchedule, parseUntil, trailingIdleRuns, wakeEntry, wakeReasons, } from '../core/parse/schedule.js';
6
+ import { parseRunLog, runLogPath } from '../core/parse/runs.js';
7
+ import { addSteerEntry, parseSteer, steerPath } from '../core/parse/steer.js';
8
+ import { git, pushIfWanted, syncFirst } from './pause.js';
9
+ export const read = (dir, rel) => readFile(path.join(dir, ...rel.split('/')), 'utf8').catch(() => undefined);
10
+ export async function readSchedule(dir) {
11
+ return parseSchedule((await read(dir, SCHEDULE_FILE)) ?? '');
12
+ }
13
+ /** Lane names from `.ai/lanes.json`; undefined when the repo has none (any simple name is then accepted). */
14
+ async function knownLanes(dir) {
15
+ const text = await read(dir, '.ai/lanes.json');
16
+ const parsed = text === undefined ? undefined : parseLanesConfig(text).config;
17
+ return parsed?.lanes.map((l) => l.name);
18
+ }
19
+ export async function checkLane(dir, lane) {
20
+ if (!/^[A-Za-z0-9][A-Za-z0-9_-]*$/.test(lane))
21
+ throw new Error(`"${lane}" is not a lane name.`);
22
+ const names = await knownLanes(dir);
23
+ if (names && !names.includes(lane))
24
+ throw new Error(`No lane "${lane}". Lanes here: ${names.join(', ')}.`);
25
+ }
26
+ export async function writeRel(dir, rel, text) {
27
+ const file = path.join(dir, ...rel.split('/'));
28
+ await mkdir(path.dirname(file), { recursive: true });
29
+ await writeFile(file, text);
30
+ }
31
+ /** Writes nothing when `commit` is false; otherwise commits the files with `Lane: control` and (by default) pushes. */
32
+ export async function commitFiles(dir, files, message, options, result, trailer = CONTROL_LANE) {
33
+ if (options.commit === false || result.changed.length === 0)
34
+ return;
35
+ await git(dir, 'add', '--', ...files);
36
+ await git(dir, 'commit', '-qm', `${message}\n\nLane: ${trailer}`, '--', ...files);
37
+ result.committed = true;
38
+ await pushIfWanted(dir, result, options.push);
39
+ }
40
+ export async function runScheduleShow(dir, now = new Date()) {
41
+ const schedule = await readSchedule(dir);
42
+ const names = (await knownLanes(dir)) ?? Object.keys(schedule.lanes);
43
+ const lanes = [];
44
+ for (const lane of names) {
45
+ const entry = schedule.lanes[lane] ?? dueEntry();
46
+ const runs = parseRunLog((await read(dir, runLogPath(lane))) ?? '');
47
+ lanes.push({ lane, state: notDueReason(entry, now) ?? 'due', entry, idleRuns: trailingIdleRuns(runs) });
48
+ }
49
+ return { lanes };
50
+ }
51
+ export function formatScheduleReport(report) {
52
+ if (report.lanes.length === 0)
53
+ return 'No lanes. Create .ai/lanes.json with `loop init --lanes a,b,c`.';
54
+ return report.lanes
55
+ .map(({ lane, state, entry, idleRuns }) => {
56
+ const detail = [entry.notBefore && state === 'snoozed' ? `until ${entry.notBefore.slice(0, 16).replace('T', ' ')} UTC` : '', idleRuns ? `${idleRuns} idle run${idleRuns === 1 ? '' : 's'}` : '', entry.reason ?? ''].filter(Boolean).join(' · ');
57
+ return `${lane.padEnd(10)} ${state.padEnd(9)} ${detail}`.trimEnd();
58
+ })
59
+ .join('\n');
60
+ }
61
+ const WOKEN = 'woken at ';
62
+ /** Applies one owner action to `.ai/schedule.json`. `wake` takes a lane name or `all`. */
63
+ export async function runScheduleAction(dir, act, options = {}) {
64
+ const now = options.now ?? new Date();
65
+ if (options.commit !== false)
66
+ await syncFirst(dir, options.push);
67
+ const lanes = act.action === 'wake' && act.lane === 'all' ? ((await knownLanes(dir)) ?? Object.keys((await readSchedule(dir)).lanes)) : [act.lane];
68
+ if (!(act.action === 'wake' && act.lane === 'all'))
69
+ await checkLane(dir, act.lane);
70
+ const schedule = await readSchedule(dir);
71
+ const result = { changed: [], committed: false };
72
+ for (const lane of lanes) {
73
+ const before = schedule.lanes[lane] ?? dueEntry();
74
+ let after;
75
+ if (act.action === 'pause')
76
+ after = { ...before, paused: true, reason: act.reason?.replace(/\s+/g, ' ').trim() || 'paused by owner' };
77
+ else if (act.action === 'resume')
78
+ after = { ...before, paused: false, reason: null };
79
+ else if (act.action === 'snooze') {
80
+ const until = parseUntil(act.until, now);
81
+ if (!until)
82
+ throw new Error(`Cannot read "${act.until}" as a future time. Use an ISO time, a date, or a span such as 3h or 2d.`);
83
+ after = { ...before, notBefore: until.toISOString(), sleeping: false, reason: act.reason?.replace(/\s+/g, ' ').trim() || 'snoozed by owner' };
84
+ }
85
+ else
86
+ after = { ...wakeEntry(before), reason: `${WOKEN}${now.toISOString()}` };
87
+ if (JSON.stringify(before) !== JSON.stringify(after)) {
88
+ schedule.lanes[lane] = after;
89
+ result.changed.push(lane);
90
+ }
91
+ }
92
+ if (result.changed.length === 0)
93
+ return result;
94
+ await writeRel(dir, SCHEDULE_FILE, formatSchedule(schedule));
95
+ await commitFiles(dir, [SCHEDULE_FILE], `Schedule: ${act.action} ${result.changed.join(', ')}`, options, result);
96
+ return result;
97
+ }
98
+ /**
99
+ * `loop schedule update`: wake lanes that have something waiting (unacknowledged steer, a message newer than their
100
+ * last run, a new round), otherwise apply the idle backoff from each lane's runs.jsonl. A lane woken by hand stays
101
+ * woken until it logs a run.
102
+ */
103
+ export async function runScheduleUpdate(dir, options = {}) {
104
+ const now = options.now ?? new Date();
105
+ if (options.commit !== false)
106
+ await syncFirst(dir, options.push);
107
+ const schedule = await readSchedule(dir);
108
+ if (options.lane)
109
+ await checkLane(dir, options.lane);
110
+ const names = options.lane ? [options.lane] : ((await knownLanes(dir)) ?? Object.keys(schedule.lanes));
111
+ const controlRoom = parseOutbox('control', (await read(dir, '.ai/control-room.md')) ?? '');
112
+ const outboxes = (await Promise.all((await knownLanes(dir) ?? names).map(async (lane) => parseOutbox(lane, (await read(dir, `.ai/lanes/${lane}/outbox.md`)) ?? '')))).flat();
113
+ const result = { changed: [], committed: false, woken: {} };
114
+ for (const lane of names) {
115
+ const before = schedule.lanes[lane] ?? dueEntry();
116
+ if (before.paused)
117
+ continue;
118
+ const runs = parseRunLog((await read(dir, runLogPath(lane))) ?? '');
119
+ const lastRunAt = runs.at(-1)?.at;
120
+ const manualWake = before.reason?.startsWith(WOKEN) && (!lastRunAt || new Date(lastRunAt).getTime() < new Date(before.reason.slice(WOKEN.length)).getTime());
121
+ const reasons = wakeReasons({
122
+ lane,
123
+ ...(lastRunAt && { lastRunAt }),
124
+ steer: parseSteer((await read(dir, steerPath(lane))) ?? ''),
125
+ messages: [...controlRoom, ...outboxes.filter((m) => m.from !== lane)],
126
+ ...(options.newRound && { newRound: true }),
127
+ });
128
+ let after = before;
129
+ if (manualWake)
130
+ continue;
131
+ if (reasons.length > 0) {
132
+ if (notDueReason(before, now)) {
133
+ after = { ...wakeEntry(before), reason: `woken: ${reasons.join(', ')}` };
134
+ result.woken[lane] = reasons;
135
+ }
136
+ }
137
+ else
138
+ after = applyBackoff(runs, before, now);
139
+ if (JSON.stringify(before) !== JSON.stringify(after)) {
140
+ schedule.lanes[lane] = after;
141
+ result.changed.push(lane);
142
+ }
143
+ }
144
+ if (result.changed.length === 0)
145
+ return result;
146
+ await writeRel(dir, SCHEDULE_FILE, formatSchedule(schedule));
147
+ await commitFiles(dir, [SCHEDULE_FILE], `Schedule: update ${result.changed.join(', ')}`, options, result, options.lane ?? CONTROL_LANE);
148
+ return result;
149
+ }
150
+ /** `loop steer`: adds a steer entry for a lane, wakes the lane in the schedule and commits both files. */
151
+ export async function runSteer(dir, lane, text, options = {}) {
152
+ const now = options.now ?? new Date();
153
+ if (!text.trim())
154
+ throw new Error('Say what the lane should do: loop steer <lane> "<text>".');
155
+ await checkLane(dir, lane);
156
+ if (options.commit !== false)
157
+ await syncFirst(dir, options.push);
158
+ const author = (options.author ?? (await git(dir, 'config', 'user.name').then((r) => r.stdout.trim(), () => ''))).trim();
159
+ if (!author)
160
+ throw new Error('Say who you are with --author <name> (git user.name is not set).');
161
+ const scope = options.standing ? 'standing' : 'next-run';
162
+ const file = steerPath(lane);
163
+ const current = (await read(dir, file)) ?? `# Steering for the ${lane} lane\n`;
164
+ await writeRel(dir, file, addSteerEntry(current, { at: now, author, scope, text }));
165
+ const schedule = await readSchedule(dir);
166
+ const before = schedule.lanes[lane];
167
+ const result = { changed: [lane], committed: false };
168
+ const files = [file];
169
+ if (before && (before.sleeping || before.notBefore)) {
170
+ schedule.lanes[lane] = { ...wakeEntry(before), reason: 'woken: steer' };
171
+ await writeRel(dir, SCHEDULE_FILE, formatSchedule(schedule));
172
+ files.push(SCHEDULE_FILE);
173
+ }
174
+ await commitFiles(dir, files, `Steer ${lane} (${scope}): ${text.trim().split(/\r?\n/)[0]?.slice(0, 60)}`, options, result);
175
+ return result;
176
+ }
177
+ //# sourceMappingURL=schedule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule.js","sourceRoot":"","sources":["../../src/cli/schedule.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { readFile } from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { promisify } from 'node:util';
5
+ import { parseLanesConfig } from '../core/lanes.js';
6
+ import { parseRunLog, runLogPath } from '../core/parse/runs.js';
7
+ import { shipCheck } from '../core/shipCheck.js';
8
+ const execFileAsync = promisify(execFile);
9
+ const read = (file) => readFile(file, 'utf8').catch(() => undefined);
10
+ const git = async (dir, ...args) => (await execFileAsync('git', args, { cwd: dir })).stdout;
11
+ /** Newest test result: the latest run-log line that carries one, else `.ai/last-test.json`. */
12
+ async function latestTests(dir) {
13
+ const configText = await read(path.join(dir, '.ai', 'lanes.json'));
14
+ const lanes = configText === undefined ? [] : (parseLanesConfig(configText).config?.lanes ?? []);
15
+ const entries = [];
16
+ for (const lane of lanes)
17
+ entries.push(...parseRunLog((await read(path.join(dir, ...runLogPath(lane.name).split('/')))) ?? ''));
18
+ const newest = entries.filter((e) => e.tests).sort((a, b) => b.at.localeCompare(a.at))[0];
19
+ if (newest?.tests)
20
+ return { ...newest.tests, at: newest.at };
21
+ try {
22
+ const record = JSON.parse((await read(path.join(dir, '.ai', 'last-test.json'))) ?? '');
23
+ if (typeof record.passed === 'number' && typeof record.failed === 'number')
24
+ return { passed: record.passed, failed: record.failed, ...(typeof record.at === 'string' && { at: record.at }) };
25
+ }
26
+ catch {
27
+ // no usable result
28
+ }
29
+ return undefined;
30
+ }
31
+ /** `loop ship-check`: gathers the facts from disk and git, then runs the pure checklist. */
32
+ export async function runShipCheck(dir) {
33
+ const pkg = JSON.parse((await read(path.join(dir, 'package.json'))) ?? 'null');
34
+ if (typeof pkg?.version !== 'string')
35
+ throw new Error('No package.json with a "version" here: ship-check needs it for the CHANGELOG and tag checks.');
36
+ const [doneText, changelogText, tags, status, tests] = await Promise.all([
37
+ read(path.join(dir, 'DONE.md')),
38
+ read(path.join(dir, 'CHANGELOG.md')),
39
+ git(dir, 'tag', '-l', `v${pkg.version}`).catch(() => ''),
40
+ git(dir, 'status', '--porcelain').catch(() => 'not a git repo'),
41
+ latestTests(dir),
42
+ ]);
43
+ return shipCheck({
44
+ version: pkg.version,
45
+ ...(doneText !== undefined && { doneText }),
46
+ ...(changelogText !== undefined && { changelogText }),
47
+ tagExists: tags.trim() !== '',
48
+ treeClean: status.trim() === '',
49
+ ...(tests && { tests }),
50
+ });
51
+ }
52
+ export function formatShipCheck(result) {
53
+ const lines = result.items.map((i) => `${i.ok ? '✓' : '✗'} ${i.label}: ${i.detail}`);
54
+ if (result.openFindings.length)
55
+ lines.push('', 'Open findings in DONE.md:', ...result.openFindings.map((f) => ` - ${f}`));
56
+ lines.push('', result.ready ? 'Ready to ship.' : 'Not ready to ship.');
57
+ return lines.join('\n');
58
+ }
59
+ //# sourceMappingURL=shipCheck.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shipCheck.js","sourceRoot":"","sources":["../../src/cli/shipCheck.ts"],"names":[],"mappings":"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"}
@@ -4,20 +4,40 @@ const VAGUE_WORDS = /\b(good|nice|great|modern|fast|clean|user-friendly|intuitiv
4
4
  const MIN_WORDS = 120;
5
5
  /** Bold labels (`**Goal:** text`) count as the deepest heading level. */
6
6
  const LABEL_LEVEL = 7;
7
+ /** `**Label:**` or `**Label**:` lead-ins, also several on one line (a round brief runs them together in a paragraph). */
8
+ const INLINE_LABEL = /(?:^|\s)\*\*([^*]{2,80}?)(?::\*\*|\*\*:)\s*/g;
7
9
  function splitSections(text) {
8
10
  const flat = [];
11
+ const addText = (line) => {
12
+ const last = flat[flat.length - 1];
13
+ if (last)
14
+ last.own += `${line}\n`;
15
+ };
9
16
  for (const line of text.split(/\r?\n/)) {
10
17
  const heading = /^(#{1,6})\s+(.*?)\s*#*\s*$/.exec(line);
11
- const label = /^\s*\*\*(.+?)\*\*:?\s*(.*)$/.exec(line) ?? /^\s*\*\*(.+?):\*\*\s*(.*)$/.exec(line);
12
- if (heading)
18
+ if (heading) {
13
19
  flat.push({ heading: heading[2] ?? '', level: (heading[1] ?? '#').length, own: '' });
14
- else if (label && !/^\s*[-*+]\s/.test(line))
15
- flat.push({ heading: (label[1] ?? '').replace(/:$/, ''), level: LABEL_LEVEL, own: `${label[2] ?? ''}\n` });
16
- else {
17
- const last = flat[flat.length - 1];
18
- if (last)
19
- last.own += `${line}\n`;
20
+ continue;
20
21
  }
22
+ const labels = /^\s*[-*+]\s/.test(line) ? [] : [...line.matchAll(INLINE_LABEL)];
23
+ const bare = labels.length === 0 ? /^\s*\*\*([^*]+?)\*\*\s*$/.exec(line) : undefined;
24
+ if (labels.length === 0 && !bare) {
25
+ addText(line);
26
+ continue;
27
+ }
28
+ if (bare) {
29
+ flat.push({ heading: (bare[1] ?? '').replace(/:$/, ''), level: LABEL_LEVEL, own: '' });
30
+ continue;
31
+ }
32
+ const first = labels[0];
33
+ const before = line.slice(0, first.index);
34
+ if (before.trim())
35
+ addText(before);
36
+ labels.forEach((label, i) => {
37
+ const start = (label.index ?? 0) + label[0].length;
38
+ const end = labels[i + 1]?.index ?? line.length;
39
+ flat.push({ heading: (label[1] ?? '').replace(/:$/, '').trim(), level: LABEL_LEVEL, own: `${line.slice(start, end)}\n` });
40
+ });
21
41
  }
22
42
  return flat.map((section, i) => {
23
43
  let body = section.own;
@@ -30,6 +50,8 @@ function splitSections(text) {
30
50
  });
31
51
  }
32
52
  const findSection = (sections, pattern) => sections.find((s) => pattern.test(s.heading));
53
+ /** A round brief lists its must-haves under lettered headings (`### A. P0 bugs`), so every such section counts. */
54
+ const LETTERED = /^\W*[A-Z][.)]\s/;
33
55
  /** Bullet and numbered-list items of a section body, without their markers. */
34
56
  export function listItems(body) {
35
57
  return body
@@ -49,7 +71,7 @@ export function lintBrief(text) {
49
71
  const sections = splitSections(text);
50
72
  const gaps = [];
51
73
  const miss = (gap) => gaps.push(gap);
52
- const oneLine = findSection(sections, /^\W*(one[- ]line|summary|overview|goal|what (this|it) is|pitch)\b/i);
74
+ const oneLine = findSection(sections, /^\W*(one[- ]line|summary|overview|goal|what (this|it|we are|we're) (is |are )?(building|is)?|the new headline|headline|pitch)\b/i);
53
75
  if (!oneLine || oneLine.body.trim().length < 20) {
54
76
  miss({ id: 'one-line', cost: 15, message: 'No one-line description of what you are building.' });
55
77
  }
@@ -57,8 +79,9 @@ export function lintBrief(text) {
57
79
  if (!audience || audience.body.trim().length < 20) {
58
80
  miss({ id: 'audience', cost: 15, message: 'No audience: say who this is for.' });
59
81
  }
60
- const mustHeading = findSection(sections, /^\W*(must[- ]?haves?|requirements?|features?|deliverables?|scope\b)/i);
61
- const items = mustHeading ? listItems(mustHeading.body) : [];
82
+ const mustSections = sections.filter((x) => /^\W*(must[- ]?haves?|requirements?|features?|deliverables?|scope\b)/i.test(x.heading) || LETTERED.test(x.heading));
83
+ // Nested sections repeat their parent's text, so count each list line once.
84
+ const items = [...new Set(mustSections.flatMap((x) => listItems(x.body)))];
62
85
  if (items.length < 3) {
63
86
  miss({ id: 'must-haves', cost: 20, message: 'Fewer than three must-haves listed as bullets.' });
64
87
  }
@@ -72,7 +95,7 @@ export function lintBrief(text) {
72
95
  });
73
96
  }
74
97
  }
75
- const doneWhen = findSection(sections, /^\W*(done[- ]when|definition of done|acceptance|success criteria)/i);
98
+ const doneWhen = findSection(sections, /^\W*(?:round \d+\s+)?(done[- ]when|definition of done|acceptance|success criteria)/i);
76
99
  const checkable = doneWhen ? /`[^`]+`|\b(npm|pnpm|yarn|pytest|make|cargo)\b|\btests?\s+(pass|green)/i.test(doneWhen.body) : false;
77
100
  if (!checkable) {
78
101
  miss({ id: 'done-when', cost: 25, message: 'No checkable done-when: list commands or tests that must pass.' });