toolroll 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 (626) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1113 -0
  3. package/THIRD_PARTY_NOTICES.md +449 -0
  4. package/dist/accent-colors.d.ts +48 -0
  5. package/dist/accent-colors.js +122 -0
  6. package/dist/action-ledger.d.ts +26 -0
  7. package/dist/action-ledger.js +75 -0
  8. package/dist/agent-fence.d.ts +42 -0
  9. package/dist/agent-fence.js +183 -0
  10. package/dist/agentconfig.d.ts +216 -0
  11. package/dist/agentconfig.js +454 -0
  12. package/dist/api-tokens.d.ts +16 -0
  13. package/dist/api-tokens.js +27 -0
  14. package/dist/approval-policy.d.ts +69 -0
  15. package/dist/approval-policy.js +137 -0
  16. package/dist/approval-rules-ui.d.ts +25 -0
  17. package/dist/approval-rules-ui.js +39 -0
  18. package/dist/assignment-adapters.d.ts +180 -0
  19. package/dist/assignment-adapters.js +239 -0
  20. package/dist/assignment-brief.d.ts +71 -0
  21. package/dist/assignment-brief.js +129 -0
  22. package/dist/assignment-delivery.d.ts +56 -0
  23. package/dist/assignment-delivery.js +160 -0
  24. package/dist/assignment-presentation.d.ts +26 -0
  25. package/dist/assignment-presentation.js +80 -0
  26. package/dist/assignment-status.d.ts +62 -0
  27. package/dist/assignment-status.js +152 -0
  28. package/dist/assignment-ui.d.ts +71 -0
  29. package/dist/assignment-ui.js +103 -0
  30. package/dist/assignment.d.ts +222 -0
  31. package/dist/assignment.js +399 -0
  32. package/dist/attest.d.ts +56 -0
  33. package/dist/attest.js +153 -0
  34. package/dist/backend.d.ts +97 -0
  35. package/dist/backend.js +166 -0
  36. package/dist/backup-ui.d.ts +22 -0
  37. package/dist/backup-ui.js +59 -0
  38. package/dist/backup.d.ts +84 -0
  39. package/dist/backup.js +421 -0
  40. package/dist/beads.d.ts +34 -0
  41. package/dist/beads.js +135 -0
  42. package/dist/bin.d.ts +2 -0
  43. package/dist/bin.js +22 -0
  44. package/dist/board.d.ts +150 -0
  45. package/dist/board.js +210 -0
  46. package/dist/boot-identity.d.ts +63 -0
  47. package/dist/boot-identity.js +99 -0
  48. package/dist/browser/THIRD_PARTY_NOTICES.txt +2295 -0
  49. package/dist/browser/workspace.css +4 -0
  50. package/dist/browser/workspace.js +225 -0
  51. package/dist/browser-crew.d.ts +11 -0
  52. package/dist/browser-crew.js +50 -0
  53. package/dist/browser-shell.d.ts +8 -0
  54. package/dist/browser-shell.js +60 -0
  55. package/dist/browser-workspace.d.ts +780 -0
  56. package/dist/browser-workspace.js +47 -0
  57. package/dist/budget-alerts.d.ts +19 -0
  58. package/dist/budget-alerts.js +46 -0
  59. package/dist/builder.d.ts +370 -0
  60. package/dist/builder.js +3262 -0
  61. package/dist/capscan.d.ts +35 -0
  62. package/dist/capscan.js +113 -0
  63. package/dist/chat-acceptance.d.ts +71 -0
  64. package/dist/chat-acceptance.js +120 -0
  65. package/dist/chat-actions.d.ts +265 -0
  66. package/dist/chat-actions.js +1273 -0
  67. package/dist/chat-channel.d.ts +109 -0
  68. package/dist/chat-channel.js +652 -0
  69. package/dist/chat-continuity.d.ts +32 -0
  70. package/dist/chat-continuity.js +317 -0
  71. package/dist/chat-controls.d.ts +113 -0
  72. package/dist/chat-controls.js +53 -0
  73. package/dist/chat-delivery-state.d.ts +159 -0
  74. package/dist/chat-delivery-state.js +309 -0
  75. package/dist/chat-delivery.d.ts +38 -0
  76. package/dist/chat-delivery.js +693 -0
  77. package/dist/chat-display.d.ts +1 -0
  78. package/dist/chat-display.js +18 -0
  79. package/dist/chat-evidence.d.ts +123 -0
  80. package/dist/chat-evidence.js +207 -0
  81. package/dist/chat-flow.d.ts +44 -0
  82. package/dist/chat-flow.js +215 -0
  83. package/dist/chat-inbox.d.ts +57 -0
  84. package/dist/chat-inbox.js +123 -0
  85. package/dist/chat-polish.d.ts +16 -0
  86. package/dist/chat-polish.js +135 -0
  87. package/dist/chat-review.d.ts +46 -0
  88. package/dist/chat-review.js +98 -0
  89. package/dist/chat-rooms.d.ts +123 -0
  90. package/dist/chat-rooms.js +216 -0
  91. package/dist/chat-task-actions.d.ts +44 -0
  92. package/dist/chat-task-actions.js +79 -0
  93. package/dist/check-progress.d.ts +51 -0
  94. package/dist/check-progress.js +290 -0
  95. package/dist/child-database.d.ts +12 -0
  96. package/dist/child-database.js +30 -0
  97. package/dist/claim.d.ts +688 -0
  98. package/dist/claim.js +1740 -0
  99. package/dist/cli.d.ts +137 -0
  100. package/dist/cli.js +1461 -0
  101. package/dist/codex-limits.d.ts +15 -0
  102. package/dist/codex-limits.js +145 -0
  103. package/dist/coding-context.d.ts +55 -0
  104. package/dist/coding-context.js +92 -0
  105. package/dist/coding-handoff.d.ts +57 -0
  106. package/dist/coding-handoff.js +277 -0
  107. package/dist/coding-provider.d.ts +72 -0
  108. package/dist/coding-provider.js +424 -0
  109. package/dist/coding-shipping-ui.d.ts +4 -0
  110. package/dist/coding-shipping-ui.js +12 -0
  111. package/dist/coding-types.d.ts +62 -0
  112. package/dist/coding-types.js +1 -0
  113. package/dist/coding-ui.d.ts +17 -0
  114. package/dist/coding-ui.js +364 -0
  115. package/dist/coding-update.d.ts +15 -0
  116. package/dist/coding-update.js +149 -0
  117. package/dist/coding-workspace.d.ts +124 -0
  118. package/dist/coding-workspace.js +768 -0
  119. package/dist/container-state.d.ts +5 -0
  120. package/dist/container-state.js +62 -0
  121. package/dist/containment.d.ts +197 -0
  122. package/dist/containment.js +559 -0
  123. package/dist/contest.d.ts +318 -0
  124. package/dist/contest.js +753 -0
  125. package/dist/control-setup.d.ts +35 -0
  126. package/dist/control-setup.js +40 -0
  127. package/dist/control-ui.d.ts +29 -0
  128. package/dist/control-ui.js +53 -0
  129. package/dist/controller-service.d.ts +1 -0
  130. package/dist/controller-service.js +19 -0
  131. package/dist/controller-supervisor.d.ts +30 -0
  132. package/dist/controller-supervisor.js +104 -0
  133. package/dist/converse.d.ts +304 -0
  134. package/dist/converse.js +849 -0
  135. package/dist/coordinator-proposals.d.ts +29 -0
  136. package/dist/coordinator-proposals.js +137 -0
  137. package/dist/coordinator.d.ts +186 -0
  138. package/dist/coordinator.js +447 -0
  139. package/dist/credentials-ui.d.ts +25 -0
  140. package/dist/credentials-ui.js +48 -0
  141. package/dist/daemon.d.ts +209 -0
  142. package/dist/daemon.js +604 -0
  143. package/dist/decision.d.ts +120 -0
  144. package/dist/decision.js +388 -0
  145. package/dist/demo.d.ts +55 -0
  146. package/dist/demo.js +992 -0
  147. package/dist/desktop-access.d.ts +28 -0
  148. package/dist/desktop-access.js +88 -0
  149. package/dist/desktop-bundle.d.ts +16 -0
  150. package/dist/desktop-bundle.js +74 -0
  151. package/dist/desktop-host.d.ts +54 -0
  152. package/dist/desktop-host.js +508 -0
  153. package/dist/desktop-update-gate.d.ts +12 -0
  154. package/dist/desktop-update-gate.js +91 -0
  155. package/dist/desktop-update-recovery.d.ts +14 -0
  156. package/dist/desktop-update-recovery.js +243 -0
  157. package/dist/desktop-update.d.ts +110 -0
  158. package/dist/desktop-update.js +740 -0
  159. package/dist/discord-api.d.ts +20 -0
  160. package/dist/discord-api.js +138 -0
  161. package/dist/discord-chat.d.ts +16 -0
  162. package/dist/discord-chat.js +381 -0
  163. package/dist/discord-settings.d.ts +7 -0
  164. package/dist/discord-settings.js +75 -0
  165. package/dist/discord.d.ts +10 -0
  166. package/dist/discord.js +169 -0
  167. package/dist/discover.d.ts +75 -0
  168. package/dist/discover.js +150 -0
  169. package/dist/dispatch.d.ts +100 -0
  170. package/dist/dispatch.js +311 -0
  171. package/dist/dispose.d.ts +161 -0
  172. package/dist/dispose.js +803 -0
  173. package/dist/email-settings.d.ts +34 -0
  174. package/dist/email-settings.js +50 -0
  175. package/dist/envelope.d.ts +47 -0
  176. package/dist/envelope.js +105 -0
  177. package/dist/evidence-pack.d.ts +185 -0
  178. package/dist/evidence-pack.js +258 -0
  179. package/dist/evidence.d.ts +345 -0
  180. package/dist/evidence.js +782 -0
  181. package/dist/exec.d.ts +285 -0
  182. package/dist/exec.js +1841 -0
  183. package/dist/exhaustion.d.ts +85 -0
  184. package/dist/exhaustion.js +141 -0
  185. package/dist/export-ui.d.ts +4 -0
  186. package/dist/export-ui.js +17 -0
  187. package/dist/export.d.ts +48 -0
  188. package/dist/export.js +305 -0
  189. package/dist/flow-actions.d.ts +77 -0
  190. package/dist/flow-actions.js +203 -0
  191. package/dist/flow-code.d.ts +50 -0
  192. package/dist/flow-code.js +159 -0
  193. package/dist/flow-draft.d.ts +38 -0
  194. package/dist/flow-draft.js +80 -0
  195. package/dist/flow-engine.d.ts +66 -0
  196. package/dist/flow-engine.js +416 -0
  197. package/dist/flow-insights.d.ts +95 -0
  198. package/dist/flow-insights.js +149 -0
  199. package/dist/flow-live.d.ts +24 -0
  200. package/dist/flow-live.js +150 -0
  201. package/dist/flow-people.d.ts +24 -0
  202. package/dist/flow-people.js +91 -0
  203. package/dist/flow-replies.d.ts +48 -0
  204. package/dist/flow-replies.js +113 -0
  205. package/dist/flow-scripts.d.ts +38 -0
  206. package/dist/flow-scripts.js +73 -0
  207. package/dist/flow-secrets.d.ts +13 -0
  208. package/dist/flow-secrets.js +45 -0
  209. package/dist/flow-sort.d.ts +82 -0
  210. package/dist/flow-sort.js +153 -0
  211. package/dist/flow-steps.d.ts +40 -0
  212. package/dist/flow-steps.js +408 -0
  213. package/dist/flow-triggers.d.ts +244 -0
  214. package/dist/flow-triggers.js +959 -0
  215. package/dist/flows-ui.d.ts +20 -0
  216. package/dist/flows-ui.js +175 -0
  217. package/dist/flows.d.ts +229 -0
  218. package/dist/flows.js +968 -0
  219. package/dist/fonts.d.ts +19 -0
  220. package/dist/fonts.js +19 -0
  221. package/dist/gaps.d.ts +35 -0
  222. package/dist/gaps.js +101 -0
  223. package/dist/gate-failure.d.ts +40 -0
  224. package/dist/gate-failure.js +66 -0
  225. package/dist/git.d.ts +54 -0
  226. package/dist/git.js +94 -0
  227. package/dist/google-mail.d.ts +58 -0
  228. package/dist/google-mail.js +151 -0
  229. package/dist/grant.d.ts +136 -0
  230. package/dist/grant.js +238 -0
  231. package/dist/graph.d.ts +164 -0
  232. package/dist/graph.js +383 -0
  233. package/dist/guides.d.ts +22 -0
  234. package/dist/guides.js +363 -0
  235. package/dist/held.d.ts +150 -0
  236. package/dist/held.js +799 -0
  237. package/dist/invoke.d.ts +112 -0
  238. package/dist/invoke.js +780 -0
  239. package/dist/issues.d.ts +41 -0
  240. package/dist/issues.js +131 -0
  241. package/dist/job-object-helper.ps1 +252 -0
  242. package/dist/jsonl-discriminants.d.ts +11 -0
  243. package/dist/jsonl-discriminants.js +93 -0
  244. package/dist/keys.d.ts +104 -0
  245. package/dist/keys.js +229 -0
  246. package/dist/kits-ui.d.ts +17 -0
  247. package/dist/kits-ui.js +46 -0
  248. package/dist/kits.d.ts +86 -0
  249. package/dist/kits.js +215 -0
  250. package/dist/knowledge-cli.d.ts +101 -0
  251. package/dist/knowledge-cli.js +92 -0
  252. package/dist/knowledge-ui.d.ts +24 -0
  253. package/dist/knowledge-ui.js +40 -0
  254. package/dist/lead-context.d.ts +8 -0
  255. package/dist/lead-context.js +56 -0
  256. package/dist/lead-follow.d.ts +22 -0
  257. package/dist/lead-follow.js +167 -0
  258. package/dist/lead-status.d.ts +75 -0
  259. package/dist/lead-status.js +285 -0
  260. package/dist/ledger-chain.d.ts +46 -0
  261. package/dist/ledger-chain.js +187 -0
  262. package/dist/ledger-csv.d.ts +4 -0
  263. package/dist/ledger-csv.js +11 -0
  264. package/dist/ledger-view.d.ts +24 -0
  265. package/dist/ledger-view.js +58 -0
  266. package/dist/limits-ui.d.ts +26 -0
  267. package/dist/limits-ui.js +67 -0
  268. package/dist/link.d.ts +72 -0
  269. package/dist/link.js +217 -0
  270. package/dist/live.d.ts +96 -0
  271. package/dist/live.js +366 -0
  272. package/dist/liveness.d.ts +30 -0
  273. package/dist/liveness.js +42 -0
  274. package/dist/log.d.ts +7 -0
  275. package/dist/log.js +25 -0
  276. package/dist/mailbox.d.ts +57 -0
  277. package/dist/mailbox.js +150 -0
  278. package/dist/maintenance.d.ts +11 -0
  279. package/dist/maintenance.js +35 -0
  280. package/dist/mate-cli.d.ts +52 -0
  281. package/dist/mate-cli.js +345 -0
  282. package/dist/mate-contract.d.ts +10 -0
  283. package/dist/mate-contract.js +30 -0
  284. package/dist/mate-doors.d.ts +69 -0
  285. package/dist/mate-doors.js +548 -0
  286. package/dist/mate-progress.d.ts +29 -0
  287. package/dist/mate-progress.js +121 -0
  288. package/dist/mate-tools.d.ts +94 -0
  289. package/dist/mate-tools.js +1878 -0
  290. package/dist/mate.d.ts +92 -0
  291. package/dist/mate.js +435 -0
  292. package/dist/mcp-connect.d.ts +103 -0
  293. package/dist/mcp-connect.js +252 -0
  294. package/dist/mcp.d.ts +27 -0
  295. package/dist/mcp.js +651 -0
  296. package/dist/memory-cli.d.ts +466 -0
  297. package/dist/memory-cli.js +111 -0
  298. package/dist/memory-pass.d.ts +160 -0
  299. package/dist/memory-pass.js +409 -0
  300. package/dist/metrics.d.ts +3 -0
  301. package/dist/metrics.js +56 -0
  302. package/dist/mobile-viewport.d.ts +3 -0
  303. package/dist/mobile-viewport.js +37 -0
  304. package/dist/model-catalog.d.ts +118 -0
  305. package/dist/model-catalog.js +376 -0
  306. package/dist/models-cli.d.ts +102 -0
  307. package/dist/models-cli.js +66 -0
  308. package/dist/models-ui.d.ts +34 -0
  309. package/dist/models-ui.js +68 -0
  310. package/dist/modes.d.ts +80 -0
  311. package/dist/modes.js +182 -0
  312. package/dist/monitoring-settings.d.ts +44 -0
  313. package/dist/monitoring-settings.js +173 -0
  314. package/dist/monitoring-ui.d.ts +20 -0
  315. package/dist/monitoring-ui.js +51 -0
  316. package/dist/monitoring.d.ts +34 -0
  317. package/dist/monitoring.js +221 -0
  318. package/dist/names.d.ts +67 -0
  319. package/dist/names.js +102 -0
  320. package/dist/observations.d.ts +40 -0
  321. package/dist/observations.js +211 -0
  322. package/dist/oidc.d.ts +71 -0
  323. package/dist/oidc.js +182 -0
  324. package/dist/onboard.d.ts +108 -0
  325. package/dist/onboard.js +325 -0
  326. package/dist/openrouter-models.d.ts +30 -0
  327. package/dist/openrouter-models.js +120 -0
  328. package/dist/operate.d.ts +118 -0
  329. package/dist/operate.js +11321 -0
  330. package/dist/peek-cli.d.ts +97 -0
  331. package/dist/peek-cli.js +215 -0
  332. package/dist/peek.d.ts +134 -0
  333. package/dist/peek.js +578 -0
  334. package/dist/phase-routing.d.ts +307 -0
  335. package/dist/phase-routing.js +658 -0
  336. package/dist/plan-auto.d.ts +14 -0
  337. package/dist/plan-auto.js +92 -0
  338. package/dist/plan.d.ts +186 -0
  339. package/dist/plan.js +401 -0
  340. package/dist/planner-source.d.ts +251 -0
  341. package/dist/planner-source.js +460 -0
  342. package/dist/planner.d.ts +75 -0
  343. package/dist/planner.js +992 -0
  344. package/dist/policy-ui.d.ts +20 -0
  345. package/dist/policy-ui.js +41 -0
  346. package/dist/policy.d.ts +111 -0
  347. package/dist/policy.js +231 -0
  348. package/dist/prepared-evidence.d.ts +16 -0
  349. package/dist/prepared-evidence.js +96 -0
  350. package/dist/pricing.d.ts +45 -0
  351. package/dist/pricing.js +77 -0
  352. package/dist/principal.d.ts +42 -0
  353. package/dist/principal.js +82 -0
  354. package/dist/probe.d.ts +46 -0
  355. package/dist/probe.js +79 -0
  356. package/dist/process-custody.d.ts +17 -0
  357. package/dist/process-custody.js +91 -0
  358. package/dist/process-liveness.d.ts +10 -0
  359. package/dist/process-liveness.js +81 -0
  360. package/dist/process-recovery-anchor.d.ts +75 -0
  361. package/dist/process-recovery-anchor.js +188 -0
  362. package/dist/process-recovery-coalition.d.ts +25 -0
  363. package/dist/process-recovery-coalition.js +105 -0
  364. package/dist/process-recovery-eligibility.d.ts +178 -0
  365. package/dist/process-recovery-eligibility.js +170 -0
  366. package/dist/process-recovery-native.d.ts +172 -0
  367. package/dist/process-recovery-native.js +592 -0
  368. package/dist/process-recovery-provenance.d.ts +163 -0
  369. package/dist/process-recovery-provenance.js +292 -0
  370. package/dist/process-recovery-services.d.ts +56 -0
  371. package/dist/process-recovery-services.js +191 -0
  372. package/dist/process-recovery-settlement.d.ts +32 -0
  373. package/dist/process-recovery-settlement.js +132 -0
  374. package/dist/process-recovery.d.ts +41 -0
  375. package/dist/process-recovery.js +91 -0
  376. package/dist/process-tree.d.ts +41 -0
  377. package/dist/process-tree.js +264 -0
  378. package/dist/project-access.d.ts +14 -0
  379. package/dist/project-access.js +34 -0
  380. package/dist/project-cli.d.ts +18 -0
  381. package/dist/project-cli.js +104 -0
  382. package/dist/project-delete-ui.d.ts +22 -0
  383. package/dist/project-delete-ui.js +48 -0
  384. package/dist/project-delete.d.ts +55 -0
  385. package/dist/project-delete.js +413 -0
  386. package/dist/project-knowledge.d.ts +111 -0
  387. package/dist/project-knowledge.js +241 -0
  388. package/dist/project-learning.d.ts +100 -0
  389. package/dist/project-learning.js +438 -0
  390. package/dist/project-memory.d.ts +81 -0
  391. package/dist/project-memory.js +264 -0
  392. package/dist/project-skills.d.ts +152 -0
  393. package/dist/project-skills.js +660 -0
  394. package/dist/project-tools.d.ts +219 -0
  395. package/dist/project-tools.js +796 -0
  396. package/dist/project.d.ts +61 -0
  397. package/dist/project.js +125 -0
  398. package/dist/prompt.d.ts +22 -0
  399. package/dist/prompt.js +72 -0
  400. package/dist/proof.d.ts +513 -0
  401. package/dist/proof.js +1140 -0
  402. package/dist/proposal.d.ts +82 -0
  403. package/dist/proposal.js +210 -0
  404. package/dist/provider-connection.d.ts +22 -0
  405. package/dist/provider-connection.js +98 -0
  406. package/dist/provider-limits.d.ts +35 -0
  407. package/dist/provider-limits.js +95 -0
  408. package/dist/provider.d.ts +279 -0
  409. package/dist/provider.js +935 -0
  410. package/dist/publish.d.ts +107 -0
  411. package/dist/publish.js +650 -0
  412. package/dist/pulls.d.ts +118 -0
  413. package/dist/pulls.js +240 -0
  414. package/dist/push.d.ts +95 -0
  415. package/dist/push.js +353 -0
  416. package/dist/quality.d.ts +8 -0
  417. package/dist/quality.js +6 -0
  418. package/dist/recipe-ui.d.ts +18 -0
  419. package/dist/recipe-ui.js +152 -0
  420. package/dist/recipes.d.ts +81 -0
  421. package/dist/recipes.js +332 -0
  422. package/dist/remote.d.ts +67 -0
  423. package/dist/remote.js +122 -0
  424. package/dist/render.d.ts +64 -0
  425. package/dist/render.js +587 -0
  426. package/dist/report-summary.d.ts +13 -0
  427. package/dist/report-summary.js +15 -0
  428. package/dist/repos.d.ts +65 -0
  429. package/dist/repos.js +277 -0
  430. package/dist/repository-context-ui.d.ts +2 -0
  431. package/dist/repository-context-ui.js +10 -0
  432. package/dist/repository-context.d.ts +67 -0
  433. package/dist/repository-context.js +376 -0
  434. package/dist/restart-certification.d.ts +134 -0
  435. package/dist/restart-certification.js +226 -0
  436. package/dist/result-actions.d.ts +28 -0
  437. package/dist/result-actions.js +270 -0
  438. package/dist/result-completion.d.ts +18 -0
  439. package/dist/result-completion.js +66 -0
  440. package/dist/result-review.d.ts +213 -0
  441. package/dist/result-review.js +430 -0
  442. package/dist/retention-ui.d.ts +12 -0
  443. package/dist/retention-ui.js +39 -0
  444. package/dist/retention.d.ts +72 -0
  445. package/dist/retention.js +288 -0
  446. package/dist/review-context.d.ts +243 -0
  447. package/dist/review-context.js +1043 -0
  448. package/dist/review-evidence.d.ts +33 -0
  449. package/dist/review-evidence.js +56 -0
  450. package/dist/reviewer.d.ts +97 -0
  451. package/dist/reviewer.js +202 -0
  452. package/dist/routine.d.ts +228 -0
  453. package/dist/routine.js +764 -0
  454. package/dist/runner.d.ts +266 -0
  455. package/dist/runner.js +399 -0
  456. package/dist/scan.d.ts +32 -0
  457. package/dist/scan.js +92 -0
  458. package/dist/scope.d.ts +695 -0
  459. package/dist/scope.js +1176 -0
  460. package/dist/scout-report.d.ts +42 -0
  461. package/dist/scout-report.js +108 -0
  462. package/dist/scout.d.ts +69 -0
  463. package/dist/scout.js +351 -0
  464. package/dist/serve.d.ts +313 -0
  465. package/dist/serve.js +21776 -0
  466. package/dist/session-brief.d.ts +8 -0
  467. package/dist/session-brief.js +24 -0
  468. package/dist/session-cli.d.ts +13 -0
  469. package/dist/session-cli.js +284 -0
  470. package/dist/session-contract.d.ts +183 -0
  471. package/dist/session-contract.js +122 -0
  472. package/dist/session-http.d.ts +19 -0
  473. package/dist/session-http.js +154 -0
  474. package/dist/session-server.d.ts +12 -0
  475. package/dist/session-server.js +37 -0
  476. package/dist/session-service.d.ts +22 -0
  477. package/dist/session-service.js +157 -0
  478. package/dist/setup-guide.d.ts +39 -0
  479. package/dist/setup-guide.js +93 -0
  480. package/dist/sign-in-guard.d.ts +45 -0
  481. package/dist/sign-in-guard.js +74 -0
  482. package/dist/skills-ui.d.ts +11 -0
  483. package/dist/skills-ui.js +58 -0
  484. package/dist/skills.d.ts +97 -0
  485. package/dist/skills.js +276 -0
  486. package/dist/slack-api.d.ts +55 -0
  487. package/dist/slack-api.js +229 -0
  488. package/dist/slack-chat.d.ts +28 -0
  489. package/dist/slack-chat.js +413 -0
  490. package/dist/slack-settings.d.ts +7 -0
  491. package/dist/slack-settings.js +75 -0
  492. package/dist/slack-state.d.ts +13 -0
  493. package/dist/slack-state.js +9 -0
  494. package/dist/slack.d.ts +13 -0
  495. package/dist/slack.js +167 -0
  496. package/dist/spend-ui.d.ts +28 -0
  497. package/dist/spend-ui.js +95 -0
  498. package/dist/spend.d.ts +142 -0
  499. package/dist/spend.js +313 -0
  500. package/dist/sqlite-runtime.d.ts +3 -0
  501. package/dist/sqlite-runtime.js +6 -0
  502. package/dist/sso-settings.d.ts +33 -0
  503. package/dist/sso-settings.js +103 -0
  504. package/dist/sso-ui.d.ts +22 -0
  505. package/dist/sso-ui.js +39 -0
  506. package/dist/storage.d.ts +15 -0
  507. package/dist/storage.js +84 -0
  508. package/dist/store.d.ts +7754 -0
  509. package/dist/store.js +23279 -0
  510. package/dist/structured-output.d.ts +58 -0
  511. package/dist/structured-output.js +103 -0
  512. package/dist/style-asset.d.ts +7 -0
  513. package/dist/style-asset.js +41 -0
  514. package/dist/subscription-chat.d.ts +46 -0
  515. package/dist/subscription-chat.js +275 -0
  516. package/dist/summary.d.ts +33 -0
  517. package/dist/summary.js +71 -0
  518. package/dist/supervisor.mjs +297 -0
  519. package/dist/surface.d.ts +63 -0
  520. package/dist/surface.js +352 -0
  521. package/dist/sync.d.ts +94 -0
  522. package/dist/sync.js +279 -0
  523. package/dist/task-composer.d.ts +13 -0
  524. package/dist/task-composer.js +52 -0
  525. package/dist/task-control.d.ts +165 -0
  526. package/dist/task-control.js +214 -0
  527. package/dist/task-outcome-cli.d.ts +10 -0
  528. package/dist/task-outcome-cli.js +92 -0
  529. package/dist/task-text.d.ts +30 -0
  530. package/dist/task-text.js +41 -0
  531. package/dist/team-cli.d.ts +15 -0
  532. package/dist/team-cli.js +618 -0
  533. package/dist/team-contract.d.ts +92 -0
  534. package/dist/team-contract.js +1 -0
  535. package/dist/team-http.d.ts +17 -0
  536. package/dist/team-http.js +144 -0
  537. package/dist/team-leads.d.ts +81 -0
  538. package/dist/team-leads.js +565 -0
  539. package/dist/team-runtime.d.ts +27 -0
  540. package/dist/team-runtime.js +264 -0
  541. package/dist/team-ui.d.ts +3 -0
  542. package/dist/team-ui.js +9 -0
  543. package/dist/team-updates.d.ts +8 -0
  544. package/dist/team-updates.js +57 -0
  545. package/dist/teammate-admin.d.ts +53 -0
  546. package/dist/teammate-admin.js +111 -0
  547. package/dist/teammate-desk.d.ts +60 -0
  548. package/dist/teammate-desk.js +154 -0
  549. package/dist/teammate-memory.d.ts +64 -0
  550. package/dist/teammate-memory.js +196 -0
  551. package/dist/teammate-question.d.ts +59 -0
  552. package/dist/teammate-question.js +175 -0
  553. package/dist/teammate-tools.d.ts +108 -0
  554. package/dist/teammate-tools.js +271 -0
  555. package/dist/teammate-week.d.ts +68 -0
  556. package/dist/teammate-week.js +132 -0
  557. package/dist/teammate-work.d.ts +76 -0
  558. package/dist/teammate-work.js +280 -0
  559. package/dist/teammates-ui.d.ts +20 -0
  560. package/dist/teammates-ui.js +166 -0
  561. package/dist/teammates.d.ts +180 -0
  562. package/dist/teammates.js +253 -0
  563. package/dist/teams-api.d.ts +33 -0
  564. package/dist/teams-api.js +204 -0
  565. package/dist/teams-chat.d.ts +26 -0
  566. package/dist/teams-chat.js +215 -0
  567. package/dist/teams-settings.d.ts +12 -0
  568. package/dist/teams-settings.js +57 -0
  569. package/dist/teams.d.ts +21 -0
  570. package/dist/teams.js +124 -0
  571. package/dist/telegram-flow.d.ts +49 -0
  572. package/dist/telegram-flow.js +110 -0
  573. package/dist/telegram-mate.d.ts +137 -0
  574. package/dist/telegram-mate.js +707 -0
  575. package/dist/telegram-progress.d.ts +14 -0
  576. package/dist/telegram-progress.js +129 -0
  577. package/dist/telegram-settings.d.ts +9 -0
  578. package/dist/telegram-settings.js +36 -0
  579. package/dist/telegram-status.d.ts +75 -0
  580. package/dist/telegram-status.js +265 -0
  581. package/dist/telegram-team.d.ts +85 -0
  582. package/dist/telegram-team.js +359 -0
  583. package/dist/telegram.d.ts +230 -0
  584. package/dist/telegram.js +1931 -0
  585. package/dist/templates.d.ts +65 -0
  586. package/dist/templates.js +118 -0
  587. package/dist/tool-launcher.d.ts +1 -0
  588. package/dist/tool-launcher.js +101 -0
  589. package/dist/tools-ui.d.ts +30 -0
  590. package/dist/tools-ui.js +40 -0
  591. package/dist/transitions-recipes.d.ts +1 -0
  592. package/dist/transitions-recipes.js +203 -0
  593. package/dist/tree-proof.d.ts +34 -0
  594. package/dist/tree-proof.js +58 -0
  595. package/dist/verification-evidence.d.ts +44 -0
  596. package/dist/verification-evidence.js +238 -0
  597. package/dist/version.d.ts +2 -0
  598. package/dist/version.js +10 -0
  599. package/dist/webhooks.d.ts +91 -0
  600. package/dist/webhooks.js +283 -0
  601. package/dist/work-index.d.ts +68 -0
  602. package/dist/work-index.js +384 -0
  603. package/dist/work-summary.d.ts +57 -0
  604. package/dist/work-summary.js +116 -0
  605. package/dist/workspace-motion.d.ts +4 -0
  606. package/dist/workspace-motion.js +133 -0
  607. package/dist/workspace-revision.d.ts +19 -0
  608. package/dist/workspace-revision.js +92 -0
  609. package/dist/workspace-ui.d.ts +204 -0
  610. package/dist/workspace-ui.js +411 -0
  611. package/dist/worktree-notices.d.ts +13 -0
  612. package/dist/worktree-notices.js +17 -0
  613. package/dist/worktree.d.ts +249 -0
  614. package/dist/worktree.js +720 -0
  615. package/package.json +122 -0
  616. package/scripts/canary-assertions.mjs +42 -0
  617. package/scripts/crash-canary.mjs +253 -0
  618. package/scripts/fixtures/crash-process.mjs +74 -0
  619. package/scripts/fixtures/pilot-scenarios.mjs +85 -0
  620. package/scripts/fixtures/restart-service.mjs +27 -0
  621. package/scripts/launchd-certification.mjs +143 -0
  622. package/scripts/pilot.mjs +121 -0
  623. package/scripts/proof-preflight.mjs +140 -0
  624. package/scripts/provider-canary.mjs +379 -0
  625. package/scripts/recovery-canary.mjs +135 -0
  626. package/scripts/restart-certification.mjs +98 -0
package/dist/sync.js ADDED
@@ -0,0 +1,279 @@
1
+ /**
2
+ * External dispatch's sync pass (v20; five review rounds are the spec).
3
+ *
4
+ * What this does: pulls a tracker's nominated work into the overlay as
5
+ * ORDINARY local tasks (mirrors), refreshes every known mirror's remote
6
+ * state, verifies the plane marker, and delivers pending write-back
7
+ * intents — all at daemon cadence, zero tokens.
8
+ *
9
+ * What this never does: touch claims or runs (the latch is a write to the
10
+ * mirror row; admission and completion enforce it), import issue BODIES
11
+ * (titles only, through the canonical proposal validator — a tracker
12
+ * anyone can write to is a prompt-injection surface), or treat absence
13
+ * from a capped listing as closure (every known mirror is fetched
14
+ * INDIVIDUALLY; only a COMPLETE pass advances freshness).
15
+ *
16
+ * The plane marker is detection, never a distributed lease: a fixed-name
17
+ * repository label carries this plane's id in its description. A 404 is
18
+ * semantic "missing" only AFTER an authenticated access proof on the
19
+ * repository itself — GitHub 404s private resources the caller cannot
20
+ * see, and that must read as an OPERATIONAL block, fail closed.
21
+ */
22
+ import { createHash } from "node:crypto";
23
+ import { run } from "./exec.js";
24
+ import { describeFailure, parseJson } from "./backend.js";
25
+ import { fileTaskProposal } from "./proposal.js";
26
+ const GH = "gh";
27
+ export const SYNC_TIMEOUT_MS = 20_000;
28
+ export const MARKER_LABEL = "standing-orders-plane";
29
+ /** Bounded forward scan: pages of 100, at most this many pages per pass. */
30
+ export const MAX_FORWARD_PAGES = 10;
31
+ const operational = (message) => ({ ok: false, kind: "operational", message });
32
+ export function ghDispatchAdapter(runner = run, timeoutMs = SYNC_TIMEOUT_MS) {
33
+ const call = (args) => runner(GH, args, { timeoutMs });
34
+ return {
35
+ async repoAccess(remoteRepo) {
36
+ const result = await call(["api", `repos/${remoteRepo}`]);
37
+ if (result.code !== 0)
38
+ return operational(describeFailure(result));
39
+ const parsed = parseJson(result.stdout);
40
+ if (parsed === null || typeof parsed !== "object")
41
+ return operational("gh returned something unreadable for the repository");
42
+ const permissions = parsed["permissions"];
43
+ return { ok: true, push: permissions !== undefined && permissions["push"] === true };
44
+ },
45
+ async listAllOpen(remoteRepo) {
46
+ const issues = [];
47
+ for (let page = 1; page <= MAX_FORWARD_PAGES; page++) {
48
+ const result = await call(["api", `repos/${remoteRepo}/issues?state=open&per_page=100&page=${page}`]);
49
+ if (result.code !== 0)
50
+ return operational(describeFailure(result));
51
+ const parsed = parseJson(result.stdout);
52
+ if (!Array.isArray(parsed))
53
+ return operational("gh returned something that is not a list");
54
+ for (const raw of parsed) {
55
+ const issue = readRemoteIssue(raw);
56
+ // The issues API interleaves pull requests; a PR is not a task.
57
+ if (issue !== null && !(typeof raw === "object" && raw !== null && "pull_request" in raw)) {
58
+ issues.push(issue);
59
+ }
60
+ }
61
+ if (parsed.length < 100)
62
+ return { ok: true, issues, complete: true };
63
+ }
64
+ return { ok: true, issues, complete: false };
65
+ },
66
+ async getIssue(remoteRepo, number) {
67
+ const result = await call(["api", `repos/${remoteRepo}/issues/${number}`]);
68
+ if (result.code !== 0) {
69
+ // The caller has ALREADY proved authenticated access this pass, so a
70
+ // 404 here is the issue itself being gone.
71
+ return /404|Not Found/i.test(result.stderr) ? { ok: true, found: null } : operational(describeFailure(result));
72
+ }
73
+ const issue = readRemoteIssue(parseJson(result.stdout));
74
+ return issue === null ? operational("gh returned an issue in a shape we do not know") : { ok: true, found: issue };
75
+ },
76
+ async readMarker(remoteRepo) {
77
+ const result = await call(["api", `repos/${remoteRepo}/labels/${MARKER_LABEL}`]);
78
+ if (result.code !== 0) {
79
+ return /404|Not Found/i.test(result.stderr) ? { ok: true, plane: null, malformed: false } : operational(describeFailure(result));
80
+ }
81
+ const parsed = parseJson(result.stdout);
82
+ const description = parsed !== null && typeof parsed["description"] === "string" ? String(parsed["description"]) : "";
83
+ const match = /^plane:([0-9a-f]{16})$/.exec(description.trim());
84
+ if (match?.[1] !== undefined)
85
+ return { ok: true, plane: match[1], malformed: false };
86
+ return { ok: true, plane: null, malformed: true };
87
+ },
88
+ async writeMarker(remoteRepo, planeId) {
89
+ const result = await call([
90
+ "label", "create", MARKER_LABEL, "--repo", remoteRepo, "--force",
91
+ "--description", `plane:${planeId}`, "--color", "ededed",
92
+ ]);
93
+ return result.code === 0 ? { ok: true } : operational(describeFailure(result));
94
+ },
95
+ async deleteMarker(remoteRepo) {
96
+ const result = await call(["api", "-X", "DELETE", `repos/${remoteRepo}/labels/${MARKER_LABEL}`]);
97
+ return result.code === 0 || /404|Not Found/i.test(result.stderr) ? { ok: true } : operational(describeFailure(result));
98
+ },
99
+ async comment(remoteRepo, number, body) {
100
+ const result = await call(["issue", "comment", number, "--repo", remoteRepo, "--body", body]);
101
+ return result.code === 0 ? { ok: true } : operational(describeFailure(result));
102
+ },
103
+ async close(remoteRepo, number) {
104
+ const result = await call(["issue", "close", number, "--repo", remoteRepo]);
105
+ return result.code === 0 ? { ok: true } : operational(describeFailure(result));
106
+ },
107
+ };
108
+ }
109
+ function readRemoteIssue(record) {
110
+ if (typeof record !== "object" || record === null)
111
+ return null;
112
+ const raw = record;
113
+ if (typeof raw["number"] !== "number")
114
+ return null;
115
+ return {
116
+ number: raw["number"],
117
+ title: typeof raw["title"] === "string" ? raw["title"] : "",
118
+ state: String(raw["state"]).toLowerCase() === "closed" ? "closed" : "open",
119
+ };
120
+ }
121
+ /** ghi-<owner>-<name>-<n>-<hash8>: collision-resistant across long slugs. */
122
+ export function mirrorTaskId(remoteRepo, remoteId) {
123
+ const hash = createHash("sha256").update(`${remoteRepo}#${remoteId}`).digest("hex").slice(0, 8);
124
+ const slug = remoteRepo.toLowerCase().replace(/[^a-z0-9]+/g, "-").slice(0, 30);
125
+ return `ghi-${slug}-${remoteId}-${hash}`;
126
+ }
127
+ /**
128
+ * One pass over one dispatch grant. Order is the spec's: access proof →
129
+ * marker verdict → forward scan → reverse sweep (every known mirror,
130
+ * individually) → intent delivery → ledger close. Only a pass in which
131
+ * EVERY step succeeded closes `complete` and advances freshness.
132
+ */
133
+ export async function syncPass(store, grant, adapter, now) {
134
+ const remoteRepo = grant.remoteRepo;
135
+ const report = { remoteRepo, outcome: "failed", detail: null, candidates: 0, mirrored: 0, latched: 0, delivered: 0 };
136
+ // 1. Authenticated access proof — WITHOUT it, every 404 downstream is
137
+ // operational, and dispatch blocks immediately (no grace window).
138
+ const access = await adapter.repoAccess(remoteRepo);
139
+ if (!access.ok) {
140
+ store.setDispatchBlocked(grant.repo, grant.backend, "unreachable", now(), access.message);
141
+ report.outcome = "blocked";
142
+ report.detail = access.message;
143
+ return report;
144
+ }
145
+ // 2. The marker verdict — semantic states only from a complete response.
146
+ const marker = await adapter.readMarker(remoteRepo);
147
+ if (!marker.ok) {
148
+ store.setDispatchBlocked(grant.repo, grant.backend, "unreachable", now(), marker.message);
149
+ report.outcome = "blocked";
150
+ report.detail = marker.message;
151
+ return report;
152
+ }
153
+ if (marker.malformed) {
154
+ store.setDispatchBlocked(grant.repo, grant.backend, "multiple-or-malformed", now(), "the plane marker's description is not this tool's shape");
155
+ report.outcome = "blocked";
156
+ report.detail = "marker malformed";
157
+ return report;
158
+ }
159
+ if (marker.plane === null) {
160
+ store.setDispatchBlocked(grant.repo, grant.backend, "missing", now(), "no plane marker on the repository — enroll again to write it");
161
+ report.outcome = "blocked";
162
+ report.detail = "marker missing";
163
+ return report;
164
+ }
165
+ if (marker.plane !== grant.planeId) {
166
+ store.setDispatchBlocked(grant.repo, grant.backend, "foreign", now(), `the repository's marker names another plane (${marker.plane.slice(0, 6)}…)`);
167
+ report.outcome = "blocked";
168
+ report.detail = "foreign plane";
169
+ return report;
170
+ }
171
+ // A VERIFIED matching marker clears any standing block — transient or
172
+ // semantic — because verification is exactly what a block awaited. The
173
+ // LIVE row is read here; the caller's copy may predate the block.
174
+ const live = store.grantFor(grant.repo, grant.backend);
175
+ if (live?.dispatchBlocked != null) {
176
+ store.setDispatchBlocked(grant.repo, grant.backend, null, now());
177
+ }
178
+ const pass = store.openSyncPass(grant.backend, remoteRepo, now());
179
+ let capped = false;
180
+ // 3. Forward: candidates. Only selector=all ESTABLISHES from the scan —
181
+ // 'ours' mirrors are established at creation/intake, never nominated
182
+ // by a listing (provenance is a record, not a label).
183
+ const listing = await adapter.listAllOpen(remoteRepo);
184
+ if (!listing.ok) {
185
+ store.closeSyncPass(pass.id, "failed", { candidates: 0, mirrored: 0 }, now(), listing.message);
186
+ report.detail = listing.message;
187
+ return report;
188
+ }
189
+ if (!listing.complete)
190
+ capped = true;
191
+ report.candidates = listing.issues.length;
192
+ for (const issue of listing.issues) {
193
+ const existing = store.mirrorByRemote(grant.backend, remoteRepo, String(issue.number));
194
+ if (existing !== null)
195
+ continue;
196
+ if (grant.selector !== "all")
197
+ continue;
198
+ const localId = mirrorTaskId(remoteRepo, String(issue.number));
199
+ const filed = store.transact(() => {
200
+ const made = fileTaskProposal(store, { id: localId, title: issue.title, repo: grant.repo, filedVia: "sync" }, now());
201
+ if (!made.ok)
202
+ return made;
203
+ const established = store.establishMirror({
204
+ localTaskId: made.id,
205
+ backend: grant.backend,
206
+ remoteRepo,
207
+ remoteId: String(issue.number),
208
+ provenance: "granted-all",
209
+ establishedBy: "sync",
210
+ syncGeneration: pass.generation,
211
+ }, now());
212
+ if (!established.ok)
213
+ throw new Error(`mirror not established: ${established.reason}`);
214
+ return made;
215
+ });
216
+ if (filed.ok)
217
+ report.mirrored += 1;
218
+ // A title the validator refuses is NOT mirrored — the pass records it
219
+ // in detail and stays honest about the count.
220
+ else if (report.detail === null)
221
+ report.detail = `refused: ${filed.message}`;
222
+ }
223
+ // 4. Reverse: every known mirror, individually — absence from a listing
224
+ // proves nothing (finding 2).
225
+ let reverseFailed = null;
226
+ for (const mirror of store.externalMirrors(grant.backend, remoteRepo)) {
227
+ const seen = await adapter.getIssue(remoteRepo, mirror.remoteId);
228
+ if (!seen.ok) {
229
+ reverseFailed = seen.message;
230
+ break;
231
+ }
232
+ if (seen.found === null) {
233
+ store.latchMirror(mirror.localTaskId, "missing", pass.generation, now());
234
+ report.latched += 1;
235
+ }
236
+ else if (seen.found.state === "closed") {
237
+ store.latchMirror(mirror.localTaskId, "closed", pass.generation, now());
238
+ report.latched += 1;
239
+ }
240
+ else {
241
+ store.observeMirrorOpen(mirror.localTaskId, pass.generation);
242
+ }
243
+ }
244
+ if (reverseFailed !== null) {
245
+ store.closeSyncPass(pass.id, "failed", { candidates: report.candidates, mirrored: report.mirrored }, now(), reverseFailed);
246
+ report.detail = reverseFailed;
247
+ return report;
248
+ }
249
+ // 5. Intents, under the grant's classes exactly — a denial is a typed
250
+ // refusal on the intent's own ledger, never a run rewrite.
251
+ for (const intent of store.pendingExternalIntents()) {
252
+ const mirror = store.mirrorByTask(intent.mirror);
253
+ if (mirror === null || mirror.remoteRepo !== remoteRepo || mirror.backend !== grant.backend)
254
+ continue;
255
+ const allowed = intent.kind === "comment"
256
+ ? grant.mutations.includes("comment")
257
+ : intent.kind === "close"
258
+ ? grant.mutations.includes("close")
259
+ : grant.mutations.includes("transition");
260
+ if (!allowed) {
261
+ store.settleExternalIntent(intent.id, "refused", now(), `the grant does not allow ${intent.kind}`);
262
+ continue;
263
+ }
264
+ const sent = intent.kind === "comment"
265
+ ? await adapter.comment(remoteRepo, mirror.remoteId, intent.body ?? "")
266
+ : await adapter.close(remoteRepo, mirror.remoteId);
267
+ if (sent.ok) {
268
+ store.settleExternalIntent(intent.id, "delivered", now());
269
+ report.delivered += 1;
270
+ }
271
+ else {
272
+ store.settleExternalIntent(intent.id, "refused", now(), sent.message);
273
+ }
274
+ }
275
+ const outcome = capped ? "capped" : "complete";
276
+ store.closeSyncPass(pass.id, outcome, { candidates: report.candidates, mirrored: report.mirrored }, now(), report.detail);
277
+ report.outcome = outcome;
278
+ return report;
279
+ }
@@ -0,0 +1,13 @@
1
+ /** UI choices translate into the same digest-bound schedules as the CLI. */
2
+ import { type Schedule } from "./routine.js";
3
+ export declare function composerSchedule(fields: URLSearchParams): {
4
+ ok: true;
5
+ schedule: string | null;
6
+ } | {
7
+ ok: false;
8
+ message: string;
9
+ };
10
+ export declare function scheduleFields(schedule: Schedule): Record<string, string>;
11
+ /** A normal form works without JavaScript; enhancement only folds unused fields. */
12
+ export declare function scheduleEditorHtml(raw: string | null, submitted?: URLSearchParams): string;
13
+ export declare function scheduleEditorScript(): string;
@@ -0,0 +1,52 @@
1
+ /** UI choices translate into the same digest-bound schedules as the CLI. */
2
+ import { parseSchedule, scheduleText, validTimezone } from "./routine.js";
3
+ export function composerSchedule(fields) {
4
+ const repeat = fields.get("repeat") ?? "once";
5
+ if (repeat === "once")
6
+ return { ok: true, schedule: null };
7
+ if (!["daily", "weekly", "custom"].includes(repeat))
8
+ return { ok: false, message: "Choose how often this task repeats." };
9
+ if (repeat === "custom") {
10
+ const count = Number(fields.get("interval"));
11
+ const unit = fields.get("interval-unit");
12
+ const multiplier = unit === "minutes" ? 1 : unit === "hours" ? 60 : unit === "days" ? 1440 : 0;
13
+ if (!Number.isInteger(count) || count < 1 || multiplier === 0 || parseSchedule(`every:${count * multiplier}`) === null)
14
+ return { ok: false, message: "Choose an interval between 5 minutes and 7 days." };
15
+ return { ok: true, schedule: `every:${count * multiplier}` };
16
+ }
17
+ const time = fields.get("time") ?? "";
18
+ const timezone = fields.get("timezone") ?? "UTC";
19
+ if (!validTimezone(timezone))
20
+ return { ok: false, message: "Choose a valid timezone." };
21
+ const text = `${repeat === "weekly" ? `weekly:${fields.get("weekday") ?? ""}` : "daily"}:${time}@${timezone}`;
22
+ const schedule = parseSchedule(text);
23
+ return schedule === null ? { ok: false, message: "Choose a valid time and day for this task." } : { ok: true, schedule: scheduleText(schedule) };
24
+ }
25
+ export function scheduleFields(schedule) {
26
+ if (schedule.kind === "every") {
27
+ const unit = schedule.minutes % 1440 === 0 ? "days" : schedule.minutes % 60 === 0 ? "hours" : "minutes";
28
+ return { repeat: "custom", interval: String(schedule.minutes / (unit === "days" ? 1440 : unit === "hours" ? 60 : 1)), "interval-unit": unit };
29
+ }
30
+ return { repeat: schedule.kind, time: schedule.hhmm, timezone: schedule.timezone ?? "UTC", ...(schedule.kind === "weekly" ? { weekday: String(schedule.day) } : {}) };
31
+ }
32
+ const escape = (text) => text.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
33
+ /** A normal form works without JavaScript; enhancement only folds unused fields. */
34
+ export function scheduleEditorHtml(raw, submitted) {
35
+ const parsed = raw === null ? null : parseSchedule(raw);
36
+ const fields = submitted?.has("repeat") ? Object.fromEntries(submitted) : parsed === null ? {} : scheduleFields(parsed);
37
+ const repeat = fields.repeat ?? "daily";
38
+ const value = (name, fallback) => escape(fields[name] ?? fallback);
39
+ return `<fieldset data-schedule-editor${raw === null && submitted === undefined ? ' data-detect-timezone="true"' : ""}><legend>When to run</legend>` +
40
+ `<label>Repeat<select name="repeat">${[["daily", "Daily"], ["weekly", "Weekly"], ["custom", "Custom interval"]].map(([id, label]) => `<option value="${id}"${repeat === id ? " selected" : ""}>${label}</option>`).join("")}</select></label>` +
41
+ `<div data-schedule-kind="weekly"><label>Day<select name="weekday">${["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"].map((day, index) => `<option value="${index}"${String(index) === (fields.weekday ?? "1") ? " selected" : ""}>${day}</option>`).join("")}</select></label></div>` +
42
+ `<div data-schedule-kind="calendar"><label>Time<input type="time" name="time" value="${value("time", "09:00")}"></label><label>Timezone<input type="text" name="timezone" value="${value("timezone", "UTC")}" autocomplete="off" placeholder="America/Los_Angeles"></label><p class="meta">Daily and weekly times follow this timezone. A skipped clock time skips that occurrence; a repeated time runs once.</p></div>` +
43
+ `<div data-schedule-kind="custom"><label>Every<input type="number" name="interval" min="1" value="${value("interval", "60")}"></label><label>Unit<select name="interval-unit">${["minutes", "hours", "days"].map(unit => `<option${unit === (fields["interval-unit"] ?? "minutes") ? " selected" : ""}>${unit}</option>`).join("")}</select></label><p class="meta">Intervals range from 5 minutes to 7 days.</p></div></fieldset>`;
44
+ }
45
+ export function scheduleEditorScript() {
46
+ return `(function(){document.querySelectorAll('[data-schedule-editor]').forEach(function(root){
47
+ var repeat=root.querySelector('[name=repeat]'),zone=root.querySelector('[name=timezone]');
48
+ if(root.dataset.detectTimezone==='true'){try{zone.value=Intl.DateTimeFormat().resolvedOptions().timeZone||'UTC';}catch(e){}}
49
+ function update(){root.querySelectorAll('[data-schedule-kind]').forEach(function(group){var active=group.dataset.scheduleKind===repeat.value||(group.dataset.scheduleKind==='calendar'&&repeat.value!=='custom');group.hidden=!active;group.querySelectorAll('input,select').forEach(function(field){field.disabled=!active;});});}
50
+ repeat.addEventListener('change',update);update();
51
+ });})();`;
52
+ }
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Safe task stop and resume (v52): the ONE domain API every surface — the
3
+ * CLI, the authenticated console, the focused chat — speaks, and the fences
4
+ * every execution road consults.
5
+ *
6
+ * The contract, in the operator's words: a stop names one exact active
7
+ * attempt. The first answer is "stop requested", never "stopped" — the
8
+ * request is durable before any process is signalled, and the attempt is
9
+ * SETTLED only once all owned runs ended and retained process witnesses
10
+ * establish exit. A dead worker can leave live subprocesses; recovery
11
+ * keeps that stop pending. Other tasks keep running. The task stays
12
+ * paused across restarts under a hold this stop owns, beside — never over —
13
+ * any hold that already stood. Resume names the same exact attempt, refuses
14
+ * until it is quiescent, lifts only that hold, approves nothing, and lets
15
+ * the next pass re-prove the signed scope, take a fresh claim, and inherit
16
+ * the preserved draft with fresh proof.
17
+ *
18
+ * Nothing here is a second engine: the stop rides the existing run, claim,
19
+ * hold, recovery, invocation-gateway, and held-session machinery. This
20
+ * module only names the door and the fence.
21
+ */
22
+ import { type DispatchDiagnosis } from "./dispatch.js";
23
+ import type { Run, RunStop, Store } from "./store.js";
24
+ /** How often a running attempt re-reads its stop row while a child runs.
25
+ * A stop is observed within this bound even when the console that filed
26
+ * it lives in another process on the same database. */
27
+ export declare const STOP_WATCH_MS = 1500;
28
+ /**
29
+ * The stop fence, as a predicate: an operator stop applies to the run (its
30
+ * own, or an owning ancestor's), or the caller's own watch-level stop says
31
+ * so. Every road that used to ask `shouldStop?.()` asks this instead.
32
+ */
33
+ export declare function stopRequestedFor(store: Store, runId: number, also?: () => boolean): boolean;
34
+ /** The words a road records when a stop wins: who asked, and where the
35
+ * work stays. */
36
+ export declare function stopWords(store: Store, runId: number, worktree: string | null, fallback: string): string;
37
+ /**
38
+ * End every live child THIS process holds for one attempt and its owned
39
+ * descendants — the exact-attempt handle, never a pid read from durable
40
+ * state. Returns how many process groups were signalled.
41
+ */
42
+ export declare function terminateStoppedAttempt(store: Store, runId: number): number;
43
+ /** Whether this process still tracks a live child for the attempt or any
44
+ * run it owns — the in-process half of "quiescent". */
45
+ export declare function attemptHasLiveChildren(store: Store, runId: number): boolean;
46
+ /**
47
+ * Run a child-bearing step under the stop watch: while `body` runs, the
48
+ * run's stop row is re-read every `intervalMs`; the moment a stop applies
49
+ * the run's owned children are killed through their handles and the
50
+ * caller's `onStop` fires once. The body's own settlement then observes
51
+ * the stop through `stopRequestedFor` and seals the attempt as
52
+ * interrupted — this watch never writes an outcome itself.
53
+ */
54
+ export declare function underStopWatch<T>(store: Store, runId: number, body: () => Promise<T>, options?: {
55
+ intervalMs?: number;
56
+ onStop?: () => void;
57
+ }): Promise<T>;
58
+ export type StopRequest = {
59
+ taskId: string;
60
+ runId: number;
61
+ by: string;
62
+ via: "cli" | "web" | "telegram" | "slack" | "discord" | "teams";
63
+ /** The held-session supervisor in this process, when there is one: a
64
+ * held attempt is fenced through its own handle the moment the request
65
+ * is durable (the lapse interval would take the same road within
66
+ * seconds for a request filed elsewhere). */
67
+ held?: {
68
+ stop(runId: number): Promise<void>;
69
+ } | undefined;
70
+ /** A composing confirmation transaction runs this effect only after it commits. */
71
+ deferSignal?: ((signal: () => void) => void) | undefined;
72
+ };
73
+ export type StopOutcome = {
74
+ ok: true;
75
+ stop: RunStop;
76
+ repeated: boolean;
77
+ terminated: number;
78
+ taskId: string;
79
+ } | {
80
+ ok: false;
81
+ reason: "no-task" | "no-run" | "wrong-task" | "finished" | "not-live" | "tournament" | "publication";
82
+ detail: string;
83
+ };
84
+ /**
85
+ * The shared stop door. Records the durable request first (one fenced
86
+ * transaction: exact run, still open, this task's current claim, no
87
+ * tournament, no admitted publication), THEN signals every child this
88
+ * process holds for the attempt. A worker in another process observes the
89
+ * same row through its stop watch within STOP_WATCH_MS.
90
+ */
91
+ export declare function requestTaskStop(store: Store, request: StopRequest, now: Date): StopOutcome;
92
+ export type ResumeRequest = {
93
+ taskId: string;
94
+ runId: number;
95
+ by: string;
96
+ via: "cli" | "web";
97
+ /** The workspace occupancy probe (the worktree pool's `inUse`): a
98
+ * checkout some process still holds is not quiescent, whatever the
99
+ * rows say — the concrete gate names the pid. */
100
+ occupied?: (worktree: string) => {
101
+ held: boolean;
102
+ by?: number | string | undefined;
103
+ };
104
+ };
105
+ export type ResumeOutcome = {
106
+ ok: true;
107
+ stop: RunStop;
108
+ taskId: string;
109
+ gate: DispatchDiagnosis | null;
110
+ } | {
111
+ ok: false;
112
+ reason: "no-task" | "no-stop" | "wrong-task" | "stopping" | "already-resumed" | "superseded" | "busy" | "review" | "occupied";
113
+ detail: string;
114
+ };
115
+ /**
116
+ * The shared resume door. Refuses in words until the exact stopped attempt
117
+ * is quiescent — settled, every owned run ended, no live claim, its
118
+ * workspace not held by any process this machine can still see — then
119
+ * lifts exactly this stop's hold. `gate` reports what still keeps the
120
+ * next pass from starting work (an approval that must be signed again, a
121
+ * worker that is offline), so a resume that cannot yet start is never
122
+ * mistaken for one that did. A stopped review is refused here and pointed
123
+ * at the explicit bounded review-retry door.
124
+ */
125
+ export declare function resumeTaskStop(store: Store, request: ResumeRequest, now: Date): ResumeOutcome;
126
+ /**
127
+ * What a surface shows for one task (v52) — the SAME projection on the
128
+ * task page, the focused chat, `task show`, and the status fragment, so no
129
+ * two surfaces can disagree about which exact run a control names:
130
+ *
131
+ * stop — an attempt is live; the control names its run.
132
+ * stopping — a stop is recorded and not yet settled.
133
+ * paused — a settled stop stands on the task's newest attempt.
134
+ * review-stopped — a review attempt was stopped; "Review again" is the
135
+ * explicit bounded retry door.
136
+ * none — nothing to control.
137
+ */
138
+ export type TaskControlView = {
139
+ kind: "none";
140
+ } | {
141
+ kind: "stop";
142
+ run: number;
143
+ role: Run["role"];
144
+ } | {
145
+ kind: "stopping";
146
+ run: number;
147
+ role: Run["role"];
148
+ stop: RunStop;
149
+ unsettledRun: boolean;
150
+ detail?: string | null;
151
+ } | {
152
+ kind: "paused";
153
+ run: number;
154
+ role: Run["role"];
155
+ stop: RunStop;
156
+ outcome: Run["outcome"];
157
+ committed: boolean;
158
+ worktree: string | null;
159
+ } | {
160
+ kind: "review-stopped";
161
+ run: number;
162
+ sourceRun: number | null;
163
+ stop: RunStop;
164
+ };
165
+ export declare function taskControlOf(store: Store, taskRef: number, now: Date): TaskControlView;