@humwick/server 0.130.2 → 0.130.4
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.
- package/bundled/prompts/manifest.json +1 -0
- package/bundled/prompts/task.hydration.md +1 -1
- package/bundled/roles/builder.md +1 -1
- package/docs/guides/sub-coordinators.md +12 -5
- package/docs/guides/tools-coordination.md +1 -0
- package/docs/guides/workflows.md +16 -0
- package/docs/openapi.json +175 -4
- package/package.json +8 -7
- package/public/assets/{MessageBubble-BWLqMGKG.js → MessageBubble-BOkmEvgZ.js} +2 -2
- package/public/assets/{PlanGraphPanel-3TlIQpjk.js → PlanGraphPanel-BkaDJp0r.js} +2 -2
- package/public/assets/{TraceView-Wimm0Czv.js → TraceView-B99Uu2yT.js} +2 -2
- package/public/assets/{VaultDecisionCard-Bau_vNax.js → VaultDecisionCard-DUIfTTFF.js} +2 -2
- package/public/assets/{activity-CrSurn-r.js → activity-ZIX0N1El.js} +2 -2
- package/public/assets/{agent-lineage-CknAJKcb.js → agent-lineage-kq9TPYFw.js} +2 -2
- package/public/assets/agent-liveness-DSQY1Aa_.js +2 -0
- package/public/assets/{agent-name-DKbiIhBo.js → agent-name-C_7F4DFR.js} +2 -2
- package/public/assets/{agent-profiles-DwF6EQ4R.js → agent-profiles-BNOcrGcY.js} +2 -2
- package/public/assets/{agent-project-badge-Diz4Sjjb.js → agent-project-badge-B6yAh70a.js} +2 -2
- package/public/assets/{agent-tools-CRhpRQza.js → agent-tools-CcrhmOzF.js} +2 -2
- package/public/assets/{agent-type-icon-LrUEU3lB.js → agent-type-icon-CXSLrKiq.js} +2 -2
- package/public/assets/{agents-B-v66C-4.js → agents-DIZG97_X.js} +2 -2
- package/public/assets/{analytics-BqCb-LKi.js → analytics-rasmoPjR.js} +2 -2
- package/public/assets/{artifact-viewer-kf4pGuAR.js → artifact-viewer-tBpTrEPb.js} +2 -2
- package/public/assets/{artifacts-DJevXcvg.js → artifacts-BNkrynP1.js} +2 -2
- package/public/assets/{artifacts-D32zyw4Y.js → artifacts-Bjq-ZyBA.js} +2 -2
- package/public/assets/{automation-BpRajx_5.js → automation-Cx422L3L.js} +2 -2
- package/public/assets/{backlog-D_UjTdzX.js → backlog-RuFQ8PUu.js} +2 -2
- package/public/assets/{busy-health-N3VEh4ao.js → busy-health-BvNQ9g5x.js} +2 -2
- package/public/assets/{channels-9jopungq.js → channels-DNbKAS0I.js} +2 -2
- package/public/assets/{chat-CSXrTB3C.js → chat-Bp3Fx73h.js} +3 -3
- package/public/assets/{code-preview-p1NnmqK0.js → code-preview-KIRZA6cz.js} +2 -2
- package/public/assets/{connectors-CZdqlDNL.js → connectors-k7vO4vvc.js} +2 -2
- package/public/assets/{cosmos-BgdsE4dG.js → cosmos-BuVoq1aw.js} +2 -2
- package/public/assets/{crate-agent-30aXTKva.js → crate-agent-irqlt4NH.js} +2 -2
- package/public/assets/{dependency-graph-B_jvw2GE.js → dependency-graph-D_rurNBz.js} +2 -2
- package/public/assets/{deploys-DoN6bAb5.js → deploys-yzZqIpxE.js} +2 -2
- package/public/assets/{display-BrKWFGJz.js → display-BemJG1f_.js} +2 -2
- package/public/assets/{files-D6XEu8Ng.js → files-DXWcrxOz.js} +2 -2
- package/public/assets/{fleet-C7jQWbw2.js → fleet-TEuOCZXE.js} +2 -2
- package/public/assets/{fleet-metrics-BiDs3MLx.js → fleet-metrics-BGoDAFI-.js} +2 -2
- package/public/assets/{formatted-body-impl-DyG0WsQS.js → formatted-body-impl-BB9eq9nN.js} +2 -2
- package/public/assets/{formatted-body-CQBwc1fb.js → formatted-body-qy2nTD_1.js} +3 -3
- package/public/assets/{host-providers-dialog-DKaW31dN.js → host-providers-dialog-BGPHxuwT.js} +2 -2
- package/public/assets/{index-CRHep3M9.js → index-BC5XZc0z.js} +5 -5
- package/public/assets/{index-MYAIwYTX.css → index-D8Rp9pz2.css} +1 -1
- package/public/assets/{insights-CzrtkpOE.js → insights-C-KQG0h-.js} +2 -2
- package/public/assets/{integrations-aVsUmigt.js → integrations-ClPRPyKU.js} +2 -2
- package/public/assets/{issue-ref-chip-BnSlM_95.js → issue-ref-chip-DbH8J9Ak.js} +2 -2
- package/public/assets/{log-viewer-qe7Ee47Z.js → log-viewer-PH4zVn24.js} +2 -2
- package/public/assets/{maintenance-NfjqFZAk.js → maintenance-5lV43uTL.js} +2 -2
- package/public/assets/{managed-agents-BiH0HgaE.js → managed-agents-BdgU35aX.js} +2 -2
- package/public/assets/{markdown-preview-BixaT3Xr.js → markdown-preview-DNT4OUwQ.js} +3 -3
- package/public/assets/{markdown-preview-impl-DNGlWIS3.js → markdown-preview-impl-CnCcPy0A.js} +2 -2
- package/public/assets/{memory-DNsCl6UX.js → memory--GgWH1gH.js} +2 -2
- package/public/assets/{messages-DopU1L1X.js → messages-CzFl_97O.js} +2 -2
- package/public/assets/{orchestrators-Cq7ckLQT.js → orchestrators-CVvJVkzv.js} +2 -2
- package/public/assets/overview-DsrZvE86.js +2 -0
- package/public/assets/{pairs-DE_m6rrE.js → pairs-D2d0d2py.js} +2 -2
- package/public/assets/{profile-icon-B3rfh77F.js → profile-icon-_SMuSbYF.js} +2 -2
- package/public/assets/{project-profile-instructions-DQWZE0kA.js → project-profile-instructions-Apn15y43.js} +2 -2
- package/public/assets/{projects-Br2Bd2h1.js → projects-D3B6kto5.js} +2 -2
- package/public/assets/{prompt-settings-BKvFsvGD.js → prompt-settings-DnPB6Ez6.js} +2 -2
- package/public/assets/provider-display-bWwiuedV.js +2 -0
- package/public/assets/{registry-Cw38_6gW.js → registry-D790cIhN.js} +2 -2
- package/public/assets/run-card-BCro-Odj.js +2 -0
- package/public/assets/{secrets-DxI-vzSq.js → secrets-CVXvfvbU.js} +2 -2
- package/public/assets/{service-access-settings-D9s_VJbd.js → service-access-settings-D3Xxqb9w.js} +2 -2
- package/public/assets/{settings-CKZTVGIx.js → settings-CoUC7Jci.js} +2 -2
- package/public/assets/shipping-D_Lp9n_J.js +2 -0
- package/public/assets/{stats-DyUBKyWI.js → stats-CXiNjB9S.js} +2 -2
- package/public/assets/{status-dot-DYqlEUhJ.js → status-dot-C703YIy1.js} +2 -2
- package/public/assets/store-BgDALGIX.js +9 -0
- package/public/assets/{tasks-Bh7Chr4-.js → tasks-DO0WpJCx.js} +2 -2
- package/public/assets/{teams-bowI7qVY.js → teams-FGkdi_tL.js} +2 -2
- package/public/assets/{terminal-viewer-BgVLHdsU.js → terminal-viewer-Dh8dSC7e.js} +3 -3
- package/public/assets/{terminal-viewer-impl-Dz22UPy6.js → terminal-viewer-impl-B5Zriip3.js} +2 -2
- package/public/assets/{use-agent-terminal-DSQQ-iY7.js → use-agent-terminal-CRUVDvLC.js} +2 -2
- package/public/assets/{use-decisions-samMQhQf.js → use-decisions-CoaqRh4l.js} +2 -2
- package/public/assets/{use-project-list-59LheVP7.js → use-project-list-X-BgT53X.js} +2 -2
- package/public/assets/{use-selectors-BZa25xEB.js → use-selectors-0X_UZkk-.js} +2 -2
- package/public/assets/{user-avatar-DHxlvUvV.js → user-avatar-CkLhVBGu.js} +2 -2
- package/public/assets/{versioned-prompt-editor-BmED5DnJ.js → versioned-prompt-editor-BkTi7eim.js} +2 -2
- package/public/assets/{work-queue-CSvpuNLz.js → work-queue-DDOLEyKo.js} +2 -2
- package/public/assets/{workflow-marker-DAZcj5qt.js → workflow-marker-CzOsB8BM.js} +2 -2
- package/public/assets/{workflows-DdmxRSyg.js → workflows-DJilvmRM.js} +2 -2
- package/public/assets/{workspaces-BxeKfVuF.js → workspaces-CHcfbLR3.js} +2 -2
- package/public/cosmos.html +4 -4
- package/public/index.html +29 -29
- package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/runner/src/adapters/claude-api.ts +1 -1
- package/runner/src/adapters/claude-headless.ts +1 -1
- package/runner/src/adapters/claude-launch-exit.ts +26 -0
- package/runner/src/adapters/claude-session-probe.ts +1 -1
- package/runner/src/adapters/claude-tmux.ts +38 -10
- package/runner/src/adapters/claude.ts +28 -75
- package/runner/src/adapters/provider-quota-harvest.ts +20 -71
- package/runner/src/agent-runner/lifecycle-milestones.ts +2 -2
- package/runner/src/agent-runner/liveness-exchange.ts +104 -0
- package/runner/src/claude-system-prompt.ts +49 -0
- package/runner/src/launch-assembly.ts +14 -10
- package/runner/src/profile-home.ts +1 -1
- package/runner/src/project-instructions.ts +2 -2
- package/runner/src/provider-command.ts +18 -0
- package/runner/src/provider-setup.ts +3 -2
- package/runner/src/runner-core.ts +14 -15
- package/runner/src/runner-helpers.ts +0 -8
- package/runner/src/session-scratch.ts +6 -2
- package/runner/test-support/provisioning-context.ts +4 -2
- package/runner/test-support/runner-harness.ts +2 -1
- package/scripts/steward-policy-cleanup.ts +2 -2
- package/src/agent-authz.ts +2 -2
- package/src/agent-drive-arbiter.ts +3 -8
- package/src/agent-exit-cleanup-async.ts +2 -2
- package/src/agent-exit-cleanup.ts +23 -19
- package/src/agent-lifecycle-events.ts +112 -85
- package/src/agent-ref.ts +3 -2
- package/src/agent-status-events.ts +43 -14
- package/src/auth/login-link.ts +35 -0
- package/src/auth/password.ts +4 -3
- package/src/auth/session-refresh.ts +1 -1
- package/src/auth/session.test-fixture.ts +2 -2
- package/src/auth/session.ts +7 -7
- package/src/automations/crud.ts +8 -81
- package/src/automations/dispatch.ts +33 -58
- package/src/automations/index.ts +1 -1
- package/src/automations/persistence.ts +65 -0
- package/src/automations/precheck.ts +18 -16
- package/src/automations/read-async.ts +11 -0
- package/src/automations/reconcile.ts +30 -39
- package/src/automations/storage.ts +33 -10
- package/src/automations/write-async.ts +33 -0
- package/src/branch-land-notice.ts +3 -3
- package/src/branch-landed.ts +25 -23
- package/src/bus.ts +21 -19
- package/src/cd-deploy-notify.ts +2 -2
- package/src/ci/notifications.ts +4 -4
- package/src/ci/root-missing.ts +3 -3
- package/src/ci/transition-notify.ts +5 -5
- package/src/claude-app/oauth-http.ts +3 -3
- package/src/cli/index.ts +7 -1
- package/src/cli/init.ts +53 -0
- package/src/cli/orchestrator.ts +1 -7
- package/src/cli/setup.ts +6 -4
- package/src/cli/workflow.ts +12 -3
- package/src/commands-db.ts +4 -4
- package/src/commands-write.ts +8 -0
- package/src/compaction-watch.ts +10 -8
- package/src/config-store-write.ts +2 -2
- package/src/config.ts +4 -11
- package/src/connectors.ts +10 -8
- package/src/context-advisory.ts +22 -21
- package/src/db/agent-action-write.ts +36 -0
- package/src/db/agent-control-async.ts +9 -0
- package/src/db/agent-control-write.ts +49 -0
- package/src/db/agent-effort-observe.ts +22 -0
- package/src/db/agent-meta.ts +14 -3
- package/src/db/agents-async.ts +8 -5
- package/src/db/agents.ts +15 -12
- package/src/db/auth-identities.ts +2 -2
- package/src/db/automation-read-ops.ts +11 -0
- package/src/db/automation-write-ops.ts +46 -0
- package/src/db/blackboard.ts +2 -2
- package/src/db/browser-session-write.ts +32 -0
- package/src/db/bus-outbox-write-ops.ts +3 -1
- package/src/db/checkout-refresh-schema.ts +47 -0
- package/src/db/checkout-refresh.ts +5 -5
- package/src/db/command-agent-profile-backfill.ts +39 -0
- package/src/db/command-agent-profiles.ts +5 -1
- package/src/db/command-retention.ts +126 -0
- package/src/db/commands-planner-stats.test-fixture.ts +8 -0
- package/src/db/commands-read-ops.ts +16 -0
- package/src/db/connection.ts +1 -182
- package/src/db/context-carry-write.ts +74 -0
- package/src/db/continuations.ts +4 -4
- package/src/db/db-error-registry.ts +12 -0
- package/src/db/gateway.ts +26 -133
- package/src/db/history-retention-ops.ts +13 -0
- package/src/db/inbox-async.ts +2 -2
- package/src/db/inbox-read-ops.ts +1 -1
- package/src/db/inbox.ts +9 -3
- package/src/db/issue-associations.ts +2 -2
- package/src/db/issue-refs-async.ts +4 -1
- package/src/db/issue-refs-read-ops.ts +6 -0
- package/src/db/issue-refs.ts +8 -8
- package/src/db/kernel-event-log-schema.ts +2 -0
- package/src/db/land-boundaries.ts +51 -5
- package/src/db/land-gate-attestations.ts +2 -2
- package/src/db/landing-receipts.ts +2 -2
- package/src/db/lifecycle-context-write.ts +5 -0
- package/src/db/lifecycle-tail-async.ts +76 -0
- package/src/db/lifecycle-tail-write-ops.ts +62 -0
- package/src/db/lifecycle-write-window.ts +2 -1
- package/src/db/lineage-pair-dedupe-sql.ts +3 -3
- package/src/db/main-connection-mode.ts +11 -0
- package/src/db/main-connection-writes.ts +20 -2
- package/src/db/maintenance-job-runs-async.ts +2 -2
- package/src/db/maintenance-job-write-ops.ts +1 -1
- package/src/db/maintenance-pauses.ts +2 -2
- package/src/db/message-send.ts +4 -0
- package/src/db/messages.ts +31 -25
- package/src/db/migrations.ts +18 -1
- package/src/db/notification-write-ops.ts +19 -0
- package/src/db/operator-answer-write.ts +19 -0
- package/src/db/orchestrators.ts +10 -4
- package/src/db/pairs-async.ts +22 -1
- package/src/db/pairs-write-ops.ts +8 -3
- package/src/db/pairs.ts +41 -48
- package/src/db/plan-dispatch-schema.ts +5 -1
- package/src/db/plan-ready-notices.ts +43 -0
- package/src/db/plan-tools-include-migration.ts +36 -0
- package/src/db/plans-write-ops.ts +2 -0
- package/src/db/presence-buffer.ts +5 -0
- package/src/db/presence-loop.ts +18 -23
- package/src/db/presence-write.ts +0 -6
- package/src/db/project-entries-async.ts +14 -0
- package/src/db/project-entries-read-ops.ts +5 -1
- package/src/db/project-entries-write-ops.ts +8 -0
- package/src/db/project-entries.ts +15 -12
- package/src/db/project-journal.ts +2 -2
- package/src/db/project-trust-approvals.ts +2 -2
- package/src/db/prompt-templates.ts +4 -4
- package/src/db/read-op-marshaling-fixtures.ts +18 -0
- package/src/db/read-ops.ts +4 -0
- package/src/db/retention.ts +13 -2
- package/src/db/review-publish-write.ts +8 -0
- package/src/db/runtime-admin-async.ts +19 -0
- package/src/db/runtime-admin-write-ops.ts +36 -0
- package/src/db/runtime-tail-async.ts +288 -0
- package/src/db/runtime-tail-write-ops.ts +97 -0
- package/src/db/schema.ts +4 -1
- package/src/db/spawn-budget.ts +5 -0
- package/src/db/spawn-delegation.ts +3 -12
- package/src/db/sql-audit-indexes.ts +3 -0
- package/src/db/stats-async.ts +5 -3
- package/src/db/task-entity.ts +5 -4
- package/src/db/team-claim-policy.ts +60 -0
- package/src/db/teams-async.ts +4 -0
- package/src/db/teams-write-ops.ts +4 -0
- package/src/db/terminal-events.ts +15 -0
- package/src/db/timer-cutover-bodies.ts +292 -0
- package/src/db/timer-cutover-core.ts +37 -278
- package/src/db/timer-cutover-state.ts +40 -0
- package/src/db/timer-cutover-write-ops.ts +1 -40
- package/src/db/token-db-write-ops.ts +2 -0
- package/src/db/token-standing-async.ts +12 -0
- package/src/db/token-standing.ts +6 -9
- package/src/db/token-usage-retention.ts +33 -0
- package/src/db/token-usage-write-ops.ts +1 -1
- package/src/db/token-usage.ts +4 -1
- package/src/db/user-invites-async.ts +13 -0
- package/src/db/user-invites.ts +3 -3
- package/src/db/users.ts +14 -6
- package/src/db/workflow-execution.ts +3 -3
- package/src/db/workspaces.ts +8 -5
- package/src/db/write-ops.ts +31 -12
- package/src/db/writer-fault-seam.ts +2 -9
- package/src/db/writer-fault-test-ops.ts +18 -0
- package/src/db/writer-gateway.ts +42 -46
- package/src/dev.ts +12 -16
- package/src/event-loop-lag.ts +4 -2
- package/src/event-loop-yield.ts +2 -2
- package/src/events.ts +10 -8
- package/src/host-provider-store.ts +5 -4
- package/src/hub-metrics-report.ts +5 -1
- package/src/hub-metrics.ts +38 -18
- package/src/init.ts +299 -0
- package/src/injection-sweep-pacing.ts +6 -8
- package/src/invite-link.ts +16 -9
- package/src/land-gate-notifications.ts +11 -10
- package/src/land-gate-queue-progress.ts +3 -3
- package/src/land-settle-dispatch.ts +52 -92
- package/src/lifecycle-context-pressure.ts +11 -10
- package/src/lifecycle-manager.ts +104 -98
- package/src/maintenance/breaker.ts +18 -16
- package/src/maintenance/checkout-refresh.ts +18 -1
- package/src/maintenance/critical-job-watchdog.ts +3 -3
- package/src/maintenance/events.ts +3 -3
- package/src/maintenance/history-retention-job.ts +30 -0
- package/src/maintenance/jobs.ts +29 -67
- package/src/maintenance/long-running-work.ts +3 -1
- package/src/maintenance/offline-agent-prune-job.ts +28 -0
- package/src/maintenance/orphaned-sessions.ts +5 -4
- package/src/maintenance/pauses.ts +4 -10
- package/src/maintenance/plan-ready-notice-job.ts +71 -0
- package/src/maintenance/scheduler.ts +18 -13
- package/src/maintenance/stalled-delivery-pager.ts +4 -4
- package/src/maintenance/teams.ts +19 -30
- package/src/maintenance/workspaces.ts +17 -27
- package/src/managed-policy-escalation.ts +7 -7
- package/src/managed-policy.ts +3 -3
- package/src/managed-provider-gate.ts +5 -4
- package/src/managed-spawn-reservation.ts +5 -4
- package/src/mcp/index.ts +8 -8
- package/src/mcp/output-descriptions.ts +1 -1
- package/src/mcp/presentation.ts +2 -1
- package/src/mcp/runtime-output.ts +6 -1
- package/src/mcp/self-care-visibility.ts +2 -2
- package/src/mcp/spawn-targets-matrix.ts +10 -1
- package/src/mcp/tool-groups.ts +3 -2
- package/src/mcp/tool-roles.ts +81 -0
- package/src/mcp/tools-workspace.ts +1 -1
- package/src/mcp-blackboard-tools.ts +6 -5
- package/src/mcp-decision-tools.ts +7 -7
- package/src/mcp-egress-tools.ts +10 -9
- package/src/mcp-issue-activity-tools.ts +2 -2
- package/src/mcp-issue-association-tools.ts +4 -4
- package/src/mcp-issue-ref-tools.ts +3 -3
- package/src/mcp-merge-tools.ts +5 -5
- package/src/mcp-notification-subscription-tools.ts +14 -15
- package/src/mcp-output-levels.test-fixture.ts +1 -1
- package/src/mcp-profile-trust-tools.ts +1 -1
- package/src/mcp-project-journal-tools.ts +4 -12
- package/src/mcp-project-tools.ts +17 -18
- package/src/mcp-routing-policy-tools.ts +3 -2
- package/src/mcp-team-tools.ts +6 -6
- package/src/mcp-workflow-tools.ts +5 -3
- package/src/memory-area-injection.ts +13 -12
- package/src/memory-boundary-capture.ts +6 -6
- package/src/memory-injection.ts +45 -43
- package/src/merge-pause-maintenance.ts +5 -4
- package/src/notification-router.ts +44 -17
- package/src/notify.ts +5 -5
- package/src/observed-reset-refresh.ts +4 -4
- package/src/operator-alarm.ts +2 -5
- package/src/project-ingest.ts +6 -6
- package/src/project-instructions.ts +8 -1
- package/src/project-trust.ts +12 -11
- package/src/prompt-resolver.ts +3 -3
- package/src/provider-quota-async.ts +5 -7
- package/src/provider-timeline-event.ts +4 -7
- package/src/quota-band-delivery.ts +2 -2
- package/src/recipe-runner.ts +4 -3
- package/src/retention-config-store.ts +4 -3
- package/src/reviewer-pipeline.ts +11 -10
- package/src/routes/_route.ts +4 -4
- package/src/routes/_shared.ts +13 -12
- package/src/routes/agent-effort.ts +5 -5
- package/src/routes/agent-heartbeat-quota.ts +23 -0
- package/src/routes/agent-keep.ts +1 -1
- package/src/routes/agent-reporting.ts +1 -1
- package/src/routes/agent-self-effort.ts +5 -5
- package/src/routes/agent-sessions.ts +24 -24
- package/src/routes/agents-spawn.ts +1 -1
- package/src/routes/agents.ts +17 -119
- package/src/routes/auth.ts +44 -17
- package/src/routes/authority-audit.ts +2 -2
- package/src/routes/automations.ts +6 -5
- package/src/routes/channel-binding-delete.ts +1 -1
- package/src/routes/channel-output.ts +3 -3
- package/src/routes/claude-api-budget.ts +5 -5
- package/src/routes/commands-listing.ts +1 -1
- package/src/routes/commands.ts +29 -27
- package/src/routes/context-resets.ts +2 -2
- package/src/routes/coordinator-teams.ts +1 -1
- package/src/routes/decisions.ts +2 -2
- package/src/routes/host-providers.ts +18 -0
- package/src/routes/host-secret-files.ts +1 -1
- package/src/routes/hosts.ts +11 -11
- package/src/routes/inbox.ts +3 -2
- package/src/routes/index.ts +7 -3
- package/src/routes/integrations.ts +9 -7
- package/src/routes/issue-activity.ts +2 -2
- package/src/routes/issue-associations.ts +4 -4
- package/src/routes/issue-refs.ts +3 -3
- package/src/routes/kernel-timers-operator.ts +1 -1
- package/src/routes/memory.ts +1 -1
- package/src/routes/merges.ts +11 -11
- package/src/routes/messages.ts +23 -17
- package/src/routes/orchestrator-bootstrap.ts +3 -1
- package/src/routes/orchestrator-host-registration.ts +2 -0
- package/src/routes/orchestrator-host-utilization.ts +2 -2
- package/src/routes/orchestrator-proxy.ts +2 -2
- package/src/routes/orchestrator.ts +27 -18
- package/src/routes/pairs.ts +8 -8
- package/src/routes/project-profile-instructions.ts +1 -1
- package/src/routes/project-trust.ts +1 -1
- package/src/routes/projects.ts +16 -16
- package/src/routes/prompt-templates.ts +12 -12
- package/src/routes/provider-quotas.ts +10 -10
- package/src/routes/run-command.ts +1 -1
- package/src/routes/secrets-backup.ts +4 -5
- package/src/routes/secrets-import.ts +3 -4
- package/src/routes/secrets-vault.ts +12 -14
- package/src/routes/settings.ts +1 -1
- package/src/routes/shipping.ts +9 -1
- package/src/routes/spawn-policy.ts +8 -7
- package/src/routes/sse.ts +2 -2
- package/src/routes/team-templates.ts +7 -7
- package/src/routes/teams.ts +10 -10
- package/src/routes/tokens.ts +18 -17
- package/src/routes/users.ts +24 -24
- package/src/routes/viewer-read.ts +3 -3
- package/src/routes/web-tool-calls.ts +4 -4
- package/src/routes/workflows.ts +2 -2
- package/src/routes/workspaces.ts +17 -16
- package/src/routing-policy-push.ts +6 -6
- package/src/runtime-grant.ts +17 -11
- package/src/runtime-install.ts +30 -0
- package/src/runtime-tokens.ts +20 -28
- package/src/secrets-broker/config.ts +1 -1
- package/src/secrets-broker/service.ts +2 -2
- package/src/security.ts +3 -1
- package/src/self-resume-carry.ts +21 -110
- package/src/self-resume-supersede.ts +4 -3
- package/src/self-resume.ts +54 -66
- package/src/server-background.ts +1 -1
- package/src/server.ts +25 -26
- package/src/services/agent-action.ts +12 -31
- package/src/services/agent-effort.ts +7 -32
- package/src/services/agent-hang-watchdog-job.ts +2 -2
- package/src/services/agent-heartbeat.ts +166 -0
- package/src/services/agent-reporting.ts +1 -1
- package/src/services/auth-context.ts +6 -0
- package/src/services/browser-inventory.ts +3 -3
- package/src/services/browser-session-state.ts +3 -2
- package/src/services/browser-session.ts +21 -27
- package/src/services/bus-command-update.ts +9 -9
- package/src/services/checkout-refresh-state.ts +1 -0
- package/src/services/checkout-refresh.test-fixture.ts +3 -2
- package/src/services/command-host.ts +7 -2
- package/src/services/coordinator-digest.ts +3 -2
- package/src/services/dispatch-command.ts +12 -13
- package/src/services/effective-launch-driver.ts +14 -9
- package/src/services/host-changed-paths.test-fixture.ts +5 -6
- package/src/services/host-project-readiness.ts +2 -2
- package/src/services/host-providers.ts +1 -1
- package/src/services/host-utilization.ts +9 -9
- package/src/services/idle-agent-digest.ts +17 -12
- package/src/services/idle-epics.ts +4 -4
- package/src/services/interrupt-agent.ts +12 -9
- package/src/services/issue-activity.ts +3 -3
- package/src/services/issue-associations.ts +15 -18
- package/src/services/issue-lifecycle-comments.ts +3 -2
- package/src/services/issue-lifecycle.ts +14 -13
- package/src/services/issue-refs.ts +4 -5
- package/src/services/kernel-timers-cutover-chaos-worker.ts +1 -1
- package/src/services/kernel-timers-ingress-chaos-worker.ts +6 -1
- package/src/services/kernel-timers-ingress.ts +3 -3
- package/src/services/kernel-timers-message-authority-chaos-worker.ts +3 -10
- package/src/services/kernel-timers-operator-chaos-worker.ts +3 -2
- package/src/services/kernel-timers-outbox.ts +1 -1
- package/src/services/kernel-timers-stage10-operator.ts +1 -1
- package/src/services/kernel-timers.ts +4 -3
- package/src/services/land-gate-placement.ts +11 -2
- package/src/services/land-issue-relations.ts +5 -4
- package/src/services/land-restart-retry.ts +7 -6
- package/src/services/landed-ancestry.ts +6 -5
- package/src/services/legacy-landing-host.ts +4 -1
- package/src/services/legacy-landing-recovery.ts +8 -6
- package/src/services/managed-running.ts +17 -17
- package/src/services/memory-areas.ts +3 -3
- package/src/services/merge-pause.ts +9 -15
- package/src/services/operator-decisions.ts +37 -41
- package/src/services/orchestrator-registration-recovery.ts +6 -2
- package/src/services/orchestrator-upgrade.ts +14 -12
- package/src/services/permission-decision.ts +4 -3
- package/src/services/plan-ci-notice.ts +1 -1
- package/src/services/plan-conformance.ts +4 -4
- package/src/services/plan-dispatch-policy.ts +10 -3
- package/src/services/plan-dispatch.ts +35 -14
- package/src/services/plan-graph.ts +39 -261
- package/src/services/plan-import.ts +1 -1
- package/src/services/plan-live-bindings.ts +8 -37
- package/src/services/plan-task-create.ts +1 -1
- package/src/services/plan-terminal-refs.ts +2 -12
- package/src/services/plan-wake-digest.ts +8 -3
- package/src/services/profile-trust.ts +2 -2
- package/src/services/project.ts +11 -10
- package/src/services/prompt-templates.ts +6 -5
- package/src/services/provider-api-key.ts +73 -0
- package/src/services/provider-hold-nudge.ts +9 -9
- package/src/services/provider-hold-record.ts +13 -12
- package/src/services/provider-state-audit.ts +19 -18
- package/src/services/provisioning-harness/driver.ts +1 -1
- package/src/services/provisioning-harness/fixture-matrix.ts +3 -3
- package/src/services/provisioning-harness/lifecycle.ts +24 -22
- package/src/services/provisioning-harness/prepare.ts +16 -17
- package/src/services/rate-limit-resume.ts +10 -9
- package/src/services/red-main-auto-revert.ts +7 -5
- package/src/services/red-main-controller-deps.ts +20 -3
- package/src/services/red-main-incident.ts +3 -1
- package/src/services/red-main-quarantine.ts +2 -3
- package/src/services/register-agent.ts +22 -22
- package/src/services/restart-project-role.ts +1 -1
- package/src/services/restart-spawn.ts +17 -16
- package/src/services/review-publish.ts +7 -24
- package/src/services/review-ref-reconcile.ts +29 -38
- package/src/services/runtime-dependency-alert.ts +27 -0
- package/src/services/scheduler-command.ts +11 -9
- package/src/services/scheduler.ts +5 -5
- package/src/services/self-effort-grant.ts +5 -25
- package/src/services/send-message.ts +16 -33
- package/src/services/shutdown-agent.ts +17 -14
- package/src/services/spawn-agent.ts +12 -41
- package/src/services/spawn-chain-inspector.ts +1 -1
- package/src/services/spawn-cwd-placement.ts +21 -5
- package/src/services/spawn-issue-activity.ts +8 -6
- package/src/services/spawn-launch.ts +17 -1
- package/src/services/spawn-loss-escalation.ts +1 -1
- package/src/services/spawn-registration-watchdog.ts +2 -2
- package/src/services/spawn-repo-probe.ts +7 -5
- package/src/services/spawn-tree-cleanup.ts +7 -8
- package/src/services/steward-reaper.ts +4 -4
- package/src/services/task-context-hydration.ts +25 -1
- package/src/services/task-delivery.ts +20 -34
- package/src/services/task-entity.ts +40 -203
- package/src/services/task-issue-link.ts +13 -20
- package/src/services/task-issue-weave.ts +12 -11
- package/src/services/task-lifecycle.ts +27 -31
- package/src/services/task-repo-cwd.ts +37 -0
- package/src/services/task-review-hold.ts +4 -17
- package/src/services/task-semantic-events.ts +13 -11
- package/src/services/task-state-reconcile.ts +3 -4
- package/src/services/task-validation.ts +2 -2
- package/src/services/team-templates.ts +5 -5
- package/src/services/team.ts +31 -98
- package/src/services/terminal-provider-exit.ts +6 -5
- package/src/services/timer-message-fire-chaos-worker.ts +7 -3
- package/src/services/timer-message-fire-outbox.ts +1 -1
- package/src/services/transient-agent-reaper.ts +22 -19
- package/src/services/turn-reconcile-audit.ts +9 -9
- package/src/services/user-onboarding.ts +8 -6
- package/src/services/user-profile.ts +6 -9
- package/src/services/work-finality.ts +16 -4
- package/src/services/workflow-auto-start.ts +2 -1
- package/src/services/workflow-caller.ts +61 -4
- package/src/services/workflow-child-proof-worker.ts +1 -1
- package/src/services/workflow-control-proof-worker.ts +1 -1
- package/src/services/workflow-coordinator.ts +8 -2
- package/src/services/workflow-decisions.ts +5 -5
- package/src/services/workflow-deferred-cleanup.ts +1 -1
- package/src/services/workflow-effect-driver.ts +42 -19
- package/src/services/workflow-effects.ts +41 -27
- package/src/services/workflow-pins.ts +7 -4
- package/src/services/workflow-reconcile.ts +1 -0
- package/src/services/workflow-resume-pins.ts +3 -3
- package/src/services/workflow-routing-defaults.ts +18 -0
- package/src/services/workflow-run-view.ts +4 -3
- package/src/services/workflow-run.test-fixture.ts +1 -1
- package/src/services/workflow-runs.ts +34 -22
- package/src/services/workflow-supervisor-state.ts +21 -1
- package/src/services/workflow-supervisor.ts +4 -3
- package/src/services/workspace-recovery.ts +4 -3
- package/src/setup.ts +47 -8
- package/src/spawn-admission.ts +10 -2
- package/src/spawn-placement.ts +27 -9
- package/src/spawn-targets.ts +8 -8
- package/src/sse-agent-status.ts +15 -6
- package/src/sse.ts +49 -24
- package/src/startup-context-injection.ts +61 -57
- package/src/steward-handoff.ts +4 -3
- package/src/steward-policy-cleanup.ts +9 -8
- package/src/steward.ts +2 -2
- package/src/task-dispatch-live.ts +5 -2
- package/src/task-dispatcher.ts +2 -2
- package/src/token-db.ts +2 -2
- package/src/token-usage-async.ts +2 -4
- package/src/user-awaiting-reply.ts +5 -5
- package/src/utils.ts +7 -0
- package/src/workspace-actions.ts +24 -29
- package/src/workspace-auto-merge.ts +14 -12
- package/src/workspace-changed-paths-client.ts +16 -5
- package/src/workspace-cleanup-stale.ts +30 -7
- package/src/workspace-command-settle.ts +24 -16
- package/src/workspace-config.ts +1 -1
- package/src/workspace-conflict-resolver.ts +9 -7
- package/src/workspace-dead-owner-recovery.ts +5 -4
- package/src/workspace-escalation.ts +12 -11
- package/src/workspace-human-escalation.ts +3 -3
- package/src/workspace-land-gate-watchdog.ts +3 -3
- package/src/workspace-land-refusal.ts +20 -0
- package/src/workspace-land-stopped.ts +1 -0
- package/src/workspace-merge.ts +10 -26
- package/src/workspace-nothing-to-land-notice.ts +2 -2
- package/src/workspace-orphans.ts +18 -37
- package/src/workspace-pr-completion.ts +10 -8
- package/src/workspace-rekey.ts +3 -3
- package/src/workspace-steward-failure.ts +2 -2
- package/src/workspace-steward-wake.ts +2 -2
- package/public/assets/agent-liveness-CaNwK0Zf.js +0 -2
- package/public/assets/overview-C1DCTzzV.js +0 -2
- package/public/assets/provider-display-DsuWMvVL.js +0 -2
- package/public/assets/run-card-CpKqRbhg.js +0 -2
- package/public/assets/shipping-B9YtnwtG.js +0 -2
- package/public/assets/store-DcClXLH0.js +0 -9
- package/runner/src/agent-runner/http-liveness.ts +0 -85
- package/src/db/on-loop-write-transaction.ts +0 -34
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { markTaskAgentReapedAsync } from "../db/task-entity-async";
|
|
2
|
+
import { markWorkspaceCarryPendingAsync } from "../db/runtime-tail-async";
|
|
1
3
|
// #831 — Task lifecycle automation ON LAND. The land event already knows the branch, commit,
|
|
2
4
|
// backlink, and (worker-reported) gate ledger; this service turns that authoritative land into
|
|
3
5
|
// the Task drive the coordinator otherwise hand-does (~40% of its tool calls): advance the
|
|
@@ -24,13 +26,7 @@
|
|
|
24
26
|
import { errMessage } from "@humwick/sdk";
|
|
25
27
|
import { boundTaskIdsForWorkspace } from "./workspace-task-binding";
|
|
26
28
|
import { resolveLandedTaskIds, type LandedTaskAttributionInput } from "./landed-task-attribution";
|
|
27
|
-
import {
|
|
28
|
-
activeWorkspaceCarryPendingHeadsForTask,
|
|
29
|
-
getAgent,
|
|
30
|
-
getTaskDetail,
|
|
31
|
-
markTaskAgentReaped,
|
|
32
|
-
markWorkspaceCarryPending,
|
|
33
|
-
} from "../db";
|
|
29
|
+
import { activeWorkspaceCarryPendingHeadsForTask, getAgent, getTaskDetail } from "../db";
|
|
34
30
|
import { setTaskEntityStage, setTaskEntityStatus } from "./task-entity";
|
|
35
31
|
import { carryPendingBlocker, carryPendingDiscardedHead, isCarryPendingBlocker, openCarryPendingBlocker } from "./carry-pending";
|
|
36
32
|
import { postTaskMilestoneComment, taskCloseBridgeAsync, type TaskCloseBridgeEntry } from "./task-issue-weave";
|
|
@@ -142,13 +138,13 @@ export interface CarryPendingMarkResult {
|
|
|
142
138
|
// records a second blocker rather than being swallowed as idempotent. SCOPED (preserves other
|
|
143
139
|
// blockers); never reopens a terminal Task.
|
|
144
140
|
// FAILS CLOSED: a swallowed marking failure would silently drop the guard, so failures flip `ok`.
|
|
145
|
-
export function markWorkspaceTasksCarryPending(workspace: LifecycleWorkspace, discardedHead: string, log: LogFn = (m) => console.warn(m)): CarryPendingMarkResult {
|
|
141
|
+
export async function markWorkspaceTasksCarryPending(workspace: LifecycleWorkspace, discardedHead: string, log: LogFn = (m) => console.warn(m)): Promise<CarryPendingMarkResult> {
|
|
146
142
|
const head = discardedHead.trim();
|
|
147
143
|
if (!head) return { ok: true, marked: [], failed: [] };
|
|
148
144
|
// 1) DURABLE WORKSPACE MARKER FIRST — its successful persistence is half the fail-closed signal.
|
|
149
145
|
let markerRecorded = false;
|
|
150
146
|
try {
|
|
151
|
-
markerRecorded =
|
|
147
|
+
markerRecorded = (await markWorkspaceCarryPendingAsync(workspace.id, head));
|
|
152
148
|
} catch (error) {
|
|
153
149
|
log(`#1456 carry-pending workspace marker write failed for ${workspace.id}: ${errMessage(error)}`);
|
|
154
150
|
}
|
|
@@ -163,7 +159,7 @@ export function markWorkspaceTasksCarryPending(workspace: LifecycleWorkspace, di
|
|
|
163
159
|
// Already have a blocker for THIS exact head? nothing to add (idempotent per head).
|
|
164
160
|
if (existing.some((b) => isCarryPendingBlocker(b) && carryPendingDiscardedHead(b) === head)) { marked.push(taskId); continue; }
|
|
165
161
|
try {
|
|
166
|
-
setTaskEntityStatus(taskId, {
|
|
162
|
+
await setTaskEntityStatus(taskId, {
|
|
167
163
|
status: "blocked",
|
|
168
164
|
blockedBy: [...existing, carryPendingBlocker(head)],
|
|
169
165
|
note: `#1456 carry-pending: delivered head ${head} was reverted (moved base); it must be confirmed carried before landing`,
|
|
@@ -227,7 +223,7 @@ function landKeyFor(input: LandedTaskLifecycleInput): string {
|
|
|
227
223
|
return `land:${base}:${input.workspace.id}:${input.workspace.branch ?? "unknown"}`.slice(0, 240);
|
|
228
224
|
}
|
|
229
225
|
|
|
230
|
-
export function emitWorkspaceTaskSemanticNotifications(input: {
|
|
226
|
+
export async function emitWorkspaceTaskSemanticNotifications(input: {
|
|
231
227
|
workspace: LifecycleWorkspace;
|
|
232
228
|
transition: TaskSemanticTransition;
|
|
233
229
|
actor?: string;
|
|
@@ -235,13 +231,13 @@ export function emitWorkspaceTaskSemanticNotifications(input: {
|
|
|
235
231
|
idempotencyKey?: string;
|
|
236
232
|
outcome?: Record<string, unknown>;
|
|
237
233
|
sha?: string;
|
|
238
|
-
}): number[] {
|
|
234
|
+
}): Promise<number[]> {
|
|
239
235
|
const emitted: number[] = [];
|
|
240
236
|
const coordinator = resolveCoordinatorAgentId(input.workspace.ownerAgentId ?? undefined);
|
|
241
237
|
for (const taskId of boundTaskIdsForWorkspace(input.workspace)) {
|
|
242
238
|
const task = getTaskDetail(taskId);
|
|
243
239
|
if (!task) continue;
|
|
244
|
-
emitTaskSemanticNotification({
|
|
240
|
+
await emitTaskSemanticNotification({
|
|
245
241
|
task,
|
|
246
242
|
transition: input.transition,
|
|
247
243
|
actor: input.actor,
|
|
@@ -273,7 +269,7 @@ interface ReapResult {
|
|
|
273
269
|
// exist (already gone → nothing to reap) and be `transient` (one-shot); a `persistent` worker
|
|
274
270
|
// keeps running (land-and-continue). Idempotent: any bound Task already stamped `reapedAt` short-
|
|
275
271
|
// circuits, so a re-land never re-reaps. Reuses the reaper's canonical shutdown path.
|
|
276
|
-
function maybeReapOwnerWorker(workspace: LifecycleWorkspace, outcomes: TaskLandOutcome[]): ReapResult {
|
|
272
|
+
async function maybeReapOwnerWorker(workspace: LifecycleWorkspace, outcomes: TaskLandOutcome[]): Promise<ReapResult> {
|
|
277
273
|
const driven = outcomes.filter((outcome) => !outcome.error);
|
|
278
274
|
if (driven.length === 0) return { reaped: false, reason: "no-task-driven" };
|
|
279
275
|
const agentId = workspace.ownerAgentId?.trim();
|
|
@@ -295,7 +291,7 @@ function maybeReapOwnerWorker(workspace: LifecycleWorkspace, outcomes: TaskLandO
|
|
|
295
291
|
const blocker = automaticDisposalBlocker(agent, Date.now(), { requireIdle: false });
|
|
296
292
|
if (blocker === "pending-own-run") return { reaped: false, agentId, reason: "pending-own-relay-run" };
|
|
297
293
|
if (blocker) return { reaped: false, agentId, reason: blocker };
|
|
298
|
-
requestTransientAgentShutdown(agent, {
|
|
294
|
+
(await requestTransientAgentShutdown(agent, {
|
|
299
295
|
reason: "deliverable-landed",
|
|
300
296
|
requestedBy: "task-lifecycle",
|
|
301
297
|
workspaceId: workspace.id,
|
|
@@ -303,13 +299,13 @@ function maybeReapOwnerWorker(workspace: LifecycleWorkspace, outcomes: TaskLandO
|
|
|
303
299
|
activityTitle: "One-shot worker reaped on land",
|
|
304
300
|
activityBody: `All ${driven.length} bound deliverable(s) landed green; disposing one-shot worker ${agentId} to free its slot + quota`,
|
|
305
301
|
landReason: "deliverable-landed",
|
|
306
|
-
});
|
|
302
|
+
}));
|
|
307
303
|
return { reaped: true, agentId };
|
|
308
304
|
}
|
|
309
305
|
|
|
310
306
|
// Stamp the reap marker on every bound Task + annotate the outcomes (the reap is decided ONCE at
|
|
311
307
|
// owner level, then applied across the owner's tasks).
|
|
312
|
-
function finalizeReap(outcomes: TaskLandOutcome[], reap: ReapResult, log: LogFn): void {
|
|
308
|
+
async function finalizeReap(outcomes: TaskLandOutcome[], reap: ReapResult, log: LogFn): Promise<void> {
|
|
313
309
|
for (const outcome of outcomes) {
|
|
314
310
|
if (outcome.error) continue;
|
|
315
311
|
outcome.reaped = reap.reaped;
|
|
@@ -317,10 +313,10 @@ function finalizeReap(outcomes: TaskLandOutcome[], reap: ReapResult, log: LogFn)
|
|
|
317
313
|
if (reap.reason) outcome.reapSkipReason = reap.reason;
|
|
318
314
|
if (reap.reaped && reap.agentId) {
|
|
319
315
|
try {
|
|
320
|
-
|
|
316
|
+
(await markTaskAgentReapedAsync(outcome.taskId, { agentId: reap.agentId, reason: "deliverable-landed" }));
|
|
321
317
|
const task = getTaskDetail(outcome.taskId);
|
|
322
318
|
if (task && task.status !== "done" && isAgentExitDoneWhen(task.doneWhen)) {
|
|
323
|
-
setTaskEntityStatus(outcome.taskId, {
|
|
319
|
+
await setTaskEntityStatus(outcome.taskId, {
|
|
324
320
|
status: validationCompletionStatus(task.validationItems),
|
|
325
321
|
note: "doneWhen=agent-exit satisfied by worker reap after land",
|
|
326
322
|
actor: "task-lifecycle",
|
|
@@ -375,7 +371,7 @@ async function driveTaskOnLand(
|
|
|
375
371
|
if (wsHeads.length > 0) {
|
|
376
372
|
carryHead = wsHeads[0];
|
|
377
373
|
try {
|
|
378
|
-
setTaskEntityStatus(taskId, {
|
|
374
|
+
await setTaskEntityStatus(taskId, {
|
|
379
375
|
status: "blocked",
|
|
380
376
|
blockedBy: [...(before.blockedBy ?? []), ...wsHeads.map(carryPendingBlocker)],
|
|
381
377
|
note: `#1456 carry-pending (inherited from workspace ${input.workspace.id}): delivered head(s) ${wsHeads.join(", ")} were reverted; confirm the carry before landing`,
|
|
@@ -405,7 +401,7 @@ async function driveTaskOnLand(
|
|
|
405
401
|
// 1 + 2 (deliverable-position axis) — advance the stage to `landed-on-main` and ATTACH the
|
|
406
402
|
// landed commit (idempotent append). The execution `status` axis is handled separately below.
|
|
407
403
|
const commit = input.mergedSha ? { sha: input.mergedSha, ...(input.subject ? { subject: input.subject } : {}) } : undefined;
|
|
408
|
-
let detail = setTaskEntityStage(taskId, {
|
|
404
|
+
let detail = await setTaskEntityStage(taskId, {
|
|
409
405
|
deliverableStage: "landed-on-main",
|
|
410
406
|
...(input.workspace.branch ? { branch: input.workspace.branch } : {}),
|
|
411
407
|
...(commit ? { commit } : {}),
|
|
@@ -480,14 +476,14 @@ async function driveTaskOnLand(
|
|
|
480
476
|
// the owner-level reap decision so `reaped` is accurate. A deliverable-LEVEL event ("task
|
|
481
477
|
// deliverable landed", not "commit X merged") through the existing bus; #835 enriches the
|
|
482
478
|
// audience/subscription layer on top of this same event.
|
|
483
|
-
function emitDeliverableLandedEvent(input: LandedTaskLifecycleInput, outcome: TaskLandOutcome): void {
|
|
479
|
+
async function emitDeliverableLandedEvent(input: LandedTaskLifecycleInput, outcome: TaskLandOutcome): Promise<void> {
|
|
484
480
|
const landKey = landKeyFor(input);
|
|
485
481
|
if (outcome.deliveredTipSuperseded) {
|
|
486
|
-
emitDeliverableSupersededEvent(input, outcome, landKey);
|
|
482
|
+
await emitDeliverableSupersededEvent(input, outcome, landKey);
|
|
487
483
|
return;
|
|
488
484
|
}
|
|
489
485
|
if (outcome.error) {
|
|
490
|
-
emitDeliverableErrorReceipt(input, outcome, landKey);
|
|
486
|
+
await emitDeliverableErrorReceipt(input, outcome, landKey);
|
|
491
487
|
return;
|
|
492
488
|
}
|
|
493
489
|
emitRelayEvent({
|
|
@@ -513,7 +509,7 @@ function emitDeliverableLandedEvent(input: LandedTaskLifecycleInput, outcome: Ta
|
|
|
513
509
|
const task = getTaskDetail(outcome.taskId);
|
|
514
510
|
if (!task) return;
|
|
515
511
|
const coordinator = resolveCoordinatorAgentId(input.workspace.ownerAgentId ?? undefined);
|
|
516
|
-
emitTaskSemanticNotification({
|
|
512
|
+
await emitTaskSemanticNotification({
|
|
517
513
|
task,
|
|
518
514
|
transition: "landed-on-main",
|
|
519
515
|
actor: "task-lifecycle",
|
|
@@ -530,7 +526,7 @@ function emitDeliverableLandedEvent(input: LandedTaskLifecycleInput, outcome: Ta
|
|
|
530
526
|
// be proven to have reached `main` after a moved-base revert. Routed durably (ttl null) to the
|
|
531
527
|
// coordinator AND the branch owner so it is confirmed/re-landed — the Task was held at `blocked`
|
|
532
528
|
// (non-terminal, recoverable), NOT landed-on-main, so the tracker never reports a phantom landing.
|
|
533
|
-
function emitDeliverableSupersededEvent(input: LandedTaskLifecycleInput, outcome: TaskLandOutcome, landKey: string): void {
|
|
529
|
+
async function emitDeliverableSupersededEvent(input: LandedTaskLifecycleInput, outcome: TaskLandOutcome, landKey: string): Promise<void> {
|
|
534
530
|
emitRelayEvent({
|
|
535
531
|
type: "task.deliverable_landed",
|
|
536
532
|
source: "server",
|
|
@@ -558,7 +554,7 @@ function emitDeliverableSupersededEvent(input: LandedTaskLifecycleInput, outcome
|
|
|
558
554
|
const createdBy = task?.createdBy?.trim();
|
|
559
555
|
const recipients = [...new Set([coordinator, taskOwnerTarget(task), owner].filter((r): r is string => Boolean(r)))];
|
|
560
556
|
if (recipients.length === 0) return;
|
|
561
|
-
routeNotification({
|
|
557
|
+
await routeNotification({
|
|
562
558
|
type: "task.land_conflict",
|
|
563
559
|
scope: {
|
|
564
560
|
taskId: String(outcome.taskId),
|
|
@@ -594,13 +590,13 @@ function emitDeliverableSupersededEvent(input: LandedTaskLifecycleInput, outcome
|
|
|
594
590
|
});
|
|
595
591
|
}
|
|
596
592
|
|
|
597
|
-
function emitDeliverableErrorReceipt(input: LandedTaskLifecycleInput, outcome: TaskLandOutcome, landKey: string): void {
|
|
593
|
+
async function emitDeliverableErrorReceipt(input: LandedTaskLifecycleInput, outcome: TaskLandOutcome, landKey: string): Promise<void> {
|
|
598
594
|
const coordinator = resolveCoordinatorAgentId(input.workspace.ownerAgentId ?? undefined);
|
|
599
595
|
const task = getTaskDetail(outcome.taskId);
|
|
600
596
|
const ownerTarget = task?.owner ? taskOwnerTarget(task) : undefined;
|
|
601
597
|
const recipients = [coordinator, ownerTarget].filter((id): id is string => Boolean(id)).map((agentId) => ({ agentId, matchedRule: "task-stakeholder" }));
|
|
602
598
|
if (!recipients.length) return;
|
|
603
|
-
routeNotification({
|
|
599
|
+
await routeNotification({
|
|
604
600
|
type: "task.landed",
|
|
605
601
|
scope: {
|
|
606
602
|
taskId: String(outcome.taskId),
|
|
@@ -662,7 +658,7 @@ export async function handleLandedTaskLifecycle(
|
|
|
662
658
|
// Reap (step 5) is decided ONCE at owner level, only when ALL bound tasks are satisfied — then
|
|
663
659
|
// applied/annotated across the outcomes. The deliverable event is emitted after, with the
|
|
664
660
|
// accurate `reaped`.
|
|
665
|
-
finalizeReap(outcomes, maybeReapOwnerWorker(input.workspace, outcomes), log);
|
|
666
|
-
for (const outcome of outcomes) emitDeliverableLandedEvent(input, outcome);
|
|
661
|
+
await finalizeReap(outcomes, (await maybeReapOwnerWorker(input.workspace, outcomes)), log);
|
|
662
|
+
for (const outcome of outcomes) await emitDeliverableLandedEvent(input, outcome);
|
|
667
663
|
return { handled: true, tasks: outcomes };
|
|
668
664
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { stringValue, type AgentCard } from "@humwick/sdk";
|
|
2
|
+
import { getAgent, getTaskDetailAsync, getTeam, listProjects, rootsForProject, workspaceRepoRootForCwd, ValidationError } from "../db";
|
|
3
|
+
import { isPathWithinBase } from "../utils";
|
|
4
|
+
|
|
5
|
+
// #3769 — workflows and role spawns resolve the same Task checkout, including callers in worktrees.
|
|
6
|
+
export async function taskLinkedRepoCwd(taskId: number, callerCwd?: string, caller?: AgentCard): Promise<string> {
|
|
7
|
+
const task = await getTaskDetailAsync(taskId);
|
|
8
|
+
if (!task) throw new ValidationError(`task ${taskId} not found or not a deliverable task`);
|
|
9
|
+
// #2844 — a Task created with `repo:` but no linked issue still names its project repo.
|
|
10
|
+
const repos = [...new Set([...task.issues.map((issue) => issue.repo), task.repo].filter((repo): repo is string => Boolean(repo)))];
|
|
11
|
+
if (repos.length === 0) {
|
|
12
|
+
throw new ValidationError(`task ${taskId} has no linked issue repo; pass cwd/orchestratorId explicitly`);
|
|
13
|
+
}
|
|
14
|
+
const candidates = listProjects()
|
|
15
|
+
.filter((project) => project.issueRepo && repos.includes(project.issueRepo))
|
|
16
|
+
.flatMap((project) => rootsForProject(project.id).map((root) => ({ project, root })));
|
|
17
|
+
if (candidates.length === 0) {
|
|
18
|
+
// #1627 — only registered roots can resolve a repo to a host checkout.
|
|
19
|
+
throw new ValidationError(`task ${taskId} links repo ${repos.join(", ")} but no Relay project root is registered for it, so relay cannot resolve a checkout path for it; pass cwd + orchestratorId explicitly, or register the checkout with relay_project_add_root`);
|
|
20
|
+
}
|
|
21
|
+
const team = caller?.teamId ? getTeam(caller.teamId) : null;
|
|
22
|
+
const rootTeam = team?.parentTeamId ? getTeam(team.parentTeamId) : team;
|
|
23
|
+
const coordinator = rootTeam?.coordinatorId ? getAgent(rootTeam.coordinatorId) : null;
|
|
24
|
+
const sources = [callerCwd, caller?.branchWorkspaceProjectRoot, stringValue(coordinator?.meta?.cwd)];
|
|
25
|
+
for (const source of sources) {
|
|
26
|
+
if (!source) continue;
|
|
27
|
+
const sourceCwd = workspaceRepoRootForCwd(source) ?? source;
|
|
28
|
+
const matching = candidates.filter(candidate => isPathWithinBase(sourceCwd, candidate.root.rootPath))
|
|
29
|
+
.sort((a, b) => b.root.rootPath.length - a.root.rootPath.length)[0];
|
|
30
|
+
if (matching) return matching.root.rootPath;
|
|
31
|
+
}
|
|
32
|
+
const projectId = team?.projectId ?? rootTeam?.projectId ?? task.projectId;
|
|
33
|
+
const preferred = projectId ? candidates.filter(candidate => candidate.project.id === projectId) : [];
|
|
34
|
+
const paths = [...new Set((preferred.length ? preferred : candidates).map(candidate => candidate.root.rootPath))];
|
|
35
|
+
if (paths.length === 1) return paths[0]!;
|
|
36
|
+
throw new ValidationError(`task ${taskId} links repo ${repos.join(", ")} with multiple registered roots; pass cwd explicitly`);
|
|
37
|
+
}
|
|
@@ -17,19 +17,7 @@
|
|
|
17
17
|
import { getCommandAsync } from "../commands-write";
|
|
18
18
|
import { settleWorkspaceMergeCommand } from "../workspace-command-settle";
|
|
19
19
|
import { errMessage, isRecord } from "@humwick/sdk";
|
|
20
|
-
import {
|
|
21
|
-
ReviewHoldConflictError,
|
|
22
|
-
clearTaskReviewHoldAsync,
|
|
23
|
-
getTaskDetail,
|
|
24
|
-
getWorkspace,
|
|
25
|
-
latestClearedReviewPromotion,
|
|
26
|
-
taskPendingReviewDelivery,
|
|
27
|
-
setTaskReviewHoldAsync,
|
|
28
|
-
unsettledTaskMergeCommandIdsAsync,
|
|
29
|
-
type ClearTaskReviewHoldResult,
|
|
30
|
-
type ClearTaskReviewHoldBodyInput,
|
|
31
|
-
type SetTaskReviewHoldResult,
|
|
32
|
-
} from "../db";
|
|
20
|
+
import { ReviewHoldConflictError, clearTaskReviewHoldAsync, getTaskDetail, getWorkspace, latestClearedReviewPromotion, taskPendingReviewDelivery, setTaskReviewHoldAsync, unsettledTaskMergeCommandIdsAsync, type ClearTaskReviewHoldResult, type ClearTaskReviewHoldBodyInput, type SetTaskReviewHoldResult, ValidationError } from "../db";
|
|
33
21
|
import { emitNewMessages, emitTaskChanged } from "../sse";
|
|
34
22
|
import { routeNotification } from "../notification-router";
|
|
35
23
|
import { COORDINATOR_AUTHORITY_HINT, callerHasTaskCoordinatorAuthority } from "../coordinator-authority";
|
|
@@ -42,7 +30,6 @@ import { landStoppedFact } from "../workspace-land-stopped";
|
|
|
42
30
|
import { headLand } from "../workspace-recorded-land";
|
|
43
31
|
import { reviewedHeadMatches } from "../db/task-review-hold";
|
|
44
32
|
import { ServiceAuthError } from "./errors";
|
|
45
|
-
import { ValidationError } from "../db";
|
|
46
33
|
import type { AuthContext } from "./auth-context";
|
|
47
34
|
import type { TaskDetail } from "../types";
|
|
48
35
|
import { taskOwnerTarget } from "../task-owner";
|
|
@@ -79,10 +66,10 @@ export function canControlTaskReviewHold(ctx: AuthContext, task: Pick<TaskDetail
|
|
|
79
66
|
return callerHasTaskCoordinatorAuthority(ctx.callerAgentId, task);
|
|
80
67
|
}
|
|
81
68
|
|
|
82
|
-
function notifyReviewHoldCleared(task: TaskDetail, promoted: { eventId: number; workspaceId: string; sourceHeadSha: string } | undefined): void {
|
|
69
|
+
async function notifyReviewHoldCleared(task: TaskDetail, promoted: { eventId: number; workspaceId: string; sourceHeadSha: string } | undefined): Promise<void> {
|
|
83
70
|
if (!promoted) return;
|
|
84
71
|
const recipients = [...new Set([task.ownerAgentId, taskOwnerTarget(task)].filter((item): item is string => Boolean(item && item.trim())))];
|
|
85
|
-
const delivered = routeNotification({
|
|
72
|
+
const delivered = await routeNotification({
|
|
86
73
|
type: "task.review-hold.cleared",
|
|
87
74
|
scope: {
|
|
88
75
|
taskId: String(task.id),
|
|
@@ -233,7 +220,7 @@ export async function setTaskReviewHoldControl(input: SetTaskReviewHoldControlIn
|
|
|
233
220
|
if (detail) emitTaskChanged(detail, input.held ? "task.review-hold.set" : "task.review-hold.cleared");
|
|
234
221
|
let landingHandoff: number | undefined;
|
|
235
222
|
if (promoted) {
|
|
236
|
-
if (detail) notifyReviewHoldCleared(detail, promoted);
|
|
223
|
+
if (detail) await notifyReviewHoldCleared(detail, promoted);
|
|
237
224
|
// Re-drive the ready/schedule effect for the promoted delivery (the held park deferred it;
|
|
238
225
|
// the promotion supplies the authorization the sweep needs).
|
|
239
226
|
landingHandoff = await reDrivePromotedLanding(task.id, promoted, actor, input.landingOperationId);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { framed } from "../hub-metrics";
|
|
2
|
+
import { addSubscriptionAsync } from "../db/lifecycle-tail-async";
|
|
1
3
|
import { guardedTimeout, LEGACY_HUMAN_AGENT_ID } from "@humwick/sdk";
|
|
2
4
|
import { getAgent } from "../db";
|
|
3
|
-
|
|
5
|
+
|
|
4
6
|
import { getTaskOwnerFacet } from "../db/task-owner";
|
|
5
7
|
import { isGoneAgentRecipient, resolveTaskOwnerAgentId, seatAgentIdOf, taskCoordinatorTarget, taskOwnerTarget, withoutSeatDuplicates } from "../task-owner";
|
|
6
8
|
import { emitRelayEvent } from "../events";
|
|
@@ -99,7 +101,7 @@ interface StatusPulseBatch {
|
|
|
99
101
|
|
|
100
102
|
const statusPulseBatches = new Map<string, StatusPulseBatch>();
|
|
101
103
|
|
|
102
|
-
export function autoSubscribeTaskCoordinator(agentId: string | undefined, taskId: number): boolean {
|
|
104
|
+
export async function autoSubscribeTaskCoordinator(agentId: string | undefined, taskId: number): Promise<boolean> {
|
|
103
105
|
const cleaned = agentId?.trim();
|
|
104
106
|
if (!cleaned || !getAgent(cleaned)) return false;
|
|
105
107
|
// #2862 — the owner (role seat or human) is addressed by every notice; a per-agent subscription
|
|
@@ -107,17 +109,17 @@ export function autoSubscribeTaskCoordinator(agentId: string | undefined, taskId
|
|
|
107
109
|
const facet = getTaskOwnerFacet(taskId);
|
|
108
110
|
if (facet?.owner && resolveTaskOwnerAgentId(facet) === cleaned) return true;
|
|
109
111
|
for (const transition of TASK_NOTIFICATION_TRANSITIONS) {
|
|
110
|
-
|
|
112
|
+
(await addSubscriptionAsync({
|
|
111
113
|
agentId: cleaned,
|
|
112
114
|
type: TASK_NOTIFICATION_TYPE[transition],
|
|
113
115
|
mode: "opt_in",
|
|
114
116
|
scopeMatch: { taskId: String(taskId) },
|
|
115
|
-
});
|
|
117
|
+
}));
|
|
116
118
|
}
|
|
117
119
|
return true;
|
|
118
120
|
}
|
|
119
121
|
|
|
120
|
-
export function emitTaskSemanticNotification(input: TaskSemanticNotificationInput): void {
|
|
122
|
+
export async function emitTaskSemanticNotification(input: TaskSemanticNotificationInput): Promise<void> {
|
|
121
123
|
const type = TASK_NOTIFICATION_TYPE[input.transition as KnownTaskSemanticTransition] ?? UNKNOWN_TASK_NOTIFICATION_TYPE;
|
|
122
124
|
const scope = taskNotificationScope(input);
|
|
123
125
|
const semanticEvent = `task.${input.transition}`;
|
|
@@ -166,7 +168,7 @@ export function emitTaskSemanticNotification(input: TaskSemanticNotificationInpu
|
|
|
166
168
|
.map((recipient) => ({ ...recipient, agentId: seatAgentIdOf(recipient.agentId) }));
|
|
167
169
|
for (const recipient of dedupeRecipients(seated)) {
|
|
168
170
|
if (recipient.agentId === input.actor) continue;
|
|
169
|
-
enqueueStatusPulse(recipient.agentId, {
|
|
171
|
+
await enqueueStatusPulse(recipient.agentId, {
|
|
170
172
|
taskId: input.task.id,
|
|
171
173
|
title: input.task.title,
|
|
172
174
|
transition: input.transition,
|
|
@@ -181,7 +183,7 @@ export function emitTaskSemanticNotification(input: TaskSemanticNotificationInpu
|
|
|
181
183
|
return;
|
|
182
184
|
}
|
|
183
185
|
|
|
184
|
-
routeNotification({
|
|
186
|
+
await routeNotification({
|
|
185
187
|
type,
|
|
186
188
|
scope,
|
|
187
189
|
recipients,
|
|
@@ -239,18 +241,18 @@ function pulseSupersededByLifecycle(agentId: string, item: StatusPulseDigestItem
|
|
|
239
241
|
|| (item.sha !== undefined && hasRecentLifecycleSignal(agentId, taskSignalKey(item.taskId, item.transition, item.sha)));
|
|
240
242
|
}
|
|
241
243
|
|
|
242
|
-
function enqueueStatusPulse(agentId: string, item: StatusPulseDigestItem): void {
|
|
244
|
+
async function enqueueStatusPulse(agentId: string, item: StatusPulseDigestItem): Promise<void> {
|
|
243
245
|
if (pulseSupersededByLifecycle(agentId, item)) return; // #1032b/#1038
|
|
244
246
|
const batch = statusPulseBatches.get(agentId) ?? { items: [] };
|
|
245
247
|
batch.items.push(item);
|
|
246
248
|
if (!batch.timer) {
|
|
247
249
|
// #3643 — the flush writes a message; a BUSY thrown from a bare timer exited the hub.
|
|
248
|
-
batch.timer = guardedTimeout(`[task-status-pulse] flush for ${agentId}`, TASK_STATUS_PULSE_BATCH_MS, () => flushTaskStatusPulses(agentId));
|
|
250
|
+
batch.timer = guardedTimeout(`[task-status-pulse] flush for ${agentId}`, TASK_STATUS_PULSE_BATCH_MS, framed("timer task-status-pulse", () => flushTaskStatusPulses(agentId)));
|
|
249
251
|
}
|
|
250
252
|
statusPulseBatches.set(agentId, batch);
|
|
251
253
|
}
|
|
252
254
|
|
|
253
|
-
export function flushTaskStatusPulses(agentId?: string): void {
|
|
255
|
+
export async function flushTaskStatusPulses(agentId?: string): Promise<void> {
|
|
254
256
|
const targets = agentId ? [agentId] : [...statusPulseBatches.keys()];
|
|
255
257
|
for (const target of targets) {
|
|
256
258
|
const batch = statusPulseBatches.get(target);
|
|
@@ -263,7 +265,7 @@ export function flushTaskStatusPulses(agentId?: string): void {
|
|
|
263
265
|
const fresh = batch.items.filter((item) => !pulseSupersededByLifecycle(target, item));
|
|
264
266
|
if (fresh.length === 0) continue;
|
|
265
267
|
const items = compactStatusPulseItems(fresh);
|
|
266
|
-
notifySystemMessage(target, {
|
|
268
|
+
await notifySystemMessage(target, {
|
|
267
269
|
subject: `Task status pulse (${items.length})`,
|
|
268
270
|
body: taskStatusPulseBody(items),
|
|
269
271
|
payload: {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// live in src/db/task-state-reconcile.ts; every change is applied by its conditional writer, which
|
|
5
5
|
// re-checks the rule in the transaction, then audited here with one `task.reconciled` relay event.
|
|
6
6
|
import { errMessage } from "@humwick/sdk";
|
|
7
|
-
import {
|
|
7
|
+
import { getGateway } from "../db/gateway";
|
|
8
8
|
import { getIssueRef } from "../db/issue-refs";
|
|
9
9
|
import { updateIssueRefAsync } from "../db/issue-refs-async";
|
|
10
10
|
import { applyTaskStateReconcileAsync, listTaskStateReconcileCandidatesAsync } from "../db/task-state-reconcile-async";
|
|
@@ -25,7 +25,6 @@ const ISSUE_REFRESHES_PER_RUN = 20;
|
|
|
25
25
|
const ISSUE_REFRESH_BACKOFF_MS = 60 * 60_000;
|
|
26
26
|
const CANDIDATE_LIMIT = 100;
|
|
27
27
|
/** A write step waits this long for another writer's lock before the run steps aside (the shared connection waits ~1 s). */
|
|
28
|
-
const STEP_BUSY_TIMEOUT_MS = 40;
|
|
29
28
|
|
|
30
29
|
export interface TaskStateReconcileOptions {
|
|
31
30
|
now?: number;
|
|
@@ -56,7 +55,7 @@ const refreshFailedAt = new Map<string, number>();
|
|
|
56
55
|
|
|
57
56
|
/** Post-commit effects of one applied change: the SSE/semantic pulse, plan refs and the audit event. */
|
|
58
57
|
async function publishApplied(applied: TaskStateReconcileApplied): Promise<void> {
|
|
59
|
-
emitStatusChangeEffects(applied.before, applied.detail, TASK_RECONCILE_ACTOR, undefined);
|
|
58
|
+
await emitStatusChangeEffects(applied.before, applied.detail, TASK_RECONCILE_ACTOR, undefined);
|
|
60
59
|
if (applied.detail.status === "done") await advanceTerminalPlanRefsAsync({ taskId: applied.detail.id, actor: TASK_RECONCILE_ACTOR });
|
|
61
60
|
emitRelayEvent({
|
|
62
61
|
type: "task.reconciled",
|
|
@@ -85,7 +84,7 @@ function stepRunner(opts: TaskStateReconcileOptions, result: TaskStateReconcileR
|
|
|
85
84
|
}
|
|
86
85
|
},
|
|
87
86
|
contended() {
|
|
88
|
-
if (
|
|
87
|
+
if (!getGateway().stats.writer.busy && getGateway().stats.writer.queued === 0) return false;
|
|
89
88
|
result.moreWork = true;
|
|
90
89
|
return true;
|
|
91
90
|
},
|
|
@@ -21,12 +21,12 @@ export async function setTaskValidationControl(taskId: number, input: SetTaskVal
|
|
|
21
21
|
const actor = ctx.callerAgentId ?? ctx.actor.id;
|
|
22
22
|
const result = await getGateway().write("taskEntity.setValidation", { id: taskId, input, actor }, { critical: true, idempotencyKey }) as unknown as { task: TaskDetail; eventId: number; item: TaskValidationItem };
|
|
23
23
|
emitTaskChanged(result.task, "task.validation");
|
|
24
|
-
if (before.status !== result.task.status) emitStatusChangeEffects(before, result.task, actor, String(result.eventId));
|
|
24
|
+
if (before.status !== result.task.status) await emitStatusChangeEffects(before, result.task, actor, String(result.eventId));
|
|
25
25
|
if (result.item.status === "failed") {
|
|
26
26
|
const coordinator = (result.task.owner ? taskOwnerTarget(result.task) : undefined)
|
|
27
27
|
?? (result.task.teamId ? resolveTeamCoordinatorAgentId(result.task.teamId) : undefined)
|
|
28
28
|
?? resolveCoordinatorAgentId(result.task.ownerAgentId) ?? result.task.createdBy;
|
|
29
|
-
emitTaskSemanticNotification({ task: result.task, transition: "gate-failed", actor, occurrenceKey: String(result.eventId), recipients: coordinator ? [coordinator] : [], outcome: { gate: "validation", detail: `${result.item.criterion}: ${result.item.note ?? "failed"}`, validationItem: result.item } });
|
|
29
|
+
await emitTaskSemanticNotification({ task: result.task, transition: "gate-failed", actor, occurrenceKey: String(result.eventId), recipients: coordinator ? [coordinator] : [], outcome: { gate: "validation", detail: `${result.item.criterion}: ${result.item.note ?? "failed"}`, validationItem: result.item } });
|
|
30
30
|
}
|
|
31
31
|
if (before.status !== "done" && result.task.status === "done") await advanceTerminalPlanRefsAsync({ taskId, actor });
|
|
32
32
|
return result.task;
|
|
@@ -22,7 +22,7 @@ interface TeamTemplateInstantiateInput {
|
|
|
22
22
|
|
|
23
23
|
interface TeamTemplateInstantiateResult {
|
|
24
24
|
template: TeamTemplate;
|
|
25
|
-
team: ReturnType<typeof setCallerTeamBrief
|
|
25
|
+
team: Awaited<ReturnType<typeof setCallerTeamBrief>>["team"];
|
|
26
26
|
spawned: SpawnAgentResult[];
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -76,8 +76,8 @@ export function getTeamTemplate(slug: string): TeamTemplate | null {
|
|
|
76
76
|
return getConfig<TeamTemplate>(TEAM_TEMPLATE_NAMESPACE, slug)?.value ?? null;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
export function deleteTeamTemplateAsync(slug: string, updatedBy?: string): Promise<boolean> {
|
|
80
|
-
return deleteConfigAsync(TEAM_TEMPLATE_NAMESPACE, slug, updatedBy);
|
|
79
|
+
export async function deleteTeamTemplateAsync(slug: string, updatedBy?: string): Promise<boolean> {
|
|
80
|
+
return (await deleteConfigAsync(TEAM_TEMPLATE_NAMESPACE, slug, updatedBy));
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
function parseFrozenComposition(raw: string): Array<Record<string, unknown>> {
|
|
@@ -158,11 +158,11 @@ export async function instantiateTeamTemplate(input: TeamTemplateInstantiateInpu
|
|
|
158
158
|
const slug = cleanString(input.slug, "slug", { required: true, max: 120 })!;
|
|
159
159
|
const template = getTeamTemplate(slug);
|
|
160
160
|
if (!template) throw new ValidationError(`team template ${slug} not found`);
|
|
161
|
-
const teamPayload = setCallerTeamBrief(ctx, {
|
|
161
|
+
const teamPayload = (await setCallerTeamBrief(ctx, {
|
|
162
162
|
title: template.title,
|
|
163
163
|
brief: template.brief,
|
|
164
164
|
definitionOfDone: template.definitionOfDone,
|
|
165
|
-
});
|
|
165
|
+
}));
|
|
166
166
|
const spawned: SpawnAgentResult[] = [];
|
|
167
167
|
for (const entry of template.composition) {
|
|
168
168
|
for (let i = 0; i < entry.count; i++) {
|