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
@@ -0,0 +1,14 @@
1
+ import { type PhoneTaskLink } from "./telegram-status.js";
2
+ import type { Run, Store } from "./store.js";
3
+ /** Offsets are UTF-16, as required by Telegram. Only our two headings are bold;
4
+ * user text stays literal, including angle brackets and Markdown characters. */
5
+ export type ProgressEntity = {
6
+ type: "bold";
7
+ offset: number;
8
+ length: number;
9
+ };
10
+ export declare function telegramProgressCard(store: Store, run: Run, taskId: string, project: string, now?: Date, root?: string): {
11
+ text: string;
12
+ entities: ProgressEntity[];
13
+ link: PhoneTaskLink;
14
+ };
@@ -0,0 +1,129 @@
1
+ /** A compact projection of saved work, never a percentage or an ETA. The
2
+ * words come from the same assignment record the console and the CLI show:
3
+ * a finished build is Ready once its saved result can be inspected, and
4
+ * Complete once the lead or a person has marked that exact result. No model
5
+ * reviewer is waited for or announced. */
6
+ import { manualReviewOnly } from "./proof.js";
7
+ import { assignmentOf } from "./assignment.js";
8
+ import { chatResultHref, chatControlHref } from "./chat-controls.js";
9
+ import { phoneText, projectLabel } from "./telegram-status.js";
10
+ /** The saved assignment for this exact result, or null when the run is not
11
+ * the family's current result (an older attempt keeps its own plain words). */
12
+ function assignmentFor(store, run, taskId, project, now, root) {
13
+ try {
14
+ const assignment = assignmentOf(store, taskId, now, { principal: "operator", repos: [project] }, root);
15
+ return assignment !== null && assignment.receipt?.runId === run.id ? assignment : null;
16
+ }
17
+ catch {
18
+ return null;
19
+ }
20
+ }
21
+ export function telegramProgressCard(store, run, taskId, project, now = new Date(), root) {
22
+ const proof = store.proofVerdictFor(run.id);
23
+ const rows = proof?.matrix ?? [];
24
+ const direct = rows.length > 0 && rows.every(row => row.assessment !== undefined);
25
+ const passed = rows.filter(row => row.state === "pass").length;
26
+ const human = manualReviewOnly(proof);
27
+ const accepted = store.proofAcceptance(run.id) !== null;
28
+ const built = run.finishedAt !== null && (run.outcome === "built" || run.outcome === "no-change");
29
+ const assignment = built ? assignmentFor(store, run, taskId, project, now, root) : null;
30
+ const checksFailed = assignment?.receipt?.checks.status === "failed";
31
+ let status = "Working";
32
+ let icon = "⏳";
33
+ let next = "";
34
+ let build = built ? "✓ Build saved" : "● Build in progress";
35
+ let checks = rows.length ? `${passed === rows.length ? "✓" : "○"} Checks · ${passed}/${rows.length} requirements` : "○ Checks pending";
36
+ if (direct)
37
+ checks = proof?.machineVerdict === "verified" ? "✓ Checks passed" : proof?.machineVerdict === "attested" ? "○ Checks not configured" : "! Checks need attention";
38
+ let label = built ? "Open result" : "Open task";
39
+ if (run.outcome === null && run.phase !== null && run.phase !== "agent-running") {
40
+ status = "Checking the result";
41
+ build = "✓ Draft prepared";
42
+ checks = "● Checks in progress";
43
+ }
44
+ if (built) {
45
+ status = run.committed === false ? "Finished without a commit" : "Result saved";
46
+ if (proof === null)
47
+ checks = "○ Checks not recorded";
48
+ const recorded = assignment?.receipt?.checks;
49
+ if (recorded !== undefined && recorded.status !== "unavailable") {
50
+ checks = recorded.status === "passed" ? "✓ Checks passed"
51
+ : recorded.status === "failed" ? `! Checks failed${recorded.exitCode === null ? "" : ` (exit ${recorded.exitCode})`}`
52
+ : "○ Checks did not run";
53
+ }
54
+ if (assignment?.state === "ready-to-check") {
55
+ status = "Ready";
56
+ icon = checksFailed ? "⚠️" : "✅";
57
+ next = checksFailed ? "Next: inspect the failed check, then mark it complete or request changes." : "Next: open the result, then mark it complete or request changes.";
58
+ }
59
+ else if (assignment?.state === "complete") {
60
+ status = "Complete";
61
+ icon = "✅";
62
+ next = phoneText(assignment.detail, 200);
63
+ }
64
+ else if (assignment?.state === "needs-decision") {
65
+ status = "Needs your decision";
66
+ icon = "💬";
67
+ next = phoneText(assignment.detail, 200);
68
+ }
69
+ else if (assignment?.state === "cancelled") {
70
+ status = "Cancelled";
71
+ icon = "⏹";
72
+ }
73
+ else if (assignment !== null) {
74
+ next = phoneText(assignment.detail, 200);
75
+ }
76
+ else if (run.committed !== false) {
77
+ next = "Open the task for its current status.";
78
+ }
79
+ }
80
+ else if (run.outcome !== null) {
81
+ status = run.outcome === "parked" ? "Decision needed" : run.outcome === "interrupted" || run.reason === "interrupted" ? "Stopped" : "Build needs attention";
82
+ icon = run.outcome === "parked" ? "💬" : "⏸";
83
+ build = "! Build unfinished";
84
+ next = "Next: inspect the blocker.";
85
+ label = "Open task";
86
+ }
87
+ const stop = store.stopOf(run.id);
88
+ if (run.outcome === null && stop !== null && stop.resumedAt === null) {
89
+ status = stop.settledAt === null ? "Stopping" : "Stopped";
90
+ icon = "⏸";
91
+ build = stop.settledAt === null ? "● Build stopping" : "! Build stopped";
92
+ next = stop.settledAt === null ? "Waiting for the running process to stop." : "Next: inspect the saved work, then resume.";
93
+ }
94
+ const holds = store.activeHolds(run.taskRef, now);
95
+ const operatorHold = holds.find(hold => hold.ownerKind === "operator");
96
+ const accessBlocked = run.reason === "retryable-infra" && /^could not re-read (?:the branch|HEAD) in /i.test(run.handoff ?? "");
97
+ if (accessBlocked) {
98
+ status = "Worker needs project access";
99
+ icon = "⏸";
100
+ next = "Next: restore the worker’s folder access, then resume.";
101
+ label = "Open task";
102
+ }
103
+ if (operatorHold) {
104
+ icon = "⏸";
105
+ if (!accessBlocked) {
106
+ status = run.outcome === null ? "Working · Next attempt paused" : "Paused";
107
+ next = phoneText(operatorHold.reason, 150);
108
+ }
109
+ label = "Open task";
110
+ }
111
+ else if (accessBlocked && holds.some(hold => hold.ownerKind === "backoff")) {
112
+ next = "The worker will retry after a short pause. Check its folder access.";
113
+ }
114
+ const checkProgress = store.checkProgress(run.id);
115
+ if (checkProgress !== null)
116
+ checks = checkProgress.line;
117
+ const publication = store.publicationForRun(run.id);
118
+ const delivery = publication?.remoteState === "MERGED" ? "Merged · Installation not confirmed" : publication?.remoteState === "CLOSED" ? "Pull request closed without merging" : publication?.state === "opened" ? "Pull request open · Not merged" : publication?.state === "pushed" ? "Branch pushed · Pull request pending" : publication?.state === "intended" ? "Publication queued" : publication?.state === "failed" ? "Publication failed · Local result preserved" : built ? "Saved locally · Not published" : null;
119
+ const acceptance = accepted ? (human ? "Accepted by a person · Recorded checks unchanged" : "Accepted with an exception · Recorded checks unchanged") : null;
120
+ const title = phoneText(store.getTask(taskId)?.title ?? taskId, 88);
121
+ const heading = `${icon} ${status}`;
122
+ const text = [title, heading, "", build, checks,
123
+ ...(next ? ["", next] : []),
124
+ ...(acceptance === null ? [] : [acceptance]),
125
+ ...(delivery === null ? [] : ["", delivery]), "", `${projectLabel(project)} · #${run.id}`].join("\n");
126
+ return { text, entities: [{ type: "bold", offset: 0, length: title.length }, { type: "bold", offset: title.length + 1, length: heading.length }],
127
+ link: { label, path: operatorHold || accessBlocked || (!built && run.outcome !== null)
128
+ ? chatControlHref("recovery", taskId) : built ? chatResultHref(taskId, run.id, checksFailed ? "checks" : "summary") : chatControlHref("task", taskId) } };
129
+ }
@@ -0,0 +1,9 @@
1
+ /** The person's own Telegram pairing, from the console: one private chat per
2
+ * teammate with the installation's bot (v72). The bot token itself stays on
3
+ * the settings page; this card only mints or revokes the signed-in person's
4
+ * pairing, never anyone else's. */
5
+ import type { Store } from "./store.js";
6
+ export declare function telegramSettingsHtml(store: Store, botId: string | null, who: string, csrf: string, options?: {
7
+ code?: string;
8
+ problem?: string;
9
+ }): string;
@@ -0,0 +1,36 @@
1
+ const escape = (text) => text
2
+ .replaceAll("&", "&")
3
+ .replaceAll("<", "&lt;")
4
+ .replaceAll(">", "&gt;")
5
+ .replaceAll('"', "&quot;")
6
+ .replaceAll("'", "&#39;");
7
+ export function telegramSettingsHtml(store, botId, who, csrf, options = {}) {
8
+ const hidden = `<input type="hidden" name="csrf" value="${escape(csrf)}">`;
9
+ const password = '<label>Your Toolroll password<input style="min-height:44px" type="password" name="password" autocomplete="current-password" required></label>';
10
+ const post = (action, content) => `<form method="post" action="/settings/telegram/${action}" class="card">${hidden}${content}</form>`;
11
+ let content = "";
12
+ if (botId === null) {
13
+ content = '<p>No Telegram bot is connected yet. An installation approver saves the bot token on the <a href="/settings">settings page</a> first.</p>';
14
+ }
15
+ else {
16
+ const bindings = store.liveTelegramBindings(botId);
17
+ const mine = bindings.filter(binding => binding.approver === who);
18
+ const others = bindings.length - mine.length;
19
+ content = `<p><strong>${mine.length > 0 ? "Your phone is paired." : "Your phone is not paired."}</strong> ${others === 0 ? "No teammates are paired yet." : `${others} teammate${others === 1 ? " is" : "s are"} paired.`}</p>`;
20
+ if (options.code !== undefined) {
21
+ content +=
22
+ "<h2>Pair your phone</h2><p>Send this to the bot in a private Telegram chat within 10 minutes:</p>" +
23
+ `<pre class="pairing-code">/pair ${escape(options.code)}</pre>` +
24
+ '<p class="meta">The code works once. That chat then answers as you, so treat it like your sign-in.</p>';
25
+ }
26
+ else if (mine.length === 0) {
27
+ content += post("pair", password + '<button type="submit">Pair my phone</button>');
28
+ }
29
+ else {
30
+ content += post("unpair", password + '<p class="meta">This phone will lose access. Its existing Telegram buttons will stop working.</p><button type="submit" class="danger">Unpair my phone</button>');
31
+ }
32
+ }
33
+ if (options.problem !== undefined)
34
+ content = `<p role="status">${escape(options.problem)}</p>` + content;
35
+ return `<h1>Telegram</h1>${content}<p class="meta">Each teammate pairs their own private chat. To connect a group, a conversation manager sends <code>/team</code> there and chooses a conversation. Everyone in the group can read its replies.</p>`;
36
+ }
@@ -0,0 +1,75 @@
1
+ import { publicChatText } from './chat-display.js';
2
+ import type { Notification, Store } from "./store.js";
3
+ export type PhoneCommand = {
4
+ kind: "status";
5
+ } | {
6
+ kind: "help";
7
+ } | {
8
+ kind: "task";
9
+ id: string;
10
+ } | {
11
+ kind: "tasks";
12
+ } | {
13
+ kind: "lead";
14
+ };
15
+ export declare function phoneCommand(text: string): PhoneCommand | null;
16
+ export declare const PHONE_HELP: string;
17
+ /** The same display scrub for every phone-bound string a person or a model authored. */
18
+ export declare const phoneText: typeof publicChatText;
19
+ export declare function projectLabel(repo: string): string;
20
+ /** repos is the transport's explicit enrollment ceiling, never opened-project
21
+ * history. This snapshot is intentionally bounded and advertises that bound. */
22
+ export declare function phoneStatus(store: Store, repos: readonly string[], now: Date, focused?: string | null): string;
23
+ /** One task a person can pick to talk about from a chat app. */
24
+ export type PhoneTaskChoice = {
25
+ id: string;
26
+ title: string;
27
+ label: string;
28
+ group: string;
29
+ };
30
+ /** The tasks a paired chat can pick from: what needs the person first,
31
+ * then work in progress, waiting work and recent results; one entry per
32
+ * task (its revisions share it), optionally narrowed by words in the id or
33
+ * title. Bounded, within the chat's own project ceiling. */
34
+ export declare function phoneTaskChoices(store: Store, repos: readonly string[], now: Date, query?: string | null, limit?: number): PhoneTaskChoice[];
35
+ /** `id` keys the chat's choice (the task's first version, where its chat
36
+ * lives); `view` is what to show: the exact version named, else the current one. */
37
+ export type PhoneTaskPick = {
38
+ kind: "one";
39
+ id: string;
40
+ view: string;
41
+ title: string;
42
+ } | {
43
+ kind: "many";
44
+ choices: PhoneTaskChoice[];
45
+ } | {
46
+ kind: "none";
47
+ };
48
+ /** `/task <what>`: an exact task id, a number from the /tasks list, or
49
+ * words from a title — one match is chosen, several are offered. */
50
+ export declare function resolvePhoneTask(store: Store, repos: readonly string[], now: Date, query: string): PhoneTaskPick;
51
+ /** The picker as text, for chat apps without buttons. */
52
+ export declare function phoneTaskListText(choices: readonly PhoneTaskChoice[], focused: string | null): string;
53
+ /** Said under a task's status when a chat app chooses it. */
54
+ export declare const PHONE_FOCUS_LINE = "Talking about this task now: ask anything or say what to change. Reply to this message later to come back to it; /lead goes back to the lead.";
55
+ /** A chosen task's status, then the line that says the chat now talks about it. */
56
+ export declare function phoneFocusText(view: string): string;
57
+ export declare const PHONE_NO_MATCH = "No such task in your connected projects. Send /tasks to pick one.";
58
+ export declare const PHONE_BACK_TO_LEAD = "Back to the lead. Your messages here are about all your work again.";
59
+ /** A fixed console destination for one task, named beside its label; the origin joins it only on the wire. */
60
+ export type PhoneTaskLink = {
61
+ label: string;
62
+ path: string;
63
+ };
64
+ /** Where the rest lives when no button can say so: the closing line of an unlinked `/task`. */
65
+ export declare const PHONE_CONSOLE_FOOTER = "Read-only status. Saved files and full actions are in the console.";
66
+ export declare function phoneTask(store: Store, repos: readonly string[], id: string, now: Date): string;
67
+ /** One task's status for a chat app: the words, its one console link, and
68
+ * the saved result it shows (a reply to it is about that result). */
69
+ export declare function phoneTaskView(store: Store, repos: readonly string[], id: string, now: Date): {
70
+ text: string;
71
+ link: PhoneTaskLink | null;
72
+ run: number | null;
73
+ };
74
+ /** Concise display only: authorization uses the stored full project identity. */
75
+ export declare function notificationIdentity(row: Pick<Notification, "project" | "taskId">): string;
@@ -0,0 +1,265 @@
1
+ import { publicChatText } from './chat-display.js';
2
+ import { manualReviewOnly } from "./proof.js";
3
+ /** Read-only phone views over the same dispatch and proof records as chat.
4
+ * No provider calls, repository access, new workflow state, or inferred success. */
5
+ import { diagnoseTaskDispatch, withDispatchDiagnoses } from "./dispatch.js";
6
+ import { CHAT_CONTROLS, chatControlHref, chatResultHref } from "./chat-controls.js";
7
+ export function phoneCommand(text) {
8
+ // Slash forms everywhere; the bare words too, because Slack and Discord
9
+ // keep unregistered slash text for themselves. Only a whole message that
10
+ // is exactly the command counts — prose never is.
11
+ const t = text.trim();
12
+ if (/^\/?(?:help|start)$/i.test(t))
13
+ return { kind: "help" };
14
+ if (/^\/?status$/i.test(t))
15
+ return { kind: "status" };
16
+ // The picker: /tasks (or /task alone) lists them to choose from; /lead
17
+ // goes back to the lead conversation.
18
+ if (/^\/?tasks?$/i.test(t))
19
+ return { kind: "tasks" };
20
+ if (/^\/?lead$/i.test(t))
21
+ return { kind: "lead" };
22
+ // An id, a number from the list, or words from the title.
23
+ const task = /^\/?task\s+([A-Za-z0-9][A-Za-z0-9 ._'-]{0,63})$/i.exec(t);
24
+ if (task !== null)
25
+ return { kind: "task", id: task[1].trim() };
26
+ // A mistyped slash command gets help, but arbitrary prose is not a command.
27
+ return /^\/(?:status|tasks?|lead|help|start)(?:\s|$)/i.test(t) ? { kind: "help" } : null;
28
+ }
29
+ export const PHONE_HELP = [
30
+ "Toolroll in chat",
31
+ "",
32
+ "Say what you want in plain words: ask how something is going, ask for a change, or describe new work. The lead answers here and shows a card before anything changes; nothing changes until you act.",
33
+ "",
34
+ "Reply to any message about a task (an update, a result, a status or the lead's answer) to talk about that task.",
35
+ "",
36
+ "/tasks — pick a task to talk about",
37
+ "/task <name or number> — the same, by a word from its name",
38
+ "/lead — back to talking about everything",
39
+ "/status — what's happening across your projects",
40
+ "/team — team conversations; /team <number> to talk in one, /team off to leave",
41
+ "/help — this message",
42
+ "",
43
+ "To answer an agent's question, tap its buttons; reply to the question to add a note. Approvals that need your password, cancelling and publishing finish in the Toolroll console, and a console button only takes you there. The computer must be awake and connected to reply.",
44
+ ].join("\n");
45
+ /** A third-party transport receives a small display copy, not logs, paths,
46
+ * credentials, or arbitrary markup. Scan BEFORE truncation/normalization. */
47
+ const plain = publicChatText;
48
+ /** The same display scrub for every phone-bound string a person or a model authored. */
49
+ export const phoneText = plain;
50
+ export function projectLabel(repo) {
51
+ return plain(repo.split(/[\\/]/).filter(Boolean).pop() ?? "project", 48);
52
+ }
53
+ function groupOf(d) {
54
+ if (d.condition === "running")
55
+ return "Working";
56
+ if (d.code === "cancelled")
57
+ return "Cancelled";
58
+ if (d.code === "complete")
59
+ return "Finished";
60
+ if (d.code === "review-pending" || d.action === null)
61
+ return "Waiting / next up";
62
+ return "Needs attention";
63
+ }
64
+ function nextStep(d) {
65
+ if (d.code === "review-pending")
66
+ return "An older review request is on record; nothing runs for it. Open the saved result in the console.";
67
+ switch (d.action) {
68
+ case "open-result": return "Open this task's result in the console, inspect it, then mark it complete or request changes.";
69
+ case "retry-task": return "Open this task in the console, review why it stopped, and use the available retry action.";
70
+ case "place-task": return "Choose a project for this task in the console.";
71
+ case "write-scope": return "Describe the goal and success checks in the console, or ask the planner to draft them.";
72
+ case "select-agent": return "Open this task in the console and check its agent settings or provider availability.";
73
+ case "approve-scope": return "Read the proposed work in the console and approve it if it is right.";
74
+ case "answer-decision": return "Answer the waiting question using its decision buttons or the console.";
75
+ case "unhold": return "Open this task in the console and release its hold when you want it to continue.";
76
+ case "inspect-hold": return "Open this task in the console to see what must change before it can continue.";
77
+ case "repair-dependency": return "Open this task in the console. Retry the required task, choose a different task to wait for, or explicitly stop waiting for it.";
78
+ case "repair-capability": return "Open this task's requirements in the console and fix the named setup issue.";
79
+ case "start-worker": return "Reopen Toolroll on the computer and finish any project-access setup. Approved work can resume when the builder reconnects.";
80
+ case "retry-review": return "Open the saved result in the console. Nothing reruns a review; mark the result complete or request changes.";
81
+ case "resume-run": return "Open this task in the console and choose Resume after its stopped attempt has finished stopping.";
82
+ case null: return d.condition === "running" ? "No action needed from you right now." : d.code === "cancelled" ? "Nothing else will run for this task." : "Toolroll can reconsider this task when its waiting condition clears.";
83
+ }
84
+ }
85
+ /** repos is the transport's explicit enrollment ceiling, never opened-project
86
+ * history. This snapshot is intentionally bounded and advertises that bound. */
87
+ export function phoneStatus(store, repos, now, focused = null) {
88
+ if (repos.length === 0)
89
+ return "No connected projects are available to this bridge. Add a project in Toolroll, then send /status again.";
90
+ return store.transact(() => {
91
+ const snapshot = withDispatchDiagnoses(store, store.chatSnapshot(repos, now), now);
92
+ const lines = [...(focused === null ? [] : [`Talking about: ${focused} · /lead to switch back`, ""]), "Recent work", `As of ${now.toISOString().replace("T", " ").slice(0, 19)} UTC · ${repos.length} project(s)`, ""];
93
+ if (snapshot.tasksSaturated)
94
+ lines.push("Newest 60 tasks only — older work may still need attention.", "");
95
+ if (snapshot.tasks.length === 0)
96
+ lines.push("No tasks are recorded in these projects.");
97
+ for (const group of ["Needs attention", "Working", "Waiting / next up", "Finished", "Cancelled"]) {
98
+ const rows = snapshot.tasks.filter(t => t.dispatch !== null && t.dispatch !== undefined && groupOf(t.dispatch) === group);
99
+ if (rows.length === 0)
100
+ continue;
101
+ lines.push(`${group} · ${rows.length}${snapshot.tasksSaturated ? " in this snapshot" : ""}`);
102
+ for (const task of rows.slice(0, 2)) {
103
+ lines.push(`${plain(task.id, 64)} · ${projectLabel(repos[task.repoIndex])}`, ` ${plain(task.title, 64)} — ${plain(task.dispatch.summary, 80)}`);
104
+ }
105
+ if (rows.length > 2)
106
+ lines.push(` +${rows.length - 2} more in the console`);
107
+ lines.push("");
108
+ }
109
+ lines.push("Send /tasks to pick one, or /task <name> for its next step. Status is a snapshot, not a promise that the next attempt will succeed.");
110
+ return lines.join("\n");
111
+ });
112
+ }
113
+ const PICK_GROUPS = ["Needs attention", "Working", "Waiting / next up", "Finished"];
114
+ /** The tasks a paired chat can pick from: what needs the person first,
115
+ * then work in progress, waiting work and recent results; one entry per
116
+ * task (its revisions share it), optionally narrowed by words in the id or
117
+ * title. Bounded, within the chat's own project ceiling. */
118
+ export function phoneTaskChoices(store, repos, now, query = null, limit = 8) {
119
+ if (repos.length === 0)
120
+ return [];
121
+ return store.transact(() => {
122
+ const snapshot = withDispatchDiagnoses(store, store.chatSnapshot(repos, now), now);
123
+ const words = query === null ? [] : query.toLowerCase().split(/\s+/).filter(Boolean);
124
+ const rows = snapshot.tasks
125
+ .filter(one => one.dispatch !== null && one.dispatch !== undefined && PICK_GROUPS.includes(groupOf(one.dispatch)))
126
+ .sort((a, b) => PICK_GROUPS.indexOf(groupOf(a.dispatch)) - PICK_GROUPS.indexOf(groupOf(b.dispatch)) || a.ageHours - b.ageHours);
127
+ const seen = new Set();
128
+ const choices = [];
129
+ for (const row of rows) {
130
+ const id = row.rootId ?? row.id;
131
+ if (seen.has(id) || !words.every(word => `${id} ${row.title}`.toLowerCase().includes(word)))
132
+ continue;
133
+ seen.add(id);
134
+ choices.push({ id, title: plain(row.title, 64), label: plain(row.dispatch.summary, 48), group: groupOf(row.dispatch) });
135
+ if (choices.length >= limit)
136
+ break;
137
+ }
138
+ return choices;
139
+ });
140
+ }
141
+ /** `/task <what>`: an exact task id, a number from the /tasks list, or
142
+ * words from a title — one match is chosen, several are offered. */
143
+ export function resolvePhoneTask(store, repos, now, query) {
144
+ const ref = store.lookupRef(query);
145
+ if (ref?.repo != null && repos.includes(ref.repo)) {
146
+ const root = store.taskFamilyOf(query, repos, false)?.root ?? null;
147
+ return { kind: "one", id: root?.id ?? query, view: query, title: plain(root?.title ?? store.getTask(query)?.title ?? query, 64) };
148
+ }
149
+ const chosen = (one) => ({ kind: "one", id: one.id, view: store.taskFamilyOf(one.id, repos, false)?.current.id ?? one.id, title: one.title });
150
+ if (/^\d{1,2}$/.test(query)) {
151
+ const pick = phoneTaskChoices(store, repos, now)[Number(query) - 1];
152
+ return pick === undefined ? { kind: "none" } : chosen(pick);
153
+ }
154
+ const matches = phoneTaskChoices(store, repos, now, query);
155
+ return matches.length === 0 ? { kind: "none" } : matches.length === 1 ? chosen(matches[0]) : { kind: "many", choices: matches };
156
+ }
157
+ /** The picker as text, for chat apps without buttons. */
158
+ export function phoneTaskListText(choices, focused) {
159
+ if (choices.length === 0)
160
+ return "No open or recent tasks in your connected projects. Describe what you want done and the lead will draft one.";
161
+ return [
162
+ ...(focused === null ? [] : [`Talking about: ${focused}`, ""]),
163
+ "Your tasks",
164
+ ...choices.map((one, index) => `${index + 1}. ${one.title} — ${one.label}`),
165
+ "",
166
+ "Send /task <number or name> to talk about one. /lead goes back to the lead.",
167
+ ].join("\n");
168
+ }
169
+ /** Said under a task's status when a chat app chooses it. */
170
+ export const PHONE_FOCUS_LINE = "Talking about this task now: ask anything or say what to change. Reply to this message later to come back to it; /lead goes back to the lead.";
171
+ /** A chosen task's status, then the line that says the chat now talks about it. */
172
+ export function phoneFocusText(view) {
173
+ return `${view}\n\n${PHONE_FOCUS_LINE}`;
174
+ }
175
+ export const PHONE_NO_MATCH = "No such task in your connected projects. Send /tasks to pick one.";
176
+ export const PHONE_BACK_TO_LEAD = "Back to the lead. Your messages here are about all your work again.";
177
+ /** Where the rest lives when no button can say so: the closing line of an unlinked `/task`. */
178
+ export const PHONE_CONSOLE_FOOTER = "Read-only status. Saved files and full actions are in the console.";
179
+ /**
180
+ * Where `/task`'s one button goes, from the recorded diagnosis: the exact
181
+ * saved result's checks (a recorded verdict) or changes (none yet) for a
182
+ * finished task; the approval control while the scope waits; the task's
183
+ * own page for retry, hold, dependency and resume ceremonies; the task lens
184
+ * otherwise (a worker that must be started is not a browser step, and the
185
+ * lens says so). Only a task inside the phone's ceiling gets here.
186
+ */
187
+ function taskLinkFor(id, d, result) {
188
+ const control = (name) => ({ label: CHAT_CONTROLS[name].label, path: chatControlHref(name, id) });
189
+ if (result !== null)
190
+ return result.verdict ? { label: "Open checks", path: chatResultHref(id, result.run, "checks") } : { label: "Open changes", path: chatResultHref(id, result.run, "changes") };
191
+ switch (d.action) {
192
+ case "approve-scope": return control("approval");
193
+ case "retry-task":
194
+ case "unhold":
195
+ case "inspect-hold":
196
+ case "repair-dependency":
197
+ case "retry-review":
198
+ case "resume-run": return control("recovery");
199
+ default: return control("task");
200
+ }
201
+ }
202
+ export function phoneTask(store, repos, id, now) {
203
+ return phoneTaskView(store, repos, id, now).text;
204
+ }
205
+ /** One task's status for a chat app: the words, its one console link, and
206
+ * the saved result it shows (a reply to it is about that result). */
207
+ export function phoneTaskView(store, repos, id, now) {
208
+ return store.transact(() => {
209
+ const ref = store.lookupRef(id);
210
+ // Check admission before reading a title, run, proof, or diagnosis.
211
+ const task = ref?.repo != null && repos.includes(ref.repo) ? store.getTask(id) : null;
212
+ if (task === null || ref?.repo == null)
213
+ return { text: "No such task in your connected projects. Send /status for task IDs.", link: null, run: null };
214
+ const d = diagnoseTaskDispatch(store, id, now);
215
+ if (d === null)
216
+ return { text: "This task's status is unavailable. Open it in the console before retrying.", link: null, run: null };
217
+ const lines = [plain(task.title, 140), `${plain(id, 64)} · ${projectLabel(ref.repo)}`, `As of ${now.toISOString().replace("T", " ").slice(0, 19)} UTC`, "", plain(d.summary, 160)];
218
+ const blocker = d.blockerTaskId === null ? null : store.lookupRef(d.blockerTaskId);
219
+ const hiddenDependency = blocker !== null && (blocker.repo === null || !repos.includes(blocker.repo));
220
+ lines.push(hiddenDependency ? "A required task outside this phone view has not finished. Open the dependency in the console." : plain(d.detail, 650));
221
+ if (d.nextAt !== null)
222
+ lines.push(`Earliest recorded wake: ${plain(d.nextAt, 40)} (a connected worker is still required).`);
223
+ const runs = store.runsFor(ref.id);
224
+ const result = task.state === "done" ? runs.find(r => (r.role === "builder" || r.role === "scout") && (r.outcome === "built" || r.outcome === "no-change") && r.finishedAt !== null) : undefined;
225
+ const latest = result ?? runs[0];
226
+ if (latest !== undefined) {
227
+ lines.push("", `${result === undefined ? "Latest recorded attempt" : "Saved result"}: #${latest.id} · ${plain(latest.provider, 40)}${latest.model === null ? "" : ` / ${plain(latest.model, 80)}`}`);
228
+ // Terminal status wins; a leftover internal phase must never read as activity.
229
+ if (latest.finishedAt !== null)
230
+ lines.push(`Attempt ended: ${plain(latest.finishedAt, 40)}`);
231
+ else if (d.condition === "running") {
232
+ const checkpoint = store.latestCheckpointForRun(latest.id);
233
+ lines.push(checkpoint === null ? "No milestone progress has been recorded for this attempt." : `Latest agent-reported milestone update: ${plain(checkpoint.createdAt, 40)} (not independent proof).`);
234
+ }
235
+ }
236
+ let link = null;
237
+ if (result !== undefined) {
238
+ const proof = store.proofVerdictFor(result.id);
239
+ link = taskLinkFor(id, d, { run: result.id, verdict: proof !== null });
240
+ const accepted = store.proofAcceptance(result.id) !== null;
241
+ const proofWords = { verified: "Checks passed at completion", attested: "Checks reported by the agent, not run by Toolroll", short: "Required saved material is missing", refuted: "The saved result conflicts with the approved scope" };
242
+ lines.push(`Checks: ${proof === null ? "No completion record saved" : manualReviewOnly(proof) ? accepted ? "Accepted by a person; the recorded checks are unchanged" : "A person must inspect this result; no recorded check failed" : proofWords[proof.verdict]}.`);
243
+ if (manualReviewOnly(proof) && !accepted)
244
+ lines.push('Reply “Send the result summary” for the checks, notes and screenshots.');
245
+ if (proof !== null && proof.matrix.length > 0)
246
+ lines.push(`Requirements: ${proof.matrix.filter(row => row.state === "pass").length}/${proof.matrix.length} satisfied in the saved record.`);
247
+ if (accepted && !manualReviewOnly(proof))
248
+ lines.push("An operator accepted this result; that does not change its recorded checks.");
249
+ const publication = store.publicationForRun(result.id);
250
+ const delivery = publication?.remoteState === "MERGED" ? "Merge observed on GitHub" : publication?.remoteState === "CLOSED" ? "Pull request closed, not merged" : publication?.state === "opened" ? `Pull request #${publication.prNumber ?? "?"} opened; not recorded as merged` : publication?.state === "pushed" ? "Branch pushed; pull request not yet recorded" : publication?.state === "intended" ? "Publication queued; not yet confirmed" : publication?.state === "failed" ? "Publication failed; the local result is preserved" : result.role === "scout" ? "Report saved locally" : "Result saved locally; no publication recorded";
251
+ lines.push(`Delivery: ${delivery}.`);
252
+ }
253
+ if (result === undefined)
254
+ link = taskLinkFor(id, d, null);
255
+ // Said once: the button is where; the sender adds the closing line when no button can ride.
256
+ lines.push("", `Next: ${nextStep(d)}`);
257
+ return { text: lines.join("\n"), link, run: result?.id ?? null };
258
+ });
259
+ }
260
+ /** Concise display only: authorization uses the stored full project identity. */
261
+ export function notificationIdentity(row) {
262
+ if (row.project === null)
263
+ return "";
264
+ return `${projectLabel(row.project)}${row.taskId === null ? "" : ` / ${plain(row.taskId, 64)}`} · `;
265
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Telegram inside the shared team conversations (v72): a group follows one
3
+ * team conversation, a private chat may select one, and every message a
4
+ * paired teammate sends there is saved through the same team operation the
5
+ * browser and CLI use — same queue, same single writer, same permissions and
6
+ * spending consent. Replies and teammates' messages come back through a
7
+ * per-chat cursor read on every bridge cycle. No model runs here.
8
+ */
9
+ import type { Store } from "./store.js";
10
+ import { type InlineButton } from "./telegram-mate.js";
11
+ import type { TelegramTransport } from "./telegram.js";
12
+ export type TeamCommand = {
13
+ kind: "list";
14
+ } | {
15
+ kind: "select";
16
+ index: number;
17
+ } | {
18
+ kind: "off";
19
+ };
20
+ /** `/team` lists, `/team <n>` chooses, `/team off` (or `private`) leaves. Any other slash text is not ours. */
21
+ export declare function teamCommand(text: string): TeamCommand | null;
22
+ export declare const PAIR_FIRST = "Pair your phone first: open Settings \u2192 Telegram in Toolroll, then send the code here in a private chat.";
23
+ type Counts = {
24
+ ignored: number;
25
+ chatQueued?: number;
26
+ chatRefused?: number;
27
+ statusReplies?: number;
28
+ problems: string[];
29
+ };
30
+ export type TeamInbound = {
31
+ store: Store;
32
+ botId: string;
33
+ now: Date;
34
+ report: Counts;
35
+ /** The enrolled ceiling read for this update; null when unreadable. */
36
+ projects: readonly string[] | null;
37
+ phoneOrigin: (() => string | null) | undefined;
38
+ updateId: number;
39
+ message: {
40
+ message_id: number;
41
+ text?: string;
42
+ chat?: {
43
+ id: number;
44
+ type?: string;
45
+ };
46
+ from?: {
47
+ id: number;
48
+ };
49
+ reply_to_message?: {
50
+ message_id: number;
51
+ };
52
+ forward_origin?: unknown;
53
+ forward_date?: unknown;
54
+ via_bot?: unknown;
55
+ sender_chat?: unknown;
56
+ caption?: string;
57
+ };
58
+ /** Queue one reply for after the update's transaction commits. */
59
+ say: (chatId: string, text: string, keyboard?: InlineButton[][]) => void;
60
+ };
61
+ /**
62
+ * Handle one inbound message that belongs to the team layer. Returns true
63
+ * when it was consumed here (a `/team` command in any chat, any message in
64
+ * a group, or a private message while a conversation is selected); false
65
+ * hands the update to the older personal paths untouched.
66
+ */
67
+ export declare function applyTeamInbound(input: TeamInbound): boolean;
68
+ /** The request identity a Telegram message carries into the team queue: the chat and the update, so the same update never saves twice and delivery can tell its own messages apart. */
69
+ export declare function teamRequestId(chatId: string, updateId: number): string;
70
+ type TeamDeliveryReport = {
71
+ sent: number;
72
+ problems: string[];
73
+ };
74
+ /**
75
+ * Carry new conversation messages to every chat that follows one: the
76
+ * lead's replies, teammates' messages (never this chat's own), and each
77
+ * reply's pending cards. Read from the cursor on every cycle; a failed send
78
+ * leaves the cursor where it was, so the next cycle retries the same
79
+ * message rather than skipping it.
80
+ */
81
+ export declare function deliverTeamChats(store: Store, botId: string, transport: TelegramTransport, clock: () => Date, report: TeamDeliveryReport, projects: readonly string[], phoneOrigin?: () => string | null, options?: {
82
+ readProjects?: () => Promise<readonly string[]>;
83
+ canDeliver?: () => boolean;
84
+ }): Promise<void>;
85
+ export {};