@mobrienv/autoloop 0.1.4 → 0.2.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 (328) hide show
  1. package/README.md +13 -0
  2. package/bin/autoloop +0 -0
  3. package/dist/agent-map.d.ts +10 -0
  4. package/dist/agent-map.js +58 -0
  5. package/dist/agent-map.js.map +1 -0
  6. package/dist/backend/acp-client.d.ts +32 -0
  7. package/dist/backend/acp-client.js +210 -0
  8. package/dist/backend/acp-client.js.map +1 -0
  9. package/dist/backend/index.d.ts +1 -1
  10. package/dist/backend/index.js +17 -5
  11. package/dist/backend/index.js.map +1 -1
  12. package/dist/backend/kiro-bridge.d.ts +17 -0
  13. package/dist/backend/kiro-bridge.js +80 -0
  14. package/dist/backend/kiro-bridge.js.map +1 -0
  15. package/dist/backend/kiro-worker.d.ts +1 -0
  16. package/dist/backend/kiro-worker.js +83 -0
  17. package/dist/backend/kiro-worker.js.map +1 -0
  18. package/dist/backend/run-command.js +2 -2
  19. package/dist/backend/run-command.js.map +1 -1
  20. package/dist/backend/run-kiro.d.ts +3 -0
  21. package/dist/backend/run-kiro.js +12 -0
  22. package/dist/backend/run-kiro.js.map +1 -0
  23. package/dist/backend/run-pi.js.map +1 -1
  24. package/dist/chains/budget.js +16 -4
  25. package/dist/chains/budget.js.map +1 -1
  26. package/dist/chains/load.d.ts +7 -1
  27. package/dist/chains/load.js +58 -9
  28. package/dist/chains/load.js.map +1 -1
  29. package/dist/chains/render.js +36 -8
  30. package/dist/chains/render.js.map +1 -1
  31. package/dist/chains/run.js +129 -44
  32. package/dist/chains/run.js.map +1 -1
  33. package/dist/chains/types.d.ts +1 -0
  34. package/dist/chains.d.ts +5 -4
  35. package/dist/chains.js +3 -3
  36. package/dist/chains.js.map +1 -1
  37. package/dist/commands/chain.js +6 -4
  38. package/dist/commands/chain.js.map +1 -1
  39. package/dist/commands/config.d.ts +1 -0
  40. package/dist/commands/config.js +74 -0
  41. package/dist/commands/config.js.map +1 -0
  42. package/dist/commands/dashboard.d.ts +1 -0
  43. package/dist/commands/dashboard.js +68 -0
  44. package/dist/commands/dashboard.js.map +1 -0
  45. package/dist/commands/inspect.js +125 -17
  46. package/dist/commands/inspect.js.map +1 -1
  47. package/dist/commands/list.d.ts +1 -1
  48. package/dist/commands/list.js +6 -3
  49. package/dist/commands/list.js.map +1 -1
  50. package/dist/commands/loops.js +11 -11
  51. package/dist/commands/loops.js.map +1 -1
  52. package/dist/commands/memory.js +2 -2
  53. package/dist/commands/memory.js.map +1 -1
  54. package/dist/commands/run.d.ts +1 -1
  55. package/dist/commands/run.js +102 -15
  56. package/dist/commands/run.js.map +1 -1
  57. package/dist/commands/runs.d.ts +1 -0
  58. package/dist/commands/runs.js +50 -0
  59. package/dist/commands/runs.js.map +1 -0
  60. package/dist/commands/task.d.ts +1 -0
  61. package/dist/commands/task.js +74 -0
  62. package/dist/commands/task.js.map +1 -0
  63. package/dist/commands/worktree.d.ts +1 -0
  64. package/dist/commands/worktree.js +162 -0
  65. package/dist/commands/worktree.js.map +1 -0
  66. package/dist/config.d.ts +15 -1
  67. package/dist/config.js +90 -21
  68. package/dist/config.js.map +1 -1
  69. package/dist/dashboard/app.d.ts +12 -0
  70. package/dist/dashboard/app.js +23 -0
  71. package/dist/dashboard/app.js.map +1 -0
  72. package/dist/dashboard/routes/api.d.ts +3 -0
  73. package/dist/dashboard/routes/api.js +103 -0
  74. package/dist/dashboard/routes/api.js.map +1 -0
  75. package/dist/dashboard/routes/pages.d.ts +2 -0
  76. package/dist/dashboard/routes/pages.js +14 -0
  77. package/dist/dashboard/routes/pages.js.map +1 -0
  78. package/dist/dashboard/views/alpine-vendor.d.ts +1 -0
  79. package/dist/dashboard/views/alpine-vendor.js +10 -0
  80. package/dist/dashboard/views/alpine-vendor.js.map +1 -0
  81. package/dist/dashboard/views/shell.d.ts +1 -0
  82. package/dist/dashboard/views/shell.js +714 -0
  83. package/dist/dashboard/views/shell.js.map +1 -0
  84. package/dist/events/decode.js.map +1 -1
  85. package/dist/events/encode.js +2 -2
  86. package/dist/events/encode.js.map +1 -1
  87. package/dist/harness/config-helpers.d.ts +11 -0
  88. package/dist/harness/config-helpers.js +242 -64
  89. package/dist/harness/config-helpers.js.map +1 -1
  90. package/dist/harness/coordination.js +12 -12
  91. package/dist/harness/coordination.js.map +1 -1
  92. package/dist/harness/display.d.ts +4 -3
  93. package/dist/harness/display.js +57 -11
  94. package/dist/harness/display.js.map +1 -1
  95. package/dist/harness/emit.js +31 -13
  96. package/dist/harness/emit.js.map +1 -1
  97. package/dist/harness/index.d.ts +7 -7
  98. package/dist/harness/index.js +151 -35
  99. package/dist/harness/index.js.map +1 -1
  100. package/dist/harness/iteration.d.ts +12 -0
  101. package/dist/harness/iteration.js +66 -64
  102. package/dist/harness/iteration.js.map +1 -1
  103. package/dist/harness/journal.d.ts +17 -0
  104. package/dist/harness/journal.js +74 -5
  105. package/dist/harness/journal.js.map +1 -1
  106. package/dist/harness/metareview.js +30 -15
  107. package/dist/harness/metareview.js.map +1 -1
  108. package/dist/harness/metrics.js +12 -12
  109. package/dist/harness/metrics.js.map +1 -1
  110. package/dist/harness/parallel.d.ts +1 -1
  111. package/dist/harness/parallel.js +141 -62
  112. package/dist/harness/parallel.js.map +1 -1
  113. package/dist/harness/prompt.d.ts +18 -9
  114. package/dist/harness/prompt.js +80 -44
  115. package/dist/harness/prompt.js.map +1 -1
  116. package/dist/harness/scratchpad.js +8 -6
  117. package/dist/harness/scratchpad.js.map +1 -1
  118. package/dist/harness/stop.js +16 -9
  119. package/dist/harness/stop.js.map +1 -1
  120. package/dist/harness/tools.js +39 -13
  121. package/dist/harness/tools.js.map +1 -1
  122. package/dist/harness/types.d.ts +29 -0
  123. package/dist/harness/wave/finalize-wave.d.ts +1 -1
  124. package/dist/harness/wave/finalize-wave.js +36 -9
  125. package/dist/harness/wave/finalize-wave.js.map +1 -1
  126. package/dist/harness/wave/launch-branches.d.ts +2 -2
  127. package/dist/harness/wave/launch-branches.js +147 -51
  128. package/dist/harness/wave/launch-branches.js.map +1 -1
  129. package/dist/harness/wave/parse-objectives.js +4 -1
  130. package/dist/harness/wave/parse-objectives.js.map +1 -1
  131. package/dist/harness/wave.d.ts +2 -2
  132. package/dist/harness/wave.js +89 -28
  133. package/dist/harness/wave.js.map +1 -1
  134. package/dist/isolation/index.d.ts +4 -0
  135. package/dist/isolation/index.js +3 -0
  136. package/dist/isolation/index.js.map +1 -0
  137. package/dist/isolation/resolve.d.ts +39 -0
  138. package/dist/isolation/resolve.js +118 -0
  139. package/dist/isolation/resolve.js.map +1 -0
  140. package/dist/isolation/run-scope.d.ts +21 -0
  141. package/dist/isolation/run-scope.js +50 -0
  142. package/dist/isolation/run-scope.js.map +1 -0
  143. package/dist/json.js +10 -8
  144. package/dist/json.js.map +1 -1
  145. package/dist/loops/health.d.ts +4 -2
  146. package/dist/loops/health.js +73 -25
  147. package/dist/loops/health.js.map +1 -1
  148. package/dist/loops/list.d.ts +2 -2
  149. package/dist/loops/list.js +6 -6
  150. package/dist/loops/list.js.map +1 -1
  151. package/dist/loops/policy.d.ts +6 -0
  152. package/dist/loops/policy.js +41 -0
  153. package/dist/loops/policy.js.map +1 -0
  154. package/dist/loops/render.d.ts +2 -1
  155. package/dist/loops/render.js +24 -11
  156. package/dist/loops/render.js.map +1 -1
  157. package/dist/loops/show.d.ts +2 -2
  158. package/dist/loops/show.js +13 -13
  159. package/dist/loops/show.js.map +1 -1
  160. package/dist/loops/watch.d.ts +7 -1
  161. package/dist/loops/watch.js +82 -16
  162. package/dist/loops/watch.js.map +1 -1
  163. package/dist/main.js +48 -11
  164. package/dist/main.js.map +1 -1
  165. package/dist/markdown.js +11 -11
  166. package/dist/markdown.js.map +1 -1
  167. package/dist/memory-render.js +5 -5
  168. package/dist/memory-render.js.map +1 -1
  169. package/dist/memory.d.ts +1 -2
  170. package/dist/memory.js +44 -40
  171. package/dist/memory.js.map +1 -1
  172. package/dist/pi-adapter.js +11 -11
  173. package/dist/pi-adapter.js.map +1 -1
  174. package/dist/profiles.d.ts +12 -0
  175. package/dist/profiles.js +71 -0
  176. package/dist/profiles.js.map +1 -0
  177. package/dist/registry/derive.js +10 -3
  178. package/dist/registry/derive.js.map +1 -1
  179. package/dist/registry/discover.d.ts +20 -0
  180. package/dist/registry/discover.js +98 -0
  181. package/dist/registry/discover.js.map +1 -0
  182. package/dist/registry/harness.js +8 -2
  183. package/dist/registry/harness.js.map +1 -1
  184. package/dist/registry/index.d.ts +4 -3
  185. package/dist/registry/index.js +3 -2
  186. package/dist/registry/index.js.map +1 -1
  187. package/dist/registry/read.js.map +1 -1
  188. package/dist/registry/rebuild.js +7 -4
  189. package/dist/registry/rebuild.js.map +1 -1
  190. package/dist/registry/types.d.ts +9 -0
  191. package/dist/registry/update.js +1 -1
  192. package/dist/registry/update.js.map +1 -1
  193. package/dist/tasks-render.d.ts +2 -0
  194. package/dist/tasks-render.js +44 -0
  195. package/dist/tasks-render.js.map +1 -0
  196. package/dist/tasks.d.ts +24 -0
  197. package/dist/tasks.js +184 -0
  198. package/dist/tasks.js.map +1 -0
  199. package/dist/testing/mock-backend.js +2 -2
  200. package/dist/testing/mock-backend.js.map +1 -1
  201. package/dist/topology.d.ts +6 -0
  202. package/dist/topology.js +129 -8
  203. package/dist/topology.js.map +1 -1
  204. package/dist/usage.d.ts +1 -0
  205. package/dist/usage.js +56 -11
  206. package/dist/usage.js.map +1 -1
  207. package/dist/utils.d.ts +6 -0
  208. package/dist/utils.js +272 -2
  209. package/dist/utils.js.map +1 -1
  210. package/dist/worktree/clean.d.ts +12 -0
  211. package/dist/worktree/clean.js +98 -0
  212. package/dist/worktree/clean.js.map +1 -0
  213. package/dist/worktree/create.d.ts +14 -0
  214. package/dist/worktree/create.js +71 -0
  215. package/dist/worktree/create.js.map +1 -0
  216. package/dist/worktree/index.d.ts +10 -0
  217. package/dist/worktree/index.js +6 -0
  218. package/dist/worktree/index.js.map +1 -0
  219. package/dist/worktree/list.d.ts +9 -0
  220. package/dist/worktree/list.js +24 -0
  221. package/dist/worktree/list.js.map +1 -0
  222. package/dist/worktree/merge.d.ts +11 -0
  223. package/dist/worktree/merge.js +129 -0
  224. package/dist/worktree/merge.js.map +1 -0
  225. package/dist/worktree/meta.d.ts +17 -0
  226. package/dist/worktree/meta.js +34 -0
  227. package/dist/worktree/meta.js.map +1 -0
  228. package/package.json +24 -4
  229. package/presets/autocode/README.md +1 -1
  230. package/presets/autocode/autoloops.toml +9 -1
  231. package/presets/autocode/harness.md +12 -5
  232. package/presets/autocode/roles/build.md +5 -4
  233. package/presets/autocode/roles/critic.md +2 -2
  234. package/presets/autocode/roles/finalizer.md +2 -2
  235. package/presets/autocode/roles/planner.md +7 -7
  236. package/presets/autodoc/README.md +1 -1
  237. package/presets/autodoc/autoloops.toml +1 -1
  238. package/presets/autodoc/harness.md +6 -6
  239. package/presets/autodoc/roles/auditor.md +3 -3
  240. package/presets/autodoc/roles/checker.md +2 -2
  241. package/presets/autodoc/roles/publisher.md +3 -3
  242. package/presets/autodoc/roles/writer.md +4 -4
  243. package/presets/autofix/README.md +1 -1
  244. package/presets/autofix/autoloops.toml +5 -2
  245. package/presets/autofix/harness.md +8 -7
  246. package/presets/autofix/roles/closer.md +4 -4
  247. package/presets/autofix/roles/diagnoser.md +6 -5
  248. package/presets/autofix/roles/fixer.md +4 -4
  249. package/presets/autofix/roles/verifier.md +2 -2
  250. package/presets/autoideas/README.md +1 -1
  251. package/presets/autoideas/autoloops.toml +1 -1
  252. package/presets/autoideas/harness.md +11 -11
  253. package/presets/autoideas/roles/analyst.md +4 -4
  254. package/presets/autoideas/roles/reviewer.md +3 -3
  255. package/presets/autoideas/roles/scanner.md +3 -3
  256. package/presets/autoideas/roles/synthesizer.md +20 -7
  257. package/presets/automerge/README.md +3 -0
  258. package/presets/automerge/autoloops.toml +12 -0
  259. package/presets/automerge/harness.md +10 -0
  260. package/presets/automerge/miniloops.toml +12 -0
  261. package/presets/automerge/roles/merge.md +10 -0
  262. package/presets/automerge/topology.toml +10 -0
  263. package/presets/autoperf/README.md +1 -1
  264. package/presets/autoperf/autoloops.toml +1 -1
  265. package/presets/autoperf/harness.md +5 -5
  266. package/presets/autoperf/roles/judge.md +3 -3
  267. package/presets/autoperf/roles/measurer.md +4 -4
  268. package/presets/autoperf/roles/optimizer.md +4 -4
  269. package/presets/autoperf/roles/profiler.md +4 -4
  270. package/presets/autopr/README.md +99 -0
  271. package/presets/autopr/autoloops.toml +22 -0
  272. package/presets/autopr/harness.md +27 -0
  273. package/presets/autopr/miniloops.toml +22 -0
  274. package/presets/autopr/roles/collector.md +55 -0
  275. package/presets/autopr/roles/drafter.md +38 -0
  276. package/presets/autopr/roles/publisher.md +28 -0
  277. package/presets/autopr/roles/validator.md +31 -0
  278. package/presets/autopr/topology.toml +32 -0
  279. package/presets/autoqa/README.md +1 -1
  280. package/presets/autoqa/autoloops.toml +1 -1
  281. package/presets/autoqa/harness.md +10 -10
  282. package/presets/autoqa/roles/executor.md +3 -3
  283. package/presets/autoqa/roles/inspector.md +2 -2
  284. package/presets/autoqa/roles/planner.md +6 -6
  285. package/presets/autoqa/roles/reporter.md +9 -9
  286. package/presets/autoresearch/README.md +1 -1
  287. package/presets/autoresearch/autoloops.toml +1 -1
  288. package/presets/autoresearch/harness.md +5 -5
  289. package/presets/autoresearch/roles/benchmarker.md +3 -3
  290. package/presets/autoresearch/roles/evaluator.md +5 -5
  291. package/presets/autoresearch/roles/implementer.md +4 -4
  292. package/presets/autoresearch/roles/strategist.md +6 -6
  293. package/presets/autoreview/README.md +1 -1
  294. package/presets/autoreview/autoloops.toml +1 -1
  295. package/presets/autoreview/harness.md +5 -5
  296. package/presets/autoreview/roles/checker.md +4 -4
  297. package/presets/autoreview/roles/reader.md +5 -5
  298. package/presets/autoreview/roles/suggester.md +4 -4
  299. package/presets/autoreview/roles/summarizer.md +4 -4
  300. package/presets/autosec/README.md +1 -1
  301. package/presets/autosec/autoloops.toml +1 -1
  302. package/presets/autosec/harness.md +5 -5
  303. package/presets/autosec/roles/analyst.md +4 -4
  304. package/presets/autosec/roles/hardener.md +2 -2
  305. package/presets/autosec/roles/reporter.md +4 -4
  306. package/presets/autosec/roles/scanner.md +3 -3
  307. package/presets/autosimplify/README.md +1 -1
  308. package/presets/autosimplify/autoloops.toml +7 -3
  309. package/presets/autosimplify/harness.md +7 -7
  310. package/presets/autosimplify/roles/reviewer.md +3 -3
  311. package/presets/autosimplify/roles/scoper.md +7 -7
  312. package/presets/autosimplify/roles/simplifier.md +4 -4
  313. package/presets/autosimplify/roles/verifier.md +3 -3
  314. package/presets/autospec/README.md +1 -1
  315. package/presets/autospec/autoloops.toml +1 -1
  316. package/presets/autospec/harness.md +6 -6
  317. package/presets/autospec/roles/clarifier.md +4 -3
  318. package/presets/autospec/roles/critic.md +1 -1
  319. package/presets/autospec/roles/designer.md +3 -3
  320. package/presets/autospec/roles/planner.md +2 -2
  321. package/presets/autospec/roles/researcher.md +3 -3
  322. package/presets/autotest/README.md +1 -1
  323. package/presets/autotest/autoloops.toml +1 -1
  324. package/presets/autotest/harness.md +6 -6
  325. package/presets/autotest/roles/assessor.md +3 -3
  326. package/presets/autotest/roles/runner.md +2 -2
  327. package/presets/autotest/roles/surveyor.md +4 -4
  328. package/presets/autotest/roles/writer.md +4 -4
@@ -0,0 +1,39 @@
1
+ import type { RunRecord } from "../registry/types.js";
2
+ export type IsolationMode = "shared" | "run-scoped" | "worktree";
3
+ export interface IsolationRequest {
4
+ worktree?: boolean;
5
+ noWorktree?: boolean;
6
+ configEnabled?: boolean;
7
+ currentCategory?: PresetCategory;
8
+ }
9
+ export interface IsolationResult {
10
+ mode: IsolationMode;
11
+ warning?: string;
12
+ }
13
+ /**
14
+ * Decide the isolation mode for a new run based on CLI flags,
15
+ * config, and the state of currently active runs.
16
+ *
17
+ * Priority:
18
+ * 1. Explicit --worktree flag → "worktree"
19
+ * 2. Explicit --no-worktree flag → "shared"
20
+ * 3. Config isolation.enabled → "worktree"
21
+ * 4. Other active runs exist with code roles → "run-scoped" + warning
22
+ * 5. Other active runs exist (non-code) → "run-scoped"
23
+ * 6. Solo run → "run-scoped" (working files isolate per run by default)
24
+ */
25
+ export declare function resolveIsolationMode(request: IsolationRequest, otherActiveRuns: RunRecord[]): IsolationResult;
26
+ export type PresetCategory = "code" | "planning" | "unknown";
27
+ /**
28
+ * Determine preset category from harness.md metadata or name heuristic.
29
+ * Reads `<!-- category: ... -->` from harness.md if present.
30
+ * Falls back to name-based heuristic.
31
+ */
32
+ export declare function presetCategory(presetName: string, projectDir: string): PresetCategory;
33
+ /**
34
+ * Heuristic: a run is "code-modifying" if its preset or objective
35
+ * suggests it writes code (builder, autocode, fix, etc.).
36
+ * Accepts an optional category override from preset metadata.
37
+ * This is intentionally conservative — returns false when uncertain.
38
+ */
39
+ export declare function isCodeModifyingRun(record: RunRecord, categoryOverride?: PresetCategory): boolean;
@@ -0,0 +1,118 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { resolvePresetDir } from "../chains/load.js";
4
+ /**
5
+ * Decide the isolation mode for a new run based on CLI flags,
6
+ * config, and the state of currently active runs.
7
+ *
8
+ * Priority:
9
+ * 1. Explicit --worktree flag → "worktree"
10
+ * 2. Explicit --no-worktree flag → "shared"
11
+ * 3. Config isolation.enabled → "worktree"
12
+ * 4. Other active runs exist with code roles → "run-scoped" + warning
13
+ * 5. Other active runs exist (non-code) → "run-scoped"
14
+ * 6. Solo run → "run-scoped" (working files isolate per run by default)
15
+ */
16
+ export function resolveIsolationMode(request, otherActiveRuns) {
17
+ if (request.worktree) {
18
+ return { mode: "worktree" };
19
+ }
20
+ if (request.noWorktree) {
21
+ return { mode: "shared" };
22
+ }
23
+ if (request.configEnabled) {
24
+ return { mode: "worktree" };
25
+ }
26
+ if (otherActiveRuns.length === 0) {
27
+ return { mode: "run-scoped" };
28
+ }
29
+ const hasCodeRuns = otherActiveRuns.some((r) => isCodeModifyingRun(r));
30
+ // Planning/read-only presets are safe to run concurrently — no warning needed
31
+ if (request.currentCategory === "planning") {
32
+ return { mode: "run-scoped" };
33
+ }
34
+ // Code or unknown presets warn when concurrent code-modifying runs exist
35
+ if (hasCodeRuns) {
36
+ const codeRuns = otherActiveRuns.filter((r) => isCodeModifyingRun(r));
37
+ const runList = codeRuns.map((r) => `${r.run_id} (${r.preset})`).join(", ");
38
+ const warning = [
39
+ `Active code-modifying run detected: ${runList}`,
40
+ " Runs sharing the same checkout may produce code conflicts.",
41
+ ' Consider: autoloop run <preset> --worktree "your prompt"',
42
+ ' Or suppress: autoloop run <preset> --no-worktree "your prompt"',
43
+ ].join("\n");
44
+ return {
45
+ mode: "run-scoped",
46
+ warning,
47
+ };
48
+ }
49
+ return { mode: "run-scoped" };
50
+ }
51
+ /**
52
+ * Determine preset category from harness.md metadata or name heuristic.
53
+ * Reads `<!-- category: ... -->` from harness.md if present.
54
+ * Falls back to name-based heuristic.
55
+ */
56
+ export function presetCategory(presetName, projectDir) {
57
+ const presetDir = resolvePresetDir(presetName, projectDir);
58
+ const harnessPath = join(presetDir, "harness.md");
59
+ if (existsSync(harnessPath)) {
60
+ const content = readFileSync(harnessPath, "utf-8");
61
+ const match = content.match(/<!--\s*category:\s*([\w-]+)\s*-->/);
62
+ if (match) {
63
+ const cat = match[1].toLowerCase();
64
+ if (cat === "code")
65
+ return "code";
66
+ if (cat === "planning")
67
+ return "planning";
68
+ }
69
+ }
70
+ // Name-based heuristic fallback
71
+ const name = presetName.toLowerCase();
72
+ const codePresets = [
73
+ "autocode",
74
+ "autofix",
75
+ "autotest",
76
+ "autosimplify",
77
+ "autoperf",
78
+ "autosec",
79
+ ];
80
+ if (codePresets.some((p) => name.includes(p)))
81
+ return "code";
82
+ const planningPresets = [
83
+ "automerge",
84
+ "autoideas",
85
+ "autoresearch",
86
+ "autodoc",
87
+ "autoreview",
88
+ "autoqa",
89
+ "autospec",
90
+ ];
91
+ if (planningPresets.some((p) => name.includes(p)))
92
+ return "planning";
93
+ return "unknown";
94
+ }
95
+ /**
96
+ * Heuristic: a run is "code-modifying" if its preset or objective
97
+ * suggests it writes code (builder, autocode, fix, etc.).
98
+ * Accepts an optional category override from preset metadata.
99
+ * This is intentionally conservative — returns false when uncertain.
100
+ */
101
+ export function isCodeModifyingRun(record, categoryOverride) {
102
+ if (categoryOverride === "code")
103
+ return true;
104
+ if (categoryOverride === "planning")
105
+ return false;
106
+ const preset = record.preset.toLowerCase();
107
+ const objective = record.objective.toLowerCase();
108
+ const codeIndicators = [
109
+ "autocode",
110
+ "builder",
111
+ "fix",
112
+ "implement",
113
+ "refactor",
114
+ "code",
115
+ ];
116
+ return codeIndicators.some((ind) => preset.includes(ind) || objective.includes(ind));
117
+ }
118
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/isolation/resolve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Create a run-scoped state directory under `.autoloop/runs/<runId>/`.
3
+ * Returns the absolute path to the created directory.
4
+ */
5
+ export declare function createRunScopedDir(baseStateDir: string, runId: string): string;
6
+ /**
7
+ * Compute the run-scoped path without creating it.
8
+ */
9
+ export declare function runScopedPath(baseStateDir: string, runId: string): string;
10
+ export interface CleanRunScopedOpts {
11
+ /** Skip directories for runs that are still active. */
12
+ activeRunIds: Set<string>;
13
+ /** Only remove directories older than this many days. 0 = no age filter. Default: 0. */
14
+ maxAgeDays?: number;
15
+ }
16
+ /**
17
+ * Clean up run-scoped directories for runs that have reached a terminal state.
18
+ * Keeps directories for runs that are still active.
19
+ * When maxAgeDays > 0, also keeps directories modified within the threshold.
20
+ */
21
+ export declare function cleanRunScopedDirs(baseStateDir: string, opts: CleanRunScopedOpts): string[];
@@ -0,0 +1,50 @@
1
+ import { existsSync, mkdirSync, readdirSync, rmSync, statSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ /**
4
+ * Create a run-scoped state directory under `.autoloop/runs/<runId>/`.
5
+ * Returns the absolute path to the created directory.
6
+ */
7
+ export function createRunScopedDir(baseStateDir, runId) {
8
+ const dir = runScopedPath(baseStateDir, runId);
9
+ mkdirSync(dir, { recursive: true });
10
+ return dir;
11
+ }
12
+ /**
13
+ * Compute the run-scoped path without creating it.
14
+ */
15
+ export function runScopedPath(baseStateDir, runId) {
16
+ return join(baseStateDir, "runs", runId);
17
+ }
18
+ /**
19
+ * Clean up run-scoped directories for runs that have reached a terminal state.
20
+ * Keeps directories for runs that are still active.
21
+ * When maxAgeDays > 0, also keeps directories modified within the threshold.
22
+ */
23
+ export function cleanRunScopedDirs(baseStateDir, opts) {
24
+ const runsDir = join(baseStateDir, "runs");
25
+ if (!existsSync(runsDir))
26
+ return [];
27
+ const { activeRunIds, maxAgeDays = 0 } = opts;
28
+ const now = Date.now();
29
+ const thresholdMs = maxAgeDays > 0 ? maxAgeDays * 86_400_000 : 0;
30
+ const removed = [];
31
+ for (const entry of readdirSync(runsDir)) {
32
+ if (activeRunIds.has(entry))
33
+ continue;
34
+ const fullPath = join(runsDir, entry);
35
+ if (thresholdMs > 0) {
36
+ try {
37
+ const mtime = statSync(fullPath).mtimeMs;
38
+ if (now - mtime < thresholdMs)
39
+ continue;
40
+ }
41
+ catch {
42
+ continue;
43
+ }
44
+ }
45
+ rmSync(fullPath, { recursive: true, force: true });
46
+ removed.push(entry);
47
+ }
48
+ return removed;
49
+ }
50
+ //# sourceMappingURL=run-scope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-scope.js","sourceRoot":"","sources":["../../src/isolation/run-scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,YAAoB,EACpB,KAAa;IAEb,MAAM,GAAG,GAAG,aAAa,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IAC/C,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpC,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,YAAoB,EAAE,KAAa;IAC/D,OAAO,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;AAC3C,CAAC;AASD;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,YAAoB,EACpB,IAAwB;IAExB,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAC3C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAC;IAEpC,MAAM,EAAE,YAAY,EAAE,UAAU,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC;IAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,WAAW,GAAG,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAEjE,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;QACzC,IAAI,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,SAAS;QACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAEtC,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;YACpB,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC;gBACzC,IAAI,GAAG,GAAG,KAAK,GAAG,WAAW;oBAAE,SAAS;YAC1C,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;QACH,CAAC;QAED,MAAM,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
package/dist/json.js CHANGED
@@ -1,16 +1,16 @@
1
- import { replaceAll, lineSep } from "./utils.js";
2
1
  import { decodeEvent } from "./events/decode.js";
2
+ import { lineSep, replaceAll } from "./utils.js";
3
3
  export function jsonString(text) {
4
- return '"' + encodeJsonValue(text) + '"';
4
+ return `"${encodeJsonValue(text)}"`;
5
5
  }
6
6
  export function jsonBool(value) {
7
7
  return value ? "true" : "false";
8
8
  }
9
9
  export function jsonField(key, value) {
10
- return '"' + key + '": ' + jsonString(value);
10
+ return `"${key}": ${jsonString(value)}`;
11
11
  }
12
12
  export function jsonFieldRaw(key, rawValue) {
13
- return '"' + key + '": ' + rawValue;
13
+ return `"${key}": ${rawValue}`;
14
14
  }
15
15
  export function extractTopic(line) {
16
16
  const decoded = decodeEvent(line);
@@ -34,9 +34,11 @@ export function extractField(line, key) {
34
34
  return decoded.source ?? "";
35
35
  return "";
36
36
  }
37
- return decoded.fields[key] ?? "";
37
+ const value = decoded.fields[key];
38
+ if (value !== undefined)
39
+ return value;
38
40
  }
39
- const marker = '"' + key + '": ';
41
+ const marker = `"${key}": `;
40
42
  return decodeJsonValue(firstQuotedValue(firstAfterMarker(line.split(marker))));
41
43
  }
42
44
  export function encodeJsonValue(text) {
@@ -50,8 +52,8 @@ export function encodeJsonValue(text) {
50
52
  function escapeRemainingControlChars(text) {
51
53
  // Replace control chars \x00-\x08, \x0b, \x0c, \x0e-\x1f
52
54
  return text.replace(
53
- // eslint-disable-next-line no-control-regex
54
- /[\x00-\x08\x0b\x0c\x0e-\x1f]/g, (ch) => "\\u" + ch.charCodeAt(0).toString(16).padStart(4, "0"));
55
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: intentional control char stripping
56
+ /[\x00-\x08\x0b\x0c\x0e-\x1f]/g, (ch) => `\\u${ch.charCodeAt(0).toString(16).padStart(4, "0")}`);
55
57
  }
56
58
  export function decodeJsonValue(text) {
57
59
  let restored = replaceAll(text, "\\u000a", lineSep());
package/dist/json.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"json.js","sourceRoot":"","sources":["../src/json.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"json.js","sourceRoot":"","sources":["../src/json.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import type { RunRecord } from "../registry/types.js";
2
2
  export interface HealthResult {
3
3
  active: RunRecord[];
4
+ watching: RunRecord[];
4
5
  stuck: RunRecord[];
5
6
  recentFailed: RunRecord[];
6
7
  recentCompleted: RunRecord[];
@@ -10,5 +11,6 @@ export interface HealthResult {
10
11
  * Exception-focused: only surfaces issues by default.
11
12
  * Pass verbose=true to also list recent completions.
12
13
  */
13
- export declare function healthSummary(registryPath: string, verbose: boolean): string;
14
- export declare function categorizeRuns(registryPath: string): HealthResult;
14
+ export declare function healthSummary(stateDir: string, verbose: boolean): string;
15
+ export declare function categorizeRuns(stateDir: string): HealthResult;
16
+ export declare function categorizeRecords(records: RunRecord[], nowMs?: number): HealthResult;
@@ -1,34 +1,54 @@
1
- import { readRegistry } from "../registry/read.js";
2
- import { renderRunLine, renderListHeader } from "./render.js";
3
- const STUCK_THRESHOLD_MS = 10 * 60 * 1000; // 10 minutes
1
+ import { readMergedRegistry } from "../registry/discover.js";
2
+ import { policyForPreset } from "./policy.js";
3
+ import { renderListHeader, renderRunLine } from "./render.js";
4
4
  const RECENT_WINDOW_MS = 24 * 60 * 60 * 1000; // 24 hours
5
5
  /**
6
6
  * Produce a health summary string from the registry.
7
7
  * Exception-focused: only surfaces issues by default.
8
8
  * Pass verbose=true to also list recent completions.
9
9
  */
10
- export function healthSummary(registryPath, verbose) {
11
- const result = categorizeRuns(registryPath);
10
+ export function healthSummary(stateDir, verbose) {
11
+ const result = categorizeRuns(stateDir);
12
12
  return renderHealth(result, verbose);
13
13
  }
14
- export function categorizeRuns(registryPath) {
15
- const now = Date.now();
16
- const all = readRegistry(registryPath);
14
+ export function categorizeRuns(stateDir) {
15
+ const all = readMergedRegistry(stateDir);
16
+ return categorizeRecords(all);
17
+ }
18
+ export function categorizeRecords(records, nowMs = Date.now()) {
17
19
  const active = [];
20
+ const watching = [];
18
21
  const stuck = [];
19
22
  const recentFailed = [];
20
23
  const recentCompleted = [];
21
- for (const r of all) {
24
+ for (const r of records) {
22
25
  if (r.status === "running") {
23
- if (isStuck(r, now)) {
24
- stuck.push(r);
26
+ // If PID is recorded and the process is dead, treat as stopped
27
+ if (r.pid != null && !isProcessAlive(r.pid)) {
28
+ r.status = "stopped";
29
+ r.stop_reason = r.stop_reason || "interrupted";
30
+ // Fall through to non-running classification
25
31
  }
26
32
  else {
27
- active.push(r);
33
+ const elapsed = elapsedMs(r, nowMs);
34
+ if (elapsed === null) {
35
+ active.push(r);
36
+ continue;
37
+ }
38
+ const policy = policyForPreset(r.preset);
39
+ if (elapsed > policy.stuckAfterMs) {
40
+ stuck.push(r);
41
+ }
42
+ else if (elapsed > policy.warningAfterMs) {
43
+ watching.push(r);
44
+ }
45
+ else {
46
+ active.push(r);
47
+ }
48
+ continue;
28
49
  }
29
- continue;
30
50
  }
31
- if (!isRecent(r, now))
51
+ if (!isRecent(r, nowMs))
32
52
  continue;
33
53
  if (r.status === "failed" || r.status === "timed_out") {
34
54
  recentFailed.push(r);
@@ -37,15 +57,24 @@ export function categorizeRuns(registryPath) {
37
57
  recentCompleted.push(r);
38
58
  }
39
59
  }
40
- return { active, stuck, recentFailed, recentCompleted };
60
+ return { active, watching, stuck, recentFailed, recentCompleted };
41
61
  }
42
- function isStuck(r, nowMs) {
62
+ function elapsedMs(r, nowMs) {
43
63
  if (!r.updated_at)
44
- return false;
64
+ return null;
45
65
  const updatedMs = new Date(r.updated_at).getTime();
46
66
  if (Number.isNaN(updatedMs))
67
+ return null;
68
+ return nowMs - updatedMs;
69
+ }
70
+ function isProcessAlive(pid) {
71
+ try {
72
+ process.kill(pid, 0);
73
+ return true;
74
+ }
75
+ catch {
47
76
  return false;
48
- return (nowMs - updatedMs) > STUCK_THRESHOLD_MS;
77
+ }
49
78
  }
50
79
  function isRecent(r, nowMs) {
51
80
  if (!r.updated_at)
@@ -53,20 +82,32 @@ function isRecent(r, nowMs) {
53
82
  const updatedMs = new Date(r.updated_at).getTime();
54
83
  if (Number.isNaN(updatedMs))
55
84
  return false;
56
- return (nowMs - updatedMs) <= RECENT_WINDOW_MS;
85
+ return nowMs - updatedMs <= RECENT_WINDOW_MS;
57
86
  }
58
87
  function renderHealth(h, verbose) {
59
- const hasExceptions = h.stuck.length > 0 || h.recentFailed.length > 0;
88
+ const hasExceptions = h.stuck.length > 0 || h.recentFailed.length > 0 || h.watching.length > 0;
60
89
  if (!hasExceptions && h.active.length === 0) {
61
- return "All clear. 0 active, " + h.recentCompleted.length + " completed in last 24h.";
90
+ return ("All clear. 0 active, " +
91
+ h.recentCompleted.length +
92
+ " completed in last 24h.");
62
93
  }
63
94
  if (!hasExceptions) {
64
- return "All clear. " + h.active.length + " active, " + h.recentCompleted.length + " completed in last 24h.";
95
+ return ("All clear. " +
96
+ h.active.length +
97
+ " active, " +
98
+ h.recentCompleted.length +
99
+ " completed in last 24h.");
65
100
  }
66
101
  const lines = [];
67
- lines.push("Health: " + h.active.length + " active, " +
68
- h.stuck.length + " stuck, " +
69
- h.recentFailed.length + " failed (last 24h)");
102
+ lines.push("Health: " +
103
+ h.active.length +
104
+ " active, " +
105
+ h.watching.length +
106
+ " watching, " +
107
+ h.stuck.length +
108
+ " stuck, " +
109
+ h.recentFailed.length +
110
+ " failed (last 24h)");
70
111
  lines.push("");
71
112
  if (h.stuck.length > 0) {
72
113
  lines.push("STUCK:");
@@ -75,6 +116,13 @@ function renderHealth(h, verbose) {
75
116
  lines.push(renderRunLine(r));
76
117
  lines.push("");
77
118
  }
119
+ if (h.watching.length > 0) {
120
+ lines.push("WATCHING:");
121
+ lines.push(renderListHeader());
122
+ for (const r of h.watching)
123
+ lines.push(renderRunLine(r));
124
+ lines.push("");
125
+ }
78
126
  if (h.recentFailed.length > 0) {
79
127
  lines.push("FAILED:");
80
128
  lines.push(renderListHeader());
@@ -1 +1 @@
1
- {"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/loops/health.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/loops/health.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  /**
2
- * List runs from the registry.
2
+ * List runs from the merged registry (root + chain/worktree children).
3
3
  * When `all` is false, only active (running) runs are shown.
4
4
  * When `all` is true, all runs are shown sorted by updated_at descending.
5
5
  */
6
- export declare function listRuns(registryPath: string, all: boolean): string;
6
+ export declare function listRuns(stateDir: string, all: boolean): string;
@@ -1,14 +1,14 @@
1
- import { readRegistry, activeRuns } from "../registry/read.js";
2
- import { renderRunLine, renderListHeader } from "./render.js";
1
+ import { mergedActiveRuns, readMergedRegistry } from "../registry/discover.js";
2
+ import { renderListHeader, renderRunLine } from "./render.js";
3
3
  /**
4
- * List runs from the registry.
4
+ * List runs from the merged registry (root + chain/worktree children).
5
5
  * When `all` is false, only active (running) runs are shown.
6
6
  * When `all` is true, all runs are shown sorted by updated_at descending.
7
7
  */
8
- export function listRuns(registryPath, all) {
8
+ export function listRuns(stateDir, all) {
9
9
  const runs = all
10
- ? readRegistry(registryPath).sort((a, b) => b.updated_at.localeCompare(a.updated_at))
11
- : activeRuns(registryPath);
10
+ ? readMergedRegistry(stateDir).sort((a, b) => b.updated_at.localeCompare(a.updated_at))
11
+ : mergedActiveRuns(stateDir);
12
12
  if (runs.length === 0) {
13
13
  return all ? "No runs found." : "No active runs.";
14
14
  }
@@ -1 +1 @@
1
- {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/loops/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE9D;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,YAAoB,EAAE,GAAY;IACzD,MAAM,IAAI,GAAG,GAAG;QACd,CAAC,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QACrF,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;IAE7B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,iBAAiB,CAAC;IACpD,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,gBAAgB,EAAE,CAAC,CAAC;IACnC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/loops/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE9D;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,QAAgB,EAAE,GAAY;IACrD,MAAM,IAAI,GAAG,GAAG;QACd,CAAC,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACzC,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,CACzC;QACH,CAAC,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAE/B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,iBAAiB,CAAC;IACpD,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,gBAAgB,EAAE,CAAC,CAAC;IACnC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface SupervisionPolicy {
2
+ label: string;
3
+ warningAfterMs: number;
4
+ stuckAfterMs: number;
5
+ }
6
+ export declare function policyForPreset(preset: string): SupervisionPolicy;
@@ -0,0 +1,41 @@
1
+ const DEFAULT_POLICY = {
2
+ label: "default",
3
+ warningAfterMs: 5 * 60 * 1000,
4
+ stuckAfterMs: 10 * 60 * 1000,
5
+ };
6
+ const POLICIES = {
7
+ autospec: {
8
+ label: "autospec",
9
+ warningAfterMs: 10 * 60 * 1000,
10
+ stuckAfterMs: 20 * 60 * 1000,
11
+ },
12
+ autocode: {
13
+ label: "autocode",
14
+ warningAfterMs: 5 * 60 * 1000,
15
+ stuckAfterMs: 12 * 60 * 1000,
16
+ },
17
+ autosimplify: {
18
+ label: "autosimplify",
19
+ warningAfterMs: 2 * 60 * 1000,
20
+ stuckAfterMs: 6 * 60 * 1000,
21
+ },
22
+ autoqa: {
23
+ label: "autoqa",
24
+ warningAfterMs: 6 * 60 * 1000,
25
+ stuckAfterMs: 15 * 60 * 1000,
26
+ },
27
+ autofix: {
28
+ label: "autofix",
29
+ warningAfterMs: 4 * 60 * 1000,
30
+ stuckAfterMs: 10 * 60 * 1000,
31
+ },
32
+ autopr: {
33
+ label: "autopr",
34
+ warningAfterMs: 3 * 60 * 1000,
35
+ stuckAfterMs: 8 * 60 * 1000,
36
+ },
37
+ };
38
+ export function policyForPreset(preset) {
39
+ return POLICIES[preset] ?? DEFAULT_POLICY;
40
+ }
41
+ //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/loops/policy.ts"],"names":[],"mappings":"AAMA,MAAM,cAAc,GAAsB;IACxC,KAAK,EAAE,SAAS;IAChB,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI;IAC7B,YAAY,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;CAC7B,CAAC;AAEF,MAAM,QAAQ,GAAsC;IAClD,QAAQ,EAAE;QACR,KAAK,EAAE,UAAU;QACjB,cAAc,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;QAC9B,YAAY,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;KAC7B;IACD,QAAQ,EAAE;QACR,KAAK,EAAE,UAAU;QACjB,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI;QAC7B,YAAY,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;KAC7B;IACD,YAAY,EAAE;QACZ,KAAK,EAAE,cAAc;QACrB,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI;QAC7B,YAAY,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI;KAC5B;IACD,MAAM,EAAE;QACN,KAAK,EAAE,QAAQ;QACf,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI;QAC7B,YAAY,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;KAC7B;IACD,OAAO,EAAE;QACP,KAAK,EAAE,SAAS;QAChB,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI;QAC7B,YAAY,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;KAC7B;IACD,MAAM,EAAE;QACN,KAAK,EAAE,QAAQ;QACf,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI;QAC7B,YAAY,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI;KAC5B;CACF,CAAC;AAEF,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,OAAO,QAAQ,CAAC,MAAM,CAAC,IAAI,cAAc,CAAC;AAC5C,CAAC"}
@@ -11,8 +11,9 @@ export declare function renderRunDetail(r: RunRecord): string;
11
11
  /**
12
12
  * Render artifact paths for a run.
13
13
  */
14
- export declare function renderArtifacts(r: RunRecord, registryPath: string): string;
14
+ export declare function renderArtifacts(r: RunRecord, stateDir: string): string;
15
15
  /**
16
16
  * Render a header line for the list view.
17
17
  */
18
18
  export declare function renderListHeader(): string;
19
+ export declare function formatTime(iso: string): string;