@humwick/server 0.130.0 → 0.130.2

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 (486) hide show
  1. package/README.md +5 -0
  2. package/docs/guides/tools-administration.md +6 -1
  3. package/docs/guides/tools-coordination.md +1 -0
  4. package/docs/guides/tools-tasks.md +8 -0
  5. package/docs/guides/workflows.md +58 -0
  6. package/docs/openapi.json +414 -1
  7. package/package.json +8 -17
  8. package/public/assets/{MessageBubble-BWpoBjl4.js → MessageBubble-BWLqMGKG.js} +2 -2
  9. package/public/assets/{PlanGraphPanel-C0auck3n.js → PlanGraphPanel-3TlIQpjk.js} +2 -2
  10. package/public/assets/{TraceView-DBnOx7AQ.js → TraceView-Wimm0Czv.js} +2 -2
  11. package/public/assets/{VaultDecisionCard-0kp2oNBC.js → VaultDecisionCard-Bau_vNax.js} +2 -2
  12. package/public/assets/{activity-yLztXEBt.js → activity-CrSurn-r.js} +2 -2
  13. package/public/assets/{agent-lineage-BbJDR1dW.js → agent-lineage-CknAJKcb.js} +2 -2
  14. package/public/assets/agent-liveness-CaNwK0Zf.js +2 -0
  15. package/public/assets/{agent-name-CTZBrSD9.js → agent-name-DKbiIhBo.js} +2 -2
  16. package/public/assets/agent-profiles-DwF6EQ4R.js +2 -0
  17. package/public/assets/{agent-project-badge-9TqzUUYE.js → agent-project-badge-Diz4Sjjb.js} +2 -2
  18. package/public/assets/{agent-tools-D4n40pn8.js → agent-tools-CRhpRQza.js} +2 -2
  19. package/public/assets/{agent-type-icon-D6FUarOf.js → agent-type-icon-LrUEU3lB.js} +2 -2
  20. package/public/assets/{agents-BYDslkJc.js → agents-B-v66C-4.js} +2 -2
  21. package/public/assets/{analytics-B-XSbEMC.js → analytics-BqCb-LKi.js} +2 -2
  22. package/public/assets/{artifact-viewer-DdWIfV6M.js → artifact-viewer-kf4pGuAR.js} +2 -2
  23. package/public/assets/{artifacts-oBOqks-2.js → artifacts-D32zyw4Y.js} +2 -2
  24. package/public/assets/{artifacts-DPN1q4pA.js → artifacts-DJevXcvg.js} +2 -2
  25. package/public/assets/{automation-4KcRFXEu.js → automation-BpRajx_5.js} +2 -2
  26. package/public/assets/{backlog-Cw9xPTCF.js → backlog-D_UjTdzX.js} +2 -2
  27. package/public/assets/{busy-health-CTu32MZt.js → busy-health-N3VEh4ao.js} +2 -2
  28. package/public/assets/{channels-BiXzg1G9.js → channels-9jopungq.js} +2 -2
  29. package/public/assets/{chat-Ctk2qwvA.js → chat-CSXrTB3C.js} +2 -2
  30. package/public/assets/{code-preview-Bm1wWqAp.js → code-preview-p1NnmqK0.js} +2 -2
  31. package/public/assets/{connectors-C36ax4Vw.js → connectors-CZdqlDNL.js} +2 -2
  32. package/public/assets/{cosmos-Jj9LK2Wf.js → cosmos-BgdsE4dG.js} +2 -2
  33. package/public/assets/{crate-agent-H6S7-B9T.js → crate-agent-30aXTKva.js} +2 -2
  34. package/public/assets/{dependency-graph-Cd1E23wa.js → dependency-graph-B_jvw2GE.js} +2 -2
  35. package/public/assets/{deploys-Bwfq146q.js → deploys-DoN6bAb5.js} +2 -2
  36. package/public/assets/{display-CfO7rTuF.js → display-BrKWFGJz.js} +2 -2
  37. package/public/assets/{files-DhhZI2Ih.js → files-D6XEu8Ng.js} +2 -2
  38. package/public/assets/fleet-C7jQWbw2.js +2 -0
  39. package/public/assets/{fleet-metrics-BkHP-P3R.js → fleet-metrics-BiDs3MLx.js} +2 -2
  40. package/public/assets/{formatted-body-Cm1RrzmN.js → formatted-body-CQBwc1fb.js} +3 -3
  41. package/public/assets/{formatted-body-impl-DQiOuOD1.js → formatted-body-impl-DyG0WsQS.js} +2 -2
  42. package/public/assets/{host-providers-dialog-CHqwXTov.js → host-providers-dialog-DKaW31dN.js} +2 -2
  43. package/public/assets/index-CRHep3M9.js +15 -0
  44. package/public/assets/index-MYAIwYTX.css +2 -0
  45. package/public/assets/{insights-fH1EL-qZ.js → insights-CzrtkpOE.js} +2 -2
  46. package/public/assets/{integrations-C5Oix6ng.js → integrations-aVsUmigt.js} +2 -2
  47. package/public/assets/{issue-ref-chip-ODyondIa.js → issue-ref-chip-BnSlM_95.js} +2 -2
  48. package/public/assets/{log-viewer-Cvfy6PW7.js → log-viewer-qe7Ee47Z.js} +2 -2
  49. package/public/assets/{maintenance-D8CDH5wZ.js → maintenance-NfjqFZAk.js} +2 -2
  50. package/public/assets/{managed-agents-egllbpij.js → managed-agents-BiH0HgaE.js} +2 -2
  51. package/public/assets/{markdown-preview-CYSFgVgK.js → markdown-preview-BixaT3Xr.js} +3 -3
  52. package/public/assets/{markdown-preview-impl-BteVIjX4.js → markdown-preview-impl-DNGlWIS3.js} +2 -2
  53. package/public/assets/{memory-C8WmXsyr.js → memory-DNsCl6UX.js} +2 -2
  54. package/public/assets/{messages-BzQdqlO6.js → messages-DopU1L1X.js} +2 -2
  55. package/public/assets/{orchestrators-B1HxzkNw.js → orchestrators-Cq7ckLQT.js} +2 -2
  56. package/public/assets/{overview-DCUnI4Z7.js → overview-C1DCTzzV.js} +2 -2
  57. package/public/assets/{pairs-ftCd2XcD.js → pairs-DE_m6rrE.js} +2 -2
  58. package/public/assets/{profile-icon-B2zH8DMH.js → profile-icon-B3rfh77F.js} +2 -2
  59. package/public/assets/project-profile-instructions-DQWZE0kA.js +2 -0
  60. package/public/assets/projects-Br2Bd2h1.js +2 -0
  61. package/public/assets/{prompt-settings-Bftq9czX.js → prompt-settings-BKvFsvGD.js} +2 -2
  62. package/public/assets/provider-display-DsuWMvVL.js +2 -0
  63. package/public/assets/{registry-DWCU5c8q.js → registry-Cw38_6gW.js} +2 -2
  64. package/public/assets/run-card-CpKqRbhg.js +2 -0
  65. package/public/assets/scroll-text-BKXS1ahr.js +2 -0
  66. package/public/assets/{secrets-C7GIUATz.js → secrets-DxI-vzSq.js} +2 -2
  67. package/public/assets/{service-access-settings-C3aujqTG.js → service-access-settings-D9s_VJbd.js} +2 -2
  68. package/public/assets/{settings-C6sZ9eBa.js → settings-CKZTVGIx.js} +2 -2
  69. package/public/assets/{shipping-Bu8p1gEw.js → shipping-B9YtnwtG.js} +2 -2
  70. package/public/assets/{stats-V9Z-GxUd.js → stats-DyUBKyWI.js} +2 -2
  71. package/public/assets/{status-dot-CVv0iGHL.js → status-dot-DYqlEUhJ.js} +2 -2
  72. package/public/assets/{store-BvtFdlGX.js → store-DcClXLH0.js} +3 -3
  73. package/public/assets/{tasks-CXU75HRF.js → tasks-Bh7Chr4-.js} +2 -2
  74. package/public/assets/{teams-BPf976zb.js → teams-bowI7qVY.js} +2 -2
  75. package/public/assets/{terminal-viewer-DE9BOe-8.js → terminal-viewer-BgVLHdsU.js} +3 -3
  76. package/public/assets/{terminal-viewer-impl-D04pjmGh.js → terminal-viewer-impl-Dz22UPy6.js} +2 -2
  77. package/public/assets/token-estimate-Co-Jdphh.js +2 -0
  78. package/public/assets/{use-agent-terminal-B1yR456R.js → use-agent-terminal-DSQQ-iY7.js} +2 -2
  79. package/public/assets/{use-decisions-D-S4tpDf.js → use-decisions-samMQhQf.js} +2 -2
  80. package/public/assets/use-project-list-59LheVP7.js +2 -0
  81. package/public/assets/{use-selectors-CnrAk2YP.js → use-selectors-BZa25xEB.js} +2 -2
  82. package/public/assets/{user-avatar-nBFIcR4M.js → user-avatar-DHxlvUvV.js} +2 -2
  83. package/public/assets/versioned-prompt-editor-BmED5DnJ.js +8 -0
  84. package/public/assets/{work-queue-TCjJxeT-.js → work-queue-CSvpuNLz.js} +2 -2
  85. package/public/assets/{workflow-marker-Cf3Hf2fN.js → workflow-marker-DAZcj5qt.js} +2 -2
  86. package/public/assets/{workflows-CXQX20Qj.js → workflows-DdmxRSyg.js} +2 -2
  87. package/public/assets/{workspaces-qSYzKYMA.js → workspaces-BxeKfVuF.js} +2 -2
  88. package/public/cosmos.html +4 -4
  89. package/public/index.html +31 -29
  90. package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
  91. package/runner/plugins/claude/hooks/gate-run-guard.provisioned.mjs +31 -1
  92. package/runner/src/adapters/claude-effort.ts +2 -4
  93. package/runner/src/adapters/codex-launch-config.ts +4 -5
  94. package/runner/src/adapters/codex.ts +1 -1
  95. package/runner/src/adapters/opencode-provider.ts +7 -22
  96. package/runner/src/adapters/opencode.ts +4 -4
  97. package/runner/src/agent-runner/credentials.ts +42 -12
  98. package/runner/src/agent-runner/inbox.ts +27 -0
  99. package/runner/src/agent-runner/lifecycle-milestones.ts +0 -2
  100. package/runner/src/bin/claude.ts +4 -0
  101. package/runner/src/bin/codex.ts +4 -0
  102. package/runner/src/bin/opencode.ts +4 -0
  103. package/runner/src/index.ts +5 -2
  104. package/runner/src/provider-setup.ts +34 -0
  105. package/runner/src/providers.ts +2 -1
  106. package/runner/src/runner-core.ts +18 -23
  107. package/runner/src/spawn-input.ts +2 -1
  108. package/runner/src/test-run-dedup.ts +59 -56
  109. package/scripts/cd-config.ts +24 -3
  110. package/scripts/gate-run-lease.ts +10 -7
  111. package/scripts/gate.sh +5 -1
  112. package/src/branch-land-notice.ts +93 -0
  113. package/src/branch-landed.ts +7 -76
  114. package/src/bus.ts +19 -20
  115. package/src/cd-deploy-notify.ts +30 -2
  116. package/src/cd-host-lag-notify.ts +7 -6
  117. package/src/ci/incidents.ts +2 -2
  118. package/src/ci/monitor.ts +5 -8
  119. package/src/ci/root-missing.ts +2 -7
  120. package/src/ci/transition-notify.ts +7 -39
  121. package/src/cli/cd-pauses.ts +19 -0
  122. package/src/cli/orchestrator.ts +1 -1
  123. package/src/cli/state.ts +2 -19
  124. package/src/cli/task-edit.ts +22 -0
  125. package/src/cli/task.ts +3 -1
  126. package/src/cli/workflow.ts +8 -2
  127. package/src/commands-db.ts +10 -6
  128. package/src/commands-write.ts +8 -0
  129. package/src/config-store-write.ts +13 -1
  130. package/src/config-store.ts +25 -14
  131. package/src/db/activity-async.ts +6 -1
  132. package/src/db/activity-write-ops.ts +13 -1
  133. package/src/db/activity.ts +1 -14
  134. package/src/db/agent-lifecycle-write-ops.ts +1 -0
  135. package/src/db/agent-meta.ts +2 -2
  136. package/src/db/agent-ownership-write-ops.ts +4 -0
  137. package/src/db/agent-search.ts +1 -15
  138. package/src/db/agents-async.ts +58 -7
  139. package/src/db/agents-write-ops.ts +28 -5
  140. package/src/db/agents.ts +81 -54
  141. package/src/db/artifacts-write-ops.ts +8 -3
  142. package/src/db/bus-outbox-write-ops.ts +1 -0
  143. package/src/db/channels-write-ops.ts +4 -0
  144. package/src/db/ci-incidents-async.ts +5 -5
  145. package/src/db/ci-incidents-write-ops.ts +2 -2
  146. package/src/db/claude-api-budget-ops.ts +5 -5
  147. package/src/db/claude-app-oauth.ts +4 -4
  148. package/src/db/codex-reset-consumes-write-ops.ts +3 -0
  149. package/src/db/command-row.ts +10 -2
  150. package/src/db/commands-list-query.ts +2 -0
  151. package/src/db/commands-spawn-read.ts +1 -1
  152. package/src/db/commands-write-ops.ts +21 -0
  153. package/src/db/config-store-write-ops.ts +9 -2
  154. package/src/db/continuation-archives-async.ts +5 -0
  155. package/src/db/continuation-archives-write-ops.ts +9 -0
  156. package/src/db/continuations.ts +2 -2
  157. package/src/db/db-writer-worker.ts +8 -1
  158. package/src/db/delivery-write-ops.ts +5 -0
  159. package/src/db/deploy-events-async.ts +1 -0
  160. package/src/db/deploy-events-read-ops.ts +2 -1
  161. package/src/db/deploy-events.ts +35 -4
  162. package/src/db/hosts-registration.ts +10 -2
  163. package/src/db/hosts-write-ops.ts +14 -0
  164. package/src/db/hosts.ts +9 -6
  165. package/src/db/inbox-write-ops.ts +4 -0
  166. package/src/db/inbox.ts +0 -14
  167. package/src/db/index.ts +2 -0
  168. package/src/db/insights-write-ops.ts +1 -0
  169. package/src/db/integrations-async.ts +8 -0
  170. package/src/db/integrations-ops.ts +15 -0
  171. package/src/db/integrations.ts +15 -21
  172. package/src/db/issue-lifecycle.ts +3 -4
  173. package/src/db/issue-refs-async.ts +20 -0
  174. package/src/db/issue-refs-write-ops.ts +29 -0
  175. package/src/db/issue-refs.ts +7 -8
  176. package/src/db/long-running-work.ts +2 -2
  177. package/src/db/macos-privacy.ts +1 -1
  178. package/src/db/main-connection-writes.ts +23 -2
  179. package/src/db/maintenance-job-reconcile.ts +61 -0
  180. package/src/db/maintenance-job-runs-async.ts +14 -0
  181. package/src/db/maintenance-job-write-ops.ts +9 -0
  182. package/src/db/mappers.ts +2 -14
  183. package/src/db/merge-lease.ts +1 -15
  184. package/src/db/message-reads-write-ops.ts +3 -0
  185. package/src/db/message-write-ops.ts +4 -0
  186. package/src/db/migrations.ts +7 -15
  187. package/src/db/orchestrators-async.ts +7 -3
  188. package/src/db/orchestrators-write-ops.ts +7 -1
  189. package/src/db/orchestrators.ts +21 -77
  190. package/src/db/pairs.ts +1 -13
  191. package/src/db/project-profile-instructions.ts +50 -0
  192. package/src/db/prompt-versions-ops.ts +1 -0
  193. package/src/db/prompt-versions.ts +9 -2
  194. package/src/db/provider-catalog-write-ops.ts +4 -4
  195. package/src/db/provider-config-history.ts +8 -3
  196. package/src/db/provider-flap-messages-write-ops.ts +1 -0
  197. package/src/db/provider-model-seed.ts +34 -0
  198. package/src/db/provider-quota-lease-write-ops.ts +1 -0
  199. package/src/db/provider-quota-write-ops.ts +2 -0
  200. package/src/db/provisioning-write-ops.ts +9 -8
  201. package/src/db/read-op-marshaling-fixtures.ts +5 -0
  202. package/src/db/read-ops.ts +4 -0
  203. package/src/db/routing-policy.ts +3 -4
  204. package/src/db/schema.ts +9 -3
  205. package/src/db/secrets-broker-write-ops.ts +5 -5
  206. package/src/db/secrets-vault-write.ts +7 -7
  207. package/src/db/services-write-ops.ts +3 -0
  208. package/src/db/spawn-delegation-state.ts +11 -4
  209. package/src/db/spawn-tree-cleanup.ts +3 -0
  210. package/src/db/stats-async.ts +4 -3
  211. package/src/db/task-entity.ts +23 -2
  212. package/src/db/task-list.ts +3 -1
  213. package/src/db/tasks.ts +1 -17
  214. package/src/db/team-spawn-delegation.ts +1 -1
  215. package/src/db/teams-write-ops.ts +4 -4
  216. package/src/db/timer-cutover-write-ops.ts +7 -0
  217. package/src/db/timer-ingress-write-ops.ts +9 -0
  218. package/src/db/timer-ingress.ts +7 -1
  219. package/src/db/timer-operator-write-ops.ts +14 -0
  220. package/src/db/timer-transfer-write-ops.ts +4 -0
  221. package/src/db/timer-write-ops.ts +14 -0
  222. package/src/db/token-db-write-ops.ts +21 -0
  223. package/src/db/token-standing.ts +15 -11
  224. package/src/db/user-settings-write-ops.ts +1 -0
  225. package/src/db/vault-backup.ts +2 -2
  226. package/src/db/vault-expiry.ts +2 -2
  227. package/src/db/vault-health.ts +3 -3
  228. package/src/db/vault-token-ops.ts +8 -8
  229. package/src/db/web-tool-call-ops.ts +3 -3
  230. package/src/db/workflow-contact.ts +1 -1
  231. package/src/db/workflow-task-read-ops.ts +30 -0
  232. package/src/db/write-ops.ts +15 -1
  233. package/src/db/writer-fault-seam.ts +5 -2
  234. package/src/db/writer-gateway.ts +21 -12
  235. package/src/dispatch-availability.ts +10 -6
  236. package/src/ephemeral/{landing-ingress-proof-worker.ts → landing-ingress-proof.test-fixture.ts} +4 -2
  237. package/src/host/disk-alert.ts +121 -0
  238. package/src/lifecycle-manager.ts +3 -2
  239. package/src/maintenance/cd-watcher.ts +3 -3
  240. package/src/maintenance/critical-job-watchdog.ts +16 -17
  241. package/src/maintenance/index.ts +1 -0
  242. package/src/maintenance/jobs.ts +3 -2
  243. package/src/maintenance/scheduler.ts +84 -128
  244. package/src/maintenance/stalled-delivery-pager.ts +6 -5
  245. package/src/maintenance/workspaces.ts +1 -1
  246. package/src/managed-policy.ts +31 -27
  247. package/src/mcp/index.ts +5 -2
  248. package/src/mcp/output-descriptions.ts +8 -8
  249. package/src/mcp/presentation.ts +4 -4
  250. package/src/mcp/project-profile-instructions.ts +32 -0
  251. package/src/mcp/tool-groups.ts +1 -1
  252. package/src/mcp/tools-spawn.ts +4 -3
  253. package/src/mcp-agent-action.ts +1 -2
  254. package/src/mcp-host-tools.ts +1 -1
  255. package/src/mcp-issue-ref-tools.ts +12 -11
  256. package/src/mcp-maintenance-tools.ts +2 -2
  257. package/src/mcp-profile-trust-tools.ts +4 -4
  258. package/src/mcp-provider-catalog.ts +2 -2
  259. package/src/mcp-task-tools.ts +11 -5
  260. package/src/mcp-team-template-tools.ts +3 -3
  261. package/src/mcp-workflow-tools.ts +10 -3
  262. package/src/notification-types.ts +2 -1
  263. package/src/operator-alarm.ts +26 -11
  264. package/src/package-pack.ts +42 -39
  265. package/src/project-instructions.ts +4 -0
  266. package/src/project-profile-instruction-text.ts +6 -0
  267. package/src/project-profile-instructions.ts +20 -0
  268. package/src/provider-catalog-store.ts +3 -49
  269. package/src/provider-config-store.ts +12 -11
  270. package/src/provider-model-seed.ts +1 -18
  271. package/src/provider-quota-config-store.ts +5 -4
  272. package/src/provider-secrets.test-fixture.ts +3 -3
  273. package/src/recipe-runner.ts +2 -2
  274. package/src/repo-config-source.ts +10 -4
  275. package/src/routes/agent-profiles.ts +6 -6
  276. package/src/routes/agents-spawn.ts +1 -1
  277. package/src/routes/agents.ts +6 -6
  278. package/src/routes/commands-listing.ts +4 -0
  279. package/src/routes/commands.ts +2 -2
  280. package/src/routes/continuation-archives.ts +2 -2
  281. package/src/routes/host-resource-control.ts +4 -1
  282. package/src/routes/index.ts +10 -1
  283. package/src/routes/integrations.ts +24 -50
  284. package/src/routes/issue-refs.ts +7 -7
  285. package/src/routes/orchestrator-bootstrap.ts +3 -3
  286. package/src/routes/orchestrator-host-registration.ts +2 -2
  287. package/src/routes/orchestrator-host-utilization.ts +3 -1
  288. package/src/routes/orchestrator-proxy.ts +2 -2
  289. package/src/routes/orchestrator.ts +4 -4
  290. package/src/routes/project-profile-instructions.ts +27 -0
  291. package/src/routes/project-trust.ts +2 -2
  292. package/src/routes/provider-config.ts +9 -8
  293. package/src/routes/provider-quota-config.ts +2 -2
  294. package/src/routes/settings.ts +5 -5
  295. package/src/routes/stats.ts +6 -6
  296. package/src/routes/task-http.ts +15 -1
  297. package/src/routes/task-issues.ts +11 -26
  298. package/src/routes/tasks.ts +22 -53
  299. package/src/routes/team-templates.ts +5 -5
  300. package/src/routes/teams-config.ts +2 -2
  301. package/src/routes/tokens.ts +12 -5
  302. package/src/routes/workflows.ts +20 -5
  303. package/src/routing-policy-normalize.ts +1 -2
  304. package/src/routing-step-defaults.ts +0 -2
  305. package/src/runner-token-mint-limit.ts +63 -0
  306. package/src/runtime-grant.ts +4 -2
  307. package/src/runtime-tokens.ts +50 -9
  308. package/src/security.ts +13 -20
  309. package/src/server-background.ts +1 -1
  310. package/src/server.ts +5 -2
  311. package/src/services/host-utilization.ts +23 -0
  312. package/src/services/idle-epics.ts +5 -6
  313. package/src/services/issue-lifecycle.ts +57 -61
  314. package/src/services/issue-refs.ts +9 -13
  315. package/src/services/kernel-timers-cutover-chaos-worker.ts +12 -7
  316. package/src/services/kernel-timers-ingress.ts +1 -1
  317. package/src/services/kernel-timers-request-key-migration-chaos-worker.ts +4 -1
  318. package/src/services/landed-ancestry.ts +19 -3
  319. package/src/services/memory-areas.ts +15 -51
  320. package/src/services/plan-ci-notice.ts +57 -0
  321. package/src/services/plan-ci-recovery.ts +2 -55
  322. package/src/services/plan-wake-digest.ts +1 -0
  323. package/src/services/profile-trust.ts +4 -3
  324. package/src/services/project-config-read.ts +70 -0
  325. package/src/services/project-profile-instructions.ts +54 -0
  326. package/src/services/provisioning-harness/budget-baseline.json +4 -4
  327. package/src/services/restart-spawn.ts +61 -49
  328. package/src/services/self-care-state.ts +2 -1
  329. package/src/services/self-effort.ts +5 -5
  330. package/src/services/send-message.ts +5 -1
  331. package/src/services/spawn-agent.ts +13 -2
  332. package/src/services/spawn-chain-inspector.ts +6 -13
  333. package/src/services/spawn-policy.ts +68 -0
  334. package/src/services/spawn-tree-cleanup.ts +2 -2
  335. package/src/services/task-dispatch.ts +3 -0
  336. package/src/services/task-state-reconcile.ts +6 -14
  337. package/src/services/team-templates.ts +9 -8
  338. package/src/services/transient-agent-reaper.ts +3 -1
  339. package/src/services/workflow-auto-start.ts +25 -13
  340. package/src/services/workflow-ci-main.ts +1 -1
  341. package/src/services/workflow-deferred-cleanup.ts +4 -2
  342. package/src/services/workflow-effect-driver.ts +2 -0
  343. package/src/services/workflow-effects.ts +18 -11
  344. package/src/services/workflow-land-notice.ts +10 -0
  345. package/src/services/workflow-pause-text.ts +43 -0
  346. package/src/services/workflow-reconcile.ts +13 -11
  347. package/src/services/workflow-run-view.ts +2 -0
  348. package/src/services/workflow-runs.ts +29 -13
  349. package/src/services/workflow-supervisor-state.ts +5 -0
  350. package/src/services/workflow-supervisor.ts +7 -3
  351. package/src/settings/registry.ts +1 -2
  352. package/src/spawn-command.ts +4 -4
  353. package/src/spawn-models.ts +10 -12
  354. package/src/spawn-placement.ts +1 -1
  355. package/src/spawn-targets.ts +1 -1
  356. package/src/startup-context-injection.ts +1 -0
  357. package/src/state-adoption/cd-cutover.ts +53 -7
  358. package/src/state-adoption/fleet-cutover.ts +35 -0
  359. package/src/state-adoption/fleet-plan.ts +36 -0
  360. package/src/state-adoption/index.ts +2 -2
  361. package/src/state-adoption/linux-plan.ts +2 -2
  362. package/src/state-adoption/linux.ts +2 -2
  363. package/src/state-adoption/macos-plan.ts +2 -2
  364. package/src/state-adoption/macos.ts +1 -1
  365. package/src/steward.ts +7 -6
  366. package/src/task-dispatch-live.ts +1 -1
  367. package/src/task-dispatcher.ts +1 -1
  368. package/src/teams-config-store.ts +4 -3
  369. package/src/token-db-write.ts +10 -0
  370. package/src/workspace-command-settle.ts +2 -1
  371. package/src/workspace-steward-wake.ts +2 -2
  372. package/node_modules/@humwick/kernel/LICENSE +0 -167
  373. package/node_modules/@humwick/kernel/async-entity-persistence.ts +0 -344
  374. package/node_modules/@humwick/kernel/async-event-log.ts +0 -107
  375. package/node_modules/@humwick/kernel/automations.pilot.ts +0 -147
  376. package/node_modules/@humwick/kernel/config.ts +0 -111
  377. package/node_modules/@humwick/kernel/contract.ts +0 -572
  378. package/node_modules/@humwick/kernel/control-authz.ts +0 -281
  379. package/node_modules/@humwick/kernel/control.ts +0 -645
  380. package/node_modules/@humwick/kernel/effects.ts +0 -493
  381. package/node_modules/@humwick/kernel/event-log.ts +0 -319
  382. package/node_modules/@humwick/kernel/http-transport.ts +0 -384
  383. package/node_modules/@humwick/kernel/identity-grammar.ts +0 -20
  384. package/node_modules/@humwick/kernel/identity.ts +0 -248
  385. package/node_modules/@humwick/kernel/index.ts +0 -28
  386. package/node_modules/@humwick/kernel/kernel-persistence.ts +0 -181
  387. package/node_modules/@humwick/kernel/landing-incident.ts +0 -306
  388. package/node_modules/@humwick/kernel/landing.ts +0 -953
  389. package/node_modules/@humwick/kernel/manifest-validation.ts +0 -460
  390. package/node_modules/@humwick/kernel/mcp-transport.ts +0 -109
  391. package/node_modules/@humwick/kernel/message-authority-chaos-worker.ts +0 -200
  392. package/node_modules/@humwick/kernel/message-authority.ts +0 -281
  393. package/node_modules/@humwick/kernel/module-host.ts +0 -722
  394. package/node_modules/@humwick/kernel/openapi-init.ts +0 -14
  395. package/node_modules/@humwick/kernel/package.json +0 -47
  396. package/node_modules/@humwick/kernel/persistence-schema.ts +0 -248
  397. package/node_modules/@humwick/kernel/persistence.ts +0 -510
  398. package/node_modules/@humwick/kernel/registry.ts +0 -60
  399. package/node_modules/@humwick/kernel/sqlite-kernel-persistence.ts +0 -499
  400. package/node_modules/@humwick/kernel/sqlite-module-host.ts +0 -87
  401. package/node_modules/@humwick/kernel/timers-chaos-worker.ts +0 -186
  402. package/node_modules/@humwick/kernel/timers.pilot.ts +0 -1411
  403. package/node_modules/@humwick/kernel/workflow-activation.ts +0 -25
  404. package/node_modules/@humwick/kernel/workflow-backstop.ts +0 -40
  405. package/node_modules/@humwick/kernel/workflow-cancel-tree.ts +0 -20
  406. package/node_modules/@humwick/kernel/workflow-chaos-worker.ts +0 -213
  407. package/node_modules/@humwick/kernel/workflow-composition.ts +0 -231
  408. package/node_modules/@humwick/kernel/workflow-container.ts +0 -72
  409. package/node_modules/@humwick/kernel/workflow-control.test-fixture.ts +0 -42
  410. package/node_modules/@humwick/kernel/workflow-control.ts +0 -178
  411. package/node_modules/@humwick/kernel/workflow-definition.ts +0 -507
  412. package/node_modules/@humwick/kernel/workflow-dispatch.ts +0 -60
  413. package/node_modules/@humwick/kernel/workflow-foreach.ts +0 -167
  414. package/node_modules/@humwick/kernel/workflow-journal-codec.ts +0 -339
  415. package/node_modules/@humwick/kernel/workflow-journal.ts +0 -922
  416. package/node_modules/@humwick/kernel/workflow-lane.ts +0 -48
  417. package/node_modules/@humwick/kernel/workflow-lease-owner.ts +0 -60
  418. package/node_modules/@humwick/kernel/workflow-recovery.test-fixture.ts +0 -19
  419. package/node_modules/@humwick/kernel/workflow-runtime.ts +0 -938
  420. package/node_modules/@humwick/kernel/workflow-script.ts +0 -11
  421. package/node_modules/@humwick/kernel/workflow-state.ts +0 -299
  422. package/node_modules/@humwick/kernel/workflow-step-commit.ts +0 -195
  423. package/node_modules/@humwick/kernel/workflow-transitions.ts +0 -317
  424. package/node_modules/@humwick/kernel/workflow-values.ts +0 -153
  425. package/node_modules/@humwick/kernel/workflow.pilot.ts +0 -376
  426. package/node_modules/@humwick/offload/LICENSE +0 -167
  427. package/node_modules/@humwick/offload/README.md +0 -57
  428. package/node_modules/@humwick/offload/dist/async-runner.d.ts +0 -18
  429. package/node_modules/@humwick/offload/dist/async-runner.d.ts.map +0 -1
  430. package/node_modules/@humwick/offload/dist/async-runner.js +0 -158
  431. package/node_modules/@humwick/offload/dist/async-runner.js.map +0 -1
  432. package/node_modules/@humwick/offload/dist/envelope.d.ts +0 -25
  433. package/node_modules/@humwick/offload/dist/envelope.d.ts.map +0 -1
  434. package/node_modules/@humwick/offload/dist/envelope.js +0 -80
  435. package/node_modules/@humwick/offload/dist/envelope.js.map +0 -1
  436. package/node_modules/@humwick/offload/dist/fixtures/worker-task.d.ts +0 -10
  437. package/node_modules/@humwick/offload/dist/fixtures/worker-task.d.ts.map +0 -1
  438. package/node_modules/@humwick/offload/dist/fixtures/worker-task.js +0 -59
  439. package/node_modules/@humwick/offload/dist/fixtures/worker-task.js.map +0 -1
  440. package/node_modules/@humwick/offload/dist/index.d.ts +0 -5
  441. package/node_modules/@humwick/offload/dist/index.d.ts.map +0 -1
  442. package/node_modules/@humwick/offload/dist/index.js +0 -5
  443. package/node_modules/@humwick/offload/dist/index.js.map +0 -1
  444. package/node_modules/@humwick/offload/dist/subprocess-runner.d.ts +0 -62
  445. package/node_modules/@humwick/offload/dist/subprocess-runner.d.ts.map +0 -1
  446. package/node_modules/@humwick/offload/dist/subprocess-runner.js +0 -295
  447. package/node_modules/@humwick/offload/dist/subprocess-runner.js.map +0 -1
  448. package/node_modules/@humwick/offload/dist/types.d.ts +0 -111
  449. package/node_modules/@humwick/offload/dist/types.d.ts.map +0 -1
  450. package/node_modules/@humwick/offload/dist/types.js +0 -176
  451. package/node_modules/@humwick/offload/dist/types.js.map +0 -1
  452. package/node_modules/@humwick/offload/dist/worker-pool.d.ts +0 -23
  453. package/node_modules/@humwick/offload/dist/worker-pool.d.ts.map +0 -1
  454. package/node_modules/@humwick/offload/dist/worker-pool.js +0 -435
  455. package/node_modules/@humwick/offload/dist/worker-pool.js.map +0 -1
  456. package/node_modules/@humwick/offload/dist/worker-runtime.d.ts +0 -2
  457. package/node_modules/@humwick/offload/dist/worker-runtime.d.ts.map +0 -1
  458. package/node_modules/@humwick/offload/dist/worker-runtime.js +0 -27
  459. package/node_modules/@humwick/offload/dist/worker-runtime.js.map +0 -1
  460. package/node_modules/@humwick/offload/dist/worker.d.ts +0 -5
  461. package/node_modules/@humwick/offload/dist/worker.d.ts.map +0 -1
  462. package/node_modules/@humwick/offload/dist/worker.js +0 -1
  463. package/node_modules/@humwick/offload/dist/worker.js.map +0 -1
  464. package/node_modules/@humwick/offload/package.json +0 -46
  465. package/node_modules/@humwick/offload/src/async-runner.ts +0 -170
  466. package/node_modules/@humwick/offload/src/envelope.ts +0 -92
  467. package/node_modules/@humwick/offload/src/fixtures/worker-task.ts +0 -49
  468. package/node_modules/@humwick/offload/src/index.ts +0 -4
  469. package/node_modules/@humwick/offload/src/subprocess-runner.ts +0 -334
  470. package/node_modules/@humwick/offload/src/types.ts +0 -235
  471. package/node_modules/@humwick/offload/src/worker-pool.ts +0 -463
  472. package/node_modules/@humwick/offload/src/worker-runtime.ts +0 -32
  473. package/node_modules/@humwick/offload/src/worker.ts +0 -5
  474. package/public/assets/agent-liveness-DyqxfB-t.js +0 -2
  475. package/public/assets/agent-profiles-BpI_jTxq.js +0 -2
  476. package/public/assets/fleet-BL4UXS_k.js +0 -2
  477. package/public/assets/index-B7ZerHLY.css +0 -2
  478. package/public/assets/index-BK0WV6hF.js +0 -15
  479. package/public/assets/projects-B_lmcqfO.js +0 -2
  480. package/public/assets/provider-display-DbLWpP3j.js +0 -2
  481. package/public/assets/run-card-CO_bguQf.js +0 -2
  482. package/public/assets/use-project-list-B-T2Bnnn.js +0 -2
  483. package/public/assets/versioned-prompt-editor-Diu8BIaM.js +0 -8
  484. package/runner/src/gate-run-lease-probe.ts +0 -38
  485. package/src/db/claude-catalog-reconcile.ts +0 -27
  486. package/src/routing-model-aliases.ts +0 -21
@@ -2,7 +2,7 @@
2
2
  import { messageViewerForRequest, visibleMessages } from "./message-viewer";
3
3
  import { attachPrincipal, attachPrincipals } from "../agent-principal";
4
4
  import { VALID_AGENT_STATUSES, agentSessionStatus, auditEvent, canViewAgentRoute, error, json, normalizeAgentSessionGuard, parseBody, parseId, parseQueryInt, visibleAgentIdsForRequest, type Handler } from "./_shared";
5
- import { ValidationError, deleteAgentAsync, getAgent, getAgentAsync, getAgentIdentityAsync, getAgentQuotaSnapshotsAsync, getAgentTimelineAsync, getCrashReport, recordHeartbeat, listAgentChatHistoryAsync, listAgents, listAgentsAsync, listArtifactsForEntityAsync, listContextSnapshotsAsync, listPendingReplyObligationsAsync, markReadyAsync, searchAgentsAsync, setLabelAsync, setStatusAsync, setTagsAsync, validateAgentSession } from "../db";
5
+ import { ValidationError, deleteAgentAsync, getAgent, getAgentAsync, getAgentIdentityAsync, getAgentQuotaSnapshotsAsync, getAgentTimelineAsync, getCrashReport, recordHeartbeatAsync, listAgentChatHistoryAsync, listAgents, listAgentsAsync, listArtifactsForEntityAsync, listContextSnapshotsAsync, listPendingReplyObligationsAsync, markReadyAsync, searchAgentsAsync, setLabelAsync, setStatusAsync, setTagsAsync, validateAgentSession } from "../db";
6
6
  import { attachBranchState, attachBranchStates } from "../agent-branch-state";
7
7
  import { redactAgentCardLaunchShape } from "../agent-launch-shape-redaction";
8
8
  import { attachChannelBinding, attachChannelBindings } from "../agent-channel-binding";
@@ -258,8 +258,8 @@ function cleanAgentStatus(value: unknown): AgentStatusValue {
258
258
  // #3606 — a reported status/readiness equal to the live card is a liveness tick, not a transition: no
259
259
  // row write, no agent.status event. Presence still advances through the coalescing heartbeat buffer,
260
260
  // except for a terminal row, which a beat would resurrect.
261
- function noteUnchangedLifecycle(agentId: string, current: AgentCard, guard: AgentSessionGuard | undefined): void {
262
- if (current.status !== "offline" && current.status !== "stale") recordHeartbeat(agentId, { guard });
261
+ async function noteUnchangedLifecycle(agentId: string, current: AgentCard, guard: AgentSessionGuard | undefined): Promise<void> {
262
+ if (current.status !== "offline" && current.status !== "stale") await recordHeartbeatAsync(agentId, { guard });
263
263
  }
264
264
 
265
265
  async function applyAgentStatus(agentId: string, status: AgentStatusValue, guard: AgentSessionGuard | undefined, before: AgentCard | null): Promise<boolean> {
@@ -309,7 +309,7 @@ export const patchAgentStatus: Handler = async (req, params) => {
309
309
  const session = validateAgentSession(params.id!, guard);
310
310
  if (!session.ok) return error(session.error!, agentSessionStatus(session.error));
311
311
  const before = getAgent(params.id!);
312
- if (before?.status === status) noteUnchangedLifecycle(params.id!, before, guard);
312
+ if (before?.status === status) await noteUnchangedLifecycle(params.id!, before, guard);
313
313
  else if (!(await applyAgentStatus(params.id!, status, guard, before))) return error("agent not found", 404);
314
314
  } catch (e) {
315
315
  if (e instanceof ValidationError) return error(e.message, 400);
@@ -349,7 +349,7 @@ export const postHeartbeat: Handler = async (req, params) => {
349
349
  // A reported terminal status must not be undone by the beat's offline/stale resurrection.
350
350
  if (status !== "offline" && status !== "stale") {
351
351
  // #1468 — route the API heartbeat through the same coalescing buffer as the bus path.
352
- if (!recordHeartbeat(params.id!, { guard })) return error("agent not found", 404);
352
+ if (!(await recordHeartbeatAsync(params.id!, { guard }))) return error("agent not found", 404);
353
353
  }
354
354
  if (wasUnavailable) {
355
355
  const after = getAgent(params.id!);
@@ -429,7 +429,7 @@ export const patchAgentReady: Handler = async (req, params) => {
429
429
  const session = validateAgentSession(params.id!, guard);
430
430
  if (!session.ok) return error(session.error!, agentSessionStatus(session.error));
431
431
  const before = getAgent(params.id!);
432
- if (before?.ready === body.ready) noteUnchangedLifecycle(params.id!, before, guard);
432
+ if (before?.ready === body.ready) await noteUnchangedLifecycle(params.id!, before, guard);
433
433
  else if (!(await applyAgentReady(params.id!, body.ready, guard, before))) return error("agent not found", 404);
434
434
  } catch (e) {
435
435
  if (e instanceof ValidationError) return error(e.message, 400);
@@ -32,6 +32,10 @@ export const getCommands: Handler = async (req) => {
32
32
  limit: limitRaw ?? undefined,
33
33
  dispatchableOnly,
34
34
  oldestFirst: dispatchableOnly && status === "pending",
35
+ // #3391 — a listing omits each spawn's inline agentProfile (13.9 MB per 30 rows blocked the hub
36
+ // loop); `GET /api/commands/:id` returns the full row. The executor dispatch feed runs the rows it
37
+ // polls, so it keeps the profile.
38
+ slim: !dispatchableOnly,
35
39
  });
36
40
  return json(commands.map((command) => serializeCommandForRead(command, ctx)));
37
41
  };
@@ -29,7 +29,7 @@ import { KERNEL_CORRELATION_PREFIX, isReservedKernelCorrelationId } from "../ser
29
29
  import { prepareScheduledCommandResultForStorage, settleScheduledCommandTimer } from "../services/scheduler-command";
30
30
  import { ServiceAuthError } from "../services/errors";
31
31
  import { applyIdleRefreshResult } from "../maintenance/workspaces";
32
- import { seedMigratedProviderConfigs } from "../provider-config-store";
32
+ import { seedMigratedProviderConfigsAsync } from "../provider-config-store";
33
33
  import { notifyAgentSpawnFailed } from "../agent-lifecycle-events";
34
34
  import { scheduleRepoMerge } from "../workspace-auto-merge";
35
35
  import { settleMemoryInjectionAfterContextCommand } from "../memory-injection";
@@ -559,7 +559,7 @@ export const patchCommand: Handler = async (req, params) => {
559
559
  if (command.type === "orchestrator.migrate-provider-config" && command.status === "succeeded" && isRecord(result)) {
560
560
  // Seed central rows from the reported host-local files with server authority (#465); idempotent, a
561
561
  // stored row wins. Seeds from the request: the persisted result holds only fingerprints (#3403).
562
- const migration = seedMigratedProviderConfigs(result);
562
+ const migration = await seedMigratedProviderConfigsAsync(result);
563
563
  if (migration?.seeded.length) {
564
564
  const { host, seeded } = migration;
565
565
  await auditEvent({
@@ -1,7 +1,7 @@
1
1
  // Auto-split from routes.ts (#299). Domain: continuation archives.
2
2
  import { isRecord } from "@humwick/sdk";
3
3
  import { resolveCallerAgentId } from "../agent-ref";
4
- import { archiveContinuationSegmentAsync, appendContinuationArchiveRefs, getAgent, listAgents, ValidationError } from "../db";
4
+ import { archiveContinuationSegmentAsync, appendContinuationArchiveRefsAsync, getAgent, listAgents, ValidationError } from "../db";
5
5
  import { getComponentAuth } from "../security";
6
6
  import { cleanEpoch, cleanPositiveId, cleanString } from "../validation";
7
7
  import { error, json, parseBody, type Handler } from "./_shared";
@@ -21,7 +21,7 @@ export const postContinuationArchiveRoute: Handler = async (req) => {
21
21
  generation: cleanPositiveId(parsed.body.generation, "generation"),
22
22
  now: cleanEpoch(parsed.body.occurredAt, "occurredAt"),
23
23
  });
24
- const envelope = appendContinuationArchiveRefs(agentId, [archive.ref]);
24
+ const envelope = await appendContinuationArchiveRefsAsync(agentId, [archive.ref]);
25
25
  return json({ archive, envelope }, 201);
26
26
  } catch (e) {
27
27
  if (e instanceof ValidationError) return error(e.message, 400);
@@ -38,7 +38,10 @@ export function cleanHostResourceControl(value: unknown): HostGateResourceContro
38
38
  })) as Partial<Record<HostGateKind, HostGateKindStatus>> : undefined;
39
39
  return { ...(kinds && HOST_GATE_KINDS.every(name => kinds[name]) ? { kinds: kinds as Record<HostGateKind, HostGateKindStatus> } : {}),
40
40
  ...(count(value.iterateOverflow) ? { iterateOverflow: value.iterateOverflow as number } : {}),
41
- ...(typeof value.gateMemoryBytes === "number" && Number.isFinite(value.gateMemoryBytes) && value.gateMemoryBytes > 0 ? { gateMemoryBytes: value.gateMemoryBytes } : {}), ...(gateLimits ? { gateLimits } : {}), ...(reservations ? { projectGateReservations: reservations } : {}), ...(work ? { work, workTruncated: value.workTruncated === true || (value.work as unknown[]).length > 50 } : {}),
41
+ ...Object.fromEntries((["gateMemoryBytes", "gateMemoryUsedBytes", "runMemoryBytes"] as const).flatMap(key => {
42
+ const bytes = value[key];
43
+ return typeof bytes === "number" && Number.isSafeInteger(bytes) && bytes >= 0 ? [[key, bytes]] : [];
44
+ })), ...(gateLimits ? { gateLimits } : {}), ...(reservations ? { projectGateReservations: reservations } : {}), ...(work ? { work, workTruncated: value.workTruncated === true || (value.work as unknown[]).length > 50 } : {}),
42
45
  ...mechanism, usableCpus: usableCpus as number, gateCpus: gateCpus as number,
43
46
  memoryBytes: memoryBytes as number, slots: slots as number, held: held as number, waiters: waiters as number,
44
47
  ...(paths ? { paths } : {}) };
@@ -70,6 +70,7 @@ import { postIssueLifecycleReopenRoute } from "./issue-lifecycle";
70
70
  import { deleteIssueRefRoute, getIssueRefRoute, listIssueRefsRoute, patchIssueRefRoute, postIssueRefRoute, resolveIssueRefRoute } from "./issue-refs";
71
71
  import { deleteProjectEntryRoute, getProjectEntriesRoute, getProjectEntryRoute, getProjectInjectionPreviewRoute, getProjectResolveRoute, getProjectRoute, getProjectsRoute, patchProjectEntryRoute, postProjectEntryRoute } from "./projects";
72
72
  import { getPromptHistoryRoute, postPromptRevisionRoute, getPromptTemplateRoute, getPromptTemplatesRoute, postPromptTemplateResetRoute, putPromptTemplateRoute } from "./prompt-templates";
73
+ import { projectProfileInstructionsRoute } from "./project-profile-instructions";
73
74
  import { getRecipeByName, getRecipeInstanceArtifacts, getRecipeInstanceById, getRecipeInstances, getRecipes, postRecipeInstanceArtifacts, postRecipeStart, postRecipeStop } from "./recipes";
74
75
  import { getSettingRoute, getSettingsNamespaceRoute, getSettingsRoute, putSettingRoute, putSettingsDefaultRoute } from "./settings";
75
76
  import { postNotificationPreviewRoute } from "./notifications";
@@ -85,7 +86,7 @@ import { postMcp } from "../mcp";
85
86
  import { postOrchestratorBootstrap, postOrchestratorBootstrapExchange } from "./orchestrator-bootstrap";
86
87
  import { getDeploysRoute } from "./deploys";
87
88
  import { getGateStatsRoute, getShippingBoardRoute, getShippingStatsRoute, postRedMainAbandonRoute } from "./shipping";
88
- import { getWorkflowCatalogRoute, getWorkflowDefinitionsRoute, getWorkflowRunBudgetRoute, getWorkflowRunRoute, getWorkflowRunsRoute, getWorkflowStatsRoute, patchWorkflowRunBudgetRoute, postWorkflowRunCancelRoute, postWorkflowRunResumeRoute, postWorkflowRunStartRoute } from "./workflows";
89
+ import { getWorkflowCatalogRoute, getWorkflowDefinitionsRoute, getWorkflowRunBudgetRoute, getWorkflowRunRoute, getWorkflowRunsRoute, getWorkflowStatsRoute, patchWorkflowRunBudgetRoute, postWorkflowRunCancelRoute, postWorkflowRunPauseRoute, postWorkflowRunResumeRoute, postWorkflowRunStartRoute, postWorkflowRunUnpauseRoute } from "./workflows";
89
90
  import { getRestartEpochRoute, postRestartEpochAbandonRoute } from "./restart-epochs";
90
91
  import { getFleetConvergenceRoute } from "./fleet-convergence";
91
92
  import { postTimerMessageOperator } from "./kernel-timers-operator";
@@ -318,6 +319,7 @@ const routes: Route[] = [
318
319
  route("DELETE", "/api/commands/:id", deleteCommandById),
319
320
  route("POST", "/api/system/timer-message-cutover/:verb", postTimerMessageOperator),
320
321
  route("GET", "/api/agent-profiles", getAgentProfilesRoute),
322
+ route("GET", "/api/agent-profiles/:name/project-instructions", projectProfileInstructionsRoute),
321
323
  route("GET", "/api/agent-profiles/tool-groups", getAgentProfileToolGroupsRoute),
322
324
  route("POST", "/api/agent-profiles/preview", postAgentProfilePreviewRoute),
323
325
  route("GET", "/api/agent-profiles/:name/resolved", getResolvedAgentProfileRoute),
@@ -546,6 +548,11 @@ const routes: Route[] = [
546
548
  route("PATCH", "/api/issue-refs/:id", patchIssueRefRoute),
547
549
  route("DELETE", "/api/issue-refs/:id", deleteIssueRefRoute),
548
550
  route("GET", "/api/projects", getProjectsRoute),
551
+ route("GET", "/api/projects/:id/profile-instructions", projectProfileInstructionsRoute),
552
+ route("GET", "/api/projects/:id/profile-instructions/:profile", projectProfileInstructionsRoute),
553
+ route("PUT", "/api/projects/:id/profile-instructions/:profile", projectProfileInstructionsRoute),
554
+ route("GET", "/api/projects/:id/profile-instructions/:profile/history", projectProfileInstructionsRoute),
555
+ route("POST", "/api/projects/:id/profile-instructions/:profile/restore", projectProfileInstructionsRoute),
549
556
  route("POST", "/api/projects", postProjectOnboardRoute),
550
557
  route("POST", "/api/projects/:id/checkouts/bind", postProjectBindCheckoutRoute),
551
558
  route("POST", "/api/projects/:id/checkouts/unbind", postProjectUnbindCheckoutRoute),
@@ -600,6 +607,8 @@ const routes: Route[] = [
600
607
  route("GET", "/api/workflows/runs/:runId/budget", getWorkflowRunBudgetRoute),
601
608
  route("PATCH", "/api/workflows/runs/:runId/budget", patchWorkflowRunBudgetRoute),
602
609
  route("POST", "/api/workflows/runs/:runId/cancel", postWorkflowRunCancelRoute),
610
+ route("POST", "/api/workflows/runs/:runId/pause", postWorkflowRunPauseRoute),
611
+ route("POST", "/api/workflows/runs/:runId/unpause", postWorkflowRunUnpauseRoute),
603
612
  route("POST", "/api/workflows/runs/:runId/resume", postWorkflowRunResumeRoute),
604
613
  route("GET", "/api/workflows/stats", getWorkflowStatsRoute),
605
614
  route("GET", "/api/workflows/definitions", getWorkflowDefinitionsRoute),
@@ -1,7 +1,8 @@
1
+ import type { IntegrationRegistryInput } from "../db/integrations";
1
2
  // Auto-split from routes.ts (#299). Domain: integrations.
2
3
  import { INTEGRATION_RATE_LIMIT_PER_MINUTE, MAX_BODY_BYTES, getIntegrationTokens, type IntegrationTokenConfig } from "../config";
3
4
  import { VALID_ARTIFACT_KINDS, VALID_ARTIFACT_ROLES, VALID_TASK_STATUSES, agentSessionStatus, authorizeRoute, cleanAttachmentRefs, dispatchTaskCallbacksInBackground, error, json, normalizeAgentSessionGuard, parseBody, reactionEmoji, sendReactionNotificationToAuthor, validateChannelAttachmentSourceRef, withPayloadAttachments, type Handler } from "./_shared";
4
- import { ValidationError, evaluatePoolBindingsAsync, findMessageByTelegramSourceAsync, getAgent, getChannelAsync, getMessage, ingestIntegrationEvent, isIntegrationRegistryEnabled, listChannelBindingsAsync, listChannelsAsync, listIntegrationRegistry, listIntegrationTaskStats, resolveChannelRoutesAsync, sendMessageWithResult, setMessageReactionAsync, upsertChannelBindingAsync, upsertIntegrationRegistry, validateAgentSession } from "../db";
5
+ import { ValidationError, evaluatePoolBindingsAsync, findMessageByTelegramSourceAsync, getAgent, getChannelAsync, getMessage, ingestIntegrationEvent, isIntegrationRegistryEnabled, listChannelBindingsAsync, listChannelsAsync, listIntegrationTaskStatsAsync, reconcileIntegrationRegistryAsync, resolveChannelRoutesAsync, sendMessageWithResult, setMessageReactionAsync, upsertChannelBindingAsync, upsertIntegrationRegistry, validateAgentSession } from "../db";
5
6
  import { cleanMeta, cleanString, cleanStringArray, optionalEnum } from "../validation";
6
7
  import { emitChannelActivity, emitMessageQueued, emitMessageReactionUpdated, emitNewMessage, emitTaskChanged } from "../sse";
7
8
  import { getComponentAuth, getIntegrationAuth, hasIntegrationScope, isRequestAuthorizedFor } from "../security";
@@ -256,24 +257,7 @@ function normalizeIntegrationEvent(body: unknown): IntegrationEventInput {
256
257
  };
257
258
  }
258
259
 
259
- function normalizeIntegrationRegistryInput(name: string, body: unknown): {
260
- name: string;
261
- displayName?: string;
262
- description?: string;
263
- enabled?: boolean;
264
- scopes?: string[];
265
- targets?: string[];
266
- channels?: string[];
267
- type?: string;
268
- icon?: string;
269
- accentColor?: string;
270
- tags?: string[];
271
- homepageUrl?: string;
272
- repositoryUrl?: string;
273
- docsUrl?: string;
274
- manifest?: Record<string, unknown>;
275
- source: "api";
276
- } {
260
+ function normalizeIntegrationRegistryInput(name: string, body: unknown): IntegrationRegistryInput & { source: "api" } {
277
261
  if (!isRecord(body)) throw new ValidationError("body must be an object");
278
262
  if (body.enabled !== undefined && typeof body.enabled !== "boolean") throw new ValidationError("enabled must be a boolean");
279
263
  return {
@@ -364,40 +348,30 @@ function safeCallbackHost(url: string | undefined): string | undefined {
364
348
  }
365
349
  }
366
350
 
367
- function reconcileIntegrationRegistry(configured: Map<string, IntegrationTokenConfig>, observedStats: Map<string, ReturnType<typeof listIntegrationTaskStats>[number]>): Map<string, ReturnType<typeof listIntegrationRegistry>[number]> {
368
- for (const config of configured.values()) {
369
- upsertIntegrationRegistry({
370
- name: config.name,
371
- displayName: config.displayName,
372
- description: config.description,
373
- scopes: config.scopes,
374
- targets: config.targets,
375
- channels: config.channels,
376
- type: config.type,
377
- icon: config.icon,
378
- accentColor: config.accentColor,
379
- tags: config.tags,
380
- homepageUrl: config.homepageUrl,
381
- repositoryUrl: config.repositoryUrl,
382
- docsUrl: config.docsUrl,
383
- manifest: config.manifest,
384
- source: "env",
385
- });
386
- }
387
- for (const stats of observedStats.values()) {
388
- upsertIntegrationRegistry({
389
- name: stats.source,
390
- enabled: true,
391
- source: "observed",
392
- });
393
- }
394
- return new Map(listIntegrationRegistry().map((integration) => [integration.name, integration]));
351
+ async function reconcileRegistry(configured: Map<string, IntegrationTokenConfig>, observedSources: string[]) {
352
+ const registry = await reconcileIntegrationRegistryAsync([...configured.values()].map((config) => ({
353
+ name: config.name,
354
+ displayName: config.displayName,
355
+ description: config.description,
356
+ scopes: config.scopes,
357
+ targets: config.targets,
358
+ channels: config.channels,
359
+ type: config.type,
360
+ icon: config.icon,
361
+ accentColor: config.accentColor,
362
+ tags: config.tags,
363
+ homepageUrl: config.homepageUrl,
364
+ repositoryUrl: config.repositoryUrl,
365
+ docsUrl: config.docsUrl,
366
+ manifest: config.manifest,
367
+ })), observedSources);
368
+ return new Map(registry.map((integration) => [integration.name, integration]));
395
369
  }
396
370
 
397
- export const getIntegrations: Handler = () => {
371
+ export const getIntegrations: Handler = async () => {
398
372
  const configured = new Map(getIntegrationTokens().map((integration) => [integration.name, integration]));
399
- const observedStats = new Map(listIntegrationTaskStats().map((stats) => [stats.source, stats]));
400
- const registry = reconcileIntegrationRegistry(configured, observedStats);
373
+ const observedStats = new Map((await listIntegrationTaskStatsAsync()).map((stats) => [stats.source, stats]));
374
+ const registry = await reconcileRegistry(configured, [...observedStats.keys()]);
401
375
  const names = [...new Set([...configured.keys(), ...observedStats.keys(), ...registry.keys()])].sort((a, b) => a.localeCompare(b));
402
376
  const now = Date.now();
403
377
 
@@ -1,4 +1,4 @@
1
- import { deleteIssueRefMapping, getIssueRef, listIssueRefs, patchIssueRefMapping, resolveIssueRefMapping, upsertIssueRefMapping, type ListIssueRefsOptions } from "../services/issue-refs";
1
+ import { deleteIssueRefMappingAsync, getIssueRef, listIssueRefs, patchIssueRefMappingAsync, resolveIssueRefMappingAsync, upsertIssueRefMappingAsync, type ListIssueRefsOptions } from "../services/issue-refs";
2
2
  import { getIssueRefByExternalKey, issueRefClosedCompleted, issueRefForRefString } from "../db/issue-refs";
3
3
  import { advanceTerminalPlanRefsAsync } from "../services/plan-terminal-refs";
4
4
  import { cleanEnum, cleanString, optionalEnum } from "../validation";
@@ -76,7 +76,7 @@ export const postIssueRefRoute: Handler = async (req) => {
76
76
  try {
77
77
  const body = cleanUpsertBody(parsed.body);
78
78
  const before = getIssueRefByExternalKey(body.provider, body.repo, body.externalKey);
79
- const issueRef = upsertIssueRefMapping(body);
79
+ const issueRef = await upsertIssueRefMappingAsync(body);
80
80
  // #2520 — a completed close cached here propagates to the plan nodes bound to this ref.
81
81
  if (issueRefClosedCompleted(before, issueRef)) await advanceTerminalPlanRefsAsync({ issueRefId: issueRef.id });
82
82
  return json({ issueRef });
@@ -98,7 +98,7 @@ export const resolveIssueRefRoute: Handler = async (req) => {
98
98
  ? issueRefForRefString(ref, cleanString(value.defaultRepo ?? value.repo, "defaultRepo", { max: 500 }))
99
99
  : getIssueRefByExternalKey(cleanProvider(value.provider), cleanString(value.repo, "repo", { required: true, max: 500 })!, cleanString(value.externalKey, "externalKey", { required: true, max: 240 })!);
100
100
  const issueRef = ref
101
- ? resolveIssueRefMapping({
101
+ ? await resolveIssueRefMappingAsync({
102
102
  ref,
103
103
  defaultRepo: cleanString(value.defaultRepo ?? value.repo, "defaultRepo", { max: 500 }),
104
104
  provider: optionalEnum(value.provider, "provider", ISSUE_PROVIDERS, "github") as IssueProvider,
@@ -107,7 +107,7 @@ export const resolveIssueRefRoute: Handler = async (req) => {
107
107
  closeReason: cleanCloseReason(value.closeReason),
108
108
  statusSyncedAt: cleanTimestamp(value.statusSyncedAt),
109
109
  })
110
- : resolveIssueRefMapping({
110
+ : await resolveIssueRefMappingAsync({
111
111
  provider: cleanProvider(value.provider),
112
112
  repo: cleanString(value.repo, "repo", { required: true, max: 500 })!,
113
113
  externalKey: cleanString(value.externalKey, "externalKey", { required: true, max: 240 })!,
@@ -142,7 +142,7 @@ export const patchIssueRefRoute: Handler = async (req, params) => {
142
142
  try {
143
143
  const id = cleanString(params.id, "id", { required: true, max: 120 })!;
144
144
  const before = getIssueRef(id);
145
- const issueRef = patchIssueRefMapping(id, cleanPatchBody(parsed.body));
145
+ const issueRef = await patchIssueRefMappingAsync(id, cleanPatchBody(parsed.body));
146
146
  if (!issueRef) return error("issue ref not found", 404);
147
147
  // #2520 — a completed close cached here propagates to the plan nodes bound to this ref.
148
148
  if (issueRefClosedCompleted(before, issueRef)) await advanceTerminalPlanRefsAsync({ issueRefId: issueRef.id });
@@ -152,9 +152,9 @@ export const patchIssueRefRoute: Handler = async (req, params) => {
152
152
  }
153
153
  };
154
154
 
155
- export const deleteIssueRefRoute: Handler = (_req, params) => {
155
+ export const deleteIssueRefRoute: Handler = async (_req, params) => {
156
156
  try {
157
- const deleted = deleteIssueRefMapping(cleanString(params.id, "id", { required: true, max: 120 })!);
157
+ const deleted = await deleteIssueRefMappingAsync(cleanString(params.id, "id", { required: true, max: 120 })!);
158
158
  if (!deleted) return error("issue ref not found", 404);
159
159
  return json({ deleted });
160
160
  } catch (err) {
@@ -6,7 +6,7 @@ import { authorizeRoute, cleanSafeNumber, error, json, parseBody, type Handler }
6
6
  import { cleanString, cleanStringArray } from "../validation";
7
7
  import { createTokenAsync, revokeTokenAsync } from "../token-db-write";
8
8
  import { getComponentAuth } from "../security";
9
- import { issueOrchestratorRuntimeToken } from "../runtime-tokens";
9
+ import { issueOrchestratorRuntimeTokenAsync } from "../runtime-tokens";
10
10
  import { type SpawnProvider } from "../types";
11
11
 
12
12
  export const postOrchestratorBootstrap: Handler = async (req) => {
@@ -50,7 +50,7 @@ export const postOrchestratorBootstrap: Handler = async (req) => {
50
50
  "--yes",
51
51
  ];
52
52
  for (const entry of pathPrefix ?? []) args.push("--path-prefix", entry);
53
- const command = ["bunx", `agent-relay-server@${version}`, ...args].map(quoteInstallCommandArg).join(" ");
53
+ const command = ["bunx", `@humwick/server@${version}`, ...args].map(quoteInstallCommandArg).join(" ");
54
54
  return json({
55
55
  command,
56
56
  relayUrl,
@@ -80,7 +80,7 @@ export const postOrchestratorBootstrapExchange: Handler = async (req) => {
80
80
  if (denied) return denied;
81
81
  const auth = getComponentAuth(req);
82
82
  if (!auth || auth.role !== "orchestrator-bootstrap") return error("bootstrap token required", 403);
83
- const runtimeToken = issueOrchestratorRuntimeToken({
83
+ const runtimeToken = await issueOrchestratorRuntimeTokenAsync({
84
84
  orchestratorId: id,
85
85
  baseDir,
86
86
  createdBy: auth.jti ? `bootstrap:${auth.jti}` : "bootstrap",
@@ -4,7 +4,7 @@
4
4
  // upsert, and fanning the operator-facing events out as activity events — lives here.
5
5
  import { isRecord } from "@humwick/sdk";
6
6
  import type { HostHardware } from "@humwick/sdk";
7
- import { upsertHostFromRegistrationAsync, type HostRegistrationEvent } from "../db";
7
+ import { conflictingHardwareFields, upsertHostFromRegistrationAsync, type HostRegistrationEvent } from "../db";
8
8
  import { auditEvent, cleanSafeNumber } from "./_shared";
9
9
  import { recordOrchestratorUtilization } from "./orchestrator-host-utilization";
10
10
  import { cleanString } from "../validation";
@@ -55,7 +55,7 @@ async function emitHostRegistrationEvents(events: readonly HostRegistrationEvent
55
55
  clientId: `host-identity-conflict-${ev.hostId}-${ev.orchestratorId}-${Date.now()}`,
56
56
  kind: "state",
57
57
  title: "Host identity conflict",
58
- body: `${ev.hostname}: reported hardware differs from the stored fingerprint — bound anyway, kept first-seen (conflict:pending)`,
58
+ body: `${ev.hostname}: reported hardware differs from the stored fingerprint (${conflictingHardwareFields(ev.stored, ev.reported).join(", ")} changed) — bound anyway, kept first-seen (conflict:pending)`,
59
59
  meta: ev.hostId,
60
60
  icon: "ti-alert-triangle",
61
61
  view: "orchestrators",
@@ -141,6 +141,7 @@ export function cleanHostUtilizationSample(value: unknown, now: number): HostUti
141
141
  const swapUsedMb = nonNegative(value.swapUsedMb);
142
142
  const diskTotalMb = nonNegative(value.diskTotalMb);
143
143
  const diskFreeMb = nonNegative(value.diskFreeMb);
144
+ const diskPath = optionalString(value.diskPath, "utilization.diskPath", 200);
144
145
 
145
146
  return {
146
147
  at,
@@ -162,7 +163,7 @@ export function cleanHostUtilizationSample(value: unknown, now: number): HostUti
162
163
  ...(swapTotalMb !== undefined && swapUsedMb !== undefined && swapUsedMb <= swapTotalMb
163
164
  ? { swapTotalMb, swapUsedMb } : {}),
164
165
  ...(diskTotalMb !== undefined && diskFreeMb !== undefined && diskFreeMb <= diskTotalMb
165
- ? { diskTotalMb, diskFreeMb } : {}),
166
+ ? { diskTotalMb, diskFreeMb, ...(diskPath ? { diskPath } : {}) } : {}),
166
167
  memPressure,
167
168
  agentCountThisDaemon,
168
169
  queuedSpawnsThisDaemon,
@@ -207,6 +208,7 @@ export function toMachineSample(sample: HostUtilizationSample): HostMachineSampl
207
208
  ...(sample.swapTotalMb !== undefined ? { swapTotalMb: sample.swapTotalMb } : {}),
208
209
  ...(sample.diskFreeMb !== undefined ? { diskFreeMb: sample.diskFreeMb } : {}),
209
210
  ...(sample.diskTotalMb !== undefined ? { diskTotalMb: sample.diskTotalMb } : {}),
211
+ ...(sample.diskPath ? { diskPath: sample.diskPath } : {}),
210
212
  memPressure: sample.memPressure,
211
213
  };
212
214
  }
@@ -1,6 +1,6 @@
1
1
  // Auto-split from routes.ts (#299). Domain: orchestrator-proxy.
2
2
  import { RELAY_TOKEN_HEADER, SPAWN_PROVIDERS, isRecord } from "@humwick/sdk";
3
- import { ValidationError, getOrchestrator, orchestratorHeartbeat } from "../db";
3
+ import { ValidationError, getOrchestrator, orchestratorHeartbeatAsync } from "../db";
4
4
  import { authorizeRoute, cleanJsonArray, error, json, type Handler } from "./_shared";
5
5
  import { cleanStringArray } from "../validation";
6
6
  import { emitOrchestratorStatus } from "../sse";
@@ -136,7 +136,7 @@ export const getOrchestratorProviders: Handler = async (req, params) => {
136
136
  }
137
137
  }
138
138
  }
139
- const updated = orchestratorHeartbeat(params.id!, {
139
+ const updated = await orchestratorHeartbeatAsync(params.id!, {
140
140
  providers,
141
141
  providerStatus: cleanJsonArray(payload.providerStatus, "providerStatus") as OrchestratorRuntimeInput["providerStatus"],
142
142
  providerCatalog: cleanJsonArray(payload.providerCatalog, "providerCatalog") as OrchestratorRuntimeInput["providerCatalog"],
@@ -6,7 +6,7 @@ import { CONTRACT_VERSIONS, parseRuntimeCapabilities, parseRuntimeContracts, par
6
6
  import { notifyAgentOffline, notifyAgentSpawnQueued } from "../agent-lifecycle-events";
7
7
  import { diagnoseReportedExit } from "../services/reported-exit-death";
8
8
  import { VERSION } from "../config";
9
- import { ValidationError, deleteOrchestrator, effectiveProviderCatalogListAsync, getAgent, getOrchestrator, getOrchestratorAsync, listOrchestrators, listOrchestratorsAsync, orchestratorHeartbeat, orchestratorHeartbeatAsync, recordAgentExitDiagnosticsAsync, reportOrchestratorRosterAsync, setOrchestratorUpgradeState, upsertOrchestratorAsync } from "../db";
9
+ import { ValidationError, deleteOrchestrator, effectiveProviderCatalogListAsync, getAgent, getOrchestrator, getOrchestratorAsync, listOrchestrators, listOrchestratorsAsync, orchestratorHeartbeatAsync, recordAgentExitDiagnosticsAsync, reportOrchestratorRosterAsync, setOrchestratorUpgradeStateAsync, upsertOrchestratorAsync } from "../db";
10
10
  import { reconcileOrchestratorSchedulerCommands } from "../services/scheduler-recovery.ts";
11
11
  import { recoverRegisteredOrchestrator } from "../services/orchestrator-registration-recovery";
12
12
  import { recoverOrchestratorLegacyLandings } from "../services/orchestrator-landing-recovery";
@@ -18,7 +18,7 @@ import { cleanMeta, cleanString, cleanStringArray, cleanWorkspaceMetadata, optio
18
18
  import { createCommandAsync } from "../commands-write";
19
19
  import { emitAgentStatus, emitOrchestratorStatus } from "../sse";
20
20
  import { getLifecycleManager } from "../lifecycle-manager";
21
- import { issueOrchestratorRuntimeToken } from "../runtime-tokens";
21
+ import { issueOrchestratorRuntimeTokenAsync } from "../runtime-tokens";
22
22
  import { authContextFromRequest } from "../services/auth-context";
23
23
  import { serializeCommandForRead } from "../services/dispatch-command";
24
24
  import { isOrchestratorRegistrationAuthorized } from "../security";
@@ -198,7 +198,7 @@ export const postOrchestrator: Handler = async (req) => {
198
198
  metadata: { orchestratorId: id, providers: orch.providers, ...authAuditMetadata(req) },
199
199
  });
200
200
  const runtimeToken = isRootCredentialRequest(req)
201
- ? issueOrchestratorRuntimeToken({ orchestratorId: id, baseDir, createdBy: `orchestrator:${id}` })
201
+ ? await issueOrchestratorRuntimeTokenAsync({ orchestratorId: id, baseDir, createdBy: `orchestrator:${id}` })
202
202
  : undefined;
203
203
  const hostProviders = await hostProviderSync(id, envProviders);
204
204
  return json({ ...orch, ...(runtimeToken ? { runtimeToken } : {}), hostProviders, gateBudget: gateBudgetForOrchestrator(id) }, 201);
@@ -624,7 +624,7 @@ export const postOrchestratorAction: Handler = async (req, params) => {
624
624
  ...(mode === "git-checkout" ? { mode, commitSha, repoUrl } : (npmReuseRepoUrl ? { repoUrl: npmReuseRepoUrl } : {})),
625
625
  },
626
626
  });
627
- setOrchestratorUpgradeState(orch.id, {
627
+ await setOrchestratorUpgradeStateAsync(orch.id, {
628
628
  desiredVersion: targetVersion, ...(mode === "git-checkout" && commitSha ? { targetGitSha: commitSha } : {}),
629
629
  status: "pending",
630
630
  commandId: command.id,
@@ -0,0 +1,27 @@
1
+ import { cleanString } from "../validation";
2
+ import { ValidationError } from "../db/connection";
3
+ import { authorizeRoute, error, json, parseBody, type Handler } from "./_shared";
4
+ import { authContextFromRequest } from "../services/auth-context";
5
+ import { PromptVersionConflictError } from "../prompt-version-errors";
6
+ import { listProjectProfileInstructions, mutateProjectProfileInstructions, projectProfileInstructionHistory, readProjectProfileInstructions } from "../services/project-profile-instructions";
7
+
8
+ export const projectProfileInstructionsRoute: Handler = async (req, params) => {
9
+ const denied = authorizeRoute(req, { scope: req.method === "GET" ? "agent:read" : "agent:write" });
10
+ if (denied) return denied;
11
+ try {
12
+ const projectId = cleanString(params.id, "projectId", { max: 200 });
13
+ const profile = cleanString(params.profile ?? params.name, "profile", { max: 200 });
14
+ if (!projectId || !profile) return json(await listProjectProfileInstructions({ projectId, profile }));
15
+ const path = new URL(req.url).pathname;
16
+ if (req.method === "GET") return json(path.endsWith("/history")
17
+ ? await projectProfileInstructionHistory(projectId, profile)
18
+ : await readProjectProfileInstructions(projectId, profile));
19
+ const body = await parseBody<unknown>(req);
20
+ if (!body.ok) return error(body.error, body.status);
21
+ return json(await mutateProjectProfileInstructions(authContextFromRequest(req), projectId, profile, body.body, path.endsWith("/restore")));
22
+ } catch (err) {
23
+ if (err instanceof PromptVersionConflictError) return json({ error: err.message, current: err.current }, 409);
24
+ if (err instanceof ValidationError) return error(err.message, /not found/.test(err.message) ? 404 : 400);
25
+ throw err;
26
+ }
27
+ };
@@ -5,7 +5,7 @@
5
5
  // code runs, and built-in profiles are admin-edited anyway.
6
6
  import { isRecord } from "@humwick/sdk";
7
7
  import { ValidationError } from "../db";
8
- import { approveProfileProjectTrust, PROJECT_REVIEW_MODES, PROJECT_TRUST_CAPABILITIES, updateProfileProjectTrust } from "../services/profile-trust";
8
+ import { approveProfileProjectTrust, PROJECT_REVIEW_MODES, PROJECT_TRUST_CAPABILITIES, updateProfileProjectTrustAsync } from "../services/profile-trust";
9
9
  import { cleanString, optionalEnum } from "../validation";
10
10
  import { auditEvent, error, isAdminRequest, json, normalizeConfigPathParam, parseBody, requestUserAddress, type Handler } from "./_shared";
11
11
  import { getAgentProfile } from "../config-store";
@@ -57,7 +57,7 @@ export const patchProjectTrustRoute: Handler = async (req, params) => {
57
57
  if (body.ack !== undefined && !Array.isArray(body.ack)) return error("ack must be an array of hooks|mcp", 400);
58
58
  const ack = (body.ack as unknown[] | undefined)?.map((capability) => optionalEnum(capability, "ack", PROJECT_TRUST_CAPABILITIES)!);
59
59
  const by = requestUserAddress(req);
60
- const saved = updateProfileProjectTrust(name, { ...(review ? { review } : {}), ...(ack ? { ack } : {}) }, by);
60
+ const saved = await updateProfileProjectTrustAsync(name, { ...(review ? { review } : {}), ...(ack ? { ack } : {}) }, by);
61
61
  await auditEvent({
62
62
  kind: "state",
63
63
  title: `Project trust updated: ${saved.value.name}`,
@@ -3,9 +3,10 @@ import { ValidationError, effectiveProviderCatalogListAsync, listOrchestrators,
3
3
  import { chooseProviderDefaultModel } from "../services/provider-catalog";
4
4
  import { applyCommandToRecipe } from "../recipe-runner";
5
5
  import { cleanString, cleanStringArray, optionalEnum } from "../validation";
6
- import { deleteCommand, getCommand } from "../commands-db";
6
+ import { getCommand } from "../commands-db";
7
+ import { deleteCommandAsync } from "../commands-write";
7
8
  import { emitCommand, error, json, parseBody, type Handler } from "./_shared";
8
- import { getProviderConfigEntry, listProviderConfigEntries, migrateLocalProviderConfigs, providerConfigPublic, setProviderConfig, VALID_PROVIDER_CONFIGS } from "../provider-config-store";
9
+ import { getProviderConfigEntry, listProviderConfigEntries, migrateLocalProviderConfigsAsync, providerConfigPublic, setProviderConfigAsync, VALID_PROVIDER_CONFIGS } from "../provider-config-store";
9
10
  import { cleanProviderModelLimits } from "../provider-catalog-store";
10
11
  import { emitConfigChanged } from "../sse";
11
12
  import { setConfigAsync } from "../config-store-write";
@@ -27,9 +28,9 @@ export const getProvidersRoute: Handler = async () => {
27
28
  });
28
29
  };
29
30
 
30
- export const getProviderConfigsRoute: Handler = (req) => {
31
+ export const getProviderConfigsRoute: Handler = async (req) => {
31
32
  const host = new URL(req.url).searchParams.get("host") ?? undefined;
32
- migrateLocalProviderConfigs();
33
+ await migrateLocalProviderConfigsAsync();
33
34
  const entries = listProviderConfigEntries(host);
34
35
  return json(Object.fromEntries(VALID_PROVIDER_CONFIGS.map((provider) => {
35
36
  return [provider, providerConfigPublic(entries[provider] ?? getProviderConfigEntry(provider, host))];
@@ -126,12 +127,12 @@ export const deleteProviderModelRoute: Handler = async (_req, params) => {
126
127
  }
127
128
  };
128
129
 
129
- export const getProviderConfigRoute: Handler = (_req, params) => {
130
+ export const getProviderConfigRoute: Handler = async (_req, params) => {
130
131
  const provider = optionalEnum(params.provider, "provider", VALID_PROVIDER_CONFIGS);
131
132
  if (!provider) return error("provider required");
132
133
  const host = new URL(_req.url).searchParams.get("host") ?? undefined;
133
134
  const includeSecrets = new URL(_req.url).searchParams.get("includeSecrets") === "1";
134
- migrateLocalProviderConfigs();
135
+ await migrateLocalProviderConfigsAsync();
135
136
  return json(providerConfigPublic(getProviderConfigEntry(provider, host), { maskEnv: !includeSecrets }));
136
137
  };
137
138
 
@@ -144,7 +145,7 @@ export const putProviderConfigRoute: Handler = async (req, params) => {
144
145
  if (!isRecord(parsed.body)) return error("provider config body must be an object");
145
146
  const host = new URL(req.url).searchParams.get("host") ?? undefined;
146
147
  const updatedBy = cleanString(parsed.body.updatedBy, "updatedBy", { max: 200 });
147
- const entry = setProviderConfig(provider, parsed.body, { host, updatedBy });
148
+ const entry = await setProviderConfigAsync(provider, parsed.body, { host, updatedBy });
148
149
  emitConfigChanged(entry.namespace, entry.key, entry.version);
149
150
  return json(providerConfigPublic(entry), entry.version === 1 ? 201 : 200);
150
151
  } catch (e) {
@@ -222,7 +223,7 @@ function optionalFraction(value: unknown, field: string): number | undefined {
222
223
  }
223
224
 
224
225
  export const deleteCommandById: Handler = async (_req, params) => {
225
- if (!deleteCommand(params.id!)) return error("command not found or cannot be canceled", 404);
226
+ if (!await deleteCommandAsync(params.id!)) return error("command not found or cannot be canceled", 404);
226
227
  const command = getCommand(params.id!);
227
228
  if (command) {
228
229
  await applyCommandToRecipe(command);
@@ -8,7 +8,7 @@ import { error, json, parseBody, type Handler } from "./_shared";
8
8
  import {
9
9
  getProviderQuotaConfig,
10
10
  listProviderQuotaConfigs,
11
- setProviderQuotaConfig,
11
+ setProviderQuotaConfigAsync,
12
12
  VALID_QUOTA_CONFIG_PROVIDERS,
13
13
  } from "../provider-quota-config-store";
14
14
  import { cleanString, optionalEnum } from "../validation";
@@ -40,7 +40,7 @@ export const putProviderQuotaConfigRoute: Handler = async (req, params) => {
40
40
  if (!parsed.ok) return error(parsed.error, parsed.status);
41
41
  try {
42
42
  const updatedBy = isRecord(parsed.body) ? cleanString(parsed.body.updatedBy, "updatedBy", { max: 200 }) : undefined;
43
- return json(setProviderQuotaConfig(provider, parsed.body, { updatedBy }));
43
+ return json(await setProviderQuotaConfigAsync(provider, parsed.body, { updatedBy }));
44
44
  } catch (e) {
45
45
  if (e instanceof ValidationError) return error(e.message, 400);
46
46
  throw e;
@@ -4,7 +4,7 @@ import { ValidationError } from "../db";
4
4
  import { getConfig } from "../config-store";
5
5
  import { setConfigAsync } from "../config-store-write";
6
6
  import { getUserSettingAsync, setUserSettingAsync } from "../user-settings-async";
7
- import { ensureProviderConfigDescriptors, migrateLocalProviderConfigs } from "../provider-config-store";
7
+ import { ensureProviderConfigDescriptors, migrateLocalProviderConfigsAsync } from "../provider-config-store";
8
8
  import { ensureNotificationSettingDescriptors } from "../notification-settings-store";
9
9
  import { NOTIFICATIONS_NAMESPACE } from "../notification-settings";
10
10
  import { getSettingDescriptor, listSettingDescriptors, validateSettingValue, PROVIDER_CONFIG_NAMESPACE } from "../settings/registry";
@@ -23,7 +23,7 @@ type SettingEnvelope = SettingEntry;
23
23
  // as before the migration (back-compat). Server-runtime/bootstrap/browser tiers ignore this.
24
24
 
25
25
  export const getSettingsRoute: Handler = async (req) => {
26
- migrateLocalProviderConfigs();
26
+ await migrateLocalProviderConfigsAsync();
27
27
  ensureProviderConfigDescriptors();
28
28
  ensureNotificationSettingDescriptors();
29
29
  return json({ settings: await listVisibleSettings(req) });
@@ -31,7 +31,7 @@ export const getSettingsRoute: Handler = async (req) => {
31
31
 
32
32
  export const getSettingsNamespaceRoute: Handler = async (req, params) => {
33
33
  const namespace = normalizeConfigPathParam(params.namespace, "namespace");
34
- migrateLocalProviderConfigs();
34
+ await migrateLocalProviderConfigsAsync();
35
35
  ensureProviderConfigDescriptors();
36
36
  if (namespace === NOTIFICATIONS_NAMESPACE) ensureNotificationSettingDescriptors();
37
37
  const settings = await listVisibleSettings(req);
@@ -41,7 +41,7 @@ export const getSettingsNamespaceRoute: Handler = async (req, params) => {
41
41
  export const getSettingRoute: Handler = async (req, params) => {
42
42
  const namespace = normalizeConfigPathParam(params.namespace, "namespace");
43
43
  const key = normalizeConfigPathParam(params.key, "key");
44
- migrateLocalProviderConfigs();
44
+ await migrateLocalProviderConfigsAsync();
45
45
  ensureProviderConfigDescriptors(namespace === PROVIDER_CONFIG_NAMESPACE ? [key] : []);
46
46
  if (namespace === NOTIFICATIONS_NAMESPACE) ensureNotificationSettingDescriptors([key]);
47
47
  const descriptor = getSettingDescriptor(namespace, key);
@@ -82,7 +82,7 @@ async function putSetting(req: Request, namespaceRaw: string | undefined, keyRaw
82
82
  if (!Object.prototype.hasOwnProperty.call(parsed.body, "value")) return error("value required", 400);
83
83
 
84
84
  try {
85
- migrateLocalProviderConfigs();
85
+ await migrateLocalProviderConfigsAsync();
86
86
  ensureProviderConfigDescriptors(namespace === PROVIDER_CONFIG_NAMESPACE ? [key] : []);
87
87
  if (namespace === NOTIFICATIONS_NAMESPACE) ensureNotificationSettingDescriptors([key]);
88
88
  const descriptor = getSettingDescriptor(namespace, key);