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,454 @@
1
+ /**
2
+ * Phase-agent resolution: which provider and model a phase runs on, layer
3
+ * by layer, with the layers written down (Codex provider review, Q8).
4
+ *
5
+ * pinned task agent — stamped by a fire transaction; NOTHING overrides it
6
+ * explicit flags — this pass's operator, per field
7
+ * project override — phase_config row scoped to the canonical repo
8
+ * installation — phase_config row scoped 'installation'
9
+ * review inheritance — when review is unset, the planner's complete pair
10
+ * default — claude, harness default model
11
+ *
12
+ * Config rows are COMPLETE pairs (provider required, model optional), so a
13
+ * partial override cannot marry a codex model to an inherited claude
14
+ * provider. Flags are per-field with one stated rule: `--model` alone
15
+ * rides whatever provider resolves; `--provider` alone runs that
16
+ * provider's default model — a lower layer's model never crosses onto a
17
+ * flag-chosen provider it was not written for.
18
+ *
19
+ * The resolved pair is validated before anything is claimed or spent, and
20
+ * the caller snapshots it into the run row.
21
+ */
22
+ import { isProviderId, validateSpec } from "./provider.js";
23
+ import { contestantProfileOf } from "./store.js";
24
+ import { CLAUDE_LIMITS, CODEX_SHAPED_LIMITS, GEMINI_LIMITS, chainFromJson, canonicalChainJson } from "./scope.js";
25
+ import { SUBSCRIPTION_CAPABLE } from "./keys.js";
26
+ import { exactModelId, legOf, PHASES, recommendRoute, routeFromJson, routeProblems, sameSpec } from "./phase-routing.js";
27
+ export const INSTALLATION_SCOPE = "installation";
28
+ /**
29
+ * Fail-closed (not a fallback to claude — a refusal): gemini's own
30
+ * `.gemini/` config loads hooks and MCP servers unconditionally
31
+ * (provider.ts's geminiArgv), a leak claude and codex both now close for
32
+ * review with a dedicated isolation argv. Until gemini earns the same, it
33
+ * is not eligible to run the reviewer phase at all — however it got
34
+ * resolved: pinned, flagged, or configured.
35
+ */
36
+ function reviewEligible(phase, spec) {
37
+ return phase === "review" && spec.provider === "gemini"
38
+ ? "gemini has no isolation posture for the review phase yet (its own config can load hooks and MCP servers) — pin review to claude or codex"
39
+ : null;
40
+ }
41
+ export function resolvePhaseAgent(store, phase, repo, flags,
42
+ /** The task being dispatched, when one is — its pin is authoritative. */
43
+ ref) {
44
+ // The pin: a firing resolved under approved terms must not be re-routed
45
+ // by anything later, flags included (Codex provider review, critical 1).
46
+ if (ref !== undefined && ref.agentProvider !== null) {
47
+ if (!isProviderId(ref.agentProvider)) {
48
+ return { ok: false, problem: `the task is pinned to unknown provider \`${ref.agentProvider}\`` };
49
+ }
50
+ const spec = { provider: ref.agentProvider, model: ref.agentModel };
51
+ const ineligible = reviewEligible(phase, spec);
52
+ if (ineligible !== null)
53
+ return { ok: false, problem: ineligible };
54
+ const valid = validateSpec(spec);
55
+ return valid.ok ? { ok: true, spec, source: "pinned" } : { ok: false, problem: valid.problem };
56
+ }
57
+ if (flags.provider !== undefined) {
58
+ if (!isProviderId(flags.provider)) {
59
+ return { ok: false, problem: `unknown provider \`${flags.provider}\`` };
60
+ }
61
+ const spec = { provider: flags.provider, model: flags.model ?? null };
62
+ const ineligible = reviewEligible(phase, spec);
63
+ if (ineligible !== null)
64
+ return { ok: false, problem: ineligible };
65
+ const valid = validateSpec(spec);
66
+ return valid.ok ? { ok: true, spec, source: "flag" } : { ok: false, problem: valid.problem };
67
+ }
68
+ const directProject = repo === null ? null : store.phaseConfig(repo, phase);
69
+ const directInstallation = store.phaseConfig(INSTALLATION_SCOPE, phase);
70
+ // Planning and review benefit from the same high-judgment model, while
71
+ // execution can use a different provider. An explicit review row always
72
+ // wins; only an unset review inherits the planner's complete pair.
73
+ const inheritedProject = phase === "review" && directProject === null && directInstallation === null && repo !== null
74
+ ? store.phaseConfig(repo, "plan")
75
+ : null;
76
+ const inheritedInstallation = phase === "review" && directProject === null && directInstallation === null
77
+ ? store.phaseConfig(INSTALLATION_SCOPE, "plan")
78
+ : null;
79
+ const project = directProject ?? inheritedProject;
80
+ const installation = directInstallation ?? inheritedInstallation;
81
+ const row = project ?? installation;
82
+ const source = project !== null ? "project" : installation !== null ? "installation" : "default";
83
+ // A misconfigured row REFUSES instead of silently rerouting to claude
84
+ // (foundations finding 3c): the operator wrote a provider; running a
85
+ // different one is not a fallback, it is a substitution.
86
+ if (row !== null && !isProviderId(row.provider)) {
87
+ return { ok: false, problem: `the ${source} configuration names unknown provider \`${row.provider}\` — fix it with \`config set\`` };
88
+ }
89
+ const provider = row !== null && isProviderId(row.provider) ? row.provider : "claude";
90
+ // --model alone rides the resolved provider; otherwise the pair comes
91
+ // whole from the row that named the provider.
92
+ const model = flags.model ?? (row !== null ? row.model : null);
93
+ const spec = { provider, model };
94
+ const ineligible = reviewEligible(phase, spec);
95
+ if (ineligible !== null)
96
+ return { ok: false, problem: ineligible };
97
+ const valid = validateSpec(spec);
98
+ return valid.ok ? { ok: true, spec, source: flags.model !== undefined ? "flag" : source } : { ok: false, problem: valid.problem };
99
+ }
100
+ export function resolveScopeProfile(store, repo, ref, flags) {
101
+ const build = resolvePhaseAgent(store, "build", repo, flags, ref);
102
+ if (!build.ok)
103
+ return { ok: false, reason: "unknown-provider", problem: build.problem };
104
+ const { provider, model } = build.spec;
105
+ if (model === null || model === "") {
106
+ return {
107
+ ok: false,
108
+ reason: "no-model",
109
+ problem: "approvals bind exact routing — name --model on the scope, or set a default once with `config set build --provider " +
110
+ provider +
111
+ " --model <model>`",
112
+ };
113
+ }
114
+ let repairModel = "inherit";
115
+ let repairFrom = "inherit";
116
+ if (flags.repairModel !== undefined && flags.repairModel !== "") {
117
+ repairModel = flags.repairModel;
118
+ repairFrom = "flag";
119
+ }
120
+ else {
121
+ const repairRow = (repo === null ? null : store.phaseConfig(repo, "repair")) ?? store.phaseConfig(INSTALLATION_SCOPE, "repair");
122
+ if (repairRow !== null) {
123
+ if (repairRow.provider !== provider) {
124
+ return {
125
+ ok: false,
126
+ reason: "repair-provider-mismatch",
127
+ problem: `the repair configuration names provider \`${repairRow.provider}\` but the build runs \`${provider}\` — cross-provider repair does not exist; fix the repair row or name --repair-model`,
128
+ };
129
+ }
130
+ if (repairRow.model !== null && repairRow.model !== "") {
131
+ repairModel = repairRow.model;
132
+ repairFrom = "config";
133
+ }
134
+ }
135
+ }
136
+ const permissionMode = flags.permissionMode ?? store.permissionDefault().mode;
137
+ const profile = provider === "claude"
138
+ ? {
139
+ provider,
140
+ model,
141
+ // Auto mode is designed for headless work: routine repository
142
+ // commands and edits proceed, while risky acts still stop at the
143
+ // provider's permission classifier. Full access is an explicit
144
+ // installation or task choice and is sealed into this profile.
145
+ permissionArgv: permissionMode,
146
+ maxTurns: CLAUDE_LIMITS.maxTurns,
147
+ repairMaxTurns: CLAUDE_LIMITS.repairMaxTurns,
148
+ timeoutSeconds: CLAUDE_LIMITS.timeoutSeconds,
149
+ timeoutKind: "idle",
150
+ repairTimeoutSeconds: CLAUDE_LIMITS.repairTimeoutSeconds,
151
+ repairModel,
152
+ }
153
+ : provider === "gemini"
154
+ ? {
155
+ provider,
156
+ model,
157
+ // The cross-provider choice resolves to Gemini's own real argv:
158
+ // auto_edit for Auto, yolo for Full access.
159
+ approvalArgv: permissionMode === "bypassPermissions" ? "yolo" : "auto_edit",
160
+ maxTurns: "unsupported",
161
+ repairMaxTurns: "unsupported",
162
+ timeoutSeconds: GEMINI_LIMITS.timeoutSeconds,
163
+ timeoutKind: "idle",
164
+ repairTimeoutSeconds: GEMINI_LIMITS.repairTimeoutSeconds,
165
+ repairModel,
166
+ }
167
+ : {
168
+ provider,
169
+ model,
170
+ sandboxMode: permissionMode === "bypassPermissions" ? "danger-full-access" : "workspace-write",
171
+ maxTurns: "unsupported",
172
+ repairMaxTurns: "unsupported",
173
+ timeoutSeconds: CODEX_SHAPED_LIMITS.timeoutSeconds,
174
+ timeoutKind: "idle",
175
+ repairTimeoutSeconds: CODEX_SHAPED_LIMITS.repairTimeoutSeconds,
176
+ repairModel,
177
+ };
178
+ return { ok: true, profile, provenance: { resolvedFrom: build.source, repairFrom } };
179
+ }
180
+ /**
181
+ * Resolve the full EXECUTION CHAIN a scope files under (v30): the base
182
+ * (entry 0) is the ordinary single-profile resolution wearing the base
183
+ * provider's auth mode; the fallbacks are the scope's configured entries,
184
+ * each resolved to a WHOLE ExecutionProfile (repair per entry). With no
185
+ * fallbacks configured, the result is `kind: "profile"` — a single-profile
186
+ * approval, byte-identical to today (NOT an explicit chain). With
187
+ * fallbacks, it is `kind: "chain"` and the approval binds the whole thing.
188
+ * The base auth mode is passed in (the caller reads it from the managed
189
+ * key store) so resolution stays pure and testable.
190
+ */
191
+ export function resolveScopeChain(store, repo, ref, flags, baseAuthMode) {
192
+ const base = resolveScopeProfile(store, repo, ref, flags);
193
+ if (!base.ok)
194
+ return { ok: false, reason: "base-unresolved", problem: base.problem };
195
+ const unreadable = repo === null ? null : store.fallbackConfigProblem(repo);
196
+ if (unreadable !== null)
197
+ return { ok: false, reason: "bad-fallback", problem: unreadable };
198
+ const fallbacks = repo === null ? [] : store.fallbackConfig(repo);
199
+ if (fallbacks.length === 0) {
200
+ // No fallbacks: a legacy single-profile approval, unchanged.
201
+ return { ok: true, chain: [{ profile: base.profile, authMode: baseAuthMode }], kind: "profile" };
202
+ }
203
+ const entries = [{ profile: base.profile, authMode: baseAuthMode }];
204
+ for (const one of fallbacks) {
205
+ if (!isProviderId(one.provider) || one.model === undefined || one.model === "") {
206
+ return { ok: false, reason: "bad-fallback", problem: `a fallback entry names an unknown provider or empty model (${one.provider}:${one.model})` };
207
+ }
208
+ if (one.authMode !== "subscription" && one.authMode !== "api-key") {
209
+ return { ok: false, reason: "bad-fallback", problem: `a fallback entry has an unknown auth mode` };
210
+ }
211
+ // An entry can only pin an auth mode its provider can actually take:
212
+ // "subscription" on a provider with no login (openrouter) would seal an
213
+ // entry that can never authenticate (E3d, gateway pin).
214
+ if (one.authMode === "subscription" && !SUBSCRIPTION_CAPABLE[one.provider]) {
215
+ return { ok: false, reason: "bad-fallback", problem: `${one.provider} has no subscription login — this entry must use an API key` };
216
+ }
217
+ // The model rides provider argv (F+G review, finding 1): the SAME
218
+ // argv-safety validation every other sealed model passes — never a
219
+ // leading dash, control bytes, or whitespace into a harness's argv.
220
+ const argvSafe = validateSpec({ provider: one.provider, model: one.model });
221
+ if (!argvSafe.ok) {
222
+ return { ok: false, reason: "bad-fallback", problem: argvSafe.problem };
223
+ }
224
+ entries.push({ profile: contestantProfileOf(one.provider, one.model, one.repairModel ?? "inherit", flags.permissionMode ?? store.permissionDefault().mode), authMode: one.authMode });
225
+ }
226
+ // Re-prove the whole chain through the strict rehydrator: it rejects
227
+ // exact-duplicate entries and any malformed shape, so what the approval
228
+ // seals is exactly what dispatch will re-derive.
229
+ const proven = chainFromJson(canonicalChainJson(entries));
230
+ if (proven === null) {
231
+ return { ok: false, reason: "duplicate", problem: "the fallback chain has a duplicate entry (same profile and auth mode) or is malformed" };
232
+ }
233
+ return { ok: true, chain: proven, kind: "chain" };
234
+ }
235
+ const PHASE_NOUN = { plan: "planner", build: "builder", repair: "repair", review: "reviewer" };
236
+ export function resolveRouteCandidates(store, repo, pins = {}) {
237
+ const strongOf = (phase) => {
238
+ const strongProject = repo === null ? null : store.phaseTierConfig(repo, phase, "strong");
239
+ const strongInstallation = store.phaseTierConfig(INSTALLATION_SCOPE, phase, "strong");
240
+ const inheritedProject = phase === "review" && strongProject === null && strongInstallation === null && repo !== null ? store.phaseTierConfig(repo, "plan", "strong") : null;
241
+ const inheritedInstallation = phase === "review" && strongProject === null && strongInstallation === null ? store.phaseTierConfig(INSTALLATION_SCOPE, "plan", "strong") : null;
242
+ const row = strongProject ?? inheritedProject ?? strongInstallation ?? inheritedInstallation;
243
+ const source = strongProject !== null ? "project (strong)" : inheritedProject !== null ? "project (strong, inherited from plan)" : strongInstallation !== null ? "installation (strong)" : inheritedInstallation !== null ? "installation (strong, inherited from plan)" : null;
244
+ if (row === null || source === null)
245
+ return { ok: true, strong: null };
246
+ if (!isProviderId(row.provider) || row.model === null || row.model === "") {
247
+ return { ok: false, problem: `the ${source} ${PHASE_NOUN[phase]} names ${row.provider}${row.model === null || row.model === "" ? " with no model" : ` · ${row.model}`} — a strong agent is an exact pair: \`config set ${phase} --tier strong --provider … --model …\`, or \`--clear\` it` };
248
+ }
249
+ const valid = validateSpec({ provider: row.provider, model: row.model });
250
+ if (!valid.ok)
251
+ return { ok: false, problem: `the ${source} ${PHASE_NOUN[phase]}: ${valid.problem}` };
252
+ return { ok: true, strong: { provider: row.provider, model: row.model, source } };
253
+ };
254
+ const exact = (phase) => {
255
+ const routine = resolvePhaseAgent(store, phase, repo, {});
256
+ if (!routine.ok)
257
+ return { ok: false, problem: routine.problem };
258
+ if (routine.spec.model === null || routine.spec.model === "") {
259
+ // A PINNED exact pair (a routine firing's approved profile, a plan
260
+ // request's pin) is the phase's agent whatever the configuration
261
+ // says — it stands in as the candidate when nothing exact is
262
+ // configured, so a firing never depends on today's config.
263
+ const pin = phase === "plan" ? pins.plan ?? null : phase === "build" ? pins.build ?? null : null;
264
+ if (pin !== null)
265
+ return { ok: true, routine: { provider: pin.provider, model: pin.model, source: "the pinned agent" } };
266
+ return {
267
+ ok: false,
268
+ problem: `approvals bind exact routing — the ${PHASE_NOUN[phase]} (${routine.spec.provider}) has no exact model: set one once with \`config set ${phase} --provider ${routine.spec.provider} --model <model>\``,
269
+ };
270
+ }
271
+ return { ok: true, routine: { provider: routine.spec.provider, model: routine.spec.model, source: routine.source === "default" ? "the built-in default" : routine.source } };
272
+ };
273
+ const out = {};
274
+ for (const phase of ["plan", "build", "review"]) {
275
+ const routine = exact(phase);
276
+ const strong = strongOf(phase);
277
+ // Retain the historical four-leg encoding, but retired reviewer settings
278
+ // cannot prevent a new task from planning or building. This leg never runs.
279
+ if (phase === "review" && (!routine.ok || !strong.ok)) {
280
+ out.review = out.plan;
281
+ continue;
282
+ }
283
+ if (!routine.ok)
284
+ return { ok: false, phase, problem: routine.problem };
285
+ if (!strong.ok)
286
+ return { ok: false, phase, problem: strong.problem };
287
+ out[phase] = { routine: routine.routine, strong: strong.strong };
288
+ }
289
+ // Repair: the configured row is optional (inherit is the law when none
290
+ // exists), but a row that EXISTS must be exact — a provider the policy
291
+ // can hold against the build's, and a model id.
292
+ const repairProject = repo === null ? null : store.phaseConfig(repo, "repair");
293
+ const repairRow = repairProject ?? store.phaseConfig(INSTALLATION_SCOPE, "repair");
294
+ const repairSource = repairProject !== null ? "project" : "installation";
295
+ let repairRoutine = null;
296
+ if (repairRow !== null) {
297
+ if (!isProviderId(repairRow.provider) || repairRow.model === null || repairRow.model === "") {
298
+ return { ok: false, phase: "repair", problem: `the ${repairSource} repair configuration names ${repairRow.provider}${repairRow.model === null || repairRow.model === "" ? " with no model" : ` · ${repairRow.model}`} — approvals bind exact routing: \`config set repair --provider … --model …\` names an exact pair, or clear it so repairs inherit the build agent` };
299
+ }
300
+ const valid = validateSpec({ provider: repairRow.provider, model: repairRow.model });
301
+ if (!valid.ok)
302
+ return { ok: false, phase: "repair", problem: `the ${repairSource} repair configuration: ${valid.problem}` };
303
+ repairRoutine = { provider: repairRow.provider, model: repairRow.model, source: repairSource };
304
+ }
305
+ const repairStrong = strongOf("repair");
306
+ if (!repairStrong.ok)
307
+ return { ok: false, phase: "repair", problem: repairStrong.problem };
308
+ out.repair = { routine: repairRoutine, strong: repairStrong.strong };
309
+ return { ok: true, candidates: out };
310
+ }
311
+ /** A task's pinned pair as an EXACT spec, or the words for why it cannot
312
+ * route: a pin with no model id binds nothing exact. */
313
+ export function exactPinOf(provider, model, phase) {
314
+ if (provider === null)
315
+ return { ok: true, pin: null };
316
+ if (!isProviderId(provider))
317
+ return { ok: false, problem: `the task's ${phase} pin names unknown provider \`${provider}\`` };
318
+ if (model === null || model === "") {
319
+ return { ok: false, problem: phase === "plan" ? `the plan pin names ${provider} with no exact model — \`task plan <id> --provider ${provider} --model <model>\` names one` : `the task's build pin names ${provider} with no exact model — approvals bind exact routing` };
320
+ }
321
+ // An exact pin is an exact ID: a stored model that is not argv-safe (a
322
+ // leading dash, whitespace, a control byte) files the scope unresolved
323
+ // in words rather than riding into a route or a spawn.
324
+ if (!exactModelId(model)) {
325
+ return { ok: false, problem: `the task's ${phase} pin names ${provider} with a model that is not an exact id — re-pin it with an exact model id` };
326
+ }
327
+ return { ok: true, pin: { provider, model } };
328
+ }
329
+ export function routeOfTask(store, taskId, ref, now) {
330
+ const sealed = store.sealedRouteOf(taskId);
331
+ if (sealed.ok)
332
+ return { kind: "route", route: sealed.route, source: "approved" };
333
+ const scope = store.getScope(taskId);
334
+ if (scope !== null) {
335
+ if (scope.routeEra == null) {
336
+ const profile = scope.approvedProfile ?? scope.profile ?? null;
337
+ return profile === null ? null : { kind: "legacy", profile, approved: sealed.reason !== "unapproved" && scope.approvedAt !== null && scope.approvedDigest === scope.digest };
338
+ }
339
+ if (sealed.reason === "unreadable")
340
+ return { kind: "unreadable", problem: sealed.detail };
341
+ const proposed = routeFromJson(scope.proposedRouteJson ?? null);
342
+ if (proposed !== null)
343
+ return { kind: "route", route: proposed, source: "proposed" };
344
+ return { kind: "unreadable", problem: scope.unresolvedReason ?? "the filed route cannot be read — re-file the scope" };
345
+ }
346
+ const repo = ref?.repo ?? null;
347
+ const overrides = ref === null || ref.routeOverrides === undefined ? [] : ref.routeOverrides;
348
+ if (overrides === null)
349
+ return { kind: "unreadable", problem: "the task's recorded route overrides cannot be read — clear or re-record them with `task route`" };
350
+ const planPin = exactPinOf(ref?.planProvider ?? null, ref?.planModel ?? null, "plan");
351
+ if (!planPin.ok)
352
+ return { kind: "unreadable", problem: planPin.problem };
353
+ const buildPin = exactPinOf(ref?.agentProvider ?? null, ref?.agentModel ?? null, "build");
354
+ if (!buildPin.ok)
355
+ return { kind: "unreadable", problem: buildPin.problem };
356
+ const candidates = resolveRouteCandidates(store, repo, { plan: planPin.pin, build: buildPin.pin });
357
+ if (!candidates.ok)
358
+ return { kind: "unreadable", problem: candidates.problem };
359
+ const route = recommendRoute({
360
+ risk: ref?.riskLevel ?? "routine",
361
+ qualityMode: ref?.qualityMode ?? store.qualityDefault().mode,
362
+ evidence: [],
363
+ publication: store.publicationAuthorityOf(repo, now),
364
+ candidates: candidates.candidates,
365
+ overrides,
366
+ pins: { plan: planPin.pin, build: buildPin.pin },
367
+ });
368
+ return { kind: "route", route, source: "live" };
369
+ }
370
+ export function resolveRoutineAuthority(store, repo, acceptance, now) {
371
+ const candidates = resolveRouteCandidates(store, repo);
372
+ if (!candidates.ok)
373
+ return { ok: false, problem: candidates.problem };
374
+ const route = recommendRoute({
375
+ risk: "routine",
376
+ qualityMode: store.qualityDefault().mode,
377
+ evidence: [...new Set(acceptance.flatMap(one => one.evidence))],
378
+ publication: store.publicationAuthorityOf(repo, now),
379
+ candidates: candidates.candidates,
380
+ overrides: [],
381
+ });
382
+ const problems = routeProblems(route);
383
+ if (problems.length > 0)
384
+ return { ok: false, problem: problems.join("; ") };
385
+ const build = legOf(route, "build");
386
+ const repair = legOf(route, "repair");
387
+ // The repair model rides as a flag only when the leg says more than
388
+ // "the build's own model" — an inheriting repair stays the stable
389
+ // literal "inherit" (= the exact build model), as saveScope files it.
390
+ const inheriting = candidates.candidates.repair.routine === null && repair.chosen === "recommended" && repair.tier === "routine" && repair.model === build.model;
391
+ const resolved = resolveScopeProfile(store, repo, undefined, { provider: build.provider, model: build.model, ...(inheriting ? {} : { repairModel: repair.model }) });
392
+ if (!resolved.ok)
393
+ return { ok: false, problem: resolved.problem };
394
+ const repairModel = resolved.profile.repairModel === "inherit" ? resolved.profile.model : resolved.profile.repairModel;
395
+ if (!sameSpec(resolved.profile, build) || repairModel !== repair.model) {
396
+ return { ok: false, problem: `the agent profile (${resolved.profile.provider} · ${resolved.profile.model}, repair ${repairModel}) does not match the route (${build.provider} · ${build.model}, repair ${repair.model})` };
397
+ }
398
+ return { ok: true, route, profile: resolved.profile };
399
+ }
400
+ /**
401
+ * THE ROLE'S CONFIGURED CHOICES (v48), simple and role-specific: for each
402
+ * role, exactly the exact pairs the active configuration names FOR THAT
403
+ * ROLE — its everyday agent and its strong agent — and nothing borrowed
404
+ * from another role. Repair runs only the build leg's provider (repairs
405
+ * resume the builder's session): its choices are the configured repair
406
+ * rows on that provider plus the build role's own configured agents on
407
+ * it, so an operator can keep repairs on the builder without naming a
408
+ * repair row. Gemini never reviews. Nothing is typed free-hand and
409
+ * nothing unconfigured is selectable: an approval binds an exact agent
410
+ * the operator named once, in configuration.
411
+ *
412
+ * The role's CURRENT leg rides along marked `current`; when the
413
+ * configuration no longer names it (a stale override, a routine's pin)
414
+ * it is display-only — `selectable: false` — so a surface can say what
415
+ * runs today without offering to re-pick it. Empty when the
416
+ * configuration cannot make exact candidates at all; the surface then
417
+ * says so instead of guessing.
418
+ */
419
+ export function agentChoicesFor(store, repo, route) {
420
+ const empty = { plan: [], build: [], repair: [], review: [] };
421
+ const candidates = resolveRouteCandidates(store, repo);
422
+ if (!candidates.ok)
423
+ return empty;
424
+ const buildProvider = route === null ? candidates.candidates.build.routine.provider : legOf(route, "build").provider;
425
+ const configuredFor = (phase) => {
426
+ const tiers = candidates.candidates[phase];
427
+ const own = phase === "repair"
428
+ ? [tiers.routine, tiers.strong, candidates.candidates.build.routine, candidates.candidates.build.strong]
429
+ : [tiers.routine, tiers.strong];
430
+ const out = [];
431
+ for (const one of own) {
432
+ if (one === null || out.some(seen => sameSpec(seen, one)))
433
+ continue;
434
+ if (phase === "review" && one.provider === "gemini")
435
+ continue;
436
+ if (phase === "repair" && one.provider !== buildProvider)
437
+ continue;
438
+ if (!validateSpec({ provider: one.provider, model: one.model }).ok)
439
+ continue;
440
+ out.push(one);
441
+ }
442
+ return out;
443
+ };
444
+ const out = { plan: [], build: [], repair: [], review: [] };
445
+ for (const phase of PHASES.filter(one => one !== "review")) {
446
+ const current = route === null ? null : legOf(route, phase);
447
+ const offered = configuredFor(phase).map(one => ({ provider: one.provider, model: one.model, source: one.source, current: current !== null && sameSpec(current, one), selectable: true }));
448
+ if (current !== null && !offered.some(one => sameSpec(one, current))) {
449
+ offered.push({ provider: current.provider, model: current.model, source: "this task's current agent — not in today's configuration", current: true, selectable: false });
450
+ }
451
+ out[phase] = offered;
452
+ }
453
+ return out;
454
+ }
@@ -0,0 +1,16 @@
1
+ export type TokenAccess = "read" | "act";
2
+ export declare const TOKEN_DAYS: readonly [30, 90, 365];
3
+ export declare function mintApiToken(): {
4
+ id: string;
5
+ secret: string;
6
+ token: string;
7
+ hash: string;
8
+ };
9
+ export declare const hashSecret: (secret: string) => string;
10
+ /** The id and secret of something shaped like a token, or null. */
11
+ export declare function parseApiToken(presented: string): {
12
+ id: string;
13
+ secret: string;
14
+ } | null;
15
+ /** Whether the secret is the one whose hash was kept, in constant time. */
16
+ export declare function secretMatches(secret: string, keptHash: string): boolean;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * API tokens (v101): what scripts and CI use instead of a password on each
3
+ * request. A token belongs to one person, reads or acts (never more than the
4
+ * person may), always expires (a year at most), is shown once, and only its
5
+ * hash is kept. `Authorization: Bearer so_<id>_<secret>`.
6
+ *
7
+ * A token never passes a step-up: approvals and other password ceremonies
8
+ * stay a person's act in the console.
9
+ */
10
+ import { createHash, randomBytes, timingSafeEqual } from "node:crypto";
11
+ export const TOKEN_DAYS = [30, 90, 365];
12
+ const SHAPE = /^so_([a-f0-9]{12})_([A-Za-z0-9_-]{43})$/;
13
+ export function mintApiToken() {
14
+ const id = randomBytes(6).toString("hex"), secret = randomBytes(32).toString("base64url");
15
+ return { id, secret, token: `so_${id}_${secret}`, hash: hashSecret(secret) };
16
+ }
17
+ export const hashSecret = (secret) => createHash("sha256").update(secret, "utf8").digest("hex");
18
+ /** The id and secret of something shaped like a token, or null. */
19
+ export function parseApiToken(presented) {
20
+ const match = SHAPE.exec(presented);
21
+ return match === null ? null : { id: match[1], secret: match[2] };
22
+ }
23
+ /** Whether the secret is the one whose hash was kept, in constant time. */
24
+ export function secretMatches(secret, keptHash) {
25
+ const a = Buffer.from(hashSecret(secret), "hex"), b = Buffer.from(keptHash, "hex");
26
+ return a.length === b.length && timingSafeEqual(a, b);
27
+ }
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Separation of duties (v102): a project's approval rules. Two can be on at
3
+ * once, and neither changes a thing until a project turns it on.
4
+ *
5
+ * - The person who filed a task can't approve it ("not the requester").
6
+ * - Protected work (the whole project, or tasks that touch protected paths)
7
+ * needs two different people to approve the same exact scope, and an AI
8
+ * teammate or an operating mode can never decide it.
9
+ *
10
+ * The store enforces these at the one place every approval is sealed
11
+ * (`Store.sealScopeApproval`); this module holds the pure parts.
12
+ */
13
+ /** Who filed a task, as far as anyone can tell: a person (browser, chat, a
14
+ * revision), a coordinator acting for the person who made it, an AI
15
+ * teammate, or automation that names no person (a routine, the CLI, a flow
16
+ * with no owner). The requester rule binds only a named person. */
17
+ export type FilerKind = "person" | "coordinator" | "teammate" | "automation";
18
+ export type Filer = {
19
+ name: string | null;
20
+ kind: FilerKind;
21
+ };
22
+ /** A filer from a name as the ledger writes it: an AI teammate's ends " (AI)"; a coordinator's starts "coordinator:"; none is automation. */
23
+ export declare function filerFor(name: string | null | undefined): Filer;
24
+ export type ApprovalRules = {
25
+ notRequester: boolean;
26
+ protectProject: boolean;
27
+ protectedPaths: string[];
28
+ };
29
+ export declare const NO_RULES: ApprovalRules;
30
+ /** Who is sealing: a person at a ceremony, an operating mode, an AI teammate, or automation. */
31
+ export type ApproverKind = "person" | "mode" | "ai" | "automation";
32
+ export type ApprovalGate = {
33
+ verdict: "seal";
34
+ protectedWork: boolean;
35
+ } | {
36
+ verdict: "vote";
37
+ have: number;
38
+ need: 2;
39
+ already: boolean;
40
+ } | {
41
+ verdict: "refuse";
42
+ reason: "requester" | "person-required";
43
+ };
44
+ /** Whether a task that says it touches `touch` may touch something under
45
+ * `protectedGlob`, or a changed file is protected. A plain path covers
46
+ * itself and everything under it; a pattern with no slash matches at any
47
+ * depth (as in .gitignore); two patterns that could reach the same files
48
+ * count as overlapping; a path that climbs out of the checkout is
49
+ * protected. Every doubt errs toward protecting. */
50
+ export declare function touchesProtected(touch: string, protectedGlob: string): boolean;
51
+ /** The changed files (from a build's diff) that the rules protect. */
52
+ export declare function protectedChanges(rules: ApprovalRules, changed: readonly string[]): string[];
53
+ /** Whether a task's declared paths reach protected work. A task that
54
+ * declares no paths can't show it stays clear, so it counts as protected. */
55
+ export declare function isProtectedWork(rules: ApprovalRules, touches: string[]): boolean;
56
+ /** Protected paths as a person types them: one per line or comma separated, trimmed, deduplicated, at most 50. */
57
+ export declare function parseProtectedPaths(raw: string): {
58
+ ok: true;
59
+ paths: string[];
60
+ } | {
61
+ ok: false;
62
+ problem: string;
63
+ };
64
+ /** The rules in a line, for the ledger's before → after. */
65
+ export declare function rulesWords(rules: ApprovalRules): string;
66
+ /** What a person reads when the rules stop an approval. */
67
+ export declare function gateWords(gate: Exclude<ApprovalGate, {
68
+ verdict: "seal";
69
+ }>): string;