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,652 @@
1
+ /** Shared membership-chat identity, proposal previews and result links. Transport adapters never grant authority. */
2
+ import { FLOW_HREF } from "./flow-engine.js";
3
+ import { createHash } from "node:crypto";
4
+ import { sharedActionPayload, sharedActionNeedsReview, sharedActionReviewPath, sharedActionAllowsChallenge, CHAT_ACTIONS, } from "./chat-actions.js";
5
+ import { isDirectChatProvider, subscriptionCredentialKey } from "./converse.js";
6
+ import { MATE_MESSAGE_MAX_CHARS } from "./mate.js";
7
+ import { MATE_TOOL_SCHEMAS } from "./mate-tools.js";
8
+ import { verifyApproverStanding } from "./principal.js";
9
+ import { canonicalProject } from "./project.js";
10
+ import { phoneText, projectLabel } from "./telegram-status.js";
11
+ import { CHAT_CONTROLS, chatControlHref, chatResultHref, isChatControl, } from "./chat-controls.js";
12
+ import { CHAT_TASK_ACTIONS, isChatTaskAction } from "./chat-task-actions.js";
13
+ export function channelRepos(store, approver, registry) {
14
+ const seen = new Set();
15
+ const repos = [];
16
+ for (const path of registry) {
17
+ const canonical = canonicalProject(path) ?? path;
18
+ if (seen.has(canonical) || !store.accountCanAccess(approver, canonical))
19
+ continue;
20
+ seen.add(canonical);
21
+ repos.push(canonical);
22
+ }
23
+ return repos;
24
+ }
25
+ /**
26
+ * The session and thread a paired phone speaks in: the approver's live
27
+ * session when it is compatible (same generation, same membership
28
+ * credential, same ceiling), else one minted under the very terms the
29
+ * console and CLI state for membership chat (no dollar ceiling, this
30
+ * ceiling digest) — and only when NO session is live, because minting
31
+ * ends the previous one and an unrelated console conversation is not
32
+ * this phone's to end. The same rule for the thread: reused when its
33
+ * ceiling matches, never closed from here.
34
+ */
35
+ export function resolveChannelMate(store, binding, repos, now) {
36
+ const config = store.getChatConfig();
37
+ if (config === null) {
38
+ return {
39
+ ok: false,
40
+ reason: "unconfigured",
41
+ said: "Chat isn't set up yet. Choose a chat provider in Toolroll settings on the computer, then message again. Nothing was changed.",
42
+ };
43
+ }
44
+ if (isDirectChatProvider(config.provider)) {
45
+ return {
46
+ ok: false,
47
+ reason: "direct-api",
48
+ said: "Chat from this phone uses your membership login. Direct API chat stays on the computer so this chat cannot spend your API budget. Nothing was changed.",
49
+ };
50
+ }
51
+ if (repos.length === 0) {
52
+ return {
53
+ ok: false,
54
+ reason: "no-projects",
55
+ said: "No connected projects are available to this phone. Add a project in Toolroll on the computer, then message again.",
56
+ };
57
+ }
58
+ const verified = verifyApproverStanding(store, binding.approver, binding.approverGeneration, repos);
59
+ if (!verified.ok)
60
+ return { ok: false, reason: "unpaired", said: null };
61
+ const who = verified.who;
62
+ const credentialKey = subscriptionCredentialKey(config.provider);
63
+ const mismatch = "Your open chat session on the computer covers different projects or another provider. Finish or end it there, then message here again. Nothing was changed.";
64
+ let session = store.activeMateSession(who.name);
65
+ if (session !== null &&
66
+ (session.approverGeneration !== who.generation ||
67
+ session.credentialKey !== credentialKey ||
68
+ session.ceilingDigest !== who.ceilingDigest)) {
69
+ return { ok: false, reason: "session-mismatch", said: mismatch };
70
+ }
71
+ const liveThread = store.liveMateThreadFor(who.name);
72
+ if (liveThread !== null && liveThread.ceilingDigest !== who.ceilingDigest)
73
+ return { ok: false, reason: "thread-mismatch", said: mismatch };
74
+ if (session === null) {
75
+ const termsDigest = createHash("sha256")
76
+ .update(`0\n${who.ceilingDigest}`)
77
+ .digest("hex");
78
+ const id = store.mintMateSession({
79
+ approver: who.name,
80
+ approverGeneration: who.generation,
81
+ credentialKey,
82
+ ceilingMicrousd: 0,
83
+ ceilingDigest: who.ceilingDigest,
84
+ termsDigest,
85
+ }, now);
86
+ session = store.getMateSession(id);
87
+ if (session === null)
88
+ return { ok: false, reason: "session-mismatch", said: mismatch };
89
+ }
90
+ const thread = liveThread ?? store.openMateThread(who.name, who.ceilingDigest, now).thread;
91
+ return {
92
+ ok: true,
93
+ who,
94
+ session,
95
+ thread,
96
+ config: config,
97
+ };
98
+ }
99
+ /** A phone exchange about one task (a reply to that task's or result's
100
+ * message) stays in the lead conversation, and is kept in the task's own
101
+ * chat as well, so the task shows everything asked of it wherever it was
102
+ * asked. Best effort: the phone conversation never depends on it. */
103
+ export function mirrorToTaskChat(store, who, taskId, surface, message, reply, now) {
104
+ try {
105
+ const root = store.taskFamilyOf(taskId, who.repos, false)?.root.id ?? taskId;
106
+ if (!taskInCeiling(store, root, who.repos))
107
+ return;
108
+ const thread = store.openMateThread(who.name, who.ceilingDigest, now, { kind: "task", key: root }).thread;
109
+ store.appendMateMessage({ thread: thread.id, turn: null, role: "operator", text: `From ${surface}: ${message}` }, now);
110
+ store.appendMateMessage({ thread: thread.id, turn: null, role: "assistant", text: reply }, now);
111
+ }
112
+ catch {
113
+ // The task chat is a copy; the phone's own conversation already has it.
114
+ }
115
+ }
116
+ export function tooLongText(length) {
117
+ return `That message is ${length.toLocaleString("en-US")} characters; chat takes up to ${MATE_MESSAGE_MAX_CHARS.toLocaleString("en-US")}. Nothing was sent to the assistant. Send it in shorter parts, or say which part matters most.`;
118
+ }
119
+ /** A reply to a message about several tasks is never guessed: it names them and says how to choose. */
120
+ export function whichTaskText(titles) {
121
+ return [
122
+ "That message is about more than one task:",
123
+ ...titles.map((title) => `• ${phoneText(title, 64)}`),
124
+ "Reply to a message about just one of them, or send /tasks to pick one.",
125
+ ].join("\n");
126
+ }
127
+ /** The server-authored context a reply to a result message carries into the turn — the exact execution and run, never a guess. */
128
+ export function replyContextFor(taskId, run) {
129
+ return [
130
+ `Current task: ${taskId}. Read it with get_task before answering or proposing changes. Read its currentExecution next and bind new actions to that exact execution. Never replace the target of a prior proposal with a newer revision. Keep this turn about that task unless the operator explicitly asks to broaden it.`,
131
+ run === null
132
+ ? `The operator is replying to a message about execution ${taskId}.`
133
+ : `The operator is replying to result #${run} from execution ${taskId}. Use get_result for that exact execution and run when responding to feedback; do not substitute another result. If the operator asks for changes, use propose_review revise; use note only when they explicitly ask to save feedback without starting work.`,
134
+ ].join(" ");
135
+ }
136
+ /** The context a chosen task (/tasks, /task <name>) carries into each turn from that chat. */
137
+ export function focusContextFor(taskId) {
138
+ return `Current task: ${taskId}. The operator chose this task in their chat app; their messages there are about it until they switch back. Read it with get_task before answering or proposing changes, and bind new actions to its currentExecution. Read get_task_conversation when they refer to earlier discussion. Keep this turn about that task unless the operator explicitly asks to broaden it.`;
139
+ }
140
+ /** A step the phone cannot take itself: said once; the button (or its absence) says where. */
141
+ const HANDOFF = "This step finishes in Toolroll.";
142
+ /** No trusted https origin is configured: one honest line, no localhost, no promise. */
143
+ export const NO_PHONE_LINK = "Phone access isn't configured. Open Toolroll on your computer.";
144
+ /** An origin exists but the card's task is not one this phone may reach now: said as that, never as missing setup. */
145
+ export const NO_TASK_LINK = "No phone link: this task is outside your connected projects now, so open Toolroll on the computer.";
146
+ /** Is this task one the phone's ceiling admits right now? A link names a stored identity, never a model's word alone. */
147
+ export function taskInCeiling(store, taskId, repos) {
148
+ const ref = store.lookupRef(taskId);
149
+ return ref !== null && ref.repo !== null && repos.includes(ref.repo);
150
+ }
151
+ /** The recorded scope's standing — none filed yet (a planner is drafting), waiting for approval, or approved (by hand or under a signed mode). Read from the row, never from an outcome's words. */
152
+ function approvalState(store, taskId) {
153
+ const scope = store.getScope(taskId);
154
+ if (scope === null)
155
+ return "none";
156
+ if (scope.approvedDigest != null && scope.approvedDigest === scope.digest)
157
+ return "approved";
158
+ // Nothing to approve while the planner is still writing the plan.
159
+ return store.lookupRef(taskId)?.plan === "requested" ? "planning" : "waiting";
160
+ }
161
+ function controlLink(control, taskId, run, project) {
162
+ return {
163
+ label: CHAT_CONTROLS[control].label,
164
+ path: chatControlHref(control, taskId, run, project),
165
+ };
166
+ }
167
+ /**
168
+ * Where a task's next step lives, from its recorded state: the approval
169
+ * control while its scope waits for one, else the task itself.
170
+ */
171
+ function taskLink(store, taskId, repos) {
172
+ if (!taskInCeiling(store, taskId, repos))
173
+ return null;
174
+ return controlLink(approvalState(store, taskId) === "waiting" ? "approval" : "task", taskId);
175
+ }
176
+ /** The card text once its challenge is armed: an irreversible answer or a
177
+ * challenge action, in the same words on every channel. */
178
+ export function armedCardText(proposal, previewText) {
179
+ const body = previewText.split("\n\nConfirm or Dismiss below")[0] ?? previewText;
180
+ if (proposal.kind === "action")
181
+ return `${body}\n\nThis records that you handled this exact result. Confirm?`;
182
+ return `⚠ This answer is IRREVERSIBLE.\n\n${body}\n\nConfirm?`;
183
+ }
184
+ /** The "yes" button's label for an armed card. */
185
+ export function armedYesLabel(proposal) {
186
+ if (proposal.kind === "action") {
187
+ const action = sharedActionPayload(proposal.payload);
188
+ return `Yes, ${(action === null ? "confirm" : CHAT_ACTIONS[action.operation].label).toLowerCase()}`;
189
+ }
190
+ return "Yes, answer";
191
+ }
192
+ export function proposalLink(store, proposal, repos, channel = null) {
193
+ const payload = proposal.payload;
194
+ if (proposal.kind === "action") {
195
+ const action = sharedActionPayload(payload);
196
+ return action &&
197
+ repos.includes(action.repo) &&
198
+ sharedActionNeedsReview(action) &&
199
+ !(channel !== null && sharedActionAllowsChallenge(action))
200
+ ? { label: "Review action", path: sharedActionReviewPath(proposal.id) }
201
+ : null;
202
+ }
203
+ const task = typeof payload["task"] === "string" ? payload["task"] : "";
204
+ if (proposal.kind === "cancel")
205
+ return task !== "" && taskInCeiling(store, task, repos)
206
+ ? controlLink("cancel", task)
207
+ : null;
208
+ if (proposal.kind === "control") {
209
+ const control = payload["control"];
210
+ if (!isChatControl(control))
211
+ return null;
212
+ if (control === "skills" || control === "tools")
213
+ return typeof payload["project"] === "string" &&
214
+ repos.includes(payload["project"])
215
+ ? controlLink(control, task, undefined, payload["project"])
216
+ : null;
217
+ if ("href" in CHAT_CONTROLS[control])
218
+ return controlLink(control, task);
219
+ return task !== "" && taskInCeiling(store, task, repos)
220
+ ? controlLink(control, task, payload["run"])
221
+ : null;
222
+ }
223
+ return null;
224
+ }
225
+ /**
226
+ * The link a CONFIRMED card carries: the exact recorded task the outcome
227
+ * names, where its remaining step lives — the approval control while the
228
+ * scope waits for one (a manual approval), the task otherwise (an
229
+ * automatic approval, a staged resume). Kinds whose outcome is complete
230
+ * carry none.
231
+ */
232
+ export function confirmedLink(store, outcome, proposal, repos) {
233
+ // A flow change opens its canvas, the card selected.
234
+ if (outcome.ok && proposal.kind === "action" && typeof outcome.href === "string" && FLOW_HREF.test(outcome.href))
235
+ return { label: "Open the flow", path: outcome.href };
236
+ if (!outcome.ok || outcome.taskId === null)
237
+ return null;
238
+ if (proposal.kind === "action" &&
239
+ proposal.payload["operation"] === "skill_test")
240
+ return taskLink(store, outcome.taskId, repos);
241
+ const staged = proposal.kind === "task" ||
242
+ proposal.kind === "scope" ||
243
+ proposal.kind === "agents" ||
244
+ (proposal.kind === "task_action" &&
245
+ proposal.payload["operation"] === "resume") ||
246
+ (proposal.kind === "review" && proposal.payload["operation"] === "revise");
247
+ return staged ? taskLink(store, outcome.taskId, repos) : null;
248
+ }
249
+ /** One url button: navigation only — it opens the console's own authenticated control and grants nothing. */
250
+ function lines(text, cap) {
251
+ return phoneText(text, cap)
252
+ .split("\n")
253
+ .map((line) => `| ${line}`);
254
+ }
255
+ /** The card: plain words for what confirming does, the exact terms it binds to, and whether a button belongs on it. */
256
+ export function proposalPreview(store, proposal, repos, channel = null) {
257
+ const payload = proposal.payload;
258
+ const t = (key, cap = 200) => typeof payload[key] === "string"
259
+ ? phoneText(payload[key], cap)
260
+ : "";
261
+ const task = t("task", 64);
262
+ const taskName = t("taskTitle", 120) || task;
263
+ const repoLabel = (() => {
264
+ const id = t("repoId", 8);
265
+ const path = /^r[0-9]+$/.test(id)
266
+ ? repos[Number(id.slice(1)) - 1]
267
+ : undefined;
268
+ return path === undefined ? id : projectLabel(path);
269
+ })();
270
+ const card = (headline, body = [], consequence = null) => ({
271
+ text: [
272
+ headline,
273
+ ...body,
274
+ ...(consequence === null ? [] : ["", consequence]),
275
+ "",
276
+ "Confirm or Dismiss below. Nothing changes until you confirm.",
277
+ ].join("\n"),
278
+ buttons: true,
279
+ });
280
+ // A handoff's text is origin-free on purpose: it is persisted before the
281
+ // send, and the button or the missing-setup line joins it at send time.
282
+ const handoff = (headline, body = []) => ({
283
+ text: [headline, ...body, "", HANDOFF].join("\n"),
284
+ buttons: false,
285
+ });
286
+ switch (proposal.kind) {
287
+ case "action": {
288
+ const action = sharedActionPayload(payload);
289
+ if (!action)
290
+ return handoff("This action is unavailable.");
291
+ if (channel !== null && sharedActionAllowsChallenge(action))
292
+ return card(phoneText(action.title, 200), action.terms.map((term) => phoneText(term, 1200)), "Confirm asks once more before anything is recorded.");
293
+ return sharedActionNeedsReview(action)
294
+ ? handoff(phoneText(action.title, 200), [
295
+ "Review the full details and confirm this exact action.",
296
+ ])
297
+ : card(phoneText(action.title, 200), action.terms.map((term) => phoneText(term, 1200)));
298
+ }
299
+ case "task":
300
+ return card(`Create task in ${repoLabel || "the project"}: ${t("title", 120)}`, [
301
+ `Goal: ${t("goal", 600)}`,
302
+ ...(t("not") === "" ? [] : [`Not: ${t("not", 300)}`]),
303
+ ...(payload["report"] === true
304
+ ? ["A scout task: it delivers a report, never a branch."]
305
+ : []),
306
+ ], payload["report"] === true
307
+ ? "Confirm files it; a scout needs no approval."
308
+ : "Confirm files it. You still approve its scope before work starts.");
309
+ case "next":
310
+ return card(`Move ${taskName} to the front of its queue (now ${String(payload["position"] ?? "?")} of ${String(payload["of"] ?? "?")}).`);
311
+ case "reserve":
312
+ return card(payload["worker"] === null
313
+ ? `Release ${taskName} to the shared queue.`
314
+ : `Reserve ${taskName} for ${t("worker", 80)}.`);
315
+ case "hold":
316
+ return card(`Hold ${taskName}: ${t("reason", 300)}`, [], "The task waits until the hold is released.");
317
+ case "unhold":
318
+ return card(`Release ${taskName} from its hold.`);
319
+ case "steer":
320
+ return card(`Guide ${taskName}'s next attempt:`, lines(t("note", 1_000), 1_000), "Scope stays the same; active work is not interrupted.");
321
+ case "repair": {
322
+ const blocker = t("blockerTitle", 120) || t("blocker", 64);
323
+ const operation = t("operation", 16);
324
+ const headline = operation === "retry"
325
+ ? `Queue ${blocker} again; ${taskName} follows when it finishes.`
326
+ : operation === "unlink"
327
+ ? `Let ${taskName} continue without ${blocker}.`
328
+ : `Make ${taskName} wait for ${t("replacementTitle", 120) || t("replacement", 64)} instead of ${blocker}.`;
329
+ return card(headline);
330
+ }
331
+ case "agents": {
332
+ const parts = [
333
+ ...(t("risk") === "" ? [] : [`risk ${t("risk", 32)}`]),
334
+ ...(t("role") === ""
335
+ ? []
336
+ : [
337
+ payload["clear"] === true
338
+ ? `${t("role", 32)}: back to the recommendation`
339
+ : `${t("role", 32)}: ${t("provider", 40)} ${t("model", 80)}`,
340
+ ]),
341
+ ];
342
+ return card(`Change agents for ${taskName}: ${parts.join("; ")}`, [], "Changing agents or risk needs renewed approval before work starts.");
343
+ }
344
+ case "scope":
345
+ return card(`Rewrite the scope of ${taskName}:`, [
346
+ `Goal: ${t("goal", 600)}`,
347
+ ...(t("not") === "" ? [] : [`Not: ${t("not", 300)}`]),
348
+ ], "After confirming, the new scope still needs your password approval before work starts.");
349
+ case "answer": {
350
+ const id = typeof payload["decision"] === "number" ? payload["decision"] : null;
351
+ const decision = id === null ? null : store.getDecision(id);
352
+ const pick = t("option", 64);
353
+ const irreversible = payload["reversible"] === false;
354
+ const body = decision === null
355
+ ? ["(the decision is gone)"]
356
+ : [
357
+ `Q: ${phoneText(decision.question, 400)}`,
358
+ ...decision.options.map((one) => `${one.id === pick ? "→" : " "} ${phoneText(one.label, 120)}${one.reversible ? "" : " — IRREVERSIBLE"}${one.id === decision.recommendation ? " (the builder recommends this)" : ""}: ${phoneText(one.consequence, 300)}`),
359
+ ...(t("rationale") === "" ? [] : [`Why: ${t("rationale", 300)}`]),
360
+ ];
361
+ return card(`Answer decision #${String(id ?? "?")} on ${taskName} with "${t("optionLabel", 120) || pick}"`, body, irreversible
362
+ ? "⚠ This choice is irreversible. Confirming asks you once more."
363
+ : null);
364
+ }
365
+ case "task_action": {
366
+ const operation = payload["operation"];
367
+ const action = isChatTaskAction(operation)
368
+ ? CHAT_TASK_ACTIONS[operation]
369
+ : null;
370
+ const dependency = t("dependencyTitle", 120) || t("dependency", 64);
371
+ if (action === null)
372
+ return handoff(`An unavailable action was proposed for ${taskName}.`);
373
+ return card(`${action.label}: ${taskName}${dependency === "" ? "" : ` · ${dependency}`}`, [action.detail], operation === "resume"
374
+ ? "Confirming only requests the resume. Work resumes after the password step on the task, not from here."
375
+ : null);
376
+ }
377
+ case "review": {
378
+ const revise = payload["operation"] === "revise";
379
+ const snapshot = payload["snapshot"];
380
+ const selected = Array.isArray(payload["notes"])
381
+ ? payload["notes"]
382
+ : [];
383
+ const saved = (snapshot?.notes ?? []).filter((one) => selected.includes(one.id));
384
+ const note = t("note", 1_000);
385
+ const path = t("path", 300);
386
+ return card(`${revise ? "Request changes to" : "Save feedback on"} result #${String(payload["run"] ?? "?")} of ${taskName}`, [
387
+ ...(note === ""
388
+ ? []
389
+ : [
390
+ `Your feedback${path === "" ? "" : ` (${path}${typeof payload["line"] === "number" ? `:${payload["line"]}` : ""})`}:`,
391
+ ...lines(note, 1_000),
392
+ ]),
393
+ ...(saved.length === 0
394
+ ? []
395
+ : [
396
+ "Saved notes included:",
397
+ ...saved.map((one) => `• ${one.path === null ? "" : `${phoneText(one.path, 120)}${one.line === null ? "" : `:${one.line}`}: `}${phoneText(one.note, 300)}`),
398
+ ]),
399
+ ], revise
400
+ ? "Creates a revision of the same task. Its approval follows your settings."
401
+ : "Saves feedback; no work starts.");
402
+ }
403
+ case "cancel":
404
+ return handoff(`Cancel ${taskName}: ${t("reason", 300)}`, [
405
+ "Cancelling is armed on the task itself, never from a card.",
406
+ ]);
407
+ case "control": {
408
+ const control = payload["control"];
409
+ const label = isChatControl(control)
410
+ ? CHAT_CONTROLS[control].label
411
+ : "A console control";
412
+ return handoff(`${label}${taskName === "" ? "" : ` for ${taskName}`}`, [
413
+ "This opens an existing control; nothing changes from here.",
414
+ ]);
415
+ }
416
+ default:
417
+ return handoff("This kind of proposal cannot be confirmed from the phone.");
418
+ }
419
+ }
420
+ /** The card after it resolves, from the recorded outcome — the same words every surface shows. */
421
+ export function proposalOutcomeText(proposal) {
422
+ const outcome = proposal.outcome;
423
+ const said = outcome !== null && typeof outcome.said === "string"
424
+ ? phoneText(outcome.said, 600)
425
+ : "";
426
+ const via = outcome !== null && typeof outcome.via === "string"
427
+ ? ` (from ${outcome.via})`
428
+ : "";
429
+ switch (proposal.state) {
430
+ case "confirmed":
431
+ return `✓ Done${via}${said === "" ? "" : `: ${said}`}`;
432
+ case "refused":
433
+ return `✗ Not done${via}${said === "" ? "" : `: ${said}`}`;
434
+ case "dismissed":
435
+ return "Dismissed.";
436
+ case "expired":
437
+ return "This card expired.";
438
+ case "confirming":
439
+ return "Being confirmed elsewhere right now.";
440
+ default:
441
+ return "Still waiting for your confirmation.";
442
+ }
443
+ }
444
+ /**
445
+ * One row per mate tool: how the paired phone reaches it. `direct` means
446
+ * the same engine tool or the same confirm door runs from Telegram;
447
+ * `handoff` means the phone shows where the existing authenticated
448
+ * control lives and does nothing itself; `missing` means no phone path
449
+ * yet. The test suite refuses a tool this table does not name, and the
450
+ * committed matrix document must agree with it line for line.
451
+ */
452
+ export const CHAT_ACTION_PARITY = {
453
+ get_brief: {
454
+ support: "direct",
455
+ how: "Reads current tasks, decisions, results and project knowledge from the local database through the shared engine, within the enrolled projects.",
456
+ gap: "Dedicated Telegram and Slack journeys for this tool and live channel rendering remain unverified.",
457
+ },
458
+ get_project_context: {
459
+ support: "direct",
460
+ how: "Reads bounded source excerpts or advisory import impact in an accessible enrolled project through the shared engine, with source-search fallback when its index is unavailable.",
461
+ gap: "Index refresh uses the local CLI. Dedicated Telegram and Slack journeys for this tool and live channel rendering remain unverified.",
462
+ },
463
+ get_action_status: {
464
+ support: "direct",
465
+ how: "Reads the exact saved shared action and its outcome, including completion through secure review.",
466
+ gap: null,
467
+ },
468
+ get_actions: {
469
+ support: "direct",
470
+ how: "Lists the shared action catalogue and required inputs.",
471
+ gap: null,
472
+ },
473
+ propose_action: {
474
+ support: "direct",
475
+ how: "Prepares exact shared skill, knowledge, approval, acceptance, cancel and resume actions (the separate review request was removed on 2026-09-21). Short ordinary changes confirm here; protected or long changes use one secure review and record the result on the same proposal.",
476
+ gap: "Secure review requires a working HTTPS console connection. Real transport verification is required.",
477
+ },
478
+ recap: {
479
+ support: "direct",
480
+ how: "Read by the model during a phone turn over the enrolled ceiling.",
481
+ gap: null,
482
+ },
483
+ list_repos: {
484
+ support: "direct",
485
+ how: "Read during a turn; projects are r1..rN in enrollment order, as on the console.",
486
+ gap: null,
487
+ },
488
+ get_skills: {
489
+ support: "direct",
490
+ how: "Reads the same project skill library, saved selections and enabled versions as the console. Use propose_action for changes and tests.",
491
+ gap: "Skill import and long content require secure review. Folder and GitHub import still use the project Skills screen.",
492
+ },
493
+ get_project_knowledge: {
494
+ support: "direct",
495
+ how: "Read during a turn.",
496
+ gap: null,
497
+ },
498
+ get_models: { support: "direct", how: "Read during a turn: default agents with the exact model each runs, CLI versions and new models. Changes use the labelled Settings → Models page.", gap: null },
499
+ get_diff: { support: "direct", how: "Read during a turn: the exact result's changed files, then one file's diff, so a requested change names the right file and line.", gap: null },
500
+ get_check_log: { support: "direct", how: "Read during a turn: the end of the exact result's check log, a page of it, or the lines matching a search.", gap: null },
501
+ get_project_tools: { support: "direct", how: "Read during a turn: a project's tools, the common tools list and servers found on the computer. Adding one is a secure-review card; secrets are set only on the console's Tools page.", gap: null },
502
+ get_task_conversation: { support: "direct", how: "Read during a turn: what the person and the lead said in one task's own chat, including what was confirmed there.", gap: null },
503
+ get_flows: { support: "direct", how: "Read during a turn: a person's flows, each one's steps in order and its cards — where each card is, what it waits on, whether it needs them, its owner and its discussion.", gap: null },
504
+ get_teammates: { support: "direct", how: "Read during a turn: the project's AI teammates, their soul files, the zones they work, what they did today and the questions they're waiting on.", gap: null },
505
+ propose_teammate: { support: "direct", how: "Adds a teammate from a template or a soul file, changes one section of its soul file (or the whole short file), pauses, resumes or removes it, passes it a note, or answers its question for the person asked, through the shared confirm door.", gap: "Soul files longer than one message are edited on the console's teammate page; the phone changes one section at a time." },
506
+ get_flow_insights: { support: "direct", how: "Read during a turn: where each flow's cards pass, fail or are sent back, how long they wait, how its scripts did, and a run's log.", gap: null },
507
+ propose_flow: { support: "direct", how: "Creates or changes a flow, adds, moves, approves, sends back or cancels its cards, comments on them (@name pings that person), sets their owner, follows them, saves the project's scripts, and adds, pauses or removes its triggers, through the shared confirm door; a long drawing opens the secure review. Work a card files is an ordinary task under the usual approvals.", gap: "The flow canvas itself is on the console; the phone confirms cards but draws nothing. Webhook addresses and the Linear key are set on the console's Triggers panel." },
508
+ search_project_memory: { support: "direct", how: "Read during a turn: one search over decisions, references, lessons and the conversations the person may read.", gap: null },
509
+ list_tasks: { support: "direct", how: "Read during a turn.", gap: null },
510
+ get_task: {
511
+ support: "direct",
512
+ how: "Read during a turn; a reply to a result message pins the exact execution.",
513
+ gap: null,
514
+ },
515
+ get_agents: { support: "direct", how: "Read during a turn.", gap: null },
516
+ list_decisions: { support: "direct", how: "Read during a turn.", gap: null },
517
+ get_decision: { support: "direct", how: "Read during a turn.", gap: null },
518
+ queue: { support: "direct", how: "Read during a turn.", gap: null },
519
+ get_result: {
520
+ support: "direct",
521
+ how: "Read during a turn; the phone card shows the verification verdict, never a local link.",
522
+ gap: "Secure remote evidence links are not delivered to the phone; a result's screenshots travel through get_result_images.",
523
+ },
524
+ get_result_images: {
525
+ support: "direct",
526
+ how: "Read during a turn; every verified original PNG/JPEG the turn selected (at most 8 per reply, the rest by offset or image id) is sent as a document with a short safe caption after the reply, re-verified before each upload, and a reply to an image binds that exact task and run.",
527
+ gap: "An image whose record or bytes fail verification, or one Telegram refuses, is named in the chat rather than sent, through the same durable retried part; the operator opens the exact result in the console. Fixture proof only, no physical-phone rendering.",
528
+ },
529
+ get_controls: { support: "direct", how: "Read during a turn.", gap: null },
530
+ get_acceptance_evidence: {
531
+ support: "direct",
532
+ how: "Shared read-only acceptance packet: exact result, criterion states, gate, reviewer findings, caveats and recorded human acceptance. Screenshot files use get_result_images; marking complete is a propose_action result_accept confirmed behind the phone's own yes/cancel challenge or on the signed-in console.",
533
+ gap: "A physical-phone completion has not been exercised.",
534
+ },
535
+ show_control: {
536
+ support: "handoff",
537
+ how: "The card names the control and the task, with one url button to that exact console control when a trusted https console-url is configured; the button opens the signed-in console and acts on nothing.",
538
+ gap: "Incomplete phone action: the control itself runs in the console, after sign-in.",
539
+ },
540
+ propose_task: {
541
+ support: "direct",
542
+ how: "Card with Confirm/Dismiss through confirmMateProposal (filed as a mate proposal, via telegram). The confirmed card links Review & start for the filed task while its scope waits; under a signed automatic mode it says the scope is approved and links the task.",
543
+ gap: "Under manual approval the password step happens in the console, reached from the card's button.",
544
+ },
545
+ propose_scope: {
546
+ support: "direct",
547
+ how: "Confirm rewrites the scope through the shared door; the confirmed card links Review & start for the exact task.",
548
+ gap: "Approving the rewritten scope needs the password, in the console.",
549
+ },
550
+ propose_next: {
551
+ support: "direct",
552
+ how: "Confirm through the shared door with the queue revision it saw.",
553
+ gap: null,
554
+ },
555
+ propose_reserve: {
556
+ support: "direct",
557
+ how: "Confirm through the shared door.",
558
+ gap: null,
559
+ },
560
+ propose_agents: {
561
+ support: "direct",
562
+ how: "Confirm through the shared route-edit door; when the change stales the approval, the confirmed card links Review & start for the exact task.",
563
+ gap: "Renewed approval after the route change happens in the console.",
564
+ },
565
+ propose_hold: {
566
+ support: "direct",
567
+ how: "Confirm through the shared door.",
568
+ gap: null,
569
+ },
570
+ propose_unhold: {
571
+ support: "direct",
572
+ how: "Confirm through the shared door.",
573
+ gap: null,
574
+ },
575
+ propose_steer: {
576
+ support: "direct",
577
+ how: "Confirm through the shared door; the guidance is shown verbatim on the card.",
578
+ gap: null,
579
+ },
580
+ propose_dependency_repair: {
581
+ support: "direct",
582
+ how: "Confirm retry/unlink/replace through the shared door with both projects re-checked.",
583
+ gap: null,
584
+ },
585
+ propose_task_action: {
586
+ support: "direct",
587
+ how: "stop, retry, plan, wait_for and stop_waiting confirm through the shared door (a stop is audited via telegram); resume confirms only the request, says nothing has resumed, and links the task where the password step lives.",
588
+ gap: "resume completes in the console (incomplete phone action).",
589
+ },
590
+ propose_answer: {
591
+ support: "direct",
592
+ how: "Confirm answers through the shared door, audited via telegram; an irreversible option arms a second tap first.",
593
+ gap: null,
594
+ },
595
+ propose_review: {
596
+ support: "direct",
597
+ how: "note saves feedback; revise creates the same-family revision through the shared result service, honouring automatic approval settings; the confirmed card links Review & start for the revision while it waits, or the task once approved.",
598
+ gap: "Under manual approval the revision is approved in the console, reached from the card's button; under a signed automatic-approval mode it runs unattended.",
599
+ },
600
+ propose_cancel: {
601
+ support: "handoff",
602
+ how: "The door refuses cancel from any card; the card links the exact task's Cancel control when a trusted https console-url is configured, and the cancel is armed there.",
603
+ gap: "Incomplete phone action: no phone path to cancel by design; the button only opens the task.",
604
+ },
605
+ };
606
+ /** Every tool the model can call, mapped; a new tool must name its phone road. */
607
+ export function parityGaps() {
608
+ return MATE_TOOL_SCHEMAS.map((tool) => tool.name).filter((name) => CHAT_ACTION_PARITY[name] === undefined);
609
+ }
610
+ export function handoffCardText(text, note) {
611
+ return note === null ? text : `${text}\n\n${note}`;
612
+ }
613
+ /**
614
+ * The resolved card, from what is RECORDED about the task the outcome
615
+ * names — never from a word search over the door's sentence. A scope that
616
+ * still waits for approval has one next action: approve it (the button, or
617
+ * the console on the computer when no link exists). A scope approved under
618
+ * a signed mode asks for nothing more. A staged resume says what remains.
619
+ */
620
+ export function confirmedCardText(store, outcome, proposal, note) {
621
+ const said = phoneText(outcome.said, 600);
622
+ if (!outcome.ok)
623
+ return `✗ Not done: ${said}`;
624
+ const taskId = outcome.taskId;
625
+ const resume = proposal.kind === "task_action" &&
626
+ proposal.payload["operation"] === "resume";
627
+ const revise = proposal.kind === "review" && proposal.payload["operation"] === "revise";
628
+ const staged = proposal.kind === "task" ||
629
+ proposal.kind === "scope" ||
630
+ proposal.kind === "agents" ||
631
+ resume ||
632
+ revise;
633
+ if (!staged || taskId === null)
634
+ return `✓ ${said}`;
635
+ const state = approvalState(store, taskId);
636
+ const approval = state === "waiting";
637
+ // The door's sentence carries an approval instruction for a filed task or
638
+ // a revision; under a signed automatic mode the recorded scope is already
639
+ // approved, and the card says that instead of asking again.
640
+ const words = proposal.kind === "task" && state === "approved"
641
+ ? `${said.split(" — ")[0]} — approved under your automatic approval settings; nothing more is needed from you.`
642
+ : revise && state === "approved"
643
+ ? "Revision created under your automatic approval settings."
644
+ : said;
645
+ const next = resume
646
+ ? "Nothing has resumed yet: the password step on the task finishes it."
647
+ : approval && note !== null
648
+ ? "Approve it in Toolroll on the computer."
649
+ : "";
650
+ const setup = (approval || resume) && note !== null ? note : "";
651
+ return [`✓ ${words}`, ...[next, setup].filter((one) => one !== "")].join("\n\n");
652
+ }