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,154 @@
1
+ import { SESSION_REQUEST_BYTES, SESSION_RESPONSE_BYTES, isSessionResponse, sessionDescriptor, validateSessionRequest, } from './session-contract.js';
2
+ function readBody(request) {
3
+ return new Promise(resolve => {
4
+ let size = 0;
5
+ let chunks = [];
6
+ let settled = false;
7
+ const finish = (result) => {
8
+ if (settled)
9
+ return;
10
+ settled = true;
11
+ chunks = [];
12
+ resolve(result);
13
+ };
14
+ const cleanup = () => {
15
+ request.off('data', onData);
16
+ request.off('end', onEnd);
17
+ request.off('aborted', onAborted);
18
+ request.off('error', onError);
19
+ request.off('close', onClose);
20
+ };
21
+ const onData = (chunk) => {
22
+ // After rejecting an oversized request, drain without retaining it.
23
+ if (settled)
24
+ return;
25
+ const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
26
+ size += bytes.length;
27
+ if (size > SESSION_REQUEST_BYTES)
28
+ finish({ ok: false, status: 413, reason: 'request-too-large', message: 'The session request is too large.' });
29
+ else
30
+ chunks.push(bytes);
31
+ };
32
+ const onEnd = () => {
33
+ cleanup();
34
+ if (settled)
35
+ return;
36
+ try {
37
+ const value = JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(Buffer.concat(chunks)));
38
+ finish({ ok: true, value });
39
+ }
40
+ catch {
41
+ finish({ ok: false, status: 400, reason: 'invalid-json', message: 'Send a valid UTF-8 JSON request.' });
42
+ }
43
+ };
44
+ const onAborted = () => {
45
+ finish({ ok: false, status: 400, reason: 'incomplete-request', message: 'The session request did not finish arriving.' });
46
+ };
47
+ const onError = () => { onAborted(); cleanup(); };
48
+ const onClose = () => { onAborted(); cleanup(); };
49
+ request.on('data', onData);
50
+ request.once('end', onEnd);
51
+ request.once('aborted', onAborted);
52
+ request.once('error', onError);
53
+ request.once('close', onClose);
54
+ if (request.aborted)
55
+ onAborted();
56
+ });
57
+ }
58
+ /** Handle this API family before the browser's form parser or login redirects.
59
+ * This adapter dispatches at most once. It owns no catalog, database or provider. */
60
+ export async function handleSessionHttp(request, response, options) {
61
+ const path = (request.url ?? '').split('?')[0] ?? '';
62
+ if (path !== '/api/sessions' && !path.startsWith('/api/sessions/'))
63
+ return false;
64
+ const match = /^\/api\/sessions\/([a-z]+)$/.exec(request.url ?? '');
65
+ const spec = match?.[1] === undefined ? undefined : sessionDescriptor(match[1]);
66
+ const operation = spec?.operation;
67
+ const write = (status, body, notSent = false) => {
68
+ if (response.destroyed || response.writableEnded)
69
+ return;
70
+ response.statusCode = status;
71
+ response.setHeader('content-type', 'application/json; charset=utf-8');
72
+ response.setHeader('content-length', Buffer.byteLength(body));
73
+ response.setHeader('cache-control', 'no-store');
74
+ response.setHeader('x-content-type-options', 'nosniff');
75
+ if (notSent)
76
+ response.setHeader('x-standing-orders-session-delivery', 'not-sent');
77
+ else
78
+ response.removeHeader('x-standing-orders-session-delivery');
79
+ response.end(body);
80
+ };
81
+ const reject = (status, reason, message) => {
82
+ // No owner call has occurred. This marker is never inferred from an
83
+ // exception, a lost response, or a response too large to deliver.
84
+ const reply = { version: 1, ...(operation === undefined ? {} : { operation }), ok: false,
85
+ status: 'rejected', delivery: 'not-sent', retry: spec?.mutation === false ? 'safe-read' : 'never', reason, message, nextActions: [] };
86
+ write(status, JSON.stringify(reply), true);
87
+ request.resume();
88
+ return true;
89
+ };
90
+ if (!spec || operation === undefined)
91
+ return reject(404, 'unsupported-operation', 'This session operation is not supported.');
92
+ if (request.method !== 'POST') {
93
+ response.setHeader('allow', 'POST');
94
+ return reject(405, 'method-not-allowed', 'Session operations require POST.');
95
+ }
96
+ if (request.headers.origin !== undefined)
97
+ return reject(403, 'browser-request', 'Use the authenticated session client for this operation.');
98
+ const authorizationCount = request.rawHeaders.filter((_, index) => index % 2 === 0 && request.rawHeaders[index]?.toLowerCase() === 'authorization').length;
99
+ if (authorizationCount !== 1 || !/^Bearer (.+):(.+)$/.test(request.headers.authorization ?? '')) {
100
+ return reject(401, 'unauthenticated', 'Current operator bearer credentials are required.');
101
+ }
102
+ let actor;
103
+ try {
104
+ actor = await options.authenticate(request);
105
+ }
106
+ catch {
107
+ return reject(503, 'authentication-unavailable', 'Operator access could not be checked. Try again after the service is ready.');
108
+ }
109
+ if (actor === null || typeof actor.name !== 'string' || !actor.name.trim() || !Number.isSafeInteger(actor.generation) || actor.generation < 1) {
110
+ return reject(401, 'unauthenticated', 'Current operator bearer credentials are required.');
111
+ }
112
+ const media = request.headers['content-type']?.split(';')[0]?.trim().toLowerCase();
113
+ if (media !== 'application/json')
114
+ return reject(415, 'unsupported-media-type', 'Send the session request as application/json.');
115
+ const length = request.headers['content-length'];
116
+ if (length !== undefined && Number(length) > SESSION_REQUEST_BYTES)
117
+ return reject(413, 'request-too-large', 'The session request is too large.');
118
+ if (options.execute === null)
119
+ return reject(503, 'session-unavailable', 'The session owner is not ready.');
120
+ const body = await readBody(request);
121
+ if (!body.ok)
122
+ return reject(body.status, body.reason, body.message);
123
+ const validated = validateSessionRequest(operation, body.value);
124
+ if (!validated.ok)
125
+ return reject(400, 'invalid-request', validated.message);
126
+ if (request.aborted || response.destroyed)
127
+ return true;
128
+ const uncertain = (reason, message) => {
129
+ const sessionId = 'sessionId' in validated.request ? validated.request.sessionId : undefined;
130
+ return { version: 1, operation, ok: false, status: 'uncertain', delivery: 'unknown', retry: 'inspect-first', reason, message,
131
+ nextActions: [{ operation: sessionId ? 'show' : 'list', label: sessionId ? 'Inspect session' : 'Inspect saved sessions', ...(sessionId ? { sessionId } : {}) }] };
132
+ };
133
+ let reply;
134
+ let encoded;
135
+ let status;
136
+ try {
137
+ reply = await options.execute(actor, operation, validated.request);
138
+ if (!isSessionResponse(reply, operation))
139
+ throw new Error('Invalid owner response');
140
+ encoded = JSON.stringify(reply);
141
+ if (Buffer.byteLength(encoded) > SESSION_RESPONSE_BYTES) {
142
+ reply = uncertain('response-too-large', 'The owner response is too large to deliver. Inspect saved activity before continuing; this request was not retried.');
143
+ encoded = JSON.stringify(reply);
144
+ }
145
+ status = reply.status === 'rejected' ? 409 : reply.status === 'uncertain' ? 502 : reply.status === 'pending' ? 202 : 200;
146
+ }
147
+ catch {
148
+ reply = uncertain('unconfirmed-response', 'The owner response could not be confirmed. Inspect saved activity before continuing; this request was not retried.');
149
+ encoded = JSON.stringify(reply);
150
+ status = 502;
151
+ }
152
+ write(status, encoded);
153
+ return true;
154
+ }
@@ -0,0 +1,12 @@
1
+ import type { IncomingMessage, ServerResponse } from 'node:http';
2
+ import type { Store } from './store.js';
3
+ import type { CodingWorkspace } from './coding-workspace.js';
4
+ /** Bind the transport to createDecisionServer's existing catalog owner and
5
+ * live project admission. No cookie, coordinator token or caller-supplied actor
6
+ * can acquire installation-wide native coding authority through this adapter. */
7
+ export declare function createSessionEndpoint(options: {
8
+ store: Store;
9
+ workspace: CodingWorkspace | null;
10
+ projects: () => readonly string[];
11
+ projectAllowed: (repo: string) => boolean;
12
+ }): (request: IncomingMessage, response: ServerResponse) => Promise<boolean>;
@@ -0,0 +1,37 @@
1
+ import { realpathSync } from 'node:fs';
2
+ import { authenticateAccount } from './scope.js';
3
+ import { handleSessionHttp } from './session-http.js';
4
+ import { SessionService } from './session-service.js';
5
+ /** Bind the transport to createDecisionServer's existing catalog owner and
6
+ * live project admission. No cookie, coordinator token or caller-supplied actor
7
+ * can acquire installation-wide native coding authority through this adapter. */
8
+ export function createSessionEndpoint(options) {
9
+ const { store } = options;
10
+ const authorized = (actor, repo) => {
11
+ const account = store.accountOf(actor.name);
12
+ return account !== null && account.revokedAt === null && account.generation === actor.generation && store.isInstanceOperator(actor.name)
13
+ && (repo === undefined || (options.projectAllowed(repo) && options.projects().includes(repo)));
14
+ };
15
+ const service = options.workspace === null || store.isDemo() ? null : new SessionService({ workspace: options.workspace, authorized,
16
+ project: (actor, input) => {
17
+ const path = realpathSync(input);
18
+ if (!authorized(actor, path) || !options.projects().includes(path))
19
+ throw Error('Choose a project already admitted to this installation.');
20
+ return path;
21
+ },
22
+ });
23
+ return (request, response) => handleSessionHttp(request, response, {
24
+ authenticate: request => {
25
+ const bearer = /^Bearer (.+):(.+)$/.exec(request.headers.authorization ?? '');
26
+ if (!bearer)
27
+ return null;
28
+ const name = bearer[1];
29
+ const authentication = authenticateAccount(store, name, bearer[2]);
30
+ if (!authentication.ok)
31
+ return null;
32
+ const actor = { name, generation: authentication.generation };
33
+ return authorized(actor) ? actor : null;
34
+ },
35
+ execute: service === null ? null : (actor, operation, request) => service.execute(actor, operation, request),
36
+ });
37
+ }
@@ -0,0 +1,22 @@
1
+ import { CodingWorkspace, type CodingActor } from './coding-workspace.js';
2
+ import { type SessionOperation, type SessionResponse } from './session-contract.js';
3
+ type Options = {
4
+ workspace: CodingWorkspace;
5
+ /** Recheck the live account generation and installation-wide operator role. */
6
+ authorized: (actor: CodingActor, repo?: string) => boolean;
7
+ /** Resolve only an admitted project. Never accept an arbitrary filesystem path. */
8
+ project: (actor: CodingActor, project: string) => string;
9
+ };
10
+ /** A narrow projection and operation boundary shared by authenticated adapters.
11
+ * This object never opens a second catalog or starts a competing provider. */
12
+ export declare class SessionService {
13
+ private readonly options;
14
+ constructor(options: Options);
15
+ private authorize;
16
+ private view;
17
+ private next;
18
+ private inspect;
19
+ private result;
20
+ execute<O extends SessionOperation>(actor: CodingActor, operation: O, value: unknown): Promise<SessionResponse>;
21
+ }
22
+ export {};
@@ -0,0 +1,157 @@
1
+ import { realpathSync } from 'node:fs';
2
+ import { CodingActionError, CodingWorkspace } from './coding-workspace.js';
3
+ import { sessionDescriptor, validateSessionRequest } from './session-contract.js';
4
+ import { savedSessionBrief } from './session-brief.js';
5
+ const mutationMessages = { start: 'Session started.', send: 'Message delivered.', stop: 'Stop requested.', resume: 'Session reconnected.', recover: 'Saved activity reconciled. Inspect the current state before continuing.' };
6
+ const expectedOf = (input) => ({ revision: input.expectedRevision, nativeThreadId: input.expectedThreadId, turnId: input.expectedTurnId });
7
+ /** A narrow projection and operation boundary shared by authenticated adapters.
8
+ * This object never opens a second catalog or starts a competing provider. */
9
+ export class SessionService {
10
+ options;
11
+ constructor(options) {
12
+ this.options = options;
13
+ }
14
+ authorize(actor, repo) {
15
+ if (!this.options.authorized(actor, repo))
16
+ throw new CodingActionError('This operation requires current operator access to the project.', 'rejected');
17
+ }
18
+ view(actor, id) {
19
+ const session = this.options.workspace.get(id, actor);
20
+ this.authorize(actor, session.repo);
21
+ return { id: session.id, repo: session.repo, title: session.title, status: session.status,
22
+ nativeThreadId: session.nativeThreadId, turnId: session.turnId,
23
+ revision: this.options.workspace.revision(id, actor), branch: session.branch, base: session.base,
24
+ error: session.error, deliveryReviewRequired: session.deliveryReviewRequired === true, updatedAt: session.updatedAt };
25
+ }
26
+ next(session) {
27
+ if (!session)
28
+ return [{ operation: 'list', label: 'Inspect sessions' }];
29
+ const sessionId = session.id;
30
+ const read = [{ operation: 'show', label: 'Inspect session', sessionId }, { operation: 'changes', label: 'Review changes', sessionId }];
31
+ if (session.deliveryReviewRequired || session.status === 'needs-input')
32
+ return [{ operation: 'open-ui', label: session.deliveryReviewRequired ? 'Review uncertain delivery' : 'Answer in the workspace', sessionId }, ...read];
33
+ if (session.status === 'uncertain')
34
+ return [{ operation: 'recover', label: 'Reconcile saved activity', sessionId }, ...read];
35
+ if (session.status === 'interrupted')
36
+ return [{ operation: 'resume', label: 'Reconnect session', sessionId }, ...read];
37
+ if (session.status === 'ready')
38
+ return [{ operation: 'send', label: 'Continue session', sessionId }, ...read];
39
+ if (session.status === 'working')
40
+ return [...read, { operation: 'send', label: 'Send a follow-up', sessionId }, { operation: 'stop', label: 'Stop this turn', sessionId }];
41
+ return read;
42
+ }
43
+ inspect(session) {
44
+ if (!session)
45
+ return [{ operation: 'list', label: 'Inspect saved sessions' }];
46
+ const sessionId = session.id;
47
+ const next = [{ operation: 'show', label: 'Inspect saved session', sessionId }, { operation: 'changes', label: 'Review changes', sessionId }];
48
+ if (session.deliveryReviewRequired || session.status === 'needs-input')
49
+ next.push({ operation: 'open-ui', label: session.deliveryReviewRequired ? 'Review uncertain delivery' : 'Answer in the workspace', sessionId });
50
+ else if (session.status === 'uncertain')
51
+ next.push({ operation: 'recover', label: 'Reconcile saved activity', sessionId });
52
+ return next;
53
+ }
54
+ result(actor, id, activity = false) {
55
+ const snapshot = this.options.workspace.snapshotBounded(id, actor), session = this.view(actor, id);
56
+ // Keep recent context and explicitly label omitted history. Native history
57
+ // remains authoritative; this bounded transport is not a memory rewrite.
58
+ let remaining = 1_000_000;
59
+ const items = [];
60
+ for (const item of snapshot.items.slice(-100).reverse()) {
61
+ const bytes = Buffer.byteLength(JSON.stringify(item));
62
+ if (bytes > remaining)
63
+ break;
64
+ items.unshift(item);
65
+ remaining -= bytes;
66
+ }
67
+ const requests = snapshot.requests.slice(0, 50).map(({ id, kind, title, detail }) => ({ id, kind, title: title.slice(0, 1000), detail: detail.slice(0, 8000) }));
68
+ const next = this.next(session)[0]?.label ?? 'Inspect session';
69
+ const truncated = snapshot.truncated || items.length !== snapshot.items.length || requests.length !== snapshot.requests.length || snapshot.requests.some(request => request.title.length > 1000 || request.detail.length > 8000);
70
+ return { session, ...(activity ? { items, requests } : {}), truncated, brief: savedSessionBrief(session, items, next, truncated) };
71
+ }
72
+ async execute(actor, operation, value) {
73
+ const rejected = (message, reason) => ({ version: 1, operation, ok: false, status: 'rejected', delivery: 'not-sent', retry: 'never', message, reason, nextActions: [] });
74
+ const validation = validateSessionRequest(operation, value);
75
+ if (!validation.ok)
76
+ return rejected(validation.message, 'invalid-request');
77
+ const input = validation.request;
78
+ const workspace = this.options.workspace;
79
+ let deliveryMayHaveOccurred = false;
80
+ try {
81
+ this.authorize(actor);
82
+ if (operation === 'list') {
83
+ const request = input;
84
+ const repo = request.project ? this.options.project(actor, request.project) : undefined;
85
+ const page = workspace.listBounded(actor, { limit: request.limit ?? 50, ...(repo === undefined ? {} : { repo }), authorized: project => this.options.authorized(actor, project) });
86
+ const sessions = page.sessions.map(s => this.view(actor, s.id));
87
+ return { version: 1, operation, ok: true, status: 'succeeded', delivery: 'confirmed', retry: 'safe-read', message: `${sessions.length} sessions${page.truncated ? ' shown; more may be available' : ''}.`, nextActions: [], result: { sessions, truncated: page.truncated } };
88
+ }
89
+ if (operation === 'show' || operation === 'changes') {
90
+ const { sessionId } = input;
91
+ this.view(actor, sessionId);
92
+ const changes = operation === 'changes' ? await workspace.changes(sessionId, actor) : undefined;
93
+ const result = this.result(actor, sessionId, operation === 'show' && input.view === 'activity');
94
+ if (changes)
95
+ result.changes = changes;
96
+ return { version: 1, operation, ok: true, status: 'succeeded', delivery: 'confirmed', retry: 'safe-read', message: 'Saved session loaded.', nextActions: this.next(result.session), result };
97
+ }
98
+ const request = input;
99
+ let repo;
100
+ if (operation === 'start') {
101
+ repo = realpathSync(this.options.project(actor, request.project));
102
+ this.authorize(actor, repo);
103
+ }
104
+ else
105
+ this.view(actor, request.sessionId);
106
+ // Stable field order makes a JSON field-order difference the same request.
107
+ const fingerprint = JSON.stringify([operation, Object.keys(request).sort().map(k => [k, request[k]]), repo ?? null]);
108
+ const receipt = await workspace.command(actor, request.key, fingerprint, () => this.authorize(actor, repo), async () => {
109
+ const sessionId = operation === 'start' ? null : request.sessionId;
110
+ try {
111
+ this.authorize(actor, repo);
112
+ if (sessionId) {
113
+ this.view(actor, sessionId);
114
+ workspace.assertExpected(sessionId, actor, expectedOf(request));
115
+ }
116
+ }
117
+ catch (error) {
118
+ throw error instanceof CodingActionError ? error : new CodingActionError(error instanceof Error ? error.message : 'This session is unavailable.', 'rejected', sessionId ?? undefined);
119
+ }
120
+ deliveryMayHaveOccurred = true;
121
+ if (operation === 'start') {
122
+ const start = request;
123
+ return (await workspace.start(actor, { repo: repo, title: start.title, prompt: start.prompt, model: start.model ?? null, requestId: start.key })).id;
124
+ }
125
+ const expected = expectedOf(request);
126
+ if (operation === 'send')
127
+ await workspace.send(sessionId, actor, request.prompt, request.key, expected);
128
+ else if (operation === 'stop')
129
+ await workspace.stop(sessionId, actor, expected);
130
+ else if (operation === 'resume')
131
+ await workspace.resume(sessionId, actor, expected);
132
+ else if (operation === 'recover')
133
+ await workspace.recover(sessionId, actor, expected);
134
+ return sessionId;
135
+ });
136
+ // A replay reads a prior receipt without performing again. Losing access
137
+ // or failing to project that result cannot prove the original was unsent.
138
+ deliveryMayHaveOccurred ||= receipt.status !== 'rejected';
139
+ const id = receipt.sessionId ?? (operation === 'start' ? undefined : request.sessionId);
140
+ const result = { ...(id ? this.result(actor, id) : {}), receipt: { key: request.key, status: receipt.status } };
141
+ const status = receipt.status === 'accepted' ? 'succeeded' : receipt.status === 'pending' && result.session ? 'pending' : receipt.status === 'rejected' ? 'rejected' : 'uncertain';
142
+ const nextActions = status === 'pending' || status === 'uncertain' ? this.inspect(result.session) : this.next(result.session);
143
+ if (result.brief && (status === 'pending' || status === 'uncertain'))
144
+ result.brief = { ...result.brief, nextAction: nextActions[0]?.label ?? 'Inspect saved session' };
145
+ return { version: 1, operation, ok: status === 'succeeded' || status === 'pending', status,
146
+ delivery: status === 'rejected' ? 'not-sent' : status === 'uncertain' ? 'unknown' : 'confirmed', retry: 'inspect-first',
147
+ message: receipt.message ?? (status === 'succeeded' ? mutationMessages[operation] : 'Inspect saved activity before continuing. This request will not be sent again.'),
148
+ nextActions, result };
149
+ }
150
+ catch (error) {
151
+ const message = error instanceof Error ? error.message : 'The session operation could not finish.';
152
+ if (deliveryMayHaveOccurred)
153
+ return { version: 1, operation, ok: false, status: 'uncertain', delivery: 'unknown', retry: 'inspect-first', message, reason: 'unconfirmed-response', nextActions: [{ operation: 'list', label: 'Inspect saved sessions' }] };
154
+ return rejected(message, sessionDescriptor(operation)?.mutation ? 'not-admitted' : 'unavailable');
155
+ }
156
+ }
157
+ }
@@ -0,0 +1,39 @@
1
+ import { type ProviderId } from "./provider.js";
2
+ export declare const ASSISTANTS: Record<ProviderId, {
3
+ name: string;
4
+ description: string;
5
+ }>;
6
+ export type ModelChoice = {
7
+ value: string;
8
+ label: string;
9
+ };
10
+ export declare function modelChoices(provider: ProviderId, configured: string | null, home?: string): ModelChoice[];
11
+ export declare function detectPreparation(repo: string): {
12
+ command: string;
13
+ label: string;
14
+ evidence: string;
15
+ } | null;
16
+ /** Browser installation may write only this known file inside its project. */
17
+ export declare function previewProjectInstructions(repo: string): {
18
+ ok: false;
19
+ message: string;
20
+ plan?: never;
21
+ content?: never;
22
+ fingerprint?: never;
23
+ installed?: never;
24
+ } | {
25
+ message?: never;
26
+ ok: true;
27
+ plan: import("./skills.js").InstallPlan;
28
+ content: string;
29
+ fingerprint: string;
30
+ installed: boolean;
31
+ };
32
+ export declare function addProjectInstructions(repo: string, fingerprint: string): {
33
+ ok: false;
34
+ message: string;
35
+ plan?: never;
36
+ content?: never;
37
+ fingerprint?: never;
38
+ installed?: never;
39
+ } | import("./skills.js").InstallResult;
@@ -0,0 +1,93 @@
1
+ /** Read-only suggestions for the shared desktop and browser setup flow. */
2
+ import { createHash } from "node:crypto";
3
+ import { existsSync, lstatSync, readFileSync } from "node:fs";
4
+ import { homedir } from "node:os";
5
+ import { join } from "node:path";
6
+ import { validModelId } from "./provider.js";
7
+ import { planInstall, applyInstall, skillContent, SKILL_DIR, SKILL_FILE } from "./skills.js";
8
+ export const ASSISTANTS = {
9
+ claude: { name: "Claude", description: "Use Claude Code for your tasks." },
10
+ codex: { name: "Codex", description: "Use your OpenAI coding assistant." },
11
+ gemini: { name: "Gemini", description: "Use Google's coding assistant." },
12
+ openrouter: { name: "OpenRouter", description: "Use a model from your OpenRouter account." },
13
+ };
14
+ export function modelChoices(provider, configured, home = homedir()) {
15
+ // Aliases documented at https://code.claude.com/docs/en/model-config.
16
+ let choices = provider === "claude"
17
+ ? [{ value: "sonnet", label: "Sonnet — everyday coding" }, { value: "opus", label: "Opus — complex tasks" },
18
+ { value: "haiku", label: "Haiku — smaller tasks" }]
19
+ : [];
20
+ if (provider === "codex") {
21
+ // Use the local CLI's own catalog, including account-specific availability.
22
+ try {
23
+ const path = join(home, ".codex", "models_cache.json");
24
+ if (lstatSync(path).size < 2_000_000) {
25
+ const data = JSON.parse(readFileSync(path, "utf8"));
26
+ choices = (Array.isArray(data.models) ? data.models : []).filter(one => one != null && one.visibility === "list" && typeof one.slug === "string" && validModelId(one.slug))
27
+ .slice(0, 30).map(one => ({ value: one.slug, label: typeof one.display_name === "string" ? one.display_name.slice(0, 80) : one.slug }));
28
+ }
29
+ }
30
+ catch { /* A missing catalog leaves the explicit model option available. */ }
31
+ }
32
+ if (configured && !choices.some(one => one.value === configured))
33
+ choices.unshift({ value: configured, label: `${configured} — current choice` });
34
+ return choices;
35
+ }
36
+ export function detectPreparation(repo) {
37
+ const has = (file) => existsSync(join(repo, file));
38
+ if (has("package.json")) {
39
+ if (has("pnpm-lock.yaml"))
40
+ return { command: "pnpm install --frozen-lockfile", label: "Install project dependencies with pnpm", evidence: "pnpm-lock.yaml" };
41
+ if (has("yarn.lock"))
42
+ return { command: has(".yarnrc.yml") ? "yarn install --immutable" : "yarn install --frozen-lockfile", label: "Install project dependencies with Yarn", evidence: "yarn.lock" };
43
+ if (has("package-lock.json") || has("npm-shrinkwrap.json"))
44
+ return { command: "npm ci", label: "Install project dependencies with npm", evidence: has("package-lock.json") ? "package-lock.json" : "npm-shrinkwrap.json" };
45
+ if (has("bun.lock") || has("bun.lockb"))
46
+ return { command: "bun install --frozen-lockfile", label: "Install project dependencies with Bun", evidence: "Bun lockfile" };
47
+ return { command: "npm install", label: "Install project dependencies with npm", evidence: "package.json" };
48
+ }
49
+ if (has("uv.lock") && has("pyproject.toml"))
50
+ return { command: "uv sync --frozen", label: "Prepare the Python environment with uv", evidence: "uv.lock" };
51
+ if (has("Cargo.lock"))
52
+ return { command: "cargo fetch --locked", label: "Download Rust dependencies", evidence: "Cargo.lock" };
53
+ if (has("go.mod"))
54
+ return { command: "go mod download", label: "Download Go dependencies", evidence: "go.mod" };
55
+ return null;
56
+ }
57
+ /** Browser installation may write only this known file inside its project. */
58
+ export function previewProjectInstructions(repo) {
59
+ try {
60
+ if (!lstatSync(repo).isDirectory())
61
+ return { ok: false, message: "This project folder is unavailable. Reconnect it before adding instructions." };
62
+ }
63
+ catch {
64
+ return { ok: false, message: "This project folder is unavailable. Reconnect it before adding instructions." };
65
+ }
66
+ for (const relative of [".claude", ".claude/skills", SKILL_DIR, join(SKILL_DIR, SKILL_FILE)]) {
67
+ const path = join(repo, relative);
68
+ try {
69
+ const entry = lstatSync(path);
70
+ if (entry.isSymbolicLink() || (relative === join(SKILL_DIR, SKILL_FILE) ? !entry.isFile() || entry.size > 2_000_000 : !entry.isDirectory()))
71
+ return { ok: false, message: "Project instructions use a linked folder or file. Choose a regular project folder before adding them." };
72
+ }
73
+ catch (error) {
74
+ if (error.code !== "ENOENT")
75
+ throw error;
76
+ }
77
+ }
78
+ const plan = planInstall(repo, false);
79
+ if (plan.skillAction === "refuse-foreign")
80
+ return { ok: false, message: "This project already has custom Toolroll instructions. They will be kept. You can continue setup without replacing them." };
81
+ const content = skillContent();
82
+ const current = existsSync(plan.skillPath) ? readFileSync(plan.skillPath, "utf8") : null;
83
+ const fingerprint = createHash("sha256").update(JSON.stringify({ repo, current, content })).digest("hex");
84
+ return { ok: true, plan, content, fingerprint, installed: current === content };
85
+ }
86
+ export function addProjectInstructions(repo, fingerprint) {
87
+ const preview = previewProjectInstructions(repo);
88
+ if (!preview.ok)
89
+ return preview;
90
+ if (preview.fingerprint !== fingerprint)
91
+ return { ok: false, message: "The project instructions changed. Review them again before saving." };
92
+ return applyInstall(repo, false);
93
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Password guessing (v99). Five wrong passwords in a row lock that account
3
+ * for 15 minutes, doubling with each further lock up to a day; a right one
4
+ * clears the count. Every password check counts: signing in, a request that
5
+ * carries a password, and each step-up inside the console. Unknown names
6
+ * count too, so guessing names gains nothing.
7
+ *
8
+ * Kept in memory, per database: a restart forgives, which someone locked out
9
+ * by another's guessing may need. The console reports each lock to the
10
+ * action ledger through onLock.
11
+ */
12
+ export type GuardPolicy = {
13
+ failuresBeforeLock: number;
14
+ firstLockMs: number;
15
+ maxLockMs: number;
16
+ };
17
+ export declare const DEFAULT_GUARD_POLICY: GuardPolicy;
18
+ export declare class PasswordGuard {
19
+ readonly policy: GuardPolicy;
20
+ private readonly accounts;
21
+ /** Told once per lock: the account (as typed), and for how long. */
22
+ onLock: ((account: string, lockMs: number) => void) | null;
23
+ constructor(policy?: GuardPolicy);
24
+ private static key;
25
+ /** Milliseconds this account stays locked (0: it may try). */
26
+ lockedFor(account: string, now: number): number;
27
+ failed(account: string, now: number): void;
28
+ succeeded(account: string): void;
29
+ }
30
+ /** The guard for one database (a store): every password check against it counts. */
31
+ export declare function passwordGuardOf(owner: object): PasswordGuard;
32
+ /**
33
+ * Wrong passwords from one address, across every account: at most `tries`
34
+ * in `windowMs`. What a lockout per account can't see (one address trying
35
+ * many names) this does.
36
+ */
37
+ export declare class SourceBudget {
38
+ readonly tries: number;
39
+ readonly windowMs: number;
40
+ private readonly sources;
41
+ constructor(tries?: number, windowMs?: number);
42
+ /** Milliseconds until this address may try again (0: it may). */
43
+ waitFor(source: string, now: number): number;
44
+ failed(source: string, now: number): void;
45
+ }
@@ -0,0 +1,74 @@
1
+ export const DEFAULT_GUARD_POLICY = { failuresBeforeLock: 5, firstLockMs: 15 * 60_000, maxLockMs: 24 * 60 * 60_000 };
2
+ const TRACKED = 10_000;
3
+ export class PasswordGuard {
4
+ policy;
5
+ accounts = new Map();
6
+ /** Told once per lock: the account (as typed), and for how long. */
7
+ onLock = null;
8
+ constructor(policy = DEFAULT_GUARD_POLICY) {
9
+ this.policy = policy;
10
+ }
11
+ static key(account) { return account.trim().toLowerCase().slice(0, 64); }
12
+ /** Milliseconds this account stays locked (0: it may try). */
13
+ lockedFor(account, now) {
14
+ const state = this.accounts.get(PasswordGuard.key(account));
15
+ return state === undefined ? 0 : Math.max(0, state.lockedUntil - now);
16
+ }
17
+ failed(account, now) {
18
+ const key = PasswordGuard.key(account);
19
+ const state = this.accounts.get(key) ?? { failures: 0, lockedUntil: 0, locks: 0 };
20
+ this.accounts.delete(key);
21
+ state.failures += 1;
22
+ if (state.failures >= this.policy.failuresBeforeLock) {
23
+ const lockMs = Math.min(this.policy.maxLockMs, this.policy.firstLockMs * 2 ** state.locks);
24
+ state.lockedUntil = now + lockMs;
25
+ state.locks += 1;
26
+ state.failures = 0;
27
+ this.onLock?.(account.trim().slice(0, 64), lockMs);
28
+ }
29
+ this.accounts.set(key, state);
30
+ // Bounded: the oldest tracked names go first.
31
+ while (this.accounts.size > TRACKED)
32
+ this.accounts.delete(this.accounts.keys().next().value);
33
+ }
34
+ succeeded(account) {
35
+ this.accounts.delete(PasswordGuard.key(account));
36
+ }
37
+ }
38
+ const guards = new WeakMap();
39
+ /** The guard for one database (a store): every password check against it counts. */
40
+ export function passwordGuardOf(owner) {
41
+ let guard = guards.get(owner);
42
+ if (guard === undefined) {
43
+ guard = new PasswordGuard();
44
+ guards.set(owner, guard);
45
+ }
46
+ return guard;
47
+ }
48
+ /**
49
+ * Wrong passwords from one address, across every account: at most `tries`
50
+ * in `windowMs`. What a lockout per account can't see (one address trying
51
+ * many names) this does.
52
+ */
53
+ export class SourceBudget {
54
+ tries;
55
+ windowMs;
56
+ sources = new Map();
57
+ constructor(tries = 20, windowMs = 10 * 60_000) {
58
+ this.tries = tries;
59
+ this.windowMs = windowMs;
60
+ }
61
+ /** Milliseconds until this address may try again (0: it may). */
62
+ waitFor(source, now) {
63
+ const recent = (this.sources.get(source) ?? []).filter(at => now - at < this.windowMs);
64
+ return recent.length < this.tries ? 0 : this.windowMs - (now - recent[0]);
65
+ }
66
+ failed(source, now) {
67
+ const recent = (this.sources.get(source) ?? []).filter(at => now - at < this.windowMs);
68
+ recent.push(now);
69
+ this.sources.delete(source);
70
+ this.sources.set(source, recent.slice(-this.tries));
71
+ while (this.sources.size > TRACKED)
72
+ this.sources.delete(this.sources.keys().next().value);
73
+ }
74
+ }
@@ -0,0 +1,11 @@
1
+ import type { SkillsSnapshot, SkillsView, skillTestResult } from "./project-skills.js";
2
+ export declare const SKILLS_CSS = ".skills{max-width:780px;min-width:0;overflow-wrap:anywhere}.skills h2{font-size:1.1rem}.skills .card{padding:18px;margin:14px 0;min-width:0}.skills form,.skills label{display:grid;gap:10px}.skills input,.skills textarea,.skills select{box-sizing:border-box;width:100%;max-width:100%;min-width:0}.skills textarea{resize:vertical;min-height:130px}.skills button{justify-self:start;white-space:nowrap;min-height:44px}.skills summary{cursor:pointer;min-height:44px;display:flex;align-items:center;gap:10px;flex-wrap:wrap}.skills pre{white-space:pre-wrap;overflow-wrap:anywhere;max-height:360px;overflow:auto;font-size:.9rem}.skills .skill-heading{display:flex;align-items:baseline;justify-content:space-between;gap:12px}.skills .skill-heading h2{margin:0}.skills .skill-state{font-size:.85rem;flex-shrink:0}.skills .skill-source{font-size:.85rem}.skills .skill-controls{display:flex;gap:12px;flex-wrap:wrap}.skills .skill-controls form{margin:0}.skills details details{margin-top:10px}.skills [hidden]{display:none!important}.skills .skill-files{max-height:200px;overflow:auto}.skills .problem{padding:12px}@media(max-width:600px){.skills input,.skills textarea,.skills select{font-size:16px}.skills .card{padding:14px}.skills .skill-heading{align-items:flex-start}}";
3
+ export declare function skillsHtml(view: SkillsView, csrf: string, canManage: boolean, options?: {
4
+ focus?: string;
5
+ error?: string;
6
+ draft?: Record<string, string>;
7
+ agent?: string;
8
+ }): string;
9
+ export declare function skillsSnapshotHtml(snapshot: SkillsSnapshot | null): string;
10
+ export declare function skillsScript(): string;
11
+ export declare function skillTestFeedbackHtml(test: NonNullable<ReturnType<typeof skillTestResult>>, csrf: string, canManage: boolean, error?: string, draft?: string): string;