@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
@@ -7,14 +7,13 @@ import { getAgent } from "./db/agents";
7
7
  import { getOrchestratorAsync } from "./db/orchestrators-async";
8
8
  import { composeProfileSpawnInstructions, composeProfileSpawnInstructionsAsync } from "./project-instructions";
9
9
  import { getSelfEffortCeiling } from "./db/self-effort-permissions";
10
- import { runnerRuntimeTokenEnv, type RunnerLaunchAuthority } from "./runtime-tokens";
11
- import { gatewayBackend } from "./db/gateway";
10
+ import { runnerRuntimeTokenEnv, runnerRuntimeTokenEnvAsync, type RunnerLaunchAuthority, type RunnerRuntimeTokenInput } from "./runtime-tokens";
12
11
  import { recordedLaunchMode, resolveHostLaunchMode } from "./launch-mode";
13
12
  import { buildSpawnCommand, generateSpawnAgentId, resolveSpawnModelParams, resolveSpawnModelParamsAsync } from "./spawn-command";
14
13
  import { applyDefaultSharedMcp } from "./shared-mcp";
15
14
  import { AGENT_SYSTEM_TAGS, systemTagsForSpawn } from "./agent-system-tags";
16
15
  import { buildWhoamiDefaultForAgent } from "./mcp/identity-projection";
17
- import { isStewardPolicy, isGenuineStewardPolicy, stewardWorktreeCwdPrefixes } from "./steward-spawn-guard";
16
+ import { isGenuineStewardPolicy, stewardWorktreeCwdPrefixes } from "./steward-spawn-guard";
18
17
  // #2033 — from isolated-workspace-placement.ts, NOT ./services/spawn-identity: that module also
19
18
  // exports buildProspectiveSpawnIdentity, which imports mcp/identity.ts → self-resume.ts →
20
19
  // restart-spawn.ts → managed-policy.ts, and importing it here would close that into a cycle.
@@ -97,7 +96,8 @@ export function buildManagedSpawnParams(policy: SpawnPolicy, requestId: string,
97
96
  const composed = composeProfileSpawnInstructions(managedInstructionInput(policy, agentProfile, agentRelayIdentity, orchestratorHost, alwaysOnAppend));
98
97
 
99
98
  return buildManagedCommand({ policy, requestId, ctx, agentId, prompt, agentProfile, orchestrator, extraCwdPrefixes, composed,
100
- modelParams: resolveSpawnModelParams(policy.provider, policy.model, policy.effort, { skipDefaultWhenEmpty: !isStewardPolicy(policy) }),
99
+ modelParams: resolveSpawnModelParams(policy.provider, policy.model, policy.effort),
100
+ env: runnerRuntimeTokenEnv(managedTokenInput(policy, requestId, ctx, agentId, extraCwdPrefixes)),
101
101
  });
102
102
  }
103
103
 
@@ -147,6 +147,7 @@ function buildManagedCommand(input: {
147
147
  extraCwdPrefixes: string[];
148
148
  composed: ReturnType<typeof composeProfileSpawnInstructions>;
149
149
  modelParams: ReturnType<typeof resolveSpawnModelParams>;
150
+ env: Record<string, string>;
150
151
  }): Record<string, unknown> {
151
152
  const { policy, requestId, ctx, agentId, prompt, agentProfile, orchestrator, extraCwdPrefixes, composed, modelParams } = input;
152
153
  return buildSpawnCommand({
@@ -177,26 +178,31 @@ function buildManagedCommand(input: {
177
178
  headless: true,
178
179
  policyName: policy.name,
179
180
  spawnRequestId: requestId,
180
- env: runnerRuntimeTokenEnv({
181
- agentId,
182
- orchestratorId: policy.orchestratorId,
183
- cwd: policy.cwd,
184
- provider: policy.provider,
185
- label: policy.label,
186
- policyName: policy.name,
187
- spawnRequestId: requestId,
188
- createdBy: ctx.createdBy,
189
- authority: ctx.authority,
190
- profile: policy.profile || undefined,
191
- // #2245 — the same posture this launch is given above; stamped into the signed constraints.
192
- approvalMode: policy.permissionMode,
193
- ...(extraCwdPrefixes.length ? { extraCwdPrefixes } : {}),
194
- }),
181
+ env: input.env,
195
182
  requestedBy: ctx.createdBy,
196
183
  requestedAt: ctx.requestedAt ?? Date.now(),
197
184
  });
198
185
  }
199
186
 
187
+ /** The runner token a managed launch carries; the sync builder and the writer-op builder mint the same input. */
188
+ function managedTokenInput(policy: SpawnPolicy, requestId: string, ctx: ManagedSpawnContext, agentId: string, extraCwdPrefixes: string[]): RunnerRuntimeTokenInput {
189
+ return {
190
+ agentId,
191
+ orchestratorId: policy.orchestratorId,
192
+ cwd: policy.cwd,
193
+ provider: policy.provider,
194
+ label: policy.label,
195
+ policyName: policy.name,
196
+ spawnRequestId: requestId,
197
+ createdBy: ctx.createdBy,
198
+ authority: ctx.authority,
199
+ profile: policy.profile || undefined,
200
+ // #2245 — the same posture this launch is given above; stamped into the signed constraints.
201
+ approvalMode: policy.permissionMode,
202
+ ...(extraCwdPrefixes.length ? { extraCwdPrefixes } : {}),
203
+ };
204
+ }
205
+
200
206
  // #2656 — backstop for every managed launch path (policy start/restart routes, agent restart): no
201
207
  // new process starts on a disabled provider. The lifecycle manager parks the policy before this.
202
208
  function assertManagedProviderEnabled(message: string | undefined): void {
@@ -205,15 +211,12 @@ function assertManagedProviderEnabled(message: string | undefined): void {
205
211
 
206
212
  /** Worker-safe counterpart used by every runtime managed launch path. The synchronous builder
207
213
  * remains for in-process unit fixtures; production must never borrow its main-thread connection. */
208
- export function buildManagedSpawnParamsAsync(policy: SpawnPolicy, requestId: string, ctx: ManagedSpawnContext): Record<string, unknown> | Promise<Record<string, unknown>> {
214
+ export async function buildManagedSpawnParamsAsync(policy: SpawnPolicy, requestId: string, ctx: ManagedSpawnContext): Promise<Record<string, unknown>> {
209
215
  if (effectiveManagedPolicyWorkspaceMode(policy) === "isolated" && ctx.gitRepoRoot === undefined) {
210
- return getOrchestratorAsync(policy.orchestratorId).then(async (host) => buildManagedSpawnParamsAsync(policy, requestId, {
211
- ...ctx, gitRepoRoot: host ? await resolveSpawnRepoRoot(host, policy.cwd) : null,
212
- }));
216
+ const host = await getOrchestratorAsync(policy.orchestratorId);
217
+ ctx = { ...ctx, gitRepoRoot: host ? await resolveSpawnRepoRoot(host, policy.cwd) : null };
213
218
  }
214
- // Preserve immediate in-process command construction for durable policy wake callers. The worker
215
- // backend never enters this synchronous branch, so it cannot reopen the closed-main DB path.
216
- return gatewayBackend() === "in-process" ? buildManagedSpawnParams(policy, requestId, ctx) : buildManagedSpawnParamsWorkerAsync(policy, requestId, ctx);
219
+ return buildManagedSpawnParamsWorkerAsync(policy, requestId, ctx);
217
220
  }
218
221
 
219
222
  async function buildManagedSpawnParamsWorkerAsync(policy: SpawnPolicy, requestId: string, ctx: ManagedSpawnContext): Promise<Record<string, unknown>> {
@@ -231,6 +234,7 @@ async function buildManagedSpawnParamsWorkerAsync(policy: SpawnPolicy, requestId
231
234
  const extraCwdPrefixes = managedCwdPrefixes(policy, requestId, ctx, orchestrator);
232
235
  const composed = await composeProfileSpawnInstructionsAsync(managedInstructionInput(policy, agentProfile, agentRelayIdentity, orchestratorHost, alwaysOnAppend));
233
236
  return buildManagedCommand({ policy, requestId, ctx, agentId, prompt, agentProfile, orchestrator, extraCwdPrefixes, composed,
234
- modelParams: await resolveSpawnModelParamsAsync(policy.provider, policy.model, policy.effort, { skipDefaultWhenEmpty: !isStewardPolicy(policy) }),
237
+ modelParams: await resolveSpawnModelParamsAsync(policy.provider, policy.model, policy.effort),
238
+ env: await runnerRuntimeTokenEnvAsync(managedTokenInput(policy, requestId, ctx, agentId, extraCwdPrefixes)),
235
239
  });
236
240
  }
package/src/mcp/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { normalizeOutputArgs, outputToolDefinition, presentToolOutput } from "./output-levels";
2
2
  import { PROMPT_TOOLS, relayPrompt } from "./prompts";
3
+ import { PROJECT_PROFILE_INSTRUCTION_TOOLS, relayProjectProfileInstructions } from "./project-profile-instructions";
3
4
  import { PromptVersionConflictError } from "../prompt-version-errors";
4
5
  import { memoryRetirementMessage } from "../memory-retirement";
5
6
  import { GUIDE_TOOLS, relayGuide } from "./guides";
@@ -60,6 +61,7 @@ const MCP_PROTOCOL_VERSION = "2024-11-05";
60
61
  const MCP_BODY_OVERHEAD_BYTES = ARTIFACT_BODY_OVERHEAD_BYTES;
61
62
  const TOOLS: ToolDefinition[] = [
62
63
  ...PROMPT_TOOLS,
64
+ ...PROJECT_PROFILE_INSTRUCTION_TOOLS,
63
65
  ...WEB_TOOL_CALL_TOOLS,
64
66
  ...MESSAGING_TOOLS,
65
67
  ...ARTIFACT_TOOLS,
@@ -215,6 +217,7 @@ async function callTool(auth: VerifiedMcpAuthContext, params: unknown, signal?:
215
217
  else if (name === "relay_hosts") result = await relayHosts(auth, args);
216
218
  else if (name === "relay_host_gate_budget") result = await relayHostGateBudget(auth, args);
217
219
  else if (name === "relay_prompt") result = await relayPrompt(auth, args);
220
+ else if (name === "relay_project_profile_instructions") result = await relayProjectProfileInstructions(auth, args);
218
221
  else if (name === "relay_service_access") result = await relayServiceAccess(auth, args);
219
222
  else if (name.startsWith("relay_secret_")) result = await relaySecretTool(auth, name, args);
220
223
  else if (name === "relay_my_agents") result = await relayMyAgents(auth, args);
@@ -223,7 +226,7 @@ async function callTool(auth: VerifiedMcpAuthContext, params: unknown, signal?:
223
226
  else if (name === "relay_agent_keep") result = await relayAgentKeep(auth, args);
224
227
  else if (name === "relay_codex_reset_consume") result = await relayCodexResetConsume(args);
225
228
  else if (name === "relay_claude_api_budget") result = await relayClaudeApiBudget(args);
226
- else if (name === "relay_profile_trust") result = relayProfileTrust(auth, args);
229
+ else if (name === "relay_profile_trust") result = await relayProfileTrust(auth, args);
227
230
  else if (name.startsWith("relay_routing_policy_")) result = await relayRoutingPolicyTool(auth, name, args);
228
231
  else if (name === "relay_agent_action") result = await relayAgentAction(auth, args);
229
232
  else if (name === "relay_set_effort") result = await relaySetEffort(auth, args);
@@ -253,7 +256,7 @@ async function callTool(auth: VerifiedMcpAuthContext, params: unknown, signal?:
253
256
  // #2591 — the journal tools must claim their prefix BEFORE the generic relay_project_
254
257
  // dispatcher, or they would fall through to relayProjectTool as "unknown tool".
255
258
  else if (name.startsWith("relay_project_journal_")) result = relayProjectJournalTool(auth, name, args);
256
- else if (name === "relay_project_ingest_claudemd") result = await relayProjectIngestClaudeMd(auth, args); else if (name.startsWith("relay_project_")) result = await relayProjectTool(auth, name, args); else if (name.startsWith("relay_issue_ref_")) result = relayIssueRefTool(auth, name, args); else if (name.startsWith("relay_issue_association_")) result = relayIssueAssociationTool(auth, name, args); else if (name.startsWith("relay_issue_activity_")) result = await relayIssueActivityTool(auth, name, args); else if (name.startsWith("relay_issue_lifecycle_")) result = await relayIssueLifecycleTool(auth, name, args);
259
+ else if (name === "relay_project_ingest_claudemd") result = await relayProjectIngestClaudeMd(auth, args); else if (name.startsWith("relay_project_")) result = await relayProjectTool(auth, name, args); else if (name.startsWith("relay_issue_ref_")) result = await relayIssueRefTool(auth, name, args); else if (name.startsWith("relay_issue_association_")) result = relayIssueAssociationTool(auth, name, args); else if (name.startsWith("relay_issue_activity_")) result = await relayIssueActivityTool(auth, name, args); else if (name.startsWith("relay_issue_lifecycle_")) result = await relayIssueLifecycleTool(auth, name, args);
257
260
  else if (name === "relay_subscribe" || name === "relay_unsubscribe" || name === "relay_list_subscriptions" || name === "relay_why_notified" || name === "relay_notification_preview") result = await relayNotificationSubscriptionTool(auth, name, args);
258
261
  else if (name === "relay_notify_ntfy") result = relayNotifyNtfy(args);
259
262
  else if (name === "relay_delete_channel_binding") result = await relayDeleteChannelBinding(args, auth);
@@ -27,14 +27,14 @@ export const OUTPUT_DESCRIPTIONS: Record<string, string> = {
27
27
  relay_kernel_listEntities: "List entities.",
28
28
  relay_kernel_listEvents: "List events.",
29
29
  relay_kernel_listInstances: "List workflow instances.",
30
- relay_list_artifacts: "List artifacts; relay_read_artifact reads bodies.",
30
+ relay_list_artifacts: "List artifacts (metadata only).",
31
31
  relay_list_subscriptions: "Your subscriptions",
32
32
  relay_list_timers: "List your scheduled timers.",
33
33
  relay_maintenance_jobs: "Job health; jobId reads runbook.",
34
34
  relay_maintenance_pauses: "Maintenance pauses.",
35
35
  relay_merge_pauses: "Merge holds",
36
36
  relay_notification_preview: "Preview notification routing.",
37
- relay_plan_get: "Read plan; mode:resume selects the frontier view.",
37
+ relay_plan_get: "Read plan; mode:resume reads the frontier.",
38
38
  relay_plan_list: "List team plans.",
39
39
  relay_project_checkout: "Inspect, bind, unbind (keeps files) or remove (deletes files) a checkout.",
40
40
  relay_project_get: "Read project and roots.",
@@ -44,7 +44,7 @@ export const OUTPUT_DESCRIPTIONS: Record<string, string> = {
44
44
  relay_project_search: "Search memory; read full bodies by returned ids.",
45
45
  relay_prompt: "Read/edit prompts; writes need expectedVersion; restore/adopt append.",
46
46
  relay_read_artifact: "Page artifact text; binary returns download command.",
47
- relay_recall: "Search history; read a returned ref for the segment.",
47
+ relay_recall: "Search history; read a returned ref.",
48
48
  relay_release_readiness: "Read release readiness.",
49
49
  relay_routing_policy_get: "Read policy",
50
50
  relay_run: "Run shell work. Long work: waitMs:0, END YOUR TURN and await completion; never poll.",
@@ -53,17 +53,17 @@ export const OUTPUT_DESCRIPTIONS: Record<string, string> = {
53
53
  relay_task_close_bridge: "Read Task close-bridge state.",
54
54
  relay_task_get: "Read Task hydration.",
55
55
  relay_task_history: "Read Task history.",
56
- relay_task_list: "List your Tasks; mine:false lists all.",
56
+ relay_task_list: "Tasks.",
57
57
  relay_task_memory_read: "Read Task continuation.",
58
58
  relay_task_needs_validation: "List Tasks awaiting validation.",
59
59
  relay_team_get: "Read team and roster summary.",
60
60
  relay_team_template_get: "Read saved",
61
61
  relay_team_template_list: "Saved",
62
- relay_web_tool_calls: "Page web calls newest first; times are epoch milliseconds.",
62
+ relay_web_tool_calls: "Page web calls, newest first; epoch ms.",
63
63
  relay_why_notified: "Explain delivery.",
64
- relay_workflow_cancel: "Cancel run and reap agents.",
65
- relay_workflow_get: "Read run status; history and result pages are opt-in.",
66
- relay_workflow_resume: "Resume or answer/escalate a decision.",
64
+ relay_workflow_cancel: "Cancel run; reap agents.",
65
+ relay_workflow_get: "Read run status; history opt-in.",
66
+ relay_workflow_resume: "Resume, pause/unpause, or answer/escalate a decision.",
67
67
  relay_workflow_start: "Start Task workflow.",
68
68
  relay_workspace_deps: "Check or refresh workspace dependencies.",
69
69
  relay_workspace_list: "List workspaces.",
@@ -50,7 +50,7 @@ export type PresentationVerbosity = "brief" | "lean" | "default" | "verbose";
50
50
 
51
51
  type TaskGateSummary = Record<TaskGateStatus, number> & { total: number };
52
52
 
53
- type TaskDetailLeanPresentation = Pick<TaskDetail, "validationItems" | "staleOwnerGone" | "terminalStage" | "completedAt" | "owner"> & {
53
+ type TaskDetailLeanPresentation = Pick<TaskDetail, "validationItems" | "staleOwnerGone" | "terminalStage" | "completedAt" | "owner" | "onDeploy"> & {
54
54
  id: number;
55
55
  title: string;
56
56
  status: string;
@@ -328,7 +328,7 @@ export function projectTaskList(
328
328
  return tasks.map((task) => ({
329
329
  id: task.id,
330
330
  label: truncateTaskListLabel(task.label),
331
- status: task.status, ...taskValidationProjection(task),
331
+ status: task.status, ...taskValidationProjection(task), ...(task.onDeploy ? { onDeploy: task.onDeploy } : {}),
332
332
  }));
333
333
  }
334
334
  return tasks.map((task) => {
@@ -339,7 +339,7 @@ export function projectTaskList(
339
339
  status: task.status,
340
340
  deliverableStage: task.deliverableStage ?? null,
341
341
  ownerAgentId: task.ownerAgentId ?? null,
342
- ...taskValidationProjection(task),
342
+ ...taskValidationProjection(task), ...(task.onDeploy ? { onDeploy: task.onDeploy } : {}),
343
343
  updatedAt: updatedAt.relative,
344
344
  ...(crossRepo && task.repo ? { repo: task.repo } : {}),
345
345
  };
@@ -368,7 +368,7 @@ export function projectTaskDetail(
368
368
  deliverableStage: task.deliverableStage ?? null,
369
369
  ownerAgentLabel: task.ownerAgentLabel ?? null,
370
370
  ...(task.owner ? { owner: task.owner } : {}),
371
- ...taskValidationProjection(task),
371
+ ...taskValidationProjection(task), ...(task.onDeploy ? { onDeploy: task.onDeploy } : {}),
372
372
  issues: task.issues,
373
373
  ...(task.waitedOnBy?.length ? { waitedOnByPlans: task.waitedOnBy.length } : {}),
374
374
  gates: summarizeTaskGates(task.gates),
@@ -0,0 +1,32 @@
1
+ import { ValidationError } from "../db/connection";
2
+ import { authContextFromMcp } from "../services/auth-context";
3
+ import { listProjectProfileInstructions, mutateProjectProfileInstructions, projectProfileInstructionHistory, readProjectProfileInstructions } from "../services/project-profile-instructions";
4
+ import { stringField } from "./validation";
5
+ import type { McpAuthContext, ToolDefinition } from "./types";
6
+ import { hasAnyScope } from "./identity";
7
+ import { McpAuthError } from "../mcp-errors";
8
+
9
+ export const PROJECT_PROFILE_INSTRUCTION_TOOLS: ToolDefinition[] = [{
10
+ name: "relay_project_profile_instructions",
11
+ description: "Project additions to profile instructions. Empty version is 0. Writes need expectedVersion; restore appends history.",
12
+ requiredScopes: ["agent:read"],
13
+ inputSchema: { type: "object", properties: {
14
+ operation: { type: "string", enum: ["list", "get", "set", "history", "restore"] },
15
+ projectId: { type: "string" }, profile: { type: "string" }, template: { type: "string" },
16
+ expectedVersion: { type: "integer", minimum: 0 }, version: { type: "integer", minimum: 1 }, reason: { type: "string" },
17
+ }, required: ["operation"], additionalProperties: false },
18
+ }];
19
+
20
+ export async function relayProjectProfileInstructions(auth: McpAuthContext, args: Record<string, unknown>) {
21
+ if (["set", "restore"].includes(String(args.operation)) && !hasAnyScope(auth, ["agent:write"])) throw new McpAuthError("agent:write scope required");
22
+ const required = args.operation !== "list";
23
+ const projectId = stringField(args.projectId, "projectId", { required, max: 200 });
24
+ const profile = stringField(args.profile, "profile", { required, max: 200 });
25
+ switch (args.operation) {
26
+ case "list": return listProjectProfileInstructions({ projectId: projectId || undefined, profile: profile || undefined });
27
+ case "get": return readProjectProfileInstructions(projectId, profile);
28
+ case "history": return projectProfileInstructionHistory(projectId, profile);
29
+ case "set": case "restore": return mutateProjectProfileInstructions(authContextFromMcp(auth), projectId, profile, args, args.operation === "restore");
30
+ default: throw new ValidationError("unknown project profile instructions operation");
31
+ }
32
+ }
@@ -29,7 +29,7 @@ export const RELAY_TOOL_GROUPS: Record<string, readonly string[]> = {
29
29
  // #3110 — opt-in: only profiles that list it (plus coordinator/ops-assistant by default) get the
30
30
  // tools AND the secrets:write scope; see runtime-tokens.ts.
31
31
  secrets: ["relay_service_access", "relay_secret_reader_create", "relay_secret_project_create", "relay_secret_set"],
32
- prompts: ["relay_prompt"],
32
+ prompts: ["relay_prompt", "relay_project_profile_instructions"],
33
33
  quota: ["relay_codex_reset_consume", "relay_claude_api_budget"],
34
34
  // #3327 — coordinator-only, like decisions: edits the fleet's routing preferences.
35
35
  routing: ["relay_routing_policy_get", "relay_routing_policy_set"],
@@ -16,7 +16,7 @@ import { workflowForBuilderSpawn } from "../services/workflow-auto-start";
16
16
  import { optionalEnum } from "../validation";
17
17
  import { cleanTaskDispatch } from "../db/task-entity";
18
18
  import { DISPATCH_SHAPE_SCHEMA } from "./dispatch-shape-schema";
19
- import { APPROVAL_MODES, AUTO_MERGE_POLICIES, LAUNCH_MODES, REPORT_VERBOSITIES, SPAWN_PROVIDERS, stringValue, VALID_AGENT_LIFECYCLES, VALID_EFFORTS, VALID_WORKSPACE_MODES } from "@humwick/sdk";
19
+ import { APPROVAL_MODES, AUTO_MERGE_POLICIES, LAUNCH_MODES, REPORT_VERBOSITIES, SPAWN_PROVIDERS, stringValue, VALID_AGENT_LIFECYCLES, VALID_WORKSPACE_MODES } from "@humwick/sdk";
20
20
  import type { ProviderEffort } from "@humwick/sdk/provider-catalog";
21
21
  import type { AgentCard, AgentLifecycle, Command, SpawnApprovalMode, SpawnProvider, WorkspaceAutoMergePolicy, WorkspaceLandingPolicy, WorkspaceLandMechanism, WorkspaceMode, WorkspaceRecord } from "../types";
22
22
  import { projectMyAgent, projectSpawnTargets, type MyAgentFullPresentation, type PresentationVerbosity } from "./presentation";
@@ -43,7 +43,7 @@ export const SPAWN_TOOLS: ToolDefinition[] = [
43
43
  env: { type: "object", additionalProperties: { type: "string" }, description: "Vault refs: secret:<name>." },
44
44
  label: { type: "string" },
45
45
  model: { type: "string" },
46
- effort: { enum: VALID_EFFORTS },
46
+ effort: { type: "string" },
47
47
  approvalMode: { enum: APPROVAL_MODES, description: "Use open; read-only blocks reports/tests; guarded waits for prompts." },
48
48
  prompt: { type: "string" },
49
49
  taskId: { oneOf: [{ type: "integer", minimum: 1 }, { type: "string" }], description: "Task id or TNNNN; loads its spec." },
@@ -70,7 +70,7 @@ export const SPAWN_TOOLS: ToolDefinition[] = [
70
70
  hostPinned: { type: "boolean" },
71
71
  landBlocked: { type: "boolean", description: "Permanent ban; for review use a Task hold." },
72
72
  selfEffort: { type: "boolean" },
73
- selfEffortCeiling: { enum: VALID_EFFORTS },
73
+ selfEffortCeiling: { type: "string" },
74
74
  profile: { type: "string" },
75
75
  role: { type: "string", description: "Default-branch project role; mutually exclusive with profile." },
76
76
  tags: { type: "array", items: { type: "string" } },
@@ -229,6 +229,7 @@ export async function relaySpawnAgent(auth: McpAuthContext, args: Record<string,
229
229
  ...(result.taskId !== undefined ? { taskId: result.taskId } : {}),
230
230
  ...(result.task ? { task: result.task } : {}),
231
231
  ...(result.warnings ? { warnings: result.warnings } : {}),
232
+ ...(result.spawnPolicy ? { spawnPolicy: result.spawnPolicy } : {}),
232
233
  ...(result.dispatchDecision ? { dispatchDecision: { target: result.dispatchDecision.target, rationale: result.dispatchDecision.rationale, warnings: result.dispatchDecision.warnings } } : {}),
233
234
  ...(workflow.reason ? { workflow: { started: false, reason: workflow.reason } } : {}),
234
235
  };
@@ -1,7 +1,6 @@
1
1
  import { REPORT_VERBOSITIES } from "@humwick/sdk";
2
2
  import { setAgentReportVerbosity } from "./services/agent-reporting";
3
3
  import { INCLUDED_TOOL_SCOPE_NEEDS } from "./mcp/tool-groups";
4
- import { VALID_EFFORTS } from "@humwick/sdk/provider-catalog";
5
4
  import { cleanEnum, cleanString } from "./validation";
6
5
  import { AgentActionTargetError, dispatchAgentAction, type AgentAction } from "./services/agent-action";
7
6
  import { authContextFromMcp } from "./services/auth-context";
@@ -37,7 +36,7 @@ export const SET_EFFORT_TOOL = {
37
36
  inputSchema: {
38
37
  type: "object",
39
38
  properties: {
40
- effort: { type: "string", enum: VALID_EFFORTS },
39
+ effort: { type: "string" },
41
40
  reason: { type: "string" },
42
41
  requestId: { type: "string" },
43
42
  },
@@ -35,7 +35,7 @@ export const HOST_TOOLS: ToolDefinition[] = [{
35
35
  landSlots: { anyOf: [{ type: "integer", minimum: 1, maximum: 1000 }, { type: "null" }] },
36
36
  validationSlots: { anyOf: [{ type: "integer", minimum: 1, maximum: 1000 }, { type: "null" }] },
37
37
  runCpus: { anyOf: [{ type: "number", minimum: 0.01, maximum: 1000 }, { type: "null" }] },
38
- runMemory: { anyOf: [{ type: "integer", minimum: 1 }, { type: "null" }], description: "Per-run memory cap in bytes" },
38
+ runMemory: { anyOf: [{ type: "integer", minimum: 1 }, { type: "null" }], description: "Soft per-run memory, bytes" },
39
39
  projectGateReservations: { anyOf: [{ type: "object", additionalProperties: { type: "integer", minimum: 1, maximum: 1000 } }, { type: "null" }] },
40
40
  },
41
41
  },
@@ -1,9 +1,10 @@
1
- import { deleteIssueRef, getIssueRef, getIssueRefByExternalKey, issueRefClosedCompleted, issueRefForRefString, listIssueRefs, resolveIssueRefByExternalKey, resolveIssueRefFromString, updateIssueRef, upsertIssueRef } from "./db/issue-refs";
1
+ import { getIssueRef, getIssueRefByExternalKey, issueRefClosedCompleted, issueRefForRefString, listIssueRefs } from "./db/issue-refs";
2
+ import { deleteIssueRefAsync, resolveIssueRefByExternalKeyAsync, resolveIssueRefFromStringAsync, updateIssueRefAsync, upsertIssueRefAsync } from "./db/issue-refs-async";
2
3
  import { McpNotFoundError } from "./mcp-errors";
3
4
  import { cleanEnum, cleanString, optionalEnum } from "./validation";
4
5
  import { ISSUE_REF_CLOSE_REASONS, ISSUE_PROVIDERS, ISSUE_REF_STATUSES, isRecord, type IssueProvider, type IssueRef, type IssueRefCloseReason, type IssueRefStatus } from "./types";
5
6
  import { ValidationError } from "./db";
6
- import { advanceTerminalPlanRefs } from "./services/plan-terminal-refs";
7
+ import { advanceTerminalPlanRefsAsync } from "./services/plan-terminal-refs";
7
8
 
8
9
  export const ISSUE_REF_TOOLS = [
9
10
  {
@@ -126,11 +127,11 @@ function currentRefFor(args: Record<string, unknown>) {
126
127
  return null;
127
128
  }
128
129
 
129
- export function relayIssueRefTool(_auth: IssueRefToolAuth, name: string, args: Record<string, unknown>): Record<string, unknown> {
130
+ export async function relayIssueRefTool(_auth: IssueRefToolAuth, name: string, args: Record<string, unknown>): Promise<Record<string, unknown>> {
130
131
  if (!isRecord(args)) throw new ValidationError("arguments must be an object");
131
132
  if (name === "relay_issue_ref_upsert") {
132
133
  const before = currentRefFor(args);
133
- const issueRef = upsertIssueRef({
134
+ const issueRef = await upsertIssueRefAsync({
134
135
  provider: providerArg(args.provider),
135
136
  repo: cleanString(args.repo, "repo", { required: true, max: 500 })!,
136
137
  externalKey: cleanString(args.externalKey, "externalKey", { required: true, max: 240 })!,
@@ -141,7 +142,7 @@ export function relayIssueRefTool(_auth: IssueRefToolAuth, name: string, args: R
141
142
  statusSyncedAt: timestampArg(args.statusSyncedAt),
142
143
  });
143
144
  // #2520 — the cached ref flipped to a completed close: propagate to bound plan nodes.
144
- if (issueRefClosedCompleted(before, issueRef)) advanceTerminalPlanRefs({ issueRefId: issueRef.id, actor: _auth.actor });
145
+ if (issueRefClosedCompleted(before, issueRef)) await advanceTerminalPlanRefsAsync({ issueRefId: issueRef.id, actor: _auth.actor });
145
146
  return issueRef as unknown as Record<string, unknown>;
146
147
  }
147
148
  if (name === "relay_issue_ref_resolve") {
@@ -153,7 +154,7 @@ export function relayIssueRefTool(_auth: IssueRefToolAuth, name: string, args: R
153
154
  ? issueRefForRefString(ref, cleanString(args.defaultRepo ?? args.repo, "defaultRepo", { max: 500 }))
154
155
  : currentRefFor(args);
155
156
  const issueRef = (ref
156
- ? resolveIssueRefFromString({
157
+ ? await resolveIssueRefFromStringAsync({
157
158
  ref,
158
159
  defaultRepo: cleanString(args.defaultRepo ?? args.repo, "defaultRepo", { max: 500 }),
159
160
  provider: optionalEnum(args.provider, "provider", ISSUE_PROVIDERS, "github") as IssueProvider,
@@ -162,7 +163,7 @@ export function relayIssueRefTool(_auth: IssueRefToolAuth, name: string, args: R
162
163
  closeReason: closeReasonArg(args.closeReason),
163
164
  statusSyncedAt: timestampArg(args.statusSyncedAt),
164
165
  })
165
- : resolveIssueRefByExternalKey({
166
+ : await resolveIssueRefByExternalKeyAsync({
166
167
  provider: providerArg(args.provider),
167
168
  repo: cleanString(args.repo, "repo", { required: true, max: 500 })!,
168
169
  externalKey: cleanString(args.externalKey, "externalKey", { required: true, max: 240 })!,
@@ -172,7 +173,7 @@ export function relayIssueRefTool(_auth: IssueRefToolAuth, name: string, args: R
172
173
  closeReason: closeReasonArg(args.closeReason),
173
174
  statusSyncedAt: timestampArg(args.statusSyncedAt),
174
175
  })) as unknown as IssueRef;
175
- if (issueRefClosedCompleted(before, issueRef)) advanceTerminalPlanRefs({ issueRefId: issueRef.id, actor: _auth.actor });
176
+ if (issueRefClosedCompleted(before, issueRef)) await advanceTerminalPlanRefsAsync({ issueRefId: issueRef.id, actor: _auth.actor });
176
177
  return issueRef as unknown as Record<string, unknown>;
177
178
  }
178
179
  if (name === "relay_issue_ref_get") {
@@ -192,7 +193,7 @@ export function relayIssueRefTool(_auth: IssueRefToolAuth, name: string, args: R
192
193
  }
193
194
  if (name === "relay_issue_ref_update") {
194
195
  const before = currentRefFor(args);
195
- const issueRef = updateIssueRef(cleanString(args.id, "id", { required: true, max: 120 })!, {
196
+ const issueRef = await updateIssueRefAsync(cleanString(args.id, "id", { required: true, max: 120 })!, {
196
197
  url: cleanString(args.url, "url", { max: 2000 }),
197
198
  title: cleanString(args.title, "title", { max: 500 }),
198
199
  status: statusArg(args.status),
@@ -201,11 +202,11 @@ export function relayIssueRefTool(_auth: IssueRefToolAuth, name: string, args: R
201
202
  });
202
203
  if (!issueRef) throw new McpNotFoundError("issue ref not found");
203
204
  // #2520 — the cached ref flipped to a completed close: propagate to bound plan nodes.
204
- if (issueRefClosedCompleted(before, issueRef)) advanceTerminalPlanRefs({ issueRefId: issueRef.id, actor: _auth.actor });
205
+ if (issueRefClosedCompleted(before, issueRef)) await advanceTerminalPlanRefsAsync({ issueRefId: issueRef.id, actor: _auth.actor });
205
206
  return { issueRef };
206
207
  }
207
208
  if (name === "relay_issue_ref_delete") {
208
- const deleted = deleteIssueRef(cleanString(args.id, "id", { required: true, max: 120 })!);
209
+ const deleted = await deleteIssueRefAsync(cleanString(args.id, "id", { required: true, max: 120 })!);
209
210
  if (!deleted) throw new McpNotFoundError("issue ref not found");
210
211
  return { deleted };
211
212
  }
@@ -11,7 +11,7 @@
11
11
 
12
12
  import { ValidationError } from "./db";
13
13
  import { McpNotFoundError } from "./mcp-errors";
14
- import { listMaintenanceJobs } from "./maintenance";
14
+ import { listMaintenanceJobsAsync } from "./maintenance";
15
15
  import { listPauses, pauseJob, resumeJobAsync } from "./maintenance/pauses";
16
16
  import { authContextFromMcp } from "./services/auth-context";
17
17
  import { cleanString } from "./validation";
@@ -72,7 +72,7 @@ export async function relayMaintenanceTool(auth: McpAuthLike, name: string, args
72
72
  }
73
73
 
74
74
  if (name === "relay_maintenance_jobs") {
75
- const jobs = listMaintenanceJobs();
75
+ const jobs = await listMaintenanceJobsAsync();
76
76
  const jobId = cleanString(args.jobId, "jobId", { max: 120 });
77
77
  if (!jobId) return { jobs, count: jobs.length };
78
78
  const job = jobs.find(candidate => candidate.id === jobId);
@@ -3,7 +3,7 @@ import { INCLUDED_TOOL_SCOPE_NEEDS } from "./mcp/tool-groups";
3
3
  import { ValidationError } from "./db";
4
4
  import { callerAgentId } from "./mcp/identity";
5
5
  import { optionalEnum } from "./validation";
6
- import { approveProfileProjectTrust, PROJECT_REVIEW_MODES, PROJECT_TRUST_CAPABILITIES, updateProfileProjectTrust } from "./services/profile-trust";
6
+ import { approveProfileProjectTrust, PROJECT_REVIEW_MODES, PROJECT_TRUST_CAPABILITIES, updateProfileProjectTrustAsync } from "./services/profile-trust";
7
7
  import type { McpAuthContext, ToolDefinition } from "./mcp/types";
8
8
 
9
9
  export const PROFILE_TRUST_TOOL: ToolDefinition = {
@@ -31,17 +31,17 @@ function text(args: Record<string, unknown>, field: string): string {
31
31
  return value.trim();
32
32
  }
33
33
 
34
- export function relayProfileTrust(auth: McpAuthContext, args: Record<string, unknown>): unknown {
34
+ export async function relayProfileTrust(auth: McpAuthContext, args: Record<string, unknown>): Promise<unknown> {
35
35
  const name = text(args, "profile");
36
36
  const by = callerAgentId(auth) ?? auth.actor;
37
37
  if (args.action === "set-review") {
38
38
  const review = optionalEnum(args.review, "review", PROJECT_REVIEW_MODES);
39
39
  if (!review) throw new ValidationError("review is required");
40
- return { trust: updateProfileProjectTrust(name, { review }, by).value.sources?.project?.trust };
40
+ return { trust: (await updateProfileProjectTrustAsync(name, { review }, by)).value.sources?.project?.trust };
41
41
  }
42
42
  const capability = optionalEnum(args.capability, "capability", PROJECT_TRUST_CAPABILITIES);
43
43
  if (!capability) throw new ValidationError("capability is required");
44
- if (args.action === "ack") return { ack: updateProfileProjectTrust(name, { ack: [capability] }, by).value.sources?.project?.[capability]?.ack };
44
+ if (args.action === "ack") return { ack: (await updateProfileProjectTrustAsync(name, { ack: [capability] }, by)).value.sources?.project?.[capability]?.ack };
45
45
  if (args.action === "approve") return { approval: approveProfileProjectTrust({ name, capability, repoKey: text(args, "repoKey"), value: text(args, "value"), by }) };
46
46
  throw new ValidationError("action must be set-review, ack or approve");
47
47
  }
@@ -1,9 +1,9 @@
1
- import { VALID_EFFORTS, isRecord } from "@humwick/sdk";
1
+ import { isRecord } from "@humwick/sdk";
2
2
  import { effectiveProviderEffortLevelsAsync } from "./db";
3
3
 
4
4
  export async function providerCatalogToolInputSchema(name: string, inputSchema: Record<string, unknown>): Promise<Record<string, unknown>> {
5
5
  if (name !== "relay_spawn_agent") return inputSchema;
6
6
  const efforts = await effectiveProviderEffortLevelsAsync();
7
7
  const properties = isRecord(inputSchema.properties) ? inputSchema.properties : {};
8
- return { ...inputSchema, properties: { ...properties, effort: { type: "string", enum: efforts.length ? efforts : VALID_EFFORTS } } };
8
+ return { ...inputSchema, properties: { ...properties, effort: { type: "string", enum: efforts }, selfEffortCeiling: { type: "string", enum: efforts } } };
9
9
  }
@@ -74,7 +74,7 @@ const TASK_ID_PROP = { oneOf: [{ type: "integer", minimum: 1 }, { type: "string"
74
74
  export const TASK_TOOLS = [
75
75
  {
76
76
  name: "relay_task_create",
77
- description: "Create a durable Task. fromIssue digests GitHub title, body, acceptance, labels and references; explicit fields win.",
77
+ description: "Create Task; fromIssue imports GitHub content; explicit fields win.",
78
78
  requiredScopes: ["task:write"],
79
79
  inputSchema: {
80
80
  type: "object",
@@ -84,9 +84,11 @@ export const TASK_TOOLS = [
84
84
  intent: { type: "string" },
85
85
  fromIssue: { type: "string", description: "GitHub URL or owner/repo#number. Fetch once before atomic create." },
86
86
  tags: { type: "array", items: { type: "string" } },
87
+ paths: { type: "array", items: { type: "string" } },
87
88
  complexity: { type: "string", enum: TASK_DISPATCH_COMPLEXITIES },
88
89
  context: { type: "string" },
89
- terminalStage: { type: "string", enum: TASK_TERMINAL_STAGES },
90
+ terminalStage: { enum: TASK_TERMINAL_STAGES },
91
+ onDeploy: { type: "string" },
90
92
  doneWhen: { type: "string" },
91
93
  teamId: { type: "string" },
92
94
  projectId: { type: "string" },
@@ -108,8 +110,8 @@ export const TASK_TOOLS = [
108
110
  },
109
111
  },
110
112
  { name: "relay_task_get", description: "Read a lean Task hydration; verbose:true includes full intent, gates and history projections.", requiredScopes: ["task:read"], inputSchema: { type: "object", properties: { taskId: TASK_ID_PROP, verbose: { type: "boolean" } }, required: ["taskId"], additionalProperties: false } },
111
- { name: "relay_task_list", description: "List your Tasks by default; mine:false lists all. mode:brief is id/label/status; lean is default.", requiredScopes: ["task:read"], inputSchema: { type: "object", properties: { status: { type: "string", enum: DELIVERABLE_STATUS_ENUM }, deliverableStage: { type: "string", enum: TASK_DELIVERABLE_STAGES }, teamId: { type: "string" }, projectId: { type: "string" }, repo: { type: "string" }, mine: { type: "boolean" }, inFlight: { type: "boolean" }, staleOwnerGone: { type: "boolean" }, limit: { type: "integer", minimum: 1, maximum: 500 }, mode: { type: "string", enum: ["brief", "lean", "full"] }, verbose: { type: "boolean" } }, additionalProperties: false } },
112
- { name: "relay_task_update", description: "Update Task intent, steer, criteria or dispatch.", requiredScopes: ["task:write"], inputSchema: { type: "object", properties: { taskId: TASK_ID_PROP, refreshIssue: { type: "object", description: "Explicit source refresh: {expectedRevision, resolutions?: {title|intent|doneWhen|tags: source|local}}. Conflicts require resolution." }, verbose: { type: "boolean" }, title: { type: "string" }, label: { type: "string" }, intent: { type: "string" }, complexity: { type: "string", enum: TASK_DISPATCH_COMPLEXITIES }, context: { type: "string" }, latestSteer: { type: "string" }, doneWhen: { type: "string" }, terminalStage: { anyOf: [{ type: "string", enum: TASK_TERMINAL_STAGES }, { type: "null" }] }, dispatch: DISPATCH_SHAPE_SCHEMA, teamId: { type: "string" }, projectId: { type: "string" }, repo: { type: "string" } }, required: ["taskId"], additionalProperties: false } },
113
+ { name: "relay_task_list", description: "List your Tasks by default; mine:false lists all. mode:brief is id/label/status; lean is default.", requiredScopes: ["task:read"], inputSchema: { type: "object", properties: { status: { enum: DELIVERABLE_STATUS_ENUM }, deliverableStage: { enum: [...TASK_DELIVERABLE_STAGES, "awaiting-deploy"] }, teamId: { type: "string" }, projectId: { type: "string" }, repo: { type: "string" }, mine: { type: "boolean" }, inFlight: { type: "boolean" }, staleOwnerGone: { type: "boolean" }, limit: { type: "integer", minimum: 1, maximum: 500 }, mode: { type: "string", enum: ["brief", "lean", "full"] }, verbose: { type: "boolean" } }, additionalProperties: false } },
114
+ { name: "relay_task_update", description: "Update Task intent, steer, criteria or dispatch.", requiredScopes: ["task:write"], inputSchema: { type: "object", properties: { taskId: TASK_ID_PROP, refreshIssue: { type: "object", description: "{expectedRevision, resolutions?: {title|intent|doneWhen|tags: source|local}}." }, verbose: { type: "boolean" }, title: { type: "string" }, label: { type: "string" }, intent: { type: "string" }, complexity: { type: "string", enum: TASK_DISPATCH_COMPLEXITIES }, context: { type: "string" }, latestSteer: { type: "string" }, onDeploy: { type: "string" }, doneWhen: { type: "string" }, terminalStage: { enum: [...TASK_TERMINAL_STAGES, null] }, dispatch: DISPATCH_SHAPE_SCHEMA, teamId: { type: "string" }, projectId: { type: "string" }, repo: { type: "string" }, paths: { type: "array", items: { type: "string" } } }, required: ["taskId"], additionalProperties: false } },
113
115
  { name: "relay_task_set_status", description: "Transition Task execution status. done requires met validation; force requires explicit override authority.", requiredScopes: ["task:write"], inputSchema: { type: "object", properties: { taskId: TASK_ID_PROP, status: { type: "string", enum: DELIVERABLE_STATUS_ENUM }, force: { type: "boolean" }, blockedBy: { type: "array", items: BLOCKER_SCHEMA }, note: { type: "string" }, verbose: { type: "boolean" } }, required: ["taskId", "status"], additionalProperties: false } },
114
116
  { name: "relay_task_set_stage", description: "Set Task delivery stage/branch/commit; normally maintained by the land/deploy pipeline.", requiredScopes: ["task:write"], inputSchema: { type: "object", properties: { taskId: TASK_ID_PROP, deliverableStage: { type: "string", enum: TASK_DELIVERABLE_STAGES }, branch: { type: "string" }, commit: COMMIT_SCHEMA }, required: ["taskId", "deliverableStage"], additionalProperties: false } },
115
117
  { name: "relay_task_confirm_carry", description: "Confirm a protected-tip revert's delivered change was carried to current main; clears only carry-pending.", requiredScopes: ["task:write"], inputSchema: { type: "object", properties: { taskId: TASK_ID_PROP, commit: COMMIT_SCHEMA, branch: { type: "string" }, note: { type: "string" } }, required: ["taskId"], additionalProperties: false } },
@@ -175,6 +177,7 @@ export async function relayTaskTool(auth: McpAuthLike, name: string, args: Recor
175
177
  complexity: optionalEnum(args.complexity, "complexity", TASK_DISPATCH_COMPLEXITIES),
176
178
  context: cleanString(args.context, "context", { max: 1_000_000 }),
177
179
  terminalStage: optionalEnum(args.terminalStage, "terminalStage", TASK_TERMINAL_STAGES),
180
+ onDeploy: cleanString(args.onDeploy, "onDeploy", { max: 500 }),
178
181
  doneWhen: cleanString(args.doneWhen, "doneWhen", { max: 1_000_000 }),
179
182
  teamId: cleanString(args.teamId, "teamId", { max: 200 }),
180
183
  projectId: cleanString(args.projectId, "projectId", { max: 120 }),
@@ -182,6 +185,7 @@ export async function relayTaskTool(auth: McpAuthLike, name: string, args: Recor
182
185
  branch: cleanString(args.branch, "branch", { max: 500 }),
183
186
  dispatch: args.dispatch as TaskDispatch | undefined,
184
187
  tags: args.tags as string[] | undefined,
188
+ paths: args.paths as string[] | undefined,
185
189
  // Alias-tolerant (#2214): a ref passed as `refs`/`issues`/`externalKey`/… used to be dropped
186
190
  // silently, leaving the Task's issues[] empty and its spawn brief without the linked spec.
187
191
  issueRefs: issueRefsFromArgs(args),
@@ -218,7 +222,7 @@ export async function relayTaskTool(auth: McpAuthLike, name: string, args: Recor
218
222
  if (name === "relay_task_list") {
219
223
  const tasks = await listTaskEntitySummariesAsync({
220
224
  status: optionalEnum(args.status, "status", DELIVERABLE_STATUS_ENUM),
221
- deliverableStage: optionalEnum(args.deliverableStage, "deliverableStage", TASK_DELIVERABLE_STAGES),
225
+ deliverableStage: optionalEnum(args.deliverableStage, "deliverableStage", [...TASK_DELIVERABLE_STAGES, "awaiting-deploy"] as const),
222
226
  teamId: cleanString(args.teamId, "teamId", { max: 200 }),
223
227
  projectId: cleanString(args.projectId, "projectId", { max: 120 }),
224
228
  repo: cleanString(args.repo, "repo", { max: 500 }),
@@ -246,12 +250,14 @@ export async function relayTaskTool(auth: McpAuthLike, name: string, args: Recor
246
250
  ...(args.complexity !== undefined ? { complexity: optionalEnum(args.complexity, "complexity", TASK_DISPATCH_COMPLEXITIES) } : {}),
247
251
  ...(args.context !== undefined ? { context: cleanString(args.context, "context", { max: 1_000_000 }) ?? "" } : {}),
248
252
  ...(args.latestSteer !== undefined ? { latestSteer: cleanString(args.latestSteer, "latestSteer", { max: 1_000_000 }) ?? "" } : {}),
253
+ ...(args.onDeploy !== undefined ? { onDeploy: cleanString(args.onDeploy, "onDeploy", { max: 500 }) ?? "" } : {}),
249
254
  ...(args.doneWhen !== undefined ? { doneWhen: cleanString(args.doneWhen, "doneWhen", { max: 1_000_000 }) ?? "" } : {}),
250
255
  ...(args.terminalStage !== undefined ? { terminalStage: args.terminalStage === null ? null : optionalEnum(args.terminalStage, "terminalStage", TASK_TERMINAL_STAGES) } : {}),
251
256
  ...(args.dispatch !== undefined ? { dispatch: args.dispatch as TaskDispatch } : {}),
252
257
  ...(args.teamId !== undefined ? { teamId: cleanString(args.teamId, "teamId", { max: 200 }) ?? "" } : {}),
253
258
  ...(args.projectId !== undefined ? { projectId: cleanString(args.projectId, "projectId", { max: 120 }) ?? "" } : {}),
254
259
  ...(args.repo !== undefined ? { repo: cleanString(args.repo, "repo", { max: 500 }) ?? "" } : {}),
260
+ ...(args.paths !== undefined ? { paths: args.paths as string[] | null } : {}),
255
261
  };
256
262
  const task = await updateTaskEntityAsync(taskIdArg(args.taskId), { ...patch, actor });
257
263
  if (args.verbose === true) return task as unknown as Record<string, unknown>;
@@ -2,7 +2,7 @@ import { INCLUDED_TOOL_SCOPE_NEEDS } from "./mcp/tool-groups";
2
2
  import { APPROVAL_MODES, SPAWN_PROVIDERS, VALID_AGENT_LIFECYCLES, VALID_WORKSPACE_MODES } from "@humwick/sdk";
3
3
  import { McpAuthError } from "./mcp-errors";
4
4
  import { authContextFromMcp } from "./services/auth-context";
5
- import { deleteTeamTemplate, getTeamTemplate, instantiateTeamTemplate, listTeamTemplates, saveTeamTemplate } from "./services/team-templates";
5
+ import { deleteTeamTemplateAsync, getTeamTemplate, instantiateTeamTemplate, listTeamTemplates, saveTeamTemplateAsync } from "./services/team-templates";
6
6
  import { summarizeSpawnCommandForCaller } from "./services/spawn-agent";
7
7
  import { ValidationError } from "./db";
8
8
 
@@ -111,7 +111,7 @@ function slugArg(args: Record<string, unknown>): string {
111
111
  export async function relayTeamTemplateTool(auth: McpAuthLike, name: string, args: Record<string, unknown>): Promise<Record<string, unknown>> {
112
112
  if (name === "relay_team_template_save") {
113
113
  requireScope(auth, "teams:write");
114
- return saveTeamTemplate(args, auth.actor) as unknown as Record<string, unknown>;
114
+ return await saveTeamTemplateAsync(args, auth.actor) as unknown as Record<string, unknown>;
115
115
  }
116
116
  if (name === "relay_team_template_list") return { templates: listTeamTemplates() };
117
117
  if (name === "relay_team_template_get") {
@@ -121,7 +121,7 @@ export async function relayTeamTemplateTool(auth: McpAuthLike, name: string, arg
121
121
  }
122
122
  if (name === "relay_team_template_delete") {
123
123
  requireScope(auth, "teams:write");
124
- return { slug: slugArg(args), deleted: deleteTeamTemplate(slugArg(args), auth.actor) };
124
+ return { slug: slugArg(args), deleted: await deleteTeamTemplateAsync(slugArg(args), auth.actor) };
125
125
  }
126
126
  if (name === "relay_team_spawn_from_template") {
127
127
  requireScope(auth, "teams:write");