toolroll 0.9.104 → 0.9.105

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 (1519) hide show
  1. package/CHANGELOG.md +62 -5
  2. package/README.md +18 -20
  3. package/dist/accent-colors.js +0 -29
  4. package/dist/acp-agents.js +0 -3
  5. package/dist/acp-attest.js +0 -30
  6. package/dist/acp-check.js +3 -70
  7. package/dist/acp-client.js +3 -94
  8. package/dist/acp-inspect.js +1 -20
  9. package/dist/action-ledger.js +0 -8
  10. package/dist/activity-line.js +0 -14
  11. package/dist/actor.js +0 -15
  12. package/dist/advanced-schema.js +12 -0
  13. package/dist/advanced-view.js +26 -0
  14. package/dist/advanced.js +61 -0
  15. package/dist/agent-board.js +0 -117
  16. package/dist/agent-fence.js +11 -367
  17. package/dist/agent-onboard.js +12 -50
  18. package/dist/agent-pulse.js +5 -38
  19. package/dist/agent-state-words.js +0 -8
  20. package/dist/agent-state.js +1 -45
  21. package/dist/agent-turns.js +3 -17
  22. package/dist/agentconfig.js +1 -99
  23. package/dist/agents-board.js +0 -60
  24. package/dist/agents-live.js +1 -8
  25. package/dist/api-tokens.js +0 -27
  26. package/dist/approval-authority.js +0 -59
  27. package/dist/approval-password.js +0 -10
  28. package/dist/approval-policy.js +0 -29
  29. package/dist/approval-rules-ui.js +0 -9
  30. package/dist/assignment-adapters.js +0 -14
  31. package/dist/assignment-brief.js +1 -17
  32. package/dist/assignment-delivery.js +0 -22
  33. package/dist/assignment-presentation.js +0 -14
  34. package/dist/assignment-status.js +1 -30
  35. package/dist/assignment-ui.js +0 -12
  36. package/dist/assignment.js +17 -139
  37. package/dist/attest.js +0 -38
  38. package/dist/audit-cli.js +0 -9
  39. package/dist/backend.js +0 -59
  40. package/dist/backup-ui.js +0 -12
  41. package/dist/backup.js +8 -61
  42. package/dist/batch-checks.js +0 -20
  43. package/dist/batch-policy.js +0 -4
  44. package/dist/beads.js +0 -48
  45. package/dist/bin.js +0 -8
  46. package/dist/board.js +1 -36
  47. package/dist/boot-identity.js +0 -42
  48. package/dist/bounded-spawn.js +4 -28
  49. package/dist/brand-mark.js +0 -21
  50. package/dist/brief-fence.js +0 -16
  51. package/dist/browser/terminal.css +1 -1
  52. package/dist/browser/terminal.js +16 -16
  53. package/dist/browser/workspace.css +2 -2
  54. package/dist/browser/workspace.js +26 -26
  55. package/dist/browser-crew.js +0 -8
  56. package/dist/browser-shell.js +2 -15
  57. package/dist/browser-workspace.js +6 -30
  58. package/dist/budget-alerts.js +1 -4
  59. package/dist/build-review.js +2 -50
  60. package/dist/builder-restart.js +0 -13
  61. package/dist/builder.js +21 -1035
  62. package/dist/canonical-json.js +0 -12
  63. package/dist/capscan.js +1 -32
  64. package/dist/card-catalog.js +0 -12
  65. package/dist/card-cli.js +0 -1
  66. package/dist/card-render.js +0 -25
  67. package/dist/card-sources.js +0 -10
  68. package/dist/chat-acceptance.js +0 -7
  69. package/dist/chat-actions.js +5 -190
  70. package/dist/chat-admission.js +0 -7
  71. package/dist/chat-approval.js +0 -25
  72. package/dist/chat-ask.js +0 -17
  73. package/dist/chat-card-part.js +0 -3
  74. package/dist/chat-card.js +0 -6
  75. package/dist/chat-channel.js +2 -83
  76. package/dist/chat-continuity.js +0 -31
  77. package/dist/chat-controls.js +0 -7
  78. package/dist/chat-core.js +0 -55
  79. package/dist/chat-decide.js +2 -153
  80. package/dist/chat-delivery-state.js +0 -49
  81. package/dist/chat-delivery.js +2 -143
  82. package/dist/chat-display.js +0 -2
  83. package/dist/chat-evidence.js +0 -65
  84. package/dist/chat-flow.js +0 -72
  85. package/dist/chat-follow.js +0 -13
  86. package/dist/chat-inbox.js +0 -34
  87. package/dist/chat-live-schema.js +0 -14
  88. package/dist/chat-live.js +2 -87
  89. package/dist/chat-message-states.js +13 -40
  90. package/dist/chat-messages.js +0 -153
  91. package/dist/chat-migration.js +0 -57
  92. package/dist/chat-polish.js +0 -7
  93. package/dist/chat-quiet.js +0 -37
  94. package/dist/chat-review.js +0 -4
  95. package/dist/chat-rooms.js +0 -22
  96. package/dist/chat-settings-page.js +0 -4
  97. package/dist/chat-task-actions.js +0 -7
  98. package/dist/chat-terms.js +0 -21
  99. package/dist/chat-voice.js +0 -38
  100. package/dist/chat-warmth.js +1 -3
  101. package/dist/check-access.js +0 -30
  102. package/dist/check-facts.js +2 -62
  103. package/dist/check-failure.js +0 -98
  104. package/dist/check-levels-ui.js +4 -10
  105. package/dist/check-levels.js +3 -35
  106. package/dist/check-load.js +1 -49
  107. package/dist/check-only-standing.js +0 -6
  108. package/dist/check-only.js +0 -22
  109. package/dist/check-progress.js +0 -32
  110. package/dist/check-repair.js +2 -35
  111. package/dist/check-report.js +1 -108
  112. package/dist/check-stamp.js +0 -20
  113. package/dist/checkout-cleanup.js +0 -84
  114. package/dist/checkout-proof.js +1 -13
  115. package/dist/child-database.js +0 -3
  116. package/dist/claim.js +4 -508
  117. package/dist/claude-print.js +0 -10
  118. package/dist/cli-fast.js +0 -8
  119. package/dist/cli-help.js +90 -78
  120. package/dist/cli-http.js +0 -10
  121. package/dist/cli.js +26 -241
  122. package/dist/code-extract.js +0 -6
  123. package/dist/code-map-acts.js +0 -7
  124. package/dist/code-map-admission.js +2 -26
  125. package/dist/code-map-build.js +3 -24
  126. package/dist/code-map-cli.js +0 -4
  127. package/dist/code-map-main.js +0 -6
  128. package/dist/code-map-read.js +0 -12
  129. package/dist/code-map-report.js +0 -9
  130. package/dist/code-map-shape.js +0 -19
  131. package/dist/code-map-store.js +0 -26
  132. package/dist/codex-limits.js +1 -17
  133. package/dist/coding-context.js +0 -10
  134. package/dist/coding-handoff.js +0 -14
  135. package/dist/coding-provider.js +0 -39
  136. package/dist/coding-shipping-ui.js +0 -1
  137. package/dist/coding-ui.js +0 -1
  138. package/dist/coding-update.js +1 -18
  139. package/dist/coding-workspace.js +0 -27
  140. package/dist/commit-extract.js +0 -83
  141. package/dist/connect-cli.js +0 -19
  142. package/dist/console-chrome.js +1 -34
  143. package/dist/console-instance.js +2 -91
  144. package/dist/container-state.js +0 -4
  145. package/dist/containment.js +2 -105
  146. package/dist/contract-changes.js +0 -6
  147. package/dist/contracts/acceptance-terms.js +0 -7
  148. package/dist/contracts/chat-actions.js +0 -46
  149. package/dist/contracts/chat-callback-rows.js +0 -8
  150. package/dist/contracts/chat-card.js +0 -14
  151. package/dist/contracts/chat-content.js +0 -55
  152. package/dist/contracts/chat-tables.js +0 -7
  153. package/dist/contracts/cli.js +0 -59
  154. package/dist/contracts/coding-activity.js +0 -15
  155. package/dist/contracts/coding-context.js +0 -15
  156. package/dist/contracts/coding-handoff.js +0 -11
  157. package/dist/contracts/coding-workspace.js +0 -14
  158. package/dist/contracts/console-api.js +1 -54
  159. package/dist/contracts/contract-test.js +0 -14
  160. package/dist/contracts/contract.js +0 -48
  161. package/dist/contracts/decision.js +0 -20
  162. package/dist/contracts/diff-stat.js +0 -16
  163. package/dist/contracts/discord-callback.js +0 -9
  164. package/dist/contracts/flow-card.js +0 -18
  165. package/dist/contracts/flow-propose.js +0 -8
  166. package/dist/contracts/flow-send.js +0 -31
  167. package/dist/contracts/flow.js +0 -112
  168. package/dist/contracts/gateway-tools.js +0 -22
  169. package/dist/contracts/handoff.js +0 -22
  170. package/dist/contracts/integration-metadata.js +0 -39
  171. package/dist/contracts/lead-context.js +0 -14
  172. package/dist/contracts/lead-tools.js +0 -49
  173. package/dist/contracts/mcp-oauth.js +0 -12
  174. package/dist/contracts/memory-pass.js +0 -21
  175. package/dist/contracts/model-catalog.js +0 -9
  176. package/dist/contracts/observation-request.js +0 -11
  177. package/dist/contracts/plan.js +0 -16
  178. package/dist/contracts/project-knowledge.js +0 -26
  179. package/dist/contracts/project-memory.js +0 -16
  180. package/dist/contracts/project-skills.js +0 -31
  181. package/dist/contracts/proof.js +0 -23
  182. package/dist/contracts/provider.js +0 -9
  183. package/dist/contracts/recipes.js +0 -16
  184. package/dist/contracts/release-check.js +0 -61
  185. package/dist/contracts/release-terms.js +0 -27
  186. package/dist/contracts/retention.js +0 -12
  187. package/dist/contracts/review-findings.js +0 -13
  188. package/dist/contracts/route-results.js +0 -15
  189. package/dist/contracts/route.js +0 -33
  190. package/dist/contracts/scope.js +0 -29
  191. package/dist/contracts/scout-report.js +0 -34
  192. package/dist/contracts/slack-callback.js +0 -11
  193. package/dist/contracts/sort-answer.js +0 -24
  194. package/dist/contracts/stage-output.js +0 -46
  195. package/dist/contracts/storage.js +0 -8
  196. package/dist/contracts/store-json.js +0 -41
  197. package/dist/contracts/subagent-turn.js +0 -23
  198. package/dist/contracts/task-sizing.js +0 -10
  199. package/dist/contracts/teams-callback.js +0 -7
  200. package/dist/contracts/telegram-callback.js +0 -27
  201. package/dist/contracts/trigger-payloads.js +0 -41
  202. package/dist/contracts/update-journal.js +0 -47
  203. package/dist/contracts/verification-receipt.js +0 -36
  204. package/dist/contracts/verification-view.js +0 -15
  205. package/dist/contracts/youiyoux-request.js +0 -26
  206. package/dist/control-setup.js +0 -7
  207. package/dist/control-ui.js +0 -3
  208. package/dist/controller-service.js +0 -4
  209. package/dist/controller-supervisor.js +0 -15
  210. package/dist/converse.js +3 -129
  211. package/dist/coordinator-proposals.js +1 -6
  212. package/dist/coordinator.js +0 -65
  213. package/dist/credentials-ui.js +0 -6
  214. package/dist/daemon.js +0 -137
  215. package/dist/database-reclaim.js +0 -3
  216. package/dist/decision.js +0 -78
  217. package/dist/demo-chat.js +4 -15
  218. package/dist/demo-sign-in.js +77 -0
  219. package/dist/demo.js +5 -194
  220. package/dist/deploy-gate.js +0 -20
  221. package/dist/deploy-lock.js +0 -4
  222. package/dist/deploy-phase.js +0 -22
  223. package/dist/deploy-rescue.js +0 -21
  224. package/dist/deprecations.js +0 -12
  225. package/dist/design/kit.css +9 -6
  226. package/dist/design/kit.js +2 -33
  227. package/dist/desktop-access.js +0 -9
  228. package/dist/desktop-bundle.js +1 -3
  229. package/dist/desktop-host.js +0 -34
  230. package/dist/desktop-update-gate.js +0 -8
  231. package/dist/desktop-update-recovery.js +1 -18
  232. package/dist/desktop-update.js +2 -48
  233. package/dist/digest-times.js +0 -2
  234. package/dist/disclosure.js +0 -5
  235. package/dist/discord-api.js +0 -6
  236. package/dist/discord-chat.js +0 -31
  237. package/dist/discord.js +0 -7
  238. package/dist/discover.js +0 -50
  239. package/dist/dispatch.js +61 -60
  240. package/dist/dispose.js +0 -208
  241. package/dist/doctor.js +0 -48
  242. package/dist/easy-start-args.js +7 -7
  243. package/dist/easy-start.js +32 -45
  244. package/dist/egress.js +1 -63
  245. package/dist/email-settings.js +0 -8
  246. package/dist/envelope.js +50 -86
  247. package/dist/eval-gate.js +1 -37
  248. package/dist/eval-hooks.js +0 -120
  249. package/dist/eval-oracle-main.js +0 -7
  250. package/dist/eval-oracle.js +3 -42
  251. package/dist/eval-world.js +1 -23
  252. package/dist/evals.js +6 -134
  253. package/dist/evidence-pack.js +0 -29
  254. package/dist/evidence-pair.js +0 -17
  255. package/dist/evidence.js +4 -280
  256. package/dist/exec.js +19 -404
  257. package/dist/exhaustion.js +0 -30
  258. package/dist/export-ui.js +0 -7
  259. package/dist/export.js +1 -38
  260. package/dist/failing-first.js +0 -6
  261. package/dist/fallback-schema.js +0 -5
  262. package/dist/fallback.js +0 -81
  263. package/dist/fast-start.js +0 -97
  264. package/dist/fast-terms.js +0 -3
  265. package/dist/fenced-check-coverage.js +0 -11
  266. package/dist/findings.js +1 -63
  267. package/dist/first-run.js +4 -57
  268. package/dist/first-tasks-child.js +0 -5
  269. package/dist/flaky-ci.js +1 -24
  270. package/dist/flaky-cli.js +0 -4
  271. package/dist/flaky.js +0 -43
  272. package/dist/fleet-schema.js +0 -11
  273. package/dist/flow-actions.js +0 -31
  274. package/dist/flow-browser.js +0 -42
  275. package/dist/flow-cadence.js +1 -24
  276. package/dist/flow-card-task.js +0 -11
  277. package/dist/flow-changed.js +0 -16
  278. package/dist/flow-code.js +1 -45
  279. package/dist/flow-draft.js +0 -17
  280. package/dist/flow-engine.js +2 -76
  281. package/dist/flow-gallery-ui.js +0 -28
  282. package/dist/flow-gallery.js +0 -54
  283. package/dist/flow-insights.js +0 -12
  284. package/dist/flow-items.js +0 -27
  285. package/dist/flow-live.js +0 -31
  286. package/dist/flow-people.js +0 -14
  287. package/dist/flow-pull-request.js +0 -32
  288. package/dist/flow-replies.js +0 -9
  289. package/dist/flow-result-card.js +0 -8
  290. package/dist/flow-schedule.js +0 -74
  291. package/dist/flow-scripts.js +0 -13
  292. package/dist/flow-secrets.js +0 -10
  293. package/dist/flow-send.js +0 -45
  294. package/dist/flow-share.js +0 -60
  295. package/dist/flow-sort.js +1 -24
  296. package/dist/flow-starters-ui.js +0 -2
  297. package/dist/flow-starters.js +0 -13
  298. package/dist/flow-steps.js +0 -80
  299. package/dist/flow-triggers.js +2 -256
  300. package/dist/flow-unattended-words.js +0 -13
  301. package/dist/flow-unattended.js +2 -115
  302. package/dist/flows-cli.js +2 -36
  303. package/dist/flows-ui.js +0 -51
  304. package/dist/flows.js +0 -158
  305. package/dist/folder-gate.js +0 -21
  306. package/dist/folder-look.js +0 -42
  307. package/dist/follow-through-brief.js +0 -6
  308. package/dist/follow-through-cli.js +0 -5
  309. package/dist/fonts.js +0 -13
  310. package/dist/gaps.js +0 -20
  311. package/dist/gate-failure.js +0 -7
  312. package/dist/git-floor.js +0 -12
  313. package/dist/git-incident.js +2 -38
  314. package/dist/git-views.js +0 -24
  315. package/dist/git.js +0 -31
  316. package/dist/github-import.js +0 -22
  317. package/dist/github-jobs.js +0 -12
  318. package/dist/google-mail.js +2 -27
  319. package/dist/grant.js +0 -110
  320. package/dist/graph.js +0 -108
  321. package/dist/guides.js +4 -15
  322. package/dist/handover-note.js +0 -12
  323. package/dist/health-cli.js +0 -2
  324. package/dist/home-groups.js +0 -15
  325. package/dist/html.js +0 -54
  326. package/dist/install-method.js +0 -12
  327. package/dist/integrations-ui.js +0 -15
  328. package/dist/integrations.js +7 -50
  329. package/dist/invoke.js +1 -381
  330. package/dist/is-record.js +0 -1
  331. package/dist/issues.js +0 -48
  332. package/dist/jsonl-discriminants.js +0 -6
  333. package/dist/keymap.js +0 -17
  334. package/dist/keys.js +0 -56
  335. package/dist/kits-ui.js +0 -3
  336. package/dist/kits.js +1 -24
  337. package/dist/knowledge-cli.js +0 -4
  338. package/dist/knowledge-ui.js +0 -8
  339. package/dist/landed-cleanup.js +0 -119
  340. package/dist/laptop-background.js +0 -85
  341. package/dist/laptop-service.js +0 -67
  342. package/dist/latency-timeline.js +2 -23
  343. package/dist/lead-about.js +0 -7
  344. package/dist/lead-answer-eval.js +0 -39
  345. package/dist/lead-capabilities.js +0 -19
  346. package/dist/lead-cli-live.js +0 -22
  347. package/dist/lead-cli.js +0 -27
  348. package/dist/lead-commitments.js +1 -27
  349. package/dist/lead-context.js +2 -42
  350. package/dist/lead-contract.js +0 -8
  351. package/dist/lead-doors.js +0 -105
  352. package/dist/lead-follow.js +0 -41
  353. package/dist/lead-identity.js +1 -4
  354. package/dist/lead-latency-schema.js +0 -13
  355. package/dist/lead-people.js +3 -18
  356. package/dist/lead-progress.js +0 -12
  357. package/dist/lead-queue-runtime.js +0 -26
  358. package/dist/lead-queue.js +0 -35
  359. package/dist/lead-route.js +0 -33
  360. package/dist/lead-status.js +0 -37
  361. package/dist/lead-sweep.js +0 -18
  362. package/dist/lead-tools.js +0 -160
  363. package/dist/lead-voice.js +0 -54
  364. package/dist/lead.js +2 -105
  365. package/dist/learning-child.js +0 -6
  366. package/dist/learning-look.js +0 -14
  367. package/dist/ledger-chain.js +0 -34
  368. package/dist/ledger-csv.js +0 -2
  369. package/dist/ledger-view.js +0 -3
  370. package/dist/lesson-notes.js +0 -56
  371. package/dist/limits-ui.js +0 -14
  372. package/dist/link.js +0 -79
  373. package/dist/live-backup.js +3 -33
  374. package/dist/live-bus.js +7 -81
  375. package/dist/live-children-read.js +4 -47
  376. package/dist/live-children.js +4 -44
  377. package/dist/live-detail.js +0 -17
  378. package/dist/live-input.js +5 -68
  379. package/dist/live-main-read.js +1 -14
  380. package/dist/live-notes.js +0 -12
  381. package/dist/live-open.js +1 -23
  382. package/dist/live-records.js +4 -151
  383. package/dist/live-reply.js +1 -51
  384. package/dist/live-terminal.js +12 -111
  385. package/dist/live.js +4 -130
  386. package/dist/local-owner-acts.js +0 -53
  387. package/dist/local-owner.js +2 -93
  388. package/dist/log.js +0 -8
  389. package/dist/login-secrets.js +2 -38
  390. package/dist/machine-check.js +0 -2
  391. package/dist/machine-identity.js +1 -46
  392. package/dist/mailbox.js +0 -30
  393. package/dist/maintenance.js +1 -3
  394. package/dist/mcp-connect.js +0 -88
  395. package/dist/mcp-core.js +0 -45
  396. package/dist/mcp-http.js +0 -13
  397. package/dist/mcp-oauth.js +0 -37
  398. package/dist/mcp-person.js +0 -11
  399. package/dist/mcp.js +3 -73
  400. package/dist/memory-cli.js +0 -3
  401. package/dist/memory-pass.js +0 -53
  402. package/dist/memory-tidy.js +0 -55
  403. package/dist/memory-use.js +2 -24
  404. package/dist/merge-checklist.js +21 -29
  405. package/dist/metrics.js +0 -10
  406. package/dist/mobile-viewport.js +0 -6
  407. package/dist/model-catalog.js +1 -33
  408. package/dist/model-choices.js +9 -84
  409. package/dist/model-names.js +0 -9
  410. package/dist/models-cli.js +0 -13
  411. package/dist/models-ui.js +0 -17
  412. package/dist/modes.js +0 -35
  413. package/dist/monitoring-settings.js +2 -27
  414. package/dist/monitoring-ui.js +2 -14
  415. package/dist/monitoring.js +2 -38
  416. package/dist/names.js +0 -39
  417. package/dist/needs-you.js +7 -70
  418. package/dist/never-index.js +0 -9
  419. package/dist/nightly-check.js +0 -74
  420. package/dist/nightly-github.js +0 -168
  421. package/dist/notification-delivery.js +0 -3
  422. package/dist/notification-rows.js +0 -17
  423. package/dist/oauth-run-token.js +1 -37
  424. package/dist/observations.js +0 -16
  425. package/dist/oidc.js +1 -20
  426. package/dist/onboard.js +4 -57
  427. package/dist/one-step-chat-schema.js +0 -15
  428. package/dist/openrouter-models.js +0 -6
  429. package/dist/operate-remote-arguments.js +0 -17
  430. package/dist/operate-remote.js +0 -33
  431. package/dist/operate.js +227 -2326
  432. package/dist/orphan-sweep.js +3 -37
  433. package/dist/page-work-contract.js +0 -3
  434. package/dist/password-bearer.js +1 -11
  435. package/dist/passwordless.js +0 -3
  436. package/dist/peek-cli.js +0 -46
  437. package/dist/peek.js +2 -61
  438. package/dist/people-audit-ui.js +0 -6
  439. package/dist/person-proof.js +0 -6
  440. package/dist/phase-routing.js +8 -183
  441. package/dist/plain-schema.js +0 -14
  442. package/dist/plain-words.js +18 -12
  443. package/dist/plan-auto.js +0 -20
  444. package/dist/plan-login.js +0 -16
  445. package/dist/plan.js +0 -68
  446. package/dist/plane-review.js +0 -56
  447. package/dist/planner-source.js +0 -96
  448. package/dist/planner.js +0 -117
  449. package/dist/policy-ui.js +0 -8
  450. package/dist/policy.js +0 -47
  451. package/dist/prepared-evidence.js +0 -5
  452. package/dist/principal.js +0 -29
  453. package/dist/probe.js +0 -30
  454. package/dist/process-custody.js +0 -15
  455. package/dist/process-liveness.js +0 -32
  456. package/dist/process-tree.js +3 -29
  457. package/dist/project-access.js +0 -10
  458. package/dist/project-admission.js +1 -41
  459. package/dist/project-cli.js +0 -6
  460. package/dist/project-concurrency.js +0 -35
  461. package/dist/project-delete-ui.js +4 -29
  462. package/dist/project-delete.js +1 -73
  463. package/dist/project-demo.js +0 -13
  464. package/dist/project-file.js +0 -2
  465. package/dist/project-identity.js +0 -41
  466. package/dist/project-knowledge.js +0 -39
  467. package/dist/project-learning.js +3 -55
  468. package/dist/project-memory.js +2 -45
  469. package/dist/project-outcomes.js +0 -6
  470. package/dist/project-sandbox.js +0 -23
  471. package/dist/project-skills.js +0 -12
  472. package/dist/project-tools.js +6 -184
  473. package/dist/project.js +0 -48
  474. package/dist/prompt.js +0 -31
  475. package/dist/proof.js +0 -220
  476. package/dist/proposal.js +0 -50
  477. package/dist/protected-storage-look.js +0 -6
  478. package/dist/protected-storage.js +1 -84
  479. package/dist/provider-auth.js +3 -69
  480. package/dist/provider-capture.js +1 -15
  481. package/dist/provider-connection.js +0 -8
  482. package/dist/provider-home.js +0 -25
  483. package/dist/provider-limits.js +0 -14
  484. package/dist/provider.js +0 -324
  485. package/dist/public-access.js +0 -34
  486. package/dist/public-check.js +0 -16
  487. package/dist/publish.js +1 -150
  488. package/dist/pull-request-flow.js +0 -77
  489. package/dist/pull-request-schema.js +0 -4
  490. package/dist/pull-request-ui.js +0 -5
  491. package/dist/pulls.js +0 -80
  492. package/dist/push.js +5 -89
  493. package/dist/quick-start.js +1 -23
  494. package/dist/read-executor-worker.js +0 -1
  495. package/dist/read-executor.js +0 -10
  496. package/dist/read-only-request.js +0 -7
  497. package/dist/recipe-ui.js +0 -6
  498. package/dist/recipes.js +0 -13
  499. package/dist/release-adapters.js +6 -214
  500. package/dist/release-approval.js +0 -74
  501. package/dist/release-authority.js +0 -42
  502. package/dist/release-auto.js +0 -142
  503. package/dist/release-card.js +0 -100
  504. package/dist/release-carry.js +0 -132
  505. package/dist/release-ci-hold.js +0 -20
  506. package/dist/release-cli.js +0 -46
  507. package/dist/release-coverage.js +0 -16
  508. package/dist/release-gate.js +0 -30
  509. package/dist/release-git.js +0 -24
  510. package/dist/release-links.js +0 -17
  511. package/dist/release-net.js +0 -42
  512. package/dist/release-next.js +0 -25
  513. package/dist/release-recheck.js +0 -89
  514. package/dist/release-refusal.js +0 -18
  515. package/dist/release-view.js +0 -5
  516. package/dist/release.js +7 -341
  517. package/dist/releases.js +0 -49
  518. package/dist/remote-audit.js +0 -25
  519. package/dist/remote-command.js +0 -16
  520. package/dist/remote-destination.js +5 -26
  521. package/dist/remote-exec.js +1 -27
  522. package/dist/remote-main.js +1 -53
  523. package/dist/remote-run.js +0 -5
  524. package/dist/remote.js +0 -49
  525. package/dist/render.js +0 -133
  526. package/dist/reply-shape.js +0 -85
  527. package/dist/reply-voice.js +0 -7
  528. package/dist/report-summary.js +0 -5
  529. package/dist/reported-usage.js +0 -30
  530. package/dist/repos.js +9 -62
  531. package/dist/repository-context.js +1 -24
  532. package/dist/request-budget-ui.js +0 -4
  533. package/dist/request-budget.js +0 -23
  534. package/dist/restart-certification.js +0 -37
  535. package/dist/result-actions.js +0 -62
  536. package/dist/result-acts.js +0 -34
  537. package/dist/result-completion.js +0 -25
  538. package/dist/result-evidence-readers.js +0 -3
  539. package/dist/result-follow-ups.js +1 -39
  540. package/dist/result-review.js +0 -86
  541. package/dist/result-shots.js +0 -39
  542. package/dist/retention-ui.js +0 -7
  543. package/dist/retention.js +2 -46
  544. package/dist/review-context.js +0 -129
  545. package/dist/review-evidence.js +0 -4
  546. package/dist/review-switch.js +1 -7
  547. package/dist/reviewer.js +0 -35
  548. package/dist/route-change-check.js +0 -2
  549. package/dist/route-change.js +0 -16
  550. package/dist/route-hooks.js +0 -27
  551. package/dist/route-results.js +2 -58
  552. package/dist/route-rules.js +1 -106
  553. package/dist/route-savings.js +0 -36
  554. package/dist/route-store.js +1 -133
  555. package/dist/run-closeout.js +2 -50
  556. package/dist/run-efficiency.js +2 -44
  557. package/dist/run-ending.js +0 -13
  558. package/dist/runner-process.js +0 -33
  559. package/dist/runner.js +17 -189
  560. package/dist/sample-project.js +2 -27
  561. package/dist/sandbox-launch.js +4 -25
  562. package/dist/sandbox-runtime.js +1 -88
  563. package/dist/scan.js +0 -27
  564. package/dist/scope.js +4 -567
  565. package/dist/scout-browser-lock.js +0 -6
  566. package/dist/scout-browser.js +2 -68
  567. package/dist/scout-net.js +1 -32
  568. package/dist/scout-report.js +0 -22
  569. package/dist/scout.js +1 -116
  570. package/dist/secret-mint.js +0 -6
  571. package/dist/serve.js +21 -555
  572. package/dist/server/agents-computers.js +0 -10
  573. package/dist/server/agents-live-filed.js +0 -13
  574. package/dist/server/agents-live-lead.js +0 -19
  575. package/dist/server/agents-live-room.js +0 -19
  576. package/dist/server/chat.js +2 -194
  577. package/dist/server/chrome.js +17 -263
  578. package/dist/server/console.css +4 -4
  579. package/dist/server/edge-refusal.js +0 -3
  580. package/dist/server/flows.js +5 -74
  581. package/dist/server/guards.js +1 -88
  582. package/dist/server/handler-registry.js +0 -2
  583. package/dist/server/home-asks.js +1 -22
  584. package/dist/server/home.js +1 -30
  585. package/dist/server/http.js +0 -82
  586. package/dist/server/in-place.js +0 -15
  587. package/dist/server/kit-standalone.js +0 -20
  588. package/dist/server/kit.js +2 -114
  589. package/dist/server/last-checks.js +0 -2
  590. package/dist/server/live.js +1 -36
  591. package/dist/server/merge-ready-view.js +0 -6
  592. package/dist/server/mutation-key.js +3 -40
  593. package/dist/server/pages-assets.js +0 -16
  594. package/dist/server/pages.js +7 -195
  595. package/dist/server/people-tokens.js +3 -101
  596. package/dist/server/remote-hooks.js +0 -13
  597. package/dist/server/remote.js +0 -28
  598. package/dist/server/render-chat.js +8 -144
  599. package/dist/server/render-code-map.js +0 -5
  600. package/dist/server/render-flaky.js +0 -8
  601. package/dist/server/render-follow-through.js +2 -5
  602. package/dist/server/render-history.js +2 -34
  603. package/dist/server/render-new-task.js +2 -29
  604. package/dist/server/render-pages.js +1 -111
  605. package/dist/server/render-people.js +2 -46
  606. package/dist/server/render-projects.js +15 -32
  607. package/dist/server/render-release.js +1 -14
  608. package/dist/server/render-results.js +4 -355
  609. package/dist/server/render-settings.js +0 -15
  610. package/dist/server/render-tasks.js +13 -493
  611. package/dist/server/request-context.js +2 -9
  612. package/dist/server/retired-routes.js +0 -11
  613. package/dist/server/route-policy.js +0 -3
  614. package/dist/server/route-table.js +6 -135
  615. package/dist/server/runtime.js +0 -1
  616. package/dist/server/session.js +0 -28
  617. package/dist/server/settings.js +40 -246
  618. package/dist/server/signup-gate.js +0 -11
  619. package/dist/server/sweeps.js +0 -6
  620. package/dist/server/task-views.js +9 -227
  621. package/dist/server/tasks.js +5 -539
  622. package/dist/server/terminals.js +2 -46
  623. package/dist/server/welcome.js +2 -22
  624. package/dist/server-telemetry.js +0 -9
  625. package/dist/settings-groups-ui.js +50 -63
  626. package/dist/settings-kit-script.js +0 -19
  627. package/dist/settings-kit.js +0 -63
  628. package/dist/settings-proofs.js +0 -23
  629. package/dist/setup-guide.js +1 -9
  630. package/dist/shared-deps.js +9 -84
  631. package/dist/sign-in-guard.js +0 -27
  632. package/dist/skills-ui.js +0 -2
  633. package/dist/skills.js +2 -54
  634. package/dist/slack-api.js +0 -3
  635. package/dist/slack-chat.js +0 -25
  636. package/dist/slack-settings.js +0 -1
  637. package/dist/slack-socket.js +0 -5
  638. package/dist/slack.js +0 -4
  639. package/dist/sleep.js +0 -1
  640. package/dist/source-key.js +0 -10
  641. package/dist/spend-report.js +0 -29
  642. package/dist/spend-ui.js +0 -26
  643. package/dist/spend.js +0 -40
  644. package/dist/sqlite-runtime.js +0 -2
  645. package/dist/sqlite-telemetry.js +0 -9
  646. package/dist/sso-settings.js +0 -13
  647. package/dist/sso-ui.js +0 -2
  648. package/dist/staged-runtimes.js +5 -39
  649. package/dist/steer-capabilities.js +1 -7
  650. package/dist/steer-controls.js +0 -10
  651. package/dist/steer-live.js +0 -31
  652. package/dist/steer-mailbox.js +4 -65
  653. package/dist/steer-status.js +0 -7
  654. package/dist/stop-proof.js +5 -62
  655. package/dist/storage-sweep-child.js +1 -5
  656. package/dist/storage-sweep-process.js +2 -20
  657. package/dist/storage-sweep-schedule.js +0 -32
  658. package/dist/storage-sweep.js +2 -51
  659. package/dist/storage-ui.js +0 -18
  660. package/dist/storage.js +0 -31
  661. package/dist/store-baseline.js +0 -14
  662. package/dist/store.js +109 -4763
  663. package/dist/stream-scope.js +0 -16
  664. package/dist/structured-output.js +0 -39
  665. package/dist/style-asset.js +0 -2
  666. package/dist/subagent-admin.js +0 -9
  667. package/dist/subagent-desk.js +0 -29
  668. package/dist/subagent-memory.js +0 -38
  669. package/dist/subagent-question.js +0 -29
  670. package/dist/subagent-tools.js +1 -60
  671. package/dist/subagent-week.js +0 -28
  672. package/dist/subagent-work.js +1 -39
  673. package/dist/subagents-ui.js +1 -13
  674. package/dist/subagents.js +0 -40
  675. package/dist/subscription-chat.js +1 -42
  676. package/dist/summary.js +0 -19
  677. package/dist/surface.js +0 -75
  678. package/dist/sweep-gate.js +0 -2
  679. package/dist/sweep-quarantine.js +2 -13
  680. package/dist/sync.js +0 -47
  681. package/dist/tailnet.js +0 -9
  682. package/dist/tamper-scan.js +0 -15
  683. package/dist/task-activity.js +1 -16
  684. package/dist/task-aliases.js +0 -3
  685. package/dist/task-archive.js +0 -7
  686. package/dist/task-base.js +0 -18
  687. package/dist/task-composer.js +0 -2
  688. package/dist/task-control.js +0 -74
  689. package/dist/task-live.js +0 -23
  690. package/dist/task-moves.js +0 -28
  691. package/dist/task-outcome-cli.js +17 -28
  692. package/dist/task-review-brief.js +0 -7
  693. package/dist/task-sizing.js +0 -47
  694. package/dist/task-source.js +0 -23
  695. package/dist/task-status.js +0 -106
  696. package/dist/task-text.js +0 -12
  697. package/dist/team-chat-authorization.js +0 -3
  698. package/dist/team-contract.js +0 -2
  699. package/dist/team-http.js +0 -4
  700. package/dist/team-leads.js +1 -16
  701. package/dist/team-runtime.js +0 -13
  702. package/dist/team-ui.js +0 -1
  703. package/dist/team-updates.js +0 -4
  704. package/dist/teams-api.js +0 -12
  705. package/dist/teams-chat.js +0 -28
  706. package/dist/teams.js +0 -12
  707. package/dist/teardown-git.js +6 -294
  708. package/dist/telegram-flow.js +0 -51
  709. package/dist/telegram-lead.js +2 -203
  710. package/dist/telegram-live.js +1 -42
  711. package/dist/telegram-progress.js +0 -18
  712. package/dist/telegram-settings.js +0 -7
  713. package/dist/telegram-status.js +0 -46
  714. package/dist/telegram-team.js +1 -33
  715. package/dist/telegram.js +6 -454
  716. package/dist/templates.js +0 -24
  717. package/dist/terminal-catalog.js +2 -20
  718. package/dist/terminal-text.js +0 -12
  719. package/dist/test-infra.js +0 -50
  720. package/dist/test-temp.js +3 -26
  721. package/dist/text-limits.js +0 -92
  722. package/dist/tidy.js +0 -76
  723. package/dist/tier-report.js +0 -2
  724. package/dist/token-notices.js +1 -9
  725. package/dist/tokens-cli.js +0 -13
  726. package/dist/tool-broker.js +2 -53
  727. package/dist/tool-launcher.js +0 -14
  728. package/dist/tool-secret-store.js +3 -125
  729. package/dist/toolroll-update-cli.js +0 -9
  730. package/dist/toolroll-update-ui.js +0 -14
  731. package/dist/toolroll-update.js +13 -252
  732. package/dist/tools-ui.js +0 -17
  733. package/dist/transitions-recipes.js +0 -2
  734. package/dist/tree-proof.js +0 -23
  735. package/dist/tui-contract.js +0 -8
  736. package/dist/tui-source.js +16 -36
  737. package/dist/tui.js +1 -1
  738. package/dist/typed-start.js +0 -27
  739. package/dist/unfenced-test-support.js +0 -5
  740. package/dist/up-processes.js +1 -40
  741. package/dist/up-role-child.js +1 -13
  742. package/dist/update-notice.js +0 -1
  743. package/dist/vanished-retry.js +0 -40
  744. package/dist/verification-evidence.js +0 -39
  745. package/dist/version.js +0 -1
  746. package/dist/wake-hub.js +0 -28
  747. package/dist/webhook-limits.js +0 -7
  748. package/dist/webhook-readers.js +0 -30
  749. package/dist/webhook-signing.js +0 -14
  750. package/dist/webhooks.js +0 -54
  751. package/dist/welcome-facts.js +2 -14
  752. package/dist/when-html.js +0 -27
  753. package/dist/work-index.js +26 -98
  754. package/dist/work-summary.js +2 -17
  755. package/dist/workspace-motion.js +0 -2
  756. package/dist/workspace-revision.js +1 -21
  757. package/dist/workspace-ui.js +15 -135
  758. package/dist/worktree-notices.js +0 -3
  759. package/dist/worktree.js +0 -308
  760. package/dist/writes-mode.js +0 -1
  761. package/dist/youiyoux-intake.js +4 -159
  762. package/package.json +4 -3
  763. package/dist/accent-colors.d.ts +0 -51
  764. package/dist/acp-agents.d.ts +0 -43
  765. package/dist/acp-attest.d.ts +0 -44
  766. package/dist/acp-check.d.ts +0 -37
  767. package/dist/acp-client.d.ts +0 -163
  768. package/dist/acp-inspect.d.ts +0 -23
  769. package/dist/action-ledger.d.ts +0 -27
  770. package/dist/activity-line.d.ts +0 -29
  771. package/dist/actor.d.ts +0 -11
  772. package/dist/agent-board.d.ts +0 -229
  773. package/dist/agent-fence.d.ts +0 -479
  774. package/dist/agent-onboard.d.ts +0 -158
  775. package/dist/agent-pulse.d.ts +0 -43
  776. package/dist/agent-state-words.d.ts +0 -19
  777. package/dist/agent-state.d.ts +0 -65
  778. package/dist/agent-turns.d.ts +0 -52
  779. package/dist/agentconfig.d.ts +0 -191
  780. package/dist/agents-board.d.ts +0 -145
  781. package/dist/agents-live.d.ts +0 -31
  782. package/dist/api-tokens.d.ts +0 -80
  783. package/dist/approval-authority.d.ts +0 -51
  784. package/dist/approval-password.d.ts +0 -31
  785. package/dist/approval-policy.d.ts +0 -69
  786. package/dist/approval-rules-ui.d.ts +0 -40
  787. package/dist/assignment-adapters.d.ts +0 -152
  788. package/dist/assignment-brief.d.ts +0 -83
  789. package/dist/assignment-delivery.d.ts +0 -86
  790. package/dist/assignment-presentation.d.ts +0 -37
  791. package/dist/assignment-status.d.ts +0 -71
  792. package/dist/assignment-ui.d.ts +0 -68
  793. package/dist/assignment.d.ts +0 -350
  794. package/dist/attest.d.ts +0 -59
  795. package/dist/audit-cli.d.ts +0 -17
  796. package/dist/backend.d.ts +0 -97
  797. package/dist/backup-ui.d.ts +0 -32
  798. package/dist/backup.d.ts +0 -92
  799. package/dist/batch-checks.d.ts +0 -15
  800. package/dist/batch-policy.d.ts +0 -23
  801. package/dist/beads.d.ts +0 -34
  802. package/dist/bin.d.ts +0 -2
  803. package/dist/board.d.ts +0 -134
  804. package/dist/boot-identity.d.ts +0 -64
  805. package/dist/bounded-spawn.d.ts +0 -57
  806. package/dist/brand-icons.d.ts +0 -168
  807. package/dist/brand-mark.d.ts +0 -28
  808. package/dist/brief-fence.d.ts +0 -9
  809. package/dist/browser-crew.d.ts +0 -12
  810. package/dist/browser-shell.d.ts +0 -9
  811. package/dist/browser-workspace.d.ts +0 -1985
  812. package/dist/budget-alerts.d.ts +0 -19
  813. package/dist/build-review.d.ts +0 -38
  814. package/dist/builder-restart.d.ts +0 -21
  815. package/dist/builder.d.ts +0 -409
  816. package/dist/canonical-json.d.ts +0 -14
  817. package/dist/capscan.d.ts +0 -35
  818. package/dist/card-catalog.d.ts +0 -209
  819. package/dist/card-cli.d.ts +0 -43
  820. package/dist/card-render.d.ts +0 -43
  821. package/dist/card-sources.d.ts +0 -68
  822. package/dist/chat-acceptance.d.ts +0 -74
  823. package/dist/chat-actions.d.ts +0 -460
  824. package/dist/chat-admission.d.ts +0 -19
  825. package/dist/chat-approval.d.ts +0 -58
  826. package/dist/chat-ask.d.ts +0 -32
  827. package/dist/chat-card-part.d.ts +0 -11
  828. package/dist/chat-card.d.ts +0 -46
  829. package/dist/chat-channel.d.ts +0 -126
  830. package/dist/chat-continuity.d.ts +0 -32
  831. package/dist/chat-controls.d.ts +0 -117
  832. package/dist/chat-core.d.ts +0 -177
  833. package/dist/chat-decide.d.ts +0 -269
  834. package/dist/chat-delivery-state.d.ts +0 -132
  835. package/dist/chat-delivery.d.ts +0 -71
  836. package/dist/chat-display.d.ts +0 -1
  837. package/dist/chat-evidence.d.ts +0 -123
  838. package/dist/chat-flow.d.ts +0 -70
  839. package/dist/chat-follow.d.ts +0 -20
  840. package/dist/chat-inbox.d.ts +0 -57
  841. package/dist/chat-live-schema.d.ts +0 -17
  842. package/dist/chat-live.d.ts +0 -161
  843. package/dist/chat-message-states.d.ts +0 -75
  844. package/dist/chat-messages.d.ts +0 -338
  845. package/dist/chat-migration.d.ts +0 -30
  846. package/dist/chat-polish.d.ts +0 -17
  847. package/dist/chat-quiet.d.ts +0 -40
  848. package/dist/chat-review.d.ts +0 -51
  849. package/dist/chat-rooms.d.ts +0 -123
  850. package/dist/chat-settings-page.d.ts +0 -43
  851. package/dist/chat-task-actions.d.ts +0 -59
  852. package/dist/chat-terms.d.ts +0 -29
  853. package/dist/chat-voice.d.ts +0 -69
  854. package/dist/chat-warmth.d.ts +0 -21
  855. package/dist/check-access.d.ts +0 -54
  856. package/dist/check-facts.d.ts +0 -126
  857. package/dist/check-failure.d.ts +0 -113
  858. package/dist/check-levels-ui.d.ts +0 -36
  859. package/dist/check-levels.d.ts +0 -70
  860. package/dist/check-load.d.ts +0 -85
  861. package/dist/check-only-standing.d.ts +0 -36
  862. package/dist/check-only.d.ts +0 -15
  863. package/dist/check-progress.d.ts +0 -78
  864. package/dist/check-repair.d.ts +0 -47
  865. package/dist/check-report.d.ts +0 -177
  866. package/dist/check-stamp.d.ts +0 -46
  867. package/dist/checkout-cleanup.d.ts +0 -157
  868. package/dist/checkout-proof.d.ts +0 -28
  869. package/dist/child-database.d.ts +0 -12
  870. package/dist/claim.d.ts +0 -627
  871. package/dist/claude-print.d.ts +0 -12
  872. package/dist/cli-fast.d.ts +0 -8
  873. package/dist/cli-help.d.ts +0 -8
  874. package/dist/cli-http.d.ts +0 -58
  875. package/dist/cli.d.ts +0 -149
  876. package/dist/code-extract.d.ts +0 -44
  877. package/dist/code-map-acts.d.ts +0 -24
  878. package/dist/code-map-admission.d.ts +0 -52
  879. package/dist/code-map-build.d.ts +0 -63
  880. package/dist/code-map-cli.d.ts +0 -153
  881. package/dist/code-map-main.d.ts +0 -1
  882. package/dist/code-map-read.d.ts +0 -106
  883. package/dist/code-map-report.d.ts +0 -37
  884. package/dist/code-map-shape.d.ts +0 -172
  885. package/dist/code-map-store.d.ts +0 -136
  886. package/dist/codex-limits.d.ts +0 -15
  887. package/dist/coding-context.d.ts +0 -18
  888. package/dist/coding-handoff.d.ts +0 -39
  889. package/dist/coding-provider.d.ts +0 -88
  890. package/dist/coding-shipping-ui.d.ts +0 -5
  891. package/dist/coding-types.d.ts +0 -16
  892. package/dist/coding-ui.d.ts +0 -19
  893. package/dist/coding-update.d.ts +0 -28
  894. package/dist/coding-workspace.d.ts +0 -141
  895. package/dist/commit-extract.d.ts +0 -135
  896. package/dist/connect-cli.d.ts +0 -34
  897. package/dist/console-chrome.d.ts +0 -41
  898. package/dist/console-instance.d.ts +0 -157
  899. package/dist/container-state.d.ts +0 -5
  900. package/dist/containment.d.ts +0 -205
  901. package/dist/contract-changes.d.ts +0 -52
  902. package/dist/contracts/acceptance-terms.d.ts +0 -14
  903. package/dist/contracts/chat-actions.d.ts +0 -465
  904. package/dist/contracts/chat-callback-rows.d.ts +0 -59
  905. package/dist/contracts/chat-card.d.ts +0 -91
  906. package/dist/contracts/chat-content.d.ts +0 -551
  907. package/dist/contracts/chat-tables.d.ts +0 -12
  908. package/dist/contracts/cli.d.ts +0 -987
  909. package/dist/contracts/coding-activity.d.ts +0 -64
  910. package/dist/contracts/coding-context.d.ts +0 -97
  911. package/dist/contracts/coding-handoff.d.ts +0 -44
  912. package/dist/contracts/coding-workspace.d.ts +0 -165
  913. package/dist/contracts/console-api.d.ts +0 -540
  914. package/dist/contracts/contract-test.d.ts +0 -45
  915. package/dist/contracts/contract.d.ts +0 -92
  916. package/dist/contracts/decision.d.ts +0 -45
  917. package/dist/contracts/diff-stat.d.ts +0 -58
  918. package/dist/contracts/discord-callback.d.ts +0 -45
  919. package/dist/contracts/flow-card.d.ts +0 -53
  920. package/dist/contracts/flow-propose.d.ts +0 -334
  921. package/dist/contracts/flow-send.d.ts +0 -245
  922. package/dist/contracts/flow.d.ts +0 -19565
  923. package/dist/contracts/gateway-tools.d.ts +0 -472
  924. package/dist/contracts/handoff.d.ts +0 -91
  925. package/dist/contracts/health.d.ts +0 -82
  926. package/dist/contracts/integration-metadata.d.ts +0 -100
  927. package/dist/contracts/lead-context.d.ts +0 -165
  928. package/dist/contracts/lead-tools.d.ts +0 -2312
  929. package/dist/contracts/mcp-oauth.d.ts +0 -53
  930. package/dist/contracts/memory-pass.d.ts +0 -157
  931. package/dist/contracts/model-catalog.d.ts +0 -21
  932. package/dist/contracts/observation-request.d.ts +0 -37
  933. package/dist/contracts/plan.d.ts +0 -58
  934. package/dist/contracts/project-knowledge.d.ts +0 -159
  935. package/dist/contracts/project-memory.d.ts +0 -119
  936. package/dist/contracts/project-skills.d.ts +0 -120
  937. package/dist/contracts/proof.d.ts +0 -136
  938. package/dist/contracts/provider.d.ts +0 -40
  939. package/dist/contracts/recipes.d.ts +0 -166
  940. package/dist/contracts/release-check.d.ts +0 -371
  941. package/dist/contracts/release-terms.d.ts +0 -107
  942. package/dist/contracts/retention.d.ts +0 -42
  943. package/dist/contracts/review-findings.d.ts +0 -46
  944. package/dist/contracts/route-results.d.ts +0 -121
  945. package/dist/contracts/route.d.ts +0 -897
  946. package/dist/contracts/scope.d.ts +0 -105
  947. package/dist/contracts/scout-report.d.ts +0 -234
  948. package/dist/contracts/slack-callback.d.ts +0 -43
  949. package/dist/contracts/sort-answer.d.ts +0 -83
  950. package/dist/contracts/stage-output.d.ts +0 -127
  951. package/dist/contracts/storage.d.ts +0 -37
  952. package/dist/contracts/store-json.d.ts +0 -313
  953. package/dist/contracts/subagent-turn.d.ts +0 -43
  954. package/dist/contracts/task-sizing.d.ts +0 -24
  955. package/dist/contracts/teams-callback.d.ts +0 -13
  956. package/dist/contracts/telegram-callback.d.ts +0 -120
  957. package/dist/contracts/trigger-payloads.d.ts +0 -389
  958. package/dist/contracts/update-journal.d.ts +0 -254
  959. package/dist/contracts/verification-receipt.d.ts +0 -200
  960. package/dist/contracts/verification-view.d.ts +0 -102
  961. package/dist/contracts/youiyoux-request.d.ts +0 -248
  962. package/dist/control-setup.d.ts +0 -44
  963. package/dist/control-ui.d.ts +0 -37
  964. package/dist/controller-service.d.ts +0 -1
  965. package/dist/controller-supervisor.d.ts +0 -38
  966. package/dist/converse.d.ts +0 -316
  967. package/dist/coordinator-proposals.d.ts +0 -29
  968. package/dist/coordinator.d.ts +0 -186
  969. package/dist/credentials-ui.d.ts +0 -33
  970. package/dist/daemon.d.ts +0 -226
  971. package/dist/database-reclaim.d.ts +0 -4
  972. package/dist/decision.d.ts +0 -119
  973. package/dist/demo-chat.d.ts +0 -32
  974. package/dist/demo.d.ts +0 -153
  975. package/dist/deploy-gate.d.ts +0 -20
  976. package/dist/deploy-lock.d.ts +0 -8
  977. package/dist/deploy-phase.d.ts +0 -37
  978. package/dist/deploy-rescue.d.ts +0 -42
  979. package/dist/deprecations.d.ts +0 -20
  980. package/dist/design/kit.d.ts +0 -216
  981. package/dist/desktop-access.d.ts +0 -28
  982. package/dist/desktop-bundle.d.ts +0 -16
  983. package/dist/desktop-host.d.ts +0 -54
  984. package/dist/desktop-update-gate.d.ts +0 -12
  985. package/dist/desktop-update-recovery.d.ts +0 -14
  986. package/dist/desktop-update.d.ts +0 -147
  987. package/dist/digest-times.d.ts +0 -3
  988. package/dist/disclosure.d.ts +0 -6
  989. package/dist/discord-api.d.ts +0 -24
  990. package/dist/discord-chat.d.ts +0 -27
  991. package/dist/discord-settings.d.ts +0 -4
  992. package/dist/discord.d.ts +0 -10
  993. package/dist/discover.d.ts +0 -75
  994. package/dist/dispatch.d.ts +0 -123
  995. package/dist/dispose.d.ts +0 -194
  996. package/dist/doctor.d.ts +0 -67
  997. package/dist/easy-start-args.d.ts +0 -13
  998. package/dist/easy-start.d.ts +0 -77
  999. package/dist/egress.d.ts +0 -121
  1000. package/dist/email-settings.d.ts +0 -34
  1001. package/dist/envelope.d.ts +0 -47
  1002. package/dist/eval-gate.d.ts +0 -51
  1003. package/dist/eval-hooks.d.ts +0 -94
  1004. package/dist/eval-oracle-main.d.ts +0 -1
  1005. package/dist/eval-oracle.d.ts +0 -60
  1006. package/dist/eval-world.d.ts +0 -17
  1007. package/dist/evals.d.ts +0 -299
  1008. package/dist/evidence-pack.d.ts +0 -186
  1009. package/dist/evidence-pair.d.ts +0 -53
  1010. package/dist/evidence.d.ts +0 -371
  1011. package/dist/exec.d.ts +0 -355
  1012. package/dist/exhaustion.d.ts +0 -58
  1013. package/dist/export-ui.d.ts +0 -11
  1014. package/dist/export.d.ts +0 -48
  1015. package/dist/failing-first.d.ts +0 -31
  1016. package/dist/fallback-schema.d.ts +0 -8
  1017. package/dist/fallback.d.ts +0 -138
  1018. package/dist/fast-start.d.ts +0 -213
  1019. package/dist/fast-terms.d.ts +0 -9
  1020. package/dist/fenced-check-coverage.d.ts +0 -62
  1021. package/dist/findings.d.ts +0 -224
  1022. package/dist/first-run.d.ts +0 -197
  1023. package/dist/first-tasks-child.d.ts +0 -1
  1024. package/dist/flaky-ci.d.ts +0 -31
  1025. package/dist/flaky-cli.d.ts +0 -60
  1026. package/dist/flaky.d.ts +0 -83
  1027. package/dist/fleet-schema.d.ts +0 -17
  1028. package/dist/flow-actions.d.ts +0 -79
  1029. package/dist/flow-browser.d.ts +0 -103
  1030. package/dist/flow-cadence.d.ts +0 -48
  1031. package/dist/flow-card-task.d.ts +0 -11
  1032. package/dist/flow-changed.d.ts +0 -14
  1033. package/dist/flow-code.d.ts +0 -84
  1034. package/dist/flow-draft.d.ts +0 -42
  1035. package/dist/flow-engine.d.ts +0 -82
  1036. package/dist/flow-gallery-ui.d.ts +0 -73
  1037. package/dist/flow-gallery.d.ts +0 -147
  1038. package/dist/flow-insights.d.ts +0 -104
  1039. package/dist/flow-items.d.ts +0 -37
  1040. package/dist/flow-live.d.ts +0 -16
  1041. package/dist/flow-people.d.ts +0 -23
  1042. package/dist/flow-pull-request.d.ts +0 -14
  1043. package/dist/flow-replies.d.ts +0 -48
  1044. package/dist/flow-result-card.d.ts +0 -22
  1045. package/dist/flow-schedule.d.ts +0 -154
  1046. package/dist/flow-scripts.d.ts +0 -31
  1047. package/dist/flow-secrets.d.ts +0 -13
  1048. package/dist/flow-send.d.ts +0 -54
  1049. package/dist/flow-share.d.ts +0 -78
  1050. package/dist/flow-sort.d.ts +0 -63
  1051. package/dist/flow-starters-ui.d.ts +0 -15
  1052. package/dist/flow-starters.d.ts +0 -63
  1053. package/dist/flow-steps.d.ts +0 -52
  1054. package/dist/flow-triggers.d.ts +0 -303
  1055. package/dist/flow-unattended-words.d.ts +0 -48
  1056. package/dist/flow-unattended.d.ts +0 -259
  1057. package/dist/flows-cli.d.ts +0 -358
  1058. package/dist/flows-ui.d.ts +0 -70
  1059. package/dist/flows.d.ts +0 -136
  1060. package/dist/folder-gate.d.ts +0 -32
  1061. package/dist/folder-look.d.ts +0 -110
  1062. package/dist/follow-through-brief.d.ts +0 -12
  1063. package/dist/follow-through-cli.d.ts +0 -23
  1064. package/dist/fonts.d.ts +0 -19
  1065. package/dist/gaps.d.ts +0 -35
  1066. package/dist/gate-failure.d.ts +0 -40
  1067. package/dist/git-floor.d.ts +0 -16
  1068. package/dist/git-incident.d.ts +0 -65
  1069. package/dist/git-views.d.ts +0 -20
  1070. package/dist/git.d.ts +0 -54
  1071. package/dist/github-import.d.ts +0 -62
  1072. package/dist/github-jobs.d.ts +0 -25
  1073. package/dist/google-mail.d.ts +0 -59
  1074. package/dist/grant.d.ts +0 -136
  1075. package/dist/graph.d.ts +0 -164
  1076. package/dist/guides.d.ts +0 -22
  1077. package/dist/handover-note.d.ts +0 -33
  1078. package/dist/health-cli.d.ts +0 -3
  1079. package/dist/home-groups.d.ts +0 -39
  1080. package/dist/html.d.ts +0 -85
  1081. package/dist/install-method.d.ts +0 -17
  1082. package/dist/integrations-ui.d.ts +0 -17
  1083. package/dist/integrations.d.ts +0 -138
  1084. package/dist/invoke.d.ts +0 -228
  1085. package/dist/is-record.d.ts +0 -2
  1086. package/dist/issues.d.ts +0 -41
  1087. package/dist/jsonl-discriminants.d.ts +0 -11
  1088. package/dist/keymap.d.ts +0 -43
  1089. package/dist/keys.d.ts +0 -108
  1090. package/dist/kits-ui.d.ts +0 -16
  1091. package/dist/kits.d.ts +0 -88
  1092. package/dist/knowledge-cli.d.ts +0 -132
  1093. package/dist/knowledge-ui.d.ts +0 -45
  1094. package/dist/landed-cleanup.d.ts +0 -175
  1095. package/dist/laptop-background.d.ts +0 -187
  1096. package/dist/laptop-service.d.ts +0 -111
  1097. package/dist/latency-timeline.d.ts +0 -46
  1098. package/dist/lead-about.d.ts +0 -35
  1099. package/dist/lead-answer-eval.d.ts +0 -93
  1100. package/dist/lead-capabilities.d.ts +0 -57
  1101. package/dist/lead-cli-live.d.ts +0 -56
  1102. package/dist/lead-cli.d.ts +0 -58
  1103. package/dist/lead-commitments.d.ts +0 -84
  1104. package/dist/lead-context.d.ts +0 -45
  1105. package/dist/lead-contract.d.ts +0 -10
  1106. package/dist/lead-doors.d.ts +0 -122
  1107. package/dist/lead-follow.d.ts +0 -26
  1108. package/dist/lead-identity.d.ts +0 -23
  1109. package/dist/lead-latency-schema.d.ts +0 -24
  1110. package/dist/lead-people.d.ts +0 -55
  1111. package/dist/lead-progress.d.ts +0 -67
  1112. package/dist/lead-queue-runtime.d.ts +0 -46
  1113. package/dist/lead-queue.d.ts +0 -104
  1114. package/dist/lead-route.d.ts +0 -56
  1115. package/dist/lead-status.d.ts +0 -116
  1116. package/dist/lead-sweep.d.ts +0 -67
  1117. package/dist/lead-tools.d.ts +0 -167
  1118. package/dist/lead-voice.d.ts +0 -85
  1119. package/dist/lead.d.ts +0 -142
  1120. package/dist/learning-child.d.ts +0 -1
  1121. package/dist/learning-look.d.ts +0 -25
  1122. package/dist/ledger-chain.d.ts +0 -46
  1123. package/dist/ledger-csv.d.ts +0 -4
  1124. package/dist/ledger-view.d.ts +0 -27
  1125. package/dist/lesson-notes.d.ts +0 -81
  1126. package/dist/limits-ui.d.ts +0 -34
  1127. package/dist/link.d.ts +0 -72
  1128. package/dist/live-backup.d.ts +0 -39
  1129. package/dist/live-bus.d.ts +0 -141
  1130. package/dist/live-children-read.d.ts +0 -52
  1131. package/dist/live-children.d.ts +0 -73
  1132. package/dist/live-detail.d.ts +0 -27
  1133. package/dist/live-input.d.ts +0 -68
  1134. package/dist/live-main-read.d.ts +0 -19
  1135. package/dist/live-notes.d.ts +0 -20
  1136. package/dist/live-open.d.ts +0 -28
  1137. package/dist/live-records.d.ts +0 -149
  1138. package/dist/live-reply.d.ts +0 -83
  1139. package/dist/live-terminal.d.ts +0 -273
  1140. package/dist/live.d.ts +0 -152
  1141. package/dist/local-owner-acts.d.ts +0 -83
  1142. package/dist/local-owner.d.ts +0 -135
  1143. package/dist/log.d.ts +0 -7
  1144. package/dist/login-secrets.d.ts +0 -60
  1145. package/dist/machine-check.d.ts +0 -16
  1146. package/dist/machine-identity.d.ts +0 -75
  1147. package/dist/mailbox.d.ts +0 -57
  1148. package/dist/maintenance.d.ts +0 -13
  1149. package/dist/mcp-connect.d.ts +0 -181
  1150. package/dist/mcp-core.d.ts +0 -110
  1151. package/dist/mcp-http.d.ts +0 -32
  1152. package/dist/mcp-oauth.d.ts +0 -92
  1153. package/dist/mcp-person.d.ts +0 -22
  1154. package/dist/mcp.d.ts +0 -20
  1155. package/dist/memory-cli.d.ts +0 -768
  1156. package/dist/memory-pass.d.ts +0 -151
  1157. package/dist/memory-tidy.d.ts +0 -181
  1158. package/dist/memory-use.d.ts +0 -35
  1159. package/dist/merge-checklist.d.ts +0 -55
  1160. package/dist/metrics.d.ts +0 -6
  1161. package/dist/mobile-viewport.d.ts +0 -7
  1162. package/dist/model-catalog.d.ts +0 -123
  1163. package/dist/model-choices.d.ts +0 -235
  1164. package/dist/model-names.d.ts +0 -6
  1165. package/dist/models-cli.d.ts +0 -307
  1166. package/dist/models-ui.d.ts +0 -161
  1167. package/dist/modes.d.ts +0 -99
  1168. package/dist/monitoring-settings.d.ts +0 -44
  1169. package/dist/monitoring-ui.d.ts +0 -23
  1170. package/dist/monitoring.d.ts +0 -34
  1171. package/dist/names.d.ts +0 -67
  1172. package/dist/needs-you.d.ts +0 -164
  1173. package/dist/never-index.d.ts +0 -3
  1174. package/dist/nightly-check.d.ts +0 -107
  1175. package/dist/nightly-github.d.ts +0 -318
  1176. package/dist/notification-delivery.d.ts +0 -19
  1177. package/dist/notification-rows.d.ts +0 -30
  1178. package/dist/oauth-run-token.d.ts +0 -51
  1179. package/dist/observations.d.ts +0 -36
  1180. package/dist/oidc.d.ts +0 -71
  1181. package/dist/onboard.d.ts +0 -108
  1182. package/dist/one-step-chat-schema.d.ts +0 -22
  1183. package/dist/openrouter-models.d.ts +0 -34
  1184. package/dist/operate-remote-arguments.d.ts +0 -36
  1185. package/dist/operate-remote.d.ts +0 -98
  1186. package/dist/operate.d.ts +0 -401
  1187. package/dist/orphan-sweep.d.ts +0 -65
  1188. package/dist/page-work-contract.d.ts +0 -21
  1189. package/dist/password-bearer.d.ts +0 -25
  1190. package/dist/passwordless.d.ts +0 -23
  1191. package/dist/peek-cli.d.ts +0 -112
  1192. package/dist/peek.d.ts +0 -110
  1193. package/dist/people-audit-ui.d.ts +0 -16
  1194. package/dist/person-proof.d.ts +0 -2
  1195. package/dist/phase-routing.d.ts +0 -401
  1196. package/dist/plain-schema.d.ts +0 -23
  1197. package/dist/plain-words.d.ts +0 -20
  1198. package/dist/plan-auto.d.ts +0 -25
  1199. package/dist/plan-login.d.ts +0 -14
  1200. package/dist/plan.d.ts +0 -188
  1201. package/dist/plane-review.d.ts +0 -54
  1202. package/dist/planner-source.d.ts +0 -225
  1203. package/dist/planner.d.ts +0 -76
  1204. package/dist/policy-ui.d.ts +0 -22
  1205. package/dist/policy.d.ts +0 -92
  1206. package/dist/prepared-evidence.d.ts +0 -17
  1207. package/dist/principal.d.ts +0 -42
  1208. package/dist/probe.d.ts +0 -46
  1209. package/dist/process-custody.d.ts +0 -17
  1210. package/dist/process-liveness.d.ts +0 -13
  1211. package/dist/process-tree.d.ts +0 -39
  1212. package/dist/project-access.d.ts +0 -17
  1213. package/dist/project-activity.d.ts +0 -20
  1214. package/dist/project-admission.d.ts +0 -105
  1215. package/dist/project-cli.d.ts +0 -19
  1216. package/dist/project-concurrency.d.ts +0 -62
  1217. package/dist/project-delete-ui.d.ts +0 -96
  1218. package/dist/project-delete.d.ts +0 -59
  1219. package/dist/project-demo.d.ts +0 -12
  1220. package/dist/project-file.d.ts +0 -3
  1221. package/dist/project-identity.d.ts +0 -52
  1222. package/dist/project-knowledge.d.ts +0 -124
  1223. package/dist/project-learning.d.ts +0 -120
  1224. package/dist/project-memory.d.ts +0 -70
  1225. package/dist/project-outcomes.d.ts +0 -119
  1226. package/dist/project-sandbox.d.ts +0 -59
  1227. package/dist/project-skills.d.ts +0 -139
  1228. package/dist/project-tools.d.ts +0 -318
  1229. package/dist/project.d.ts +0 -65
  1230. package/dist/prompt.d.ts +0 -33
  1231. package/dist/proof.d.ts +0 -457
  1232. package/dist/proposal.d.ts +0 -70
  1233. package/dist/protected-storage-look.d.ts +0 -1
  1234. package/dist/protected-storage.d.ts +0 -98
  1235. package/dist/provider-auth.d.ts +0 -143
  1236. package/dist/provider-capture.d.ts +0 -34
  1237. package/dist/provider-connection.d.ts +0 -23
  1238. package/dist/provider-home.d.ts +0 -22
  1239. package/dist/provider-limits.d.ts +0 -37
  1240. package/dist/provider.d.ts +0 -369
  1241. package/dist/public-access.d.ts +0 -61
  1242. package/dist/public-check.d.ts +0 -37
  1243. package/dist/publish.d.ts +0 -146
  1244. package/dist/pull-request-flow.d.ts +0 -189
  1245. package/dist/pull-request-schema.d.ts +0 -5
  1246. package/dist/pull-request-ui.d.ts +0 -25
  1247. package/dist/pulls.d.ts +0 -121
  1248. package/dist/push.d.ts +0 -120
  1249. package/dist/quality.d.ts +0 -8
  1250. package/dist/quick-start.d.ts +0 -26
  1251. package/dist/read-executor-worker.d.ts +0 -1
  1252. package/dist/read-executor.d.ts +0 -66
  1253. package/dist/read-only-request.d.ts +0 -4
  1254. package/dist/recipe-ui.d.ts +0 -21
  1255. package/dist/recipes.d.ts +0 -56
  1256. package/dist/release-adapters.d.ts +0 -205
  1257. package/dist/release-approval.d.ts +0 -180
  1258. package/dist/release-authority.d.ts +0 -173
  1259. package/dist/release-auto.d.ts +0 -184
  1260. package/dist/release-card.d.ts +0 -170
  1261. package/dist/release-carry.d.ts +0 -261
  1262. package/dist/release-ci-hold.d.ts +0 -41
  1263. package/dist/release-cli.d.ts +0 -34
  1264. package/dist/release-coverage.d.ts +0 -16
  1265. package/dist/release-gate.d.ts +0 -84
  1266. package/dist/release-git.d.ts +0 -43
  1267. package/dist/release-links.d.ts +0 -29
  1268. package/dist/release-net.d.ts +0 -90
  1269. package/dist/release-next.d.ts +0 -48
  1270. package/dist/release-recheck.d.ts +0 -146
  1271. package/dist/release-refusal.d.ts +0 -32
  1272. package/dist/release-view.d.ts +0 -37
  1273. package/dist/release.d.ts +0 -806
  1274. package/dist/releases.d.ts +0 -94
  1275. package/dist/remote-audit.d.ts +0 -79
  1276. package/dist/remote-command.d.ts +0 -45
  1277. package/dist/remote-destination.d.ts +0 -36
  1278. package/dist/remote-exec.d.ts +0 -38
  1279. package/dist/remote-main.d.ts +0 -111
  1280. package/dist/remote-run.d.ts +0 -20
  1281. package/dist/remote.d.ts +0 -67
  1282. package/dist/render.d.ts +0 -64
  1283. package/dist/reply-shape.d.ts +0 -106
  1284. package/dist/reply-voice.d.ts +0 -23
  1285. package/dist/report-summary.d.ts +0 -22
  1286. package/dist/reported-usage.d.ts +0 -69
  1287. package/dist/repos.d.ts +0 -67
  1288. package/dist/repository-context-ui.d.ts +0 -3
  1289. package/dist/repository-context.d.ts +0 -66
  1290. package/dist/request-budget-ui.d.ts +0 -14
  1291. package/dist/request-budget.d.ts +0 -127
  1292. package/dist/restart-certification.d.ts +0 -133
  1293. package/dist/result-actions.d.ts +0 -36
  1294. package/dist/result-acts.d.ts +0 -112
  1295. package/dist/result-completion.d.ts +0 -39
  1296. package/dist/result-evidence-readers.d.ts +0 -42
  1297. package/dist/result-follow-ups.d.ts +0 -118
  1298. package/dist/result-review.d.ts +0 -220
  1299. package/dist/result-shots.d.ts +0 -59
  1300. package/dist/retention-ui.d.ts +0 -21
  1301. package/dist/retention.d.ts +0 -77
  1302. package/dist/review-context.d.ts +0 -245
  1303. package/dist/review-evidence.d.ts +0 -33
  1304. package/dist/review-switch.d.ts +0 -36
  1305. package/dist/reviewer.d.ts +0 -99
  1306. package/dist/route-change-check.d.ts +0 -4
  1307. package/dist/route-change.d.ts +0 -22
  1308. package/dist/route-hooks.d.ts +0 -54
  1309. package/dist/route-results.d.ts +0 -75
  1310. package/dist/route-rules.d.ts +0 -324
  1311. package/dist/route-savings.d.ts +0 -136
  1312. package/dist/route-store.d.ts +0 -300
  1313. package/dist/run-closeout.d.ts +0 -89
  1314. package/dist/run-efficiency.d.ts +0 -74
  1315. package/dist/run-ending.d.ts +0 -21
  1316. package/dist/runner-process.d.ts +0 -76
  1317. package/dist/runner.d.ts +0 -324
  1318. package/dist/sample-project.d.ts +0 -31
  1319. package/dist/sandbox-launch.d.ts +0 -1
  1320. package/dist/sandbox-runtime.d.ts +0 -128
  1321. package/dist/scan.d.ts +0 -32
  1322. package/dist/scope.d.ts +0 -1098
  1323. package/dist/scout-browser-lock.d.ts +0 -69
  1324. package/dist/scout-browser.d.ts +0 -107
  1325. package/dist/scout-net.d.ts +0 -25
  1326. package/dist/scout-report.d.ts +0 -23
  1327. package/dist/scout.d.ts +0 -142
  1328. package/dist/secret-mint.d.ts +0 -1
  1329. package/dist/serve.d.ts +0 -11
  1330. package/dist/server/agents-computers.d.ts +0 -9
  1331. package/dist/server/agents-live-filed.d.ts +0 -17
  1332. package/dist/server/agents-live-lead.d.ts +0 -47
  1333. package/dist/server/agents-live-room.d.ts +0 -23
  1334. package/dist/server/chat.d.ts +0 -39
  1335. package/dist/server/chrome.d.ts +0 -328
  1336. package/dist/server/edge-refusal.d.ts +0 -7
  1337. package/dist/server/flows.d.ts +0 -8
  1338. package/dist/server/guards.d.ts +0 -81
  1339. package/dist/server/handler-context.d.ts +0 -22
  1340. package/dist/server/handler-registry.d.ts +0 -23
  1341. package/dist/server/home-asks.d.ts +0 -45
  1342. package/dist/server/home.d.ts +0 -65
  1343. package/dist/server/http.d.ts +0 -337
  1344. package/dist/server/in-place.d.ts +0 -15
  1345. package/dist/server/kit-standalone.d.ts +0 -22
  1346. package/dist/server/kit.d.ts +0 -452
  1347. package/dist/server/last-checks.d.ts +0 -17
  1348. package/dist/server/live.d.ts +0 -74
  1349. package/dist/server/merge-ready-view.d.ts +0 -10
  1350. package/dist/server/mutation-key.d.ts +0 -70
  1351. package/dist/server/pages-assets.d.ts +0 -11
  1352. package/dist/server/pages.d.ts +0 -8
  1353. package/dist/server/people-tokens.d.ts +0 -18
  1354. package/dist/server/remote-hooks.d.ts +0 -29
  1355. package/dist/server/remote.d.ts +0 -60
  1356. package/dist/server/render-chat.d.ts +0 -439
  1357. package/dist/server/render-code-map.d.ts +0 -30
  1358. package/dist/server/render-flaky.d.ts +0 -20
  1359. package/dist/server/render-follow-through.d.ts +0 -11
  1360. package/dist/server/render-history.d.ts +0 -51
  1361. package/dist/server/render-new-task.d.ts +0 -54
  1362. package/dist/server/render-pages.d.ts +0 -236
  1363. package/dist/server/render-people.d.ts +0 -102
  1364. package/dist/server/render-projects.d.ts +0 -104
  1365. package/dist/server/render-release.d.ts +0 -19
  1366. package/dist/server/render-results.d.ts +0 -758
  1367. package/dist/server/render-settings.d.ts +0 -93
  1368. package/dist/server/render-tasks.d.ts +0 -783
  1369. package/dist/server/request-context.d.ts +0 -78
  1370. package/dist/server/retired-routes.d.ts +0 -17
  1371. package/dist/server/route-policy.d.ts +0 -18
  1372. package/dist/server/route-table.d.ts +0 -114
  1373. package/dist/server/runtime.d.ts +0 -343
  1374. package/dist/server/session.d.ts +0 -192
  1375. package/dist/server/settings.d.ts +0 -76
  1376. package/dist/server/signup-gate.d.ts +0 -9
  1377. package/dist/server/sweeps.d.ts +0 -4
  1378. package/dist/server/task-views.d.ts +0 -98
  1379. package/dist/server/tasks.d.ts +0 -108
  1380. package/dist/server/terminals.d.ts +0 -31
  1381. package/dist/server/welcome.d.ts +0 -28
  1382. package/dist/server-telemetry.d.ts +0 -87
  1383. package/dist/settings-groups-ui.d.ts +0 -286
  1384. package/dist/settings-kit-script.d.ts +0 -21
  1385. package/dist/settings-kit.d.ts +0 -173
  1386. package/dist/settings-proofs.d.ts +0 -64
  1387. package/dist/setup-guide.d.ts +0 -39
  1388. package/dist/shared-deps.d.ts +0 -115
  1389. package/dist/sign-in-guard.d.ts +0 -70
  1390. package/dist/skills-ui.d.ts +0 -12
  1391. package/dist/skills.d.ts +0 -99
  1392. package/dist/slack-api.d.ts +0 -59
  1393. package/dist/slack-chat.d.ts +0 -37
  1394. package/dist/slack-settings.d.ts +0 -4
  1395. package/dist/slack-socket.d.ts +0 -12
  1396. package/dist/slack.d.ts +0 -6
  1397. package/dist/sleep.d.ts +0 -2
  1398. package/dist/source-key.d.ts +0 -2
  1399. package/dist/spend-report.d.ts +0 -87
  1400. package/dist/spend-ui.d.ts +0 -80
  1401. package/dist/spend.d.ts +0 -142
  1402. package/dist/sqlite-runtime.d.ts +0 -3
  1403. package/dist/sqlite-telemetry.d.ts +0 -9
  1404. package/dist/sso-settings.d.ts +0 -33
  1405. package/dist/sso-ui.d.ts +0 -26
  1406. package/dist/staged-runtimes.d.ts +0 -54
  1407. package/dist/steer-capabilities.d.ts +0 -32
  1408. package/dist/steer-controls.d.ts +0 -14
  1409. package/dist/steer-live.d.ts +0 -19
  1410. package/dist/steer-mailbox.d.ts +0 -46
  1411. package/dist/steer-status.d.ts +0 -25
  1412. package/dist/stop-proof.d.ts +0 -67
  1413. package/dist/storage-sweep-child.d.ts +0 -1
  1414. package/dist/storage-sweep-process.d.ts +0 -55
  1415. package/dist/storage-sweep-schedule.d.ts +0 -30
  1416. package/dist/storage-sweep.d.ts +0 -77
  1417. package/dist/storage-ui.d.ts +0 -23
  1418. package/dist/storage.d.ts +0 -68
  1419. package/dist/store-baseline.d.ts +0 -19
  1420. package/dist/store.d.ts +0 -8613
  1421. package/dist/stream-scope.d.ts +0 -18
  1422. package/dist/structured-output.d.ts +0 -57
  1423. package/dist/style-asset.d.ts +0 -7
  1424. package/dist/subagent-admin.d.ts +0 -53
  1425. package/dist/subagent-desk.d.ts +0 -59
  1426. package/dist/subagent-memory.d.ts +0 -65
  1427. package/dist/subagent-question.d.ts +0 -59
  1428. package/dist/subagent-tools.d.ts +0 -125
  1429. package/dist/subagent-week.d.ts +0 -68
  1430. package/dist/subagent-work.d.ts +0 -76
  1431. package/dist/subagents-ui.d.ts +0 -22
  1432. package/dist/subagents.d.ts +0 -146
  1433. package/dist/subscription-chat.d.ts +0 -54
  1434. package/dist/summary.d.ts +0 -33
  1435. package/dist/surface.d.ts +0 -49
  1436. package/dist/sweep-gate.d.ts +0 -10
  1437. package/dist/sweep-quarantine.d.ts +0 -29
  1438. package/dist/sync.d.ts +0 -94
  1439. package/dist/tailnet.d.ts +0 -11
  1440. package/dist/tamper-scan.d.ts +0 -4
  1441. package/dist/task-activity.d.ts +0 -27
  1442. package/dist/task-aliases.d.ts +0 -5
  1443. package/dist/task-archive.d.ts +0 -13
  1444. package/dist/task-base.d.ts +0 -39
  1445. package/dist/task-composer.d.ts +0 -14
  1446. package/dist/task-control.d.ts +0 -159
  1447. package/dist/task-live.d.ts +0 -8
  1448. package/dist/task-moves.d.ts +0 -90
  1449. package/dist/task-outcome-cli.d.ts +0 -48
  1450. package/dist/task-review-brief.d.ts +0 -69
  1451. package/dist/task-sizing.d.ts +0 -58
  1452. package/dist/task-source.d.ts +0 -77
  1453. package/dist/task-status.d.ts +0 -324
  1454. package/dist/task-text.d.ts +0 -31
  1455. package/dist/team-chat-authorization.d.ts +0 -11
  1456. package/dist/team-contract.d.ts +0 -103
  1457. package/dist/team-http.d.ts +0 -25
  1458. package/dist/team-leads.d.ts +0 -85
  1459. package/dist/team-runtime.d.ts +0 -25
  1460. package/dist/team-ui.d.ts +0 -4
  1461. package/dist/team-updates.d.ts +0 -8
  1462. package/dist/teams-api.d.ts +0 -33
  1463. package/dist/teams-chat.d.ts +0 -36
  1464. package/dist/teams-settings.d.ts +0 -14
  1465. package/dist/teams.d.ts +0 -24
  1466. package/dist/teardown-git.d.ts +0 -164
  1467. package/dist/telegram-flow.d.ts +0 -112
  1468. package/dist/telegram-lead.d.ts +0 -151
  1469. package/dist/telegram-live.d.ts +0 -116
  1470. package/dist/telegram-progress.d.ts +0 -20
  1471. package/dist/telegram-settings.d.ts +0 -9
  1472. package/dist/telegram-status.d.ts +0 -83
  1473. package/dist/telegram-team.d.ts +0 -68
  1474. package/dist/telegram.d.ts +0 -271
  1475. package/dist/templates.d.ts +0 -69
  1476. package/dist/terminal-catalog.d.ts +0 -11
  1477. package/dist/terminal-text.d.ts +0 -11
  1478. package/dist/test-infra.d.ts +0 -34
  1479. package/dist/test-temp.d.ts +0 -40
  1480. package/dist/text-limits.d.ts +0 -297
  1481. package/dist/tidy.d.ts +0 -130
  1482. package/dist/tier-report.d.ts +0 -44
  1483. package/dist/token-notices.d.ts +0 -11
  1484. package/dist/tokens-cli.d.ts +0 -21
  1485. package/dist/tool-broker.d.ts +0 -52
  1486. package/dist/tool-launcher.d.ts +0 -1
  1487. package/dist/tool-secret-store.d.ts +0 -167
  1488. package/dist/toolroll-update-cli.d.ts +0 -15
  1489. package/dist/toolroll-update-ui.d.ts +0 -47
  1490. package/dist/toolroll-update.d.ts +0 -265
  1491. package/dist/tools-ui.d.ts +0 -51
  1492. package/dist/transitions-recipes.d.ts +0 -1
  1493. package/dist/tree-proof.d.ts +0 -34
  1494. package/dist/tui-contract.d.ts +0 -202
  1495. package/dist/tui-source.d.ts +0 -14
  1496. package/dist/typed-start.d.ts +0 -51
  1497. package/dist/unfenced-test-support.d.ts +0 -2
  1498. package/dist/up-processes.d.ts +0 -162
  1499. package/dist/up-role-child.d.ts +0 -1
  1500. package/dist/update-notice.d.ts +0 -5
  1501. package/dist/vanished-retry.d.ts +0 -30
  1502. package/dist/verification-evidence.d.ts +0 -68
  1503. package/dist/version.d.ts +0 -2
  1504. package/dist/wake-hub.d.ts +0 -72
  1505. package/dist/webhook-limits.d.ts +0 -23
  1506. package/dist/webhook-readers.d.ts +0 -56
  1507. package/dist/webhook-signing.d.ts +0 -27
  1508. package/dist/webhooks.d.ts +0 -84
  1509. package/dist/welcome-facts.d.ts +0 -18
  1510. package/dist/when-html.d.ts +0 -40
  1511. package/dist/work-index.d.ts +0 -175
  1512. package/dist/work-summary.d.ts +0 -61
  1513. package/dist/workspace-motion.d.ts +0 -4
  1514. package/dist/workspace-revision.d.ts +0 -48
  1515. package/dist/workspace-ui.d.ts +0 -385
  1516. package/dist/worktree-notices.d.ts +0 -13
  1517. package/dist/worktree.d.ts +0 -365
  1518. package/dist/writes-mode.d.ts +0 -9
  1519. package/dist/youiyoux-intake.d.ts +0 -234
package/dist/serve.js CHANGED
@@ -20,8 +20,6 @@ import { html, htmlString, jsonScript, textHtml } from "./html.js";
20
20
  import { browserAssetsAvailable, browserWorkspaceDocument } from './browser-shell.js';
21
21
  import { accessKey, countsKey, indexKey, projectSummaryOf, RevisionCache, summaryKey } from './console-chrome.js';
22
22
  import { usageChipOf } from './limits-ui.js';
23
- /** How often the background checks look at what is due (docs/plans/get-side-effects.md), and how often this
24
- * computer's agent sign-ins are asked again. */
25
23
  const BACKGROUND_CHECKS_MS = 30_000;
26
24
  const LOCAL_AGENTS_EVERY_MS = 2 * 60_000;
27
25
  import { browserCrewFromIndex, browserCrewOf, browserNavigationOf, browserProjectsOf, needsYouLabelOf } from './browser-workspace.js';
@@ -61,48 +59,6 @@ import {} from "./tools-ui.js";
61
59
  import { WORK_INDEX_MAX_LIMIT, workCountsByProject, workIndexPage } from "./work-index.js";
62
60
  import { WORKSPACE_MOTION_SCRIPT } from "./workspace-motion.js";
63
61
  import { prepareWorkspaceRevision, WorkspaceValidatorCache } from "./workspace-revision.js";
64
- /**
65
- * The web console (§7, grown per the console review): the whole built-in
66
- * queue, visible and operable from a phone. `toolroll serve` — node:http,
67
- * no dependencies, no JavaScript in the page. TLS is a proxy's job and the
68
- * docs say so; what is not delegated is everything else:
69
- *
70
- * **Authentication is required on every bind, localhost included.** The
71
- * credential is the approver's — the same name-and-token that approves a
72
- * scope and answers in the CLI — because `answered_by` must be an identity
73
- * somebody proved, not a string a request asserted. A browser logs in once
74
- * (POST /login) and carries an HttpOnly SameSite=Strict session cookie; an
75
- * API caller sends `Authorization: Bearer <name>:<token>` per request. The
76
- * token never travels in a URL, where it would land in history and logs.
77
- *
78
- * **Every request proves its Host** against the names this server was told
79
- * it answers as. Cookie-authenticated mutations additionally pass one
80
- * centralized gate — `authorizeMutation` — that proves content type, an
81
- * allowed Origin, and the per-session CSRF nonce, and refuses duplicated
82
- * security fields; a mutation route cannot forget a check it never wrote.
83
- * Bearer mutations carry no cookie for a hostile page to ride, so they skip CSRF.
84
- * Step-up ceremonies still require a cookie session; repeating a bearer password cannot approve.
85
- *
86
- * **Approval is step-up.** A session alone never approves a scope: the
87
- * approval form restates the goal, the exclusions, and the touches — the
88
- * three fields the digest binds — and requires the approver token typed
89
- * again, plus (for browsers) a single-use nonce minted when the form was
90
- * rendered, bound server-side to who saw which digest of which task. A
91
- * stolen cookie can read; it cannot agree to work.
92
- *
93
- * **GET never mutates.** Overdue-ness is derived at render time from the
94
- * deadline on the row; the durable expiry sweep belongs to the CLI's
95
- * surfaces and the loop, not to a crawler hitting a page.
96
- *
97
- * **Everything rendered is escaped at the sink**, and every identifier in an
98
- * href is URL-encoded first — HTML escaping does not make `a/b?x=1` a valid
99
- * path segment. The CSP is belt to those suspenders.
100
- *
101
- * **Evidence goes through one verified reader** (`readVerifiedArtifact`) and
102
- * membership is enforced by the lookup — a decision serves only its linked
103
- * artifacts, a run only its own rows, and when this server was scoped to a
104
- * repo, only runs whose task belongs to that repo (or to no repo yet).
105
- */
106
62
  import { createHash, randomBytes } from "node:crypto";
107
63
  import { keepSlowRequest, Timeline } from "./latency-timeline.js";
108
64
  import { readFileSync } from "node:fs";
@@ -156,8 +112,9 @@ import { createPeopleHandlers } from './server/people-tokens.js';
156
112
  import { createSettingsHandlers } from './server/settings.js';
157
113
  import { readPurpose, requestContext } from "./server/request-context.js";
158
114
  import { inPlaceRoute, prefetchRoute } from "./server/in-place.js";
115
+ import { advancedShownFor } from "./advanced.js";
159
116
  import { LOCAL_OWNER_ELSEWHERE, asLocalOwner, localModeOn, localOwnerRefusal, localOwnerStandsNow } from "./local-owner.js";
160
- import { defaultAgentOf, fillDefaultRouting } from "./model-choices.js";
117
+ import { defaultAgentOf, fillDefaultRouting, fillRoutingOnSignIn } from "./model-choices.js";
161
118
  import { chromeScript, DEMO_BANNER, DEMO_BANNER_SHORT, focusDocument, KBD_HELP, pinnedTheme, QUEUE_VIEW, refuse, screen, SENSITIVE_INPUT, shell, sidebarScript } from "./server/chrome.js";
162
119
  import { BODY_CAP, form, loginHref, passwordSetNext, refusalNext, matchTaskPath, page, projectChatHref, redactedPath, redirect, respond, safeReturn, SHUTDOWN_WAIT_MS, taskChatHref } from "./server/http.js";
163
120
  import { decisionsFor, LEAD_BY_DEFAULT_FACT, leadBrowserMessages, leadChatVersion, NOT_STARTED_SESSION, TASK_COMPOSER_MODES, teamProposalCardParts } from "./server/render-chat.js";
@@ -178,8 +135,6 @@ import { loadConsoleUrl } from "./webhooks.js";
178
135
  import { reviewFactsOf } from "./workspace-ui.js";
179
136
  import { WorktreePool } from "./worktree.js";
180
137
  export function createDecisionServer(options) {
181
- // Identities come from what the console's start resolved off its thread (startConsole); a path that didn't answer
182
- // stays unresolved, kept restrictive. Without them (embedders, tests) the old synchronous reads apply.
183
138
  const identities = options.identities ?? syncProjectIdentities();
184
139
  const { projectFamilyPeek, familiesInView, familyTasksInView, revisionDestination, runIsLive, runIsTaskResult, revisionViewOf, taskViewData, routeViewOf, taskChatFocus, pullRequestTargetOf, failureOf, explainAttempt, taskScreen, armTaskResume, planViewOf, planContractViewOf, revisionDocOf, revisionLedgerOf, resultDetailOf } = createTaskViews({
185
140
  get store() { return store; },
@@ -232,18 +187,14 @@ export function createDecisionServer(options) {
232
187
  }
233
188
  }
234
189
  }
235
- // Live terminals (docs/plans/live-terminal.md): on a machine that runs agents, when this install has a pty library.
236
190
  const terminals = terminalHostFor(store, options);
237
191
  const clock = options.clock ?? (() => new Date());
238
- // Heavy reads (the work index behind `task list`) run on read-only worker connections, off the request loop.
239
192
  const readFile = store.isDemo() ? null : store.databaseFile();
240
193
  const readWorkers = options.readWorkers ?? (process.env["VITEST"] !== undefined ? 0 : defaultReadWorkers());
241
194
  const reads = readFile === null || readWorkers < 1 ? null : new ReadExecutor(readFile, readWorkers);
242
195
  const detachReads = reads === null ? () => { } : attachReadExecutor(store, reads);
243
- /** Task checkouts, for Settings → Storage: the pool's own root, or the folder beside the database. */
244
196
  const storagePool = (databaseFile) => new WorktreePool(store, { root: options.poolRoot ?? join(dirname(databaseFile), "worktrees") });
245
197
  const install = installMethod(options.installBin);
246
- /** What the last daily check found (the cache only, never the network), or nothing while checks are off. */
247
198
  const updateFacts = () => {
248
199
  if (options.configDir === undefined)
249
200
  return null;
@@ -251,7 +202,6 @@ export function createDecisionServer(options) {
251
202
  const release = switched.off ? null : cachedRelease(options.configDir);
252
203
  return { release, newer: release !== null && isNewer(release.version, PACKAGE_VERSION), on: !switched.off, byEnv: switched.byEnv };
253
204
  };
254
- /** Settings → Updates, for everyone who can open Settings; only an operator may flip the switch. */
255
205
  const settingsUpdates = (actor, csrf) => {
256
206
  const facts = updateFacts();
257
207
  if (facts === null)
@@ -269,29 +219,20 @@ export function createDecisionServer(options) {
269
219
  };
270
220
  };
271
221
  const workspaceRevision = prepareWorkspaceRevision(store);
272
- // The sidebar, the Tasks count and the crew: read at most once per workspace revision per reader's exact access
273
- // (console-chrome.ts), and filled from a read worker before a page renders when one is attached.
274
222
  const chromeReads = new RevisionCache(workspaceRevision, clock);
275
223
  const workspaceIncarnation = randomBytes(16).toString('hex');
276
224
  const workspaceValidators = new WorkspaceValidatorCache();
277
225
  const providerHome = options.connectionHome ?? homedir();
278
226
  const checkConnection = createConnectionChecker({ home: providerHome, clock, ...(options.connectionProbe === undefined ? {} : { probe: options.connectionProbe }) });
279
- // Every sign-in check the console makes also answers a sign-in pause.
280
- // Whether this computer can fence agents: asked once as the console starts (a sandbox running /usr/bin/true), so
281
- // Settings → Project never starts a process (docs/plans/get-side-effects.md).
282
227
  const fenceHere = options.fenceAvailable === undefined ? macosFenceAvailable() || linuxFenceAvailable() : false;
283
- // Phone notifications' signing pair, made once as the console starts so /push/key only reads it.
284
228
  if (options.telegramTokenFile !== undefined) {
285
229
  try {
286
230
  loadOrCreateVapidKeys(dirname(options.telegramTokenFile));
287
231
  }
288
- catch { /* /push/key says push is not set up */ }
232
+ catch { }
289
233
  }
290
- // The last answer of every other check a page shows (docs/plans/get-side-effects.md).
291
234
  const lastChecks = new LastChecks();
292
- /** The newest release, asked of npm (Settings → Updates shows the last answer). */
293
235
  const checkRelease = () => lastChecks.run("release", () => latestReleaseFor(options.updates?.latest));
294
- // What each sign-in check said last: what a page shows (docs/plans/get-side-effects.md). A page never checks.
295
236
  const knownConnections = new Map();
296
237
  const connectionKnown = (provider) => knownConnections.get(provider) ?? null;
297
238
  const connectionCheck = async (provider, fresh) => {
@@ -300,10 +241,9 @@ export function createDecisionServer(options) {
300
241
  try {
301
242
  noteSignInProbe(store, provider, value.state, clock());
302
243
  }
303
- catch { /* the pause keeps its own state */ }
244
+ catch { }
304
245
  return value;
305
246
  };
306
- // Settings → Integrations: checked in the background with a short cache, as the first-run suggestions are.
307
247
  const integrations = createIntegrationMonitor(() => ({
308
248
  store,
309
249
  dir: options.configDir ?? null,
@@ -324,24 +264,10 @@ export function createDecisionServer(options) {
324
264
  ...(options.modelPath === undefined ? {} : { path: options.modelPath }),
325
265
  };
326
266
  const sessions = new PersistentSessions(store);
327
- // Sessions from before a restart that ran out, or whose account changed since, go now.
328
267
  store.sweepWebSessions(Date.now(), SESSION_IDLE_MS, SESSION_ABSOLUTE_MS);
329
- /** Where a new session signs in from: the browser (its user agent, short) and the address. */
330
268
  const arrival = (request) => ({ agent: (request.headers["user-agent"] ?? "").slice(0, 300) || null, address: forwardedSourceOf(request).replace(/^fwd:/, "") });
331
- /** Wrong setup codes left before the first-account road closes. */
332
269
  let setupAttemptsLeft = 5;
333
- // The /join road's limiter (D6; Codex people round 1, finding 4):
334
- // PER-SOURCE buckets so one stranger cannot drain sign-up capacity for
335
- // everyone, under a global ceiling that bounds total KDF work. Spent
336
- // only by WELL-FORMED submissions — malformed requests are refused by
337
- // the shape guards for free. The per-invite attempt counter remains the
338
- // durable meter; these buckets only price the trying.
339
270
  const joinBySource = new Map();
340
- /** The per-source key (round 2, finding 4): the direct peer — except
341
- * behind the documented same-host TLS proxy, where every client would
342
- * share the proxy's one bucket. A LOOPBACK peer is that proxy, and only
343
- * then is the forwarded chain believed, taking the LAST hop (the one
344
- * the trusted proxy itself appended; earlier entries are client-typed). */
345
271
  function forwardedSourceOf(request) {
346
272
  const peer = request.socket.remoteAddress ?? "unknown";
347
273
  const loopback = LOOPBACK_PEERS.has(peer);
@@ -352,45 +278,27 @@ export function createDecisionServer(options) {
352
278
  const lastHop = chain.split(",").pop()?.trim() ?? "";
353
279
  return lastHop === "" ? peer : `fwd:${lastHop.slice(0, 64)}`;
354
280
  }
355
- /** That source as every per-source budget counts it: a native IPv6 caller by its /64 (source-key.ts). */
356
281
  function joinSourceOf(request) { return sourceKey(forwardedSourceOf(request)); }
357
282
  const signInBudget = new SourceBudget();
358
- // A re-check or a link is the session that started it: its kept hash and credential generation ride the visit and the
359
- // hand-off, and finish refuses any other session (a sign-out and a new sign-in in between never inherit it).
360
283
  const ssoVisits = new Map();
361
284
  const ssoHandoffs = new Map();
362
285
  let ssoProvider = null;
363
286
  const ssoSettings = () => readSsoSettings(options.configDir);
364
287
  const ssoOffer = () => { const settings = ssoSettings(); return settings === null ? null : { label: settings.label, operatorsOnly: settings.passwords === "operators" }; };
365
- /** A step-up within this long of the provider checking someone needs no password. */
366
- // The one-time sign-in link `up` opens in the browser: single use, ten minutes, from this computer only. Only a hash
367
- // of the code is kept, in memory; the code itself is never written to a log or the ledger.
368
288
  const signInLinks = new Map();
369
289
  const linkKey = (code) => createHash("sha256").update(code).digest("hex");
370
290
  function mintSignInLink(account) {
371
291
  const known = store.accountOf(account);
372
- // A full link is for an account with a password: a local owner without one gets only mintLocalLink's.
373
292
  if (known === null || known.role !== "approver" || known.revokedAt !== null || !known.passwordSet)
374
293
  return null;
375
294
  return holdSignInLink({ kind: "full", account, expires: Date.now() + SIGN_IN_LINK_MS });
376
295
  }
377
- /** v147: this console start's key epoch (easy-start C2): the browser-key wave binds each session's mutation key to it. */
378
296
  const keyEpoch = options.keyEpoch ?? randomBytes(16).toString("hex");
379
- /** This computer, and nothing in front of it: a loopback peer that names a loopback address, with no sign of a proxy —
380
- * any forwarding header at all (Forwarded, X-Forwarded-*, X-Real-IP, Via, …) disqualifies the request. The one reading
381
- * (public-access.ts), which guards.ts also applies to every request a local owner's session makes. */
382
297
  const fromThisComputer = (request) => requestFromThisComputer(request);
383
- /**
384
- * Cockpit B2: a request's password-freshness facts — the one place they are made (scope.ts honours them). Every
385
- * reader looks at the session as it is at the moment of the act, never a snapshot taken before the body arrived:
386
- * still signed in here, under the account's current credential generation, after any Forget.
387
- */
388
298
  function freshFactsOf(request, who, allowlisted = false) {
389
299
  if (who?.via !== 'cookie')
390
300
  return null;
391
301
  const session = who.session, local = fromThisComputer(request);
392
- // The same validity lookupSession applies, read again at the act: held here, within its idle and absolute
393
- // lifetimes, under the account's current credential generation, not revoked.
394
302
  const live = () => {
395
303
  const now = Date.now(), account = store.accountOf(who.name);
396
304
  return sessions.holds(session) && sessions.savedNow(session) && sessionWithinLifetime(session, now)
@@ -402,14 +310,12 @@ export function createDecisionServer(options) {
402
310
  consumeSsoNow: () => {
403
311
  const was = session.ssoNowAt;
404
312
  delete session.ssoNowAt;
405
- // A refund puts back only what this spend took, once, and only if nothing newer arrived (Forget still floors it).
406
313
  let refunded = false;
407
314
  return () => { if (refunded)
408
315
  return; refunded = true; if (was !== undefined && session.ssoNowAt === undefined)
409
316
  session.ssoNowAt = was; };
410
317
  },
411
318
  floor: () => session.freshFloor ?? 0,
412
- // Only a direct local request may start a password window (a typed password elsewhere proves now, nothing more).
413
319
  stamp: at => { if (local && live())
414
320
  session.passwordAt = at; } };
415
321
  }
@@ -421,9 +327,6 @@ export function createDecisionServer(options) {
421
327
  ssoProvider = { issuer, provider: found.provider, at: Date.now() };
422
328
  return found;
423
329
  }
424
- /** The identity provider as last discovered: what starting a sign-in uses (a GET, so it fetches nothing,
425
- * docs/plans/get-side-effects.md). Discovered as the console starts, by the background checks every ten minutes, and
426
- * when sign-in settings are saved or tested. */
427
330
  function providerKnown(issuer) {
428
331
  return ssoProvider !== null && ssoProvider.issuer === issuer ? ssoProvider.provider : null;
429
332
  }
@@ -432,10 +335,8 @@ export function createDecisionServer(options) {
432
335
  if (settings !== null)
433
336
  void providerFor(settings.issuer).catch(() => undefined);
434
337
  }
435
- /** Password sign-in is only for instance operators when the provider says so (a way in if it's down). */
436
338
  const passwordAllowed = (name) => { const settings = ssoSettings(); return settings === null || settings.passwords === "everyone" || store.isInstanceOperator(name); };
437
339
  const minutesWords = (ms) => { const minutes = Math.max(1, Math.ceil(ms / 60_000)); return minutes >= 120 ? `${Math.round(minutes / 60)} hours` : `${minutes} minute${minutes === 1 ? "" : "s"}`; };
438
- /** A sign-in event names the account only when it exists: what someone typed into the name box stays out of history. */
439
340
  const signInActor = (name) => name !== null && store.accountOf(name) !== null ? name : "unknown account";
440
341
  const recordSignIn = (actor, action, outcome, detail = null) => {
441
342
  try {
@@ -452,28 +353,14 @@ export function createDecisionServer(options) {
452
353
  };
453
354
  let joinGlobal = { tokens: 30, refilledAt: Date.now() };
454
355
  const approvalNonces = new Map();
455
- // Startup authority: the configured repos and roots as their identities say (startupCeiling). Missing or unresolved
456
- // paths remain restrictive. Native additions come only from the controller after its admission checks.
457
356
  const { ceiling, unresolved: unresolvedRepos, defaultProject, configured, configuredPaths } = startupCeiling([...(options.repo === undefined ? [] : [options.repo]), ...(options.repos ?? [])], options.projectRoots ?? [], options.identities === undefined ? undefined : identities, identities.strict);
458
- /** No ceiling configured at all: the legacy trust-everything mode, named. */
459
- // An `up` console (it is handed its admitted set) is never unscoped: with every saved project away it is empty.
460
- // Judged by what was configured, never by what has resolved so far: a console whose folders haven't answered yet is
461
- // scoped and empty, not unscoped.
462
357
  const unscopedMode = !configured && options.admittedRepos === undefined;
463
- /** Per-row visibility under the ceiling — the authorization question for reads. */
464
- /** The exact repositories this console serves now: `up`'s live admitted set when it supplies one, else startup's. */
465
358
  const exactRepos = () => options.admittedRepos?.() ?? ceiling.repos;
466
359
  const liveCeiling = () => {
467
360
  const repos = [...exactRepos(), ...(options.additionalProjectRepos?.() ?? [])];
468
- // An admitted set that is empty for now is an empty ceiling, never the legacy unscoped mode.
469
361
  return { repos: repos.length === 0 && ceiling.roots.length === 0 && !unscopedMode ? [NO_PROJECT] : repos, roots: ceiling.roots, canon: identities.strict };
470
362
  };
471
- /** The explicit, currently proved project list. The callback is supplied
472
- * only by `up`, after it has independently checked git-ness and the root
473
- * ceiling; this server still filters every row through its own ceiling. */
474
- /** Projects deleted while this console runs: gone from its lists though a builder started with them still watches. */
475
363
  const deletedRepos = new Set();
476
- /** Those still gone: a project added again (from here, `repos add`, or the lead) has its row back and shows again. */
477
364
  const goneRepos = () => {
478
365
  if (deletedRepos.size === 0)
479
366
  return deletedRepos;
@@ -494,7 +381,6 @@ export function createDecisionServer(options) {
494
381
  }
495
382
  return repos;
496
383
  };
497
- /** Settings → Project's view of a project: what's held for it, what's running, and whether this person may delete it. */
498
384
  const projectViewOf = (repo, who) => ({
499
385
  repo, name: projectName(repo), holdings: projectHoldings(store, repo), running: projectRunning(store, repo, clock()),
500
386
  canDelete: who.via === "cookie" && store.isInstanceOperator(who.name),
@@ -514,18 +400,15 @@ export function createDecisionServer(options) {
514
400
  liveView: (() => {
515
401
  const commands = liveCommandsShown(store, repo);
516
402
  const canChange = who.via === "cookie" && who.role === "approver" && !store.isDemo() && store.accountCanAccess(who.name, repo);
517
- // Showing commands is consent to one exact change: a single-use nonce for this person, project and terms.
518
403
  return { commands, canChange, ...(canChange && !commands ? { nonce: mintApprovalNonce(who.name, LIVE_VIEW_CONSENT, liveViewConsentDigest(repo)) } : {}) };
519
404
  })(),
520
405
  });
521
- /** Settings → Project → Build access: the project's named tools and whether each loads for its builds. */
522
406
  const projectAccessOf = (repo) => {
523
407
  try {
524
408
  const policy = store.orgPolicy();
525
409
  return { tools: projectToolsOf(store, repo).map(tool => {
526
410
  const refused = toolRefusal(policy, tool.name);
527
411
  const set = secretsSetFor(repo, tool.spec, toolHome);
528
- // As a launch decides (toolLaunchFor): a tool the organisation doesn't allow, or missing a secret, is left out.
529
412
  return refused !== null ? { name: tool.name, loads: false, words: refused }
530
413
  : { name: tool.name, loads: tool.spec.secrets.every(one => one.optional || set.includes(one.name)), words: toolStanding(tool, set).words };
531
414
  }) };
@@ -534,7 +417,6 @@ export function createDecisionServer(options) {
534
417
  return { problem: "Couldn't read this project's tools right now." };
535
418
  }
536
419
  };
537
- /** Settings → Project → Builds at once: the saved number, its workers' capacity, and what builds now. */
538
420
  const projectBuildsOf = (repo, who) => {
539
421
  const capacities = store.listRunners().filter(one => one.retiredAt === null && one.repos.includes(repo)).map(one => one.capacity);
540
422
  return {
@@ -544,7 +426,6 @@ export function createDecisionServer(options) {
544
426
  canChange: who.via === "cookie" && who.role === "approver" && store.accountCanAccess(who.name, repo),
545
427
  };
546
428
  };
547
- /** Codex's own MCP servers for a project (`codex mcp list --json`), for "Found on this computer"; null when Codex can't say. */
548
429
  const codexServers = async (repo) => {
549
430
  try {
550
431
  const listed = await (options.codexToolList ?? (async (cwd) => {
@@ -558,38 +439,28 @@ export function createDecisionServer(options) {
558
439
  return null;
559
440
  }
560
441
  };
561
- /** One project's Tools page: its tools with which secrets are set (never values), the common tools not yet added, and what this computer already has. */
562
- // A test's own folder for tool secrets and found tools; Toolroll's own (beside its database, and this home) otherwise.
563
442
  const toolHome = options.toolHome;
564
443
  const toolsViewOf = (repo, codex, kit = null, wanted = null) => {
565
444
  const tools = projectToolsOf(store, repo);
566
445
  const names = new Set(tools.map(one => one.name));
567
446
  return {
568
447
  repo, project: repo.split(/[\\/]/).filter(Boolean).at(-1) ?? repo,
569
- // Secrets that can't be read (a refused folder, a locked keychain) read as none set: the page says why once (storage).
570
448
  tools: tools.map(tool => { let secretsSet = []; try {
571
449
  secretsSet = secretsSetFor(repo, tool.spec, toolHome);
572
450
  }
573
451
  catch {
574
452
  secretsSet = [];
575
453
  } return { tool, secretsSet }; }),
576
- // A service that connects by signing in (or an app's own Connect) is offered only that way.
577
454
  catalog: TOOL_CATALOG.filter(one => !names.has(one.name) && oneClickOf(one.name) === null && localConnectOf(one.name) === null),
578
455
  connections: connectionsOf(store, repo, toolHome), kit, wanted,
579
- // The project's own .mcp.json as the background pass last read it off the console's thread (never read here).
580
456
  found: discoverTools(repo, codex, toolHome, process.env, options.identities === undefined ? undefined : savedProjectMcp.get(repo) ?? null).filter(one => !names.has(one.spec.name)),
581
457
  storage: toolSecretStorage(),
582
458
  };
583
459
  };
584
460
  const codingProjects = () => [...new Set([...managedRepos(), ...store.listProjects().map(project => project.path)])].filter(repo => rowVisible(liveCeiling(), repo));
585
- /** Open chat streams (live replies), ended when the server closes. */
586
461
  let liveTurnStarted = () => { };
587
- /** Google sign-ins in progress (v89): each consent visit's state, for 10 minutes. */
588
462
  const googleVisits = new Map();
589
- /** One-click connections on their way: the service's sign-in page and back, 15 minutes at most. */
590
463
  const connectVisits = new Map();
591
- /** Flows open in a browser (v88): who's here, and a nudge when one changes. */
592
- // Live views push on write (live-bus.ts): each commit moves the workspace revision, the rooms hear it.
593
464
  const liveBus = createLiveBus();
594
465
  const liveFollower = followWorkspace(store, () => workspaceRevision.current(), liveBus, { file: store.databaseFile() });
595
466
  const flowRooms = createFlowRooms(flow => flowFingerprint(store, flow), { bus: liveBus });
@@ -600,9 +471,6 @@ export function createDecisionServer(options) {
600
471
  provider: teamChatProvider,
601
472
  ...(options.subscriptionChatRunner ? { subscriptionRunner: options.subscriptionChatRunner } : {}),
602
473
  });
603
- // The personal lead queue (docs/plans/lead-message-queue.md). Projects and a message's task are re-proved AS the
604
- // person (never from a live request's context), and its live reply display is the console's own (chat handlers below,
605
- // reached only once the server is listening).
606
474
  const asActor = (account, work) => requestContext.run({ csrf: "", returnTo: "/", actor: account }, work);
607
475
  const admittedReposFor = (account) => asActor(account, () => managedRepos());
608
476
  const personalQueue = createPersonalQueueRuntime({
@@ -622,12 +490,10 @@ export function createDecisionServer(options) {
622
490
  return run !== null && family.versions.some(one => one.refId === run.taskRef);
623
491
  }),
624
492
  names: { project: projectName, modes: TASK_COMPOSER_MODES },
625
- // A queued message's partials are shaped as its final reply will be: for its words, with this console's own addresses.
626
493
  live: { begin: (thread, asked) => chatHandlers.beginLiveTurn(thread, { asked, appOrigin: [publicOrigin?.origin ?? null, options.configDir === undefined ? null : loadConsoleUrl(process.env, options.configDir)] }), end: (thread, ok, progress) => chatHandlers.endLiveTurn(thread, ok, progress) },
627
494
  ...(options.chatFetcher ? { fetcher: options.chatFetcher } : {}),
628
495
  ...(options.subscriptionChatRunner ? { subscriptionRunner: options.subscriptionChatRunner } : {}),
629
496
  });
630
- // Only browser sessions receive HTML cards. The CLI keeps its summary contract.
631
497
  const teamBrowserReply = (reply, actor, csrf) => {
632
498
  const snapshot = reply.snapshot;
633
499
  if (!snapshot?.selected || !snapshot.proposals)
@@ -640,9 +506,7 @@ export function createDecisionServer(options) {
640
506
  return { ...summary, card: teamProposalCardParts(store, actor, proposal, snapshot, csrf, decision, clock(), teamChatProvider).card };
641
507
  }) } };
642
508
  };
643
- // v112: one request budget per server for person API tokens, shared by every route a token signs in at (request-budget.ts).
644
509
  const requestBudget = new RequestBudget({ store, ...(options.requestBudgetClock === undefined ? {} : { clock: options.requestBudgetClock }) });
645
- // Unproved password attempts share a source budget. Only successful proof spends an account budget.
646
510
  const sourceClock = options.requestBudgetClock === undefined ? {} : { clock: options.requestBudgetClock };
647
511
  const passwordSourceBudget = new SourceAdmission({ perMinute: SOURCE_BUDGET_DEFAULTS.password, ...sourceClock });
648
512
  const passwordAccountBudget = new SourceAdmission({ perMinute: SOURCE_BUDGET_DEFAULTS.password, keyMode: "exact", ...sourceClock });
@@ -651,27 +515,19 @@ export function createDecisionServer(options) {
651
515
  const oauthTokenBudget = new SourceAdmission({ perMinute: SOURCE_BUDGET_DEFAULTS.oauthToken, ...sourceClock });
652
516
  const presentsPassword = (request) => /^Bearer (.+):(.+)$/.test(request.headers.authorization ?? "");
653
517
  const admitPasswordSource = (request) => presentsPassword(request) ? passwordSourceBudget.admit(joinSourceOf(request)) : { ok: true };
654
- /** Called only with a proved identity; cookies spend neither bearer budget. */
655
518
  const admitBearer = (request, actor) => {
656
519
  if (actor.principal !== undefined)
657
520
  return requestBudget.admit(actor.principal.tokenId, "api");
658
521
  return presentsPassword(request) ? passwordAccountBudget.admit(actor.name) : { ok: true };
659
522
  };
660
- /** Every project this person may pick in the console — the switcher, Projects, Settings, Tools and Flows read this
661
- * one list: the live admitted set (taskless projects included) and every project with saved work, each through
662
- * the ceiling and this account's project grants. A project removed or deleted here is gone from it. */
663
523
  const consoleProjects = () => {
664
524
  const gone = goneRepos();
665
525
  return [...new Set([...(admissionList() ?? []), ...managedRepos(), ...store.knownRepos()])].filter(one => visible(one) && !gone.has(one));
666
526
  };
667
527
  const server = createServer((request, response) => {
668
528
  instrumentRequest(store.telemetry, request, response);
669
- // Every password checked while answering counts against where this request came from (sign-in-guard.ts).
670
- // A GET or HEAD only reads (docs/plans/get-side-effects.md): store reads that would tidy up as they go don't.
671
529
  const answer = () => consoleFolders(options, identities, () => handle(request, response));
672
530
  void withPasswordSource(joinSourceOf(request), () => request.method === "GET" || request.method === "HEAD" ? asReadOnlyRequest(answer) : answer()).catch(error => {
673
- // Every unhandled error is logged (v99): the path and the message, never the request's body or query. The reference
674
- // is what a person's error page shows, so the log line can be found from it.
675
531
  const reference = `err_${randomBytes(4).toString("hex")}`;
676
532
  logEvent("error", "serve.error", { method: request.method, path: redactedPath(new URL(request.url ?? "/", "http://placeholder").pathname), error: error instanceof Error ? error.message : String(error), reference });
677
533
  if (envValue(process.env, "SERVE_DEBUG") === "1")
@@ -680,15 +536,13 @@ export function createDecisionServer(options) {
680
536
  const updating = error instanceof Error && error.message.includes(UPDATE_PAUSED);
681
537
  if (updating)
682
538
  response.setHeader("Retry-After", "5");
683
- // A browser asking for a page gets a page (Wave E): what happened, whether anything changed, the reference. It
684
- // holds no error text. Everything else keeps the plain answer.
685
539
  if (/\btext\/html\b/.test(String(request.headers.accept ?? "")) && (request.method === "GET" || request.method === "POST")) {
686
540
  const read = request.method === "GET";
687
541
  const at = new URL(request.url ?? "/", "http://placeholder");
688
542
  try {
689
543
  return page(response, updating ? 503 : 500, serverErrorPage({ updating, read, reference, at: new Date(), retry: read ? at.pathname + at.search : null }));
690
544
  }
691
- catch { /* the plain answer below */ }
545
+ catch { }
692
546
  }
693
547
  respond(response, updating ? 503 : 500, "text/plain; charset=utf-8", updating ? UPDATE_PAUSED : "something broke");
694
548
  }
@@ -699,9 +553,6 @@ export function createDecisionServer(options) {
699
553
  });
700
554
  server.once('listening', () => store.telemetry.start());
701
555
  server.once('close', () => store.telemetry.stop());
702
- // --public-url (arc 3): validated to EXACTLY an https origin. Its host
703
- // joins the allowed set, its origin authorizes POSTs, and cookies turn
704
- // Secure. Anything malformed refuses at startup, loudly.
705
556
  const publicOrigin = (() => {
706
557
  if (options.publicUrl === undefined)
707
558
  return null;
@@ -718,9 +569,7 @@ export function createDecisionServer(options) {
718
569
  return parsed;
719
570
  })();
720
571
  const cookieSecure = publicOrigin === null ? "" : "; Secure";
721
- /** Where Google may send someone back to (v89): the public https address, or this computer's own. */
722
572
  const consoleOrigin = (host) => host === undefined ? null : publicOrigin !== null && host === publicOrigin.host ? publicOrigin.origin : /^(localhost|127\.0\.0\.1|\[::1\]):[0-9]{1,5}$/.test(host) ? `http://${host}` : null;
723
- /** This computer's tailnet names, the last ones read (onboarding). */
724
573
  let tailnet = [];
725
574
  if (options.tailnetNames !== undefined) {
726
575
  const readTailnet = options.tailnetNames;
@@ -734,7 +583,7 @@ export function createDecisionServer(options) {
734
583
  const flushBudget = () => { try {
735
584
  requestBudget.flush();
736
585
  }
737
- catch { /* the next admit refuses if the database is unwell */ } };
586
+ catch { } };
738
587
  const timer = setInterval(flushBudget, REQUEST_BUDGET_FLUSH_MS);
739
588
  timer.unref?.();
740
589
  server.on("close", () => { clearInterval(timer); flushBudget(); });
@@ -743,7 +592,6 @@ export function createDecisionServer(options) {
743
592
  const address = server.address();
744
593
  return typeof address === "object" && address !== null ? address.port : null;
745
594
  };
746
- /** The names this server answers as. Anything else is a rebind, refused. */
747
595
  const allowedHost = (host) => {
748
596
  if (host === undefined)
749
597
  return false;
@@ -751,8 +599,6 @@ export function createDecisionServer(options) {
751
599
  const locals = port === null ? [] : [`localhost:${port}`, `127.0.0.1:${port}`, `[::1]:${port}`, ...tailnet.map(name => `${name}:${port}`)];
752
600
  return [...locals, ...(options.allowedHosts ?? []), ...(publicOrigin === null ? [] : [publicOrigin.host])].includes(host);
753
601
  };
754
- /** Easy-start C2: a protected loopback install (bound to loopback only, no --allow-host, no public URL, no tailnet
755
- * names) has one browser host, and there every browser mutation also presents the session's key (mutation-key.ts). */
756
602
  const browserKeys = createBrowserKeys({
757
603
  enabled: options.browserKey === true,
758
604
  epoch: keyEpoch,
@@ -765,7 +611,6 @@ export function createDecisionServer(options) {
765
611
  return address.address === "127.0.0.1" ? `127.0.0.1:${port}` : address.address === "::1" ? `[::1]:${port}` : null;
766
612
  },
767
613
  });
768
- /** The exact command that starts this console again as it runs now, plus a listening address or one more allowed host. */
769
614
  const consoleCommand = (change) => {
770
615
  const port = servedPort() ?? 4180;
771
616
  const address = server.address();
@@ -775,7 +620,6 @@ export function createDecisionServer(options) {
775
620
  return [`toolroll ${options.upConsole === true ? "up" : "serve"}`, ...(host === null ? [] : [`--host ${host}`]), ...(port === 4180 ? [] : [`--port ${port}`]),
776
621
  ...(allowed.length === 0 ? [] : [`--allow-host ${allowed.join(",")}`])].join(" ");
777
622
  };
778
- /** The wrong-host page's facts: the address opened, where the console answers, and the exact command that admits it. */
779
623
  const wrongHost = (host) => {
780
624
  const opened = host !== undefined && /^[A-Za-z0-9.-]{1,253}(:[0-9]{1,5})?$|^\[[0-9A-Fa-f:.]{2,45}\](:[0-9]{1,5})?$/.test(host) ? host : null;
781
625
  return { opened, served: `127.0.0.1:${servedPort() ?? 4180}`, command: opened === null ? null : consoleCommand({ allow: opened }) };
@@ -790,7 +634,6 @@ export function createDecisionServer(options) {
790
634
  approvalNonces.set(nonce, { name, taskId, digest, expiresAt: Date.now() + NONCE_TTL_MS });
791
635
  return nonce;
792
636
  }
793
- /** Single use, bound to who saw which digest of which task, and young. */
794
637
  function consumeApprovalNonce(nonce, name, taskId, digest) {
795
638
  const held = approvalNonces.get(nonce);
796
639
  if (held === undefined)
@@ -803,22 +646,13 @@ export function createDecisionServer(options) {
803
646
  }
804
647
  const hookContext = { store, clock, options };
805
648
  async function handle(request, response) {
806
- // Webhooks come through a public relay (Tailscale Funnel, a reverse
807
- // proxy) that forwards its own host name. The host check guards pages a
808
- // signed-in browser reads; a delivery carries no session and its answer
809
- // reveals nothing, so /hooks/ is answered before it, and only there.
810
649
  const hook = new URL(request.url ?? "/", "http://placeholder");
811
- // v99: a liveness probe for a load balancer or orchestrator. It answers before the host check (a probe
812
- // uses the address it reached), reads one row, and says nothing else about the installation.
813
650
  const method = request.method ?? "GET";
814
651
  const matchedRoute = matchRoute(method, hook.pathname);
815
- // Where a slow answer's time went (latency-timeline.ts): milestones by route id only, kept when it took a second.
816
652
  const timeline = new Timeline();
817
653
  timeline.mark("route matched");
818
654
  const edgeRoute = matchedRoute?.stage === 'edge' ? matchedRoute : null;
819
655
  const wrongMethodEdge = edgeRoute === null ? ROUTES.find(row => row.stage === 'edge' && new RegExp(row.pattern).test(hook.pathname)) ?? null : null;
820
- // D7: a password on a request still signs in this release, announced on every answer and named in every refusal;
821
- // from the release that removes it, it is refused here before anything checks it.
822
656
  if (isPasswordBearer(request.headers.authorization)) {
823
657
  if (!(options.passwordBearerAccepted ?? passwordBearerAccepted())) {
824
658
  request.resume();
@@ -835,9 +669,6 @@ export function createDecisionServer(options) {
835
669
  if (!allowedHost(request.headers.host)) {
836
670
  return respond(response, 421, "text/html; charset=utf-8", wrongHostPage(wrongHost(request.headers.host)));
837
671
  }
838
- // Easy-start C2: a protected loopback install has one browser origin, whose storage holds the session's mutation key.
839
- // A browser's page read at another loopback name (localhost, [::1]) moves there; machine callers and protocol
840
- // adapters (an API token, MCP's own addresses) are left where they are.
841
672
  const canonical = browserKeys.canonicalHost();
842
673
  if (canonical !== null && request.headers.host !== canonical && (method === "GET" || method === "HEAD") && request.headers.authorization === undefined
843
674
  && (edgeRoute === null || edgeRoute.domain === "people")) {
@@ -846,8 +677,6 @@ export function createDecisionServer(options) {
846
677
  response.end();
847
678
  return;
848
679
  }
849
- // A real domain (public-access.ts): HSTS for the public https host reached over HTTPS, and no API token over
850
- // plain HTTP from outside this computer and the tailnet — refused before anything reads or checks it.
851
680
  const transport = transportOf({ peer: request.socket.remoteAddress, joinSource: forwardedSourceOf(request), forwardedProto: request.headers["x-forwarded-proto"], forwarded: request.headers["forwarded"] });
852
681
  const hsts = hstsFor(publicOrigin?.host ?? null, request.headers.host, transport);
853
682
  if (hsts !== null)
@@ -858,31 +687,19 @@ export function createDecisionServer(options) {
858
687
  return respond(response, 403, "text/plain; charset=utf-8", insecure);
859
688
  }
860
689
  const url = new URL(request.url ?? "/", "http://placeholder");
861
- // A token in a URL is a token in history, logs, and referers. Refused
862
- // outright rather than ignored, so nobody learns the habit works.
863
690
  if (url.searchParams.has("token")) {
864
691
  return respond(response, 400, "text/plain; charset=utf-8", "credentials never travel in URLs");
865
692
  }
866
693
  if (edgeRoute === null && isEdgeAddress(url.pathname))
867
694
  return refuseEdge(request, response, url.pathname, wrongMethodEdge);
868
- // Live rooms share the browser identity/context below; their adapter carries token limits into each room.
869
695
  if (edgeRoute !== null && edgeRoute.domain !== 'people' && edgeRoute.domain !== 'live')
870
696
  return dispatchEdge(edgeRoute, { url, who: null, request, response, method });
871
- // Passive polls authenticate without extending the browser session.
872
697
  const fragmentName = url.searchParams.get("fragment");
873
698
  const workspaceRead = method === "GET" && url.searchParams.get('format') === 'workspace';
874
- // A workspace read's purpose (live-pages-and-home.md A1.4): bookkeeping only. Read on workspace GETs alone; on any other
875
- // request the header means nothing. No authorisation decision below reads it.
876
699
  const purpose = workspaceRead ? readPurpose(request.headers['x-toolroll-read']) : 'poll';
877
- // The reads that never extend the session, whatever their header says.
878
700
  const noTouch = edgeRoute?.domain === 'live' || (fragmentName !== null && NO_TOUCH_FRAGMENTS.has(fragmentName)) || /^\/code\/[a-f0-9]{32}\/state$/.test(url.pathname) || url.pathname === '/term/state'
879
- // The Agents view's Live grid only watches: its polls never extend or write the session.
880
701
  || url.pathname === '/agents/live' || /^\/agents\/live\/[0-9]{1,15}$/.test(url.pathname) || (url.pathname === '/agents' && url.searchParams.get('view') === 'live');
881
- // A followed link (`navigate`) extends the session exactly as the HTML GET of the same address would; every other
882
- // workspace read (a re-read, a prefetch) does not.
883
702
  const touch = !(method === "GET" && (noTouch || (workspaceRead && purpose !== 'navigate')));
884
- // A read ahead is answered only for a browser session, only for the prefetch allowlist (in-place.ts): anything else
885
- // hears 204 before any sign-in bookkeeping (a token's last use, a sign-in charge) is written.
886
703
  if (purpose === 'prefetch' && (request.headers.authorization !== undefined || !prefetchRoute(matchedRoute?.id, url))) {
887
704
  request.resume();
888
705
  return respond(response, 204, "text/plain; charset=utf-8", "");
@@ -896,15 +713,11 @@ export function createDecisionServer(options) {
896
713
  respond(response, admitted.status, "text/plain; charset=utf-8", admitted.status === 429 ? limitWords(admitted.limit, admitted.retryAfter) : "Request limits could not be checked; nothing ran. Try again shortly.");
897
714
  return true;
898
715
  };
899
- // One source charge before password proof and one account/token charge after it, including GET /login.
900
716
  if (refuseBudget(admitPasswordSource(request)))
901
717
  return;
902
718
  const refusedToken = {};
903
719
  const who = identify(request, touch, edgeRoute?.domain === 'live', refusedToken);
904
720
  timeline.mark("signed in");
905
- // Local-owner slice 0: a local owner's session presented from anywhere but this computer (another address, a
906
- // proxy, a tailnet or LAN name) signs in no one and changes nothing. Sign-in pages still answer (a password signs
907
- // in there); everything else is refused in plain words.
908
721
  if (refusedToken.elsewhere === true && edgeRoute?.domain !== 'people') {
909
722
  request.resume();
910
723
  response.setHeader("x-toolroll-refused", "local-owner-elsewhere");
@@ -920,7 +733,6 @@ export function createDecisionServer(options) {
920
733
  }
921
734
  if (who?.via === "bearer" && refuseBudget(admitBearer(request, who)))
922
735
  return;
923
- // A read ahead from anything but a signed-in browser session (signed out, a token): 204, never the sign-in page.
924
736
  if (purpose === 'prefetch' && who?.via !== 'cookie') {
925
737
  request.resume();
926
738
  return respond(response, 204, "text/plain; charset=utf-8", "");
@@ -930,11 +742,8 @@ export function createDecisionServer(options) {
930
742
  if (edgeRoute?.domain === 'people')
931
743
  return freshFacts.run(fresh, () => provenPasswordAccount.run(passwordProof, () => dispatchEdge(edgeRoute, { url, who, request, response, method })));
932
744
  if (who === null) {
933
- // A password on a request that did not sign in is a machine's refusal, never a login page.
934
745
  if (isPasswordBearer(request.headers.authorization))
935
746
  return respond(response, 401, "text/plain; charset=utf-8", "authenticate first");
936
- // A GET to an exact task or result (a phone's deep link) signs in and
937
- // comes back to it — the destination is a same-site path only.
938
747
  return method === "GET"
939
748
  ? redirect(response, loginHref(url.pathname + url.search))
940
749
  : respond(response, 401, "text/plain; charset=utf-8", "authenticate first");
@@ -946,15 +755,11 @@ export function createDecisionServer(options) {
946
755
  actor: who.name,
947
756
  csrf: who.via === "cookie" ? who.session.csrf : "",
948
757
  returnTo: safeReturn(url.pathname + url.search),
949
- // This console's own addresses: a lead reply's links there read as "the task", "the result", "Settings → Lead".
950
758
  appOrigins: [consoleOrigin(request.headers.host), publicOrigin?.origin ?? null, options.configDir === undefined ? null : loadConsoleUrl(process.env, options.configDir)],
951
- // Every signed-in page shares the workspace shell; pages showing a one-time secret opt out (forceSensitive).
952
759
  browser: who.via === 'cookie',
953
- // Passwordless (read once for rendering; every act proves it again at the act): ceremony fields render as nothing.
954
760
  passwordless: who.via === 'cookie' && passwordlessOn(store),
761
+ advanced: advancedShownFor(store, who.name),
955
762
  openProject: who.via === 'cookie' ? who.session.project : null,
956
- // v100: signed in with the identity provider: its label, and whether it checked them recently enough to stand in for a password.
957
- // Cockpit B2: "fresh" is an explicit re-check made on request and not yet spent (read live; one step-up uses it).
958
763
  sso: who.via === 'cookie' && who.session.sso !== undefined ? { label: ssoSettings()?.label ?? "your identity provider",
959
764
  get fresh() { return freshFacts.getStore() != null && ssoNowAvailable(who.name); } } : undefined,
960
765
  refusal: (answer, status, body) => sendScreen(answer, status, screen(status === 404 ? "Not found" : "Request refused", body, { chrome: chromeFor(who.via === "cookie" ? who.session.project : null, "work") })),
@@ -966,15 +771,11 @@ export function createDecisionServer(options) {
966
771
  ...(workspaceRead && typeof request.headers['if-none-match'] === 'string' ? { workspaceIfNoneMatch: request.headers['if-none-match'] } : {}),
967
772
  workspaceRequest: url.searchParams.get('request'),
968
773
  timeline,
969
- // Easy-start C2: every page that posts carries the key fill while the key is required; a session whose key is from
970
- // an earlier start (or has none) is told to reconnect.
971
774
  keyFill: browserKeys.required(),
972
- // Easy start: a local owner with no password sees "Set a password to do this." where a step-up field would be.
973
775
  ...(who.via === "cookie" && who.authority === "local-owner" && store.accountOf(who.name)?.passwordSet === false
974
776
  ? { localStepUp: localOwnerRefusal(false, method === "GET" ? passwordSetNext(pagePathOf(url)) : "/").href } : {}),
975
777
  reconnect: browserKeys.stale(who, method === "GET" ? safeReturn(pagePathOf(url)) : "/"),
976
778
  };
977
- // A read ahead writes nothing, not even a slow request's record.
978
779
  if (purpose !== 'prefetch')
979
780
  response.once("finish", () => keepSlowRequest(store, timeline, matchedRoute?.id ?? "unmatched", response.statusCode, clock()));
980
781
  if (method === "GET" || method === "POST")
@@ -984,16 +785,11 @@ export function createDecisionServer(options) {
984
785
  const body = method === "POST" ? await form(request, (matchedRoute?.stage === "console" ? matchedRoute.bodyCap : undefined) ?? BODY_CAP) : null;
985
786
  const target = actionTarget(url, who, request, body === null ? null : readForm(body, CONSOLE_FORMS.ledgerTarget));
986
787
  const execute = async () => {
987
- // THE ROUTE TABLE (server/route-table.ts): nothing reaches a handler unless a row declares this method and
988
- // path and admits this kind of caller. Undeclared addresses retain the legacy instance-access refusal
989
- // for project-limited accounts, before the unrestricted router's not-found response.
990
788
  const route = matchedRoute?.stage === "console" ? matchedRoute : null;
991
789
  if (route === null)
992
790
  return restricted()
993
791
  ? refuse(response, who, 403, "This area requires instance access. Your account operates within its assigned projects.", "/projects")
994
792
  : refuse(response, who, 404, "There's no page at this address.", "/chat");
995
- // Easy-start C1: a local owner's session reaches only the rows marked for it (route-table.ts `local`), decided
996
- // first, before the route's policy reads anything and before any handler runs, GET and POST alike.
997
793
  if (who.via === "cookie" && who.authority !== "full" && (route.local !== "allow" || localPrincipalOf(who, route) === null)) {
998
794
  request.resume();
999
795
  return refuseLocalOwner(response, who, method, url, request.headers.accept);
@@ -1005,8 +801,6 @@ export function createDecisionServer(options) {
1005
801
  request.resume();
1006
802
  if (method === "POST" && who.via === "bearer" && who.principal?.scope === "read")
1007
803
  return refuse(response, who, 403, REMOTE_MESSAGES.read);
1008
- // A viewer's act stays refused even when the table rejects their caller first (for example a
1009
- // password bearer at a step-up route). Preserve the viewer wording and explicit protocol refusals.
1010
804
  if (policy.reason === "scope" || (method === "POST" && who.role === "viewer" && !route.viewer && route.callerRefusal === undefined)) {
1011
805
  return refuse(response, who, 403, route.scopeRefusal ?? "your login can watch, not act — ask an approver to upgrade you");
1012
806
  }
@@ -1015,8 +809,6 @@ export function createDecisionServer(options) {
1015
809
  : respond(response, route.callerRefusal.status, route.callerRefusal.type, route.callerRefusal.body);
1016
810
  }
1017
811
  if (method === "GET") {
1018
- // Authorize every read before considering a conditional response.
1019
- // Task/result opening and receipt reconciliation always re-read work.
1020
812
  const facts = requestContext.getStore();
1021
813
  if (facts?.workspaceRead && who.via === 'cookie' && route.id === 'chat.page' &&
1022
814
  !url.searchParams.has('task') && !url.searchParams.has('result') && !url.searchParams.has('request')) {
@@ -1030,15 +822,11 @@ export function createDecisionServer(options) {
1030
822
  return respond(response, 304, 'application/json; charset=utf-8', '');
1031
823
  }
1032
824
  const expiresAt = workspaceRevision.expiresAt(now);
1033
- // A clock-bound refresh receives a different validator even when
1034
- // no database row changed (for example an expired worker lease).
1035
825
  facts.workspaceValidator = { key, revision, expiresAt,
1036
826
  etag: '"' + createHash('sha256').update(`${key}:${revision}:${expiresAt}`).digest('hex') + '"' };
1037
827
  }
1038
828
  await prefetchChrome(route, url, who);
1039
829
  timeline.mark("chrome and worker reads");
1040
- // The worker wait lets a sign-out, credential/access change or console ceiling change land. Prove the
1041
- // cookie and route again before rendering protected content or answering with a content validator.
1042
830
  if (who.via === 'cookie') {
1043
831
  const current = identify(request, false);
1044
832
  if (current?.via !== 'cookie' || current.session !== who.session)
@@ -1050,16 +838,12 @@ export function createDecisionServer(options) {
1050
838
  }
1051
839
  return handlePost(route, url, who, request, response, body);
1052
840
  };
1053
- // Easy-start C1: an allowed row runs as the local owner, in the act the row is (execute refuses every other): the
1054
- // prover answers "local-owner" only for that act, and every write it makes re-proves it still stands.
1055
841
  const local = who.via === "cookie" && who.authority !== "full" && matchedRoute?.stage === "console" && matchedRoute.local === "allow" ? localPrincipalOf(who, matchedRoute) : null;
1056
842
  if (local !== null)
1057
843
  response.once("close", () => { local.request.ended = true; });
1058
844
  const run = () => local === null ? execute() : asLocalOwner(local, execute);
1059
845
  if (method === "GET")
1060
846
  return projectAuthority.run({ actor: who.name, repo: target.repo }, run);
1061
- // Request acceptance is separate from durable work completion. Never
1062
- // persist a body, query string, token, password, or arbitrary URL.
1063
847
  const entry = { at: clock().toISOString(), actor: who.name, ...target, source: "request", ...(who.via === "bearer" && who.token !== undefined ? { detail: `API token: ${who.token}` } : {}) };
1064
848
  store.recordAction({ ...entry, outcome: "requested" });
1065
849
  try {
@@ -1083,7 +867,7 @@ export function createDecisionServer(options) {
1083
867
  try {
1084
868
  repo = coding.get(match[1], { name: who.name, generation: who.session.generation }).repo;
1085
869
  }
1086
- catch { /* The route refuses unknown/foreign sessions. */ }
870
+ catch { }
1087
871
  }
1088
872
  return { repo, taskId: null, runId: null, action: `coding ${body ? url.pathname.split('/').at(-1) : 'view'}` };
1089
873
  }
@@ -1134,9 +918,6 @@ export function createDecisionServer(options) {
1134
918
  if (project === undefined) {
1135
919
  return refuse(response, who, 403, "that project is outside what this server was configured to show");
1136
920
  }
1137
- // A project link is a read context, not a session-changing operation.
1138
- // Prove it against both admission and the known project catalog before
1139
- // collection queries; unknown/foreign paths reveal no work.
1140
921
  if ((route.id === 'tasks' || route.id === 'work' || route.id === 'system') && url.searchParams.has('project')) {
1141
922
  const wanted = url.searchParams.get('project') ?? '';
1142
923
  if (url.searchParams.getAll('project').length !== 1 || !visible(wanted) ||
@@ -1145,8 +926,6 @@ export function createDecisionServer(options) {
1145
926
  }
1146
927
  project = wanted;
1147
928
  }
1148
- // Home (UI revamp wave B) shows every project unless its address names one (proved the same way), and the rail's
1149
- // and the dock's Needs-you count follow that same one scope.
1150
929
  if (route.id === 'home') {
1151
930
  const wanted = url.searchParams.get('project');
1152
931
  if (wanted !== null && (url.searchParams.getAll('project').length !== 1 || !visible(wanted) ||
@@ -1155,19 +934,12 @@ export function createDecisionServer(options) {
1155
934
  }
1156
935
  project = wanted;
1157
936
  }
1158
- // All projects, asked for by name on Tasks (its project filter): the rolled-up list, admission-bound as ever.
1159
- // Tasks (P1.4) says every project as scope=all; an old link's all=1 still reads so.
1160
937
  if (route.id === 'tasks' && !url.searchParams.has('project') && ((url.searchParams.get('scope') === 'all' && url.searchParams.getAll('scope').length === 1)
1161
938
  || (url.searchParams.get('all') === '1' && url.searchParams.getAll('all').length === 1)))
1162
939
  project = null;
1163
- // Every page's Tasks count covers this one project view, whatever project the page itself shows.
1164
940
  const facts = requestContext.getStore();
1165
941
  if (facts !== undefined)
1166
942
  facts.lens = project;
1167
- // Exact result links carry their own read context. Check the stored
1168
- // placement against both account and instance access before using it;
1169
- // viewing a result never changes the session's selected project, and
1170
- // the page's project switch keeps showing the person's own choice.
1171
943
  const chosenProject = project;
1172
944
  if (route.id === "review" && url.searchParams.has("result")) {
1173
945
  const wanted = url.searchParams.get("result") ?? "";
@@ -1180,24 +952,6 @@ export function createDecisionServer(options) {
1180
952
  if (who.via === "cookie" && ref !== null && visible(ref.repo))
1181
953
  project = ref.repo;
1182
954
  }
1183
- // Nothing open and more than one thing to choose: land on the opener.
1184
- // Decisions and their evidence stay reachable — answering must never be
1185
- // blocked by project state — and the opener itself must not loop.
1186
- // A run's page and its evidence (workspace package 1): a bookmarked
1187
- // `/r/<id>` from All projects used to bounce to the opener until a
1188
- // project was chosen. The handler below re-proves the run's repo
1189
- // against the ceiling and the account (`runVisible`) before a byte
1190
- // renders, so letting the path through widens nothing.
1191
- // The chat's two read-only refresh routes (package 2 revision): the
1192
- // page itself is allowed from All projects, so its status poll and
1193
- // task fragment must be too — a 303 to the opener answered the poll
1194
- // with HTML and the page wrongly said the sign-in was lost. Each
1195
- // route keeps its own cookie, role, session, ceiling, and task
1196
- // admission checks. Shared action links likewise recheck the saved
1197
- // owner and project in their handler, so they stay reachable from All
1198
- // projects without changing the selected project or granting access.
1199
- // Which reads first need an open project is the route table's `needsProject` column; an exact result link
1200
- // and the all-projects board carry their own read context.
1201
955
  const needsProject = who.via === "cookie" && project === null && !unscopedMode &&
1202
956
  route.needsProject &&
1203
957
  !(route.id === "review" && url.searchParams.has("result")) &&
@@ -1206,32 +960,15 @@ export function createDecisionServer(options) {
1206
960
  return redirect(response, `/projects?return=${encodeURIComponent(safeReturn(url.pathname + url.search))}`);
1207
961
  return dispatchConsole(route, { url, who, request, response, route, now, project, chosenProject, posted: new URLSearchParams() });
1208
962
  }
1209
- /**
1210
- * The first run (adoption track, step 3): three plain steps derived from
1211
- * live state on every render, never a stored cursor, and retired
1212
- * PERMANENTLY by the first-success installation fact (Codex adoption
1213
- * review, finding 14). Each step is either something this console can do,
1214
- * or the exact command where only the CLI can (finding e).
1215
- */
1216
963
  function firstRunStepsNow(now) {
1217
964
  if (restricted() || store.isDemo() || store.firstSuccessAt(now) !== null)
1218
965
  return null;
1219
966
  return firstRunSteps({ agentSignedIn: agentSignedIn(now), projects: managedRepos().length, hasTask: store.hasAnyWork(), firstResultAt: null, signInCommand: agentSignInCommand() });
1220
967
  }
1221
- /**
1222
- * Whether a coding agent is signed in where the work runs. This machine's
1223
- * own checks (the ones Settings makes) speak only for a worker on this
1224
- * machine, or for the first one while none is registered yet (it is started
1225
- * here); a worker elsewhere speaks through its own readiness report, and
1226
- * the console never claims to have checked that machine (finding 15).
1227
- * Nothing here waits on a probe: this machine's answer is the last one
1228
- * seen, refreshed in the background, and null until the first one is in.
1229
- */
1230
968
  function agentSignedIn(now) {
1231
969
  const here = hostname();
1232
970
  const registered = store.listRunners().filter(one => one.retiredAt === null);
1233
971
  const workers = registered.filter(one => runnerAlive(one, now));
1234
- // This machine under any of its own names (machine-identity.ts): a hostname that moved with the network is still here.
1235
972
  if (workers.some(one => !sameMachineHost(one.host, here) && store.providerReadiness(one.name).some(seen => seen.state === "ready")))
1236
973
  return true;
1237
974
  return options.localRunner !== undefined || registered.length === 0 || workers.some(one => sameMachineHost(one.host, here)) ? localAgentSignedIn() : false;
@@ -1239,7 +976,6 @@ export function createDecisionServer(options) {
1239
976
  let localSignIn = null;
1240
977
  let localSignInChecking = null;
1241
978
  let leadRecheckedAt = 0;
1242
- /** Ask this computer's agent CLIs again (no model, nothing spent); `fresh` skips their 30-second cache. */
1243
979
  function checkLocalAgents(fresh = false) {
1244
980
  if (localSignInChecking !== null)
1245
981
  return localSignInChecking;
@@ -1247,22 +983,16 @@ export function createDecisionServer(options) {
1247
983
  .then(([claude, codex]) => {
1248
984
  localSignIn = { at: Date.now(), signedIn: [claude, codex].some(state => state === "connected" || state === "key-works" || state === "key-present"), states: { claude: claude, codex: codex } };
1249
985
  leadByDefault();
986
+ if (options.leadByDefault === true && !store.isDemo())
987
+ fillRoutingOnSignIn(store, localSignIn.states, clock());
1250
988
  })
1251
989
  .catch(() => { })
1252
990
  .finally(() => { localSignInChecking = null; });
1253
991
  return localSignInChecking;
1254
992
  }
1255
- /** The last answer only (docs/plans/get-side-effects.md): this computer is asked again by the background checks or a
1256
- * person's Check now, never because a page was opened. */
1257
993
  function localAgentSignedIn() {
1258
994
  return localSignIn?.signedIn ?? null;
1259
995
  }
1260
- /**
1261
- * The lead on by default (onboarding): with no lead set up yet, the agent CLI signed in on this computer runs it
1262
- * (Claude Code first, else Codex) on its membership with today's safe defaults: the CLI's own default model, 50 turns
1263
- * a day, no dollar spend, and every action it proposes still a card a person confirms. Once only, ever: a lead
1264
- * someone turned off stays off, and Settings → Lead changes it.
1265
- */
1266
996
  function leadByDefault() {
1267
997
  if (options.leadByDefault !== true || store.isDemo() || store.getChatConfig() !== null || store.installationFact(LEAD_BY_DEFAULT_FACT) !== null)
1268
998
  return;
@@ -1273,29 +1003,21 @@ export function createDecisionServer(options) {
1273
1003
  store.transact(() => {
1274
1004
  store.setChatConfig({ provider, model: "default", dailyTurns: 50, weeklyCeilingMicrousd: 0, priceInMicrousd: 0, priceOutMicrousd: 0 }, "toolroll", now);
1275
1005
  store.recordInstallationFact(LEAD_BY_DEFAULT_FACT, provider, now);
1276
- // A laptop install (local mode on): the agent chosen here also starts the models, on its default preset, while
1277
- // nothing is chosen yet, so the owner's first task plans without a password (model-choices.ts fillDefaultRouting).
1278
1006
  const agent = defaultAgentOf(provider);
1279
1007
  if (agent !== null && localModeOn(store))
1280
1008
  fillDefaultRouting(store, agent, "toolroll", { kind: "first-start" }, now);
1281
1009
  });
1282
1010
  }
1283
- // Look once at start, so the lead is on by the time the browser opens.
1284
1011
  if (options.leadByDefault === true && !store.isDemo() && store.getChatConfig() === null)
1285
1012
  void checkLocalAgents();
1286
- /** What the lead runs on, in words for one line ("your Claude Code sign-in"); null for a direct API or no lead. */
1287
1013
  function leadWords() {
1288
1014
  const config = store.getChatConfig();
1289
1015
  return config?.provider === "claude-subscription" ? "your Claude Code sign-in" : config?.provider === "codex-subscription" ? "your Codex sign-in" : null;
1290
1016
  }
1291
- /** The one command that gets an agent signed in here, for this operating system: sign in when its CLI is installed, else install Claude Code and sign in. */
1292
1017
  function agentSignInCommand() {
1293
1018
  return signInCommandFor(localSignIn?.states ?? null, options.platform ?? process.platform);
1294
1019
  }
1295
- /** First tasks per project: the last ones found (safe generic ones until then), re-read in the background at most
1296
- * every ten minutes. A render never waits on `gh` or `git grep`. */
1297
1020
  const firstTasks = new Map();
1298
- /** The phone setup itself (Settings → Chat apps): a chat app, or this console over Tailscale. */
1299
1021
  function phoneSetup(who) {
1300
1022
  if (who.role !== "approver" || store.isDemo())
1301
1023
  return undefined;
@@ -1310,49 +1032,27 @@ export function createDecisionServer(options) {
1310
1032
  dismissHref: "/onboarding/phone/dismiss",
1311
1033
  };
1312
1034
  }
1313
- // ---- fleet chat (v13) ----------------------------------------------------
1314
1035
  const chatFetcher = options.chatFetcher ?? fetch;
1315
1036
  const chatEnv = options.chatEnv ?? process.env;
1316
- /** The lead's last non-answer per BROWSER session (keyed by its csrf —
1317
- * never by name, so two browsers on one account do not read each other's
1318
- * notes), bound to the mate turn it came from so a note from a session
1319
- * that has since ended never shows; bounded; read once. */
1320
1037
  const leadSaid = new Map();
1321
- /** The unified conversation's rows for one reader (package 2): the SAME
1322
- * rows the page renders and the status poll's fragments re-render, so a
1323
- * live update can never show a card the page would not. A task lens
1324
- * keeps only that task's coordinator cards; the lead's own thread is one
1325
- * thread regardless of lens. */
1326
1038
  function leadConversationRows(who, principal, focusTask, now, chatProject = null) {
1327
1039
  const allCoordinatorRows = store.listCoordinatorProposals({ repos: managedRepos(), states: ["pending", "confirmed", "refused"], limit: 30 });
1328
1040
  const coordinatorProposals = focusTask !== null ? allCoordinatorRows.filter(one => focusTask.family.versions.some(version => version.id === one.payload["task"]))
1329
1041
  : chatProject !== null ? allCoordinatorRows.filter(one => one.repo === chatProject) : allCoordinatorRows;
1330
- // A visit only reads (quiet page visits): this opens no thread. The first message opens it (chatSend), and a
1331
- // live thread kept under another ceiling is what that message replaces, so it reads here as the earlier one.
1332
1042
  const found = store.liveLeadThreadFor(who.name, chatScopeOf(focusTask, chatProject));
1333
1043
  const thread = found !== null && found.ceilingDigest === principal.ceilingDigest ? found : null;
1334
1044
  const proposals = thread === null ? [] : store.listLeadProposals(thread.id);
1335
- // One reply runs at a time per person; this thread shows it only when
1336
- // the reply is its own.
1337
1045
  const live = store.liveLeadTurnFor(who.name);
1338
1046
  const messages = thread === null ? [] : store.listLeadMessages(thread.id, 40);
1339
- // The lead's question with buttons, while its reply is the last word in the thread.
1340
1047
  const last = messages.at(-1);
1341
1048
  const asking = last?.role === "assistant" && last.turn !== null && store.getLeadTurn(last.turn)?.approver === who.name ? store.leadAskOpen(last.turn, now) : null;
1342
- // A question about this task loses its buttons once the version shown moved after it was asked (its plan
1343
- // rewritten or approved, a new attempt started): its options answered a state that is gone. Its words stay, marked so.
1344
1049
  const staleAsk = asking !== null && focusTask !== null && taskMovedSince(store, focusTask.executionId, asking.createdAt) ? asking.turn : null;
1345
1050
  const ask = staleAsk === null ? asking : null;
1346
- // Answered questions stay readable above the answer; only their buttons go.
1347
1051
  const asks = new Map(messages.flatMap(one => { const asked = one.role === "assistant" && one.turn !== null ? store.leadAsk(one.turn) : null; return asked === null ? [] : [[asked.turn, asked]]; }));
1348
- // The person's queued messages in this thread: each shows waiting (with Remove) or why it was not sent.
1349
1052
  const queue = new Map(thread === null ? [] : personalQueue.queue.forThread(thread.id).map(row => [row.message, row]));
1350
- // The thread a ceiling change replaced (ruling 9), display only: closed already, or still live under the old ceiling.
1351
1053
  const replaced = thread !== null ? store.replacedLeadThread(thread)
1352
1054
  : found !== null && found.scope.kind === "lead" && store.listLeadMessages(found.id, 1).length > 0 ? found : null;
1353
1055
  const previousProposals = replaced === null ? [] : store.listLeadProposals(replaced.id);
1354
- // How this thread's last reply ended, read from its saved turn (never process memory, which a restart loses): a
1355
- // failed turn that saved no message of its own says why in the thread, until the next reply starts.
1356
1056
  const lastTurn = thread === null ? null : latestLeadTurnOfThread(store, thread.id);
1357
1057
  const failure = lastTurn !== null && lastTurn.state === "failed" && !messages.some(one => one.role === "assistant" && one.turn === lastTurn.id)
1358
1058
  ? leadFailureText(lastTurn.failureReason, store.leadTurnCostUnconfirmed(lastTurn.id), lastTurn.failureDetail ?? null) : null;
@@ -1371,18 +1071,10 @@ export function createDecisionServer(options) {
1371
1071
  recent: store.recentLeadTurns(who.name, 5),
1372
1072
  };
1373
1073
  }
1374
- /** The thread a chat surface speaks in (v77): the task's own thread, the
1375
- * project's, or the lead conversation across every project. */
1376
1074
  function chatScopeOf(focusTask, chatProject) {
1377
1075
  return focusTask !== null ? { kind: "task", key: focusTask.id } : chatProject !== null ? { kind: "project", key: chatProject } : LEAD_THREAD;
1378
1076
  }
1379
1077
  const liveTurns = new Map();
1380
- /** The Ask panel (v77): the conversation a task, result or project page
1381
- * docks beside itself — that page's own thread, the same session and
1382
- * cards as /chat. Null when this person has no lead chat here. A page
1383
- * view starts nothing (quiet page visits): with no membership
1384
- * conversation yet, the panel binds its sends to NOT_STARTED_SESSION and
1385
- * the first message starts one (chatSend). */
1386
1078
  function dockedConversation(who, focusTask, chatProject, now, back, resultRunId = null) {
1387
1079
  if (who.via !== "cookie" || who.role !== "approver" || (focusTask === null && chatProject === null))
1388
1080
  return null;
@@ -1403,21 +1095,13 @@ export function createDecisionServer(options) {
1403
1095
  taskId: focusTask?.id ?? null, resultRunId, project: focusTask === null ? chatProject : null, failure: rows.pending === null ? rows.failure : null,
1404
1096
  };
1405
1097
  }
1406
- /** The session-layer principal (ruling 3): cookie, csrf, and role were
1407
- * proved at the edge; the row and the generation are re-proved here. */
1408
- /** Start the person's lead conversation: the session every later turn
1409
- * debits (a membership spends nothing; direct API gets a per-conversation
1410
- * ceiling) and its thread. Starting ends any older session. */
1411
1098
  function startLeadConversation(who, principal, enabled, ceilingUsd, follow, now, scope = LEAD_THREAD, request) {
1412
- // A page's first send (quiet page visits) starts it under that send's request: the start and its record are one
1413
- // write, so a retry of the same request finds the conversation it started and never starts another.
1414
1099
  if (request !== undefined) {
1415
1100
  return store.transact(() => store.replay({ idempotencyKey: `mate-start:${who.name}:${request}`, actor: who.name, at: now }, "mate-start", () => ({ session: startLeadConversation(who, principal, enabled, ceilingUsd, follow, now, scope) })).session);
1416
1101
  }
1417
1102
  const ceilingMicrousd = enabled.billing === "subscription" ? 0 : Math.round(ceilingUsd * 1_000_000);
1418
1103
  const termsDigest = createHash("sha256").update(`${ceilingMicrousd}\n${principal.ceilingDigest}`).digest("hex");
1419
1104
  const sessionId = store.mintLeadSession({ approver: who.name, approverGeneration: principal.generation, credentialKey: enabled.credentialKey, ceilingMicrousd, ceilingDigest: principal.ceilingDigest, termsDigest }, now);
1420
- // The thread the first message goes to (quiet page visits: a task's first message opens only the task's thread).
1421
1105
  const thread = store.openLeadThread(who.name, principal.ceilingDigest, now, scope).thread;
1422
1106
  if (follow)
1423
1107
  configureLeadFollow(store, principal, store.getLeadSession(sessionId), thread, true, now);
@@ -1430,15 +1114,10 @@ export function createDecisionServer(options) {
1430
1114
  }
1431
1115
  const CHAT_CANDIDATES_PER_APPROVER = 9;
1432
1116
  const CHAT_CANDIDATE_TTL_MS = 30 * 60_000;
1433
- /** The frozen explicit repo list, digested canonically (sorted) — every
1434
- * candidate binds to it and filing re-proves it (v2 new finding 5). */
1435
1117
  const chatCeilingDigest = (repos = managedRepos()) => createHash("sha256").update([...repos].sort().join("\n")).digest("hex");
1436
- /** The scripted lead answers only inside a demo database. */
1437
1118
  function demoLeadHere() {
1438
1119
  return options.demoLead !== undefined && store.isDemo() ? options.demoLead : null;
1439
1120
  }
1440
- /** Every condition re-proved per request — the render and the POST each
1441
- * ask again; nothing is cached into authority. */
1442
1121
  function chatEnablement() {
1443
1122
  if (store.isDemo())
1444
1123
  return { ok: false, code: "demo", why: "this is a demo database — chat cannot contact an external model" };
@@ -1471,13 +1150,6 @@ export function createDecisionServer(options) {
1471
1150
  return { ok: false, code: "no-key", why: `no ${config.provider} key — paste one below (stored 0600 beside the database, never in it), or export ${CHAT_KEY_ENV[config.provider]} in the serve environment` };
1472
1151
  return { ok: true, billing: "metered", config: config, key: key.key, keySource: key.source, price, credentialKey: credentialKeyOf(config.provider, key.key) };
1473
1152
  }
1474
- /**
1475
- * Where a chat key comes from, in priority order: the serve process
1476
- * environment, then the 0600 key file under the config directory (the
1477
- * Telegram bot-token precedent — settable from the console, never the
1478
- * database, never echoed whole). The file exists so onboarding lives
1479
- * in the UI; the environment exists so operators who prefer it keep it.
1480
- */
1481
1153
  function chatKeyFor(provider) {
1482
1154
  const fromEnv = chatEnv[CHAT_KEY_ENV[provider]];
1483
1155
  if (fromEnv !== undefined && fromEnv !== "")
@@ -1492,13 +1164,7 @@ export function createDecisionServer(options) {
1492
1164
  return null;
1493
1165
  }
1494
1166
  }
1495
- /** OpenRouter's live catalog, cached briefly: every selectable model
1496
- * arrives WITH the price the config will pin (operator request — the
1497
- * whole catalog, not a hand-pinned shortlist). null = no key or the
1498
- * catalog is unreachable; callers fall back to the compiled table. */
1499
1167
  let catalogCache = null;
1500
- /** The catalog as last fetched, for a page to show (docs/plans/get-side-effects.md): a page never fetches it. The
1501
- * background checks keep it current while an OpenRouter key is saved; saving a choice fetches it (chatCatalog). */
1502
1168
  function chatCatalogKnown() {
1503
1169
  return chatKeyFor("openrouter-api") === null ? null : catalogCache?.models ?? null;
1504
1170
  }
@@ -1524,11 +1190,6 @@ export function createDecisionServer(options) {
1524
1190
  clearTimeout(timer);
1525
1191
  }
1526
1192
  }
1527
- /**
1528
- * The palette's server-rendered index (attended review, finding 4): a
1529
- * non-executable JSON block on an already-authorized page — the same
1530
- * titles the page itself may render, bounded, saturation declared.
1531
- */
1532
1193
  function paletteIndexTag(project) {
1533
1194
  const admitted = project === null ? admissionList() : null;
1534
1195
  const entries = [
@@ -1558,15 +1219,6 @@ export function createDecisionServer(options) {
1558
1219
  const safeEntries = restricted() ? entries.filter(one => ["/tasks", "/tasks?view=needs-you", "/", "/tasks?view=board", "/flows", "/tasks?view=done", "/tasks?view=ready", "/runs", "/projects", "/ledger"].includes(one.href) || one.href.startsWith("/t/")) : entries;
1559
1220
  return jsonScript(saturated ? [...safeEntries, { label: "… more in Tasks", href: "/tasks" }] : safeEntries, { id: "palette-index" });
1560
1221
  }
1561
- /**
1562
- * The palette cache (arc 4, finding 6), and its honest contract: a
1563
- * render may be up to five seconds stale after OUT-OF-PROCESS changes;
1564
- * an accepted in-process mutation invalidates immediately (bustBadge),
1565
- * so "one query per five seconds" holds only between invalidations;
1566
- * and an OPEN page keeps its navigation-time snapshot until the next
1567
- * navigation — no refresh mechanism exists or is promised. The key
1568
- * carries the one configuration bit the entries vary by.
1569
- */
1570
1222
  const paletteCache = new Map();
1571
1223
  function paletteTagCached(project) {
1572
1224
  const actor = requestContext.getStore()?.actor;
@@ -1578,44 +1230,26 @@ export function createDecisionServer(options) {
1578
1230
  paletteCache.set(key, { at: Date.now(), tag });
1579
1231
  return tag;
1580
1232
  }
1581
- /**
1582
- * Every chromed HTML response leaves through here (arc 4, findings
1583
- * 5/18): one place owns the sensitivity call, the nonce, the palette
1584
- * index, the shortcuts overlay, script composition, and the CSP —
1585
- * at most one nonce-bearing script per response, connect-src only when
1586
- * that script fetches. The named exception: /fleet and /settings keep
1587
- * their FUNCTIONAL scripts beside credential fields (a poller and the
1588
- * push enrollment — neither reads the fields); the chrome additions
1589
- * are what sensitivity strips.
1590
- */
1591
1233
  function sendScreen(response, status, s) {
1592
1234
  requestContext.getStore()?.timeline?.mark("handler done; rendering");
1593
- // Sensitivity is the page as authored (cockpit §2, R14): its own explicit word, else a password field it was written
1594
- // with — judged before an identity-provider sign-in replaces that field, so an SSO step-up page stays sensitive.
1595
1235
  const authored = s.sensitive ?? (s.forceSensitive === true ||
1596
1236
  SENSITIVE_INPUT.test(htmlString(s.body)) ||
1597
1237
  (s.workspace?.pageHtml != null && SENSITIVE_INPUT.test(htmlString(s.workspace.pageHtml))) ||
1598
1238
  (s.chrome?.listPane !== undefined && SENSITIVE_INPUT.test(htmlString(s.chrome.listPane))));
1599
- // v100: signed in with the identity provider, a step-up's password field is that sign-in instead.
1600
1239
  const ssoFacts = requestContext.getStore()?.sso;
1601
1240
  if (ssoFacts !== undefined) {
1602
1241
  const back = requestContext.getStore()?.returnTo ?? "/";
1603
- // A typed-only proof (settings-kit.ts) stays a password field: its handler takes nothing else.
1604
1242
  s = { ...s, body: keepTypedFields(s.body, ssoStepUps, ssoFacts, back), ...(s.workspace?.pageHtml == null ? {} : { workspace: { ...s.workspace, pageHtml: keepTypedFields(s.workspace.pageHtml, ssoStepUps, ssoFacts, back) } }) };
1605
1243
  if (s.workspace?.view?.kind === "flow")
1606
1244
  s = { ...s, workspace: { ...s.workspace, view: { ...s.workspace.view, stepUp: { label: ssoFacts.label, fresh: ssoFacts.fresh, confirmHref: `/login/sso?reauth=1&return=${encodeURIComponent(back)}` } } } };
1607
1245
  }
1608
- // Easy start: a local owner with no password has none to type: each step-up field says how to set one instead.
1609
1246
  const localStepUp = requestContext.getStore()?.localStepUp;
1610
1247
  if (localStepUp !== undefined) {
1611
1248
  s = { ...s, body: localOwnerStepUps(s.body, localStepUp), ...(s.workspace?.pageHtml == null ? {} : { workspace: { ...s.workspace, pageHtml: localOwnerStepUps(s.workspace.pageHtml, localStepUp) } }) };
1612
1249
  }
1613
- // D5: team chat (the central team service) is deprecated; /chat?team=1 still opens this release, but nothing links to it.
1614
1250
  const sensitive = authored || s.forceSensitive === true;
1615
1251
  const requestFacts = requestContext.getStore();
1616
- // Easy-start C2: while the browser mutation key is required, every page's one nonce'd script also fills the key.
1617
1252
  const keyFill = requestFacts?.keyFill === true ? KEY_FILL_SCRIPT : "";
1618
- // The settings frame (settings-kit.ts): its breadcrumb, for the shell and the workspace alike.
1619
1253
  if (s.chrome !== undefined && s.chrome.crumbs === undefined) {
1620
1254
  const crumbs = settingsCrumbs(new URL(requestFacts?.returnTo ?? '/', 'http://standing-orders.local').pathname, s.title, htmlString(s.body));
1621
1255
  if (crumbs !== undefined)
@@ -1627,8 +1261,6 @@ export function createDecisionServer(options) {
1627
1261
  path.searchParams.delete('request');
1628
1262
  const currentPath = path.pathname + path.search;
1629
1263
  path.searchParams.set('format', 'workspace');
1630
- // The legacy list pane (every task or build as links) duplicates the
1631
- // Crew panel and Tasks page; inside the workspace the page stands alone.
1632
1264
  const pageHtml = htmlString(s.body);
1633
1265
  const extras = s.workspace ?? {};
1634
1266
  const notices = [...(extras.notices ?? [])];
@@ -1642,7 +1274,6 @@ export function createDecisionServer(options) {
1642
1274
  try {
1643
1275
  const project = s.chrome.active === 'chat' ? null : s.chrome.project;
1644
1276
  crew = extras.team?.tasks ? browserCrewFromIndex(extras.team.tasks, extras.team.selected?.id) : requestFacts.workCrew?.project === project ? browserCrewFromIndex(requestFacts.workCrew.page)
1645
- // The reader's own lead's claims read "<name> is on it" here too.
1646
1277
  : (() => {
1647
1278
  const access = { principal: 'operator', repos: managedRepos(), includeUnplaced: false, viewer: requestFacts.actor ?? null };
1648
1279
  return chromeRead(`crew\u0000${accessKey(access)}\u0000${project ?? ''}`, () => browserCrewOf(store, clock(), access, { evidenceRoot, project }));
@@ -1651,7 +1282,6 @@ export function createDecisionServer(options) {
1651
1282
  catch {
1652
1283
  notices.push('Crew updates are unavailable. Open Tasks to inspect saved work.');
1653
1284
  }
1654
- // A running row says what its agent did last, and when (the task page's own line).
1655
1285
  try {
1656
1286
  const now = clock(), live = new Map();
1657
1287
  if (crew.crew.length > 0)
@@ -1663,14 +1293,9 @@ export function createDecisionServer(options) {
1663
1293
  if (live.size > 0)
1664
1294
  crew = { ...crew, crew: crew.crew.map(item => { const activity = live.get(item.id); return activity === undefined ? item : { ...item, activity }; }) };
1665
1295
  }
1666
- catch { /* the rows keep their status; the line returns on the next read */ }
1667
- // "Wake me only for these": the navigation carries the sidebar's own
1668
- // Tasks count (chromeFor) and links to the project view it covers, so
1669
- // it matches that page's Needs you tab on every screen.
1296
+ catch { }
1670
1297
  const needsYou = s.chrome.inboxCount;
1671
1298
  const tasksProject = s.chrome.inboxProject === undefined ? s.chrome.project : s.chrome.inboxProject;
1672
- // The person's own project and task conversations (v77), for the
1673
- // sidebar's chat list; a thread whose project is out of view is left out.
1674
1299
  let chats = [];
1675
1300
  try {
1676
1301
  const actor = requestFacts.actor ?? '';
@@ -1693,31 +1318,18 @@ export function createDecisionServer(options) {
1693
1318
  }
1694
1319
  const conversation = extras.conversation ?? null;
1695
1320
  const request = requestFacts.workspaceRequest;
1696
- // React owns the conversation and its refresh/draft lifecycle. Native
1697
- // guarded forms keep their current behavior after React inserts them.
1698
- // A page with its own view keeps its script; the chat page runs the result script.
1699
- // The exact page script the document would run: the JSON arm and the document arm read this one value.
1700
1321
  const ownScript = conversation === null || extras.view;
1701
1322
  const pageScript = ownScript ? (s.functional?.script ?? '') : RESULT_REVIEW_SCRIPT;
1702
1323
  const routeInPlace = inPlaceRoute(requestFacts.routeId, path);
1703
- // The app runs the page's behaviour itself (docs/plans/task-page-in-app.md §2) only when all of these hold: the
1704
- // app covers the WHOLE script, no password field (a password page keeps its string path), an in-place route, and a
1705
- // reader that can run it: a document load (its bundle is this server's, served no-store) or a workspace read that
1706
- // says so. Anything else is the page exactly as before: the string, no work, a document.
1707
1324
  const covered = ownScript ? s.functional?.app : undefined;
1708
1325
  const work = pageScript !== '' && covered !== undefined && covered.length > 0 && !sensitive && routeInPlace
1709
1326
  && (!requestFacts.workspaceRead || requestFacts.appWork === true) ? covered : null;
1710
1327
  const functional = work === null ? pageScript : '';
1711
- // May replace another page without a document load (live-pages-and-home.md A1.1): an allowlisted route, no password
1712
- // field, no page script (a page script runs once per document, so its page always loads as one).
1713
1328
  const inPlace = routeInPlace && !sensitive && functional === '';
1714
1329
  const workspace = {
1715
1330
  version: 1, path: currentPath, title: s.title, user: requestFacts.actor ?? '', csrf: requestFacts.csrf, sensitive, inPlace,
1716
1331
  ...(work === null ? {} : { work }),
1717
- // Said on the document that ships it: this document's page script listens for as long as the document lives.
1718
1332
  ...(functional !== '' && !requestFacts.workspaceRead ? { scripted: true } : {}),
1719
- // The project picker names the open project; the settings frame carries its breadcrumb.
1720
- // Only a project this person may see now: never the raw saved path (settings-kit.ts openProjectFor).
1721
1333
  openProject: openProjectFor(requestFacts.openProject ?? null, s.chrome.project, s.chrome.projects ?? []),
1722
1334
  ...(s.chrome.crumbs === undefined ? {} : { crumbs: s.chrome.crumbs }),
1723
1335
  ...(requestFacts.passwordless === true ? { passwordless: true } : {}),
@@ -1726,7 +1338,6 @@ export function createDecisionServer(options) {
1726
1338
  receipt: conversation !== null && request && REQUEST_TOKEN.test(request)
1727
1339
  ? { request, received: store.leadRequestReceived(conversation.sessionId, request) } : null,
1728
1340
  projects: browserProjectsOf(s.chrome.projects ?? []), ...crew,
1729
- // The sidebar's project states: never on a sensitive page (no rail, no summary stream there).
1730
1341
  ...(() => { if (sensitive)
1731
1342
  return {}; try {
1732
1343
  return { projectStates: projectSummary() };
@@ -1734,7 +1345,6 @@ export function createDecisionServer(options) {
1734
1345
  catch {
1735
1346
  return {};
1736
1347
  } })(),
1737
- // Cockpit B2: the remembered password's chip, only where it could be used (a direct local request).
1738
1348
  ...(() => {
1739
1349
  const facts = freshFacts.getStore();
1740
1350
  if (sensitive || facts == null || !facts.local || !facts.live())
@@ -1745,10 +1355,9 @@ export function createDecisionServer(options) {
1745
1355
  const left = FRESH_WINDOW_MS - (Date.now() - at);
1746
1356
  return left <= 0 ? {} : { fresh: { minutes: Math.max(1, Math.ceil(left / 60_000)), forget: '/session/forget-password' } };
1747
1357
  })(),
1748
- // The usage chip: the Limits view's own audience (an operator on a browser session), never a sensitive page.
1749
1358
  ...(() => {
1750
1359
  const actor = requestFacts.actor;
1751
- if (sensitive || !actor || requestFacts.csrf === '' || !store.isInstanceOperator(actor))
1360
+ if (sensitive || !actor || requestFacts.csrf === '' || requestFacts.advanced === false || !store.isInstanceOperator(actor))
1752
1361
  return {};
1753
1362
  try {
1754
1363
  const usage = usageChipOf(store.providerLimits(), clock());
@@ -1762,15 +1371,12 @@ export function createDecisionServer(options) {
1762
1371
  catchUpHtml: extras.catchUpHtml === undefined ? '' : htmlString(extras.catchUpHtml), controlsHtml: extras.controlsHtml === undefined ? '' : htmlString(extras.controlsHtml), notices, view: extras.view ?? null,
1763
1372
  ...(s.chrome.demo ? { demo: { text: DEMO_BANNER, short: DEMO_BANNER_SHORT } } : {}),
1764
1373
  pageHtml: extras.pageHtml === undefined ? (conversation === null ? pageHtml : null) : extras.pageHtml === null ? null : htmlString(extras.pageHtml),
1765
- navigation: browserNavigationOf(currentPath, s.chrome.project, needsYou, tasksProject, s.chrome.inboxLabel),
1766
- // The one Needs-you count (tasks only), with the scope it covers: the Tasks list's own count for this project
1767
- // view (or every project), so the rail, the phone header and Home all read the same number.
1374
+ navigation: browserNavigationOf(currentPath, s.chrome.project, needsYou, tasksProject, s.chrome.inboxLabel, requestFacts.advanced !== false),
1375
+ ...(requestFacts.advanced === false ? { advanced: false } : {}),
1768
1376
  needsYou: { count: needsYou, saturated: s.chrome.inboxSaturated === true, scope: tasksProject ?? null,
1769
1377
  label: s.chrome.inboxLabel ?? `${needsYou} ${needsYou === 1 ? 'needs' : 'need'} you`,
1770
- // Every project, said by name (all=1), so a session's own open project never narrows the list the count opens.
1771
1378
  href: tasksProject === null ? '/tasks?scope=all&view=needs-you' : `/tasks?project=${encodeURIComponent(tasksProject)}&view=needs-you` },
1772
1379
  chats,
1773
- // The same count per project (the rail's project rows), read from the same work index totals.
1774
1380
  ...(() => { if (sensitive)
1775
1381
  return {}; try {
1776
1382
  return { needsYouByProject: projectCounts(clock()).map(one => ({ path: one.repo, count: one.totals['needs-you'] })) };
@@ -1784,7 +1390,6 @@ export function createDecisionServer(options) {
1784
1390
  ...(extras.firstRun === undefined ? {} : { firstRun: extras.firstRun }),
1785
1391
  ...(extras.phone === undefined ? {} : { phone: extras.phone }),
1786
1392
  ...(extras.home == null ? {} : { home: extras.home }),
1787
- // Easy-start C2: this tab's key is from an earlier start (or it has none): one way to reconnect.
1788
1393
  ...(requestFacts.reconnect == null ? {} : { reconnect: requestFacts.reconnect }),
1789
1394
  };
1790
1395
  if (requestFacts.workspaceRead) {
@@ -1794,9 +1399,6 @@ export function createDecisionServer(options) {
1794
1399
  response.setHeader('ETag', validator.etag);
1795
1400
  }
1796
1401
  const body = JSON.stringify(workspace);
1797
- // Every other page's re-read after a live `change` (chat keeps its own validator, and its receipt, task and
1798
- // result reads none): when what it renders now is exactly what the page holds, it hears 304 and keeps its view
1799
- // (no transfer, no re-render).
1800
1402
  if (status === 200 && validator === undefined && path.pathname !== '/chat') {
1801
1403
  const etag = '"w' + createHash('sha256').update(body).digest('base64url') + '"';
1802
1404
  response.setHeader('ETag', etag);
@@ -1807,14 +1409,8 @@ export function createDecisionServer(options) {
1807
1409
  }
1808
1410
  const nonce = randomBytes(16).toString('base64');
1809
1411
  const document = shell(s.title, s.body, { chrome: s.chrome, sensitive });
1810
- // The keys and their list (keymap.ts) work here as on every chromed page; the list sits beside the app React owns.
1811
- // A sensitive page keeps to its own script.
1812
1412
  return page(response, status, browserWorkspaceDocument(document, workspace, nonce, functional + MOBILE_VIEWPORT_SCRIPT + keyFill + (sensitive ? '' : chromeScript()), sensitive ? html `` : KBD_HELP), nonce, true);
1813
1413
  }
1814
- // A one-time secret on screen (a token, an invite link, a pairing code): the
1815
- // page carries no script of any kind, so it leaves the workspace for a
1816
- // focused page in the same look: the brand, the one card, and the way back.
1817
- // Easy-start C2: but for the key fill when it has a form that posts (the fill reads nothing on the page).
1818
1414
  if (s.forceSensitive === true) {
1819
1415
  if (keyFill === "" || !/<form\b[^>]*method="post"/i.test(htmlString(s.body)))
1820
1416
  return page(response, status, focusDocument(s.title, s.body));
@@ -1823,10 +1419,7 @@ export function createDecisionServer(options) {
1823
1419
  }
1824
1420
  const chromeLayer = !sensitive && s.chrome !== undefined;
1825
1421
  const functional = s.functional?.script ?? "";
1826
- // Sensitive pages strip the palette and keys but keep the sidebar toggle.
1827
1422
  const sensitiveChrome = sensitive && s.chrome !== undefined ? sidebarScript() : "";
1828
- // Kit markup the workspace bundle would have wired (a composer, an overlay, a switch, an idea) gets the kit's own small
1829
- // behaviour here (kit-standalone.ts); never on a sensitive page, which carries no chrome additions.
1830
1423
  const kitBehavior = chromeLayer && KIT_BEHAVIOR_MARKUP.test(htmlString(s.body)) ? KIT_STANDALONE_SCRIPT : "";
1831
1424
  const script = functional + (chromeLayer ? chromeScript() + WORKSPACE_MOTION_SCRIPT + kitBehavior : sensitiveChrome) + keyFill;
1832
1425
  const nonce = script === "" ? undefined : randomBytes(16).toString("base64");
@@ -1840,23 +1433,14 @@ export function createDecisionServer(options) {
1840
1433
  ...(s.refreshSeconds === undefined ? {} : { refreshSeconds: s.refreshSeconds }),
1841
1434
  ...(nonce === undefined ? {} : { live: { nonce, script, fallbackRefresh: s.functional?.fetches === true } }),
1842
1435
  });
1843
- // Pages that ship the chrome layer keep connect-src (v28 granted it for
1844
- // the since-removed watched-session beat), beside pages whose own
1845
- // functional script polls.
1846
1436
  return page(response, status, document, nonce, s.functional?.fetches === true || chromeLayer || sensitiveChrome !== "");
1847
1437
  }
1848
- /** The needs-you count every surface wears, read from this request's own
1849
- * Work counts (one read per request, kept only while the workspace revision
1850
- * it was read at stands), so a live page's badge and its Needs you tab
1851
- * always agree. */
1852
1438
  function needsYouBadge(project) {
1853
1439
  return needsYouCount(project);
1854
1440
  }
1855
1441
  const bustBadge = () => {
1856
1442
  paletteCache.clear();
1857
1443
  };
1858
- /** Enrolled projects first (most recently opened), then the repos this server was told to serve that nobody has
1859
- * opened yet — the switcher lists every project it is allowed to show, each exactly once. */
1860
1444
  function sidebarProjects() {
1861
1445
  const seen = new Set();
1862
1446
  const rows = [];
@@ -1871,33 +1455,21 @@ export function createDecisionServer(options) {
1871
1455
  }
1872
1456
  return rows;
1873
1457
  }
1874
- /** The sidebar's projects with their states (agent-state.ts), for the request's own reader: the page's first read
1875
- * and the summary room's snapshots are this one function, so the two never disagree. Never marks anything seen.
1876
- * Work with no project yet is its own entry when this reader may see it and something counts there. */
1877
1458
  function projectSummary() {
1878
1459
  const projects = sidebarProjects();
1879
1460
  const actor = requestContext.getStore()?.actor ?? '';
1880
1461
  const access = workAccess();
1881
1462
  return chromeRead(summaryKey(actor, access, projects), () => projectSummaryOf(store, clock(), access, actor, projects, evidenceRoot));
1882
1463
  }
1883
- /** What one account may see now, as the summary room keys it: a narrowed ceiling or grant is a different key, so a
1884
- * snapshot read for the wider scope never reaches it. Null: no such account. */
1885
1464
  const projectScopeFor = (account) => store.accountOf(account) === null ? null : requestContext.run({ csrf: '', returnTo: '/', actor: account }, () => {
1886
- // Canonical: what may be seen, never the order it was last opened in.
1887
1465
  const access = workAccess();
1888
1466
  return JSON.stringify({ projects: sidebarProjects().map(one => one.path).sort(), access: { ...access, repos: access.repos === null ? null : [...access.repos].sort() } });
1889
1467
  });
1890
- /** One account's summary snapshot, read as that account for this exact scope (the summary room's fingerprint): null
1891
- * when the account is gone or its scope moved. */
1892
1468
  const projectSummaryFor = (account, scope) => projectScopeFor(account) !== scope ? null : requestContext.run({ csrf: '', returnTo: '/', actor: account }, () => JSON.stringify(projectSummary()));
1893
- /** The sidebar's facts for this request. */
1894
1469
  function chromeFor(project, active, listPane, scope) {
1895
1470
  if (restricted() && !visible(project))
1896
1471
  project = null;
1897
1472
  const actor = requestContext.getStore()?.actor;
1898
- // One Tasks count per request: Needs you in the request's project view
1899
- // (the open project, else every admitted project), never the page's own
1900
- // project — a flow or task in another project shows the same number.
1901
1473
  const lens = requestContext.getStore()?.lens;
1902
1474
  const inboxProject = lens !== undefined && (!restricted() || visible(lens)) ? lens : project;
1903
1475
  const badge = needsYouBadge(inboxProject);
@@ -1909,7 +1481,6 @@ export function createDecisionServer(options) {
1909
1481
  projectPeek = projectFamilyPeek(project, clock());
1910
1482
  }
1911
1483
  catch {
1912
- // Chrome is orientation, never a reason to fail the actual screen.
1913
1484
  projectPeek = undefined;
1914
1485
  }
1915
1486
  }
@@ -1920,9 +1491,6 @@ export function createDecisionServer(options) {
1920
1491
  project,
1921
1492
  projectScoped: restricted(),
1922
1493
  ...(projectPeek === undefined ? {} : { projectPeek }),
1923
- // Enrolled projects first (most recently opened), then the repos this
1924
- // server was told to serve that nobody has opened yet — the switcher
1925
- // lists every project it is allowed to show, each exactly once.
1926
1494
  projects: sidebarProjects(),
1927
1495
  ...(facts === undefined ? {} : { csrf: facts.csrf, returnTo: facts.returnTo }),
1928
1496
  inboxCount: badge.count,
@@ -1934,7 +1502,6 @@ export function createDecisionServer(options) {
1934
1502
  ...(store.isDemo() ? { demo: true } : {}),
1935
1503
  ...(() => { const signIn = signInNotices(store); return signIn.length === 0 ? {} : { signIn }; })(),
1936
1504
  ...(() => {
1937
- // Operators only (only someone at this computer can update it), and gone once this version is dismissed.
1938
1505
  if (!facts?.csrf || !actor || !store.isInstanceOperator(actor))
1939
1506
  return {};
1940
1507
  const update = updateFacts();
@@ -1944,7 +1511,6 @@ export function createDecisionServer(options) {
1944
1511
  })(),
1945
1512
  ...(() => {
1946
1513
  const databaseFile = store.databaseFile();
1947
- // Settings → Updates says a `toolroll update` in full; every other page (and the app's update everywhere) names it once.
1948
1514
  if (!actor || databaseFile === null || !store.isInstanceOperator(actor))
1949
1515
  return {};
1950
1516
  const waiting = waitingUpdate(databaseFile, run => store.stopQuiescenceProblem(run) !== null, clock());
@@ -1959,15 +1525,11 @@ export function createDecisionServer(options) {
1959
1525
  },
1960
1526
  }),
1961
1527
  ...(!restricted() && !unscopedMode && managedRepos().length > 0 ? { chat: true } : {}),
1962
- // Live terminals: offered to an installation-wide operator (the routes prove it again).
1963
1528
  ...(actor !== undefined && !store.isDemo() && store.isInstanceOperator(actor) ? { code: true } : {}),
1964
1529
  ...(listPane === undefined ? {} : { listPane }),
1965
1530
  ...(scope === undefined ? {} : { scope }),
1966
1531
  };
1967
1532
  }
1968
- // All project counts are read together, at most once per workspace revision
1969
- // for this reader's access. No task artifacts or processes are inspected to
1970
- // paint a badge or a project switcher.
1971
1533
  function projectCounts(now) {
1972
1534
  const facts = requestContext.getStore();
1973
1535
  if (facts?.workCounts !== undefined)
@@ -1983,16 +1545,11 @@ export function createDecisionServer(options) {
1983
1545
  .reduce((sum, one) => sum + one.totals['needs-you'], 0);
1984
1546
  return { count, saturated: false };
1985
1547
  }
1986
- /** One work index page for an already-admitted reader, through the chrome cache: a whole view the chat landing reads
1987
- * on every refresh. */
1988
1548
  function sharedIndexPage(access, options) {
1989
- // Receipt reconciliation, task and result reads always read work afresh (disk state included).
1990
1549
  if (requestContext.getStore()?.freshWork === true)
1991
1550
  return workIndexPage(store, clock(), access, options);
1992
1551
  return chromeRead(indexKey(access, options), () => workIndexPage(store, clock(), access, options));
1993
1552
  }
1994
- /** A chrome read for this request: what it already read (its prefetch included) stands for the whole request, else
1995
- * the revision cache's value, else `compute()` now. */
1996
1553
  function chromeRead(key, compute) {
1997
1554
  const facts = requestContext.getStore();
1998
1555
  const held = facts?.chromeReads?.get(key);
@@ -2003,23 +1560,16 @@ export function createDecisionServer(options) {
2003
1560
  (facts.chromeReads ??= new Map()).set(key, value);
2004
1561
  return value;
2005
1562
  }
2006
- /** The chat landing's three whole views (chat.ts chatHomeOf), as it asks for them. */
2007
1563
  const chatHomeViews = () => ["all", "needs-you", "completed"]
2008
1564
  .map(view => ({ view, limit: WORK_INDEX_MAX_LIMIT, ...(evidenceRoot === undefined ? {} : { root: evidenceRoot }) }));
2009
- /** Pages that wear the chrome (the sidebar's states and the Tasks count). */
2010
1565
  const CHROME_PAGES = new Set(["home", "work", "board", "agents", "agents.live", "task.page", "run.page", "chat.page", "review", "tasks", "inbox",
2011
1566
  "next", "done", "projects.page", "flows.page", "flow.page", "settings.page", "decision.page", "menu"]);
2012
- /** Before a chromed page renders: its chrome reads (and the chat landing's views) run on a read worker, so the
2013
- * request thread finds them cached instead of computing them. The reader is the one this request admitted; the keys
2014
- * carry its exact access (console-chrome.ts). Without a worker, or when one fails, the page computes them as before. */
2015
1567
  async function prefetchChrome(route, url, who) {
2016
1568
  if (reads === null || who.via !== "cookie" || !CHROME_PAGES.has(route.id))
2017
1569
  return;
2018
1570
  try {
2019
1571
  const actor = requestContext.getStore()?.actor ?? "";
2020
1572
  const access = workAccess(), projects = sidebarProjects(), now = clock();
2021
- // Populate only the revision cache. Each answer must still pass its revision/expiry check when rendering:
2022
- // another job can remain pending while an earlier answer's approval or Needs-you state changes.
2023
1573
  const fill = async (key, read) => { await chromeReads.fill(key, read); };
2024
1574
  const jobs = [
2025
1575
  fill(countsKey(access), () => reads.workCounts(now, access)),
@@ -2029,7 +1579,6 @@ export function createDecisionServer(options) {
2029
1579
  if (!["project", "room", "team"].some(name => url.searchParams.has(name)) && requestContext.getStore()?.freshWork !== true)
2030
1580
  for (const options of chatHomeViews())
2031
1581
  jobs.push(fill(indexKey(access, options), () => reads.workIndexPage(now, access, options)));
2032
- // The conversation's briefing (chat.ts: the fleet snapshot's states), read as chat reads it.
2033
1582
  const repos = managedRepos();
2034
1583
  if (repos.length > 0 && requestContext.getStore()?.freshWork !== true) {
2035
1584
  const fleet = { principal: "operator", repos, includeUnplaced: false, viewer: who.name };
@@ -2039,26 +1588,15 @@ export function createDecisionServer(options) {
2039
1588
  }
2040
1589
  await Promise.all(jobs);
2041
1590
  }
2042
- catch { /* the page computes what is missing */ }
1591
+ catch { }
2043
1592
  }
2044
- /** A live page's own beat without a docked chat: 10 s while any admitted task is building, else 30 s. */
2045
1593
  function liveRefreshSeconds() {
2046
1594
  return projectCounts(clock()).some(one => one.totals.running > 0) ? 10 : 30;
2047
1595
  }
2048
- /** This exact run's review facts for the shared projection (review
2049
- * fixes, finding 4): the store's bounded retry projection plus the live
2050
- * reviewer's own liveness — read per run, so an older selected result
2051
- * never wears a newer run's review. */
2052
1596
  const reviewFactsFor = (runId) => reviewFactsOf(store.reviewRetryStateOf(runId), runner => {
2053
1597
  const one = store.getRunner(runner)?.runner;
2054
1598
  return one !== undefined && runnerAlive(one, clock());
2055
1599
  }, buildReviewOf(store, runId)?.state === "pending");
2056
- // ---- the live peek (A2; three review rounds' findings are the spec) ----
2057
- //
2058
- // Names and counts only, never content; nothing durable, ever. The cache
2059
- // holds finished ESCAPED fragments keyed by run:base:epoch — the epoch
2060
- // rotates with every lease AND release, so a stale entry's key can never
2061
- // be asked for again; hits still re-prove the whole guard list.
2062
1600
  const peekCache = new Map();
2063
1601
  let peekCacheBytes = 0;
2064
1602
  const peekInFlight = new Map();
@@ -2077,39 +1615,24 @@ export function createDecisionServer(options) {
2077
1615
  peekCacheBytes -= entry.bytes;
2078
1616
  }
2079
1617
  };
2080
- /** One typed sentence inside the region — plain words, no raw errors.
2081
- * `final` marks conditions that cannot heal for this run (finished,
2082
- * superseded, wrong machine): the region poller reads the marker and
2083
- * stops, instead of refetching a dead build every beat forever. */
2084
1618
  const peekSay = (message, final = false) => html `<p class="meta"${final ? html ` data-region-stop` : ""}>${message}</p>`;
2085
- /** The sanitize pipeline (finding 30/35): normalize → mask → escape. */
2086
1619
  const peekName = (path) => {
2087
1620
  const normalized = path.replace(/[\u0000-\u001f\u007f]/g, "");
2088
1621
  const masked = scanForSecrets(normalized).length > 0 ? "[redacted: a credential-shaped name]" : normalized;
2089
1622
  return textHtml(masked);
2090
1623
  };
2091
1624
  async function handlePost(route, url, who, request, response, posted) {
2092
- // Every POST passes the shared mutation guard. Caller, scope, project (including a limited account's posted repo)
2093
- // and role were admitted by the route table.
2094
1625
  const denied = authorizeMutation(request, who, readForm(posted, CONSOLE_FORMS.mutationGuard));
2095
1626
  if (denied !== null)
2096
1627
  return refuse(response, who, denied.status, denied.message, "/", denied.reconnect?.kind === "password" ? { label: "Reconnect", href: denied.reconnect.href } : undefined);
2097
- // Standing can change after a token was minted: a viewer's act stays refused, cookie and bearer alike, except
2098
- // the row's session-local acts.
2099
1628
  if (who.role === "viewer" && !route.viewer)
2100
1629
  return refuse(response, who, 403, "your login can watch, not act — ask an approver to upgrade you");
2101
1630
  const now = clock();
2102
- // Any accepted mutation may change what the inbox owes; the badge
2103
- // re-counts within five seconds either way, this just makes it exact.
2104
1631
  bustBadge();
2105
1632
  return dispatchConsole(route, { url, who, request, response, route, now, project: projectOf(who, request) ?? null, chosenProject: projectOf(who, request) ?? null, posted });
2106
1633
  }
2107
- // Only explicitly authorized conversations receive automatic turns. The
2108
- // deterministic scan is idle without new meaningful work; shutdown drains it.
2109
1634
  let leadMaintenance = null;
2110
1635
  let leadClosing = false;
2111
- // Started in the console's folder scope (folder-gate.ts), so their own timers and the personal queue's kick (which
2112
- // restores the context it was started in, never a request's) read folders as the console's work does.
2113
1636
  server.once('listening', () => consoleFolders(options, identities, () => {
2114
1637
  team.start();
2115
1638
  personalQueue.start();
@@ -2117,23 +1640,17 @@ export function createDecisionServer(options) {
2117
1640
  run: () => runLeadFollowPass({ store, repos: managedRepos, evidenceRoot, clock,
2118
1641
  provider: () => { const enabled = chatEnablement(); return enabled.ok ? { config: enabled.config, key: enabled.key } : null; },
2119
1642
  fetcher: chatFetcher, ...(options.subscriptionChatRunner ? { subscriptionRunner: options.subscriptionChatRunner } : {}) }),
2120
- // Pending delivery is durable and is read again on the next pass; a failure is said where follow status is read.
2121
1643
  onError: error => recordLeadFollowFailure(store, error, clock()),
2122
1644
  });
2123
1645
  }));
2124
- // Background checks (docs/plans/get-side-effects.md): what pages show about this computer's agent sign-ins and the
2125
- // services Toolroll uses is asked here, on a timer, and a page reads the last answer. A page visit never starts a
2126
- // process or a network call, and never acts on what a check finds: lifting a sign-in pause and the lead-by-default
2127
- // rule run from this pass (or a person's Check now), not from a GET.
2128
1646
  let backgroundChecks = null;
2129
1647
  let agentsCheckedAt = 0;
2130
1648
  if (options.backgroundChecks === true)
2131
1649
  server.once('listening', () => {
2132
- // This Toolroll's folder for secrets, checked once now, so a page can read which are set without preparing it.
2133
1650
  try {
2134
1651
  secretFolder();
2135
1652
  }
2136
- catch { /* a page says secrets can't be read; the next action reports why */ }
1653
+ catch { }
2137
1654
  backgroundChecks = startMaintenance({ intervalMs: options.backgroundChecksMs ?? BACKGROUND_CHECKS_MS, shouldStop: () => leadClosing,
2138
1655
  run: () => consoleFolders(options, identities, async () => {
2139
1656
  const now = Date.now();
@@ -2141,11 +1658,9 @@ export function createDecisionServer(options) {
2141
1658
  if (now - agentsCheckedAt >= (options.backgroundChecksMs ?? LOCAL_AGENTS_EVERY_MS)) {
2142
1659
  agentsCheckedAt = now;
2143
1660
  waits.push(checkLocalAgents());
2144
- // The other agents Settings lists: their last answer is what the page shows.
2145
1661
  for (const provider of PROVIDER_IDS.filter(isKeyedProvider).filter(one => one !== "claude" && one !== "codex"))
2146
1662
  waits.push(connectionCheck(provider).catch(() => undefined));
2147
1663
  }
2148
- // Project identities, resolved off the thread: what pages asked about, and answers gone stale.
2149
1664
  waits.push(identities.refresh([...configuredPaths, ...exactRepos(), ...(options.currentRepos?.() ?? []), ...store.listProjects().map(one => one.path), ...store.knownRepos()]));
2150
1665
  integrations.refreshIfDue();
2151
1666
  const sso = ssoSettings();
@@ -2154,28 +1669,22 @@ export function createDecisionServer(options) {
2154
1669
  if (chatKeyFor("openrouter-api") !== null)
2155
1670
  waits.push(chatCatalog());
2156
1671
  const openrouter = readProviderKey("openrouter", providerHome);
2157
- // The cache answers until its list is due again (ten minutes, or 30 s after a failure), then fetches.
2158
1672
  if (openrouter !== null)
2159
1673
  waits.push(modelCatalog(openrouter));
2160
- // What used to be closed by whichever page read it first: an operating mode or a flow's "runs on its own"
2161
- // grant past its expiry, a stalled update, old coordinator proposals. (Lead turns past their deadline are the
2162
- // follow pass's, which settles them even while an update drains.)
2163
1674
  const at = clock();
2164
1675
  store.closeExpiredModes(at);
2165
1676
  closeExpiredUnattendedGrants(store, at);
2166
1677
  store.sweepCoordinatorProposals(at);
2167
- // The demo's scripted story, if a beat timer missed (its pages only read it).
2168
1678
  try {
2169
1679
  options.demoLead?.advance(at);
2170
1680
  }
2171
- catch { /* the next pass tries again */ }
1681
+ catch { }
2172
1682
  const databaseFile = store.databaseFile();
2173
1683
  if (databaseFile !== null && !updateChecksOff(process.env, options.configDir ?? dirname(databaseFile)).off) {
2174
1684
  const last = lastChecks.known("release");
2175
1685
  if (lastChecks.due("release", last !== null && "problem" in last.value ? 60_000 : 15 * 60_000))
2176
1686
  waits.push(checkRelease());
2177
1687
  }
2178
- // Chat's first tasks (issues and TODOs) while the first run is open and nothing is filed yet.
2179
1688
  if (firstRunStepsNow(clock()) !== null && !store.hasAnyWork()) {
2180
1689
  for (const repo of managedRepos()) {
2181
1690
  const entry = firstTasks.get(repo);
@@ -2183,18 +1692,11 @@ export function createDecisionServer(options) {
2183
1692
  continue;
2184
1693
  const reading = { until: Date.now() + 10 * 60_000, found: entry?.found ?? null, reading: true };
2185
1694
  firstTasks.set(repo, reading);
2186
- // A test's runner reads in-process; otherwise in a process of its own (learning-look.ts), so the hardened
2187
- // git's synchronous reads of the project's folder never hold the console's thread.
2188
1695
  waits.push((options.firstTaskRunner !== undefined ? findFirstTasks(repo, options.firstTaskRunner) : firstTasksOffThread(repo)).then(found => { reading.found = found; }, () => { }).finally(() => { reading.reading = false; }));
2189
1696
  }
2190
1697
  }
2191
- // Learning recovered from reviewed runs (and a project's saved rows carried to its current identity), which
2192
- // Settings → Learning and Knowledge used to do as they opened.
2193
1698
  if (lastChecks.due("learning", 10 * 60_000)) {
2194
1699
  waits.push(lastChecks.run("learning", async () => {
2195
- // Its reads of each project's Git folder are synchronous, so with a database file they run in a process of
2196
- // their own (learning-look.ts): a folder that doesn't answer costs its own recovery, never the console. An
2197
- // in-memory database (a test) can't be shared, so it is read here.
2198
1700
  if (databaseFile !== null) {
2199
1701
  await recoverLearningOffThread({ databaseFile, evidenceRoot, repos: managedRepos() }, options.learningRunner === undefined ? {} : { runner: options.learningRunner });
2200
1702
  return;
@@ -2203,17 +1705,15 @@ export function createDecisionServer(options) {
2203
1705
  try {
2204
1706
  acceptedIdentities(store, repo);
2205
1707
  }
2206
- catch { /* the next pass tries again */ }
1708
+ catch { }
2207
1709
  try {
2208
1710
  recoverLearning(store, evidenceRoot, repo);
2209
1711
  }
2210
- catch { /* the next pass tries again */ }
1712
+ catch { }
2211
1713
  }
2212
1714
  }));
2213
1715
  }
2214
- // What Codex has configured, per project, for Settings → Tools to offer.
2215
1716
  for (const repo of managedRepos()) {
2216
- // The project's own .mcp.json, read off the console's thread (folder-look.ts) for the Tools page and the lead.
2217
1717
  if (options.identities !== undefined && lastChecks.due(`project-mcp:${repo}`, 10 * 60_000)) {
2218
1718
  waits.push(lastChecks.run(`project-mcp:${repo}`, async () => { const looked = await lookProjectMcp(repo); if (looked.ok)
2219
1719
  savedProjectMcp.set(repo, looked.value); return looked.ok; }));
@@ -2224,25 +1724,17 @@ export function createDecisionServer(options) {
2224
1724
  if (databaseFile !== null && lastChecks.due("storage", 30 * 60_000)) {
2225
1725
  waits.push(lastChecks.run("storage", () => checkoutPlan(store, storagePool(databaseFile), clock(), { manual: true })));
2226
1726
  }
2227
- // The same reading the chrome does, outside a page visit, so it releases a stalled `toolroll update` and a stalled
2228
- // desktop update in every folder the chrome looks in.
2229
1727
  if (databaseFile !== null) {
2230
1728
  try {
2231
1729
  waitingUpdate(databaseFile, run => store.stopQuiescenceProblem(run) !== null, at);
2232
1730
  }
2233
- catch { /* shown as last saved */ }
1731
+ catch { }
2234
1732
  }
2235
1733
  await Promise.all(waits);
2236
1734
  }),
2237
1735
  onError: () => { }, });
2238
1736
  void backgroundChecks.runNow();
2239
1737
  });
2240
- // Keep native process custody until shutdown has verified agent/tool exit.
2241
- // Coding custody does not depend on subagents or the lead's follow pass, so
2242
- // it closes at once and never waits behind a model turn: a stop must release
2243
- // the owner record well inside the service's exit window (Oct 2: deploys
2244
- // over 0.9.11 found it still held by a killed process).
2245
- /** Set once the terminal handlers exist (below): drops every socket and ends every program. */
2246
1738
  const terminalClosing = {};
2247
1739
  let codingClosing = null;
2248
1740
  const closeCoding = () => {
@@ -2259,14 +1751,13 @@ export function createDecisionServer(options) {
2259
1751
  try {
2260
1752
  requestBudget.flush();
2261
1753
  }
2262
- catch { /* saved again on the close event when it can be */ }
1754
+ catch { }
2263
1755
  flowRooms.close();
2264
1756
  taskRooms.close();
2265
1757
  liveHandlers.close();
2266
1758
  detachReads();
2267
1759
  liveFollower.close();
2268
1760
  void Promise.all([closeCoding(), terminalClosing.close?.().then(problem => { terminalClosing.problem = problem; }), bounded(team.close()), bounded(personalQueue.close()), bounded(leadMaintenance?.stop()), bounded(backgroundChecks?.stop()), bounded(reads?.close())])
2269
- // The server always closes; a terminal whose processes couldn't be proved stopped is the close's error.
2270
1761
  .then(() => closeServer(error => callback?.(error ?? terminalClosing.problem ?? undefined))).catch(error => {
2271
1762
  if (callback)
2272
1763
  callback(error instanceof Error ? error : Error('Coding session shutdown failed.'));
@@ -2464,7 +1955,6 @@ export function createDecisionServer(options) {
2464
1955
  };
2465
1956
  const liveHandlers = createLiveHandlers(handlerRuntime, { bus: liveBus, workspaceRevision, chatProjectOf: chatHandlers.chatProjectOf, projectSummaryFor, projectScopeFor });
2466
1957
  liveTurnStarted = liveHandlers.turnStarted;
2467
- // The one upgrade this server takes is a terminal's socket (terminals.ts listens); anything else is dropped.
2468
1958
  const terminalHandlers = createTerminalHandlers(handlerRuntime, { ...terminals, bus: liveBus, allowedHost, publicOrigin, forwardedSourceOf, server });
2469
1959
  terminalClosing.close = terminalHandlers.close;
2470
1960
  const remoteHandlers = createRemoteHandlers(remoteRuntime);
@@ -2474,7 +1964,6 @@ export function createDecisionServer(options) {
2474
1964
  ...remoteHandlers.registrations, ...liveHandlers.registrations, ...terminalHandlers.registrations, ...createSweepHandlers(handlerRuntime).registrations,
2475
1965
  ...createWelcomeHandlers(handlerRuntime).registrations,
2476
1966
  ]);
2477
- /** The row's role, after admission and before its one handler. */
2478
1967
  function dispatchConsole(route, ctx) {
2479
1968
  const { who, response } = ctx;
2480
1969
  const held = route.role === "any" || ((!route.roleBrowser || who.via === "cookie") &&
@@ -2497,8 +1986,6 @@ export function createDecisionServer(options) {
2497
1986
  }
2498
1987
  return withEdgePolicy(route, () => registry.edge(route, { ...ctx, route }));
2499
1988
  }
2500
- /** Easy-start C1: the local owner a browser session acts as on an allowed row, bound to its session's saved row and
2501
- * the generations it was made under; null when it no longer stands (refused like any other row). */
2502
1989
  function localPrincipalOf(who, route) {
2503
1990
  const sessionHash = sessions.hashOf(who.session);
2504
1991
  if (route.localAct === null || who.session.localGeneration === null || sessionHash === null)
@@ -2507,17 +1994,13 @@ export function createDecisionServer(options) {
2507
1994
  transport: "browser", act: route.localAct, sessionHash, request: { ended: false } };
2508
1995
  return localOwnerStandsNow(store, principal) ? principal : null;
2509
1996
  }
2510
- /** What a local owner hears on a row not marked for it: set a first password, or sign in with the one set. */
2511
1997
  function refuseLocalOwner(response, who, method, url, accept) {
2512
- // The page it was refused on, built here from the request (never from a header): a form's nearest page above it.
2513
1998
  const words = localOwnerRefusal(store.accountOf(who.name)?.passwordSet === true, refusalNext(method, url));
2514
- // Which refusal this was, for the shell (it offers the same way on) and the route inventory's rule table.
2515
1999
  response.setHeader("x-toolroll-refused", "local-owner");
2516
2000
  if (String(accept ?? "").includes("application/json"))
2517
2001
  return respond(response, 403, "application/json", JSON.stringify({ ok: false, said: words.message, href: words.href }));
2518
2002
  return refuse(response, who, 403, words.message, words.href, { label: words.action, href: words.href });
2519
2003
  }
2520
- // Defined last, so the reviewed functions above keep their places (password-freshness.test.ts).
2521
2004
  function holdSignInLink(link) {
2522
2005
  for (const [key, one] of signInLinks)
2523
2006
  if (one.expires < Date.now())
@@ -2528,8 +2011,6 @@ export function createDecisionServer(options) {
2528
2011
  signInLinks.set(linkKey(code), link);
2529
2012
  return `${SIGN_IN_LINK_PATH}${code}`;
2530
2013
  }
2531
- /** Easy-start C4: a local owner's one-time link. It names no account: local mode's own owner, read now, while local
2532
- * mode is on and the owner is active. Redemption reads local mode again and issues only a local-owner session. */
2533
2014
  function mintLocalLink() {
2534
2015
  const binding = localOwnerBinding(store);
2535
2016
  if (binding === null)
@@ -2546,12 +2027,6 @@ export { ssoStepUps, wrongHostPage } from "./server/render-people.js";
2546
2027
  export { diffFileAnchor, editorFileHref, needActionOf, orderChangedFiles, plainConclusionOf, rankReviewQueue, reviewFilePriority, reviewPriorityOf, runFactsFragment, withinSignedTouches } from "./server/render-results.js";
2547
2028
  export { decisionAnswerScript, earlierVersionsWords, revisionLineageWords } from "./server/render-tasks.js";
2548
2029
  export { SIGN_IN_LINK_MS, SIGN_IN_LINK_PATH } from "./server/session.js";
2549
- /**
2550
- * The console's configured repos and roots. Without identities (embedders and tests) they resolve once, synchronously,
2551
- * as before. With them, the console resolves them in the background after it listens (operate.ts startConsole), so
2552
- * each is read from the last answer: a configured path counts by its real path from the moment its folder answers,
2553
- * and until then only by its spelling, which the strict `canon` never matches for an unresolved row.
2554
- */
2555
2030
  function startupCeiling(repos, roots, identities, canon) {
2556
2031
  const configured = repos.length > 0 || roots.length > 0;
2557
2032
  const configuredPaths = [...repos, ...roots];
@@ -2565,8 +2040,6 @@ function startupCeiling(repos, roots, identities, canon) {
2565
2040
  configuredPaths,
2566
2041
  };
2567
2042
  }
2568
- // Only resolved entries authorize: an unresolved configured path is in no list, so it matches nothing (not even its
2569
- // own spelling) and is no session's default until its folder answers.
2570
2043
  const resolved = (paths) => [...new Set(paths.flatMap(path => { const real = identities.known(path); return typeof real === "string" ? [real] : []; }))];
2571
2044
  const ceiling = {
2572
2045
  get repos() { return resolved(repos); },
@@ -2581,14 +2054,7 @@ function startupCeiling(repos, roots, identities, canon) {
2581
2054
  configuredPaths,
2582
2055
  };
2583
2056
  }
2584
- /** Each console's folder gate (folder-gate.ts), made once for its options. */
2585
2057
  const consoleGates = new WeakMap();
2586
- /**
2587
- * Runs the console's own work (a request, a background pass) in its folder scope: with identities resolved off its
2588
- * thread (up and serve), it reads a person's folder synchronously only while that folder answered a look lately; its
2589
- * own data (the database's folder, evidence, build checkouts) is read freely. Without identities (embedders, tests):
2590
- * as before. Work that isn't the console's (a worker in the same process) never runs in it.
2591
- */
2592
2058
  function consoleFolders(options, identities, work) {
2593
2059
  if (options.identities === undefined)
2594
2060
  return work();