@humwick/server 0.130.2 → 0.130.3

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 (570) hide show
  1. package/bundled/prompts/manifest.json +1 -0
  2. package/bundled/prompts/task.hydration.md +1 -1
  3. package/bundled/roles/builder.md +1 -1
  4. package/docs/guides/sub-coordinators.md +12 -5
  5. package/docs/guides/tools-coordination.md +1 -0
  6. package/docs/guides/workflows.md +16 -0
  7. package/docs/openapi.json +73 -4
  8. package/package.json +8 -7
  9. package/public/assets/{MessageBubble-BWLqMGKG.js → MessageBubble-Bq9kr21N.js} +2 -2
  10. package/public/assets/{PlanGraphPanel-3TlIQpjk.js → PlanGraphPanel-Dqiroy06.js} +2 -2
  11. package/public/assets/{TraceView-Wimm0Czv.js → TraceView-DYU962-H.js} +2 -2
  12. package/public/assets/{VaultDecisionCard-Bau_vNax.js → VaultDecisionCard-DhPfzioE.js} +2 -2
  13. package/public/assets/{activity-CrSurn-r.js → activity-DzCcQTee.js} +2 -2
  14. package/public/assets/{agent-lineage-CknAJKcb.js → agent-lineage-SgDt9i3T.js} +2 -2
  15. package/public/assets/agent-liveness-Bq-s73jW.js +2 -0
  16. package/public/assets/{agent-name-DKbiIhBo.js → agent-name-CcY3Aijy.js} +2 -2
  17. package/public/assets/{agent-profiles-DwF6EQ4R.js → agent-profiles-cxtRBn6O.js} +2 -2
  18. package/public/assets/{agent-project-badge-Diz4Sjjb.js → agent-project-badge-DGYbIhaI.js} +2 -2
  19. package/public/assets/{agent-tools-CRhpRQza.js → agent-tools-DHbftV0N.js} +2 -2
  20. package/public/assets/{agent-type-icon-LrUEU3lB.js → agent-type-icon-CY113sp-.js} +2 -2
  21. package/public/assets/{agents-B-v66C-4.js → agents-BPzY7IlQ.js} +2 -2
  22. package/public/assets/{analytics-BqCb-LKi.js → analytics-DENFPv_a.js} +2 -2
  23. package/public/assets/{artifact-viewer-kf4pGuAR.js → artifact-viewer-KRvSc7sl.js} +2 -2
  24. package/public/assets/{artifacts-DJevXcvg.js → artifacts-C9gSmL3s.js} +2 -2
  25. package/public/assets/{artifacts-D32zyw4Y.js → artifacts-DT-HkI5O.js} +2 -2
  26. package/public/assets/{automation-BpRajx_5.js → automation-BsmjQhKD.js} +2 -2
  27. package/public/assets/{backlog-D_UjTdzX.js → backlog-8NYH_62t.js} +2 -2
  28. package/public/assets/{busy-health-N3VEh4ao.js → busy-health-D3hwvYb4.js} +2 -2
  29. package/public/assets/{channels-9jopungq.js → channels-DCJ5WL7O.js} +2 -2
  30. package/public/assets/{chat-CSXrTB3C.js → chat-DAIl357U.js} +3 -3
  31. package/public/assets/{code-preview-p1NnmqK0.js → code-preview-CzrZfr9U.js} +2 -2
  32. package/public/assets/{connectors-CZdqlDNL.js → connectors-xTxtlyou.js} +2 -2
  33. package/public/assets/{cosmos-BgdsE4dG.js → cosmos-BpebFLK2.js} +2 -2
  34. package/public/assets/{crate-agent-30aXTKva.js → crate-agent-BHvI5wXC.js} +2 -2
  35. package/public/assets/{dependency-graph-B_jvw2GE.js → dependency-graph-DGT0o3wJ.js} +2 -2
  36. package/public/assets/{deploys-DoN6bAb5.js → deploys-hqWOHSHE.js} +2 -2
  37. package/public/assets/{display-BrKWFGJz.js → display-CDeH4I8T.js} +2 -2
  38. package/public/assets/{files-D6XEu8Ng.js → files-BTeGVmTg.js} +2 -2
  39. package/public/assets/{fleet-C7jQWbw2.js → fleet-DgXtNgCa.js} +2 -2
  40. package/public/assets/{fleet-metrics-BiDs3MLx.js → fleet-metrics-BHEt5yc_.js} +2 -2
  41. package/public/assets/{formatted-body-CQBwc1fb.js → formatted-body-MLtodyPp.js} +3 -3
  42. package/public/assets/{formatted-body-impl-DyG0WsQS.js → formatted-body-impl-CAe664Z8.js} +2 -2
  43. package/public/assets/{host-providers-dialog-DKaW31dN.js → host-providers-dialog-mapF4Fj9.js} +2 -2
  44. package/public/assets/{index-CRHep3M9.js → index-CqqgOI5R.js} +5 -5
  45. package/public/assets/{insights-CzrtkpOE.js → insights-DNyf7IzF.js} +2 -2
  46. package/public/assets/{integrations-aVsUmigt.js → integrations-DlYOHq7T.js} +2 -2
  47. package/public/assets/{issue-ref-chip-BnSlM_95.js → issue-ref-chip-CeWBNWn7.js} +2 -2
  48. package/public/assets/{log-viewer-qe7Ee47Z.js → log-viewer-Cib8nqdE.js} +2 -2
  49. package/public/assets/{maintenance-NfjqFZAk.js → maintenance-DSn1cPm7.js} +2 -2
  50. package/public/assets/{managed-agents-BiH0HgaE.js → managed-agents-C3CkM81m.js} +2 -2
  51. package/public/assets/{markdown-preview-BixaT3Xr.js → markdown-preview-W4VQQPAv.js} +3 -3
  52. package/public/assets/{markdown-preview-impl-DNGlWIS3.js → markdown-preview-impl-CMsTdhjq.js} +2 -2
  53. package/public/assets/{memory-DNsCl6UX.js → memory-BV17qtO4.js} +2 -2
  54. package/public/assets/{messages-DopU1L1X.js → messages-Bm_1AqSA.js} +2 -2
  55. package/public/assets/{orchestrators-Cq7ckLQT.js → orchestrators-Dg-vfP09.js} +2 -2
  56. package/public/assets/{overview-C1DCTzzV.js → overview-DcYCrvlr.js} +2 -2
  57. package/public/assets/{pairs-DE_m6rrE.js → pairs-8o9nuG3V.js} +2 -2
  58. package/public/assets/{profile-icon-B3rfh77F.js → profile-icon-BsRyBMea.js} +2 -2
  59. package/public/assets/{project-profile-instructions-DQWZE0kA.js → project-profile-instructions-DETKFn_E.js} +2 -2
  60. package/public/assets/{projects-Br2Bd2h1.js → projects-M_m6AHws.js} +2 -2
  61. package/public/assets/{prompt-settings-BKvFsvGD.js → prompt-settings-C_mNCgeL.js} +2 -2
  62. package/public/assets/provider-display-BEeLXC_D.js +2 -0
  63. package/public/assets/{registry-Cw38_6gW.js → registry-DDHHHE5N.js} +2 -2
  64. package/public/assets/run-card-Dt4I4jaP.js +2 -0
  65. package/public/assets/{secrets-DxI-vzSq.js → secrets-BkVwxI5O.js} +2 -2
  66. package/public/assets/{service-access-settings-D9s_VJbd.js → service-access-settings-Crq-6a-B.js} +2 -2
  67. package/public/assets/{settings-CKZTVGIx.js → settings-CYcavMFu.js} +2 -2
  68. package/public/assets/shipping-H6gzEeZB.js +2 -0
  69. package/public/assets/{stats-DyUBKyWI.js → stats-BJVeWkpV.js} +2 -2
  70. package/public/assets/{status-dot-DYqlEUhJ.js → status-dot-BcHyw1Vw.js} +2 -2
  71. package/public/assets/store-DKPDIZBe.js +9 -0
  72. package/public/assets/{tasks-Bh7Chr4-.js → tasks-qJjlQPpx.js} +2 -2
  73. package/public/assets/{teams-bowI7qVY.js → teams-Cd5Sk1uX.js} +2 -2
  74. package/public/assets/{terminal-viewer-BgVLHdsU.js → terminal-viewer-CpY5_m7W.js} +3 -3
  75. package/public/assets/{terminal-viewer-impl-Dz22UPy6.js → terminal-viewer-impl-DI_2llFR.js} +2 -2
  76. package/public/assets/{use-agent-terminal-DSQQ-iY7.js → use-agent-terminal-0yJA_buM.js} +2 -2
  77. package/public/assets/{use-decisions-samMQhQf.js → use-decisions-uJXHf34W.js} +2 -2
  78. package/public/assets/{use-project-list-59LheVP7.js → use-project-list-CpWl6eHQ.js} +2 -2
  79. package/public/assets/{use-selectors-BZa25xEB.js → use-selectors-BdxBW8mL.js} +2 -2
  80. package/public/assets/{user-avatar-DHxlvUvV.js → user-avatar-3IndfpOc.js} +2 -2
  81. package/public/assets/{versioned-prompt-editor-BmED5DnJ.js → versioned-prompt-editor-CIVg7XB1.js} +2 -2
  82. package/public/assets/{work-queue-CSvpuNLz.js → work-queue-B9rnLwHZ.js} +2 -2
  83. package/public/assets/{workflow-marker-DAZcj5qt.js → workflow-marker-X8wxyhzC.js} +2 -2
  84. package/public/assets/{workflows-DdmxRSyg.js → workflows-o5YyMFW7.js} +2 -2
  85. package/public/assets/{workspaces-BxeKfVuF.js → workspaces-CzEGoAng.js} +2 -2
  86. package/public/cosmos.html +4 -4
  87. package/public/index.html +28 -28
  88. package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
  89. package/runner/src/adapters/claude-headless.ts +1 -1
  90. package/runner/src/adapters/claude-launch-exit.ts +26 -0
  91. package/runner/src/adapters/claude-session-probe.ts +1 -1
  92. package/runner/src/adapters/claude-tmux.ts +38 -10
  93. package/runner/src/adapters/claude.ts +28 -75
  94. package/runner/src/adapters/provider-quota-harvest.ts +20 -71
  95. package/runner/src/agent-runner/lifecycle-milestones.ts +2 -2
  96. package/runner/src/agent-runner/liveness-exchange.ts +104 -0
  97. package/runner/src/claude-system-prompt.ts +49 -0
  98. package/runner/src/launch-assembly.ts +14 -10
  99. package/runner/src/profile-home.ts +1 -1
  100. package/runner/src/project-instructions.ts +2 -2
  101. package/runner/src/provider-command.ts +18 -0
  102. package/runner/src/provider-setup.ts +2 -1
  103. package/runner/src/runner-core.ts +14 -15
  104. package/runner/src/runner-helpers.ts +0 -8
  105. package/runner/src/session-scratch.ts +6 -2
  106. package/runner/test-support/provisioning-context.ts +4 -2
  107. package/runner/test-support/runner-harness.ts +2 -1
  108. package/scripts/steward-policy-cleanup.ts +2 -2
  109. package/src/agent-authz.ts +2 -2
  110. package/src/agent-drive-arbiter.ts +3 -8
  111. package/src/agent-exit-cleanup-async.ts +2 -2
  112. package/src/agent-exit-cleanup.ts +23 -19
  113. package/src/agent-lifecycle-events.ts +112 -85
  114. package/src/agent-ref.ts +3 -2
  115. package/src/agent-status-events.ts +43 -14
  116. package/src/auth/password.ts +4 -3
  117. package/src/auth/session-refresh.ts +1 -1
  118. package/src/auth/session.test-fixture.ts +2 -2
  119. package/src/auth/session.ts +7 -7
  120. package/src/automations/crud.ts +8 -81
  121. package/src/automations/dispatch.ts +33 -58
  122. package/src/automations/index.ts +1 -1
  123. package/src/automations/persistence.ts +65 -0
  124. package/src/automations/precheck.ts +18 -16
  125. package/src/automations/read-async.ts +11 -0
  126. package/src/automations/reconcile.ts +30 -39
  127. package/src/automations/storage.ts +33 -10
  128. package/src/automations/write-async.ts +33 -0
  129. package/src/branch-land-notice.ts +3 -3
  130. package/src/branch-landed.ts +25 -23
  131. package/src/bus.ts +21 -19
  132. package/src/cd-deploy-notify.ts +2 -2
  133. package/src/ci/notifications.ts +4 -4
  134. package/src/ci/root-missing.ts +3 -3
  135. package/src/ci/transition-notify.ts +5 -5
  136. package/src/claude-app/oauth-http.ts +3 -3
  137. package/src/cli/workflow.ts +12 -3
  138. package/src/commands-db.ts +4 -4
  139. package/src/commands-write.ts +8 -0
  140. package/src/compaction-watch.ts +10 -8
  141. package/src/config-store-write.ts +2 -2
  142. package/src/config.ts +4 -11
  143. package/src/connectors.ts +10 -8
  144. package/src/context-advisory.ts +22 -21
  145. package/src/db/agent-action-write.ts +36 -0
  146. package/src/db/agent-control-async.ts +9 -0
  147. package/src/db/agent-control-write.ts +49 -0
  148. package/src/db/agent-effort-observe.ts +22 -0
  149. package/src/db/agent-meta.ts +14 -3
  150. package/src/db/agents-async.ts +8 -5
  151. package/src/db/agents.ts +15 -12
  152. package/src/db/auth-identities.ts +2 -2
  153. package/src/db/automation-read-ops.ts +11 -0
  154. package/src/db/automation-write-ops.ts +46 -0
  155. package/src/db/blackboard.ts +2 -2
  156. package/src/db/browser-session-write.ts +32 -0
  157. package/src/db/bus-outbox-write-ops.ts +3 -1
  158. package/src/db/checkout-refresh-schema.ts +47 -0
  159. package/src/db/checkout-refresh.ts +5 -5
  160. package/src/db/command-agent-profile-backfill.ts +39 -0
  161. package/src/db/command-agent-profiles.ts +5 -1
  162. package/src/db/command-retention.ts +126 -0
  163. package/src/db/commands-planner-stats.test-fixture.ts +8 -0
  164. package/src/db/commands-read-ops.ts +16 -0
  165. package/src/db/connection.ts +1 -182
  166. package/src/db/context-carry-write.ts +74 -0
  167. package/src/db/continuations.ts +4 -4
  168. package/src/db/db-error-registry.ts +12 -0
  169. package/src/db/gateway.ts +26 -133
  170. package/src/db/history-retention-ops.ts +13 -0
  171. package/src/db/inbox-async.ts +2 -2
  172. package/src/db/inbox-read-ops.ts +1 -1
  173. package/src/db/inbox.ts +9 -3
  174. package/src/db/issue-associations.ts +2 -2
  175. package/src/db/issue-refs-async.ts +4 -1
  176. package/src/db/issue-refs-read-ops.ts +6 -0
  177. package/src/db/issue-refs.ts +8 -8
  178. package/src/db/kernel-event-log-schema.ts +2 -0
  179. package/src/db/land-boundaries.ts +51 -5
  180. package/src/db/land-gate-attestations.ts +2 -2
  181. package/src/db/landing-receipts.ts +2 -2
  182. package/src/db/lifecycle-context-write.ts +5 -0
  183. package/src/db/lifecycle-tail-async.ts +76 -0
  184. package/src/db/lifecycle-tail-write-ops.ts +62 -0
  185. package/src/db/lifecycle-write-window.ts +2 -1
  186. package/src/db/lineage-pair-dedupe-sql.ts +3 -3
  187. package/src/db/main-connection-mode.ts +11 -0
  188. package/src/db/main-connection-writes.ts +20 -2
  189. package/src/db/maintenance-job-runs-async.ts +2 -2
  190. package/src/db/maintenance-job-write-ops.ts +1 -1
  191. package/src/db/maintenance-pauses.ts +2 -2
  192. package/src/db/message-send.ts +4 -0
  193. package/src/db/messages.ts +31 -25
  194. package/src/db/migrations.ts +18 -1
  195. package/src/db/notification-write-ops.ts +19 -0
  196. package/src/db/operator-answer-write.ts +19 -0
  197. package/src/db/orchestrators.ts +10 -4
  198. package/src/db/pairs-async.ts +22 -1
  199. package/src/db/pairs-write-ops.ts +8 -3
  200. package/src/db/pairs.ts +41 -48
  201. package/src/db/plan-dispatch-schema.ts +5 -1
  202. package/src/db/plan-ready-notices.ts +43 -0
  203. package/src/db/plan-tools-include-migration.ts +36 -0
  204. package/src/db/plans-write-ops.ts +2 -0
  205. package/src/db/presence-buffer.ts +5 -0
  206. package/src/db/presence-loop.ts +18 -23
  207. package/src/db/presence-write.ts +0 -6
  208. package/src/db/project-entries-async.ts +14 -0
  209. package/src/db/project-entries-read-ops.ts +5 -1
  210. package/src/db/project-entries-write-ops.ts +8 -0
  211. package/src/db/project-entries.ts +15 -12
  212. package/src/db/project-journal.ts +2 -2
  213. package/src/db/project-trust-approvals.ts +2 -2
  214. package/src/db/prompt-templates.ts +4 -4
  215. package/src/db/read-op-marshaling-fixtures.ts +18 -0
  216. package/src/db/read-ops.ts +4 -0
  217. package/src/db/retention.ts +13 -2
  218. package/src/db/review-publish-write.ts +8 -0
  219. package/src/db/runtime-admin-async.ts +19 -0
  220. package/src/db/runtime-admin-write-ops.ts +36 -0
  221. package/src/db/runtime-tail-async.ts +288 -0
  222. package/src/db/runtime-tail-write-ops.ts +97 -0
  223. package/src/db/schema.ts +4 -1
  224. package/src/db/spawn-budget.ts +5 -0
  225. package/src/db/spawn-delegation.ts +1 -11
  226. package/src/db/sql-audit-indexes.ts +3 -0
  227. package/src/db/stats-async.ts +5 -3
  228. package/src/db/task-entity.ts +5 -4
  229. package/src/db/team-claim-policy.ts +60 -0
  230. package/src/db/teams-async.ts +4 -0
  231. package/src/db/teams-write-ops.ts +4 -0
  232. package/src/db/terminal-events.ts +15 -0
  233. package/src/db/timer-cutover-bodies.ts +292 -0
  234. package/src/db/timer-cutover-core.ts +37 -278
  235. package/src/db/timer-cutover-state.ts +40 -0
  236. package/src/db/timer-cutover-write-ops.ts +1 -40
  237. package/src/db/token-db-write-ops.ts +2 -0
  238. package/src/db/token-standing-async.ts +12 -0
  239. package/src/db/token-standing.ts +6 -9
  240. package/src/db/token-usage-retention.ts +33 -0
  241. package/src/db/token-usage-write-ops.ts +1 -1
  242. package/src/db/token-usage.ts +4 -1
  243. package/src/db/user-invites-async.ts +13 -0
  244. package/src/db/user-invites.ts +3 -3
  245. package/src/db/users.ts +14 -6
  246. package/src/db/workspaces.ts +8 -5
  247. package/src/db/write-ops.ts +31 -12
  248. package/src/db/writer-fault-seam.ts +2 -9
  249. package/src/db/writer-fault-test-ops.ts +18 -0
  250. package/src/db/writer-gateway.ts +42 -46
  251. package/src/dev.ts +8 -3
  252. package/src/event-loop-lag.ts +4 -2
  253. package/src/event-loop-yield.ts +2 -2
  254. package/src/events.ts +10 -8
  255. package/src/host-provider-store.ts +5 -4
  256. package/src/hub-metrics-report.ts +5 -1
  257. package/src/hub-metrics.ts +38 -18
  258. package/src/injection-sweep-pacing.ts +6 -8
  259. package/src/land-gate-notifications.ts +11 -10
  260. package/src/land-gate-queue-progress.ts +3 -3
  261. package/src/land-settle-dispatch.ts +52 -92
  262. package/src/lifecycle-context-pressure.ts +11 -10
  263. package/src/lifecycle-manager.ts +104 -98
  264. package/src/maintenance/breaker.ts +18 -16
  265. package/src/maintenance/checkout-refresh.ts +18 -1
  266. package/src/maintenance/critical-job-watchdog.ts +3 -3
  267. package/src/maintenance/events.ts +3 -3
  268. package/src/maintenance/history-retention-job.ts +30 -0
  269. package/src/maintenance/jobs.ts +29 -67
  270. package/src/maintenance/long-running-work.ts +3 -1
  271. package/src/maintenance/offline-agent-prune-job.ts +28 -0
  272. package/src/maintenance/orphaned-sessions.ts +5 -4
  273. package/src/maintenance/pauses.ts +4 -10
  274. package/src/maintenance/plan-ready-notice-job.ts +71 -0
  275. package/src/maintenance/scheduler.ts +18 -13
  276. package/src/maintenance/stalled-delivery-pager.ts +4 -4
  277. package/src/maintenance/teams.ts +19 -30
  278. package/src/maintenance/workspaces.ts +17 -27
  279. package/src/managed-policy-escalation.ts +7 -7
  280. package/src/managed-policy.ts +3 -3
  281. package/src/managed-provider-gate.ts +5 -4
  282. package/src/managed-spawn-reservation.ts +5 -4
  283. package/src/mcp/index.ts +8 -8
  284. package/src/mcp/output-descriptions.ts +1 -1
  285. package/src/mcp/presentation.ts +2 -1
  286. package/src/mcp/runtime-output.ts +6 -1
  287. package/src/mcp/self-care-visibility.ts +2 -2
  288. package/src/mcp/spawn-targets-matrix.ts +10 -1
  289. package/src/mcp/tool-groups.ts +3 -2
  290. package/src/mcp/tool-roles.ts +81 -0
  291. package/src/mcp/tools-workspace.ts +1 -1
  292. package/src/mcp-blackboard-tools.ts +6 -5
  293. package/src/mcp-decision-tools.ts +7 -7
  294. package/src/mcp-egress-tools.ts +10 -9
  295. package/src/mcp-issue-activity-tools.ts +2 -2
  296. package/src/mcp-issue-association-tools.ts +4 -4
  297. package/src/mcp-issue-ref-tools.ts +3 -3
  298. package/src/mcp-merge-tools.ts +5 -5
  299. package/src/mcp-notification-subscription-tools.ts +14 -15
  300. package/src/mcp-output-levels.test-fixture.ts +1 -1
  301. package/src/mcp-profile-trust-tools.ts +1 -1
  302. package/src/mcp-project-journal-tools.ts +4 -12
  303. package/src/mcp-project-tools.ts +17 -18
  304. package/src/mcp-routing-policy-tools.ts +3 -2
  305. package/src/mcp-team-tools.ts +6 -6
  306. package/src/mcp-workflow-tools.ts +5 -3
  307. package/src/memory-area-injection.ts +13 -12
  308. package/src/memory-boundary-capture.ts +6 -6
  309. package/src/memory-injection.ts +45 -43
  310. package/src/merge-pause-maintenance.ts +5 -4
  311. package/src/notification-router.ts +44 -17
  312. package/src/notify.ts +5 -5
  313. package/src/observed-reset-refresh.ts +4 -4
  314. package/src/operator-alarm.ts +2 -5
  315. package/src/project-ingest.ts +6 -6
  316. package/src/project-instructions.ts +8 -1
  317. package/src/project-trust.ts +12 -11
  318. package/src/prompt-resolver.ts +3 -3
  319. package/src/provider-quota-async.ts +5 -7
  320. package/src/provider-timeline-event.ts +4 -7
  321. package/src/quota-band-delivery.ts +2 -2
  322. package/src/recipe-runner.ts +4 -3
  323. package/src/retention-config-store.ts +4 -3
  324. package/src/reviewer-pipeline.ts +11 -10
  325. package/src/routes/_route.ts +4 -4
  326. package/src/routes/_shared.ts +13 -12
  327. package/src/routes/agent-effort.ts +5 -5
  328. package/src/routes/agent-heartbeat-quota.ts +23 -0
  329. package/src/routes/agent-keep.ts +1 -1
  330. package/src/routes/agent-reporting.ts +1 -1
  331. package/src/routes/agent-self-effort.ts +5 -5
  332. package/src/routes/agent-sessions.ts +24 -24
  333. package/src/routes/agents-spawn.ts +1 -1
  334. package/src/routes/agents.ts +17 -119
  335. package/src/routes/auth.ts +14 -15
  336. package/src/routes/authority-audit.ts +2 -2
  337. package/src/routes/automations.ts +6 -5
  338. package/src/routes/channel-binding-delete.ts +1 -1
  339. package/src/routes/channel-output.ts +3 -3
  340. package/src/routes/claude-api-budget.ts +5 -5
  341. package/src/routes/commands-listing.ts +1 -1
  342. package/src/routes/commands.ts +29 -27
  343. package/src/routes/context-resets.ts +2 -2
  344. package/src/routes/coordinator-teams.ts +1 -1
  345. package/src/routes/decisions.ts +2 -2
  346. package/src/routes/host-secret-files.ts +1 -1
  347. package/src/routes/hosts.ts +11 -11
  348. package/src/routes/inbox.ts +3 -2
  349. package/src/routes/index.ts +2 -1
  350. package/src/routes/integrations.ts +9 -7
  351. package/src/routes/issue-activity.ts +2 -2
  352. package/src/routes/issue-associations.ts +4 -4
  353. package/src/routes/issue-refs.ts +3 -3
  354. package/src/routes/kernel-timers-operator.ts +1 -1
  355. package/src/routes/memory.ts +1 -1
  356. package/src/routes/merges.ts +11 -11
  357. package/src/routes/messages.ts +23 -17
  358. package/src/routes/orchestrator-bootstrap.ts +1 -1
  359. package/src/routes/orchestrator-host-registration.ts +2 -0
  360. package/src/routes/orchestrator-host-utilization.ts +2 -2
  361. package/src/routes/orchestrator-proxy.ts +2 -2
  362. package/src/routes/orchestrator.ts +27 -18
  363. package/src/routes/pairs.ts +8 -8
  364. package/src/routes/project-profile-instructions.ts +1 -1
  365. package/src/routes/project-trust.ts +1 -1
  366. package/src/routes/projects.ts +16 -16
  367. package/src/routes/prompt-templates.ts +12 -12
  368. package/src/routes/provider-quotas.ts +10 -10
  369. package/src/routes/run-command.ts +1 -1
  370. package/src/routes/secrets-backup.ts +2 -2
  371. package/src/routes/secrets-import.ts +1 -1
  372. package/src/routes/secrets-vault.ts +7 -7
  373. package/src/routes/settings.ts +1 -1
  374. package/src/routes/shipping.ts +9 -1
  375. package/src/routes/spawn-policy.ts +8 -7
  376. package/src/routes/sse.ts +2 -2
  377. package/src/routes/team-templates.ts +7 -7
  378. package/src/routes/teams.ts +10 -10
  379. package/src/routes/tokens.ts +18 -17
  380. package/src/routes/users.ts +24 -24
  381. package/src/routes/viewer-read.ts +3 -3
  382. package/src/routes/web-tool-calls.ts +4 -4
  383. package/src/routes/workflows.ts +2 -2
  384. package/src/routes/workspaces.ts +17 -16
  385. package/src/routing-policy-push.ts +6 -6
  386. package/src/runtime-grant.ts +17 -11
  387. package/src/runtime-tokens.ts +20 -28
  388. package/src/secrets-broker/config.ts +1 -1
  389. package/src/secrets-broker/service.ts +2 -2
  390. package/src/security.ts +3 -1
  391. package/src/self-resume-carry.ts +21 -110
  392. package/src/self-resume-supersede.ts +4 -3
  393. package/src/self-resume.ts +54 -66
  394. package/src/server-background.ts +1 -1
  395. package/src/server.ts +21 -22
  396. package/src/services/agent-action.ts +12 -31
  397. package/src/services/agent-effort.ts +7 -32
  398. package/src/services/agent-hang-watchdog-job.ts +2 -2
  399. package/src/services/agent-heartbeat.ts +166 -0
  400. package/src/services/agent-reporting.ts +1 -1
  401. package/src/services/browser-inventory.ts +3 -3
  402. package/src/services/browser-session-state.ts +3 -2
  403. package/src/services/browser-session.ts +21 -27
  404. package/src/services/bus-command-update.ts +9 -9
  405. package/src/services/checkout-refresh-state.ts +1 -0
  406. package/src/services/checkout-refresh.test-fixture.ts +3 -2
  407. package/src/services/command-host.ts +7 -2
  408. package/src/services/coordinator-digest.ts +3 -2
  409. package/src/services/dispatch-command.ts +12 -13
  410. package/src/services/effective-launch-driver.ts +14 -9
  411. package/src/services/host-changed-paths.test-fixture.ts +5 -6
  412. package/src/services/host-project-readiness.ts +2 -2
  413. package/src/services/host-providers.ts +1 -1
  414. package/src/services/host-utilization.ts +9 -9
  415. package/src/services/idle-agent-digest.ts +17 -12
  416. package/src/services/idle-epics.ts +4 -4
  417. package/src/services/interrupt-agent.ts +12 -9
  418. package/src/services/issue-activity.ts +3 -3
  419. package/src/services/issue-associations.ts +15 -18
  420. package/src/services/issue-lifecycle-comments.ts +3 -2
  421. package/src/services/issue-lifecycle.ts +14 -13
  422. package/src/services/issue-refs.ts +4 -5
  423. package/src/services/kernel-timers-cutover-chaos-worker.ts +1 -1
  424. package/src/services/kernel-timers-ingress-chaos-worker.ts +6 -1
  425. package/src/services/kernel-timers-ingress.ts +3 -3
  426. package/src/services/kernel-timers-message-authority-chaos-worker.ts +3 -10
  427. package/src/services/kernel-timers-operator-chaos-worker.ts +3 -2
  428. package/src/services/kernel-timers-outbox.ts +1 -1
  429. package/src/services/kernel-timers-stage10-operator.ts +1 -1
  430. package/src/services/kernel-timers.ts +4 -3
  431. package/src/services/land-gate-placement.ts +11 -2
  432. package/src/services/land-issue-relations.ts +5 -4
  433. package/src/services/land-restart-retry.ts +7 -6
  434. package/src/services/landed-ancestry.ts +6 -5
  435. package/src/services/legacy-landing-host.ts +4 -1
  436. package/src/services/legacy-landing-recovery.ts +8 -6
  437. package/src/services/managed-running.ts +17 -17
  438. package/src/services/memory-areas.ts +3 -3
  439. package/src/services/merge-pause.ts +9 -15
  440. package/src/services/operator-decisions.ts +37 -41
  441. package/src/services/orchestrator-registration-recovery.ts +6 -2
  442. package/src/services/orchestrator-upgrade.ts +14 -12
  443. package/src/services/permission-decision.ts +4 -3
  444. package/src/services/plan-ci-notice.ts +1 -1
  445. package/src/services/plan-conformance.ts +4 -4
  446. package/src/services/plan-dispatch-policy.ts +10 -3
  447. package/src/services/plan-dispatch.ts +35 -14
  448. package/src/services/plan-graph.ts +39 -261
  449. package/src/services/plan-import.ts +1 -1
  450. package/src/services/plan-live-bindings.ts +8 -37
  451. package/src/services/plan-task-create.ts +1 -1
  452. package/src/services/plan-terminal-refs.ts +2 -12
  453. package/src/services/plan-wake-digest.ts +8 -3
  454. package/src/services/profile-trust.ts +2 -2
  455. package/src/services/project.ts +11 -10
  456. package/src/services/prompt-templates.ts +6 -5
  457. package/src/services/provider-hold-nudge.ts +9 -9
  458. package/src/services/provider-hold-record.ts +13 -12
  459. package/src/services/provider-state-audit.ts +19 -18
  460. package/src/services/provisioning-harness/driver.ts +1 -1
  461. package/src/services/provisioning-harness/fixture-matrix.ts +3 -3
  462. package/src/services/provisioning-harness/lifecycle.ts +24 -22
  463. package/src/services/provisioning-harness/prepare.ts +16 -17
  464. package/src/services/rate-limit-resume.ts +10 -9
  465. package/src/services/red-main-auto-revert.ts +7 -5
  466. package/src/services/red-main-controller-deps.ts +20 -3
  467. package/src/services/red-main-incident.ts +3 -1
  468. package/src/services/red-main-quarantine.ts +2 -3
  469. package/src/services/register-agent.ts +22 -22
  470. package/src/services/restart-project-role.ts +1 -1
  471. package/src/services/restart-spawn.ts +17 -16
  472. package/src/services/review-publish.ts +7 -24
  473. package/src/services/review-ref-reconcile.ts +29 -38
  474. package/src/services/runtime-dependency-alert.ts +27 -0
  475. package/src/services/scheduler-command.ts +11 -9
  476. package/src/services/scheduler.ts +5 -5
  477. package/src/services/self-effort-grant.ts +5 -25
  478. package/src/services/send-message.ts +16 -33
  479. package/src/services/shutdown-agent.ts +17 -14
  480. package/src/services/spawn-agent.ts +12 -41
  481. package/src/services/spawn-chain-inspector.ts +1 -1
  482. package/src/services/spawn-cwd-placement.ts +21 -5
  483. package/src/services/spawn-issue-activity.ts +8 -6
  484. package/src/services/spawn-launch.ts +17 -1
  485. package/src/services/spawn-loss-escalation.ts +1 -1
  486. package/src/services/spawn-registration-watchdog.ts +2 -2
  487. package/src/services/spawn-repo-probe.ts +7 -5
  488. package/src/services/spawn-tree-cleanup.ts +7 -8
  489. package/src/services/steward-reaper.ts +4 -4
  490. package/src/services/task-context-hydration.ts +25 -1
  491. package/src/services/task-delivery.ts +20 -34
  492. package/src/services/task-entity.ts +40 -203
  493. package/src/services/task-issue-link.ts +13 -20
  494. package/src/services/task-issue-weave.ts +12 -11
  495. package/src/services/task-lifecycle.ts +27 -31
  496. package/src/services/task-repo-cwd.ts +37 -0
  497. package/src/services/task-review-hold.ts +4 -17
  498. package/src/services/task-semantic-events.ts +13 -11
  499. package/src/services/task-state-reconcile.ts +3 -4
  500. package/src/services/task-validation.ts +2 -2
  501. package/src/services/team-templates.ts +5 -5
  502. package/src/services/team.ts +31 -98
  503. package/src/services/terminal-provider-exit.ts +6 -5
  504. package/src/services/timer-message-fire-chaos-worker.ts +7 -3
  505. package/src/services/timer-message-fire-outbox.ts +1 -1
  506. package/src/services/transient-agent-reaper.ts +22 -19
  507. package/src/services/turn-reconcile-audit.ts +9 -9
  508. package/src/services/user-onboarding.ts +8 -6
  509. package/src/services/user-profile.ts +6 -9
  510. package/src/services/work-finality.ts +16 -4
  511. package/src/services/workflow-auto-start.ts +2 -1
  512. package/src/services/workflow-caller.ts +61 -4
  513. package/src/services/workflow-child-proof-worker.ts +1 -1
  514. package/src/services/workflow-control-proof-worker.ts +1 -1
  515. package/src/services/workflow-coordinator.ts +8 -2
  516. package/src/services/workflow-decisions.ts +5 -5
  517. package/src/services/workflow-deferred-cleanup.ts +1 -1
  518. package/src/services/workflow-effect-driver.ts +42 -19
  519. package/src/services/workflow-effects.ts +41 -27
  520. package/src/services/workflow-pins.ts +7 -4
  521. package/src/services/workflow-reconcile.ts +1 -0
  522. package/src/services/workflow-resume-pins.ts +3 -3
  523. package/src/services/workflow-routing-defaults.ts +18 -0
  524. package/src/services/workflow-run-view.ts +4 -3
  525. package/src/services/workflow-run.test-fixture.ts +1 -1
  526. package/src/services/workflow-runs.ts +34 -22
  527. package/src/services/workflow-supervisor-state.ts +21 -1
  528. package/src/services/workflow-supervisor.ts +4 -3
  529. package/src/services/workspace-recovery.ts +4 -3
  530. package/src/spawn-admission.ts +10 -2
  531. package/src/spawn-placement.ts +27 -9
  532. package/src/spawn-targets.ts +8 -8
  533. package/src/sse-agent-status.ts +15 -6
  534. package/src/sse.ts +49 -24
  535. package/src/startup-context-injection.ts +61 -57
  536. package/src/steward-handoff.ts +4 -3
  537. package/src/steward-policy-cleanup.ts +9 -8
  538. package/src/steward.ts +2 -2
  539. package/src/task-dispatch-live.ts +5 -2
  540. package/src/task-dispatcher.ts +2 -2
  541. package/src/token-db.ts +2 -2
  542. package/src/token-usage-async.ts +2 -4
  543. package/src/user-awaiting-reply.ts +5 -5
  544. package/src/workspace-actions.ts +24 -29
  545. package/src/workspace-auto-merge.ts +14 -12
  546. package/src/workspace-changed-paths-client.ts +16 -5
  547. package/src/workspace-cleanup-stale.ts +30 -7
  548. package/src/workspace-command-settle.ts +24 -16
  549. package/src/workspace-config.ts +1 -1
  550. package/src/workspace-conflict-resolver.ts +9 -7
  551. package/src/workspace-dead-owner-recovery.ts +5 -4
  552. package/src/workspace-escalation.ts +12 -11
  553. package/src/workspace-human-escalation.ts +3 -3
  554. package/src/workspace-land-gate-watchdog.ts +3 -3
  555. package/src/workspace-land-refusal.ts +20 -0
  556. package/src/workspace-land-stopped.ts +1 -0
  557. package/src/workspace-merge.ts +10 -26
  558. package/src/workspace-nothing-to-land-notice.ts +2 -2
  559. package/src/workspace-orphans.ts +18 -37
  560. package/src/workspace-pr-completion.ts +10 -8
  561. package/src/workspace-rekey.ts +3 -3
  562. package/src/workspace-steward-failure.ts +2 -2
  563. package/src/workspace-steward-wake.ts +2 -2
  564. package/public/assets/agent-liveness-CaNwK0Zf.js +0 -2
  565. package/public/assets/provider-display-DsuWMvVL.js +0 -2
  566. package/public/assets/run-card-CpKqRbhg.js +0 -2
  567. package/public/assets/shipping-B9YtnwtG.js +0 -2
  568. package/public/assets/store-DcClXLH0.js +0 -9
  569. package/runner/src/agent-runner/http-liveness.ts +0 -85
  570. package/src/db/on-loop-write-transaction.ts +0 -34
@@ -1,5 +1,6 @@
1
+ import { claimWorkspaceHumanEscalationAlertAsync } from "./db/runtime-tail-async";
1
2
  import { stewardFallbackTarget } from "./config";
2
- import { claimWorkspaceHumanEscalationAlert } from "./db";
3
+
3
4
  import { routeNotification } from "./notification-router";
4
5
  import { raiseOperatorAlarm } from "./operator-alarm";
5
6
  import { resolveStewardIdentity } from "./steward-identity";
@@ -18,7 +19,7 @@ export interface WorkspaceCustodyEscalationInput {
18
19
  idempotencyKey?: string;
19
20
  }
20
21
 
21
- export function routeWorkspaceCustodyEscalation(input: WorkspaceCustodyEscalationInput): string[] {
22
+ export async function routeWorkspaceCustodyEscalation(input: WorkspaceCustodyEscalationInput): Promise<string[]> {
22
23
  const { ownerAgentId, coordinatorAgentId } = resolveStewardIdentity(input.workspace);
23
24
  const fallback = stewardFallbackTarget();
24
25
  const recipients = [...new Set([ownerAgentId, coordinatorAgentId, fallback].filter((value): value is string => Boolean(value)))];
@@ -31,7 +32,7 @@ export function routeWorkspaceCustodyEscalation(input: WorkspaceCustodyEscalatio
31
32
  // the caller's idempotencyKey (which already bakes in the condition
32
33
  // fingerprint) so an unchanged condition never re-sends, while a real change
33
34
  // (new key) still alerts.
34
- if (input.idempotencyKey && !claimWorkspaceHumanEscalationAlert(input.idempotencyKey)) {
35
+ if (input.idempotencyKey && !(await claimWorkspaceHumanEscalationAlertAsync(input.idempotencyKey))) {
35
36
  const channelId = workspaceHumanEscalationChannelId();
36
37
  return channelId ? [channelId] : [];
37
38
  }
@@ -41,18 +42,18 @@ export function routeWorkspaceCustodyEscalation(input: WorkspaceCustodyEscalatio
41
42
  ownerAgentId,
42
43
  fallbackTarget: fallback || undefined,
43
44
  };
44
- const human = notifyWorkspaceHumanEscalation({
45
+ const human = (await notifyWorkspaceHumanEscalation({
45
46
  subject: input.subject,
46
47
  body: input.body,
47
48
  payload,
48
49
  source: "workspace-custody",
49
- });
50
+ }));
50
51
  if (human.accepted && human.channelId) return [human.channelId];
51
52
  console.warn(`[workspace-escalation] zero agent recipients and no human channel for workspace ${input.workspace.id}: ${human.reason ?? "unknown reason"}`);
52
53
  return [];
53
54
  }
54
55
 
55
- routeNotification({
56
+ await routeNotification({
56
57
  type: input.type ?? "workspace.stranded_escalation",
57
58
  scope: {
58
59
  workspaceId: input.workspace.id,
@@ -84,13 +85,13 @@ export function routeWorkspaceCustodyEscalation(input: WorkspaceCustodyEscalatio
84
85
  // undefined) and most `review_requested` auto-abandons have no agent to page by default,
85
86
  // so without this the notice is swallowed and the strand loops in the dark. Returns the
86
87
  // (possibly empty) recipient list so the caller can still decide whether to stamp state.
87
- export function routeWorkspaceCustodyEscalationOrAlarm(
88
+ export async function routeWorkspaceCustodyEscalationOrAlarm(
88
89
  input: WorkspaceCustodyEscalationInput & { source: string },
89
- ): string[] {
90
+ ): Promise<string[]> {
90
91
  const { source, ...escalation } = input;
91
- const targets = routeWorkspaceCustodyEscalation(escalation);
92
+ const targets = await routeWorkspaceCustodyEscalation(escalation);
92
93
  if (!targets.length) {
93
- raiseOperatorAlarm({
94
+ (await raiseOperatorAlarm({
94
95
  clientId: `${escalation.idempotencyKey ?? `${escalation.workspace.id}:${escalation.subject}`}:no-recipients`,
95
96
  source,
96
97
  subject: escalation.subject,
@@ -101,7 +102,7 @@ export function routeWorkspaceCustodyEscalationOrAlarm(
101
102
  branch: escalation.workspace.branch,
102
103
  status: escalation.workspace.status,
103
104
  },
104
- });
105
+ }));
105
106
  }
106
107
  return targets;
107
108
  }
@@ -43,7 +43,7 @@ export function warnIfNoHumanReachableEscalationTarget(log: (message: string) =>
43
43
  return true;
44
44
  }
45
45
 
46
- export function notifyWorkspaceHumanEscalation(input: WorkspaceHumanEscalationInput): WorkspaceHumanEscalationResult {
46
+ export async function notifyWorkspaceHumanEscalation(input: WorkspaceHumanEscalationInput): Promise<WorkspaceHumanEscalationResult> {
47
47
  const channelId = workspaceHumanEscalationChannelId();
48
48
  if (!channelId) return { accepted: false, reason: "no human escalation channel configured" };
49
49
  if (!getChannel(channelId)) return { accepted: false, reason: `human escalation channel ${channelId} is not registered` };
@@ -59,9 +59,9 @@ export function notifyWorkspaceHumanEscalation(input: WorkspaceHumanEscalationIn
59
59
 
60
60
  try {
61
61
  if (channelId === DEFAULT_NTFY_CHANNEL_ID) {
62
- relayNotifyNtfy(event, input.idempotencyKey);
62
+ (await relayNotifyNtfy(event, input.idempotencyKey));
63
63
  } else {
64
- relayEgressToChannel({ channelId, event }, undefined, input.idempotencyKey);
64
+ (await relayEgressToChannel({ channelId, event }, undefined, input.idempotencyKey));
65
65
  }
66
66
  return { accepted: true, channelId };
67
67
  } catch (error) {
@@ -41,21 +41,21 @@ export async function runLandGateFailureWatchdog(opts: { now?: number; delayMs?:
41
41
  const coordinator = resolveCoordinatorAgentId(owner);
42
42
  const target = coordinator ?? stewardFallbackTarget() ?? owner;
43
43
  if (!target) {
44
- raiseOperatorAlarm({
44
+ (await raiseOperatorAlarm({
45
45
  clientId: `land-gate-failed-unescalatable:${fresh.id}:${failure.notifiedAt}`,
46
46
  source: "workspace-land-gate-watchdog",
47
47
  subject: "Land gate failure has no escalation recipient",
48
48
  detail: `${fresh.branch ?? fresh.id} remains blocked by required gate ${failure.gateName ?? "(unknown)"} with no author, coordinator, or configured fallback.`,
49
49
  view: "orchestrators",
50
50
  metadata: { workspaceId: fresh.id, repoRoot: fresh.repoRoot, branch: fresh.branch, gateName: failure.gateName },
51
- });
51
+ }));
52
52
  await patchWorkspaceMetadataAsync(fresh.id, { landGateFailureEscalatedAt: now });
53
53
  escalated.push(fresh.id);
54
54
  continue;
55
55
  }
56
56
  const targetAgent = getAgent(target);
57
57
  const enabled = notificationEnabledFor("workspace.land_gate_failed", { agentId: target, teamId: targetAgent?.teamId });
58
- routeNotification({
58
+ await routeNotification({
59
59
  type: "workspace.land_gate_failed",
60
60
  scope: { author: owner, parent: coordinator ?? undefined, repoRoot: fresh.repoRoot, workspaceId: fresh.id },
61
61
  recipients: [target],
@@ -0,0 +1,20 @@
1
+ import type { WorkspaceRecord } from "@humwick/sdk";
2
+ import { updateWorkspaceStatusAsync } from "./db";
3
+ import { notifyBranchLandFailed } from "./branch-landed";
4
+ import { deferLandSettleSideEffect } from "./land-settle-dispatch";
5
+ import { landStoppedFact, recordLandStopped } from "./workspace-land-stopped";
6
+
7
+ export class LandConfigurationError extends Error {}
8
+
9
+ /** A new delivery arms a new hand-off; base movement cannot repair a refused configuration (#3824). */
10
+ export function workspaceLandRefused(workspace: WorkspaceRecord): boolean {
11
+ const stop = landStoppedFact(workspace.metadata);
12
+ return stop?.reason === "refused" && stop.handoff === workspace.metadata.landRequestAttemptAt;
13
+ }
14
+
15
+ export async function refuseWorkspaceLand(workspace: WorkspaceRecord, reason: string, commandId?: string): Promise<void> {
16
+ if (workspaceLandRefused(workspace)) return;
17
+ const current = await updateWorkspaceStatusAsync(workspace.id, "review_requested", { mergeError: reason });
18
+ await recordLandStopped(workspace.id, "refused", reason, { final: true });
19
+ deferLandSettleSideEffect("land-refused", () => notifyBranchLandFailed({ workspace: current ?? workspace, commandId, reason }));
20
+ }
@@ -5,6 +5,7 @@ import { getWorkspace, patchWorkspaceMetadataAsync } from "./db";
5
5
  import type { WorkspaceRecord } from "./types";
6
6
 
7
7
  export type LandStopReason =
8
+ | "refused"
8
9
  | "no-progress"
9
10
  | "nothing-to-land"
10
11
  | "retry-exhausted"
@@ -1,3 +1,5 @@
1
+ import { acquireMergeLeaseAsync, releaseMergeLeaseAsync } from "./db/runtime-tail-async";
2
+ import { LandConfigurationError, refuseWorkspaceLand } from "./workspace-land-refusal";
1
3
  import { capturedDeliveryGateRefusal } from "./services/captured-delivery-gate";
2
4
  import { ValidationError } from "./db/connection";
3
5
  import { WORKSPACE_MERGE_HOLD_MESSAGE } from "./db/workspace-merge-hold";
@@ -6,19 +8,7 @@ import { resolve } from "node:path";
6
8
  import { randomUUID } from "node:crypto";
7
9
  import { errMessage, isRecord, stringValue, type LandingContainmentMode } from "@humwick/sdk";
8
10
  import { cancelPendingLegacyLandingsAsync, createLegacyLandingAsync } from "./commands-landing-async";
9
- import {
10
- acquireMergeLease,
11
- exitCertificateMatchesInstance,
12
- getActiveMergePause,
13
- getAgent,
14
- listAgents,
15
- listOrchestrators,
16
- patchWorkspaceMetadataAsync,
17
- releaseMergeLease,
18
- REVIEW_HOLD_REJECT_MESSAGE,
19
- updateWorkspaceStatusAsync,
20
- workspaceLandBarrier,
21
- } from "./db";
11
+ import { exitCertificateMatchesInstance, getActiveMergePause, getAgent, listAgents, listOrchestrators, patchWorkspaceMetadataAsync, REVIEW_HOLD_REJECT_MESSAGE, updateWorkspaceStatusAsync, workspaceLandBarrier } from "./db";
22
12
  import { ensureLegacyOpenLandingOwnershipAsync } from "./db/landing-ingress-async";
23
13
  import { OFFLINE_PRUNE_MS } from "./config";
24
14
  import { getLandingConfig } from "./config-store";
@@ -44,8 +34,6 @@ import type { LandingLaneIdentity } from "./landing-lane-key";
44
34
  import { archiveLandAttempt, CLEAR_LAST_ATTEMPT_VERDICT, CLEAR_MERGE_RETRY, heavyGateQueuePriorityForRetry } from "./workspace-merge-progress";
45
35
  import { coalesceWorkspaceMerge } from "./workspace-merge-dispatch";
46
36
 
47
- // Re-export so consumers can import the tuple from the strategy home without a
48
- // second import hop.
49
37
  export { AUTO_MERGE_POLICIES } from "./types";
50
38
 
51
39
  // One home for the land-strategy contract, shared by BOTH land surfaces — the HTTP
@@ -393,12 +381,7 @@ async function dispatchWorkspaceMerge(workspace: WorkspaceRecord, opts: RequestW
393
381
  // unauthorized one is refused outright instead of being silently ignored.
394
382
  const gate = resolveWorkspaceLandGate(workspace, { level: opts.gateLevel, reason: opts.gateReason, auth: opts.gateAuth });
395
383
  if (!gate.ok) return { ok: false, status: gate.status, error: gate.error };
396
- // #638 — an active merge-pause is the operator's tourniquet for a merge loop on this
397
- // repo. The auto-merge job already honors it (workspace-auto-merge.ts), but gate the
398
- // shared dispatcher too as defense-in-depth: never let an auto-merge-originated request
399
- // acquire the lease + storm while paused, regardless of which caller dispatched it. A
400
- // manual/steward land (any other `requestedBy`) is the intended RECOVERY path during a
401
- // pause, so it's allowed through.
384
+ // #638 — auto-merge honors the repo pause here too; manual/steward lands remain a recovery path.
402
385
  if (!plainGit && opts.requestedBy === "auto-merge" && getActiveMergePause(workspace.repoRoot, workspace.baseRef ?? "main")) {
403
386
  return { ok: false, status: 409, error: `auto-merge paused for ${workspace.repoRoot}` };
404
387
  }
@@ -420,9 +403,10 @@ async function dispatchWorkspaceMerge(workspace: WorkspaceRecord, opts: RequestW
420
403
  let gatePlacement: Awaited<ReturnType<typeof selectLandGateHost>>;
421
404
  try {
422
405
  gatePlacement = await selectLandGateHost(workspace, onlineOwner, laneIdentity.remoteIdentity,
423
- effectiveStrategy !== "pr" && effectiveStrategy !== "auto" && gate.gate.level !== "none" ? laneIdentity.gateRequirements : undefined);
406
+ effectiveStrategy !== "pr" && effectiveStrategy !== "auto" && gate.gate.level !== "none" ? laneIdentity.gateRequirements : undefined, laneIdentity.gateDepsStrategy);
424
407
  } catch (error) {
425
- return { ok: false, status: 409, error: errMessage(error) };
408
+ if (error instanceof LandConfigurationError) await refuseWorkspaceLand(workspace, error.message);
409
+ return { ok: false, status: error instanceof LandConfigurationError ? 422 : 409, error: errMessage(error) };
426
410
  }
427
411
  const gateHost = gatePlacement.orchestrator;
428
412
  const mergeLeaseKey = laneIdentity.remoteIdentity.startsWith("remote:") ? laneIdentity.remoteIdentity : `remote:${laneIdentity.remoteIdentity}`;
@@ -438,7 +422,7 @@ async function dispatchWorkspaceMerge(workspace: WorkspaceRecord, opts: RequestW
438
422
  let leaseAcquired = false;
439
423
  let commandCreated = false;
440
424
  if (!plainGit || gatePlacement.delegated) {
441
- const lease = acquireMergeLease(mergeLeaseKey, workspace.id, opts.requestedBy);
425
+ const lease = (await acquireMergeLeaseAsync(mergeLeaseKey, workspace.id, opts.requestedBy));
442
426
  if (!lease.ok) {
443
427
  if (containmentMode === "cgroup-v2-close-v1") {
444
428
  await cleanupLegacyLandingReservationOnHost(gateHost, executionTreeHandle!).catch(() => false);
@@ -493,7 +477,7 @@ async function dispatchWorkspaceMerge(workspace: WorkspaceRecord, opts: RequestW
493
477
  lastWorkspaceActionAt: armAt,
494
478
  });
495
479
  if (!updated) {
496
- if (leaseAcquired) releaseMergeLease({ repoRoot: mergeLeaseKey, workspaceId: workspace.id });
480
+ if (leaseAcquired) (await releaseMergeLeaseAsync({ repoRoot: mergeLeaseKey, workspaceId: workspace.id }));
497
481
  if (containmentMode === "cgroup-v2-close-v1") {
498
482
  await cleanupLegacyLandingReservationOnHost(gateHost, executionTreeHandle!).catch(() => false);
499
483
  }
@@ -604,7 +588,7 @@ async function dispatchWorkspaceMerge(workspace: WorkspaceRecord, opts: RequestW
604
588
  } catch (e) {
605
589
  // Acquired the lease but failed before dispatch — release it or the repo
606
590
  // stays blocked until the TTL expires.
607
- if (!commandCreated && leaseAcquired) releaseMergeLease({ repoRoot: mergeLeaseKey, workspaceId: workspace.id });
591
+ if (!commandCreated && leaseAcquired) (await releaseMergeLeaseAsync({ repoRoot: mergeLeaseKey, workspaceId: workspace.id }));
608
592
  if (!commandCreated && containmentMode === "cgroup-v2-close-v1") {
609
593
  await cleanupLegacyLandingReservationOnHost(gateHost, executionTreeHandle!).catch(() => false);
610
594
  }
@@ -6,14 +6,14 @@ import { withWorkspaceTaskOwnerRoles } from "./task-owner-notices";
6
6
  import { resolveLandedTaskIds } from "./services/landed-task-attribution";
7
7
  import type { WorkspaceRecord } from "./types";
8
8
 
9
- export function notifyNothingToLand(workspace: WorkspaceRecord, sha: string, commandId: string, sourceHeadSha?: string): void {
9
+ export async function notifyNothingToLand(workspace: WorkspaceRecord, sha: string, commandId: string, sourceHeadSha?: string): Promise<void> {
10
10
  const author = workspace.ownerAgentId;
11
11
  const coordinator = resolveCoordinatorAgentId(author);
12
12
  const taskOwners = resolveLandedTaskIds({ workspace, sourceHeadSha }).map(id => resolveTaskOwnerAgentId(getTaskDetail(id)));
13
13
  const recipients = withWorkspaceTaskOwnerRoles([author, coordinator, ...taskOwners], workspace);
14
14
  if (!recipients.length) return;
15
15
  const base = workspace.baseRef ?? "base";
16
- routeNotification({
16
+ await routeNotification({
17
17
  type: "branch.landed",
18
18
  scope: { author, parent: coordinator ?? undefined, repoRoot: workspace.repoRoot, workspaceId: workspace.id },
19
19
  recipients, forceDelivery: true, ttlMs: null,
@@ -1,3 +1,6 @@
1
+ import { pruneWorkspaceOrphanAlertsAsync, pruneStaleWorkspaceHumanEscalationAlertsAsync, claimWorkspaceOrphanAlertAsync } from "./db/runtime-tail-async";
2
+ import { dispatchOrphanCleanup } from "./workspace-cleanup-stale";
3
+ import { emitCommandEvent } from "./command-events";
1
4
  // Orphaned-worktree reconciliation (#244). An isolated worktree on disk with no
2
5
  // live DB row is "orphaned" — left behind when a session ended without a clean
3
6
  // teardown (crash, killed runner, a reaped row). Symmetrically, a live row whose
@@ -20,8 +23,8 @@
20
23
 
21
24
  import { resolve } from "node:path";
22
25
  import type { WorkspaceMergePreview, WorkspaceOrphan, WorkspaceProbe, WorkspaceProbeWorktree, WorkspaceRecord, WorkspaceStatus } from "./types";
23
- import { claimWorkspaceOrphanAlert, createActivityEventAsync, getWorkspace, listOrchestrators, listWorkspaces, pruneStaleWorkspaceHumanEscalationAlerts, pruneWorkspaceOrphanAlerts, updateWorkspaceStatusAsync } from "./db";
24
- import { createCommand } from "./commands-db";
26
+ import { createActivityEventAsync, getWorkspace, listOrchestrators, listWorkspaces, updateWorkspaceStatusAsync } from "./db";
27
+
25
28
  import { isPathWithinBase } from "./utils";
26
29
  import { IN_FLIGHT_WORKSPACE_STATUSES, TERMINAL_WORKSPACE_STATUSES, worktreeReapable, type WorktreeReapState } from "./workspace-phase";
27
30
  import { isOwnerAlive, isOwnerProcessConfirmedGone, liveAgentCwds, worktreeInUseByLiveAgent } from "./workspace-merge";
@@ -33,7 +36,6 @@ import { READY_TO_LAND_ESCALATION_STATUSES, routeWorkspaceCustodyEscalationOrAla
33
36
  import { workspaceLandBlocked } from "./land-block";
34
37
  import { dispatchDeadOwnerRescue } from "./workspace-dead-owner-recovery";
35
38
  import { runWithConcurrency, sortLeastRecentlyProbed } from "./maintenance/workspaces";
36
- import { emitCommandEvent } from "./command-events";
37
39
  import {
38
40
  WORKSPACE_ORPHAN_REAPER_DEAD_OWNER_PROBE_BATCH_SIZE,
39
41
  WORKSPACE_ORPHAN_REAPER_MISSING_PROBE_BATCH_SIZE,
@@ -421,27 +423,6 @@ export async function collectWorkspaceOrphans(
421
423
  return { orphans, missingWorktrees, deadOwnerWorkspaces, ...(moreOrphanEnrichmentWork ? { moreOrphanEnrichmentWork } : {}) };
422
424
  }
423
425
 
424
- function dispatchCleanup(orch: OnlineOrchestrator, orphan: WorkspaceOrphan): string {
425
- const command = createCommand({
426
- type: "workspace.cleanup",
427
- source: "system",
428
- target: orch.agentId,
429
- params: {
430
- action: "cleanup",
431
- worktreePath: orphan.worktreePath,
432
- repoRoot: orphan.repoRoot,
433
- branch: orphan.branch,
434
- baseRef: orphan.baseRef,
435
- baseSha: orphan.baseSha,
436
- deleteBranch: true,
437
- reclaim: true,
438
- requestedBy: "workspace-orphan-reaper",
439
- requestedAt: Date.now(),
440
- },
441
- });
442
- emitCommandEvent(command, `command.${command.status}`);
443
- return command.id;
444
- }
445
426
 
446
427
  /**
447
428
  * Scheduled reaper (maintenance job). Auto-removes orphaned worktrees that are
@@ -520,7 +501,7 @@ export async function reapOrphanedWorktrees(context: { signal?: AbortSignal } =
520
501
  if (!reapEnabled) continue; // detect-only mode
521
502
  if (nonTerminalRowsByPath.has(resolve(orphan.worktreePath))) continue; // still claimed — never reap (#278)
522
503
  if (worktreeInUseByLiveAgent(orphan.worktreePath, liveCwds)) continue; // a live agent runs in it — never reap its cwd
523
- const commandId = dispatchCleanup(orch, orphan);
504
+ const commandId = (await dispatchOrphanCleanup(orch.agentId, orphan));
524
505
  reaped.push(orphan.worktreePath);
525
506
  await createActivityEventAsync({
526
507
  clientId: `workspace-orphan-reaped-${orphan.worktreePath}-${now}`,
@@ -541,7 +522,7 @@ export async function reapOrphanedWorktrees(context: { signal?: AbortSignal } =
541
522
  const alertKey = `disk:${resolve(orphan.worktreePath)}`;
542
523
  liveAlertKeys.add(alertKey);
543
524
  const fingerprint = orphanAlertFingerprint({ headSha: orphan.headSha, ahead: orphan.ahead, unmergedAhead: orphan.unmergedAhead, dirty: orphan.dirty, safeToReap: orphan.safeToReap });
544
- if (!claimWorkspaceOrphanAlert(alertKey, fingerprint, now)) continue;
525
+ if (!(await claimWorkspaceOrphanAlertAsync(alertKey, fingerprint, now))) continue;
545
526
  flagged.push(orphan.worktreePath);
546
527
  const detail = orphan.safeToReap === undefined
547
528
  ? "host could not be probed for land-state"
@@ -549,7 +530,7 @@ export async function reapOrphanedWorktrees(context: { signal?: AbortSignal } =
549
530
  ? "uncommitted changes in the worktree"
550
531
  : `${orphan.unmergedAhead ?? orphan.ahead ?? "?"} un-landed commit(s)`;
551
532
  if (orphanHasWorkEvidence(orphan)) {
552
- routeWorkspaceCustodyEscalationOrAlarm({
533
+ await routeWorkspaceCustodyEscalationOrAlarm({
553
534
  source: "workspace-orphan-reaper",
554
535
  workspace: { id: `orphan:${orphan.worktreePath}`, repoRoot: orphan.repoRoot, branch: orphan.branch, status: "review_requested", ownerAgentId: undefined },
555
536
  subject: "Stranded worktree needs attention",
@@ -586,9 +567,9 @@ export async function reapOrphanedWorktrees(context: { signal?: AbortSignal } =
586
567
  const inFlight = IN_FLIGHT_WORKSPACE_STATUSES.has(workspace.status);
587
568
  if (ownerAlive || inFlight) {
588
569
  liveAlertKeys.add(key);
589
- if (!claimWorkspaceOrphanAlert(key, orphanAlertFingerprint({ status: workspace.status, ownerAlive, inFlight }), now)) continue;
570
+ if (!(await claimWorkspaceOrphanAlertAsync(key, orphanAlertFingerprint({ status: workspace.status, ownerAlive, inFlight }), now))) continue;
590
571
  if (workspaceNeedsCustodyEscalation(workspace, false)) {
591
- routeWorkspaceCustodyEscalationOrAlarm({
572
+ await routeWorkspaceCustodyEscalationOrAlarm({
592
573
  source: "workspace-orphan-reaper",
593
574
  workspace,
594
575
  subject: "Workspace row has no worktree on disk",
@@ -658,7 +639,7 @@ export async function reapOrphanedWorktrees(context: { signal?: AbortSignal } =
658
639
  if (!updated) continue;
659
640
  autoAbandoned.push(workspace.id);
660
641
  if (workspaceNeedsCustodyEscalation(workspace, previewHasWorkEvidence(probe.kind === "preview" ? probe.preview : null))) {
661
- routeWorkspaceCustodyEscalationOrAlarm({
642
+ await routeWorkspaceCustodyEscalationOrAlarm({
662
643
  source: "workspace-orphan-reaper",
663
644
  workspace,
664
645
  type: "workspace.auto_abandoned",
@@ -690,7 +671,7 @@ export async function reapOrphanedWorktrees(context: { signal?: AbortSignal } =
690
671
 
691
672
  liveAlertKeys.add(key);
692
673
  const missingFingerprint = orphanAlertFingerprint({ status: workspace.status, probe: probe.kind, recoverableTip: probe.kind === "preview" ? probe.preview.recoverableTip : undefined, headSha: probe.kind === "preview" ? probe.preview.headSha : undefined, ahead: probe.kind === "preview" ? probe.preview.ahead : undefined, unmergedAhead: probe.kind === "preview" ? probe.preview.unmergedAhead : undefined });
693
- if (!claimWorkspaceOrphanAlert(key, missingFingerprint, now)) continue;
674
+ if (!(await claimWorkspaceOrphanAlertAsync(key, missingFingerprint, now))) continue;
694
675
  flaggedMissingWorktrees.push(workspace.id);
695
676
  const hasWorkEvidence = probe.kind === "preview" && previewHasWorkEvidence(probe.preview);
696
677
  const detail = probe.kind === "preview"
@@ -701,7 +682,7 @@ export async function reapOrphanedWorktrees(context: { signal?: AbortSignal } =
701
682
  ? `host could not confirm whether branch ${workspace.branch} has landed`
702
683
  : "host could not confirm whether recoverable branch work remains";
703
684
  if (workspaceNeedsCustodyEscalation(workspace, hasWorkEvidence)) {
704
- routeWorkspaceCustodyEscalationOrAlarm({
685
+ await routeWorkspaceCustodyEscalationOrAlarm({
705
686
  source: "workspace-orphan-reaper",
706
687
  workspace,
707
688
  subject: "Missing-worktree workspace needs attention",
@@ -846,10 +827,10 @@ export async function reapOrphanedWorktrees(context: { signal?: AbortSignal } =
846
827
  liveDeadOwnerKeys.add(flagKey);
847
828
  liveAlertKeys.add(flagKey);
848
829
  const deadOwnerFingerprint = orphanAlertFingerprint({ status: workspace.status, headSha: preview?.headSha, ahead: preview?.ahead, unmergedAhead: preview?.unmergedAhead, dirtyCount: preview?.dirtyCount, probeAvailable: Boolean(preview) });
849
- if (!claimWorkspaceOrphanAlert(flagKey, deadOwnerFingerprint, now)) continue;
830
+ if (!(await claimWorkspaceOrphanAlertAsync(flagKey, deadOwnerFingerprint, now))) continue;
850
831
  deadOwnerFlagged.push(workspace.id);
851
832
  const rescueCommandId = preview?.originCaptureChecked === true && preview.originCaptured === false && orch
852
- ? dispatchDeadOwnerRescue(orch, workspace)
833
+ ? (await dispatchDeadOwnerRescue(orch, workspace))
853
834
  : undefined;
854
835
  const detail = safeToReap === undefined
855
836
  ? "host could not be probed for land-state"
@@ -858,7 +839,7 @@ export async function reapOrphanedWorktrees(context: { signal?: AbortSignal } =
858
839
  : `${preview?.unmergedAhead ?? preview?.ahead ?? "?"} un-landed commit(s)`;
859
840
  const hasWorkEvidence = previewHasWorkEvidence(preview);
860
841
  if (workspaceNeedsCustodyEscalation(workspace, hasWorkEvidence)) {
861
- routeWorkspaceCustodyEscalationOrAlarm({
842
+ await routeWorkspaceCustodyEscalationOrAlarm({
862
843
  source: "workspace-orphan-reaper",
863
844
  workspace,
864
845
  subject: "Dead-owner worktree needs attention",
@@ -896,8 +877,8 @@ export async function reapOrphanedWorktrees(context: { signal?: AbortSignal } =
896
877
  // still waiting it out and re-fire orphan alerts already claimed for this condition.
897
878
  if (!signal?.aborted) {
898
879
  for (const key of deadOwnerTracker.keys()) if (!liveDeadOwnerKeys.has(key)) deadOwnerTracker.delete(key);
899
- pruneWorkspaceOrphanAlerts(liveAlertKeys);
900
- pruneStaleWorkspaceHumanEscalationAlerts(now, HUMAN_ESCALATION_ALERT_MAX_AGE_MS);
880
+ (await pruneWorkspaceOrphanAlertsAsync(liveAlertKeys));
881
+ (await pruneStaleWorkspaceHumanEscalationAlertsAsync(now, HUMAN_ESCALATION_ALERT_MAX_AGE_MS));
901
882
  }
902
883
 
903
884
  // #2408 — true whenever ANY of the three per-tick probe budgets left candidates un-probed this run.
@@ -1,6 +1,8 @@
1
+ import { createActivityEventAsync } from "./db/activity-async";
2
+ import { createCommandAsync } from "./commands-write";
1
3
  import { isRecord } from "@humwick/sdk";
2
- import { createCommand, getCommand } from "./commands-db";
3
- import { createActivityEvent, patchWorkspaceMetadataAsync, workspaceLandBarrier } from "./db";
4
+ import { getCommand } from "./commands-db";
5
+ import { patchWorkspaceMetadataAsync, workspaceLandBarrier } from "./db";
4
6
  import { handleReviewerPipelineScan, isAwaitingReviewerApproval } from "./reviewer-pipeline";
5
7
  import { isOwnerAlive, requestWorkspaceMerge } from "./workspace-merge";
6
8
  import type { Command, WorkspaceAutoMergePolicy, WorkspaceMergePreview, WorkspaceRecord } from "./types";
@@ -39,7 +41,7 @@ export async function reconcileLandedPr(workspace: WorkspaceRecord, preview: Wor
39
41
  },
40
42
  });
41
43
  if (recycle.ok) {
42
- createActivityEvent({
44
+ (await createActivityEventAsync({
43
45
  clientId: `workspace-pr-recycle-${workspace.id}-${Date.now()}`,
44
46
  kind: "state",
45
47
  title: "Workspace recycling after PR land",
@@ -48,7 +50,7 @@ export async function reconcileLandedPr(workspace: WorkspaceRecord, preview: Wor
48
50
  icon: "ti-git-merge",
49
51
  view: "orchestrators",
50
52
  metadata: { source: "server", maintenanceJobId: "workspace-conflict-scan", workspaceId: workspace.id, commandId: recycle.command.id, landedVia: "pr" },
51
- });
53
+ }));
52
54
  return { kind: "recycle", command: recycle.command };
53
55
  }
54
56
  // 409 = lease held by an in-flight merge — retry next sweep, don't finalize (re-strands a
@@ -199,7 +201,7 @@ async function dispatchRelayPrMergeCommand(workspace: WorkspaceRecord, preview:
199
201
  const now = Date.now();
200
202
  const prNumber = preview.prNumber ?? (typeof workspace.metadata.prNumber === "number" ? workspace.metadata.prNumber : undefined);
201
203
  const prUrl = preview.prUrl ?? text(workspace.metadata.prUrl);
202
- const command = createCommand({
204
+ const command = (await createCommandAsync({
203
205
  type: "workspace.pr-merge",
204
206
  source: "system",
205
207
  target: orchestratorAgentId,
@@ -209,7 +211,7 @@ async function dispatchRelayPrMergeCommand(workspace: WorkspaceRecord, preview:
209
211
  branch: workspace.branch, baseRef: workspace.baseRef, prNumber, prUrl, policy,
210
212
  requestedBy: "relay-pr-completion", requestedAt: now,
211
213
  },
212
- });
214
+ }));
213
215
  await patchWorkspaceMetadataAsync(workspace.id, {
214
216
  relayMerged: true, relayMergeCommandId: command.id, relayMergeDispatchedAt: now, relayMergePolicy: policy,
215
217
  relayMergeError: undefined, relayMergeFailedAt: undefined,
@@ -221,7 +223,7 @@ async function dispatchRelayPrRefreshCommand(workspace: WorkspaceRecord, preview
221
223
  const now = Date.now();
222
224
  const prNumber = preview.prNumber ?? (typeof workspace.metadata.prNumber === "number" ? workspace.metadata.prNumber : undefined);
223
225
  const prUrl = preview.prUrl ?? text(workspace.metadata.prUrl);
224
- const command = createCommand({
226
+ const command = (await createCommandAsync({
225
227
  type: "workspace.pr-refresh",
226
228
  source: "system",
227
229
  target: orchestratorAgentId,
@@ -231,7 +233,7 @@ async function dispatchRelayPrRefreshCommand(workspace: WorkspaceRecord, preview
231
233
  branch: workspace.branch, baseRef: workspace.baseRef, prNumber, prUrl, policy, refreshKey, attempts,
232
234
  requestedBy: "relay-pr-completion", requestedAt: now,
233
235
  },
234
- });
236
+ }));
235
237
  await patchWorkspaceMetadataAsync(workspace.id, {
236
238
  prRefreshCommandId: command.id, prRefreshDispatchedAt: now, prRefreshPolicy: policy, prRefreshPrNumber: prNumber,
237
239
  prRefreshKey: refreshKey, prRefreshAttempts: attempts, prRefreshError: undefined, prRefreshFailedAt: undefined,
@@ -55,7 +55,7 @@ export function fenceWorkspaceRekeyCommand(commandId: string): Promise<{ fenced:
55
55
  export async function drainStewardRekeyNotices(): Promise<void> {
56
56
  for (const row of pendingStewardRekeyNotices()) {
57
57
  try {
58
- const routed = notifyTaskCoordinatorOfRekey(row);
58
+ const routed = await notifyTaskCoordinatorOfRekey(row);
59
59
  if (routed) await getGateway().write("workspaceRekey.noticeSent", { eventId: row.id });
60
60
  } catch (error) {
61
61
  console.warn(`[steward-rekey] notice for task event ${row.id} failed; retrying later: ${error}`);
@@ -63,7 +63,7 @@ export async function drainStewardRekeyNotices(): Promise<void> {
63
63
  }
64
64
  }
65
65
 
66
- function notifyTaskCoordinatorOfRekey(row: StewardRekeyNoticeRow): boolean {
66
+ async function notifyTaskCoordinatorOfRekey(row: StewardRekeyNoticeRow): Promise<boolean> {
67
67
  const task = getTaskDetail(row.task_id);
68
68
  if (!task) return false;
69
69
  const m = parseJson<Record<string, unknown>>(row.metadata, {});
@@ -82,7 +82,7 @@ function notifyTaskCoordinatorOfRekey(row: StewardRekeyNoticeRow): boolean {
82
82
  ...(rewritten.length ? [`${rewritten.length} commit(s) changed patch identity`] : []),
83
83
  ...(merges.length ? [`${merges.length} merge commit(s) were re-resolved and cannot be verified by patch-id`] : []),
84
84
  ];
85
- const delivered = routeNotification({
85
+ const delivered = await routeNotification({
86
86
  type: "task.steward_rekey",
87
87
  scope: {
88
88
  taskId: String(task.id), transition: "steward-rekey", workspaceId,
@@ -30,13 +30,13 @@ export async function recordStewardWakeFailure(workspace: WorkspaceRecord, error
30
30
  const body = `Workspace \`${ws.id}\` (\`${ws.branch ?? ws.id}\` → \`${ws.baseRef ?? "base"}\`): ${error}. Relay will retry after ${Math.ceil(STEWARD_HANDOFF_WATCHDOG_MS / 60_000)} minutes. ${stewardRecoveryAdvice(ws.baseRef ?? "main", capExhausted)}`;
31
31
  const payload = { kind: "workspace.steward-spawn-failed", workspaceId: ws.id, branch: ws.branch, reason: error };
32
32
  if (recipients.length) {
33
- routeNotification({
33
+ await routeNotification({
34
34
  type: "workspace.stranded_escalation", forceDelivery: true, ttlMs: null,
35
35
  scope: { workspaceId: ws.id, repoRoot: ws.repoRoot, author: ownerAgentId, parent: coordinatorAgentId ?? undefined },
36
36
  recipients, message: { subject, body, payload, idempotencyKey: `steward-spawn-failed:${ws.id}:${failureId}` },
37
37
  });
38
38
  } else {
39
- raiseOperatorAlarm({ clientId: `steward-spawn-failed:${ws.id}:${failureId}`, source: "workspace-steward-failure", subject, detail: body, dedupeEvent: true, metadata: payload });
39
+ (await raiseOperatorAlarm({ clientId: `steward-spawn-failed:${ws.id}:${failureId}`, source: "workspace-steward-failure", subject, detail: body, dedupeEvent: true, metadata: payload }));
40
40
  }
41
41
  await patchWorkspaceMetadataAsync(ws.id, { stewardWakeFailureNotifiedAt: now });
42
42
  }
@@ -92,7 +92,7 @@ export async function wakeRepoSteward(ws: WorkspaceRecord, reason: string, opts:
92
92
  stewardHandoffEscalatedAt: undefined, stewardRewakeCount: undefined,
93
93
  } : {}),
94
94
  });
95
- routeNotification({
95
+ await routeNotification({
96
96
  type: "workspace.steward_task",
97
97
  scope: { workspaceId: ws.id, repoRoot: ws.repoRoot, author: ownerAgentId, parent: coordinatorAgentId ?? undefined },
98
98
  recipients: [`policy:${policyName}`],
@@ -139,7 +139,7 @@ export async function wakeRepoSteward(ws: WorkspaceRecord, reason: string, opts:
139
139
  }, attempt < STEWARD_WAKE_STAMP_ATTEMPTS ? current : undefined);
140
140
  if (!stamped) continue;
141
141
  if (current.landState === "merge-error") await transitionWorkspaceLandStateAsync(ws.id, "steward-requested");
142
- notifyStewardHandoff({ workspace: ws, stewardId: policyName, coordinatorAgentId, reason });
142
+ await notifyStewardHandoff({ workspace: ws, stewardId: policyName, coordinatorAgentId, reason });
143
143
  return { ok: true, policy: policyName };
144
144
  }
145
145
  } catch (e) {
@@ -1,2 +0,0 @@
1
- import{T as e}from"./display-BrKWFGJz.js";function t(t,n){return!!n&&n.status!==`offline`&&!e(t,n)}export{t};
2
- //# sourceMappingURL=agent-liveness-CaNwK0Zf.js.map
@@ -1,2 +0,0 @@
1
- function e(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function t(e){if(typeof e!=`string`)return;let t=e.trim();return t.length>0?t:void 0}function n(e){return e instanceof Error?e.message:String(e)}var r=`provider-enablement`,i=`default`,a=`user`;function o(e){return`user:${e}`}var s=o(`claude-app`);function c(e){return e===`user`||typeof e==`string`&&e.startsWith(`user:`)}function ee(e){if(e===`user`)return i;if(typeof e==`string`&&e.startsWith(`user:`))return e.slice(5)||`default`}function te(e){return e===`user`||e===o(`default`)||e===`user:`?a:e}var ne=[`system`,`control`,`session`];function re(e){return ne.includes(e??``)}var ie=[`memory`,`memory-area`,`instructions`,`tools`,`comms`,`knowledge`,`context`];function ae(e){return typeof e==`string`&&ie.includes(e)}function oe(t){return e(t)&&(t.turnFinal===!0||t.final===!0)}function l(t){return e(t)&&e(t.finality)}function se(t){if(!e(t))return!1;if(l(t))return!0;let n=t.session;return e(n)&&n.final===!0&&n.turnFinal!==!0}function u(t){if(t.messageType===`final-turn`)return!0;let n=e(t.payload?.responseCapture)?t.payload.responseCapture:void 0;return oe(n)&&n.type===`response`}var d=[`decisions`,`actions`,`escalations`,`finalReports`,`failures`];Object.freeze({decisions:`all`,actions:`all`,escalations:`all`,finalReports:`all`,failures:`all`});var ce=/^[a-z][a-z0-9-]*$/,f=new Map,p=[`CLAUDE_CODE_OAUTH_TOKEN`,`ANTHROPIC_API_KEY`,`ANTHROPIC_AUTH_TOKEN`];function m(e){if(!ce.test(e.id))throw Error(`invalid provider id: ${e.id}`);if(!e.label.trim())throw Error(`provider ${e.id} is missing a label`);if(!e.icon.trim())throw Error(`provider ${e.id} is missing an icon`);if(f.has(e.id))throw Error(`provider already registered: ${e.id}`);f.set(e.id,e)}function h(e){return f.get(e)}function g(){return[...f.values()]}function le(e,t){let n=f.get(e)?.capabilityDefaults.session?.shellMode,r=t===`read-only`?n?.readOnly:n?.[t];return!!(r&&r!==`unsupported`)}function _(e){return[`open`,`guarded`,`read-only`].filter(t=>le(e,t))}var v=[`low`,`medium`,`high`,`max`],y=[`low`,`medium`,`high`,`xhigh`,`max`],b={value:2e5,source:`catalog`,confidence:`declared`},x={value:1e6,source:`catalog`,confidence:`declared`},ue={modalities:{input:{text:!0,image:!0},output:{text:!0}},tools:{code:!0,review:!0,debug:!0,refactor:!0},source:`catalog`,confidence:`declared`},S=[{name:`five_hour`,unit:`%`,reset:!0},{name:`seven_day`,unit:`%`,reset:!0}];function C(e){return{...e?{limits:e}:{},capabilities:ue}}var w={id:`claude`,credentialEnvKeys:p,label:`Claude`,icon:`🟠`,launchModes:[`interactive`,`headless`],effortSwitch:!0,launch:{managedPolicyPrompt:{alwaysOn:`append-system-prompt`},taskHydration:{channel:`append-system-prompt`}},catalog:{defaultModel:`sonnet`,models:[{alias:`haiku-5.5`,label:`Haiku 5.5`,providerModel:`claude-haiku-5-5`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:x})},{alias:`opus-5.5`,label:`Opus 5.5`,providerModel:`claude-opus-5-5`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:x})},{alias:`sonnet-5.5`,label:`Sonnet 5.5`,providerModel:`claude-sonnet-5-5`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:x})},{alias:`fable-5.1`,label:`Fable 5.1`,providerModel:`claude-fable-5-1`,efforts:y,defaultEffort:`high`,...C({contextWindowTokens:x})},{alias:`fable-5`,label:`Fable 5`,providerModel:`claude-fable-5`,efforts:y,defaultEffort:`medium`,unavailable:`suspended by export-control directive, 2026-06-12`,...C({contextWindowTokens:x})},{alias:`opus-4.8`,label:`Opus 4.8`,providerModel:`claude-opus-4-8`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:b})},{alias:`opus-4.8[1m]`,label:`Opus 4.8 1M`,providerModel:`claude-opus-4-8[1m]`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:x})},{alias:`opus-4.7`,label:`Opus 4.7`,providerModel:`claude-opus-4-7`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:b})},{alias:`opus-4.7[1m]`,label:`Opus 4.7 1M`,providerModel:`claude-opus-4-7[1m]`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:x})},{alias:`opus-4.6`,label:`Opus 4.6`,providerModel:`claude-opus-4-6`,efforts:v,defaultEffort:`medium`,...C({contextWindowTokens:b})},{alias:`opus-4.6[1m]`,label:`Opus 4.6 1M`,providerModel:`claude-opus-4-6[1m]`,efforts:v,defaultEffort:`medium`,...C({contextWindowTokens:x})},{alias:`sonnet-5`,label:`Sonnet 5`,providerModel:`claude-sonnet-5`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:b})},{alias:`sonnet-5[1m]`,label:`Sonnet 5 1M`,providerModel:`claude-sonnet-5[1m]`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:x})},{alias:`haiku`,label:`Haiku`,providerModel:`claude-haiku-5-5`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:x})},{alias:`fable`,label:`Fable`,providerModel:`claude-fable-5-1`,efforts:y,defaultEffort:`high`,...C({contextWindowTokens:x})},{alias:`opus`,label:`Opus`,providerModel:`claude-opus-5-5`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:x})},{alias:`opus[1m]`,label:`Opus 1M`,providerModel:`claude-opus-5-5`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:x})},{alias:`sonnet`,label:`Sonnet`,providerModel:`claude-sonnet-5-5`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:x})},{alias:`sonnet[1m]`,label:`Sonnet 1M`,providerModel:`claude-sonnet-5-5`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:x})}]},quotaWindows:[...S],capabilityDefaults:{lifecycle:{managed:!0,shutdownHard:{when:`headless`,value:!0,otherwise:!1},restartHard:{when:`headless`,value:!0,otherwise:!1},semanticStatus:!0,reconnect:!0},session:{fileRead:!0,fileWrite:{when:`approval:not-read-only`,value:!0,otherwise:!1},shell:!0,shellMode:{open:`unrestricted`,guarded:`guarded`,readOnly:`read-only-guarded`}},context:{managed:`headless`,compact:{when:`headless`,value:!0,otherwise:!1},clear:{when:`headless`,value:!0,otherwise:!1},inject:!0,resumePreference:[`native`,`clear-inject`,`none`]},quota:{supported:!0,source:`probe`,unit:`%`,windows:[...S]},terminal:{mode:`live`,condition:`headless`,live:{read:!0,write:!0}},liveSession:{capture:!0,inject:!0,interrupt:!0,promptEcho:!0,reasoning:!0,slashCommands:!0}},slashCommands:[`/clear`,`/compact`,`/model`,`/help`],resume:{supported:!0,idFormat:`uuid-v4`,idPattern:`[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}`},home:{configDir:`.claude`,envPrefix:`CLAUDE`,configDirEnvVar:`CLAUDE_CONFIG_DIR`,quotaCredentialFile:`.credentials.json`,authItems:[`.credentials.json`,`statsig`],globalInstructionFiles:[`CLAUDE.md`]},provisioning:{pluginManifestPath:`.claude-plugin/plugin.json`,bundledPlugin:{ref:`agent-relay-claude-plugin`,dir:`runner/plugins/claude`,title:`Humwick Claude plugin`,description:`Bundled Humwick Claude plugin, materialized whole through the provisioning registry.`,omitFiles:[`monitors/relay-monitor.provisioned.mjs`,`hooks/gate-run-guard.provisioned.mjs`,`hooks/kill-guard.provisioned.mjs`],fileOverrides:[{path:`monitors/relay-monitor.ts`,sourcePath:`monitors/relay-monitor.provisioned.mjs`},{path:`hooks/gate-run-guard.ts`,sourcePath:`hooks/gate-run-guard.provisioned.mjs`},{path:`hooks/kill-guard.ts`,sourcePath:`hooks/kill-guard.provisioned.mjs`}]},bundledHooks:[{ref:`agent-relay-rg-r-guard`,dir:`runner/hooks/rg-r-guard`,title:`Humwick baseline hook: rg -r guard`,description:"Baseline Humwick PreToolUse hook that blocks the ripgrep `rg -r` replace footgun.",baseline:!0},{ref:`agent-relay-fff-search-redirect`,dir:`runner/hooks/fff-search-redirect`,title:`Humwick fff search redirect`,description:`Redirects standalone repository searches to fff for Claude profiles with a configured fff MCP server.`,omitFiles:[`fff-search-redirect.test.ts`]},{ref:`agent-relay-web-tools-redirect`,dir:`runner/hooks/web-tools-redirect`,title:`Humwick web tools redirect`,description:`Redirects built-in WebSearch/WebFetch to the profile's Relay web_search and local-first page reader tools (#3024).`,omitFiles:[`web-tools-redirect.test.ts`]}]},upgrade:{packages:[`agent-relay-runner`,`agent-relay-plugin`],detectPackages:[`agent-relay-runner`],detectCommands:[`claude`]},harness:{upgrade:{strategy:`self-update`,args:[`update`]}},probe:{command:`claude`,args:[`--version`],healthCheck:`claude --version`,featureChecks:[{name:`rig`,command:`claude-rig`,homeDir:`.claude-rig`}],authCheck:{command:`claude`,args:[`auth`,`status`,`--json`],loginArgs:[`auth`,`login`]}},quotaPoll:{strategy:`none`},shim:{kind:`claude-relay`},mcpToolManifest:{clientNativeToolDeferral:!0,runnerManagedToolDeferral:!1}};m(w),m({...w,id:`claude-b`,label:`Claude B`,home:{...w.home,configDir:`.claude-b`,dedicatedHome:!0}}),m({...w,id:`claude-api`,label:`Claude API`,automaticFamilyRouting:!1,defaultEnabled:!1,resume:{supported:!1},credentialEnvKeys:[`ANTHROPIC_API_KEY`],apiAuth:{keyPrefix:`sk-ant-`,keyEnvVar:`ANTHROPIC_API_KEY`,defaultKeyFile:`~/.config/agent-relay/secrets/anthropic-api.key`,unsetEnvKeys:[...p,`ANTHROPIC_BASE_URL`,`CLAUDE_CODE_USE_BEDROCK`,`CLAUDE_CODE_USE_VERTEX`,`CLAUDE_CODE_USE_FOUNDRY`,`ANTHROPIC_CUSTOM_HEADERS`,`CLAUDE_CODE_API_KEY_HELPER_TTL_MS`]},home:{...w.home,configDir:`.claude-api`,sourceEnvVar:`CLAUDE_API_CONFIG_DIR`,dedicatedHome:!0,authItems:[]},launchModes:void 0,quotaWindows:[],capabilityDefaults:{...w.capabilityDefaults,quota:{supported:!1,source:`runtime`,unit:`USD`,windows:[]}}});var T=[`low`,`medium`,`high`,`xhigh`],E={value:2e5,source:`catalog`,confidence:`declared`},D={value:5e5,source:`catalog`,confidence:`declared`},de={modalities:{input:{text:!0,image:!0},output:{text:!0}},tools:{code:!0,review:!0,debug:!0,refactor:!0},source:`catalog`,confidence:`declared`},O=[{name:`primary`,unit:`%`,reset:!0},{name:`secondary`,unit:`%`,reset:!0}];function k(e){return{...e?{limits:e}:{},capabilities:de}}m({id:`codex`,credentialEnvKeys:[`OPENAI_API_KEY`],label:`Codex`,icon:`⌨️`,launchModes:[`interactive`,`headless`],launch:{secretEnvRequiresManagedHome:!0,managedPolicyPrompt:{alwaysOn:`prompt`},taskHydration:{channel:`prompt`}},catalog:{defaultModel:`sol`,models:[{alias:`sol`,label:`GPT-6.1 Sol`,providerModel:`gpt-6.1-sol`,efforts:T,defaultEffort:`medium`,...k({contextWindowTokens:D})},{alias:`luna`,label:`GPT-6 Luna`,providerModel:`gpt-6-luna`,efforts:T,defaultEffort:`medium`,...k({contextWindowTokens:E})},{alias:`gpt-6-sol`,label:`GPT-6 Sol`,providerModel:`gpt-6-sol`,efforts:T,defaultEffort:`medium`,...k({contextWindowTokens:E})},{alias:`gpt-6.1-sol`,label:`GPT-6.1 Sol`,providerModel:`gpt-6.1-sol`,efforts:T,defaultEffort:`medium`,...k({contextWindowTokens:D})},{alias:`gpt-6-luna`,label:`GPT-6 Luna`,providerModel:`gpt-6-luna`,efforts:T,defaultEffort:`medium`,...k({contextWindowTokens:E})},{alias:`gpt-5.6-terra`,label:`GPT-5.6 Terra`,providerModel:`gpt-5.6-terra`,efforts:T,defaultEffort:`medium`,...k({contextWindowTokens:E})},{alias:`gpt-5.5`,label:`GPT-5.5`,providerModel:`gpt-5.5`,efforts:T,defaultEffort:`medium`,...k({contextWindowTokens:E})},{alias:`gpt-5.4`,label:`GPT-5.4`,providerModel:`gpt-5.4`,efforts:T,defaultEffort:`medium`,...k({contextWindowTokens:E})},{alias:`gpt-5.4-mini`,label:`GPT-5.4 Mini`,providerModel:`gpt-5.4-mini`,efforts:T,defaultEffort:`medium`,...k({contextWindowTokens:E})},{alias:`gpt-5.3-codex`,label:`GPT-5.3 Codex`,providerModel:`gpt-5.3-codex`,efforts:T,defaultEffort:`medium`,...k({contextWindowTokens:E})},{alias:`gpt-5.3-codex-spark`,label:`GPT-5.3 Codex Spark`,providerModel:`gpt-5.3-codex-spark`,efforts:T,defaultEffort:`high`,...k({contextWindowTokens:E})},{alias:`gpt-5.2`,label:`GPT-5.2`,providerModel:`gpt-5.2`,efforts:T,defaultEffort:`medium`,...k({contextWindowTokens:E})}]},quotaWindows:[...O],capabilityDefaults:{lifecycle:{managed:!0,shutdownHard:!0,restartHard:!0,semanticStatus:!0,reconnect:!0},session:{fileRead:!0,fileWrite:{when:`approval:not-read-only`,value:!0,otherwise:!1},shell:{when:`approval:not-read-only`,value:!0,otherwise:!1},shellMode:{open:`unrestricted`,guarded:`guarded`,readOnly:`none`}},context:{managed:`always`,compact:!0,clear:!0,inject:!0,resumePreference:[`native`,`clear-inject`,`none`]},quota:{supported:!0,source:`probe`,unit:`%`,windows:[...O]},terminal:{mode:`attach`,attach:{create:!0,read:!0,write:!0,detach:!0}},liveSession:{capture:!0,inject:!0,interrupt:!0,promptEcho:!0,reasoning:!0,slashCommands:!0}},slashCommands:[`/compact`,`/new`],resume:{supported:!0,idFormat:`codex-thread-id`,idPattern:`[\\w-]+`},home:{configDir:`.codex`,envPrefix:`CODEX`,configDirEnvVar:`CODEX_HOME`,quotaCredentialFile:`auth.json`,authItems:[`auth.json`,`installation_id`],globalInstructionFiles:[`AGENTS.md`]},provisioning:{pluginManifestPath:`.codex-plugin/plugin.json`,bundledSkills:{refPrefix:`agent-relay-codex-`,dir:`runner/plugins/codex/skills`,titlePrefix:`Humwick Codex skill: `,description:`Bundled Humwick Codex skill, materialized through the provisioning registry.`,entryFile:`SKILL.md`},bundledHooks:[{ref:`agent-relay-rg-r-guard`,dir:`runner/hooks/rg-r-guard`,title:`Humwick baseline hook: rg -r guard`,description:"Baseline Humwick PreToolUse hook that blocks the ripgrep `rg -r` replace footgun.",baseline:!0}]},upgrade:{packages:[`agent-relay-runner`,`agent-relay-codex`],detectPackages:[`agent-relay-runner`,`agent-relay-codex`],detectCommands:[`codex-relay`,`agent-relay-runner`]},harness:{upgrade:{strategy:`self-update`,args:[`update`]}},probe:{command:`codex`,args:[`--version`],healthCheck:`codex --version`,authCheck:{command:`codex`,args:[`login`,`status`],loginArgs:[`login`]}},quotaPoll:{strategy:`codex-app-server`},resetCredits:{supported:!0},shim:{kind:`codex-relay`,extraBinPaths:[`codex/bin/codex`],cleanLegacyHooks:!0},mcpToolManifest:{clientNativeToolDeferral:!1,runnerManagedToolDeferral:!0,runnerManagedToolDeferralRoute:`meta-only-callmux`}});var A={mode:`attach`,attach:{create:!0,read:!0,write:!0,detach:!0}},j=`opencode-ai@latest`;m({id:`opencode`,label:`OpenCode`,icon:`⚡`,launch:{managedPolicyPrompt:{alwaysOn:`prompt`},taskHydration:{channel:`prompt`}},catalog:{defaultModel:`muse-spark`,models:[{alias:`muse-spark`,label:`Muse Spark 1.3 Contributor`,providerModel:`meta/muse-spark-1.3-contributor`,efforts:[],limits:{contextWindowTokens:{value:1048576,source:`catalog`,confidence:`declared`},maxOutputTokens:{value:943718,source:`catalog`,confidence:`declared`}},capabilities:{modalities:{input:{text:!0},output:{text:!0}},tools:{code:!0,shell:!0,fileRead:!0,fileWrite:!0},source:`provider`,confidence:`estimated`}},{alias:`openai/gpt-6.1-sol`,label:`GPT-6.1 Sol · OpenAI API`,providerModel:`openai/gpt-6.1-sol`,efforts:[],limits:{contextWindowTokens:{value:272e3,source:`catalog`,confidence:`declared`},maxOutputTokens:{value:128e3,source:`catalog`,confidence:`declared`}}}]},quotaWindows:[],capabilityDefaults:{lifecycle:{managed:!0,shutdownHard:!0,restartHard:!0,semanticStatus:!0,reconnect:!0},session:{fileRead:!0,fileWrite:!0,shell:!0,shellMode:{open:`unrestricted`,guarded:`unsupported`,readOnly:`unsupported`}},context:{managed:`always`,compact:!0,clear:!0,inject:!0,resumePreference:[`native`,`clear-inject`,`none`]},quota:{supported:!1,source:`runtime`,unit:`%`,windows:[]},terminal:A,liveSession:{capture:!0,inject:!0,interrupt:!0,promptEcho:!0,reasoning:!1,slashCommands:!1}},resume:{supported:!1},home:{configDir:`.config/opencode`,envPrefix:`OPENCODE`},opencode:{opencodeProviderID:`openrouter`,apiKeyEnvVar:`OPENROUTER_API_KEY`},upgrade:{packages:[`agent-relay-runner`],externalPackages:[j],detectPackages:[`opencode-ai`],detectCommands:[`opencode`]},harness:{upgrade:{strategy:`external-packages`}},probe:{command:`opencode`,args:[`--version`],healthCheck:`opencode --version`},shim:{kind:`opencode-relay`},quotaPoll:{strategy:`none`},mcpToolManifest:{clientNativeToolDeferral:!1,runnerManagedToolDeferral:!1}});var M=[{name:`rolling`,unit:`%`,reset:!0,description:`Rolling 5-hour usage window`},{name:`weekly`,unit:`%`,reset:!0,description:`Weekly usage window`},{name:`monthly`,unit:`%`,reset:!0,description:`Monthly usage window (display-only)`}],fe={modalities:{input:{text:!0},output:{text:!0}},tools:{code:!0,shell:!0,fileRead:!0,fileWrite:!0},source:`provider`,confidence:`estimated`};function N(e,t){return{alias:e,label:t,providerModel:e,efforts:[],capabilities:fe}}m({id:`opencode-go`,label:`OpenCode Go`,icon:`⚡`,defaultEnabled:!1,launch:{managedPolicyPrompt:{alwaysOn:`prompt`},taskHydration:{channel:`prompt`}},catalog:{defaultModel:`glm-5.3-flash`,models:[N(`claude-haiku-5-5`,`Claude Haiku 5.5`),N(`deepseek-v4-pro`,`DeepSeek V4 Pro`),N(`deepseek-v4.1-flash`,`DeepSeek V4.1 Flash`),N(`gemini-4-argon-contributor`,`Gemini 4 Argon Contributor`),N(`glm-5.2`,`GLM-5.2`),N(`glm-5.3`,`GLM-5.3`),N(`glm-5.3-flash`,`GLM-5.3 Flash`),N(`gpt-5.6-luna`,`GPT-5.6 Luna`),N(`gpt-6-luna`,`GPT-6 Luna`),N(`grok-4.6`,`Grok 4.6`),N(`grok-4.7`,`Grok 4.7`),N(`hy3`,`Hy3`),N(`hy4-preview`,`Hy4 Preview`),N(`kimi-k2.7-code`,`Kimi K2.7 Code`),N(`kimi-k3`,`Kimi K3`),N(`longcat-2.0`,`LongCat 2.0`),N(`mimo-v2.5`,`MiMo V2.5`),N(`mimo-v2.5-pro`,`MiMo V2.5 Pro`),N(`mimo-v2.6-flash`,`MiMo V2.6 Flash`),N(`mimo-v2.6-pro`,`MiMo V2.6 Pro`),N(`minimax-m2.7`,`MiniMax M2.7`),N(`minimax-m3`,`MiniMax M3`),N(`muse-spark-1.2-contributor`,`Muse Spark 1.2 Contributor`),N(`muse-spark-1.3-contributor`,`Muse Spark 1.3 Contributor`),N(`qwen3.7-plus`,`Qwen3.7 Plus`),N(`qwen3.8-flash`,`Qwen3.8 Flash`),N(`qwen3.8-max`,`Qwen3.8 Max`),N(`space-bunny`,`Space Bunny`)]},quotaWindows:[...M],capabilityDefaults:{lifecycle:{managed:!0,shutdownHard:!0,restartHard:!0,semanticStatus:!0,reconnect:!0},session:{fileRead:!0,fileWrite:!0,shell:!0,shellMode:{open:`unrestricted`,guarded:`unsupported`,readOnly:`unsupported`}},context:{managed:`always`,compact:!0,clear:!0,inject:!0,resumePreference:[`native`,`clear-inject`,`none`]},quota:{supported:!0,source:`runtime`,unit:`%`,windows:[...M]},terminal:A,liveSession:{capture:!0,inject:!0,interrupt:!0,promptEcho:!0,reasoning:!1,slashCommands:!1}},resume:{supported:!1},home:{configDir:`.local/share/opencode`,envPrefix:`OPENCODE_GO`,quotaCredentialFile:`auth.json`},opencode:{opencodeProviderID:`opencode-go`,apiKeyEnvVar:`OPENCODE_API_KEY`,hostAuth:!0},upgrade:{packages:[`agent-relay-runner`],externalPackages:[j],detectPackages:[`opencode-ai`],detectCommands:[`opencode`]},harness:{upgrade:{strategy:`external-packages`}},probe:{command:`opencode`,args:[`--version`],healthCheck:`opencode --version`},shim:{kind:`opencode-relay`},quotaPoll:{strategy:`opencode-go`},quotaAlsoWith:`opencode`,mcpToolManifest:{clientNativeToolDeferral:!1,runnerManagedToolDeferral:!1}});var P={value:1e6,source:`catalog`,confidence:`declared`},F={value:131072,source:`catalog`,confidence:`declared`},pe={modalities:{input:{text:!0},output:{text:!0}},tools:{code:!0,shell:!0,fileRead:!0,fileWrite:!0},source:`provider`,confidence:`declared`},me={modalities:{input:{text:!0,image:!0},output:{text:!0}},tools:{code:!0,shell:!0,fileRead:!0,fileWrite:!0},source:`provider`,confidence:`declared`},I=[{name:`five_hour`,unit:`%`,reset:!0,description:`Rolling 5-hour credit window`},{name:`seven_day`,unit:`%`,reset:!0,description:`Weekly credits, reset from the subscription timestamp`}];m({id:`zai`,label:`z.ai`,icon:`🟣`,launch:{managedPolicyPrompt:{alwaysOn:`prompt`},taskHydration:{channel:`prompt`}},catalog:{defaultModel:`glm-5.3-flash`,models:[{alias:`glm-5.3`,label:`GLM-5.3`,providerModel:`glm-5.3`,efforts:[],limits:{contextWindowTokens:P,maxOutputTokens:F},capabilities:pe},{alias:`glm-5.3-flash`,label:`GLM-5.3 Flash`,providerModel:`glm-5.3-flash`,efforts:[],limits:{contextWindowTokens:P,maxOutputTokens:F},capabilities:me}]},quotaWindows:[...I],capabilityDefaults:{lifecycle:{managed:!0,shutdownHard:!0,restartHard:!0,semanticStatus:!0,reconnect:!0},session:{fileRead:!0,fileWrite:!0,shell:!0,shellMode:{open:`unrestricted`,guarded:`unsupported`,readOnly:`unsupported`}},context:{managed:`always`,compact:!0,clear:!0,inject:!0,resumePreference:[`native`,`clear-inject`,`none`]},quota:{supported:!0,source:`runtime`,unit:`%`,windows:[...I]},terminal:A,liveSession:{capture:!0,inject:!0,interrupt:!0,promptEcho:!0,reasoning:!1,slashCommands:!1}},resume:{supported:!1},home:{configDir:`.config/opencode`,envPrefix:`ZAI`,quotaCredentialFile:`auth.json`},opencode:{opencodeProviderID:`zai`,baseURL:`https://api.z.ai/api/coding/paas/v4`,npm:`@ai-sdk/openai-compatible`,apiKeyEnvVar:`ZAI_API_KEY`},upgrade:{packages:[`agent-relay-runner`],externalPackages:[j],detectPackages:[`opencode-ai`],detectCommands:[`opencode`]},harness:{upgrade:{strategy:`external-packages`}},probe:{command:`opencode`,args:[`--version`],healthCheck:`opencode --version`},shim:{kind:`opencode-relay`},quotaPoll:{strategy:`zai`},mcpToolManifest:{clientNativeToolDeferral:!1,runnerManagedToolDeferral:!1}}),Object.freeze({codex:{"gpt-5.6-terra":`sol`,"gpt-5.6-sol":`sol`,"gpt-6-sol":`sol`,"gpt-6.1-sol":`sol`,"gpt-5.6-luna":`luna`,"gpt-6-luna":`luna`},claude:{"opus-4.8":`opus`,"sonnet-5":`sonnet`,"fable-5":`fable`},"claude-b":{"opus-4.8":`opus`,"sonnet-5":`sonnet`,"fable-5":`fable`}});var L={opencode:{envVar:`OPENCODE_API_KEY`},"opencode-go":{envVar:`OPENCODE_API_KEY`},anthropic:{envVar:`ANTHROPIC_API_KEY`},openai:{envVar:`OPENAI_API_KEY`},openrouter:{envVar:`OPENROUTER_API_KEY`},google:{envVar:`GOOGLE_GENERATIVE_AI_API_KEY`},mistral:{envVar:`MISTRAL_API_KEY`},deepseek:{envVar:`DEEPSEEK_API_KEY`},xai:{envVar:`XAI_API_KEY`},groq:{envVar:`GROQ_API_KEY`},azure:{envVar:`AZURE_API_KEY`},moonshotai:{envVar:`MOONSHOT_API_KEY`},cerebras:{envVar:`CEREBRAS_API_KEY`},cohere:{envVar:`COHERE_API_KEY`},"fireworks-ai":{envVar:`FIREWORKS_API_KEY`},togetherai:{envVar:`TOGETHER_API_KEY`},chutes:{envVar:`CHUTES_API_KEY`},zai:{envVar:`ZAI_API_KEY`,custom:!0}},R=class extends Error{candidates;constructor(e,t){super(e),this.candidates=t,this.name=`OpenCodeModelResolutionError`}},z=8;function B(e,t){let n=e.indexOf(`/`);return n<=0?{backendID:t,modelID:e,qualified:`${t}/${e}`}:{backendID:e.slice(0,n),modelID:e.slice(n+1),qualified:e}}function he(e,t,n){let r=e.trim();if(!r)throw new R(`OpenCode model id is empty.`,[]);let i=r.indexOf(`/`),a=i>0?r.slice(0,i):void 0;if(!n)return a&&(a===t||L[a]!==void 0)?B(r,t):{backendID:t,modelID:r,qualified:`${t}/${r}`};if(n.models.has(r))return B(r,t);if(n.models.has(`${t}/${r}`))return{backendID:t,modelID:r,qualified:`${t}/${r}`};if(a&&n.providers.has(a))return B(r,t);if(!a){let e=[...n.models].filter(e=>e.slice(e.indexOf(`/`)+1)===r);if(e.length===1)return B(e[0],t);if(e.length>1){let t=e.sort().slice(0,z);throw new R(`OpenCode model "${r}" is ambiguous on this host (${n.source} registry); qualify it as one of: ${t.join(`, `)}.`,t)}}let o=ge(r,n),s=o.length?` Did you mean: ${o.join(`, `)}?`:``;throw new R(`OpenCode model "${r}" is not available on this host (${n.source} registry: backend "${a??t}" is not a known opencode provider and no listed model matches).${s}`,o)}function ge(e,t){let n=e.slice(e.lastIndexOf(`/`)+1).toLowerCase();if(!n)return[];let r=[],i=[];for(let e of t.models){let t=e.slice(e.lastIndexOf(`/`)+1).toLowerCase();t===n?r.push(e):t.includes(n)&&i.push(e)}return[...r.sort(),...i.sort()].slice(0,z)}var _e=[`off`,`quiet`,`normal`,`verbose`];g().map(e=>e.id);var V=[`narration`,`tools`,`reasoning`,`memories`,`startup`,`injected`,`agentMessages`,`workflow`,`land`,`task`,`agents`,`other`,`undelivered`],ve=[`workflow`,`land`,`task`,`agents`,`other`];function H(e){return Object.fromEntries(V.map(t=>[t,e(t)]))}var U=H(e=>ve.includes(e)),W={calm:U,everything:H(()=>!0)};function ye(e){let t=e&&typeof e==`object`&&!Array.isArray(e)?e:{};return H(e=>typeof t[e]==`boolean`?t[e]:U[e])}function be(e){for(let[t,n]of Object.entries(W))if(V.every(t=>n[t]===e[t]))return t;return null}function xe(e,t){let n=e?.opencodeProviderID,r=t?.trim();if(!(!n||!r))return he(r,n).qualified}function Se(e){return!e?.disabled}var Ce=.1,we=.9,G=.8,K=.4,q=256e3,J=1e6;function Te(){return g().map(e=>({provider:e.id,label:e.label,models:[],...e.opencode?.opencodeProviderID?{opencodeProviderID:e.opencode.opencodeProviderID}:{},...e.launchModes?.length?{launchModes:[...e.launchModes]}:{},...e.effortSwitch?{effortSwitch:!0}:{}}))}function Ee(e){let t=De(e);return{selfCompactUtilization:t,warnUtilization:Oe(t),hardBackstopUtilization:Math.max(we,t)}}function De(e){return!Number.isFinite(e)||!e||e<=q?G:e>=J?K:Y(G-(e-q)/(J-q)*(G-K))}function Oe(e){return Y(Math.max(0,e-Ce))}function Y(e){return Math.round(e*1e3)/1e3}function X(e,t){if(e)return(t??Te()).find(t=>t.provider===e)}function ke(e,t,n={}){let r=(Array.isArray(t)?t:t?[t]:[]).map(e=>e.trim()).filter(Boolean);if(r.length){for(let t of r){let i=Ae(e,t,n.requireUnambiguous),a=je(e,i,r,n.observedWindowTokens);if(a)return a;if(i)return i}if(!(n.requireUnambiguous||n.exactOnly))for(let t of r){let n=e.models.find(e=>e.alias.startsWith(t+`-`));if(n)return n}}}function Ae(e,t,n=!1){let r=t.toLowerCase(),i=e.models.find(e=>e.alias===t)??e.models.find(e=>e.alias.toLowerCase()===r);if(i)return i;let a=e.models.filter(e=>e.providerModel.toLowerCase()===r);if(a.length>1&&n)throw Error(`ambiguous ${e.provider} provider model: ${t} (select an alias: ${a.map(e=>e.alias).join(`, `)})`);return a[0]}function je(e,t,n,r){if(!Number.isFinite(r)||!r)return;if(t?.limits?.contextWindowTokens?.value===r)return t;let i=new Set([...t?[t.alias,t.providerModel]:[],...n].map(Z));return e.models.find(e=>e.limits?.contextWindowTokens?.value===r&&(i.has(Z(e.alias))||i.has(Z(e.providerModel))))}function Z(e){return e.trim().toLowerCase().replace(/\[[^\]]+\]$/,``)}function Me(e){return!e.disabled&&!e.unavailable}function Ne(e){let t=e.defaultModel,n=t?e.models.find(e=>e.alias===t):void 0;return n&&Me(n)?{alias:n.alias,preferred:t,fellBack:!1}:{alias:void 0,preferred:t,fellBack:!0}}function Pe(e){return h(e)?.resetCredits?.supported===!0}var Q=[`bg-tone-warning/10 text-tone-warning-fg border-tone-warning/30`,`bg-tone-sky/10 text-tone-sky-fg border-tone-sky/30`,`bg-tone-violet/10 text-tone-violet-fg border-tone-violet/30`,`bg-tone-success/10 text-tone-success-fg border-tone-success/30`,`bg-tone-rose/10 text-tone-rose-fg border-tone-rose/30`];function Fe(e){let t=0;for(let n=0;n<e.length;n++)t=t*31+e.charCodeAt(n)>>>0;return t}var $=new Map(g().map((e,t)=>[e.id,Q[t%Q.length]]));function Ie(e){return e?h(e)?.label??e.charAt(0).toUpperCase()+e.slice(1):`Unknown provider`}function Le(e){let t=$.get(e);if(t)return t;let n=Q[Fe(e)%Q.length];return $.set(e,n),n}function Re(){return g().map(e=>e.id)}function ze(e){return h(e)}function Be(e,t){let n=e?.id||e?.alias;if(!e||!n)return;let r=X(e.provider,t),i=r?ke(r,[e.alias||``,n]):void 0;return{label:i?.label||n,...i?{entry:i}:{}}}export{o as A,se as C,te as D,a as E,n as M,e as N,c as O,t as P,ae as S,i as T,_,Pe as a,u as b,X as c,Ne as d,U as f,_e as g,ye as h,ze as i,r as j,ee as k,Se as l,be as m,Le as n,Be as o,W as p,Ie as r,Ee as s,Re as t,xe as u,d as v,s as w,re as x,l as y};
2
- //# sourceMappingURL=provider-display-DsuWMvVL.js.map