@humwick/server 0.130.2 → 0.130.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +73 -4
- package/package.json +8 -7
- package/public/assets/{MessageBubble-BWLqMGKG.js → MessageBubble-Bq9kr21N.js} +2 -2
- package/public/assets/{PlanGraphPanel-3TlIQpjk.js → PlanGraphPanel-Dqiroy06.js} +2 -2
- package/public/assets/{TraceView-Wimm0Czv.js → TraceView-DYU962-H.js} +2 -2
- package/public/assets/{VaultDecisionCard-Bau_vNax.js → VaultDecisionCard-DhPfzioE.js} +2 -2
- package/public/assets/{activity-CrSurn-r.js → activity-DzCcQTee.js} +2 -2
- package/public/assets/{agent-lineage-CknAJKcb.js → agent-lineage-SgDt9i3T.js} +2 -2
- package/public/assets/agent-liveness-Bq-s73jW.js +2 -0
- package/public/assets/{agent-name-DKbiIhBo.js → agent-name-CcY3Aijy.js} +2 -2
- package/public/assets/{agent-profiles-DwF6EQ4R.js → agent-profiles-cxtRBn6O.js} +2 -2
- package/public/assets/{agent-project-badge-Diz4Sjjb.js → agent-project-badge-DGYbIhaI.js} +2 -2
- package/public/assets/{agent-tools-CRhpRQza.js → agent-tools-DHbftV0N.js} +2 -2
- package/public/assets/{agent-type-icon-LrUEU3lB.js → agent-type-icon-CY113sp-.js} +2 -2
- package/public/assets/{agents-B-v66C-4.js → agents-BPzY7IlQ.js} +2 -2
- package/public/assets/{analytics-BqCb-LKi.js → analytics-DENFPv_a.js} +2 -2
- package/public/assets/{artifact-viewer-kf4pGuAR.js → artifact-viewer-KRvSc7sl.js} +2 -2
- package/public/assets/{artifacts-DJevXcvg.js → artifacts-C9gSmL3s.js} +2 -2
- package/public/assets/{artifacts-D32zyw4Y.js → artifacts-DT-HkI5O.js} +2 -2
- package/public/assets/{automation-BpRajx_5.js → automation-BsmjQhKD.js} +2 -2
- package/public/assets/{backlog-D_UjTdzX.js → backlog-8NYH_62t.js} +2 -2
- package/public/assets/{busy-health-N3VEh4ao.js → busy-health-D3hwvYb4.js} +2 -2
- package/public/assets/{channels-9jopungq.js → channels-DCJ5WL7O.js} +2 -2
- package/public/assets/{chat-CSXrTB3C.js → chat-DAIl357U.js} +3 -3
- package/public/assets/{code-preview-p1NnmqK0.js → code-preview-CzrZfr9U.js} +2 -2
- package/public/assets/{connectors-CZdqlDNL.js → connectors-xTxtlyou.js} +2 -2
- package/public/assets/{cosmos-BgdsE4dG.js → cosmos-BpebFLK2.js} +2 -2
- package/public/assets/{crate-agent-30aXTKva.js → crate-agent-BHvI5wXC.js} +2 -2
- package/public/assets/{dependency-graph-B_jvw2GE.js → dependency-graph-DGT0o3wJ.js} +2 -2
- package/public/assets/{deploys-DoN6bAb5.js → deploys-hqWOHSHE.js} +2 -2
- package/public/assets/{display-BrKWFGJz.js → display-CDeH4I8T.js} +2 -2
- package/public/assets/{files-D6XEu8Ng.js → files-BTeGVmTg.js} +2 -2
- package/public/assets/{fleet-C7jQWbw2.js → fleet-DgXtNgCa.js} +2 -2
- package/public/assets/{fleet-metrics-BiDs3MLx.js → fleet-metrics-BHEt5yc_.js} +2 -2
- package/public/assets/{formatted-body-CQBwc1fb.js → formatted-body-MLtodyPp.js} +3 -3
- package/public/assets/{formatted-body-impl-DyG0WsQS.js → formatted-body-impl-CAe664Z8.js} +2 -2
- package/public/assets/{host-providers-dialog-DKaW31dN.js → host-providers-dialog-mapF4Fj9.js} +2 -2
- package/public/assets/{index-CRHep3M9.js → index-CqqgOI5R.js} +5 -5
- package/public/assets/{insights-CzrtkpOE.js → insights-DNyf7IzF.js} +2 -2
- package/public/assets/{integrations-aVsUmigt.js → integrations-DlYOHq7T.js} +2 -2
- package/public/assets/{issue-ref-chip-BnSlM_95.js → issue-ref-chip-CeWBNWn7.js} +2 -2
- package/public/assets/{log-viewer-qe7Ee47Z.js → log-viewer-Cib8nqdE.js} +2 -2
- package/public/assets/{maintenance-NfjqFZAk.js → maintenance-DSn1cPm7.js} +2 -2
- package/public/assets/{managed-agents-BiH0HgaE.js → managed-agents-C3CkM81m.js} +2 -2
- package/public/assets/{markdown-preview-BixaT3Xr.js → markdown-preview-W4VQQPAv.js} +3 -3
- package/public/assets/{markdown-preview-impl-DNGlWIS3.js → markdown-preview-impl-CMsTdhjq.js} +2 -2
- package/public/assets/{memory-DNsCl6UX.js → memory-BV17qtO4.js} +2 -2
- package/public/assets/{messages-DopU1L1X.js → messages-Bm_1AqSA.js} +2 -2
- package/public/assets/{orchestrators-Cq7ckLQT.js → orchestrators-Dg-vfP09.js} +2 -2
- package/public/assets/{overview-C1DCTzzV.js → overview-DcYCrvlr.js} +2 -2
- package/public/assets/{pairs-DE_m6rrE.js → pairs-8o9nuG3V.js} +2 -2
- package/public/assets/{profile-icon-B3rfh77F.js → profile-icon-BsRyBMea.js} +2 -2
- package/public/assets/{project-profile-instructions-DQWZE0kA.js → project-profile-instructions-DETKFn_E.js} +2 -2
- package/public/assets/{projects-Br2Bd2h1.js → projects-M_m6AHws.js} +2 -2
- package/public/assets/{prompt-settings-BKvFsvGD.js → prompt-settings-C_mNCgeL.js} +2 -2
- package/public/assets/provider-display-BEeLXC_D.js +2 -0
- package/public/assets/{registry-Cw38_6gW.js → registry-DDHHHE5N.js} +2 -2
- package/public/assets/run-card-Dt4I4jaP.js +2 -0
- package/public/assets/{secrets-DxI-vzSq.js → secrets-BkVwxI5O.js} +2 -2
- package/public/assets/{service-access-settings-D9s_VJbd.js → service-access-settings-Crq-6a-B.js} +2 -2
- package/public/assets/{settings-CKZTVGIx.js → settings-CYcavMFu.js} +2 -2
- package/public/assets/shipping-H6gzEeZB.js +2 -0
- package/public/assets/{stats-DyUBKyWI.js → stats-BJVeWkpV.js} +2 -2
- package/public/assets/{status-dot-DYqlEUhJ.js → status-dot-BcHyw1Vw.js} +2 -2
- package/public/assets/store-DKPDIZBe.js +9 -0
- package/public/assets/{tasks-Bh7Chr4-.js → tasks-qJjlQPpx.js} +2 -2
- package/public/assets/{teams-bowI7qVY.js → teams-Cd5Sk1uX.js} +2 -2
- package/public/assets/{terminal-viewer-BgVLHdsU.js → terminal-viewer-CpY5_m7W.js} +3 -3
- package/public/assets/{terminal-viewer-impl-Dz22UPy6.js → terminal-viewer-impl-DI_2llFR.js} +2 -2
- package/public/assets/{use-agent-terminal-DSQQ-iY7.js → use-agent-terminal-0yJA_buM.js} +2 -2
- package/public/assets/{use-decisions-samMQhQf.js → use-decisions-uJXHf34W.js} +2 -2
- package/public/assets/{use-project-list-59LheVP7.js → use-project-list-CpWl6eHQ.js} +2 -2
- package/public/assets/{use-selectors-BZa25xEB.js → use-selectors-BdxBW8mL.js} +2 -2
- package/public/assets/{user-avatar-DHxlvUvV.js → user-avatar-3IndfpOc.js} +2 -2
- package/public/assets/{versioned-prompt-editor-BmED5DnJ.js → versioned-prompt-editor-CIVg7XB1.js} +2 -2
- package/public/assets/{work-queue-CSvpuNLz.js → work-queue-B9rnLwHZ.js} +2 -2
- package/public/assets/{workflow-marker-DAZcj5qt.js → workflow-marker-X8wxyhzC.js} +2 -2
- package/public/assets/{workflows-DdmxRSyg.js → workflows-o5YyMFW7.js} +2 -2
- package/public/assets/{workspaces-BxeKfVuF.js → workspaces-CzEGoAng.js} +2 -2
- package/public/cosmos.html +4 -4
- package/public/index.html +28 -28
- package/runner/plugins/claude/.claude-plugin/plugin.json +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 +2 -1
- 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/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/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 +1 -11
- 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/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 +8 -3
- 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/injection-sweep-pacing.ts +6 -8
- 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 +14 -15
- 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-secret-files.ts +1 -1
- package/src/routes/hosts.ts +11 -11
- package/src/routes/inbox.ts +3 -2
- package/src/routes/index.ts +2 -1
- 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 +1 -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 +2 -2
- package/src/routes/secrets-import.ts +1 -1
- package/src/routes/secrets-vault.ts +7 -7
- 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-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 +21 -22
- 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/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-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/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/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/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
package/src/routes/commands.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
|
+
import { fencePublishForPushAsync, setReviewRefFenceTokenAsync } from "../db/runtime-tail-async";
|
|
2
|
+
import { updateCommandAsync, claimPendingCommandAsync } from "../commands-write";
|
|
3
|
+
import { setOrchestratorUpgradeStateAsync } from "../db/orchestrators-async";
|
|
4
|
+
import { deleteWorkspaceAsync } from "../db/lifecycle-tail-async";
|
|
1
5
|
import { VaultError } from "../secrets-vault/keys";
|
|
2
6
|
import { settleProjectRepoCreation } from "../services/project-repo-create";
|
|
3
7
|
import { settleAgentExitCleanupAsync } from "../agent-exit-cleanup-async";
|
|
4
8
|
// Auto-split from routes.ts (#299). Domain: commands.
|
|
5
9
|
import { randomUUID } from "node:crypto";
|
|
6
10
|
import { VALID_AGENT_ACTIONS, agentControlActionIcon, auditEvent, authorizeRoute, emitCommand, error, json, parseBody, type AgentControlAction, type Handler } from "./_shared";
|
|
7
|
-
import { getReviewRefFenceToken,
|
|
11
|
+
import { getReviewRefFenceToken, ValidationError, getOrchestrator, getWorkspace, listOrchestrators, patchWorkspaceMetadataAsync, updateWorkspaceStatus } from "../db";
|
|
8
12
|
import { cleanCommandReport, cleanParams, cleanString, optionalEnum } from "../validation";
|
|
9
|
-
import { ValidationError, deleteWorkspace, getOrchestrator, getWorkspace, listOrchestrators, patchWorkspaceMetadataAsync, setOrchestratorUpgradeState, updateWorkspaceStatus } from "../db";
|
|
10
13
|
import { applyCommandToRecipe } from "../recipe-runner";
|
|
11
|
-
import {
|
|
12
|
-
import { claimPendingCommandAsync, updateCommandAsync } from "../commands-write";
|
|
14
|
+
import { getCommand, listAcceptedCommandsByOwner } from "../commands-db";
|
|
13
15
|
import {
|
|
14
16
|
acceptLandingProgressAsync,
|
|
15
17
|
acquireKernelPublishFenceAsync,
|
|
@@ -103,7 +105,7 @@ async function settleFailedOrchestratorUpgrade(command: Command): Promise<void>
|
|
|
103
105
|
const up = orch?.upgrade;
|
|
104
106
|
if (!orch || !up || up.status !== "pending" || up.commandId !== command.id) return;
|
|
105
107
|
const errMsg = command.error ?? "orchestrator upgrade failed";
|
|
106
|
-
|
|
108
|
+
(await setOrchestratorUpgradeStateAsync(orch.id, { ...up, status: "failed", settledAt: Date.now(), error: errMsg }));
|
|
107
109
|
await auditEvent({
|
|
108
110
|
clientId: `server-orchestrator-upgrade-command-failed-${orch.id}-${command.id}`,
|
|
109
111
|
kind: "state",
|
|
@@ -170,7 +172,7 @@ export const getCommandById: Handler = async (req, params) => {
|
|
|
170
172
|
// token it minted before claiming; this returns only rows that token accepted and that have not begun
|
|
171
173
|
// running. It is intentionally separate from the normal pending poll, where accepted rows are hidden.
|
|
172
174
|
export const postOwnedAcceptedCommands: Handler = async (req) => {
|
|
173
|
-
const denied = authorizeRoute(req, { scope: "command:write" });
|
|
175
|
+
const denied = (await authorizeRoute(req, { scope: "command:write" }));
|
|
174
176
|
if (denied) return denied;
|
|
175
177
|
const parsed = await parseBody<unknown>(req);
|
|
176
178
|
if (!parsed.ok || !isRecord(parsed.body)) return error("command body must be an object", 400);
|
|
@@ -188,7 +190,7 @@ export const postOwnedAcceptedCommands: Handler = async (req) => {
|
|
|
188
190
|
export const claimCommandById: Handler = async (req, params) => {
|
|
189
191
|
const current = getCommand(params.id!);
|
|
190
192
|
if (!current) return error("command not found", 404);
|
|
191
|
-
const denied = authorizeRoute(req, { scope: "command:write", resource: dispatchCommandAuthorizationResource(current) });
|
|
193
|
+
const denied = (await authorizeRoute(req, { scope: "command:write", resource: dispatchCommandAuthorizationResource(current) }));
|
|
192
194
|
if (denied) return denied;
|
|
193
195
|
const parsed = await parseBody<unknown>(req);
|
|
194
196
|
const expectedType = parsed.ok && isRecord(parsed.body) ? cleanString(parsed.body.type, "type", { max: 100 }) : undefined;
|
|
@@ -223,12 +225,12 @@ export const claimCommandById: Handler = async (req, params) => {
|
|
|
223
225
|
// persist it in the durable ledger. It is the ONLY credential that authorizes this command's terminal
|
|
224
226
|
// settlement (POST /commands/:id/settle-review-publish), so no other command:write holder — including an
|
|
225
227
|
// admin/`*` token — can spoof succeeded/failed/canceled on the claimed publish (generic PATCH + WS bus
|
|
226
|
-
// are refused at the
|
|
228
|
+
// are refused at the updateCommandAsync choke point). Returned to the executor only; never serialized to reads.
|
|
227
229
|
let reviewFenceToken: string | undefined;
|
|
228
230
|
if (claimed && claimed.type === "workspace.publish-review") {
|
|
229
231
|
const storedFenceToken = getReviewRefFenceToken(claimed.id);
|
|
230
232
|
reviewFenceToken = storedFenceToken ?? randomUUID();
|
|
231
|
-
if (!storedFenceToken)
|
|
233
|
+
if (!storedFenceToken) (await setReviewRefFenceTokenAsync(claimed.id, reviewFenceToken));
|
|
232
234
|
}
|
|
233
235
|
// #2663 — a land that lost its CAS because an OLDER land on the same target's lane is still
|
|
234
236
|
// pending is QUEUED, not out-raced, so name the head. Only a genuine CAS loss opens that: every
|
|
@@ -253,14 +255,14 @@ export const claimCommandById: Handler = async (req, params) => {
|
|
|
253
255
|
};
|
|
254
256
|
|
|
255
257
|
// #1452 round-13 HIGH#2 — token-gated settlement endpoint: the ONLY external path that may terminalize a
|
|
256
|
-
// CLAIMED review publish (generic PATCH + WS bus are refused at the
|
|
258
|
+
// CLAIMED review publish (generic PATCH + WS bus are refused at the updateCommandAsync choke point). The caller
|
|
257
259
|
// must present the exact fence token minted at claim; a missing/mismatched token fails closed (409). Only
|
|
258
|
-
// then does
|
|
260
|
+
// then does updateCommandAsync run with executor authority. Confines settlement to the actual executor.
|
|
259
261
|
export const settleReviewPublishCommandById: Handler = async (req, params) => {
|
|
260
262
|
const current = getCommand(params.id!);
|
|
261
263
|
if (!current) return error("command not found", 404);
|
|
262
264
|
if (current.type !== "workspace.publish-review") return error("not a review publish command", 400);
|
|
263
|
-
const denied = authorizeRoute(req, { scope: "command:write", resource: dispatchCommandAuthorizationResource(current) });
|
|
265
|
+
const denied = (await authorizeRoute(req, { scope: "command:write", resource: dispatchCommandAuthorizationResource(current) }));
|
|
264
266
|
if (denied) return denied;
|
|
265
267
|
const parsed = await parseBody<unknown>(req);
|
|
266
268
|
if (!parsed.ok || !isRecord(parsed.body)) return error("command body must be an object", 400);
|
|
@@ -271,7 +273,7 @@ export const settleReviewPublishCommandById: Handler = async (req, params) => {
|
|
|
271
273
|
if (!status) return error("status must be succeeded or failed", 400);
|
|
272
274
|
const result = cleanParams(parsed.body.result, "result");
|
|
273
275
|
const err = cleanString(parsed.body.error, "error", { max: 4000 });
|
|
274
|
-
const command =
|
|
276
|
+
const command = (await updateCommandAsync(params.id!, { status: status as CommandStatus, result, error: err }, { executor: true }));
|
|
275
277
|
if (!command) return error("command not found", 404);
|
|
276
278
|
emitCommand(command);
|
|
277
279
|
return json(serializeCommandForRead(command, authContextFromRequest(req)));
|
|
@@ -285,7 +287,7 @@ export const settleReviewPublishCommandById: Handler = async (req, params) => {
|
|
|
285
287
|
export const fencePublishCommandById: Handler = async (req, params) => {
|
|
286
288
|
const current = getCommand(params.id!);
|
|
287
289
|
if (!current) return error("command not found", 404);
|
|
288
|
-
const denied = authorizeRoute(req, { scope: "command:write", resource: dispatchCommandAuthorizationResource(current) });
|
|
290
|
+
const denied = (await authorizeRoute(req, { scope: "command:write", resource: dispatchCommandAuthorizationResource(current) }));
|
|
289
291
|
if (denied) return denied;
|
|
290
292
|
const parsed = await parseBody<unknown>(req);
|
|
291
293
|
const body = parsed.ok && isRecord(parsed.body) ? parsed.body : {};
|
|
@@ -335,7 +337,7 @@ export const fencePublishCommandById: Handler = async (req, params) => {
|
|
|
335
337
|
...(fenced.reason ? { reason: fenced.reason } : {}) });
|
|
336
338
|
}
|
|
337
339
|
if (current.type === "workspace.merge" && current.landingContainmentMode === "legacy-unfenced-v0") {
|
|
338
|
-
const fenced =
|
|
340
|
+
const fenced = (await fencePublishForPushAsync(params.id!, expectedType));
|
|
339
341
|
return json({ fenced: Boolean(fenced),
|
|
340
342
|
...(fenced ? { command: serializeCommandForRead(fenced, authContextFromRequest(req)) } : {}) });
|
|
341
343
|
}
|
|
@@ -386,7 +388,7 @@ export const fencePublishCommandById: Handler = async (req, params) => {
|
|
|
386
388
|
});
|
|
387
389
|
return json({ fenced: permit.permitted, ...(permit.permitId ? { permitId: permit.permitId } : {}), ...(permit.reason ? { reason: permit.reason } : {}) });
|
|
388
390
|
}
|
|
389
|
-
const fenced =
|
|
391
|
+
const fenced = (await fencePublishForPushAsync(params.id!, expectedType));
|
|
390
392
|
return json({
|
|
391
393
|
fenced: Boolean(fenced),
|
|
392
394
|
...(fenced ? { command: serializeCommandForRead(fenced, authContextFromRequest(req)) } : {}),
|
|
@@ -400,7 +402,7 @@ export const patchCommand: Handler = async (req, params) => {
|
|
|
400
402
|
try {
|
|
401
403
|
const current = getCommand(params.id!);
|
|
402
404
|
if (!current) return error("command not found", 404);
|
|
403
|
-
const denied = authorizeRoute(req, { scope: "command:write", resource: dispatchCommandAuthorizationResource(current) });
|
|
405
|
+
const denied = (await authorizeRoute(req, { scope: "command:write", resource: dispatchCommandAuthorizationResource(current) }));
|
|
404
406
|
if (denied) return denied;
|
|
405
407
|
const status = optionalEnum(parsed.body.status, "status", VALID_COMMAND_STATUSES);
|
|
406
408
|
const fencedLanding = (current.type === "workspace.merge" || isLandingCommandType(current.type))
|
|
@@ -462,23 +464,23 @@ export const patchCommand: Handler = async (req, params) => {
|
|
|
462
464
|
noteCompactionCommandCompleted(command);
|
|
463
465
|
// #2095 — durable "clear committed vs no-op" signal, fired on terminal compact/clear commands.
|
|
464
466
|
noteCompactionResult(command);
|
|
465
|
-
settleSelfResumeContinuationIngestion(command);
|
|
466
|
-
enqueueContinuationInjectionAfterSelfResume(command);
|
|
467
|
-
enqueueLifecycleIdentityInjectionAfterContextCommand(command);
|
|
468
|
-
notifySelfResumeNoOp(command);
|
|
469
|
-
settleContextResetCarry(command);
|
|
470
|
-
settleSelfRestartManagedState(command);
|
|
471
|
-
settleInterruptRedirectMessage(command);
|
|
467
|
+
(await settleSelfResumeContinuationIngestion(command));
|
|
468
|
+
(await enqueueContinuationInjectionAfterSelfResume(command));
|
|
469
|
+
(await enqueueLifecycleIdentityInjectionAfterContextCommand(command));
|
|
470
|
+
await notifySelfResumeNoOp(command);
|
|
471
|
+
(await settleContextResetCarry(command));
|
|
472
|
+
(await settleSelfRestartManagedState(command));
|
|
473
|
+
(await settleInterruptRedirectMessage(command));
|
|
472
474
|
// #1565 P4b — memory rides BESIDE the continuation as its own payload (§7), delta-gated on
|
|
473
475
|
// compact; and a memory inject that SUCCEEDS is what advances that gate. Ordered LAST and
|
|
474
476
|
// contained (#1565 F8): composing a block touches the DB, ownership and cwd resolution, and a
|
|
475
477
|
// throw in any of that must not take the rest of the settle chain down with it. The continuation
|
|
476
478
|
// enqueue stays first, so it is unaffected either way.
|
|
477
|
-
settleMemoryInjectionAfterContextCommand(command);
|
|
479
|
+
(await settleMemoryInjectionAfterContextCommand(command));
|
|
478
480
|
// #1951 — startup context (validation commands, report-up, profile charter, caller context)
|
|
479
481
|
// recomposed from the DB and re-injected beside the others, delta-gated on compact. Contained
|
|
480
482
|
// the same way (a compose throw must not take the rest of the settle chain down with it).
|
|
481
|
-
settleStartupContextInjectionAfterContextCommand(command);
|
|
483
|
+
(await settleStartupContextInjectionAfterContextCommand(command));
|
|
482
484
|
if (command.type === "scheduler.command") {
|
|
483
485
|
await settleScheduledCommandTimer(command);
|
|
484
486
|
}
|
|
@@ -548,7 +550,7 @@ export const patchCommand: Handler = async (req, params) => {
|
|
|
548
550
|
if (command.type === "agent.spawn" && command.status === "failed") {
|
|
549
551
|
const parent = isRecord(command.params) ? cleanString(command.params.spawnedBy, "params.spawnedBy", { max: 240 }) : undefined;
|
|
550
552
|
if (parent) {
|
|
551
|
-
notifyAgentSpawnFailed({
|
|
553
|
+
await notifyAgentSpawnFailed({
|
|
552
554
|
parent,
|
|
553
555
|
spawnRequestId: isRecord(command.params) ? cleanString(command.params.spawnRequestId, "params.spawnRequestId", { max: 160 }) : undefined,
|
|
554
556
|
provider: isRecord(command.params) ? cleanString(command.params.provider, "params.provider", { max: 40 }) : undefined,
|
|
@@ -24,9 +24,9 @@ export const postAgentContextResetRoute: Handler = async (req, params) => {
|
|
|
24
24
|
evidence: { instanceId: cleanString(body.instanceId, "instanceId", { max: 200 }) ?? null },
|
|
25
25
|
observedAt,
|
|
26
26
|
};
|
|
27
|
-
const carry = recordContextReset(fact);
|
|
27
|
+
const carry = (await recordContextReset(fact));
|
|
28
28
|
// #3698 — a commanded reset is refreshed by its command's settle; an uncommanded one only here.
|
|
29
|
-
if (!fact.commandId) refreshContextAfterObservedReset(fact);
|
|
29
|
+
if (!fact.commandId) (await refreshContextAfterObservedReset(fact));
|
|
30
30
|
return json({ ok: true, carryMessageId: carry?.id ?? null });
|
|
31
31
|
} catch (e) {
|
|
32
32
|
if (e instanceof ValidationError) return error(e.message, 400);
|
|
@@ -4,7 +4,7 @@ import type { CoordinatorTeamSummary } from "../types";
|
|
|
4
4
|
|
|
5
5
|
/** Connector discovery: no roster, plan, or per-team runtime queries. */
|
|
6
6
|
export const getCoordinatorTeams: Handler = async req => {
|
|
7
|
-
const denied = authorizeRoute(req, { scope: "channel:read" });
|
|
7
|
+
const denied = (await authorizeRoute(req, { scope: "channel:read" }));
|
|
8
8
|
if (denied) return denied;
|
|
9
9
|
const teams: CoordinatorTeamSummary[] = (await listCoordinatorTeamsAsync()).filter(team => team.coordinatorId).map(team => ({
|
|
10
10
|
id: team.id, coordinatorId: team.coordinatorId!, title: team.title ?? null, projectId: team.projectId, projectName: team.projectName,
|
package/src/routes/decisions.ts
CHANGED
|
@@ -48,7 +48,7 @@ export const postDecisionAnswerRoute: Handler = async (req, params) => {
|
|
|
48
48
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
49
49
|
const body = isRecord(parsed.body) ? parsed.body : {};
|
|
50
50
|
try {
|
|
51
|
-
return json(answerDecision(authContextFromRequest(req), id, { answers: body.answers, note: body.note }));
|
|
51
|
+
return json((await answerDecision(authContextFromRequest(req), id, { answers: body.answers, note: body.note })));
|
|
52
52
|
} catch (err) {
|
|
53
53
|
return routeError(err);
|
|
54
54
|
}
|
|
@@ -59,7 +59,7 @@ export const postDecisionRoute: Handler = async (req) => {
|
|
|
59
59
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
60
60
|
try {
|
|
61
61
|
const ctx = authContextFromRequest(req);
|
|
62
|
-
return json(fileDecision(ctx, isRecord(parsed.body) ? parsed.body : {}, callerProjectId(ctx)), 201);
|
|
62
|
+
return json((await fileDecision(ctx, isRecord(parsed.body) ? parsed.body : {}, callerProjectId(ctx))), 201);
|
|
63
63
|
} catch (err) {
|
|
64
64
|
return routeError(err);
|
|
65
65
|
}
|
|
@@ -10,7 +10,7 @@ import { authorizeRoute, error, parseBody, type Handler } from "./_shared";
|
|
|
10
10
|
export const postHostSecretFilesResolve: Handler = async (req, params) => {
|
|
11
11
|
const orch = getOrchestrator(params.id!);
|
|
12
12
|
if (!orch) return error("orchestrator not found", 404);
|
|
13
|
-
const denied = authorizeRoute(req, { scope: "command:write", resource: { orchestratorId: orch.id } });
|
|
13
|
+
const denied = (await authorizeRoute(req, { scope: "command:write", resource: { orchestratorId: orch.id } }));
|
|
14
14
|
if (denied) return denied;
|
|
15
15
|
const component = getComponentAuth(req);
|
|
16
16
|
if (!isFullReachRequest(req) && !(component?.role === "orchestrator" && component.constraints?.orchestrators?.includes(orch.id))) return error("forbidden", 403);
|
package/src/routes/hosts.ts
CHANGED
|
@@ -14,7 +14,7 @@ function queryTags(value: string | null, field: string): string[] | undefined {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
export const getHostsRoute: Handler = async (req) => {
|
|
17
|
-
const denied = authorizeRoute(req, { scope: "hosts:read" });
|
|
17
|
+
const denied = (await authorizeRoute(req, { scope: "hosts:read" }));
|
|
18
18
|
if (denied) return denied;
|
|
19
19
|
const query = new URL(req.url).searchParams;
|
|
20
20
|
try {
|
|
@@ -44,7 +44,7 @@ export const getHostsRoute: Handler = async (req) => {
|
|
|
44
44
|
* relay shows a rebuilding chart, not a stale one).
|
|
45
45
|
*/
|
|
46
46
|
export const getHostUtilizationSeries: Handler = async (req, params) => {
|
|
47
|
-
const denied = authorizeRoute(req, { scope: "hosts:read" });
|
|
47
|
+
const denied = (await authorizeRoute(req, { scope: "hosts:read" }));
|
|
48
48
|
if (denied) return denied;
|
|
49
49
|
const samples = readHostUtilizationSeries(params.id!);
|
|
50
50
|
return json({ host: params.id!, window_ms: HOST_UTILIZATION_BUFFER_MS, samples });
|
|
@@ -54,7 +54,7 @@ export const getHostUtilizationSeries: Handler = async (req, params) => {
|
|
|
54
54
|
// gateway write ops the MCP host tools already use (hosts.setLabel / hosts.setTags); this route is
|
|
55
55
|
// just the HTTP door onto them, same shape as patchAgentLabel/patchAgentTags in agents.ts.
|
|
56
56
|
export const patchHostLabel: Handler = async (req, params) => {
|
|
57
|
-
const denied = authorizeRoute(req, { scope: "hosts:write" });
|
|
57
|
+
const denied = (await authorizeRoute(req, { scope: "hosts:write" }));
|
|
58
58
|
if (denied) return denied;
|
|
59
59
|
const parsed = await parseBody<unknown>(req);
|
|
60
60
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
@@ -81,7 +81,7 @@ export const patchHostLabel: Handler = async (req, params) => {
|
|
|
81
81
|
};
|
|
82
82
|
|
|
83
83
|
export const patchHostTags: Handler = async (req, params) => {
|
|
84
|
-
const denied = authorizeRoute(req, { scope: "hosts:write" });
|
|
84
|
+
const denied = (await authorizeRoute(req, { scope: "hosts:write" }));
|
|
85
85
|
if (denied) return denied;
|
|
86
86
|
const parsed = await parseBody<unknown>(req);
|
|
87
87
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
@@ -111,7 +111,7 @@ export const patchHostTags: Handler = async (req, params) => {
|
|
|
111
111
|
// write is idempotent: an already-accepted host remains accepted and a later identity change still
|
|
112
112
|
// traverses the registration tripwire.
|
|
113
113
|
export const postAcceptHostHardware: Handler = async (req, params) => {
|
|
114
|
-
const denied = authorizeRoute(req, { scope: "hosts:write" });
|
|
114
|
+
const denied = (await authorizeRoute(req, { scope: "hosts:write" }));
|
|
115
115
|
if (denied) return denied;
|
|
116
116
|
const host = await acceptHostHardwareAsync(params.id!);
|
|
117
117
|
if (!host) return error("host not found", 404);
|
|
@@ -129,7 +129,7 @@ export const postAcceptHostHardware: Handler = async (req, params) => {
|
|
|
129
129
|
};
|
|
130
130
|
|
|
131
131
|
export const patchHostLandingPlacement: Handler = async (req, params) => {
|
|
132
|
-
const denied = authorizeRoute(req, { scope: "hosts:write" });
|
|
132
|
+
const denied = (await authorizeRoute(req, { scope: "hosts:write" }));
|
|
133
133
|
if (denied) return denied;
|
|
134
134
|
const parsed = await parseBody<unknown>(req);
|
|
135
135
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
@@ -153,7 +153,7 @@ export const patchHostLandingPlacement: Handler = async (req, params) => {
|
|
|
153
153
|
};
|
|
154
154
|
|
|
155
155
|
export const patchHostAgentCap: Handler = async (req, params) => {
|
|
156
|
-
const denied = authorizeRoute(req, { scope: "hosts:write" });
|
|
156
|
+
const denied = (await authorizeRoute(req, { scope: "hosts:write" }));
|
|
157
157
|
if (denied) return denied;
|
|
158
158
|
const parsed = await parseBody<unknown>(req);
|
|
159
159
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
@@ -177,7 +177,7 @@ export const patchHostAgentCap: Handler = async (req, params) => {
|
|
|
177
177
|
};
|
|
178
178
|
|
|
179
179
|
export const patchHostLandingCap: Handler = async (req, params) => {
|
|
180
|
-
const denied = authorizeRoute(req, { scope: "hosts:write" });
|
|
180
|
+
const denied = (await authorizeRoute(req, { scope: "hosts:write" }));
|
|
181
181
|
if (denied) return denied;
|
|
182
182
|
const parsed = await parseBody<unknown>(req);
|
|
183
183
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
@@ -201,7 +201,7 @@ export const patchHostLandingCap: Handler = async (req, params) => {
|
|
|
201
201
|
};
|
|
202
202
|
|
|
203
203
|
export const patchHostGateBudget: Handler = async (req, params) => {
|
|
204
|
-
const denied = authorizeRoute(req, { scope: "hosts:write" });
|
|
204
|
+
const denied = (await authorizeRoute(req, { scope: "hosts:write" }));
|
|
205
205
|
if (denied) return denied;
|
|
206
206
|
const parsed = await parseBody<unknown>(req);
|
|
207
207
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
@@ -217,7 +217,7 @@ export const patchHostGateBudget: Handler = async (req, params) => {
|
|
|
217
217
|
};
|
|
218
218
|
|
|
219
219
|
export const patchHostAdmission: Handler = async (req, params) => {
|
|
220
|
-
const denied = authorizeRoute(req, { scope: "hosts:write" });
|
|
220
|
+
const denied = (await authorizeRoute(req, { scope: "hosts:write" }));
|
|
221
221
|
if (denied) return denied;
|
|
222
222
|
const parsed = await parseBody<unknown>(req);
|
|
223
223
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
@@ -232,7 +232,7 @@ export const patchHostAdmission: Handler = async (req, params) => {
|
|
|
232
232
|
};
|
|
233
233
|
|
|
234
234
|
export const getHostAdmission: Handler = async (req, params) => {
|
|
235
|
-
const denied = getComponentAuth(req) ? null : authorizeRoute(req, { scope: "hosts:read" });
|
|
235
|
+
const denied = getComponentAuth(req) ? null : (await authorizeRoute(req, { scope: "hosts:read" }));
|
|
236
236
|
if (denied) return denied;
|
|
237
237
|
const host = await getHostAsync(resolveHostId(params.id!) ?? params.id!);
|
|
238
238
|
if (!host) return error("host not found", 404);
|
package/src/routes/inbox.ts
CHANGED
|
@@ -78,7 +78,8 @@ function normalizeChatHistoryImportInput(body: unknown): {
|
|
|
78
78
|
export const getInboxStateRoute: Handler = async (req) => {
|
|
79
79
|
const url = new URL(req.url);
|
|
80
80
|
const operatorId = inboxOperatorId(req, url.searchParams.get("operatorId") ?? undefined);
|
|
81
|
-
|
|
81
|
+
const raw = url.searchParams.get("excludeOffline");
|
|
82
|
+
return json(await getInboxStateAsync(operatorId, { excludeOffline: raw === "1" || raw === "true" }));
|
|
82
83
|
};
|
|
83
84
|
|
|
84
85
|
export const patchInboxThreadState: Handler = async (req) => {
|
|
@@ -140,7 +141,7 @@ export const postChatHistoryImportRoute: Handler = async (req) => {
|
|
|
140
141
|
try {
|
|
141
142
|
const input = normalizeChatHistoryImportInput(parsed.body);
|
|
142
143
|
if (resolveActingUser(req)?.source === "session") input.importedBy = requestUserAddress(req);
|
|
143
|
-
const denied = authorizeRoute(req, { scope: "agent:write", resource: { agentId: input.targetAgentId, spawnRequestId: input.targetSpawnRequestId } });
|
|
144
|
+
const denied = (await authorizeRoute(req, { scope: "agent:write", resource: { agentId: input.targetAgentId, spawnRequestId: input.targetSpawnRequestId } }));
|
|
144
145
|
if (denied) return denied;
|
|
145
146
|
const imported = await createChatHistoryImportAsync(input);
|
|
146
147
|
return json(imported, 201);
|
package/src/routes/index.ts
CHANGED
|
@@ -85,7 +85,7 @@ import { getMergeDrain, getMergePauseById, getMergePauses, postMergePause, postM
|
|
|
85
85
|
import { postMcp } from "../mcp";
|
|
86
86
|
import { postOrchestratorBootstrap, postOrchestratorBootstrapExchange } from "./orchestrator-bootstrap";
|
|
87
87
|
import { getDeploysRoute } from "./deploys";
|
|
88
|
-
import { getGateStatsRoute, getShippingBoardRoute, getShippingStatsRoute, postRedMainAbandonRoute } from "./shipping";
|
|
88
|
+
import { getGateStatsRoute, getKnownFailuresRoute, getShippingBoardRoute, getShippingStatsRoute, postRedMainAbandonRoute } from "./shipping";
|
|
89
89
|
import { getWorkflowCatalogRoute, getWorkflowDefinitionsRoute, getWorkflowRunBudgetRoute, getWorkflowRunRoute, getWorkflowRunsRoute, getWorkflowStatsRoute, patchWorkflowRunBudgetRoute, postWorkflowRunCancelRoute, postWorkflowRunPauseRoute, postWorkflowRunResumeRoute, postWorkflowRunStartRoute, postWorkflowRunUnpauseRoute } from "./workflows";
|
|
90
90
|
import { getRestartEpochRoute, postRestartEpochAbandonRoute } from "./restart-epochs";
|
|
91
91
|
import { getFleetConvergenceRoute } from "./fleet-convergence";
|
|
@@ -599,6 +599,7 @@ const routes: Route[] = [
|
|
|
599
599
|
route("POST", "/api/shipping/incidents/:id/abandon", postRedMainAbandonRoute),
|
|
600
600
|
route("GET", "/api/shipping/board", getShippingBoardRoute),
|
|
601
601
|
route("GET", "/api/shipping/stats", getShippingStatsRoute),
|
|
602
|
+
route("GET", "/api/shipping/known-failures", getKnownFailuresRoute),
|
|
602
603
|
route("GET", "/api/gates/stats", getGateStatsRoute),
|
|
603
604
|
route("GET", "/api/workflows/catalog", getWorkflowCatalogRoute),
|
|
604
605
|
route("POST", "/api/workflows/runs", postWorkflowRunStartRoute),
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { upsertIntegrationRegistryAsync, ingestIntegrationEventAsync } from "../db/runtime-tail-async";
|
|
2
|
+
import { sendMessageWithResultAsync } from "../db/message-send";
|
|
1
3
|
import type { IntegrationRegistryInput } from "../db/integrations";
|
|
2
4
|
// Auto-split from routes.ts (#299). Domain: integrations.
|
|
3
5
|
import { INTEGRATION_RATE_LIMIT_PER_MINUTE, MAX_BODY_BYTES, getIntegrationTokens, type IntegrationTokenConfig } from "../config";
|
|
4
6
|
import { VALID_ARTIFACT_KINDS, VALID_ARTIFACT_ROLES, VALID_TASK_STATUSES, agentSessionStatus, authorizeRoute, cleanAttachmentRefs, dispatchTaskCallbacksInBackground, error, json, normalizeAgentSessionGuard, parseBody, reactionEmoji, sendReactionNotificationToAuthor, validateChannelAttachmentSourceRef, withPayloadAttachments, type Handler } from "./_shared";
|
|
5
|
-
import { ValidationError, evaluatePoolBindingsAsync, findMessageByTelegramSourceAsync, getAgent, getChannelAsync, getMessage,
|
|
7
|
+
import { ValidationError, evaluatePoolBindingsAsync, findMessageByTelegramSourceAsync, getAgent, getChannelAsync, getMessage, isIntegrationRegistryEnabled, listChannelBindingsAsync, listChannelsAsync, listIntegrationTaskStatsAsync, reconcileIntegrationRegistryAsync, resolveChannelRoutesAsync, setMessageReactionAsync, upsertChannelBindingAsync, validateAgentSession } from "../db";
|
|
6
8
|
import { cleanMeta, cleanString, cleanStringArray, optionalEnum } from "../validation";
|
|
7
9
|
import { emitChannelActivity, emitMessageQueued, emitMessageReactionUpdated, emitNewMessage, emitTaskChanged } from "../sse";
|
|
8
10
|
import { getComponentAuth, getIntegrationAuth, hasIntegrationScope, isRequestAuthorizedFor } from "../security";
|
|
@@ -425,7 +427,7 @@ export const putIntegrationRegistryRoute: Handler = async (req, params) => {
|
|
|
425
427
|
const parsed = await parseBody<unknown>(req);
|
|
426
428
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
427
429
|
try {
|
|
428
|
-
return json(
|
|
430
|
+
return json((await upsertIntegrationRegistryAsync(normalizeIntegrationRegistryInput(name, parsed.body))));
|
|
429
431
|
} catch (e) {
|
|
430
432
|
if (e instanceof ValidationError) return error(e.message, 400);
|
|
431
433
|
throw e;
|
|
@@ -497,7 +499,7 @@ async function applyInboundChannelReaction(payload: Record<string, unknown>): Pr
|
|
|
497
499
|
const result = await setMessageReactionAsync({ messageId: parent.id, actorId, emoji, action });
|
|
498
500
|
if (result.ok) {
|
|
499
501
|
emitMessageReactionUpdated(result.message);
|
|
500
|
-
sendReactionNotificationToAuthor(result.message, actorId, emoji, action);
|
|
502
|
+
(await sendReactionNotificationToAuthor(result.message, actorId, emoji, action));
|
|
501
503
|
}
|
|
502
504
|
}
|
|
503
505
|
|
|
@@ -509,7 +511,7 @@ export const postChannelEvent: Handler = async (req, params) => {
|
|
|
509
511
|
if (!channel) return error("channel not found", 404);
|
|
510
512
|
const sessionError = requireChannelSession(req, parsed.body, channel);
|
|
511
513
|
if (sessionError) return sessionError;
|
|
512
|
-
const denied = authorizeRoute(req, { scope: "channel:write", resource: { channel: channel.id } });
|
|
514
|
+
const denied = (await authorizeRoute(req, { scope: "channel:write", resource: { channel: channel.id } }));
|
|
513
515
|
if (denied) return denied;
|
|
514
516
|
const input = normalizeChannelEventBody(parsed.body);
|
|
515
517
|
validateChannelEnvelope(input.payload, channel);
|
|
@@ -521,7 +523,7 @@ export const postChannelEvent: Handler = async (req, params) => {
|
|
|
521
523
|
await applyInboundChannelReaction(input.payload);
|
|
522
524
|
const bindings = await resolveChannelRoutesAsync(channel.id, input.conversationId);
|
|
523
525
|
if (!bindings.length) return error("channel has no binding", 409);
|
|
524
|
-
const results = bindings.map((binding) =>
|
|
526
|
+
const results = await Promise.all(bindings.map(async (binding) => (await sendMessageWithResultAsync({
|
|
525
527
|
from: channel.agentId,
|
|
526
528
|
to: messageTargetForChannelTarget(binding.target, binding),
|
|
527
529
|
kind: "channel.event",
|
|
@@ -530,7 +532,7 @@ export const postChannelEvent: Handler = async (req, params) => {
|
|
|
530
532
|
payload: input.payload,
|
|
531
533
|
idempotencyKey: scopedChannelIdempotencyKey(input.idempotencyKey, binding),
|
|
532
534
|
claimable: false,
|
|
533
|
-
}));
|
|
535
|
+
}))));
|
|
534
536
|
for (const result of results) {
|
|
535
537
|
if (!result.created) continue;
|
|
536
538
|
if (result.message.deliveryStatus === "queued") emitMessageQueued(result.message);
|
|
@@ -598,7 +600,7 @@ export const postIntegrationEvent: Handler = async (req) => {
|
|
|
598
600
|
return error("integration token cannot target this task", 403);
|
|
599
601
|
}
|
|
600
602
|
const input = await resolveIntegrationEventTarget({ ...normalized, source: normalized.source ?? integrationName });
|
|
601
|
-
const result =
|
|
603
|
+
const result = (await ingestIntegrationEventAsync(input, integrationName));
|
|
602
604
|
if (result.message) emitNewMessage(result.message);
|
|
603
605
|
emitTaskChanged(result.task, result.created ? "task.created" : "task.updated");
|
|
604
606
|
dispatchTaskCallbacksInBackground(result.task.id, result.created ? "task.created" : "task.updated");
|
|
@@ -31,7 +31,7 @@ export const postIssueActivityRoute: Handler = async (req) => {
|
|
|
31
31
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
32
32
|
try {
|
|
33
33
|
if (!isRecord(parsed.body)) throw new ValidationError("issue activity body required");
|
|
34
|
-
const event = recordAndEmitIssueActivity({
|
|
34
|
+
const event = (await recordAndEmitIssueActivity({
|
|
35
35
|
agentId: cleanString(parsed.body.agentId, "agentId", { required: true, max: 200 })!,
|
|
36
36
|
action: cleanAction(parsed.body.action),
|
|
37
37
|
issueRefId: cleanString(parsed.body.issueRefId, "issueRefId", { max: 120 }),
|
|
@@ -42,7 +42,7 @@ export const postIssueActivityRoute: Handler = async (req) => {
|
|
|
42
42
|
title: cleanString(parsed.body.title, "title", { max: 200 }),
|
|
43
43
|
body: cleanString(parsed.body.body, "body", { max: 1000 }),
|
|
44
44
|
metadata: cleanMeta(parsed.body.metadata),
|
|
45
|
-
});
|
|
45
|
+
}));
|
|
46
46
|
return json({ event }, 201);
|
|
47
47
|
} catch (err) {
|
|
48
48
|
if (err instanceof ValidationError) return error(err.message, 400);
|
|
@@ -37,7 +37,7 @@ export const postIssueAssociationRoute: Handler = async (req) => {
|
|
|
37
37
|
const parsed = await parseBody<unknown>(req);
|
|
38
38
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
39
39
|
try {
|
|
40
|
-
return json(associateIssueRef(cleanAssociationBody(parsed.body)));
|
|
40
|
+
return json((await associateIssueRef(cleanAssociationBody(parsed.body))));
|
|
41
41
|
} catch (err) {
|
|
42
42
|
return routeError(err);
|
|
43
43
|
}
|
|
@@ -56,9 +56,9 @@ export const getIssueAssociationEntityIssuesRoute: Handler = (_req, params) => {
|
|
|
56
56
|
}
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
-
export const getIssueAssociationIssueEntitiesRoute: Handler = (_req, params) => {
|
|
59
|
+
export const getIssueAssociationIssueEntitiesRoute: Handler = async (_req, params) => {
|
|
60
60
|
try {
|
|
61
|
-
const issueRef = resolveAssociationIssueRef({ issueRefId: cleanString(params.issueRefId, "issueRefId", { required: true, max: 120 })! });
|
|
61
|
+
const issueRef = (await resolveAssociationIssueRef({ issueRefId: cleanString(params.issueRefId, "issueRefId", { required: true, max: 120 })! }));
|
|
62
62
|
return json({ issueRef, entities: listIssueEntities(issueRef.id) });
|
|
63
63
|
} catch (err) {
|
|
64
64
|
return routeError(err);
|
|
@@ -69,7 +69,7 @@ export const deleteIssueAssociationRoute: Handler = async (req) => {
|
|
|
69
69
|
const parsed = await parseBody<unknown>(req);
|
|
70
70
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
71
71
|
try {
|
|
72
|
-
return json(removeIssueAssociation(cleanAssociationBody(parsed.body)));
|
|
72
|
+
return json((await removeIssueAssociation(cleanAssociationBody(parsed.body))));
|
|
73
73
|
} catch (err) {
|
|
74
74
|
return routeError(err);
|
|
75
75
|
}
|
package/src/routes/issue-refs.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { deleteIssueRefMappingAsync, getIssueRef,
|
|
1
|
+
import { deleteIssueRefMappingAsync, getIssueRef, listIssueRefsAsync, patchIssueRefMappingAsync, resolveIssueRefMappingAsync, upsertIssueRefMappingAsync, type ListIssueRefsOptions } from "../services/issue-refs";
|
|
2
2
|
import { getIssueRefByExternalKey, issueRefClosedCompleted, issueRefForRefString } from "../db/issue-refs";
|
|
3
3
|
import { advanceTerminalPlanRefsAsync } from "../services/plan-terminal-refs";
|
|
4
4
|
import { cleanEnum, cleanString, optionalEnum } from "../validation";
|
|
@@ -53,7 +53,7 @@ function cleanResolveBody(body: unknown) {
|
|
|
53
53
|
return body;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
export const listIssueRefsRoute: Handler = (req) => {
|
|
56
|
+
export const listIssueRefsRoute: Handler = async (req) => {
|
|
57
57
|
try {
|
|
58
58
|
const url = new URL(req.url);
|
|
59
59
|
const rawLimit = parseQueryInt(url.searchParams.get("limit"), { min: 1, max: 500, clamp: true });
|
|
@@ -64,7 +64,7 @@ export const listIssueRefsRoute: Handler = (req) => {
|
|
|
64
64
|
status: optionalEnum(url.searchParams.get("status") ?? undefined, "status", ISSUE_REF_STATUSES) as IssueRefStatus | undefined,
|
|
65
65
|
limit: rawLimit ?? undefined,
|
|
66
66
|
};
|
|
67
|
-
return json({ issueRefs:
|
|
67
|
+
return json({ issueRefs: await listIssueRefsAsync(opts) });
|
|
68
68
|
} catch (err) {
|
|
69
69
|
return error(err instanceof Error ? err.message : "issue refs route failed");
|
|
70
70
|
}
|
|
@@ -22,7 +22,7 @@ export const postTimerMessageOperator: Handler = async (req, params) => {
|
|
|
22
22
|
// Unlike routine routes in allow-unauth development mode, the migration trigger always requires
|
|
23
23
|
// an actual credential. This keeps "authenticated" a property of the action, not deployment mode.
|
|
24
24
|
if (!hasPresentedCredential(req)) return error("authentication required", 401);
|
|
25
|
-
const denied = authorizeRoute(req, { scope: "system:admin" });
|
|
25
|
+
const denied = (await authorizeRoute(req, { scope: "system:admin" }));
|
|
26
26
|
if (denied) return denied;
|
|
27
27
|
const actor = resolveActorLabel(req);
|
|
28
28
|
if (!actor) return error("authenticated operator identity required", 403);
|
package/src/routes/memory.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { authorizeRoute, error, json, parseBody, type Handler } from "./_shared"
|
|
|
7
7
|
// that area's memories (src/memory-area-injection.ts).
|
|
8
8
|
export const postAgentAreaEntered: Handler = async (req, params) => {
|
|
9
9
|
const agentId = params.id!;
|
|
10
|
-
const denied = authorizeRoute(req, { scope: "agent:write", resource: { agentId } });
|
|
10
|
+
const denied = (await authorizeRoute(req, { scope: "agent:write", resource: { agentId } }));
|
|
11
11
|
if (denied) return denied;
|
|
12
12
|
const ctx = authContextFromRequest(req);
|
|
13
13
|
if (ctx.actor.kind !== "system" && ctx.callerAgentId !== agentId) return error("forbidden: only the agent's own runner may report its area touches", 403);
|
package/src/routes/merges.ts
CHANGED
|
@@ -22,8 +22,8 @@ function actorFromRequest(req: Request): string {
|
|
|
22
22
|
: "root";
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
export const getMergePauses: Handler = (req) => {
|
|
26
|
-
const denied = authorizeRoute(req, { scope: "command:read" });
|
|
25
|
+
export const getMergePauses: Handler = async (req) => {
|
|
26
|
+
const denied = (await authorizeRoute(req, { scope: "command:read" }));
|
|
27
27
|
if (denied) return denied;
|
|
28
28
|
return json({ pauses: listAutoMergePauses() });
|
|
29
29
|
};
|
|
@@ -37,13 +37,13 @@ export const getMergePauses: Handler = (req) => {
|
|
|
37
37
|
* indefinitely, and #2094's fast reclaim covers whatever the interlock misses.
|
|
38
38
|
*/
|
|
39
39
|
export const getMergeDrain: Handler = async (req) => {
|
|
40
|
-
const denied = authorizeRoute(req, { scope: "command:read" });
|
|
40
|
+
const denied = (await authorizeRoute(req, { scope: "command:read" }));
|
|
41
41
|
if (denied) return denied;
|
|
42
42
|
return json(await workspaceMergeDrainStatusAsync());
|
|
43
43
|
};
|
|
44
44
|
|
|
45
45
|
export const postMergePause: Handler = async (req) => {
|
|
46
|
-
const denied = authorizeRoute(req, { scope: "command:write" });
|
|
46
|
+
const denied = (await authorizeRoute(req, { scope: "command:write" }));
|
|
47
47
|
if (denied) return denied;
|
|
48
48
|
const parsed = await parseBody<unknown>(req);
|
|
49
49
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
@@ -54,7 +54,7 @@ export const postMergePause: Handler = async (req) => {
|
|
|
54
54
|
const holder = cleanString(parsed.body.holder, "holder", { max: 240 }) ?? actorFromRequest(req);
|
|
55
55
|
const reason = cleanString(parsed.body.reason, "reason", { max: 500 });
|
|
56
56
|
const ttlMs = cleanTtlMs(parsed.body.ttlMs);
|
|
57
|
-
const result = pauseAutoMerge({ repoRoot, baseRef, holder, reason, ttlMs });
|
|
57
|
+
const result = (await pauseAutoMerge({ repoRoot, baseRef, holder, reason, ttlMs }));
|
|
58
58
|
if (!result.ok) {
|
|
59
59
|
return json({ error: "merge target already paused", pause: result.pause }, 409);
|
|
60
60
|
}
|
|
@@ -66,7 +66,7 @@ export const postMergePause: Handler = async (req) => {
|
|
|
66
66
|
};
|
|
67
67
|
|
|
68
68
|
export const postMergePauseRenew: Handler = async (req) => {
|
|
69
|
-
const denied = authorizeRoute(req, { scope: "command:write" });
|
|
69
|
+
const denied = (await authorizeRoute(req, { scope: "command:write" }));
|
|
70
70
|
if (denied) return denied;
|
|
71
71
|
const parsed = await parseBody<unknown>(req);
|
|
72
72
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
@@ -74,7 +74,7 @@ export const postMergePauseRenew: Handler = async (req) => {
|
|
|
74
74
|
if (!isRecord(parsed.body)) return error("body required");
|
|
75
75
|
const id = cleanString(parsed.body.id, "id", { required: true, max: 120 })!;
|
|
76
76
|
const ttlMs = cleanTtlMs(parsed.body.ttlMs);
|
|
77
|
-
const pause = renewAutoMergePause(id, ttlMs);
|
|
77
|
+
const pause = (await renewAutoMergePause(id, ttlMs));
|
|
78
78
|
return pause ? json({ pause }) : error("merge pause not found or expired", 404);
|
|
79
79
|
} catch (e) {
|
|
80
80
|
if (e instanceof ValidationError) return error(e.message, 400);
|
|
@@ -83,7 +83,7 @@ export const postMergePauseRenew: Handler = async (req) => {
|
|
|
83
83
|
};
|
|
84
84
|
|
|
85
85
|
export const postMergePauseResume: Handler = async (req) => {
|
|
86
|
-
const denied = authorizeRoute(req, { scope: "command:write" });
|
|
86
|
+
const denied = (await authorizeRoute(req, { scope: "command:write" }));
|
|
87
87
|
if (denied) return denied;
|
|
88
88
|
const parsed = await parseBody<unknown>(req);
|
|
89
89
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
@@ -93,7 +93,7 @@ export const postMergePauseResume: Handler = async (req) => {
|
|
|
93
93
|
const repoRoot = cleanString(parsed.body.repoRoot, "repoRoot", { max: 1000 });
|
|
94
94
|
const baseRef = cleanString(parsed.body.baseRef, "baseRef", { max: 240 });
|
|
95
95
|
if (!id && !repoRoot) return error("id or repoRoot required", 400);
|
|
96
|
-
const released = resumeAutoMerge(id ? { id } : { repoRoot: repoRoot!, baseRef: baseRef ?? "main" });
|
|
96
|
+
const released = (await resumeAutoMerge(id ? { id } : { repoRoot: repoRoot!, baseRef: baseRef ?? "main" }));
|
|
97
97
|
return json({ released });
|
|
98
98
|
} catch (e) {
|
|
99
99
|
if (e instanceof ValidationError) return error(e.message, 400);
|
|
@@ -101,8 +101,8 @@ export const postMergePauseResume: Handler = async (req) => {
|
|
|
101
101
|
}
|
|
102
102
|
};
|
|
103
103
|
|
|
104
|
-
export const getMergePauseById: Handler = (req, params) => {
|
|
105
|
-
const denied = authorizeRoute(req, { scope: "command:read" });
|
|
104
|
+
export const getMergePauseById: Handler = async (req, params) => {
|
|
105
|
+
const denied = (await authorizeRoute(req, { scope: "command:read" }));
|
|
106
106
|
if (denied) return denied;
|
|
107
107
|
const pause = getAutoMergePause(params.id!);
|
|
108
108
|
return pause ? json(pause) : error("merge pause not found", 404);
|