toolroll 0.9.92 → 0.9.94

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 (341) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/dist/activity-line.d.ts +7 -4
  3. package/dist/activity-line.js +9 -7
  4. package/dist/agent-fence.d.ts +4 -0
  5. package/dist/agent-fence.js +4 -1
  6. package/dist/approval-authority.d.ts +7 -1
  7. package/dist/approval-authority.js +11 -2
  8. package/dist/approval-password.d.ts +31 -0
  9. package/dist/approval-password.js +26 -0
  10. package/dist/assignment-status.d.ts +1 -1
  11. package/dist/assignment-ui.js +3 -3
  12. package/dist/assignment.js +16 -3
  13. package/dist/boot-identity.d.ts +2 -1
  14. package/dist/boot-identity.js +6 -4
  15. package/dist/bounded-spawn.d.ts +57 -0
  16. package/dist/bounded-spawn.js +220 -0
  17. package/dist/browser/terminal.js +42 -42
  18. package/dist/browser/workspace.css +2 -2
  19. package/dist/browser/workspace.js +26 -26
  20. package/dist/browser-crew.js +2 -2
  21. package/dist/browser-shell.d.ts +1 -1
  22. package/dist/browser-shell.js +2 -2
  23. package/dist/browser-workspace.d.ts +48 -7
  24. package/dist/browser-workspace.js +3 -3
  25. package/dist/builder-restart.d.ts +21 -0
  26. package/dist/builder-restart.js +50 -0
  27. package/dist/builder.d.ts +4 -0
  28. package/dist/builder.js +73 -25
  29. package/dist/chat-acceptance.js +1 -1
  30. package/dist/chat-actions.d.ts +12 -2
  31. package/dist/chat-actions.js +25 -2
  32. package/dist/chat-channel.js +11 -0
  33. package/dist/chat-decide.d.ts +7 -2
  34. package/dist/chat-decide.js +37 -9
  35. package/dist/chat-quiet.js +3 -3
  36. package/dist/chat-voice.d.ts +1 -1
  37. package/dist/chat-voice.js +2 -2
  38. package/dist/check-facts.d.ts +126 -0
  39. package/dist/check-facts.js +318 -0
  40. package/dist/check-failure.d.ts +22 -3
  41. package/dist/check-failure.js +57 -13
  42. package/dist/check-levels-ui.d.ts +4 -0
  43. package/dist/check-levels-ui.js +10 -1
  44. package/dist/check-load.d.ts +85 -0
  45. package/dist/check-load.js +147 -0
  46. package/dist/check-only-standing.d.ts +36 -0
  47. package/dist/check-only-standing.js +39 -0
  48. package/dist/check-only.d.ts +15 -0
  49. package/dist/check-only.js +99 -0
  50. package/dist/check-report.d.ts +7 -0
  51. package/dist/check-report.js +4 -3
  52. package/dist/check-stamp.d.ts +46 -0
  53. package/dist/check-stamp.js +93 -0
  54. package/dist/checkout-cleanup.d.ts +36 -5
  55. package/dist/checkout-cleanup.js +166 -14
  56. package/dist/cli-help.d.ts +4 -1
  57. package/dist/cli-help.js +47 -30
  58. package/dist/cli.js +16 -1
  59. package/dist/code-extract.d.ts +44 -0
  60. package/dist/code-extract.js +88 -0
  61. package/dist/code-map-acts.d.ts +24 -0
  62. package/dist/code-map-acts.js +53 -0
  63. package/dist/code-map-admission.d.ts +52 -0
  64. package/dist/code-map-admission.js +295 -0
  65. package/dist/code-map-build.d.ts +63 -0
  66. package/dist/code-map-build.js +415 -0
  67. package/dist/code-map-cli.d.ts +153 -0
  68. package/dist/code-map-cli.js +103 -0
  69. package/dist/code-map-main.d.ts +1 -0
  70. package/dist/code-map-main.js +48 -0
  71. package/dist/code-map-read.d.ts +106 -0
  72. package/dist/code-map-read.js +171 -0
  73. package/dist/code-map-report.d.ts +37 -0
  74. package/dist/code-map-report.js +95 -0
  75. package/dist/code-map-shape.d.ts +172 -0
  76. package/dist/code-map-shape.js +327 -0
  77. package/dist/code-map-store.d.ts +136 -0
  78. package/dist/code-map-store.js +233 -0
  79. package/dist/coding-provider.d.ts +2 -0
  80. package/dist/coding-provider.js +3 -2
  81. package/dist/coding-update.js +3 -2
  82. package/dist/coding-workspace.js +4 -4
  83. package/dist/console-chrome.js +2 -2
  84. package/dist/containment.d.ts +5 -0
  85. package/dist/containment.js +14 -1
  86. package/dist/contracts/chat-actions.d.ts +9 -0
  87. package/dist/contracts/chat-actions.js +2 -0
  88. package/dist/contracts/cli.d.ts +52 -0
  89. package/dist/contracts/cli.js +4 -0
  90. package/dist/contracts/console-api.d.ts +12 -5
  91. package/dist/contracts/console-api.js +12 -5
  92. package/dist/contracts/gateway-tools.d.ts +17 -0
  93. package/dist/contracts/gateway-tools.js +3 -1
  94. package/dist/contracts/lead-tools.d.ts +61 -0
  95. package/dist/contracts/lead-tools.js +10 -1
  96. package/dist/contracts/project-knowledge.d.ts +38 -5
  97. package/dist/contracts/project-knowledge.js +11 -5
  98. package/dist/contracts/project-memory.d.ts +3 -1
  99. package/dist/contracts/project-memory.js +3 -2
  100. package/dist/contracts/release-check.d.ts +25 -1
  101. package/dist/contracts/release-check.js +19 -0
  102. package/dist/contracts/storage.d.ts +14 -0
  103. package/dist/contracts/storage.js +3 -1
  104. package/dist/contracts/store-json.d.ts +2 -0
  105. package/dist/contracts/youiyoux-request.d.ts +1 -1
  106. package/dist/contracts/youiyoux-request.js +1 -1
  107. package/dist/desktop-access.js +6 -2
  108. package/dist/desktop-update.d.ts +2 -2
  109. package/dist/desktop-update.js +13 -9
  110. package/dist/dispatch.js +18 -15
  111. package/dist/dispose.js +8 -2
  112. package/dist/easy-start.js +2 -3
  113. package/dist/eval-hooks.d.ts +55 -0
  114. package/dist/eval-hooks.js +227 -4
  115. package/dist/evals.js +2 -1
  116. package/dist/fast-start.d.ts +136 -0
  117. package/dist/fast-start.js +431 -0
  118. package/dist/fast-terms.d.ts +9 -0
  119. package/dist/fast-terms.js +23 -0
  120. package/dist/fenced-check-coverage.d.ts +62 -0
  121. package/dist/fenced-check-coverage.js +54 -0
  122. package/dist/first-run.js +1 -1
  123. package/dist/flaky-ci.d.ts +31 -0
  124. package/dist/flaky-ci.js +149 -0
  125. package/dist/flaky-cli.d.ts +60 -0
  126. package/dist/flaky-cli.js +60 -0
  127. package/dist/flaky.d.ts +83 -0
  128. package/dist/flaky.js +264 -0
  129. package/dist/flow-card-task.js +3 -0
  130. package/dist/flow-triggers.d.ts +1 -1
  131. package/dist/flow-triggers.js +1 -1
  132. package/dist/github-import.d.ts +62 -0
  133. package/dist/github-import.js +146 -0
  134. package/dist/guides.js +15 -10
  135. package/dist/invoke.d.ts +5 -1
  136. package/dist/invoke.js +49 -14
  137. package/dist/job-object-helper.ps1 +10 -3
  138. package/dist/keymap.d.ts +41 -0
  139. package/dist/keymap.js +51 -0
  140. package/dist/knowledge-cli.js +1 -1
  141. package/dist/knowledge-ui.d.ts +21 -4
  142. package/dist/knowledge-ui.js +75 -7
  143. package/dist/laptop-background.d.ts +16 -0
  144. package/dist/laptop-background.js +108 -2
  145. package/dist/lead-context.js +1 -1
  146. package/dist/lead-contract.d.ts +1 -1
  147. package/dist/lead-contract.js +2 -2
  148. package/dist/lead-progress.js +3 -0
  149. package/dist/lead-status.d.ts +2 -0
  150. package/dist/lead-status.js +6 -2
  151. package/dist/lead-tools.js +51 -2
  152. package/dist/lead.js +1 -1
  153. package/dist/lesson-notes.d.ts +81 -0
  154. package/dist/lesson-notes.js +336 -0
  155. package/dist/limits-ui.js +1 -1
  156. package/dist/local-owner.d.ts +1 -1
  157. package/dist/local-owner.js +11 -0
  158. package/dist/machine-check.d.ts +16 -0
  159. package/dist/machine-check.js +26 -0
  160. package/dist/machine-identity.d.ts +75 -0
  161. package/dist/machine-identity.js +170 -0
  162. package/dist/mcp-core.js +11 -1
  163. package/dist/memory-cli.d.ts +300 -1
  164. package/dist/memory-cli.js +62 -9
  165. package/dist/memory-pass.d.ts +16 -0
  166. package/dist/memory-pass.js +67 -3
  167. package/dist/memory-tidy.d.ts +181 -0
  168. package/dist/memory-tidy.js +523 -0
  169. package/dist/memory-use.d.ts +35 -0
  170. package/dist/memory-use.js +109 -0
  171. package/dist/merge-checklist.d.ts +55 -0
  172. package/dist/merge-checklist.js +182 -0
  173. package/dist/needs-you.d.ts +32 -13
  174. package/dist/needs-you.js +108 -49
  175. package/dist/nightly-github.d.ts +2 -0
  176. package/dist/nightly-github.js +4 -4
  177. package/dist/operate-remote-arguments.js +6 -1
  178. package/dist/operate-remote.js +3 -1
  179. package/dist/operate.d.ts +6 -1
  180. package/dist/operate.js +540 -70
  181. package/dist/phase-routing.js +2 -2
  182. package/dist/plain-schema.d.ts +23 -0
  183. package/dist/plain-schema.js +94 -0
  184. package/dist/plain-words.d.ts +20 -0
  185. package/dist/plain-words.js +66 -0
  186. package/dist/planner.js +2 -1
  187. package/dist/process-liveness.d.ts +2 -0
  188. package/dist/process-liveness.js +61 -17
  189. package/dist/project-delete-ui.d.ts +7 -2
  190. package/dist/project-delete-ui.js +12 -1
  191. package/dist/project-delete.js +13 -2
  192. package/dist/project-knowledge.d.ts +18 -11
  193. package/dist/project-knowledge.js +39 -9
  194. package/dist/project-learning.d.ts +2 -1
  195. package/dist/project-learning.js +15 -45
  196. package/dist/project-memory.d.ts +5 -0
  197. package/dist/project-memory.js +22 -2
  198. package/dist/proof.js +30 -5
  199. package/dist/provider-auth.js +1 -1
  200. package/dist/publish.js +9 -1
  201. package/dist/pull-request-flow.js +5 -0
  202. package/dist/push.d.ts +26 -3
  203. package/dist/push.js +55 -15
  204. package/dist/release-adapters.d.ts +9 -0
  205. package/dist/release-adapters.js +87 -1
  206. package/dist/release-approval.d.ts +191 -0
  207. package/dist/release-approval.js +382 -0
  208. package/dist/release-auto.js +26 -17
  209. package/dist/release-card.d.ts +74 -6
  210. package/dist/release-card.js +179 -23
  211. package/dist/release-carry.d.ts +7 -2
  212. package/dist/release-carry.js +39 -9
  213. package/dist/release-cli.d.ts +4 -0
  214. package/dist/release-cli.js +38 -23
  215. package/dist/release-coverage.js +1 -1
  216. package/dist/release-next.d.ts +48 -0
  217. package/dist/release-next.js +161 -0
  218. package/dist/release.d.ts +50 -1
  219. package/dist/release.js +118 -11
  220. package/dist/remote-destination.d.ts +36 -0
  221. package/dist/remote-destination.js +217 -0
  222. package/dist/remote-main.d.ts +48 -0
  223. package/dist/remote-main.js +84 -5
  224. package/dist/repository-context.d.ts +3 -2
  225. package/dist/repository-context.js +112 -70
  226. package/dist/restart-certification.d.ts +1 -0
  227. package/dist/restart-certification.js +8 -6
  228. package/dist/result-acts.d.ts +29 -21
  229. package/dist/result-acts.js +36 -25
  230. package/dist/result-follow-ups.d.ts +2 -2
  231. package/dist/result-follow-ups.js +18 -4
  232. package/dist/result-review.d.ts +1 -1
  233. package/dist/route-change-check.d.ts +4 -0
  234. package/dist/route-change-check.js +13 -0
  235. package/dist/route-change.d.ts +22 -0
  236. package/dist/route-change.js +89 -0
  237. package/dist/route-hooks.js +3 -2
  238. package/dist/route-results.d.ts +6 -1
  239. package/dist/route-results.js +14 -5
  240. package/dist/run-closeout.d.ts +1 -1
  241. package/dist/run-closeout.js +7 -5
  242. package/dist/runner-process.js +3 -2
  243. package/dist/runner.js +2 -1
  244. package/dist/scope.d.ts +6 -1
  245. package/dist/scope.js +22 -9
  246. package/dist/serve.d.ts +1 -1
  247. package/dist/serve.js +24 -18
  248. package/dist/server/chat.js +14 -12
  249. package/dist/server/chrome.d.ts +1 -1
  250. package/dist/server/chrome.js +26 -35
  251. package/dist/server/console.css +23 -0
  252. package/dist/server/guards.js +4 -0
  253. package/dist/server/home.d.ts +6 -0
  254. package/dist/server/home.js +21 -13
  255. package/dist/server/http.js +1 -1
  256. package/dist/server/kit.js +1 -1
  257. package/dist/server/merge-ready-view.d.ts +10 -0
  258. package/dist/server/merge-ready-view.js +30 -0
  259. package/dist/server/pages-assets.d.ts +1 -0
  260. package/dist/server/pages-assets.js +8 -5
  261. package/dist/server/pages.js +103 -82
  262. package/dist/server/render-chat.js +2 -2
  263. package/dist/server/render-code-map.d.ts +30 -0
  264. package/dist/server/render-code-map.js +137 -0
  265. package/dist/server/render-flaky.d.ts +20 -0
  266. package/dist/server/render-flaky.js +59 -0
  267. package/dist/server/render-history.js +1 -1
  268. package/dist/server/render-new-task.d.ts +26 -1
  269. package/dist/server/render-new-task.js +30 -5
  270. package/dist/server/render-pages.d.ts +1 -175
  271. package/dist/server/render-pages.js +38 -313
  272. package/dist/server/render-projects.d.ts +2 -1
  273. package/dist/server/render-projects.js +9 -7
  274. package/dist/server/render-release.d.ts +19 -0
  275. package/dist/server/render-release.js +84 -0
  276. package/dist/server/render-results.d.ts +2 -2
  277. package/dist/server/render-results.js +71 -73
  278. package/dist/server/render-tasks.d.ts +13 -2
  279. package/dist/server/render-tasks.js +156 -139
  280. package/dist/server/retired-routes.d.ts +17 -0
  281. package/dist/server/retired-routes.js +53 -0
  282. package/dist/server/route-table.d.ts +4 -1
  283. package/dist/server/route-table.js +52 -13
  284. package/dist/server/settings.js +129 -22
  285. package/dist/server/task-views.js +61 -26
  286. package/dist/server/tasks.d.ts +17 -6
  287. package/dist/server/tasks.js +273 -338
  288. package/dist/server/welcome.js +1 -1
  289. package/dist/settings-groups-ui.js +1 -1
  290. package/dist/setup-guide.d.ts +2 -2
  291. package/dist/stop-proof.d.ts +67 -0
  292. package/dist/stop-proof.js +295 -0
  293. package/dist/storage-sweep-process.js +1 -1
  294. package/dist/storage-sweep.d.ts +5 -3
  295. package/dist/storage-sweep.js +30 -9
  296. package/dist/storage-ui.js +28 -17
  297. package/dist/storage.d.ts +27 -2
  298. package/dist/storage.js +39 -2
  299. package/dist/store.d.ts +148 -34
  300. package/dist/store.js +626 -177
  301. package/dist/surface.js +46 -5
  302. package/dist/sweep-quarantine.d.ts +1 -0
  303. package/dist/sweep-quarantine.js +6 -4
  304. package/dist/tamper-scan.d.ts +4 -0
  305. package/dist/tamper-scan.js +90 -0
  306. package/dist/task-aliases.d.ts +5 -0
  307. package/dist/task-aliases.js +9 -0
  308. package/dist/task-control.js +4 -1
  309. package/dist/task-outcome-cli.d.ts +2 -0
  310. package/dist/task-outcome-cli.js +36 -17
  311. package/dist/task-sizing.d.ts +5 -0
  312. package/dist/task-sizing.js +2 -0
  313. package/dist/task-source.d.ts +7 -0
  314. package/dist/task-source.js +14 -0
  315. package/dist/task-status.d.ts +9 -0
  316. package/dist/task-status.js +40 -49
  317. package/dist/teardown-git.d.ts +16 -0
  318. package/dist/teardown-git.js +63 -5
  319. package/dist/telegram-progress.js +5 -3
  320. package/dist/telegram-status.js +6 -4
  321. package/dist/test-infra.d.ts +8 -0
  322. package/dist/test-infra.js +18 -0
  323. package/dist/tidy.js +1 -1
  324. package/dist/toolroll-update-ui.js +2 -2
  325. package/dist/toolroll-update.js +18 -5
  326. package/dist/tui-contract.d.ts +24 -0
  327. package/dist/tui-source.js +67 -8
  328. package/dist/tui.js +51 -51
  329. package/dist/vanished-retry.d.ts +30 -0
  330. package/dist/vanished-retry.js +174 -0
  331. package/dist/work-index.d.ts +2 -0
  332. package/dist/work-index.js +82 -70
  333. package/dist/work-summary.d.ts +2 -2
  334. package/dist/work-summary.js +2 -0
  335. package/dist/workspace-ui.d.ts +4 -2
  336. package/dist/workspace-ui.js +28 -22
  337. package/dist/worktree.d.ts +12 -3
  338. package/dist/worktree.js +68 -13
  339. package/package.json +1 -1
  340. package/dist/server/render-next.d.ts +0 -63
  341. package/dist/server/render-next.js +0 -109
package/dist/needs-you.js CHANGED
@@ -22,9 +22,10 @@ export const NEEDS = {
22
22
  answer: { sentence: () => "Answer the question so the work can continue.", action: { code: "answer-decision", label: "Answer the question" }, useReason: always },
23
23
  questions: { sentence: () => "Too many questions are open. Answer one so this task can start.", action: { code: "inspect-decisions", label: "Answer questions" } },
24
24
  "sign-in": { sentence: context => `${context.provider ?? "Your agent"} needs you to sign in again. The task starts on its own after.`, action: { code: "sign-in", label: "Sign in again" }, useReason: reason => /sign in|API key/i.test(reason) },
25
- "confirm-stopped": { sentence: context => `Toolroll can't confirm ${build(context)} stopped. Nothing from it is running.`, action: { code: "confirm-stopped", label: "Confirm it stopped" } },
26
- // Toolroll can't look at all: never "nothing is running"; the person checks, says so, then confirms.
27
- "check-stopped": { sentence: context => `Toolroll can't check whether ${build(context)} stopped. Make sure nothing from it is running, then confirm.`, action: { code: "confirm-stopped", label: "Confirm it stopped" } },
25
+ // Toolroll proves a build stopped itself (stop-proof.ts); nobody is asked to vouch for it. Only when this computer
26
+ // can't look, or something Toolroll didn't start is using the build's folder, is the work held: the person can close
27
+ // what's theirs and have it look again, nothing more.
28
+ "stop-unproven": { sentence: context => `Toolroll can't prove ${build(context)} stopped from this computer, so the work is held. Close anything of yours that is using its folder, then check again.`, action: { code: "recheck-stopped", label: "Check again" } },
28
29
  hold: { sentence: () => "A hold is keeping this task from starting. Review it to release it.", action: { code: "inspect-hold", label: "Review hold" } },
29
30
  "choose-project": { sentence: () => "Choose a project so a builder can start.", action: { code: "place-task", label: "Choose a project" } },
30
31
  "define-task": { sentence: () => "Say what the task should do so it can be planned.", action: { code: "write-scope", label: "Define the task" } },
@@ -40,14 +41,18 @@ export const NEEDS = {
40
41
  } },
41
42
  "add-requirement": { sentence: () => "This project is missing something the task needs. Add it so a builder can start.", action: { code: "repair-capability", label: "Add the requirement" } },
42
43
  "connect-builder": { sentence: () => "No builder works on this project yet. Connect one so the task can start.", action: { code: "start-worker", label: "Connect a builder" } },
43
- "start-builder": { sentence: () => "The builder for this project is offline. Start it and the task begins on its own.", action: { code: "start-worker", label: "Start the builder" } },
44
- vanished: { sentence: context => `${Build(context)} stopped without finishing. Check it, then retry.`, action: { code: "reconcile-run", label: "Check the build" } },
45
- "review-result": { sentence: () => "Check the result, then accept it or ask for changes.", action: { code: "open-result", label: "Open result" } },
44
+ "start-builder": { sentence: () => "The builder is offline. Start the builder.", action: { code: "start-worker", label: "Start the builder" } },
45
+ // The same act as before (it opens the build, where Retry is): only the words are plainer.
46
+ vanished: { sentence: context => `${Build(context)} stopped unexpectedly. Retry it.`, action: { code: "reconcile-run", label: "Open the build" } },
47
+ "review-result": { sentence: () => "Check the result, then accept it or send it back.", action: { code: "open-result", label: "Open result" } },
46
48
  // Accepting it would not help: it was built to terms that are no longer the plan.
47
- rebuild: { sentence: context => `${Build(context)} was made to an earlier plan. Build it again to the current plan.`, action: { code: "retry-task", label: "Build again" } },
49
+ rebuild: { sentence: context => `${Build(context)} was made to an earlier plan. Retry it on the current plan.`, action: { code: "retry-task", label: "Retry" } },
48
50
  // The plan was rewritten after the build and not yet approved: the yes comes first, then Build again.
49
- replan: { sentence: context => `The plan changed after ${build(context)}. Approve the new plan, then build it again.`, action: { code: "approve-scope", label: "Approve plan" } },
50
- "earlier-version": { sentence: () => "An earlier version of this task still needs you. Finish it first.", action: { code: "inspect-task", label: "Open earlier version" } },
51
+ replan: { sentence: context => `The plan changed after ${build(context)}. Approve the new plan, then retry it.`, action: { code: "approve-scope", label: "Approve plan" } },
52
+ "earlier-version": { sentence: context => context.task == null ? "An earlier version of this task still needs you. Finish it first." : `An earlier version, ${context.task}, still needs you. Finish it first.`,
53
+ action: { code: "inspect-task", label: "Open earlier version" } },
54
+ // An actionable need, never a quiet Waiting: a person opens it to retry or archive it.
55
+ history: { sentence: () => "Toolroll can't read this task's history. Open it to retry or archive it.", action: { code: "inspect-task", label: "Open the task" } },
51
56
  other: { sentence: () => "Open the task to see what it needs from you.", action: { code: "inspect-task", label: "Open the task" }, useReason: always },
52
57
  };
53
58
  export const ASKS = ["decide", "review", "unblock"];
@@ -70,7 +75,7 @@ export function askChipOf(read) {
70
75
  return "Question";
71
76
  if (read.need === "hold")
72
77
  return "On hold";
73
- if (read.need === "vanished" || read.need === "confirm-stopped" || read.need === "check-stopped")
78
+ if (read.need === "vanished" || read.need === "stop-unproven")
74
79
  return "Stopped";
75
80
  if (read.need === "sign-in")
76
81
  return "Sign in";
@@ -100,21 +105,28 @@ export const NEED_ASK = {
100
105
  approval: "decide", card: "decide", answer: "decide", questions: "decide", "choose-project": "decide", "define-task": "decide",
101
106
  "fix-request": "decide", "choose-agent": "decide",
102
107
  "review-result": "review", rebuild: "review", replan: "decide",
103
- "sign-in": "unblock", "confirm-stopped": "unblock", "check-stopped": "unblock", hold: "unblock", "fix-dependency": "unblock",
104
- "add-requirement": "unblock", "connect-builder": "unblock", "start-builder": "unblock", vanished: "unblock", "earlier-version": "unblock", other: "unblock",
108
+ "sign-in": "unblock", "stop-unproven": "unblock", hold: "unblock", "fix-dependency": "unblock",
109
+ "add-requirement": "unblock", "connect-builder": "unblock", "start-builder": "unblock", vanished: "unblock", "earlier-version": "unblock", history: "unblock", other: "unblock",
105
110
  };
106
111
  export const WAITS = {
107
112
  "build-finishing": () => "Finishing up; this clears on its own.",
108
- "build-stopping": context => `Waiting for ${build(context)} to stop. Nothing is needed from you.`,
113
+ "build-checking": context => `Making sure ${build(context)} stopped. This clears on its own.`,
114
+ "build-stopping": context => `Waiting: Toolroll is stopping ${build(context)}.`,
109
115
  "other-computer": context => `Waiting for the computer that ran ${build(context)} to confirm it stopped.`,
110
116
  "card-reply": () => "Waiting for a reply.",
111
117
  "card-time": () => "Waiting before moving on.",
112
118
  "card-ci": () => "Waiting for the pull request's checks.",
119
+ "plan-next": () => "Waiting to plan.",
120
+ "research-next": () => "Waiting to research.",
121
+ "builders-busy": () => "Waiting its turn: builders are busy.",
122
+ "retry-later": context => `Waiting: Toolroll retries ${build(context)} ${context.retry ?? "soon"}.`,
123
+ "app-update": () => "Waiting: Toolroll is updating. New work starts after it.",
124
+ "other-task": context => context.task == null ? "Waiting for another task to finish first." : `Waiting for ${context.task} to finish first.`,
113
125
  };
114
- /** Words that name the machine's internals; no Needs you or Waiting sentence carries them. */
115
- export const BANNED_WORDS = ["witness", "unproven", "quiescence", "quiescent", "digest", "scope digest"];
116
- const BANNED = new RegExp(`\\b(?:${BANNED_WORDS.join("|")})\\b`, "i");
117
- export const hasInternalWords = (text) => BANNED.test(text);
126
+ /** Words that name the machine's internals (plain-words.ts, the one table); no Needs you or Waiting sentence carries
127
+ * them, and a recorded reason that does is replaced by the need's own words. */
128
+ export { BANNED_WORDS, PLAIN_WORDS, bannedWordsIn, hasInternalWords } from "./plain-words.js";
129
+ import { hasInternalWords } from "./plain-words.js";
118
130
  /** The sentence for a need: its recorded reason when the need keeps one and
119
131
  * it reads plainly, otherwise the need's own words. */
120
132
  export function needSentence(key, reason, context = {}) {
@@ -124,35 +136,82 @@ export function needSentence(key, reason, context = {}) {
124
136
  return need.sentence(context);
125
137
  return need.withReason === undefined ? plain : need.withReason(plain);
126
138
  }
139
+ /** Waits whose words need a fact (when it retries, which task it waits on): without it, a plain recorded reason that
140
+ * already says it is kept. */
141
+ const WAITS_WITH_FACTS = {
142
+ "retry-later": context => context.retry != null, "other-task": context => context.task != null,
143
+ };
127
144
  export function waitSentence(key, reason, context = {}) {
128
- if (key !== undefined)
129
- return WAITS[key](context);
130
145
  const plain = reason?.trim() || null;
131
- return plain !== null && !hasInternalWords(plain) ? plain : "Waiting for the work to continue on its own.";
146
+ const known = plain !== null && !hasInternalWords(plain) ? plain : null;
147
+ if (key !== undefined)
148
+ return WAITS_WITH_FACTS[key]?.(context) === false && known !== null ? known : WAITS[key](context);
149
+ return known ?? "Waiting for the work to continue on its own.";
132
150
  }
133
- /** A finished run Toolroll can't prove stopped (store.stopQuiescenceFact):
134
- * a person can confirm it only when nothing of it may still be running.
135
- * `unknown`: Toolroll can't check, so the person confirms they checked. */
151
+ /** A finished run Toolroll can't yet prove stopped (store.stopQuiescenceFact). Nobody is asked to confirm it:
152
+ * `unprovable` is Toolroll's own check still to run (stop-proof.ts), which settles by itself; `unknown` is that this
153
+ * computer can't look, or something Toolroll didn't start is in the build's folder — held, with nothing to vouch for. */
136
154
  export function processNeedOf(fact) {
137
155
  if (fact === null)
138
156
  return null;
139
157
  if (fact.kind === "settling")
140
158
  return { wait: "build-finishing", build: fact.run };
141
159
  if (fact.kind === "unprovable")
142
- return { need: "confirm-stopped", build: fact.run };
160
+ return { wait: "build-checking", build: fact.run };
143
161
  if (fact.kind === "unknown")
144
- return { need: "check-stopped", build: fact.run };
162
+ return { need: "stop-unproven", build: fact.run };
145
163
  return { wait: fact.kind === "elsewhere" ? "other-computer" : "build-stopping", build: fact.run };
146
164
  }
147
- /** Dispatch and work-index codes that wait on a person, as their need. */
148
- export const CODE_NEED = {
149
- "signed-out": "sign-in", "needs-approval": "approval", "waiting-decision": "answer", "decision-queue": "answer",
150
- "needs-project": "choose-project", "needs-scope": "define-task", "planner-source": "fix-request", "needs-agent-profile": "choose-agent",
151
- "terminal-dependency": "fix-dependency", "missing-requirement": "add-requirement", "no-worker-registered": "connect-builder",
152
- "no-worker-online": "start-builder", "vanished-run": "vanished", "needs-verification": "review-result", "proof-refuted": "review-result",
153
- "no-build-record": "review-result", "verification-needed": "review-result", "evidence-mismatch": "review-result",
154
- "record-incomplete": "review-result", "evidence-damaged": "review-result",
165
+ export const CODE_READING = {
166
+ // Plain states: nothing is asked and nothing is waited on by name.
167
+ queued: { stage: "queued" }, ready: { stage: "queued" }, "provider-quota": { stage: "queued" },
168
+ running: { stage: "building" }, reviewing: { stage: "reviewing" }, "review-pending": { stage: "building" }, "checks-running": { stage: "checking" },
169
+ "ready-to-check": { stage: "finished", act: "open-result" }, "ready-to-review": { stage: "finished" }, "report-ready": { stage: "finished" }, "no-change": { stage: "finished" },
170
+ "pr-opened": { stage: "finished" }, "merge-observed": { stage: "finished" }, "pr-closed": { stage: "finished" }, "agent-attested": { stage: "finished" }, "accepted-exception": { stage: "finished" },
171
+ complete: { stage: "complete", act: "open-result" }, cancelled: { stage: "stopped", act: "inspect-task" }, paused: { stage: "stopped" },
172
+ stopped: { stage: "stopped", act: "resume-run" },
173
+ failed: { stage: "failed", act: "retry-task" }, "checks-failed": { stage: "failed" },
174
+ // The same failure again and again: a need over Retry, its own act, said plainly.
175
+ "waiting-incident": { stage: "failed", act: "retry-task" },
176
+ // Waits: Toolroll or another task moves these on; no person is asked.
177
+ stopping: { stage: "waiting", wait: "build-stopping" },
178
+ "build-stopping": { stage: "waiting", wait: "build-stopping" }, "other-computer": { stage: "waiting", wait: "other-computer" },
179
+ "planning-ready": { stage: "waiting", wait: "plan-next" }, "scouting-ready": { stage: "waiting", wait: "research-next" },
180
+ "worker-at-capacity": { stage: "waiting", wait: "builders-busy" }, "retry-scheduled": { stage: "waiting", wait: "retry-later" },
181
+ updating: { stage: "waiting", wait: "app-update" }, "waiting-dependency": { stage: "waiting", wait: "other-task" },
182
+ // Needs, each over the act it has always had.
183
+ "history-problem": { stage: "needs-you", need: "history", act: "inspect-task" },
184
+ "earlier-active": { stage: "needs-you", need: "earlier-version", act: "inspect-task" },
185
+ "waiting-decision": { stage: "needs-you", need: "answer", act: "answer-decision" },
186
+ "decision-queue": { stage: "needs-you", need: "questions", act: "inspect-decisions" },
187
+ // A saved result that can't simply be accepted yet: its own reason (resultHoldUpSentence) is the sentence.
188
+ "result-needs-attention": { stage: "needs-you", need: "other", act: "inspect-run" },
189
+ "process-needs-attention": { stage: "needs-you", need: "stop-unproven", act: "inspect-run" },
190
+ "vanished-run": { stage: "needs-you", need: "vanished", act: "reconcile-run" },
191
+ held: { stage: "needs-you", need: "hold", act: "inspect-hold" },
192
+ "terminal-dependency": { stage: "needs-you", need: "fix-dependency", act: "repair-dependency" },
193
+ "needs-project": { stage: "needs-you", need: "choose-project", act: "place-task" },
194
+ "needs-scope": { stage: "needs-you", need: "define-task", act: "write-scope" },
195
+ "invalid-scope": { stage: "needs-you", need: "define-task", act: "write-scope" },
196
+ "planner-source": { stage: "needs-you", need: "fix-request", act: "write-scope" },
197
+ "needs-agent-profile": { stage: "needs-you", need: "choose-agent", act: "select-agent" },
198
+ "needs-approval": { stage: "needs-you", need: "approval", act: "approve-scope" },
199
+ "missing-requirement": { stage: "needs-you", need: "add-requirement", act: "repair-capability" },
200
+ "no-worker-registered": { stage: "needs-you", need: "connect-builder", act: "start-worker" },
201
+ "no-worker-online": { stage: "needs-you", need: "start-builder", act: "start-worker" },
202
+ "signed-out": { stage: "needs-you", need: "sign-in", act: "sign-in" },
203
+ "needs-verification": { stage: "needs-you", need: "review-result" }, "proof-refuted": { stage: "needs-you", need: "review-result" },
204
+ "no-build-record": { stage: "needs-you", need: "review-result" }, "verification-needed": { stage: "needs-you", need: "review-result" },
205
+ "evidence-mismatch": { stage: "needs-you", need: "review-result" }, "record-incomplete": { stage: "needs-you", need: "review-result" },
206
+ "evidence-damaged": { stage: "needs-you", need: "review-result" },
155
207
  };
208
+ /** A code that waits on Toolroll or another task: no person is asked. */
209
+ export const isWaitCode = (code) => CODE_READING[code]?.stage === "waiting";
210
+ /** Notification kinds that need nothing from a person: they stay in the activity log and never ping a phone. */
211
+ export const ACTIVITY_ONLY_KINDS = new Set(["check-progress"]);
212
+ /** Dispatch and work-index codes that wait on a person, as their need (read from CODE_READING). */
213
+ export const CODE_NEED = Object.fromEntries(Object.entries(CODE_READING)
214
+ .flatMap(([code, reading]) => reading.need === undefined ? [] : [[code, reading.need]]));
156
215
  /** A stopped run's recorded reason code, in words (the run record, the thread, a failed task's status). */
157
216
  export const RUN_REASON_WORDS = {
158
217
  agent: "the agent failed",
@@ -165,28 +224,28 @@ export const RUN_REASON_WORDS = {
165
224
  git: "a git step failed",
166
225
  "malformed-decision": "the agent's question was malformed",
167
226
  "malformed-plan": "the plan was malformed",
168
- fenced: "another worker took the task over",
169
- unapproved: "the scope was not approved",
170
- "scope-changed": "the scope changed after approval",
227
+ fenced: "another builder took the task over",
228
+ unapproved: "the plan was not approved",
229
+ "scope-changed": "the plan changed after approval",
171
230
  capability: "a requirement was missing",
172
231
  setup: "the workspace preparation step failed",
173
232
  "provider-init": "the agent could not start",
174
233
  "commit-failure": "the commit failed",
175
234
  "protected-branch": "refused to touch a protected branch",
176
235
  "wrong-branch": "the checkout was on the wrong branch",
177
- "not-leased": "the lease was not valid",
178
- "no-claim": "the lease was not valid",
179
- "not-yours": "the lease was not valid",
180
- "no-run-record": "the run record was missing",
181
- "missing-mailbox": "the resume mailbox could not be read",
182
- "unreadable-mailbox": "the resume mailbox could not be read",
236
+ "not-leased": "the builder lost its hold on the task",
237
+ "no-claim": "the builder lost its hold on the task",
238
+ "not-yours": "the builder lost its hold on the task",
239
+ "no-run-record": "the build's record was missing",
240
+ "missing-mailbox": "the saved notes to resume from could not be read",
241
+ "unreadable-mailbox": "the saved notes to resume from could not be read",
183
242
  "revision-brief": "the revision brief could not be read",
184
243
  "repaired-park": "resumed from a parked question",
185
- stopped: "stopped by the operator",
186
- acceptance: "the result didn't meet its signed requirements",
187
- evidence: "its evidence could not be saved",
244
+ stopped: "stopped by a person",
245
+ acceptance: "the result didn't meet its approved requirements",
246
+ evidence: "its saved files could not be kept",
188
247
  interrupted: "the attempt was interrupted",
189
- orphaned: "the attempt lost its worker",
248
+ orphaned: "the attempt lost its builder",
190
249
  "retryable-infra": "a temporary problem on the machine stopped it",
191
250
  unknown: "the attempt stopped unexpectedly",
192
251
  "spawn-failed": "the agent process could not start",
@@ -194,12 +253,12 @@ export const RUN_REASON_WORDS = {
194
253
  "auth-expired": "the agent's sign-in expired",
195
254
  "budget-unenforceable": "its spending limit could not be enforced",
196
255
  "stale-source": "the request changed while the plan was being made",
197
- "stale-approval": "the approval no longer matched the scope",
256
+ "stale-approval": "the approval no longer matched the plan",
198
257
  "source-invalid": "the plan's source could not be recorded",
199
258
  "external-closed": "the linked issue was closed while it was being built",
200
259
  "repair-admission": "the repair could not start",
201
260
  "reviewer-error": "the review failed",
202
- "malformed-report": "the scout's report was malformed",
261
+ "malformed-report": "the research report was malformed",
203
262
  "attempts-exhausted": "it failed too many times in a row",
204
263
  "plan-revised": "the plan changed, so a fresh attempt took over",
205
264
  };
@@ -257,7 +316,7 @@ export function failedAttemptSentence(reason) {
257
316
  /** What to change before the next attempt, by a stopped run's recorded reason: one plain suggestion, the note Retry
258
317
  * starts with. A reason with no suggestion of its own gets the general one. */
259
318
  const STOP_SUGGESTIONS = {
260
- acceptance: "Before handing off, check each signed requirement against the changes.",
319
+ acceptance: "Before handing off, check each approved requirement against the changes.",
261
320
  timeout: "Split the work into smaller steps, or name the one part to finish first.",
262
321
  "no-op": "Say exactly which files or behaviour should change.",
263
322
  agent: "Say what to do differently this time, or name the part to try first.",
@@ -159,6 +159,8 @@ export type NightlyRead = {
159
159
  * failed call stops where it is; what was recorded stays, and the cursor never moves past a page it couldn't read.
160
160
  */
161
161
  export declare function readGithubNightly(store: Store, repo: string, deps: NightlyDeps, budgetMs: number): Promise<NightlyRead>;
162
+ /** Read one run by id, strictly. */
163
+ export declare function readRun(get: Get, slug: string, id: number): Promise<GhRun | null>;
162
164
  /** Every job of one exact attempt of one run, every page, each GitHub's record of that run, attempt and commit. Null
163
165
  * when any page can't be read whole. */
164
166
  export declare function readAttemptJobs(get: Get, slug: string, run: number, attempt: number, sha: string): Promise<GhJob[] | null>;
@@ -410,7 +410,7 @@ async function listRuns(store, repo, slug, get, now) {
410
410
  return { ok: true, listed, complete: false };
411
411
  }
412
412
  /** Read one run by id, strictly. */
413
- async function readRun(get, slug, id) {
413
+ export async function readRun(get, slug, id) {
414
414
  const got = await get(`repos/${slug}/actions/runs/${id}`);
415
415
  if (!got.ok)
416
416
  return null;
@@ -556,7 +556,7 @@ function recordAttempt(store, repo, attempt, now) {
556
556
  store.enqueueNotification({ dedupeKey: `github-nightly-failed:${Number(opened.lastInsertRowid)}`, kind: "github-nightly-failed", subject: "GitHub's nightly failed on main",
557
557
  body: `Nightly checks failed: ${lane}, on main at ${attempt.sha.slice(0, 7)}. Releases wait until it passes again.`, pushClass: "attention",
558
558
  // The project it belongs to, so its people's chats may carry it (Codex round 1, finding 8).
559
- source: { project: repo }, link: "/board" }, now);
559
+ source: { project: repo }, link: "/tasks?view=board" }, now);
560
560
  }
561
561
  }
562
562
  });
@@ -954,7 +954,7 @@ export function nightlyNeedsYou(store, shown) {
954
954
  for (const failure of openFailures(store, repo)) {
955
955
  needs.push({ key: `github-nightly-${failure.id}`, repo, title: `Nightly checks failed: ${laneName(store, repo, failure.laneId)}`,
956
956
  reason: `On main at ${failure.sha.slice(0, 7)}. Releases wait until it passes again.`,
957
- href: slug === null ? "/board" : `https://github.com/${slug}/actions/runs/${failure.ghRun}/job/${failure.jobId}`, since: failure.openedAt });
957
+ href: slug === null ? "/tasks?view=board" : `https://github.com/${slug}/actions/runs/${failure.ghRun}/job/${failure.jobId}`, since: failure.openedAt });
958
958
  }
959
959
  }
960
960
  // The plane's own nightly check of main (nightly-check.ts): one item per failed check, its items summed up.
@@ -968,7 +968,7 @@ export function nightlyNeedsYou(store, shown) {
968
968
  const items = store.handle.prepare("SELECT item FROM main_check_failure WHERE repo = ? AND run = ? AND cleared_at IS NULL ORDER BY item").all(repo, Number(row["run"])).map(one => String(one["item"]));
969
969
  needs.push({ key: `main-check-${Number(row["run"])}`, repo, title: `Nightly check of main failed: ${failureSummary(items)}`,
970
970
  reason: `On main at ${String(row["sha"]).slice(0, 7)}. Composed releases wait until a full check passes.`,
971
- href: task === null ? "/board" : `/t/${encodeURIComponent(task)}`, since: String(row["since"]) });
971
+ href: task === null ? "/tasks?view=board" : `/t/${encodeURIComponent(task)}`, since: String(row["since"]) });
972
972
  }
973
973
  return needs.sort((a, b) => a.since.localeCompare(b.since));
974
974
  }
@@ -20,6 +20,7 @@ export const REMOTE_ARGUMENTS = new Map([
20
20
  ['task ask', args('id:task', 'person why')],
21
21
  ['task checks', args('task:task', 'level')],
22
22
  ['task ship', args('task:task')],
23
+ ['task ready', args('task:task')],
23
24
  ['task add-tests', args('task:task')],
24
25
  ['task list', args('', 'state view limit cursor')],
25
26
  ['task show', args('id:task')],
@@ -57,10 +58,14 @@ export const REMOTE_ARGUMENTS = new Map([
57
58
  ['template show', args('name')],
58
59
  ...['search', 'impact'].map(action => [`knowledge ${action}`, args('query', 'base')]),
59
60
  ['knowledge refresh', args('', 'base')],
61
+ ['map', args('', 'cursor')], ...['area', 'file'].map(action => [`map ${action}`, args('target', 'cursor')]), ['map search', args('target*', 'cursor')], ['map refresh', args('')],
60
62
  // Decision reads are already project-bound in project-memory.ts. Memory writes (decide, retire, apply) are a person's
61
63
  // step-up, never a token's act, so none is listed here.
64
+ // Project-bound by flaky-cli.ts like memory reads; a row's key is compared inside the reader's own project.
65
+ ['flaky list', args('', 'days')],
66
+ ['flaky show', args('identity*', 'days')],
62
67
  ...['search', 'decisions', 'show', 'review', 'status'].map(action => [`memory ${action}`,
63
- args(action === 'search' ? 'query*' : action === 'show' ? 'query' : '', 'why reason supersedes source all decision sessions no-local')]),
68
+ args(action === 'search' ? 'query*' : action === 'show' ? 'query' : '', 'why reason supersedes source all decision claim choice revision sessions no-local')]),
64
69
  ['flows list', args()],
65
70
  ['flows show', args('flow:flow')], ['flows export', args('flow:flow')],
66
71
  ['flows create', args('', 'yes name template', { steps: 'steps' })],
@@ -37,7 +37,7 @@ const references = { kind: "references" }, listing = { kind: "listing" };
37
37
  export const REMOTE_SCOPES = new Map([
38
38
  ["status", listing], ["integrations", installation], ["ready", listing], ["grants", installation], ["sync", installation],
39
39
  ["gaps", repo], ["task add", repo],
40
- ...["ask", "checks", "ship", "add-tests", "show", "wait", "complete", "revise", "state", "block", "unblock", "next", "steer", "pause", "continue", "assign", "scope", "plan", "hold",
40
+ ...["ask", "checks", "ship", "ready", "add-tests", "show", "wait", "complete", "revise", "state", "block", "unblock", "next", "steer", "pause", "continue", "assign", "scope", "plan", "hold",
41
41
  "unhold", "require", "requeue", "review", "repair", "route", "reopen", "stop", "resume"].map(action => [`task ${action}`, references]),
42
42
  ["check-progress", references],
43
43
  ["task list", listing],
@@ -50,7 +50,9 @@ export const REMOTE_SCOPES = new Map([
50
50
  // The person's own remote actions, or everyone's within their projects for an approver (remote-audit.ts).
51
51
  ["audit", self],
52
52
  ["knowledge search", repo], ["knowledge impact", repo], ["knowledge refresh", repo],
53
+ ["map", repo], ["map area", repo], ["map file", repo], ["map search", repo], ["map refresh", repo],
53
54
  ...["search", "decisions", "show", "review", "status"].map(action => [`memory ${action}`, self]),
55
+ ["flaky list", self], ["flaky show", self],
54
56
  ...["list", "show", "export", "create", "edit", "trigger add", "trigger pause", "trigger resume", "trigger remove", "card add", "archive"]
55
57
  .map(action => [`flows ${action}`, self]),
56
58
  ["models status", global], ["models list", global],
package/dist/operate.d.ts CHANGED
@@ -124,7 +124,7 @@ type Args = {
124
124
  * exports are behavior, not commentary — and the declared command guide
125
125
  * (surface.ts) is tested for exact equality against them.
126
126
  */
127
- export declare const TASK_ACTIONS: readonly ["add", "list", "show", "wait", "state", "block", "unblock", "next", "steer", "pause", "continue", "assign", "reopen", "scope", "approve", "hold", "unhold", "require", "requeue", "regate", "plan", "review", "accept", "repair", "route", "stop", "resume", "complete", "revise", "merge", "ask", "checks", "add-tests", "archive", "restore", "tidy", "ship"];
127
+ export declare const TASK_ACTIONS: readonly ["add", "new", "keep", "list", "show", "wait", "state", "block", "unblock", "next", "steer", "pause", "continue", "assign", "reopen", "scope", "approve", "hold", "unhold", "require", "requeue", "regate", "plan", "review", "accept", "repair", "route", "stop", "resume", "complete", "revise", "merge", "ask", "checks", "add-tests", "archive", "restore", "tidy", "ship", "ready"];
128
128
  export declare const PUBLISH_ACTIONS: readonly ["setup", "grant", "revoke", "status", "unblock", "rearm", "merge", "refire"];
129
129
  export declare const CONFIG_ACTIONS: readonly ["show", "set", "clear"];
130
130
  export declare const APPROVER_ACTIONS: readonly ["list", "add"];
@@ -360,6 +360,8 @@ export type EasyCommandSeams = {
360
360
  check?: import("./provider-connection.js").ConnectionChecker;
361
361
  ask?: (question: string) => Promise<string>;
362
362
  askHidden?: (question: string) => Promise<string>;
363
+ confirm?: (question: string) => Promise<boolean>;
364
+ github?: import("./github-import.js").ImportDeps;
363
365
  };
364
366
  /**
365
367
  * Easy start: the ports `up --laptop` (no --port) tries, in order. The port this install saved, alone; else, for a NEW
@@ -368,3 +370,6 @@ export type EasyCommandSeams = {
368
370
  * way) `up`'s default alone, as before. `fromSeam` replaces the default range in tests.
369
371
  */
370
372
  export declare function upLaptopPortCandidates(store: Store, fromSeam?: readonly number[]): number[];
373
+ /** The watch loop's background learning pass (docs/plans/learning-loops.md): advisory reads, each project at most every
374
+ * 30 minutes through the plane's own gh. A failure here never reaches the loop: it is tried on the next pass. */
375
+ export declare function refreshLearning(store: Store, now: () => Date, reads?: GhRead): Promise<void>;