@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
|
@@ -45,7 +45,7 @@ function cleanUnavailableWindows(value: unknown): ProviderQuotaWindowIdentity[]
|
|
|
45
45
|
return windows;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
function cleanProviderQuotaUpdate(body: unknown): ProviderQuotaUpdateInput | string {
|
|
48
|
+
export function cleanProviderQuotaUpdate(body: unknown): ProviderQuotaUpdateInput | string {
|
|
49
49
|
if (!isRecord(body)) return "JSON object body required";
|
|
50
50
|
const provider = cleanString(body.provider, "provider", { required: true, max: 80 })!;
|
|
51
51
|
const accountKey = cleanString(body.accountKey, "accountKey", { required: true, max: 240 })!;
|
|
@@ -122,7 +122,7 @@ export const postProviderQuotaRoute: Handler = async (req) => {
|
|
|
122
122
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
123
123
|
const input = cleanProviderQuotaUpdate(parsed.body);
|
|
124
124
|
if (typeof input === "string") return error(input);
|
|
125
|
-
const providerWriteGate = authorizeProviderQuotaWrite(req, input);
|
|
125
|
+
const providerWriteGate = (await authorizeProviderQuotaWrite(req, input));
|
|
126
126
|
if (providerWriteGate) return providerWriteGate;
|
|
127
127
|
if ((VALID_QUOTA_CONFIG_PROVIDERS as readonly string[]).includes(input.provider) && getProviderQuotaConfig(input.provider).enabled === false) return json({ skipped: true, reason: "provider quota collection disabled" }, 202);
|
|
128
128
|
const providerContext = authContextFromRequest(req);
|
|
@@ -218,19 +218,19 @@ function cleanPublisherLeaseBody(body: unknown): {
|
|
|
218
218
|
|
|
219
219
|
const runnerLeaseHolderId = (sourceAgentId: string) => `runner:${sourceAgentId}`;
|
|
220
220
|
|
|
221
|
-
function authorizeProviderQuotaSourceAgent(req: Request, sourceAgentId: string): Response | null {
|
|
221
|
+
async function authorizeProviderQuotaSourceAgent(req: Request, sourceAgentId: string): Promise<Response | null> {
|
|
222
222
|
const ctx = authContextFromRequest(req);
|
|
223
223
|
if (ctx.component?.role !== "provider") return null;
|
|
224
|
-
const denied = authorizeRoute(req, { scope: "quota:write" });
|
|
224
|
+
const denied = (await authorizeRoute(req, { scope: "quota:write" }));
|
|
225
225
|
if (denied) return denied;
|
|
226
226
|
return ctx.callerAgentId === sourceAgentId ? null : error("forbidden", 403);
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
-
function authorizeProviderQuotaWrite(req: Request, input: ProviderQuotaUpdateInput): Response | null {
|
|
229
|
+
export async function authorizeProviderQuotaWrite(req: Request, input: ProviderQuotaUpdateInput): Promise<Response | null> {
|
|
230
230
|
const ctx = authContextFromRequest(req);
|
|
231
231
|
if (ctx.component?.role !== "provider") return null;
|
|
232
232
|
if (!input.sourceAgentId) return error("sourceAgentId required for provider quota writer", 403);
|
|
233
|
-
const denied = authorizeProviderQuotaSourceAgent(req, input.sourceAgentId);
|
|
233
|
+
const denied = (await authorizeProviderQuotaSourceAgent(req, input.sourceAgentId));
|
|
234
234
|
if (denied) return denied;
|
|
235
235
|
// The authority fence is deliberately folded into providerQuotas.upsert. A pre-read here would
|
|
236
236
|
// race lease transfer while the async writer is queued.
|
|
@@ -242,7 +242,7 @@ export const postProviderQuotaPublisherLeaseAcquireRoute: Handler = async (req)
|
|
|
242
242
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
243
243
|
const input = cleanPublisherLeaseBody(parsed.body);
|
|
244
244
|
if (typeof input === "string") return error(input);
|
|
245
|
-
const denied = authorizeProviderQuotaSourceAgent(req, input.sourceAgentId);
|
|
245
|
+
const denied = (await authorizeProviderQuotaSourceAgent(req, input.sourceAgentId));
|
|
246
246
|
if (denied) return denied;
|
|
247
247
|
return json(await acquireProviderQuotaLeaseAsync({
|
|
248
248
|
provider: input.provider,
|
|
@@ -260,7 +260,7 @@ export const postProviderQuotaPublisherLeaseReleaseRoute: Handler = async (req)
|
|
|
260
260
|
const input = cleanPublisherLeaseBody(parsed.body);
|
|
261
261
|
if (typeof input === "string") return error(input);
|
|
262
262
|
if (!input.leaseToken) return error("leaseToken required");
|
|
263
|
-
const denied = authorizeProviderQuotaSourceAgent(req, input.sourceAgentId);
|
|
263
|
+
const denied = (await authorizeProviderQuotaSourceAgent(req, input.sourceAgentId));
|
|
264
264
|
if (denied) return denied;
|
|
265
265
|
return json({
|
|
266
266
|
released: await releaseProviderQuotaLeaseAsync({
|
|
@@ -275,7 +275,7 @@ export const postProviderQuotaPublisherLeaseReleaseRoute: Handler = async (req)
|
|
|
275
275
|
export const postProviderQuotaLeaseAcquireRoute: Handler = async (req, params) => {
|
|
276
276
|
const orch = getOrchestrator(params.id!);
|
|
277
277
|
if (!orch) return error("orchestrator not found", 404);
|
|
278
|
-
const denied = authorizeRoute(req, { scope: "command:write", resource: { orchestratorId: orch.id } });
|
|
278
|
+
const denied = (await authorizeRoute(req, { scope: "command:write", resource: { orchestratorId: orch.id } }));
|
|
279
279
|
if (denied) return denied;
|
|
280
280
|
const parsed = await parseBody<unknown>(req);
|
|
281
281
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
@@ -294,7 +294,7 @@ export const postProviderQuotaLeaseAcquireRoute: Handler = async (req, params) =
|
|
|
294
294
|
export const postProviderQuotaLeaseReleaseRoute: Handler = async (req, params) => {
|
|
295
295
|
const orch = getOrchestrator(params.id!);
|
|
296
296
|
if (!orch) return error("orchestrator not found", 404);
|
|
297
|
-
const denied = authorizeRoute(req, { scope: "command:write", resource: { orchestratorId: orch.id } });
|
|
297
|
+
const denied = (await authorizeRoute(req, { scope: "command:write", resource: { orchestratorId: orch.id } }));
|
|
298
298
|
if (denied) return denied;
|
|
299
299
|
const parsed = await parseBody<unknown>(req);
|
|
300
300
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
@@ -10,7 +10,7 @@ import { authorizeRoute, error, json, parseBody, type Handler } from "./_shared"
|
|
|
10
10
|
export const postRunCommand: Handler = async (req) => {
|
|
11
11
|
// Require authentication even when the server permits credential-less development requests.
|
|
12
12
|
if (!hasPresentedCredential(req) || !isAuthorized(req)) return error("authentication required", 401);
|
|
13
|
-
const denied = authorizeRoute(req, { scope: "command:write" });
|
|
13
|
+
const denied = (await authorizeRoute(req, { scope: "command:write" }));
|
|
14
14
|
if (denied) return denied;
|
|
15
15
|
const parsed = await parseBody<unknown>(req);
|
|
16
16
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
@@ -20,7 +20,7 @@ function backupError(cause: unknown): Response {
|
|
|
20
20
|
/** Backup and restore move every secret at once: the operator only, never a secrets-scoped agent. */
|
|
21
21
|
function operatorRoute(handle: (body: Record<string, unknown>, actor: string) => Promise<Response>): Handler {
|
|
22
22
|
return async req => {
|
|
23
|
-
const denied = authorizeRoute(req, { scope: "secrets:write" });
|
|
23
|
+
const denied = (await authorizeRoute(req, { scope: "secrets:write" }));
|
|
24
24
|
if (denied) return denied;
|
|
25
25
|
if (!isRootCredentialRequest(req) && getComponentAuth(req)?.role !== "dashboard") return error("operator token required for vault backup and restore", 403);
|
|
26
26
|
let body: unknown = {};
|
|
@@ -37,7 +37,7 @@ function operatorRoute(handle: (body: Record<string, unknown>, actor: string) =>
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export const getVaultBackupRoute: Handler = async req => {
|
|
40
|
-
const denied = authorizeRoute(req, { scope: "secrets:write" });
|
|
40
|
+
const denied = (await authorizeRoute(req, { scope: "secrets:write" }));
|
|
41
41
|
if (denied) return denied;
|
|
42
42
|
try { return json(await vaultBackupStatus()); } catch (cause) { return backupError(cause); }
|
|
43
43
|
};
|
|
@@ -9,7 +9,7 @@ import { authorizeRoute, error, isRootCredentialRequest, json, parseBody, type H
|
|
|
9
9
|
|
|
10
10
|
function importRoute(preview: boolean): Handler {
|
|
11
11
|
return async req => {
|
|
12
|
-
const denied = authorizeRoute(req, { scope: "secrets:write" });
|
|
12
|
+
const denied = (await authorizeRoute(req, { scope: "secrets:write" }));
|
|
13
13
|
if (denied) return denied;
|
|
14
14
|
// Import is the operator's batch approval; a secrets-scoped agent may not approve its own migration.
|
|
15
15
|
if (!isRootCredentialRequest(req) && getComponentAuth(req)?.role !== "dashboard") return error("operator token required to import secrets", 403);
|
|
@@ -13,7 +13,7 @@ import { resolveHostProviderEnv } from "../secrets-vault/provider-env";
|
|
|
13
13
|
import { isOrchestratorSelfReportAuthorized } from "../orchestrator-self-report-authz";
|
|
14
14
|
|
|
15
15
|
export const getVaultMetadataRoute: Handler = async (req) => {
|
|
16
|
-
const denied = authorizeRoute(req, { scope: "secrets:write" });
|
|
16
|
+
const denied = (await authorizeRoute(req, { scope: "secrets:write" }));
|
|
17
17
|
if (denied) return denied;
|
|
18
18
|
// health() opens a row, so a missing or wrong key answers 503 here instead of listing names that nothing can resolve.
|
|
19
19
|
try {
|
|
@@ -49,7 +49,7 @@ function vaultWriteError(cause: unknown): Response {
|
|
|
49
49
|
|
|
50
50
|
/** The operator creates a new secret straight from the dashboard; the value is never echoed or logged. */
|
|
51
51
|
export const postVaultSecretRoute: Handler = async (req) => {
|
|
52
|
-
const denied = authorizeRoute(req, { scope: "secrets:write" });
|
|
52
|
+
const denied = (await authorizeRoute(req, { scope: "secrets:write" }));
|
|
53
53
|
if (denied) return denied;
|
|
54
54
|
const parsed = await parseBody<unknown>(req);
|
|
55
55
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
@@ -60,7 +60,7 @@ export const postVaultSecretRoute: Handler = async (req) => {
|
|
|
60
60
|
|
|
61
61
|
/** #3558 — the operator sets a new version of an existing secret (`:name` is `NAME` or `project:<id>:NAME`). */
|
|
62
62
|
export const putVaultSecretRoute: Handler = async (req, params) => {
|
|
63
|
-
const denied = authorizeRoute(req, { scope: "secrets:write" });
|
|
63
|
+
const denied = (await authorizeRoute(req, { scope: "secrets:write" }));
|
|
64
64
|
if (denied) return denied;
|
|
65
65
|
const parsed = await parseBody<unknown>(req);
|
|
66
66
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
@@ -72,7 +72,7 @@ export const putVaultSecretRoute: Handler = async (req, params) => {
|
|
|
72
72
|
|
|
73
73
|
/** #3554 — the operator deletes every version of one secret. */
|
|
74
74
|
export const deleteVaultSecretRoute: Handler = async (req, params) => {
|
|
75
|
-
const denied = authorizeRoute(req, { scope: "secrets:write" });
|
|
75
|
+
const denied = (await authorizeRoute(req, { scope: "secrets:write" }));
|
|
76
76
|
if (denied) return denied;
|
|
77
77
|
try { return json(await deleteOperatorSecret(operatorActor(req), params.name!, new URL(req.url).searchParams.get("environment") ?? undefined)); }
|
|
78
78
|
catch (cause) { return vaultWriteError(cause); }
|
|
@@ -91,7 +91,7 @@ export const getVaultAuditRoute: Handler = async (req, params) => {
|
|
|
91
91
|
export const getOrchestratorProviderEnvRoute: Handler = async (req, params) => {
|
|
92
92
|
const orch = getOrchestrator(params.id!);
|
|
93
93
|
if (!orch) return error("orchestrator not found", 404);
|
|
94
|
-
const denied = authorizeRoute(req, { scope: "command:write", resource: { orchestratorId: orch.id } });
|
|
94
|
+
const denied = (await authorizeRoute(req, { scope: "command:write", resource: { orchestratorId: orch.id } }));
|
|
95
95
|
if (denied) return denied;
|
|
96
96
|
// Plaintext keys: only this orchestrator's own host credential (or admin), never a runner token with command:write.
|
|
97
97
|
if (!isOrchestratorSelfReportAuthorized(req, orch.id)) return error("forbidden", 403);
|
|
@@ -105,14 +105,14 @@ export const getOrchestratorProviderEnvRoute: Handler = async (req, params) => {
|
|
|
105
105
|
};
|
|
106
106
|
|
|
107
107
|
export const getVaultSecretRoute: Handler = async (req, params) => {
|
|
108
|
-
const denied = authorizeRoute(req, { scope: "secrets:write" });
|
|
108
|
+
const denied = (await authorizeRoute(req, { scope: "secrets:write" }));
|
|
109
109
|
if (denied) return denied;
|
|
110
110
|
try { return json(await getSecretMetadata(params.name!, new URL(req.url).searchParams.get("environment") ?? undefined)); }
|
|
111
111
|
catch (cause) { return vaultWriteError(cause); }
|
|
112
112
|
};
|
|
113
113
|
|
|
114
114
|
export const patchVaultMetadataRoute: Handler = async (req, params) => {
|
|
115
|
-
const denied = authorizeRoute(req, { scope: "secrets:write" });
|
|
115
|
+
const denied = (await authorizeRoute(req, { scope: "secrets:write" }));
|
|
116
116
|
if (denied) return denied;
|
|
117
117
|
const parsed = await parseBody<unknown>(req);
|
|
118
118
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
package/src/routes/settings.ts
CHANGED
|
@@ -70,7 +70,7 @@ export async function setRegisteredSettingValue(namespace: string, key: string,
|
|
|
70
70
|
const validation = validateSettingValue(namespace, key, merged);
|
|
71
71
|
if (!validation.valid) throw new ValidationError(validation.errors.join("; "));
|
|
72
72
|
if (descriptor.tier === "user") return setUserSettingAsync(DEFAULT_USER_ID, namespace, key, merged, updatedBy);
|
|
73
|
-
return setConfigAsync(namespace, key, merged, updatedBy);
|
|
73
|
+
return (await setConfigAsync(namespace, key, merged, updatedBy));
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
async function putSetting(req: Request, namespaceRaw: string | undefined, keyRaw: string | undefined): Promise<Response> {
|
package/src/routes/shipping.ts
CHANGED
|
@@ -5,12 +5,13 @@ import { readGateStatsAsync, resolveProjectAsync } from "../db";
|
|
|
5
5
|
import { getShippingBoard } from "../services/shipping-board";
|
|
6
6
|
import { getShippingStats } from "../services/shipping-stats";
|
|
7
7
|
import { abandonRedMainIncident } from "../services/red-main-incident";
|
|
8
|
+
import { baseKnownFailures } from "../db/land-boundaries";
|
|
8
9
|
import { OpError } from "@humwick/kernel/contract";
|
|
9
10
|
import { cleanString } from "../validation";
|
|
10
11
|
import { authorizeRoute, error, json, parseBody, resolveActorLabel, type Handler } from "./_shared";
|
|
11
12
|
|
|
12
13
|
export const postRedMainAbandonRoute: Handler = async (req, params) => {
|
|
13
|
-
const denied = authorizeRoute(req, { scope: "command:write" });
|
|
14
|
+
const denied = (await authorizeRoute(req, { scope: "command:write" }));
|
|
14
15
|
if (denied) return denied;
|
|
15
16
|
const parsed = await parseBody<{ reason?: unknown }>(req);
|
|
16
17
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
@@ -23,6 +24,13 @@ export const postRedMainAbandonRoute: Handler = async (req, params) => {
|
|
|
23
24
|
}
|
|
24
25
|
};
|
|
25
26
|
|
|
27
|
+
// #3362 §11: what a builder's delivery gate holds out of unrelated runs. agent:read, so every agent token reads it.
|
|
28
|
+
export const getKnownFailuresRoute: Handler = async (req) => {
|
|
29
|
+
const remote = new URL(req.url).searchParams.get("remote")?.trim();
|
|
30
|
+
if (!remote || !/^[\w.-]+\/[\w.-]+$/.test(remote)) return error("remote must be owner/repo", 400);
|
|
31
|
+
return json({ failures: baseKnownFailures(remote) });
|
|
32
|
+
};
|
|
33
|
+
|
|
26
34
|
/** A `projectId` query names a project by id or slug; absent means all projects. */
|
|
27
35
|
async function projectFilter(req: Request): Promise<{ projectId?: string } | Response> {
|
|
28
36
|
const ref = new URL(req.url).searchParams.get("projectId")?.trim();
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { upsertManagedAgentStateAsync } from "../db/lifecycle-tail-async";
|
|
1
2
|
// Auto-split from routes.ts (#299). Domain: spawn-policy.
|
|
2
3
|
import { ValidationError, getCrashReport, getManagedPolicyTimelineAsync, getOrchestrator } from "../db";
|
|
3
4
|
import { auditEvent, authAuditMetadata, dashboardAttribution, emitCommand, error, json, parseBody, parseQueryInt, spawnRequestId, type Handler } from "./_shared";
|
|
@@ -6,7 +7,7 @@ import { SYSTEM_LAUNCH } from "../runtime-tokens";
|
|
|
6
7
|
import { cleanString } from "../validation";
|
|
7
8
|
import { hostSpawnsDrained } from "../db/spawn-host-cap";
|
|
8
9
|
import { createCommandAsync } from "../commands-write";
|
|
9
|
-
import { getManagedAgentState, getSpawnPolicy, listSpawnPolicies
|
|
10
|
+
import { getManagedAgentState, getSpawnPolicy, listSpawnPolicies } from "../config-store";
|
|
10
11
|
import { deleteConfigAsync, setConfigAsync } from "../config-store-write";
|
|
11
12
|
import { managedSpawnReservationCurrent, restoreDrainedSpawnReservation } from "../managed-spawn-reservation";
|
|
12
13
|
import { emitConfigChanged, emitManagedAgentStateChanged } from "../sse";
|
|
@@ -72,7 +73,7 @@ async function enqueuePolicyStart(policy: SpawnPolicy, reason: string): Promise<
|
|
|
72
73
|
if (stewardDeny) return error(`steward spawn refused: ${stewardDeny}`, 409);
|
|
73
74
|
const requestId = spawnRequestId();
|
|
74
75
|
const existing = getManagedAgentState(policy.name);
|
|
75
|
-
const state =
|
|
76
|
+
const state = (await upsertManagedAgentStateAsync({
|
|
76
77
|
policyName: policy.name,
|
|
77
78
|
status: "starting",
|
|
78
79
|
orchestratorId: policy.orchestratorId,
|
|
@@ -82,7 +83,7 @@ async function enqueuePolicyStart(policy: SpawnPolicy, reason: string): Promise<
|
|
|
82
83
|
// An operator start deliberately retries a failed policy after correcting its launch.
|
|
83
84
|
restartCount: existing?.restartCount ?? 0,
|
|
84
85
|
consecutiveFailures: 0,
|
|
85
|
-
});
|
|
86
|
+
}));
|
|
86
87
|
emitManagedAgentStateChanged(policy.name, state as unknown as Record<string, unknown>);
|
|
87
88
|
const policySnapshot = JSON.stringify(policy);
|
|
88
89
|
const spawnParams = await buildManagedSpawnParamsAsync(policy, requestId, { createdBy: "managed-agent", authority: SYSTEM_LAUNCH });
|
|
@@ -93,7 +94,7 @@ async function enqueuePolicyStart(policy: SpawnPolicy, reason: string): Promise<
|
|
|
93
94
|
return error("managed policy start was superseded", 409);
|
|
94
95
|
}
|
|
95
96
|
if (hostSpawnsDrained(orch.agentId)) {
|
|
96
|
-
restoreDrainedSpawnReservation(policy, requestId, existing);
|
|
97
|
+
(await restoreDrainedSpawnReservation(policy, requestId, existing));
|
|
97
98
|
return error(`host ${orch.hostname} is draining: new spawns disabled`, 409);
|
|
98
99
|
}
|
|
99
100
|
const command = await createCommandAsync({
|
|
@@ -131,7 +132,7 @@ async function enqueuePolicyStop(policy: SpawnPolicy, action: "shutdown" | "rest
|
|
|
131
132
|
})
|
|
132
133
|
: undefined;
|
|
133
134
|
if (action === "restart" && hostSpawnsDrained(orch.agentId)) return error(`host ${orch.hostname} is draining: new spawns disabled`, 409);
|
|
134
|
-
const nextState =
|
|
135
|
+
const nextState = (await upsertManagedAgentStateAsync({
|
|
135
136
|
policyName: policy.name,
|
|
136
137
|
status: "stopping",
|
|
137
138
|
agentId: state?.agentId,
|
|
@@ -143,7 +144,7 @@ async function enqueuePolicyStop(policy: SpawnPolicy, action: "shutdown" | "rest
|
|
|
143
144
|
lastStopAt: Date.now(),
|
|
144
145
|
restartCount: state?.restartCount ?? 0,
|
|
145
146
|
consecutiveFailures: state?.consecutiveFailures ?? 0,
|
|
146
|
-
});
|
|
147
|
+
}));
|
|
147
148
|
emitManagedAgentStateChanged(policy.name, nextState as unknown as Record<string, unknown>);
|
|
148
149
|
const command = await createCommandAsync({
|
|
149
150
|
type: action === "restart" ? "agent.restart" : "agent.shutdown",
|
|
@@ -209,7 +210,7 @@ export const putSpawnPolicyRoute: Handler = async (req, params) => {
|
|
|
209
210
|
const updatedBy = isRecord(parsed.body) ? cleanString(parsed.body.updatedBy, "updatedBy", { max: 200 }) : undefined;
|
|
210
211
|
const entry = await setConfigAsync("spawn-policy", params.name!, value, updatedBy);
|
|
211
212
|
emitConfigChanged(entry.namespace, entry.key, entry.version);
|
|
212
|
-
getLifecycleManager().onConfigChanged("spawn-policy", entry.key);
|
|
213
|
+
(await getLifecycleManager().onConfigChanged("spawn-policy", entry.key));
|
|
213
214
|
return json(entry, entry.version === 1 ? 201 : 200);
|
|
214
215
|
} catch (e) {
|
|
215
216
|
if (e instanceof ValidationError) return error(e.message, 400);
|
package/src/routes/sse.ts
CHANGED
|
@@ -5,13 +5,13 @@ import { isOtherHumanSink } from "../message-visibility";
|
|
|
5
5
|
import { canViewAgentRoute, error, type Handler } from "./_shared";
|
|
6
6
|
import { messageViewerForRequest } from "./message-viewer";
|
|
7
7
|
|
|
8
|
-
export const getEvents: Handler = (req) => {
|
|
8
|
+
export const getEvents: Handler = async (req) => {
|
|
9
9
|
const url = new URL(req.url);
|
|
10
10
|
const agentId = url.searchParams.get("for") || null;
|
|
11
11
|
const lastEventId = Number(req.headers.get("last-event-id") ?? "");
|
|
12
12
|
// #3567 D6 — a signed-in human streams their own messages and notifications only.
|
|
13
13
|
const viewer = messageViewerForRequest(req) ?? undefined;
|
|
14
|
-
if (agentId && isOtherHumanSink(viewer, agentId)) return authorityDenied(req, "you can only read your own messages", 403, agentId, "read sink stream");
|
|
14
|
+
if (agentId && isOtherHumanSink(viewer, agentId)) return (await authorityDenied(req, "you can only read your own messages", 403, agentId, "read sink stream"));
|
|
15
15
|
if (agentId && !canViewAgentRoute(req, agentId)) return error("agent not found", 404);
|
|
16
16
|
return createSSEStream(agentId, Number.isSafeInteger(lastEventId) && lastEventId > 0 ? lastEventId : 0,
|
|
17
17
|
url.searchParams.get("agentStatus") === "delta", viewer);
|
|
@@ -16,14 +16,14 @@ function slugParam(params: Record<string, string | undefined>): string {
|
|
|
16
16
|
return cleanString(params.slug, "slug", { required: true, max: 120 })!;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
export const getTeamTemplatesRoute: Handler = (req) => {
|
|
20
|
-
const denied = authorizeRoute(req, { scope: "system:admin" });
|
|
19
|
+
export const getTeamTemplatesRoute: Handler = async (req) => {
|
|
20
|
+
const denied = (await authorizeRoute(req, { scope: "system:admin" }));
|
|
21
21
|
if (denied) return denied;
|
|
22
22
|
return json({ templates: listTeamTemplates() });
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
export const getTeamTemplateRoute: Handler = (req, params) => {
|
|
26
|
-
const denied = authorizeRoute(req, { scope: "system:admin" });
|
|
25
|
+
export const getTeamTemplateRoute: Handler = async (req, params) => {
|
|
26
|
+
const denied = (await authorizeRoute(req, { scope: "system:admin" }));
|
|
27
27
|
if (denied) return denied;
|
|
28
28
|
try {
|
|
29
29
|
const template = getTeamTemplate(slugParam(params));
|
|
@@ -34,7 +34,7 @@ export const getTeamTemplateRoute: Handler = (req, params) => {
|
|
|
34
34
|
};
|
|
35
35
|
|
|
36
36
|
export const postTeamTemplateRoute: Handler = async (req) => {
|
|
37
|
-
const denied = authorizeRoute(req, { scope: "system:admin" });
|
|
37
|
+
const denied = (await authorizeRoute(req, { scope: "system:admin" }));
|
|
38
38
|
if (denied) return denied;
|
|
39
39
|
const parsed = await parseBody<Record<string, unknown>>(req);
|
|
40
40
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
@@ -46,7 +46,7 @@ export const postTeamTemplateRoute: Handler = async (req) => {
|
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
export const putTeamTemplateRoute: Handler = async (req, params) => {
|
|
49
|
-
const denied = authorizeRoute(req, { scope: "system:admin" });
|
|
49
|
+
const denied = (await authorizeRoute(req, { scope: "system:admin" }));
|
|
50
50
|
if (denied) return denied;
|
|
51
51
|
const parsed = await parseBody<Record<string, unknown>>(req);
|
|
52
52
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
@@ -58,7 +58,7 @@ export const putTeamTemplateRoute: Handler = async (req, params) => {
|
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
export const deleteTeamTemplateRoute: Handler = async (req, params) => {
|
|
61
|
-
const denied = authorizeRoute(req, { scope: "system:admin" });
|
|
61
|
+
const denied = (await authorizeRoute(req, { scope: "system:admin" }));
|
|
62
62
|
if (denied) return denied;
|
|
63
63
|
const slug = slugParam(params);
|
|
64
64
|
return json({ slug, deleted: await deleteTeamTemplateAsync(slug, updatedBy(req)) });
|
package/src/routes/teams.ts
CHANGED
|
@@ -43,9 +43,9 @@ export const getMyTeamRoute: Handler = (req) => {
|
|
|
43
43
|
};
|
|
44
44
|
|
|
45
45
|
// #3725 — a signed-in member lists the teams their agent scope can see; machine callers stay admin-only.
|
|
46
|
-
export const getTeamsRoute: Handler = (req) => {
|
|
46
|
+
export const getTeamsRoute: Handler = async (req) => {
|
|
47
47
|
const viewer = viewerScopeForRequest(req);
|
|
48
|
-
const denied = authorizeRoute(req, { scope: viewer ? "teams:read" : "system:admin" });
|
|
48
|
+
const denied = (await authorizeRoute(req, { scope: viewer ? "teams:read" : "system:admin" }));
|
|
49
49
|
if (denied) return denied;
|
|
50
50
|
try {
|
|
51
51
|
const status = optionalEnum(new URL(req.url).searchParams.get("status") ?? undefined, "status", TEAM_STATUSES) as Team["status"] | undefined;
|
|
@@ -67,7 +67,7 @@ export const getTeamsRoute: Handler = (req) => {
|
|
|
67
67
|
};
|
|
68
68
|
|
|
69
69
|
export const getTeamOutcomesRoute: Handler = async (req) => {
|
|
70
|
-
const denied = authorizeRoute(req, { scope: "system:admin" });
|
|
70
|
+
const denied = (await authorizeRoute(req, { scope: "system:admin" }));
|
|
71
71
|
if (denied) return denied;
|
|
72
72
|
try {
|
|
73
73
|
const recentLimit = parseQueryInt(new URL(req.url).searchParams.get("recentLimit"), { min: 1, max: 50, clamp: true }) ?? undefined;
|
|
@@ -83,11 +83,11 @@ export const putMyTeamBriefRoute: Handler = async (req) => {
|
|
|
83
83
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
84
84
|
try {
|
|
85
85
|
const body = parsed.body ?? {};
|
|
86
|
-
return json(setCallerTeamBrief(authContextFromRequest(req), {
|
|
86
|
+
return json((await setCallerTeamBrief(authContextFromRequest(req), {
|
|
87
87
|
title: cleanString(body.title, "title", { max: 240 }),
|
|
88
88
|
brief: cleanString(body.brief, "brief", { max: 16_000 }),
|
|
89
89
|
definitionOfDone: cleanString(body.definitionOfDone, "definitionOfDone", { max: 4000 }),
|
|
90
|
-
}));
|
|
90
|
+
})));
|
|
91
91
|
} catch (err) {
|
|
92
92
|
return routeError(err);
|
|
93
93
|
}
|
|
@@ -98,28 +98,28 @@ export const postMyTeamDissolveRoute: Handler = async (req) => {
|
|
|
98
98
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
99
99
|
try {
|
|
100
100
|
const body = parsed.body ?? {};
|
|
101
|
-
return json(dissolveCallerTeam(authContextFromRequest(req), cleanDissolveInput(body)));
|
|
101
|
+
return json(await dissolveCallerTeam(authContextFromRequest(req), cleanDissolveInput(body)));
|
|
102
102
|
} catch (err) {
|
|
103
103
|
return routeError(err);
|
|
104
104
|
}
|
|
105
105
|
};
|
|
106
106
|
|
|
107
107
|
export const postTeamDissolveByIdRoute: Handler = async (req, params) => {
|
|
108
|
-
const denied = authorizeRoute(req, { scope: "system:admin" });
|
|
108
|
+
const denied = (await authorizeRoute(req, { scope: "system:admin" }));
|
|
109
109
|
if (denied) return denied;
|
|
110
110
|
const parsed = await parseBody<Record<string, unknown>>(req);
|
|
111
111
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
112
112
|
try {
|
|
113
113
|
const id = params.id!;
|
|
114
114
|
if (!getTeam(id)) return error("team not found", 404);
|
|
115
|
-
return json(dissolveTeamById(id, cleanDissolveInput(parsed.body ?? {})));
|
|
115
|
+
return json(await dissolveTeamById(id, cleanDissolveInput(parsed.body ?? {})));
|
|
116
116
|
} catch (err) {
|
|
117
117
|
return routeError(err);
|
|
118
118
|
}
|
|
119
119
|
};
|
|
120
120
|
|
|
121
121
|
export const patchTeamSpawnDelegationRoute: Handler = async (req, params) => {
|
|
122
|
-
const denied = authorizeRoute(req, { scope: "teams:write" });
|
|
122
|
+
const denied = (await authorizeRoute(req, { scope: "teams:write" }));
|
|
123
123
|
if (denied) return denied;
|
|
124
124
|
const parsed = await parseBody<Record<string, unknown>>(req);
|
|
125
125
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
@@ -132,7 +132,7 @@ export const patchTeamSpawnDelegationRoute: Handler = async (req, params) => {
|
|
|
132
132
|
export const getTeamSpawnDelegationRoute: Handler = async (req, params) => {
|
|
133
133
|
// #3725 — the grant names projects and launches across the tree; a member's session may not read it.
|
|
134
134
|
const viewer = viewerScopeForRequest(req);
|
|
135
|
-
const denied = authorizeRoute(req, { scope: viewer && !viewer.seesAll ? "system:admin" : "teams:read" });
|
|
135
|
+
const denied = (await authorizeRoute(req, { scope: viewer && !viewer.seesAll ? "system:admin" : "teams:read" }));
|
|
136
136
|
if (denied) return denied;
|
|
137
137
|
try {
|
|
138
138
|
const state = await getTeamSpawnDelegation(authContextFromRequest(req), params.id!);
|
package/src/routes/tokens.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import { upsertIntegrationRegistryAsync, upsertTokenProfileAsync, updateTokenProfileAsync, deleteTokenProfileAsync } from "../db/runtime-tail-async";
|
|
1
2
|
// Auto-split from routes.ts (#299). Domain: tokens.
|
|
2
3
|
import { revokeUserSession, sessionUserIdOf } from "../auth/session";
|
|
3
4
|
import { withSessionCookie } from "../auth/session-cookie";
|
|
4
5
|
import { APPROVAL_MODES, SPAWN_PROVIDERS, isRecord, userSinkId } from "@humwick/sdk";
|
|
5
|
-
import { ValidationError, getOrchestrator
|
|
6
|
+
import { ValidationError, getOrchestrator } from "../db";
|
|
6
7
|
import { auditEvent, authAuditMetadata, authorizeRoute, error, isRootCredentialRequest, json, parseBody, resolveActingUser, type Handler } from "./_shared";
|
|
7
8
|
import { cleanString, cleanStringArray, cleanTokenConstraints, optionalEnum } from "../validation";
|
|
8
|
-
import {
|
|
9
|
+
import { getToken, getTokenProfile, listTokenProfiles, listTokens } from "../token-db";
|
|
9
10
|
import { createTokenAsync, revokeTokenAsync } from "../token-db-write";
|
|
10
11
|
import { getComponentAuth, getIntegrationAuth, isAuthorized } from "../security";
|
|
11
12
|
import { handoffRunnerTokenAsync, issueIntegrationRuntimeToken, issueInteractiveRunnerRuntimeToken, issueMcpRuntimeToken, reissueRunnerRuntimeToken, remintRunnerRuntimeToken, type RunnerTokenMintRefusal } from "../runtime-tokens";
|
|
@@ -176,7 +177,7 @@ export const postRuntimeTokenRemint: Handler = async (req) => {
|
|
|
176
177
|
export const postOrchestratorRunnerToken: Handler = async (req, params) => {
|
|
177
178
|
const orch = getOrchestrator(params.id!);
|
|
178
179
|
if (!orch) return error("orchestrator not found", 404);
|
|
179
|
-
const denied = authorizeRoute(req, { scope: "command:write", resource: { orchestratorId: orch.id } });
|
|
180
|
+
const denied = (await authorizeRoute(req, { scope: "command:write", resource: { orchestratorId: orch.id } }));
|
|
180
181
|
if (denied) return denied;
|
|
181
182
|
const parsed = await parseBody<unknown>(req);
|
|
182
183
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
@@ -219,7 +220,7 @@ export const postInteractiveRunnerRuntimeToken: Handler = async (req) => {
|
|
|
219
220
|
// (`isRootCredentialRequest` above), which can mint any token it likes anyway — the value is
|
|
220
221
|
// pinned into the signature so every LATER, scoped read of it is unforgeable.
|
|
221
222
|
const approvalMode = optionalEnum(parsed.body.approvalMode, "approvalMode", APPROVAL_MODES);
|
|
222
|
-
const runtimeToken = issueInteractiveRunnerRuntimeToken({
|
|
223
|
+
const runtimeToken = (await issueInteractiveRunnerRuntimeToken({
|
|
223
224
|
provider,
|
|
224
225
|
cwd,
|
|
225
226
|
runnerId,
|
|
@@ -228,7 +229,7 @@ export const postInteractiveRunnerRuntimeToken: Handler = async (req) => {
|
|
|
228
229
|
host,
|
|
229
230
|
...(approvalMode ? { approvalMode } : {}),
|
|
230
231
|
createdBy: `interactive:${runnerId}`,
|
|
231
|
-
});
|
|
232
|
+
}));
|
|
232
233
|
await auditEvent({
|
|
233
234
|
clientId: "server-runtime-token-interactive-" + runnerId + "-" + Date.now(),
|
|
234
235
|
kind: "state",
|
|
@@ -263,13 +264,13 @@ export const postMcpRuntimeToken: Handler = async (req) => {
|
|
|
263
264
|
const agentId = cleanString(parsed.body.agentId, "agentId", { max: 240 });
|
|
264
265
|
const targets = cleanStringArray(parsed.body.targets, "targets", { itemMax: 80, maxItems: 50 });
|
|
265
266
|
const channels = cleanStringArray(parsed.body.channels, "channels", { itemMax: 80, maxItems: 50 });
|
|
266
|
-
const runtimeToken = issueMcpRuntimeToken({
|
|
267
|
+
const runtimeToken = (await issueMcpRuntimeToken({
|
|
267
268
|
sessionId,
|
|
268
269
|
agentId,
|
|
269
270
|
targets,
|
|
270
271
|
channels,
|
|
271
272
|
createdBy: `mcp:${sessionId}`,
|
|
272
|
-
});
|
|
273
|
+
}));
|
|
273
274
|
await auditEvent({
|
|
274
275
|
clientId: "server-runtime-token-mcp-" + sessionId + "-" + Date.now(),
|
|
275
276
|
kind: "state",
|
|
@@ -302,19 +303,19 @@ export const postIntegrationRuntimeToken: Handler = async (req) => {
|
|
|
302
303
|
const name = cleanString(parsed.body.name, "name", { required: true, max: 120 })!;
|
|
303
304
|
const targets = cleanStringArray(parsed.body.targets, "targets", { itemMax: 80, maxItems: 50 });
|
|
304
305
|
const channels = cleanStringArray(parsed.body.channels, "channels", { itemMax: 80, maxItems: 50 });
|
|
305
|
-
const runtimeToken = issueIntegrationRuntimeToken({
|
|
306
|
+
const runtimeToken = (await issueIntegrationRuntimeToken({
|
|
306
307
|
name,
|
|
307
308
|
targets,
|
|
308
309
|
channels,
|
|
309
310
|
createdBy: `integration:${name}`,
|
|
310
|
-
});
|
|
311
|
-
|
|
311
|
+
}));
|
|
312
|
+
(await upsertIntegrationRegistryAsync({
|
|
312
313
|
name,
|
|
313
314
|
scopes: runtimeToken.record.scope,
|
|
314
315
|
targets,
|
|
315
316
|
channels,
|
|
316
317
|
source: "api",
|
|
317
|
-
});
|
|
318
|
+
}));
|
|
318
319
|
await auditEvent({
|
|
319
320
|
clientId: "server-runtime-token-integration-" + name + "-" + Date.now(),
|
|
320
321
|
kind: "state",
|
|
@@ -344,7 +345,7 @@ export const postTokenProfile: Handler = async (req) => {
|
|
|
344
345
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
345
346
|
try {
|
|
346
347
|
const input = cleanTokenProfileInput(parsed.body);
|
|
347
|
-
return json(
|
|
348
|
+
return json((await upsertTokenProfileAsync({
|
|
348
349
|
id: input.id,
|
|
349
350
|
name: input.name!,
|
|
350
351
|
description: input.description,
|
|
@@ -353,7 +354,7 @@ export const postTokenProfile: Handler = async (req) => {
|
|
|
353
354
|
constraints: input.constraints,
|
|
354
355
|
ttlSeconds: input.ttlSeconds,
|
|
355
356
|
createdBy: input.createdBy,
|
|
356
|
-
}), 201);
|
|
357
|
+
})), 201);
|
|
357
358
|
} catch (e) {
|
|
358
359
|
if (e instanceof ValidationError) return error(e.message, 400);
|
|
359
360
|
if (e instanceof Error) return error(e.message, 400);
|
|
@@ -366,7 +367,7 @@ export const patchTokenProfile: Handler = async (req, params) => {
|
|
|
366
367
|
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
367
368
|
try {
|
|
368
369
|
const patch = cleanTokenProfileInput(parsed.body, true);
|
|
369
|
-
const updated =
|
|
370
|
+
const updated = (await updateTokenProfileAsync(params.id!, {
|
|
370
371
|
name: patch.name,
|
|
371
372
|
description: patch.description,
|
|
372
373
|
role: patch.role,
|
|
@@ -374,7 +375,7 @@ export const patchTokenProfile: Handler = async (req, params) => {
|
|
|
374
375
|
constraints: patch.constraints,
|
|
375
376
|
ttlSeconds: patch.ttlSeconds,
|
|
376
377
|
createdBy: patch.createdBy,
|
|
377
|
-
});
|
|
378
|
+
}));
|
|
378
379
|
return updated ? json(updated) : error("token profile not found", 404);
|
|
379
380
|
} catch (e) {
|
|
380
381
|
if (e instanceof ValidationError) return error(e.message, 400);
|
|
@@ -383,8 +384,8 @@ export const patchTokenProfile: Handler = async (req, params) => {
|
|
|
383
384
|
}
|
|
384
385
|
};
|
|
385
386
|
|
|
386
|
-
export const deleteTokenProfileRoute: Handler = (_req, params) => {
|
|
387
|
-
return
|
|
387
|
+
export const deleteTokenProfileRoute: Handler = async (_req, params) => {
|
|
388
|
+
return (await deleteTokenProfileAsync(params.id!)) ? json({ ok: true }) : error("token profile not found or built-in", 404);
|
|
388
389
|
};
|
|
389
390
|
|
|
390
391
|
export const postTokenRevoke: Handler = async (req, params) => {
|