@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
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { createPlanRow, deletePlan, replacePlanIfVersion, setPlanArchived } from "./plans.ts";
|
|
2
|
+
import { PLAN_READY_NOTICE_WRITE_OPS } from "./plan-ready-notices.ts";
|
|
2
3
|
import type { WriterOpContext, WriterOpSpec } from "./write-ops.ts";
|
|
3
4
|
|
|
4
5
|
export const PLANS_WRITE_OPS: Readonly<Record<string, WriterOpSpec>> = Object.freeze({
|
|
6
|
+
...PLAN_READY_NOTICE_WRITE_OPS,
|
|
5
7
|
"plans.create": { offLoop: true, idempotent: false, fn: (args: { input: Parameters<typeof createPlanRow>[0] }, ctx: WriterOpContext) => createPlanRow(args.input, ctx.now) },
|
|
6
8
|
"plans.replace": { offLoop: true, idempotent: false, fn: (args: { input: Parameters<typeof replacePlanIfVersion>[0]; changedBy?: string }, ctx: WriterOpContext) => replacePlanIfVersion(args.input, args.changedBy, ctx.now, false) },
|
|
7
9
|
"plans.setArchived": { offLoop: true, idempotent: true, fn: (args: { id: string; archived: boolean }, ctx: WriterOpContext) => setPlanArchived(args.id, args.archived, ctx.now) },
|
|
@@ -104,6 +104,11 @@ export function snapshotBufferedPresence(): PresenceSnapshot {
|
|
|
104
104
|
* current, and the caller's surrounding status/ready predicates constrain the match. */
|
|
105
105
|
export function bufferedLiveAgentIds(cutoff: number): string[] {
|
|
106
106
|
const ids: string[] = [];
|
|
107
|
+
const snapshot = writerPresenceSnapshot();
|
|
108
|
+
if (snapshot) {
|
|
109
|
+
for (const beat of snapshot) if (beat.lastSeen > cutoff) ids.push(beat.id);
|
|
110
|
+
return ids;
|
|
111
|
+
}
|
|
107
112
|
for (const [id, pending] of pendingPresence) {
|
|
108
113
|
if (pending.lastSeen > cutoff) ids.push(id);
|
|
109
114
|
}
|
package/src/db/presence-loop.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { framed } from "../hub-metrics";
|
|
1
2
|
import { assertMainThreadState } from "./main-thread-state";
|
|
2
3
|
// Lifecycle glue for the coalesced presence buffer. Kept outside agents.ts so its writer-op body
|
|
3
4
|
// never depends on the gateway-facing facade (ADR 0001 §3.1).
|
|
@@ -6,53 +7,47 @@ import { errMessage } from "@humwick/sdk";
|
|
|
6
7
|
import { PRESENCE_FLUSH_MS } from "../config";
|
|
7
8
|
import { drainPendingLandSettleSideEffects } from "../land-settle-dispatch";
|
|
8
9
|
import { onShutdown } from "../shutdown";
|
|
9
|
-
import {
|
|
10
|
+
import { flushPresenceAsync } from "./presence-write.ts";
|
|
10
11
|
import { pendingPresence } from "./presence-buffer.ts";
|
|
11
12
|
|
|
12
13
|
let presenceFlushTimer: ReturnType<typeof setInterval> | undefined;
|
|
13
|
-
let asyncPresenceFlusher: (() => Promise<{ flushed: number }>) | undefined;
|
|
14
14
|
let removeShutdownHook: (() => void) | undefined;
|
|
15
15
|
|
|
16
|
-
/** Attach the gateway-backed normal-tick flusher without importing the gateway into agents.ts. */
|
|
17
|
-
export function setAsyncPresenceFlusher(flusher: () => Promise<{ flushed: number }>): void {
|
|
18
|
-
assertMainThreadState("presence-loop.ts");
|
|
19
|
-
asyncPresenceFlusher = flusher;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
16
|
/** Start the periodic presence-buffer flush loop (server boot). */
|
|
23
17
|
export function startPresenceFlushLoop(intervalMs: number = PRESENCE_FLUSH_MS): void {
|
|
24
18
|
assertMainThreadState("presence-loop.ts");
|
|
25
19
|
if (presenceFlushTimer) return;
|
|
26
|
-
presenceFlushTimer = setInterval(() =>
|
|
27
|
-
|
|
28
|
-
if (!flush) return flushPresenceQuietly(); // Bootstrap/isolated compatibility fallback.
|
|
29
|
-
void flush().catch((err) => console.warn(`[presence] flush failed: ${errMessage(err)}`));
|
|
30
|
-
}, intervalMs);
|
|
20
|
+
presenceFlushTimer = setInterval(framed("timer presence-flush", () =>
|
|
21
|
+
flushPresenceAsync().catch((err) => console.warn(`[presence] flush failed: ${errMessage(err)}`))), intervalMs);
|
|
31
22
|
presenceFlushTimer.unref?.();
|
|
32
|
-
process.once("beforeExit",
|
|
33
|
-
removeShutdownHook = onShutdown("presence", () => {
|
|
34
|
-
drainPendingLandSettleSideEffects();
|
|
35
|
-
stopPresenceFlushLoop();
|
|
23
|
+
process.once("beforeExit", flushPresenceBeforeExit);
|
|
24
|
+
removeShutdownHook = onShutdown("presence", async () => {
|
|
25
|
+
await drainPendingLandSettleSideEffects();
|
|
26
|
+
await stopPresenceFlushLoop();
|
|
36
27
|
});
|
|
37
28
|
}
|
|
38
29
|
|
|
39
30
|
/** Stop the loop and persist whatever is buffered (graceful shutdown / test teardown). */
|
|
40
|
-
|
|
31
|
+
function detachPresenceLoop(): void {
|
|
41
32
|
assertMainThreadState("presence-loop.ts");
|
|
42
33
|
removeShutdownHook?.();
|
|
43
34
|
removeShutdownHook = undefined;
|
|
44
|
-
process.removeListener("beforeExit",
|
|
35
|
+
process.removeListener("beforeExit", flushPresenceBeforeExit);
|
|
45
36
|
if (presenceFlushTimer) clearInterval(presenceFlushTimer);
|
|
46
37
|
presenceFlushTimer = undefined;
|
|
47
|
-
flushPresenceQuietly();
|
|
48
38
|
}
|
|
49
39
|
|
|
50
|
-
function
|
|
51
|
-
|
|
40
|
+
export async function stopPresenceFlushLoop(): Promise<void> {
|
|
41
|
+
detachPresenceLoop();
|
|
42
|
+
await flushPresenceAsync();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function flushPresenceBeforeExit(): void {
|
|
46
|
+
void flushPresenceAsync().catch(err => console.warn(`[presence] flush failed: ${errMessage(err)}`));
|
|
52
47
|
}
|
|
53
48
|
|
|
54
49
|
/** Test-only: drop the buffered presence and stop the flush loop. */
|
|
55
50
|
export function resetPresenceBufferForTests(): void {
|
|
56
51
|
pendingPresence.clear();
|
|
57
|
-
|
|
52
|
+
detachPresenceLoop();
|
|
58
53
|
}
|
package/src/db/presence-write.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { assertMainThreadState } from "./main-thread-state";
|
|
|
3
3
|
// Kept outside agents.ts because the writer registry imports the op body from that module; importing
|
|
4
4
|
// the gateway there would make the writer-stack cycle gateway → write-ops → agents → gateway.
|
|
5
5
|
|
|
6
|
-
import { setAsyncPresenceFlusher } from "./presence-loop.ts";
|
|
7
6
|
import { settlePendingPresenceFlush, snapshotPendingPresenceFlush, type PresenceFlushPayload } from "./presence-buffer.ts";
|
|
8
7
|
import { getGateway } from "./gateway.ts";
|
|
9
8
|
|
|
@@ -31,8 +30,3 @@ export function flushPresenceAsync(now: number = Date.now()): Promise<{ flushed:
|
|
|
31
30
|
.finally(() => { activeFlush = undefined; });
|
|
32
31
|
return activeFlush;
|
|
33
32
|
}
|
|
34
|
-
|
|
35
|
-
// The timer remains owned by presence-loop.ts for its synchronous shutdown guarantee, while normal ticks
|
|
36
|
-
// arrive here through an injected callback. This direction deliberately avoids a writer-op → gateway
|
|
37
|
-
// dependency cycle; the callback carries no DB closure across the worker seam.
|
|
38
|
-
setAsyncPresenceFlusher(flushPresenceAsync);
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import type { writeProjectEntry, promoteBlackboardEntry } from "./project-entries";
|
|
1
3
|
// Async project-entries facades (T4060 hub on-loop). Kept outside
|
|
2
4
|
// project-entries.ts to avoid a gateway cycle.
|
|
3
5
|
import { getGateway } from "./gateway.ts";
|
|
@@ -16,3 +18,15 @@ export const searchProjectEntriesAsync = (
|
|
|
16
18
|
query: string,
|
|
17
19
|
opts: ProjectEntrySearchOptions = {},
|
|
18
20
|
): Promise<ProjectEntrySearchResult[]> => read("projectEntries.search", { projectId, query, ...opts });
|
|
21
|
+
|
|
22
|
+
export const getProjectEntryAsync = (id: string): Promise<ProjectEntry | null> => read("projectEntries.get", { id });
|
|
23
|
+
export const getProjectEntryChainAsync = (id: string): Promise<ProjectEntry[]> => read("projectEntries.chain", { id });
|
|
24
|
+
export const listActiveEntriesInAreaAsync = (projectId: string, area: string): Promise<ProjectEntry[]> => read("projectEntries.inArea", { projectId, area });
|
|
25
|
+
export const countActivePinnedEntriesInAreaAsync = (projectId: string, area: string): Promise<number> => read("projectEntries.countPinnedInArea", { projectId, area });
|
|
26
|
+
|
|
27
|
+
export const writeProjectEntryAsync = (input: Parameters<typeof writeProjectEntry>[0], requestId: string = randomUUID()): Promise<ProjectEntry> =>
|
|
28
|
+
getGateway().write("projectEntries.write", input, { idempotencyKey: requestId }) as unknown as Promise<ProjectEntry>;
|
|
29
|
+
export const retractProjectEntryAsync = (id: string): Promise<ProjectEntry | null> =>
|
|
30
|
+
getGateway().write("projectEntries.retract", { id }) as unknown as Promise<ProjectEntry | null>;
|
|
31
|
+
export const promoteBlackboardEntryAsync = (input: Parameters<typeof promoteBlackboardEntry>[0], requestId: string = randomUUID()): Promise<ProjectEntry> =>
|
|
32
|
+
getGateway().write("projectEntries.promoteBlackboard", input, { idempotencyKey: requestId }) as unknown as Promise<ProjectEntry>;
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
// Project-entries reader operations (T4060 hub on-loop). The MCP memory/project
|
|
2
2
|
// read tools ran these scans synchronously on the event loop — including the
|
|
3
3
|
// temp-B-TREE display ORDER BY over cells whose rows are ~95% retracted.
|
|
4
|
-
import { listProjectEntries, searchProjectEntries } from "./project-entries.ts";
|
|
4
|
+
import { countActivePinnedEntriesInArea, getProjectEntry, getProjectEntryChain, listActiveEntriesInArea, listProjectEntries, searchProjectEntries } from "./project-entries.ts";
|
|
5
5
|
import type { ProjectEntryKind, ProjectEntryStatus, ProjectEntrySearchOptions } from "../types";
|
|
6
6
|
|
|
7
7
|
export const PROJECT_ENTRIES_READ_OPS = {
|
|
8
|
+
"projectEntries.get": (args: { id: string }) => getProjectEntry(args.id),
|
|
9
|
+
"projectEntries.chain": (args: { id: string }) => getProjectEntryChain(args.id),
|
|
10
|
+
"projectEntries.inArea": (args: { projectId: string; area: string }) => listActiveEntriesInArea(args.projectId, args.area),
|
|
11
|
+
"projectEntries.countPinnedInArea": (args: { projectId: string; area: string }) => countActivePinnedEntriesInArea(args.projectId, args.area),
|
|
8
12
|
"projectEntries.list": (args: {
|
|
9
13
|
projectId: string;
|
|
10
14
|
kind?: ProjectEntryKind;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { promoteBlackboardEntry, retractProjectEntry, writeProjectEntry } from "./project-entries";
|
|
2
|
+
import type { WriterOpSpec } from "./write-ops";
|
|
3
|
+
|
|
4
|
+
export const PROJECT_ENTRIES_WRITE_OPS: Readonly<Record<string, WriterOpSpec>> = {
|
|
5
|
+
"projectEntries.write": { offLoop: true, idempotent: false, fn: (args: Parameters<typeof writeProjectEntry>[0], ctx) => writeProjectEntry(args, ctx.now) },
|
|
6
|
+
"projectEntries.retract": { offLoop: true, idempotent: true, fn: (args: { id: string }, ctx) => retractProjectEntry(args.id, ctx.now) },
|
|
7
|
+
"projectEntries.promoteBlackboard": { offLoop: true, idempotent: false, fn: (args: Parameters<typeof promoteBlackboardEntry>[0], ctx) => promoteBlackboardEntry(args, ctx.now) },
|
|
8
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isolateMemoryEntry } from "../memory-entry-safety";
|
|
2
2
|
import { validateProjectEntryText } from "../validation";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
|
-
import { getDb,
|
|
4
|
+
import { getDb, inWriteTransaction, ValidationError } from "./connection.ts";
|
|
5
5
|
import { getEntry as getBlackboardEntry, listEntries as listBlackboardEntries } from "./blackboard.ts";
|
|
6
6
|
import { parseJson } from "../utils";
|
|
7
7
|
import {
|
|
@@ -211,7 +211,7 @@ function assertProjectKnowledge(projectId: string): void {
|
|
|
211
211
|
}
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
-
export function writeProjectEntry(input: WriteProjectEntryInput): ProjectEntry {
|
|
214
|
+
export function writeProjectEntry(input: WriteProjectEntryInput, now: number = Date.now()): ProjectEntry {
|
|
215
215
|
validateProjectEntryText(input);
|
|
216
216
|
assertProjectKnowledge(input.projectId);
|
|
217
217
|
assertKind(input.kind);
|
|
@@ -234,8 +234,7 @@ export function writeProjectEntry(input: WriteProjectEntryInput): ProjectEntry {
|
|
|
234
234
|
supersedes = latestEntryByTitle(input.projectId, input.kind, input.title)?.id;
|
|
235
235
|
}
|
|
236
236
|
const id = projectEntryId();
|
|
237
|
-
|
|
238
|
-
writeTransaction(() => {
|
|
237
|
+
inWriteTransaction(() => {
|
|
239
238
|
let inheritedAreas: string[] | null = null;
|
|
240
239
|
if (supersedes) {
|
|
241
240
|
const previous = getProjectEntry(supersedes);
|
|
@@ -404,21 +403,25 @@ export function countActivePinnedEntriesInArea(projectId: string, area: string):
|
|
|
404
403
|
}
|
|
405
404
|
|
|
406
405
|
/** #3410 — active entries of one cell that name `area`, newest first. Same index as the count above. */
|
|
407
|
-
export function
|
|
408
|
-
|
|
406
|
+
export function buildActiveEntriesInAreaQuery(projectId: string, area: string): { sql: string; params: string[] } {
|
|
407
|
+
return { sql: `
|
|
409
408
|
SELECT * FROM project_entries
|
|
410
409
|
WHERE project_id = ? AND status = 'active' AND areas LIKE ? ESCAPE '\\'
|
|
411
410
|
ORDER BY updated_at DESC, created_at DESC, id DESC
|
|
412
|
-
|
|
413
|
-
return rows.map(rowToEntry);
|
|
411
|
+
`, params: [projectId, `%${escapeLike(JSON.stringify(area))}%`] };
|
|
414
412
|
}
|
|
415
413
|
|
|
416
|
-
export function
|
|
414
|
+
export function listActiveEntriesInArea(projectId: string, area: string): ProjectEntry[] {
|
|
415
|
+
const { sql, params } = buildActiveEntriesInAreaQuery(projectId, area);
|
|
416
|
+
return (getDb().query(sql).all(...params) as ProjectEntryRow[]).map(rowToEntry);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
export function retractProjectEntry(id: string, now: number = Date.now()): ProjectEntry | null {
|
|
417
420
|
const existing = getProjectEntry(id);
|
|
418
421
|
if (!existing) return null;
|
|
419
422
|
assertStatus("retracted");
|
|
420
423
|
getDb().query("UPDATE project_entries SET status = 'retracted', updated_at = ? WHERE id = ?")
|
|
421
|
-
.run(
|
|
424
|
+
.run(now, id);
|
|
422
425
|
return getProjectEntry(id);
|
|
423
426
|
}
|
|
424
427
|
|
|
@@ -472,7 +475,7 @@ function activePromotedEntry(projectId: string, originRef: string): ProjectEntry
|
|
|
472
475
|
* project supersedes the prior promoted copy rather than duplicating it, so the durable
|
|
473
476
|
* ledger holds at most one active entry per promoted finding while keeping the full
|
|
474
477
|
* supersede chain for audit. */
|
|
475
|
-
export function promoteBlackboardEntry(input: PromoteBlackboardEntryInput): ProjectEntry {
|
|
478
|
+
export function promoteBlackboardEntry(input: PromoteBlackboardEntryInput, now: number = Date.now()): ProjectEntry {
|
|
476
479
|
const source = getBlackboardEntry(input.blackboardEntryId);
|
|
477
480
|
if (!source) throw new ValidationError(`blackboard entry ${input.blackboardEntryId} not found`);
|
|
478
481
|
if (source.status !== "active") {
|
|
@@ -489,7 +492,7 @@ export function promoteBlackboardEntry(input: PromoteBlackboardEntryInput): Proj
|
|
|
489
492
|
source: "promoted",
|
|
490
493
|
originRef: source.id,
|
|
491
494
|
...(existing ? { supersedes: existing.id } : {}),
|
|
492
|
-
});
|
|
495
|
+
}, now);
|
|
493
496
|
}
|
|
494
497
|
|
|
495
498
|
export interface UnpromotedBlackboardSummary {
|
|
@@ -203,7 +203,7 @@ export function setProjectJournalFields(input: {
|
|
|
203
203
|
fields: Record<string, string | null>;
|
|
204
204
|
changedBy: string;
|
|
205
205
|
now?: number;
|
|
206
|
-
}): ProjectJournalFieldChange[] {
|
|
206
|
+
}, submittedAt: number = Date.now()): ProjectJournalFieldChange[] {
|
|
207
207
|
const entries = Object.entries(input.fields);
|
|
208
208
|
if (!entries.length) throw new ValidationError("fields must name at least one journal field");
|
|
209
209
|
const plan: Array<{ field: ProjectJournalField; value: string | null; previous: string | null }> = [];
|
|
@@ -222,7 +222,7 @@ export function setProjectJournalFields(input: {
|
|
|
222
222
|
plan.push({ field, value: value === "" ? null : value, previous });
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
-
const now = input.now ??
|
|
225
|
+
const now = input.now ?? submittedAt;
|
|
226
226
|
const changes: ProjectJournalFieldChange[] = [];
|
|
227
227
|
writeTransaction(() => {
|
|
228
228
|
for (const { field, value, previous } of plan) {
|
|
@@ -68,9 +68,9 @@ export interface UpsertProjectTrustApprovalInput {
|
|
|
68
68
|
/** Records `approvedValue` as the trusted content for this (profile, repo, capability), replacing
|
|
69
69
|
* any prior approval — used both by the operator-triggered dashboard approve action and by the
|
|
70
70
|
* gate's own grandfather-on-first-encounter path (decision #4). */
|
|
71
|
-
export function upsertProjectTrustApproval(input: UpsertProjectTrustApprovalInput): ProjectTrustApproval {
|
|
71
|
+
export function upsertProjectTrustApproval(input: UpsertProjectTrustApprovalInput, submittedAt: number = Date.now()): ProjectTrustApproval {
|
|
72
72
|
return writeTransaction(() => {
|
|
73
|
-
const now =
|
|
73
|
+
const now = submittedAt;
|
|
74
74
|
const existing = getDb().query(`
|
|
75
75
|
SELECT id FROM project_trust_approvals WHERE profile_name = ? AND repo_key = ? AND capability = ?
|
|
76
76
|
`).get(input.profileName, input.repoKey, input.capability) as { id: string } | null;
|
|
@@ -74,8 +74,8 @@ export function listTemplates(category?: string): PromptTemplateRecord[] {
|
|
|
74
74
|
return templates;
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
export function upsertTemplate(slug: string, template: string): void {
|
|
78
|
-
const now =
|
|
77
|
+
export function upsertTemplate(slug: string, template: string, submittedAt: number = Date.now()): void {
|
|
78
|
+
const now = submittedAt;
|
|
79
79
|
if (versionedPromptSlot(slug)) {
|
|
80
80
|
throw new ValidationError("Use the versioned prompt writer with expectedVersion and actor");
|
|
81
81
|
}
|
|
@@ -83,11 +83,11 @@ export function upsertTemplate(slug: string, template: string): void {
|
|
|
83
83
|
if ((result.changes ?? 0) === 0) throw new ValidationError(`prompt template ${slug} not found`);
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
export function resetTemplate(slug: string): void {
|
|
86
|
+
export function resetTemplate(slug: string, submittedAt: number = Date.now()): void {
|
|
87
87
|
if (versionedPromptSlot(slug)) {
|
|
88
88
|
throw new ValidationError("Use the versioned prompt writer with expectedVersion and actor");
|
|
89
89
|
}
|
|
90
|
-
const now =
|
|
90
|
+
const now = submittedAt;
|
|
91
91
|
const result = getDb().query("UPDATE prompt_templates SET template = default_template, updated_at = ? WHERE slug = ?").run(now, slug);
|
|
92
92
|
if ((result.changes ?? 0) === 0) throw new ValidationError(`prompt template ${slug} not found`);
|
|
93
93
|
}
|
|
@@ -191,6 +191,16 @@ export const READ_OP_MARSHALING_FIXTURES: ReadOpFixtures = {
|
|
|
191
191
|
"projects.resolveEntries": { args: { projectId: SEED.projectId } },
|
|
192
192
|
"projects.readMemoryEntriesByIds": { args: { identity: { projectId: SEED.projectId }, ids: ["pe_t9_alpha"] } },
|
|
193
193
|
"projects.memoryPreamble": { args: { identity: { projectId: SEED.projectId }, options: {} } },
|
|
194
|
+
"issueRefs.list": { args: { limit: 10 } },
|
|
195
|
+
"automations.listRuns": { args: { limit: 10 } },
|
|
196
|
+
"automations.pendingPrecheckRuns": { args: undefined },
|
|
197
|
+
"automations.reconcilableRuns": { args: undefined },
|
|
198
|
+
"automations.dispatchableQueuedRuns": { args: undefined },
|
|
199
|
+
"automations.dueAutomations": { args: { now: 1_700_000_000_000 } },
|
|
200
|
+
"projectEntries.get": { args: { id: "pe_t9_alpha" } },
|
|
201
|
+
"projectEntries.chain": { args: { id: "pe_t9_alpha" } },
|
|
202
|
+
"projectEntries.inArea": { args: { projectId: SEED.projectId, area: "db" } },
|
|
203
|
+
"projectEntries.countPinnedInArea": { args: { projectId: SEED.projectId, area: "db" } },
|
|
194
204
|
"projectEntries.list": { args: { projectId: SEED.projectId } },
|
|
195
205
|
"projectEntries.search": { args: { projectId: SEED.projectId, query: "t9" } },
|
|
196
206
|
"teams.spawnDelegation.get": { args: { teamId: SEED.teamId } },
|
|
@@ -242,6 +252,7 @@ export const READ_OP_MARSHALING_FIXTURES: ReadOpFixtures = {
|
|
|
242
252
|
// --- commands / codex reset / inbox / insights --------------------------------------------------
|
|
243
253
|
"commands.spawnOutcome": { args: { spawnRequestId: "spawn-t9" } },
|
|
244
254
|
"commands.get": { args: { id: SEED.commandId } },
|
|
255
|
+
"commands.latestAttempt": { args: { baseId: SEED.commandId } },
|
|
245
256
|
"commands.listLegacyLandingBackfillCandidates": { args: { afterId: "", limit: 10 } },
|
|
246
257
|
// `observedAt` is the dispatcher's own `ctx.now`, so the in-process and worker runs legitimately
|
|
247
258
|
// stamp different clock readings for the same DB state — normalize it out or the #1960 worker-seam
|
|
@@ -714,6 +725,12 @@ export function seedReadOpMarshalingData(): void {
|
|
|
714
725
|
VALUES ('t9', 't9 claimed task', 't9', 'info', 'in_progress', 't9', 'claim', ?, ?, ?, ?, ?)`,
|
|
715
726
|
).run(SEED.agentId, t - 1, t, t, t);
|
|
716
727
|
|
|
728
|
+
// An open task-bound run so the automation scan ops marshal a NON-trivial run (meta/result JSON parsed worker-side).
|
|
729
|
+
db.query(
|
|
730
|
+
`INSERT INTO automation_runs (id, automation_id, status, scheduled_for, orchestrator_id, task_id, meta, created_at, updated_at)
|
|
731
|
+
VALUES ('run-t9', 'automation-t9', 'running', ?, 'orch-t9', 1, '{"k":"v"}', ?, ?)`,
|
|
732
|
+
).run(t, t, t);
|
|
733
|
+
|
|
717
734
|
// Project-entries rows so `projectEntries.list`/`search` marshal NON-trivial results:
|
|
718
735
|
// two active rows the query term hits, plus a retracted row proving mixed-status parity.
|
|
719
736
|
for (const [id, title, body, status, updatedAt] of [
|
|
@@ -725,5 +742,6 @@ export function seedReadOpMarshalingData(): void {
|
|
|
725
742
|
`INSERT INTO project_entries (id, project_id, kind, title, body, status, tags, author_id, source, audience, inject, sensitivity, created_at, updated_at)
|
|
726
743
|
VALUES (?, ?, 'rule', ?, ?, ?, '["t9"]', ?, 'manual', 'all', 'indexed', 'normal', ?, ?)`,
|
|
727
744
|
).run(id, SEED.projectId, title, body, status, SEED.agentId, updatedAt, updatedAt);
|
|
745
|
+
db.query("UPDATE project_entries SET areas = ?, inject = ? WHERE id = ?").run('["db"]', "pinned", id);
|
|
728
746
|
}
|
|
729
747
|
}
|
package/src/db/read-ops.ts
CHANGED
|
@@ -63,6 +63,8 @@ import { ARTIFACTS_READ_OPS } from "./artifacts-read-ops.ts";
|
|
|
63
63
|
import { PLANS_READ_OPS } from "./plans-read-ops.ts";
|
|
64
64
|
import { CONTINUATION_ARCHIVES_READ_OPS } from "./continuation-archives-read-ops.ts";
|
|
65
65
|
import { WORKFLOW_JOURNAL_READ_OPS } from "./workflow-journal-read-ops.ts";
|
|
66
|
+
import { AUTOMATION_READ_OPS } from "./automation-read-ops.ts";
|
|
67
|
+
import { ISSUE_REFS_READ_OPS } from "./issue-refs-read-ops.ts";
|
|
66
68
|
import { PROJECTS_READ_OPS } from "./projects-read-ops.ts";
|
|
67
69
|
import { PROJECT_ENTRIES_READ_OPS } from "./project-entries-read-ops.ts";
|
|
68
70
|
import { CHANNELS_READ_OPS } from "./channels-read-ops.ts";
|
|
@@ -256,6 +258,8 @@ export const readOps = {
|
|
|
256
258
|
...WORKFLOW_JOURNAL_READ_OPS,
|
|
257
259
|
...PROJECTS_READ_OPS,
|
|
258
260
|
...PROJECT_ENTRIES_READ_OPS,
|
|
261
|
+
...AUTOMATION_READ_OPS,
|
|
262
|
+
...ISSUE_REFS_READ_OPS,
|
|
259
263
|
...CHANNELS_READ_OPS,
|
|
260
264
|
...INTEGRATIONS_READ_OPS,
|
|
261
265
|
} satisfies Record<string, ReadOpFn>;
|
package/src/db/retention.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getDb, getDbPath, runDbMaintenanceWorker } from "./connection.ts";
|
|
2
2
|
import { spawnProcessGoneSql } from "./spawn-process-evidence";
|
|
3
|
+
import { slimSpawnProfileChunk } from "./command-agent-profile-backfill";
|
|
3
4
|
|
|
4
5
|
export interface RetentionPruneInput {
|
|
5
6
|
messageCutoff: number;
|
|
@@ -13,6 +14,8 @@ export interface RetentionPruneResult {
|
|
|
13
14
|
prunedMessages: number;
|
|
14
15
|
prunedActivityEvents: number;
|
|
15
16
|
prunedSpawnCommands: number;
|
|
17
|
+
/** #3610 — legacy spawn rows whose inline agentProfile moved to the content-hash store. */
|
|
18
|
+
slimmedSpawnProfiles: number;
|
|
16
19
|
// #1758 — true when this run stopped on its batch-size cap or its wall-time budget with candidate
|
|
17
20
|
// rows still available in at least one table, i.e. it made bounded progress but did NOT drain the
|
|
18
21
|
// backlog. The scheduler uses it to record the run `succeeded` (not `failed`) and to reschedule the
|
|
@@ -325,11 +328,13 @@ export function pruneRetentionBatchOnDb(db: RetentionDb, input: RetentionPruneIn
|
|
|
325
328
|
const messages = pruneChunks(batchSize, deadlineAt, (limit) => messageChunk(db, input.messageCutoff, limit));
|
|
326
329
|
const activity = pruneChunks(batchSize, deadlineAt, (limit) => activityChunk(db, input.activityCutoff, activityHotSetBoundary, limit));
|
|
327
330
|
const spawnCommands = pruneChunks(batchSize, deadlineAt, (limit) => spawnCommandChunk(db, input.spawnCommandCutoff, limit));
|
|
331
|
+
const profiles = pruneChunks(batchSize, deadlineAt, (limit) => slimSpawnProfileChunk(db, limit));
|
|
328
332
|
return {
|
|
329
333
|
prunedMessages: messages.pruned,
|
|
330
334
|
prunedActivityEvents: activity.pruned,
|
|
331
335
|
prunedSpawnCommands: spawnCommands.pruned,
|
|
332
|
-
|
|
336
|
+
slimmedSpawnProfiles: profiles.pruned,
|
|
337
|
+
moreWork: messages.moreWork || activity.moreWork || spawnCommands.moreWork || profiles.moreWork,
|
|
333
338
|
};
|
|
334
339
|
}
|
|
335
340
|
|
|
@@ -362,10 +367,13 @@ export async function pruneRetentionBatchOnDbAsync(
|
|
|
362
367
|
const runMessages = (deadlineAt: number) => pruneChunksAsync(batchCap, deadlineAt, (limit) => messageChunk(db, input.messageCutoff, limit));
|
|
363
368
|
const runActivity = (deadlineAt: number) => pruneChunksAsync(batchCap, deadlineAt, (limit) => activityChunk(db, input.activityCutoff, activityHotSetBoundary, limit));
|
|
364
369
|
const runSpawn = (deadlineAt: number) => pruneChunksAsync(batchCap, deadlineAt, (limit) => spawnCommandChunk(db, input.spawnCommandCutoff, limit));
|
|
370
|
+
// After the deletes, so rows about to age out are never rewritten first.
|
|
371
|
+
const runProfiles = (deadlineAt: number) => pruneChunksAsync(batchCap, deadlineAt, (limit) => slimSpawnProfileChunk(db, limit));
|
|
365
372
|
|
|
366
373
|
let messages: { pruned: number; moreWork: boolean };
|
|
367
374
|
let activity: { pruned: number; moreWork: boolean };
|
|
368
375
|
let spawnCommands: { pruned: number; moreWork: boolean };
|
|
376
|
+
let profiles: { pruned: number; moreWork: boolean };
|
|
369
377
|
if (options.catchUp) {
|
|
370
378
|
// Cumulative per-table deadline checkpoints against one shared clock. With the batch cap unreachable,
|
|
371
379
|
// a single shared deadline would let a large `messages` backlog consume the whole budget before
|
|
@@ -377,6 +385,7 @@ export async function pruneRetentionBatchOnDbAsync(
|
|
|
377
385
|
const third = totalBudget / 3;
|
|
378
386
|
activity = await runActivity(start + third);
|
|
379
387
|
spawnCommands = await runSpawn(start + 2 * third);
|
|
388
|
+
profiles = await runProfiles(start + 2 * third);
|
|
380
389
|
messages = await runMessages(start + totalBudget);
|
|
381
390
|
} else {
|
|
382
391
|
// Inline-async fallback (:memory:): one shared deadline + the operator batch cap, unchanged.
|
|
@@ -384,12 +393,14 @@ export async function pruneRetentionBatchOnDbAsync(
|
|
|
384
393
|
messages = await runMessages(deadlineAt);
|
|
385
394
|
activity = await runActivity(deadlineAt);
|
|
386
395
|
spawnCommands = await runSpawn(deadlineAt);
|
|
396
|
+
profiles = await runProfiles(deadlineAt);
|
|
387
397
|
}
|
|
388
398
|
return {
|
|
389
399
|
prunedMessages: messages.pruned,
|
|
390
400
|
prunedActivityEvents: activity.pruned,
|
|
391
401
|
prunedSpawnCommands: spawnCommands.pruned,
|
|
392
|
-
|
|
402
|
+
slimmedSpawnProfiles: profiles.pruned,
|
|
403
|
+
moreWork: messages.moreWork || activity.moreWork || spawnCommands.moreWork || profiles.moreWork,
|
|
393
404
|
};
|
|
394
405
|
}
|
|
395
406
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { createCommandInternal, type CreateCommandWriteArgs } from "../commands-db";
|
|
2
|
+
import { upsertReviewRefCleanup } from "./review-ref-cleanups";
|
|
3
|
+
export type ReviewCleanupInput = Omit<Parameters<typeof upsertReviewRefCleanup>[0], "id">;
|
|
4
|
+
export function createReviewPublishBody(args: { command: CreateCommandWriteArgs; cleanup: ReviewCleanupInput }, now: number) {
|
|
5
|
+
const command = createCommandInternal(args.command, now);
|
|
6
|
+
upsertReviewRefCleanup({ ...args.cleanup, id: command.id });
|
|
7
|
+
return command;
|
|
8
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { getGateway } from "./gateway";
|
|
3
|
+
import { emitWorkspaceChange, emitWorkspaceCreate, type RecoveredWorkspaceInput } from "./workspaces";
|
|
4
|
+
import type { upsertWorkspaceRow } from "./workspaces";
|
|
5
|
+
import type { recoverWorkspaceBody, expireRuntimeCommands } from "./runtime-admin-write-ops";
|
|
6
|
+
|
|
7
|
+
export async function upsertWorkspaceAsync(input: Parameters<typeof upsertWorkspaceRow>[0]) {
|
|
8
|
+
const result = await getGateway().write("workspaces.upsertRow", input, { idempotencyKey: randomUUID() }) as unknown as ReturnType<typeof upsertWorkspaceRow>;
|
|
9
|
+
if (result.changed) emitWorkspaceChange(result.workspace);
|
|
10
|
+
return result.workspace;
|
|
11
|
+
}
|
|
12
|
+
export async function insertRecoveredWorkspaceAsync(input: RecoveredWorkspaceInput): Promise<ReturnType<typeof recoverWorkspaceBody>> {
|
|
13
|
+
const result = await getGateway().write("workspaces.recover", input, { idempotencyKey: randomUUID() }) as unknown as ReturnType<typeof recoverWorkspaceBody>;
|
|
14
|
+
if (result.created) { emitWorkspaceChange(result.workspace); emitWorkspaceCreate(result.workspace); }
|
|
15
|
+
return result;
|
|
16
|
+
}
|
|
17
|
+
export function expireCommandsAsync(now = Date.now()): Promise<ReturnType<typeof expireRuntimeCommands>> {
|
|
18
|
+
return getGateway().write("commands.expireRuntime", { now }, { idempotencyKey: randomUUID(), critical: true }) as unknown as Promise<ReturnType<typeof expireRuntimeCommands>>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createUserInvite, acceptUserInvite } from "./user-invites";
|
|
2
|
+
import { getAgent } from "./agents";
|
|
3
|
+
import { getWorkspace, upsertWorkspaceRow, type RecoveredWorkspaceInput } from "./workspaces";
|
|
4
|
+
import { expireCommands, updateCommandInternal, applyCommandUpdatePostCommit } from "../commands-db";
|
|
5
|
+
import { redactCommandSecrets } from "../command-secrets";
|
|
6
|
+
import type { Command } from "../types";
|
|
7
|
+
import type { WriterOpSpec } from "./write-ops";
|
|
8
|
+
|
|
9
|
+
export function recoverWorkspaceBody(input: RecoveredWorkspaceInput, now: number) {
|
|
10
|
+
const existing = getWorkspace(input.id);
|
|
11
|
+
if (existing) return { workspace: existing, created: false };
|
|
12
|
+
const result = upsertWorkspaceRow({ id: input.id, repoRoot: input.repoRoot, sourceCwd: input.sourceCwd, worktreePath: input.worktreePath,
|
|
13
|
+
branch: input.branch, baseRef: input.baseRef, baseSha: input.baseSha, mode: "isolated", status: "active", orchestratorId: input.orchestratorId,
|
|
14
|
+
ownerAgentId: input.ownerAgentId, metadata: { reregistered: true, ...input.landMetadata } }, now);
|
|
15
|
+
return { workspace: result.workspace, created: result.created };
|
|
16
|
+
}
|
|
17
|
+
export function expireRuntimeCommands(now: number) {
|
|
18
|
+
return expireCommands(now, {
|
|
19
|
+
isTargetGone: command => Boolean(command.target && command.target !== "system" && (!getAgent(command.target) || getAgent(command.target)!.status === "offline")),
|
|
20
|
+
update: (id, input, options) => {
|
|
21
|
+
const result = updateCommandInternal(id, input, options, now);
|
|
22
|
+
return applyCommandUpdatePostCommit(result.previousStatus, result.command);
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
export const RUNTIME_ADMIN_WRITE_OPS: Readonly<Record<string, WriterOpSpec>> = Object.freeze({
|
|
27
|
+
"userInvites.create": { offLoop: true, idempotent: false,
|
|
28
|
+
fn: (input: Parameters<typeof createUserInvite>[0], ctx) => createUserInvite({ ...input, now: input.now ?? ctx.now }),
|
|
29
|
+
// The invite code is a bearer credential returned once, like a token mint (#1870).
|
|
30
|
+
serializeIdempotencyResult: value => ({ invite: (value as ReturnType<typeof createUserInvite>).invite }) },
|
|
31
|
+
"userInvites.accept": { offLoop: true, idempotent: false, fn: (input: Parameters<typeof acceptUserInvite>[0], ctx) => acceptUserInvite({ ...input, now: input.now ?? ctx.now }) },
|
|
32
|
+
"workspaces.upsertRow": { offLoop: true, idempotent: false, fn: (input: Parameters<typeof upsertWorkspaceRow>[0], ctx) => upsertWorkspaceRow(input, ctx.now) },
|
|
33
|
+
"workspaces.recover": { offLoop: true, idempotent: false, fn: (input: RecoveredWorkspaceInput, ctx) => recoverWorkspaceBody(input, ctx.now) },
|
|
34
|
+
"commands.expireRuntime": { offLoop: true, idempotent: false, fn: (args: { now?: number }, ctx) => expireRuntimeCommands(args.now ?? ctx.now),
|
|
35
|
+
serializeIdempotencyResult: value => (value as Command[]).map(command => redactCommandSecrets(command)) },
|
|
36
|
+
});
|