@pellux/goodvibes-sdk 0.37.2 → 1.0.0
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/dist/contracts/artifacts/operator-contract.json +3171 -929
- package/dist/daemon.d.ts +2 -0
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +4 -0
- package/dist/events/communication.d.ts +21 -1
- package/dist/events/communication.d.ts.map +1 -1
- package/dist/events/surfaces.d.ts +25 -3
- package/dist/events/surfaces.d.ts.map +1 -1
- package/dist/events/surfaces.js +22 -1
- package/dist/events/workflows.d.ts +7 -6
- package/dist/events/workflows.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/platform/agents/archetypes.d.ts.map +1 -1
- package/dist/platform/agents/archetypes.js +7 -0
- package/dist/platform/agents/index.d.ts +1 -0
- package/dist/platform/agents/index.d.ts.map +1 -1
- package/dist/platform/agents/index.js +1 -0
- package/dist/platform/agents/message-bus-core.d.ts +7 -0
- package/dist/platform/agents/message-bus-core.d.ts.map +1 -1
- package/dist/platform/agents/message-bus-core.js +2 -1
- package/dist/platform/agents/orchestrator-runner.d.ts +50 -1
- package/dist/platform/agents/orchestrator-runner.d.ts.map +1 -1
- package/dist/platform/agents/orchestrator-runner.js +172 -7
- package/dist/platform/agents/orchestrator.d.ts +78 -6
- package/dist/platform/agents/orchestrator.d.ts.map +1 -1
- package/dist/platform/agents/orchestrator.js +95 -18
- package/dist/platform/agents/planner-decomposition-runner.d.ts +38 -0
- package/dist/platform/agents/planner-decomposition-runner.d.ts.map +1 -0
- package/dist/platform/agents/planner-decomposition-runner.js +113 -0
- package/dist/platform/agents/turn-knowledge-injection.d.ts +192 -0
- package/dist/platform/agents/turn-knowledge-injection.d.ts.map +1 -0
- package/dist/platform/agents/turn-knowledge-injection.js +269 -0
- package/dist/platform/agents/worktree.d.ts +126 -8
- package/dist/platform/agents/worktree.d.ts.map +1 -1
- package/dist/platform/agents/worktree.js +240 -19
- package/dist/platform/agents/wrfc-controller.d.ts +46 -0
- package/dist/platform/agents/wrfc-controller.d.ts.map +1 -1
- package/dist/platform/agents/wrfc-controller.js +213 -32
- package/dist/platform/agents/wrfc-gate-runtime.d.ts +9 -0
- package/dist/platform/agents/wrfc-gate-runtime.d.ts.map +1 -1
- package/dist/platform/agents/wrfc-gate-runtime.js +7 -3
- package/dist/platform/agents/wrfc-gates.d.ts +1 -1
- package/dist/platform/agents/wrfc-gates.d.ts.map +1 -1
- package/dist/platform/agents/wrfc-gates.js +7 -1
- package/dist/platform/agents/wrfc-types.d.ts +23 -3
- package/dist/platform/agents/wrfc-types.d.ts.map +1 -1
- package/dist/platform/automation/types.d.ts +9 -1
- package/dist/platform/automation/types.d.ts.map +1 -1
- package/dist/platform/calendar/calendar-api-shared.d.ts +25 -0
- package/dist/platform/calendar/calendar-api-shared.d.ts.map +1 -0
- package/dist/platform/calendar/calendar-api-shared.js +100 -0
- package/dist/platform/calendar/calendar-connector.d.ts +79 -0
- package/dist/platform/calendar/calendar-connector.d.ts.map +1 -0
- package/dist/platform/calendar/calendar-connector.js +155 -0
- package/dist/platform/calendar/google-calendar-api.d.ts +25 -0
- package/dist/platform/calendar/google-calendar-api.d.ts.map +1 -0
- package/dist/platform/calendar/google-calendar-api.js +89 -0
- package/dist/platform/calendar/http-fetch-adapter.d.ts +25 -0
- package/dist/platform/calendar/http-fetch-adapter.d.ts.map +1 -0
- package/dist/platform/calendar/http-fetch-adapter.js +25 -0
- package/dist/platform/calendar/ics-parser.d.ts +35 -0
- package/dist/platform/calendar/ics-parser.d.ts.map +1 -0
- package/dist/platform/calendar/ics-parser.js +236 -0
- package/dist/platform/calendar/index.d.ts +41 -0
- package/dist/platform/calendar/index.d.ts.map +1 -0
- package/dist/platform/calendar/index.js +49 -0
- package/dist/platform/calendar/merged-calendar-model.d.ts +67 -0
- package/dist/platform/calendar/merged-calendar-model.d.ts.map +1 -0
- package/dist/platform/calendar/merged-calendar-model.js +181 -0
- package/dist/platform/calendar/microsoft-graph-api.d.ts +25 -0
- package/dist/platform/calendar/microsoft-graph-api.d.ts.map +1 -0
- package/dist/platform/calendar/microsoft-graph-api.js +95 -0
- package/dist/platform/calendar/oauth-flow.d.ts +62 -0
- package/dist/platform/calendar/oauth-flow.d.ts.map +1 -0
- package/dist/platform/calendar/oauth-flow.js +305 -0
- package/dist/platform/calendar/oauth-providers.d.ts +43 -0
- package/dist/platform/calendar/oauth-providers.d.ts.map +1 -0
- package/dist/platform/calendar/oauth-providers.js +120 -0
- package/dist/platform/calendar/oauth-token-store.d.ts +72 -0
- package/dist/platform/calendar/oauth-token-store.d.ts.map +1 -0
- package/dist/platform/calendar/oauth-token-store.js +189 -0
- package/dist/platform/calendar/oauth-types.d.ts +274 -0
- package/dist/platform/calendar/oauth-types.d.ts.map +1 -0
- package/dist/platform/calendar/oauth-types.js +22 -0
- package/dist/platform/calendar/rrule.d.ts +39 -0
- package/dist/platform/calendar/rrule.d.ts.map +1 -0
- package/dist/platform/calendar/rrule.js +261 -0
- package/dist/platform/calendar/subscription-store.d.ts +118 -0
- package/dist/platform/calendar/subscription-store.d.ts.map +1 -0
- package/dist/platform/calendar/subscription-store.js +293 -0
- package/dist/platform/calendar/types.d.ts +170 -0
- package/dist/platform/calendar/types.d.ts.map +1 -0
- package/dist/platform/calendar/types.js +21 -0
- package/dist/platform/companion/companion-chat-attachments.d.ts +29 -0
- package/dist/platform/companion/companion-chat-attachments.d.ts.map +1 -0
- package/dist/platform/companion/companion-chat-attachments.js +121 -0
- package/dist/platform/companion/companion-chat-broker-bridge.d.ts +40 -0
- package/dist/platform/companion/companion-chat-broker-bridge.d.ts.map +1 -0
- package/dist/platform/companion/companion-chat-broker-bridge.js +14 -0
- package/dist/platform/companion/companion-chat-broker-sync.d.ts +38 -0
- package/dist/platform/companion/companion-chat-broker-sync.d.ts.map +1 -0
- package/dist/platform/companion/companion-chat-broker-sync.js +80 -0
- package/dist/platform/companion/companion-chat-gc.d.ts +63 -0
- package/dist/platform/companion/companion-chat-gc.d.ts.map +1 -0
- package/dist/platform/companion/companion-chat-gc.js +38 -0
- package/dist/platform/companion/companion-chat-manager.d.ts +67 -20
- package/dist/platform/companion/companion-chat-manager.d.ts.map +1 -1
- package/dist/platform/companion/companion-chat-manager.js +130 -144
- package/dist/platform/companion/companion-chat-persistence.d.ts +9 -1
- package/dist/platform/companion/companion-chat-persistence.d.ts.map +1 -1
- package/dist/platform/companion/companion-chat-persistence.js +10 -2
- package/dist/platform/companion/companion-chat-routes.d.ts +2 -1
- package/dist/platform/companion/companion-chat-routes.d.ts.map +1 -1
- package/dist/platform/companion/companion-chat-routes.js +37 -4
- package/dist/platform/config/credential-status.d.ts +28 -0
- package/dist/platform/config/credential-status.d.ts.map +1 -0
- package/dist/platform/config/credential-status.js +75 -0
- package/dist/platform/config/index.d.ts +25 -0
- package/dist/platform/config/index.d.ts.map +1 -1
- package/dist/platform/config/index.js +18 -0
- package/dist/platform/config/manager.d.ts +18 -0
- package/dist/platform/config/manager.d.ts.map +1 -1
- package/dist/platform/config/manager.js +36 -2
- package/dist/platform/config/migrations.d.ts +48 -0
- package/dist/platform/config/migrations.d.ts.map +1 -0
- package/dist/platform/config/migrations.js +54 -0
- package/dist/platform/config/schema-domain-core.d.ts +10 -1
- package/dist/platform/config/schema-domain-core.d.ts.map +1 -1
- package/dist/platform/config/schema-domain-core.js +46 -3
- package/dist/platform/config/schema-types.d.ts +13 -7
- package/dist/platform/config/schema-types.d.ts.map +1 -1
- package/dist/platform/config/schema.d.ts.map +1 -1
- package/dist/platform/config/schema.js +2 -0
- package/dist/platform/control-plane/approval-broker.d.ts +11 -0
- package/dist/platform/control-plane/approval-broker.d.ts.map +1 -1
- package/dist/platform/control-plane/approval-broker.js +17 -1
- package/dist/platform/control-plane/approval-hunk-apply.d.ts +77 -0
- package/dist/platform/control-plane/approval-hunk-apply.d.ts.map +1 -0
- package/dist/platform/control-plane/approval-hunk-apply.js +80 -0
- package/dist/platform/control-plane/gateway-disabled-response.d.ts +20 -0
- package/dist/platform/control-plane/gateway-disabled-response.d.ts.map +1 -0
- package/dist/platform/control-plane/gateway-disabled-response.js +24 -0
- package/dist/platform/control-plane/gateway-scope-enforcement.d.ts +68 -0
- package/dist/platform/control-plane/gateway-scope-enforcement.d.ts.map +1 -0
- package/dist/platform/control-plane/gateway-scope-enforcement.js +91 -0
- package/dist/platform/control-plane/gateway-utils.d.ts +17 -0
- package/dist/platform/control-plane/gateway-utils.d.ts.map +1 -1
- package/dist/platform/control-plane/gateway-utils.js +30 -0
- package/dist/platform/control-plane/gateway.d.ts +12 -2
- package/dist/platform/control-plane/gateway.d.ts.map +1 -1
- package/dist/platform/control-plane/gateway.js +27 -31
- package/dist/platform/control-plane/index.d.ts +6 -1
- package/dist/platform/control-plane/index.d.ts.map +1 -1
- package/dist/platform/control-plane/index.js +4 -0
- package/dist/platform/control-plane/invoke-input-validation.d.ts +56 -0
- package/dist/platform/control-plane/invoke-input-validation.d.ts.map +1 -0
- package/dist/platform/control-plane/invoke-input-validation.js +163 -0
- package/dist/platform/control-plane/method-catalog-admin.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog-admin.js +12 -1
- package/dist/platform/control-plane/method-catalog-calendar.d.ts +16 -0
- package/dist/platform/control-plane/method-catalog-calendar.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog-calendar.js +21 -0
- package/dist/platform/control-plane/method-catalog-channels.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog-channels.js +32 -3
- package/dist/platform/control-plane/method-catalog-control-automation.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog-control-automation.js +19 -34
- package/dist/platform/control-plane/method-catalog-control-companion.d.ts +15 -0
- package/dist/platform/control-plane/method-catalog-control-companion.d.ts.map +1 -0
- package/dist/platform/control-plane/method-catalog-control-companion.js +133 -0
- package/dist/platform/control-plane/method-catalog-control-core.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog-control-core.js +104 -122
- package/dist/platform/control-plane/method-catalog-control.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog-control.js +4 -0
- package/dist/platform/control-plane/method-catalog-email.d.ts +17 -0
- package/dist/platform/control-plane/method-catalog-email.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog-email.js +21 -0
- package/dist/platform/control-plane/method-catalog-events.d.ts +28 -0
- package/dist/platform/control-plane/method-catalog-events.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog-events.js +74 -1
- package/dist/platform/control-plane/method-catalog-fleet.d.ts +24 -0
- package/dist/platform/control-plane/method-catalog-fleet.d.ts.map +1 -0
- package/dist/platform/control-plane/method-catalog-fleet.js +65 -0
- package/dist/platform/control-plane/method-catalog-route-reconcile.d.ts +84 -0
- package/dist/platform/control-plane/method-catalog-route-reconcile.d.ts.map +1 -0
- package/dist/platform/control-plane/method-catalog-route-reconcile.js +103 -0
- package/dist/platform/control-plane/method-catalog-shared.d.ts +29 -0
- package/dist/platform/control-plane/method-catalog-shared.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog.d.ts +9 -0
- package/dist/platform/control-plane/method-catalog.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog.js +32 -3
- package/dist/platform/control-plane/operator-contract-schemas-admin.d.ts +8 -0
- package/dist/platform/control-plane/operator-contract-schemas-admin.d.ts.map +1 -1
- package/dist/platform/control-plane/operator-contract-schemas-admin.js +22 -1
- package/dist/platform/control-plane/operator-contract-schemas-fleet.d.ts +18 -0
- package/dist/platform/control-plane/operator-contract-schemas-fleet.d.ts.map +1 -0
- package/dist/platform/control-plane/operator-contract-schemas-fleet.js +182 -0
- package/dist/platform/control-plane/operator-contract-schemas-permissions.d.ts.map +1 -1
- package/dist/platform/control-plane/operator-contract-schemas-permissions.js +5 -0
- package/dist/platform/control-plane/operator-contract-schemas-runtime.d.ts +29 -0
- package/dist/platform/control-plane/operator-contract-schemas-runtime.d.ts.map +1 -1
- package/dist/platform/control-plane/operator-contract-schemas-runtime.js +57 -3
- package/dist/platform/control-plane/operator-contract-schemas.d.ts +1 -0
- package/dist/platform/control-plane/operator-contract-schemas.d.ts.map +1 -1
- package/dist/platform/control-plane/operator-contract-schemas.js +1 -0
- package/dist/platform/control-plane/operator-contract.d.ts.map +1 -1
- package/dist/platform/control-plane/operator-contract.js +8 -0
- package/dist/platform/control-plane/routes/checkpoints.d.ts +39 -0
- package/dist/platform/control-plane/routes/checkpoints.d.ts.map +1 -0
- package/dist/platform/control-plane/routes/checkpoints.js +166 -0
- package/dist/platform/control-plane/routes/fleet.d.ts +53 -0
- package/dist/platform/control-plane/routes/fleet.d.ts.map +1 -0
- package/dist/platform/control-plane/routes/fleet.js +153 -0
- package/dist/platform/control-plane/routes/gateway-verb-error.d.ts +30 -0
- package/dist/platform/control-plane/routes/gateway-verb-error.d.ts.map +1 -0
- package/dist/platform/control-plane/routes/gateway-verb-error.js +36 -0
- package/dist/platform/control-plane/routes/index.d.ts +0 -6
- package/dist/platform/control-plane/routes/index.d.ts.map +1 -1
- package/dist/platform/control-plane/routes/index.js +5 -5
- package/dist/platform/control-plane/routes/invocation-params.d.ts +23 -0
- package/dist/platform/control-plane/routes/invocation-params.d.ts.map +1 -0
- package/dist/platform/control-plane/routes/invocation-params.js +9 -0
- package/dist/platform/control-plane/routes/register-w3-s2.d.ts +26 -0
- package/dist/platform/control-plane/routes/register-w3-s2.d.ts.map +1 -0
- package/dist/platform/control-plane/routes/register-w3-s2.js +8 -0
- package/dist/platform/control-plane/routes/session-search.d.ts +37 -0
- package/dist/platform/control-plane/routes/session-search.d.ts.map +1 -0
- package/dist/platform/control-plane/routes/session-search.js +113 -0
- package/dist/platform/control-plane/session-broker-gc.d.ts +16 -0
- package/dist/platform/control-plane/session-broker-gc.d.ts.map +1 -1
- package/dist/platform/control-plane/session-broker-gc.js +23 -6
- package/dist/platform/control-plane/session-broker-helpers.d.ts +3 -3
- package/dist/platform/control-plane/session-broker-helpers.d.ts.map +1 -1
- package/dist/platform/control-plane/session-broker-inputs.d.ts +18 -0
- package/dist/platform/control-plane/session-broker-inputs.d.ts.map +1 -1
- package/dist/platform/control-plane/session-broker-inputs.js +34 -0
- package/dist/platform/control-plane/session-broker-sessions.d.ts +102 -3
- package/dist/platform/control-plane/session-broker-sessions.d.ts.map +1 -1
- package/dist/platform/control-plane/session-broker-sessions.js +179 -5
- package/dist/platform/control-plane/session-broker-state.d.ts +20 -1
- package/dist/platform/control-plane/session-broker-state.d.ts.map +1 -1
- package/dist/platform/control-plane/session-broker-state.js +67 -5
- package/dist/platform/control-plane/session-broker.d.ts +51 -38
- package/dist/platform/control-plane/session-broker.d.ts.map +1 -1
- package/dist/platform/control-plane/session-broker.js +183 -75
- package/dist/platform/control-plane/session-store-importer.d.ts +57 -0
- package/dist/platform/control-plane/session-store-importer.d.ts.map +1 -0
- package/dist/platform/control-plane/session-store-importer.js +227 -0
- package/dist/platform/control-plane/session-types.d.ts +142 -7
- package/dist/platform/control-plane/session-types.d.ts.map +1 -1
- package/dist/platform/core/adaptive-planner.d.ts +50 -0
- package/dist/platform/core/adaptive-planner.d.ts.map +1 -1
- package/dist/platform/core/adaptive-planner.js +49 -0
- package/dist/platform/core/execution-plan.d.ts +43 -1
- package/dist/platform/core/execution-plan.d.ts.map +1 -1
- package/dist/platform/core/execution-plan.js +46 -10
- package/dist/platform/core/index.d.ts +2 -0
- package/dist/platform/core/index.d.ts.map +1 -1
- package/dist/platform/core/index.js +2 -0
- package/dist/platform/core/orchestrator-runtime.d.ts +31 -0
- package/dist/platform/core/orchestrator-runtime.d.ts.map +1 -1
- package/dist/platform/core/orchestrator-tool-runtime.d.ts +7 -0
- package/dist/platform/core/orchestrator-tool-runtime.d.ts.map +1 -1
- package/dist/platform/core/orchestrator-tool-runtime.js +10 -0
- package/dist/platform/core/orchestrator-turn-loop.d.ts +35 -1
- package/dist/platform/core/orchestrator-turn-loop.d.ts.map +1 -1
- package/dist/platform/core/orchestrator-turn-loop.js +121 -3
- package/dist/platform/core/orchestrator.d.ts +67 -0
- package/dist/platform/core/orchestrator.d.ts.map +1 -1
- package/dist/platform/core/orchestrator.js +89 -1
- package/dist/platform/core/plan-decomposition.d.ts +196 -0
- package/dist/platform/core/plan-decomposition.d.ts.map +1 -0
- package/dist/platform/core/plan-decomposition.js +417 -0
- package/dist/platform/core/plan-proposal.d.ts +204 -0
- package/dist/platform/core/plan-proposal.d.ts.map +1 -0
- package/dist/platform/core/plan-proposal.js +296 -0
- package/dist/platform/core/wrfc-routing.d.ts +1 -0
- package/dist/platform/core/wrfc-routing.d.ts.map +1 -1
- package/dist/platform/core/wrfc-routing.js +51 -1
- package/dist/platform/daemon/boot.d.ts +63 -0
- package/dist/platform/daemon/boot.d.ts.map +1 -0
- package/dist/platform/daemon/boot.js +60 -0
- package/dist/platform/daemon/cli.js +2 -1
- package/dist/platform/daemon/control-plane.d.ts.map +1 -1
- package/dist/platform/daemon/control-plane.js +50 -1
- package/dist/platform/daemon/facade-composition.d.ts.map +1 -1
- package/dist/platform/daemon/facade-composition.js +6 -0
- package/dist/platform/daemon/facade.d.ts +18 -6
- package/dist/platform/daemon/facade.d.ts.map +1 -1
- package/dist/platform/daemon/facade.js +50 -43
- package/dist/platform/daemon/http/router-route-contexts.d.ts +1 -0
- package/dist/platform/daemon/http/router-route-contexts.d.ts.map +1 -1
- package/dist/platform/daemon/http/router-route-contexts.js +1 -0
- package/dist/platform/daemon/http/router-session-broker-adapter.d.ts +13 -0
- package/dist/platform/daemon/http/router-session-broker-adapter.d.ts.map +1 -0
- package/dist/platform/daemon/http/router-session-broker-adapter.js +27 -0
- package/dist/platform/daemon/http/router.d.ts +1 -1
- package/dist/platform/daemon/http/router.d.ts.map +1 -1
- package/dist/platform/daemon/http/router.js +7 -22
- package/dist/platform/daemon/http/runtime-route-types.d.ts +42 -4
- package/dist/platform/daemon/http/runtime-route-types.d.ts.map +1 -1
- package/dist/platform/daemon/index.d.ts +2 -0
- package/dist/platform/daemon/index.d.ts.map +1 -1
- package/dist/platform/daemon/index.js +1 -0
- package/dist/platform/daemon/service-manager.d.ts +16 -0
- package/dist/platform/daemon/service-manager.d.ts.map +1 -1
- package/dist/platform/daemon/service-manager.js +79 -15
- package/dist/platform/intelligence/tree-sitter/service.d.ts.map +1 -1
- package/dist/platform/intelligence/tree-sitter/service.js +16 -2
- package/dist/platform/knowledge/browser-history/readers.d.ts.map +1 -1
- package/dist/platform/knowledge/browser-history/readers.js +15 -5
- package/dist/platform/knowledge/knowledge-api.d.ts +26 -0
- package/dist/platform/knowledge/knowledge-api.d.ts.map +1 -1
- package/dist/platform/knowledge/knowledge-api.js +11 -0
- package/dist/platform/knowledge/project-planning/service.d.ts +14 -1
- package/dist/platform/knowledge/project-planning/service.d.ts.map +1 -1
- package/dist/platform/knowledge/project-planning/service.js +77 -0
- package/dist/platform/knowledge/project-planning/types.d.ts +32 -0
- package/dist/platform/knowledge/project-planning/types.d.ts.map +1 -1
- package/dist/platform/orchestration/bookkeeping.d.ts +12 -0
- package/dist/platform/orchestration/bookkeeping.d.ts.map +1 -0
- package/dist/platform/orchestration/bookkeeping.js +91 -0
- package/dist/platform/orchestration/budget.d.ts +22 -0
- package/dist/platform/orchestration/budget.d.ts.map +1 -0
- package/dist/platform/orchestration/budget.js +35 -0
- package/dist/platform/orchestration/cancellation.d.ts +31 -0
- package/dist/platform/orchestration/cancellation.d.ts.map +1 -0
- package/dist/platform/orchestration/cancellation.js +25 -0
- package/dist/platform/orchestration/controller-compat.d.ts +46 -0
- package/dist/platform/orchestration/controller-compat.d.ts.map +1 -0
- package/dist/platform/orchestration/controller-compat.js +27 -0
- package/dist/platform/orchestration/dirty-guard.d.ts +32 -0
- package/dist/platform/orchestration/dirty-guard.d.ts.map +1 -0
- package/dist/platform/orchestration/dirty-guard.js +147 -0
- package/dist/platform/orchestration/engine.d.ts +82 -0
- package/dist/platform/orchestration/engine.d.ts.map +1 -0
- package/dist/platform/orchestration/engine.js +623 -0
- package/dist/platform/orchestration/index.d.ts +20 -0
- package/dist/platform/orchestration/index.d.ts.map +1 -0
- package/dist/platform/orchestration/index.js +11 -0
- package/dist/platform/orchestration/persistence.d.ts +24 -0
- package/dist/platform/orchestration/persistence.d.ts.map +1 -0
- package/dist/platform/orchestration/persistence.js +179 -0
- package/dist/platform/orchestration/phase-runner.d.ts +114 -0
- package/dist/platform/orchestration/phase-runner.d.ts.map +1 -0
- package/dist/platform/orchestration/phase-runner.js +347 -0
- package/dist/platform/orchestration/proposal-workstream.d.ts +56 -0
- package/dist/platform/orchestration/proposal-workstream.d.ts.map +1 -0
- package/dist/platform/orchestration/proposal-workstream.js +76 -0
- package/dist/platform/orchestration/scheduler.d.ts +64 -0
- package/dist/platform/orchestration/scheduler.d.ts.map +1 -0
- package/dist/platform/orchestration/scheduler.js +73 -0
- package/dist/platform/orchestration/types.d.ts +535 -0
- package/dist/platform/orchestration/types.d.ts.map +1 -0
- package/dist/platform/orchestration/types.js +47 -0
- package/dist/platform/orchestration/worktree-isolation.d.ts +33 -0
- package/dist/platform/orchestration/worktree-isolation.d.ts.map +1 -0
- package/dist/platform/orchestration/worktree-isolation.js +248 -0
- package/dist/platform/presentation/glyphs.d.ts +91 -0
- package/dist/platform/presentation/glyphs.d.ts.map +1 -0
- package/dist/platform/presentation/glyphs.js +93 -0
- package/dist/platform/presentation/index.d.ts +28 -0
- package/dist/platform/presentation/index.d.ts.map +1 -0
- package/dist/platform/presentation/index.js +27 -0
- package/dist/platform/presentation/thinking-phrases.d.ts +12 -0
- package/dist/platform/presentation/thinking-phrases.d.ts.map +1 -0
- package/dist/platform/presentation/thinking-phrases.js +32 -0
- package/dist/platform/presentation/tones.d.ts +121 -0
- package/dist/platform/presentation/tones.d.ts.map +1 -0
- package/dist/platform/presentation/tones.js +145 -0
- package/dist/platform/presentation/waiting-wording.d.ts +54 -0
- package/dist/platform/presentation/waiting-wording.d.ts.map +1 -0
- package/dist/platform/presentation/waiting-wording.js +51 -0
- package/dist/platform/providers/runtime-snapshot.d.ts.map +1 -1
- package/dist/platform/providers/runtime-snapshot.js +12 -2
- package/dist/platform/runtime/bootstrap-services.d.ts +62 -2
- package/dist/platform/runtime/bootstrap-services.d.ts.map +1 -1
- package/dist/platform/runtime/bootstrap-services.js +217 -50
- package/dist/platform/runtime/daemon-version-compat.d.ts +39 -0
- package/dist/platform/runtime/daemon-version-compat.d.ts.map +1 -0
- package/dist/platform/runtime/daemon-version-compat.js +75 -0
- package/dist/platform/runtime/detached-daemon-runtime.d.ts +26 -0
- package/dist/platform/runtime/detached-daemon-runtime.d.ts.map +1 -0
- package/dist/platform/runtime/detached-daemon-runtime.js +49 -0
- package/dist/platform/runtime/emitters/communication.d.ts +11 -0
- package/dist/platform/runtime/emitters/communication.d.ts.map +1 -1
- package/dist/platform/runtime/emitters/communication.js +9 -0
- package/dist/platform/runtime/emitters/workflows.d.ts +1 -1
- package/dist/platform/runtime/emitters/workflows.d.ts.map +1 -1
- package/dist/platform/runtime/events/index.d.ts +13 -0
- package/dist/platform/runtime/events/index.d.ts.map +1 -1
- package/dist/platform/runtime/events/index.js +13 -0
- package/dist/platform/runtime/feature-flags/flags.d.ts.map +1 -1
- package/dist/platform/runtime/feature-flags/flags.js +56 -1
- package/dist/platform/runtime/fleet/adapters/agent.d.ts +56 -0
- package/dist/platform/runtime/fleet/adapters/agent.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/adapters/agent.js +143 -0
- package/dist/platform/runtime/fleet/adapters/automation.d.ts +30 -0
- package/dist/platform/runtime/fleet/adapters/automation.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/adapters/automation.js +41 -0
- package/dist/platform/runtime/fleet/adapters/background-process.d.ts +12 -0
- package/dist/platform/runtime/fleet/adapters/background-process.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/adapters/background-process.js +46 -0
- package/dist/platform/runtime/fleet/adapters/code-index.d.ts +21 -0
- package/dist/platform/runtime/fleet/adapters/code-index.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/adapters/code-index.js +44 -0
- package/dist/platform/runtime/fleet/adapters/orchestration.d.ts +69 -0
- package/dist/platform/runtime/fleet/adapters/orchestration.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/adapters/orchestration.js +329 -0
- package/dist/platform/runtime/fleet/adapters/schedule.d.ts +14 -0
- package/dist/platform/runtime/fleet/adapters/schedule.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/adapters/schedule.js +28 -0
- package/dist/platform/runtime/fleet/adapters/trigger.d.ts +12 -0
- package/dist/platform/runtime/fleet/adapters/trigger.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/adapters/trigger.js +22 -0
- package/dist/platform/runtime/fleet/adapters/watcher.d.ts +13 -0
- package/dist/platform/runtime/fleet/adapters/watcher.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/adapters/watcher.js +47 -0
- package/dist/platform/runtime/fleet/adapters/workflow.d.ts +11 -0
- package/dist/platform/runtime/fleet/adapters/workflow.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/adapters/workflow.js +34 -0
- package/dist/platform/runtime/fleet/adapters/wrfc.d.ts +35 -0
- package/dist/platform/runtime/fleet/adapters/wrfc.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/adapters/wrfc.js +275 -0
- package/dist/platform/runtime/fleet/index.d.ts +10 -0
- package/dist/platform/runtime/fleet/index.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/index.js +6 -0
- package/dist/platform/runtime/fleet/registry.d.ts +113 -0
- package/dist/platform/runtime/fleet/registry.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/registry.js +664 -0
- package/dist/platform/runtime/fleet/types.d.ts +199 -0
- package/dist/platform/runtime/fleet/types.d.ts.map +1 -0
- package/dist/platform/runtime/fleet/types.js +2 -0
- package/dist/platform/runtime/operator-client.d.ts +20 -2
- package/dist/platform/runtime/operator-client.d.ts.map +1 -1
- package/dist/platform/runtime/operator-client.js +11 -1
- package/dist/platform/runtime/provider-accounts/registry.d.ts.map +1 -1
- package/dist/platform/runtime/provider-accounts/registry.js +11 -1
- package/dist/platform/runtime/runtime-knowledge-api.d.ts +1 -1
- package/dist/platform/runtime/runtime-knowledge-api.d.ts.map +1 -1
- package/dist/platform/runtime/runtime-knowledge-api.js +1 -0
- package/dist/platform/runtime/services.d.ts +48 -0
- package/dist/platform/runtime/services.d.ts.map +1 -1
- package/dist/platform/runtime/services.js +95 -2
- package/dist/platform/runtime/session-spine/client.d.ts +234 -0
- package/dist/platform/runtime/session-spine/client.d.ts.map +1 -0
- package/dist/platform/runtime/session-spine/client.js +449 -0
- package/dist/platform/runtime/session-spine/index.d.ts +12 -0
- package/dist/platform/runtime/session-spine/index.d.ts.map +1 -0
- package/dist/platform/runtime/session-spine/index.js +11 -0
- package/dist/platform/runtime/session-spine/union-cache.d.ts +225 -0
- package/dist/platform/runtime/session-spine/union-cache.d.ts.map +1 -0
- package/dist/platform/runtime/session-spine/union-cache.js +333 -0
- package/dist/platform/runtime/shell-command-ops.d.ts +3 -1
- package/dist/platform/runtime/shell-command-ops.d.ts.map +1 -1
- package/dist/platform/runtime/transports/daemon-http-client-validators.d.ts.map +1 -1
- package/dist/platform/runtime/transports/daemon-http-client-validators.js +22 -0
- package/dist/platform/runtime/transports/daemon-http-client.d.ts.map +1 -1
- package/dist/platform/runtime/transports/daemon-http-client.js +25 -2
- package/dist/platform/runtime/transports/http-types.d.ts +9 -2
- package/dist/platform/runtime/transports/http-types.d.ts.map +1 -1
- package/dist/platform/state/canonical-memory.d.ts +95 -0
- package/dist/platform/state/canonical-memory.d.ts.map +1 -0
- package/dist/platform/state/canonical-memory.js +155 -0
- package/dist/platform/state/code-index-chunking.d.ts +49 -0
- package/dist/platform/state/code-index-chunking.d.ts.map +1 -0
- package/dist/platform/state/code-index-chunking.js +111 -0
- package/dist/platform/state/code-index-db.d.ts +53 -0
- package/dist/platform/state/code-index-db.d.ts.map +1 -0
- package/dist/platform/state/code-index-db.js +101 -0
- package/dist/platform/state/code-index-reindex.d.ts +73 -0
- package/dist/platform/state/code-index-reindex.d.ts.map +1 -0
- package/dist/platform/state/code-index-reindex.js +156 -0
- package/dist/platform/state/code-index-store.d.ts +175 -0
- package/dist/platform/state/code-index-store.d.ts.map +1 -0
- package/dist/platform/state/code-index-store.js +620 -0
- package/dist/platform/state/index.d.ts +12 -2
- package/dist/platform/state/index.d.ts.map +1 -1
- package/dist/platform/state/index.js +6 -1
- package/dist/platform/state/knowledge-injection.d.ts +23 -0
- package/dist/platform/state/knowledge-injection.d.ts.map +1 -1
- package/dist/platform/state/knowledge-injection.js +34 -19
- package/dist/platform/state/memory-recall-contract.d.ts +63 -0
- package/dist/platform/state/memory-recall-contract.d.ts.map +1 -0
- package/dist/platform/state/memory-recall-contract.js +94 -0
- package/dist/platform/state/memory-store.d.ts +2 -0
- package/dist/platform/state/memory-store.d.ts.map +1 -1
- package/dist/platform/state/memory-store.js +4 -0
- package/dist/platform/state/memory-vector-store.d.ts +1 -13
- package/dist/platform/state/memory-vector-store.d.ts.map +1 -1
- package/dist/platform/state/memory-vector-store.js +18 -39
- package/dist/platform/state/sqlite-store.d.ts +2 -0
- package/dist/platform/state/sqlite-store.d.ts.map +1 -1
- package/dist/platform/state/sqlite-store.js +4 -0
- package/dist/platform/state/sqlite-vec-loader.d.ts +25 -0
- package/dist/platform/state/sqlite-vec-loader.d.ts.map +1 -0
- package/dist/platform/state/sqlite-vec-loader.js +43 -0
- package/dist/platform/state/vibe-projection.d.ts +67 -0
- package/dist/platform/state/vibe-projection.d.ts.map +1 -0
- package/dist/platform/state/vibe-projection.js +115 -0
- package/dist/platform/tools/agent/index.d.ts.map +1 -1
- package/dist/platform/tools/agent/index.js +8 -0
- package/dist/platform/tools/agent/manager.d.ts +140 -1
- package/dist/platform/tools/agent/manager.d.ts.map +1 -1
- package/dist/platform/tools/agent/manager.js +143 -1
- package/dist/platform/tools/agent/schema.d.ts +26 -0
- package/dist/platform/tools/agent/schema.d.ts.map +1 -1
- package/dist/platform/tools/agent/schema.js +2 -2
- package/dist/platform/tools/agent/wrfc-batch-policy.d.ts +13 -0
- package/dist/platform/tools/agent/wrfc-batch-policy.d.ts.map +1 -1
- package/dist/platform/tools/agent/wrfc-batch-policy.js +60 -0
- package/dist/platform/tools/exec/runtime.d.ts +10 -0
- package/dist/platform/tools/exec/runtime.d.ts.map +1 -1
- package/dist/platform/tools/exec/runtime.js +161 -49
- package/dist/platform/tools/exec/schema.d.ts +3 -1
- package/dist/platform/tools/exec/schema.d.ts.map +1 -1
- package/dist/platform/tools/exec/schema.js +2 -1
- package/dist/platform/tools/fetch/runtime.d.ts +7 -0
- package/dist/platform/tools/fetch/runtime.d.ts.map +1 -1
- package/dist/platform/tools/fetch/runtime.js +8 -6
- package/dist/platform/tools/index.d.ts +2 -0
- package/dist/platform/tools/index.d.ts.map +1 -1
- package/dist/platform/tools/index.js +2 -0
- package/dist/platform/tools/registry.d.ts +9 -3
- package/dist/platform/tools/registry.d.ts.map +1 -1
- package/dist/platform/tools/registry.js +9 -3
- package/dist/platform/tools/state/index.d.ts +9 -0
- package/dist/platform/tools/state/index.d.ts.map +1 -1
- package/dist/platform/tools/state/index.js +60 -3
- package/dist/platform/types/foundation-contract.d.ts +1 -1
- package/dist/platform/types/foundation-contract.d.ts.map +1 -1
- package/dist/platform/types/index.d.ts +1 -1
- package/dist/platform/types/index.d.ts.map +1 -1
- package/dist/platform/types/tools.d.ts +14 -1
- package/dist/platform/types/tools.d.ts.map +1 -1
- package/dist/platform/version.js +1 -1
- package/package.json +29 -9
- package/dist/platform/control-plane/routes/automation.d.ts +0 -3
- package/dist/platform/control-plane/routes/automation.d.ts.map +0 -1
- package/dist/platform/control-plane/routes/automation.js +0 -63
- package/dist/platform/control-plane/routes/context.d.ts +0 -2
- package/dist/platform/control-plane/routes/context.d.ts.map +0 -1
- package/dist/platform/control-plane/routes/context.js +0 -1
- package/dist/platform/control-plane/routes/operator.d.ts +0 -8
- package/dist/platform/control-plane/routes/operator.d.ts.map +0 -1
- package/dist/platform/control-plane/routes/operator.js +0 -415
- package/dist/platform/control-plane/routes/remote.d.ts +0 -3
- package/dist/platform/control-plane/routes/remote.d.ts.map +0 -1
- package/dist/platform/control-plane/routes/remote.js +0 -35
- package/dist/platform/control-plane/routes/sessions.d.ts +0 -3
- package/dist/platform/control-plane/routes/sessions.d.ts.map +0 -1
- package/dist/platform/control-plane/routes/sessions.js +0 -43
- package/dist/platform/control-plane/routes/tasks.d.ts +0 -3
- package/dist/platform/control-plane/routes/tasks.d.ts.map +0 -1
- package/dist/platform/control-plane/routes/tasks.js +0 -22
|
@@ -0,0 +1,623 @@
|
|
|
1
|
+
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
|
+
/**
|
|
3
|
+
* OrchestrationEngine (Wave 4, wo701) — owns Workstream state and drives the
|
|
4
|
+
* pipeline. WRAPS a canned/authored workstream; does not rewrite or touch
|
|
5
|
+
* WrfcController (stage 1 of the 3-stage migration — see controller-compat.ts
|
|
6
|
+
* and the work-order report).
|
|
7
|
+
*
|
|
8
|
+
* The tick loop is reactive, not timer-driven: `start()` runs one tick;
|
|
9
|
+
* every phase-run completion re-runs tick() for its workstream. Because JS
|
|
10
|
+
* is single-threaded, computeClaims()'s synchronous read of in-flight counts
|
|
11
|
+
* is never racing a concurrent claim — items are marked 'in-phase'
|
|
12
|
+
* synchronously before any `await` inside the claim loop, so a re-entrant
|
|
13
|
+
* tick() (triggered by an earlier completion resolving on a later turn of
|
|
14
|
+
* the microtask queue) always sees up-to-date state.
|
|
15
|
+
*/
|
|
16
|
+
import { checkBudget } from './budget.js';
|
|
17
|
+
import { createCancellationRegistry } from './cancellation.js';
|
|
18
|
+
import { runPhase } from './phase-runner.js';
|
|
19
|
+
import { snapshotDirtyTree } from './dirty-guard.js';
|
|
20
|
+
import { createWorktreeIsolationManager } from './worktree-isolation.js';
|
|
21
|
+
import { deserializeWorkstream as deserializeWorkstreamModel, deserializeWorkstreamSnapshot, attachDebouncedWriter, listSnapshotWorkstreamIds, loadWorkstreamSnapshot, serializeWorkstreamSnapshot, } from './persistence.js';
|
|
22
|
+
import { computeClaims, dependencyStatus, firstPhase, nextPhaseAfter, reviewPhaseBefore, sortedPhases } from './scheduler.js';
|
|
23
|
+
import { CURRENT_WORKSTREAM_SCHEMA_VERSION, emptyWorkItemUsage, mergeWorkItemUsage, } from './types.js';
|
|
24
|
+
import { logger } from '../utils/logger.js';
|
|
25
|
+
import { summarizeError } from '../utils/error-display.js';
|
|
26
|
+
function generateId(prefix) {
|
|
27
|
+
return `${prefix}-${crypto.randomUUID().slice(0, 8)}`;
|
|
28
|
+
}
|
|
29
|
+
export function createOrchestrationEngine(deps) {
|
|
30
|
+
const now = deps.now ?? (() => Date.now());
|
|
31
|
+
const sessionId = deps.sessionId ?? crypto.randomUUID().slice(0, 8);
|
|
32
|
+
const maxPhaseVisits = deps.maxPhaseVisits ?? 5;
|
|
33
|
+
const workstreams = new Map();
|
|
34
|
+
const completedResults = new Map();
|
|
35
|
+
const cancellation = createCancellationRegistry();
|
|
36
|
+
const listeners = new Set();
|
|
37
|
+
let disposed = false;
|
|
38
|
+
function emit(event) {
|
|
39
|
+
for (const listener of listeners) {
|
|
40
|
+
try {
|
|
41
|
+
listener(event);
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
logger.warn('orchestration engine: listener threw', { error: summarizeError(error) });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function on(listener) {
|
|
49
|
+
listeners.add(listener);
|
|
50
|
+
return () => listeners.delete(listener);
|
|
51
|
+
}
|
|
52
|
+
// Dirty-residue guard (Wave 6, wo-F item 4): snapshot the working tree's
|
|
53
|
+
// dirty paths + content hashes ONCE, right at engine launch (synchronous —
|
|
54
|
+
// see dirty-guard.ts's doc comment for why this must not be a promise
|
|
55
|
+
// backed by real subprocess I/O), before any phase of this run has had a
|
|
56
|
+
// chance to touch anything. A previously killed run sharing this same
|
|
57
|
+
// projectRoot can leave uncommitted residue behind; this snapshot is what
|
|
58
|
+
// lets a later scoped commit tell "residue from before this run" apart
|
|
59
|
+
// from "this run's own changes" (see dirty-guard.ts and phase-runner.ts's
|
|
60
|
+
// commitPhaseWork).
|
|
61
|
+
const launchDirtySnapshot = snapshotDirtyTree(deps.projectRoot);
|
|
62
|
+
if (launchDirtySnapshot.size > 0) {
|
|
63
|
+
emit({ type: 'dirty-tree-at-launch', paths: [...launchDirtySnapshot.keys()] });
|
|
64
|
+
}
|
|
65
|
+
// Worktree-isolation lane (only ever exercised by a workstream created with
|
|
66
|
+
// isolation: 'worktree' — see createWorkstream/runItemPhase/failItem below).
|
|
67
|
+
// Constructing this unconditionally is cheap: it does no I/O until a
|
|
68
|
+
// worktree-mode workstream actually calls into it.
|
|
69
|
+
const worktreeIsolation = createWorktreeIsolationManager({
|
|
70
|
+
projectRoot: deps.projectRoot,
|
|
71
|
+
emit,
|
|
72
|
+
now,
|
|
73
|
+
keptWorktreeCap: deps.keptWorktreeCap,
|
|
74
|
+
});
|
|
75
|
+
function getWorkstream(id) {
|
|
76
|
+
return workstreams.get(id) ?? null;
|
|
77
|
+
}
|
|
78
|
+
function listWorkstreams() {
|
|
79
|
+
return Array.from(workstreams.values());
|
|
80
|
+
}
|
|
81
|
+
function getPhaseResults(workstreamId) {
|
|
82
|
+
return completedResults.get(workstreamId) ?? [];
|
|
83
|
+
}
|
|
84
|
+
const unsubscribeWriter = deps.persist === false
|
|
85
|
+
? () => undefined
|
|
86
|
+
: attachDebouncedWriter(deps.projectRoot, getWorkstream, getPhaseResults, on);
|
|
87
|
+
function buildPhase(spec, ordinal, insertedAt) {
|
|
88
|
+
return {
|
|
89
|
+
id: spec.id ?? generateId('phase'),
|
|
90
|
+
ordinal,
|
|
91
|
+
role: spec.role,
|
|
92
|
+
capacity: spec.capacity,
|
|
93
|
+
gate: spec.gate,
|
|
94
|
+
kind: spec.kind,
|
|
95
|
+
...(insertedAt !== undefined ? { insertedAt } : {}),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function buildItem(spec, startPhaseId) {
|
|
99
|
+
return {
|
|
100
|
+
id: spec.id ?? generateId('item'),
|
|
101
|
+
title: spec.title,
|
|
102
|
+
task: spec.task,
|
|
103
|
+
dependsOn: spec.dependsOn ? [...spec.dependsOn] : [],
|
|
104
|
+
currentPhaseId: startPhaseId,
|
|
105
|
+
state: startPhaseId ? 'pending' : 'passed',
|
|
106
|
+
allAgentIds: [],
|
|
107
|
+
visits: new Map(),
|
|
108
|
+
touchedPaths: [],
|
|
109
|
+
usage: emptyWorkItemUsage(),
|
|
110
|
+
transportRetryCount: 0,
|
|
111
|
+
createdAt: now(),
|
|
112
|
+
...(startPhaseId ? {} : { completedAt: now() }),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function createWorkstream(input) {
|
|
116
|
+
const phases = input.phases.map((spec, index) => buildPhase(spec, index + 1));
|
|
117
|
+
const workstream = {
|
|
118
|
+
id: input.id ?? generateId('ws'),
|
|
119
|
+
title: input.title,
|
|
120
|
+
schemaVersion: CURRENT_WORKSTREAM_SCHEMA_VERSION,
|
|
121
|
+
phases,
|
|
122
|
+
items: [],
|
|
123
|
+
budget: input.budget,
|
|
124
|
+
isolation: input.isolation,
|
|
125
|
+
provenance: input.provenance,
|
|
126
|
+
createdAt: now(),
|
|
127
|
+
};
|
|
128
|
+
const first = firstPhase(workstream)?.id ?? null;
|
|
129
|
+
workstream.items = input.items.map((spec) => buildItem(spec, first));
|
|
130
|
+
workstreams.set(workstream.id, workstream);
|
|
131
|
+
completedResults.set(workstream.id, []);
|
|
132
|
+
return workstream;
|
|
133
|
+
}
|
|
134
|
+
function insertPhase(workstreamId, afterOrdinal, spec) {
|
|
135
|
+
const workstream = workstreams.get(workstreamId);
|
|
136
|
+
if (!workstream)
|
|
137
|
+
return null;
|
|
138
|
+
const following = sortedPhases(workstream).filter((p) => p.ordinal > afterOrdinal);
|
|
139
|
+
const nextOrdinal = following[0]?.ordinal ?? afterOrdinal + 1;
|
|
140
|
+
const ordinal = (afterOrdinal + nextOrdinal) / 2;
|
|
141
|
+
const phase = buildPhase(spec, ordinal, now());
|
|
142
|
+
workstream.phases.push(phase);
|
|
143
|
+
emit({ type: 'phase-inserted', workstreamId, phase });
|
|
144
|
+
return phase;
|
|
145
|
+
}
|
|
146
|
+
function findOrInsertFixPhase(workstream, reviewPhase) {
|
|
147
|
+
const existing = workstream.phases.find((p) => p.kind === 'fix' && reviewPhaseBefore(workstream, p)?.id === reviewPhase.id);
|
|
148
|
+
if (existing)
|
|
149
|
+
return existing;
|
|
150
|
+
return insertPhase(workstream.id, reviewPhase.ordinal, {
|
|
151
|
+
role: 'fixer',
|
|
152
|
+
capacity: reviewPhase.capacity,
|
|
153
|
+
gate: reviewPhase.gate,
|
|
154
|
+
kind: 'fix',
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
function visitsFor(item, phaseId) {
|
|
158
|
+
return item.visits.get(phaseId) ?? 0;
|
|
159
|
+
}
|
|
160
|
+
function recordVisit(item, phaseId) {
|
|
161
|
+
item.visits.set(phaseId, visitsFor(item, phaseId) + 1);
|
|
162
|
+
}
|
|
163
|
+
function routeItem(workstream, item, toPhase, fromPhaseId) {
|
|
164
|
+
if (toPhase) {
|
|
165
|
+
item.currentPhaseId = toPhase.id;
|
|
166
|
+
item.state = 'awaiting-capacity';
|
|
167
|
+
emit({ type: 'item-advanced', workstreamId: workstream.id, itemId: item.id, fromPhaseId, toPhaseId: toPhase.id });
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
item.currentPhaseId = null;
|
|
171
|
+
item.state = 'passed';
|
|
172
|
+
item.completedAt = now();
|
|
173
|
+
emit({
|
|
174
|
+
type: 'item-passed',
|
|
175
|
+
workstreamId: workstream.id,
|
|
176
|
+
itemId: item.id,
|
|
177
|
+
...(item.warnings && item.warnings.length > 0 ? { warnings: [...item.warnings] } : {}),
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
function failItem(workstream, item, reason) {
|
|
182
|
+
item.state = 'failed';
|
|
183
|
+
item.completedAt = now();
|
|
184
|
+
item.failureReason = reason;
|
|
185
|
+
emit({ type: 'item-failed', workstreamId: workstream.id, itemId: item.id, reason });
|
|
186
|
+
// Worktree-mode fail/kill cleanup rule (remove only if clean, else KEEP —
|
|
187
|
+
// data safety): covers every failItem call site uniformly, including
|
|
188
|
+
// kill() and the tick()-catch path for a throw before any phase outcome.
|
|
189
|
+
// No-op (instantly resolves) for a shared-isolation workstream, or an
|
|
190
|
+
// item that never reached a claim and therefore never got a worktree.
|
|
191
|
+
if (workstream.isolation === 'worktree') {
|
|
192
|
+
void worktreeIsolation.cleanupTerminated(workstream, item).catch((error) => {
|
|
193
|
+
logger.error('orchestration engine: worktree cleanup after item failure did not complete', {
|
|
194
|
+
itemId: item.id, error: summarizeError(error),
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Record a NON-FATAL bookkeeping note on an item without touching its
|
|
201
|
+
* terminal status (DEBT-4 item 1). Used for post-gate faults that do not
|
|
202
|
+
* negate the phase's passed work — e.g. a scoped commit that could not
|
|
203
|
+
* complete. The item still passes/advances; the warning rides along on
|
|
204
|
+
* `item.warnings` and, for a terminal pass, in the `item-passed` event, so a
|
|
205
|
+
* passed-with-caveats outcome is visible instead of hidden or mislabelled.
|
|
206
|
+
*/
|
|
207
|
+
function warnItem(item, note) {
|
|
208
|
+
(item.warnings ??= []).push(note);
|
|
209
|
+
logger.warn('orchestration engine: non-fatal bookkeeping warning on a passed work item', {
|
|
210
|
+
itemId: item.id,
|
|
211
|
+
note,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
/** Indirection to defeat TS's cross-await narrowing of item.state — see the call site below. */
|
|
215
|
+
function currentState(item) {
|
|
216
|
+
return item.state;
|
|
217
|
+
}
|
|
218
|
+
async function runItemPhase(workstream, item, phase) {
|
|
219
|
+
recordVisit(item, phase.id);
|
|
220
|
+
item.state = 'in-phase';
|
|
221
|
+
item.currentPhaseId = phase.id;
|
|
222
|
+
item.blockedReason = undefined;
|
|
223
|
+
// Worktree mode: ensure this item has its dedicated worktree BEFORE
|
|
224
|
+
// spawning its phase agent (idempotent — a no-op from the item's second
|
|
225
|
+
// phase onward, since the worktree persists across the item's whole run;
|
|
226
|
+
// see WorktreeIsolationManager.ensureWorktree). A setup failure here is a
|
|
227
|
+
// genuine phase-run failure (there is nowhere isolated for the agent to
|
|
228
|
+
// work) — fail the item honestly rather than silently falling back to the
|
|
229
|
+
// shared tree, which would defeat isolation's whole purpose.
|
|
230
|
+
let itemWorktree;
|
|
231
|
+
if (workstream.isolation === 'worktree') {
|
|
232
|
+
try {
|
|
233
|
+
itemWorktree = await worktreeIsolation.ensureWorktree(workstream, item);
|
|
234
|
+
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
logger.error('orchestration engine: failed to prepare item worktree', { itemId: item.id, error: summarizeError(error) });
|
|
237
|
+
failItem(workstream, item, `worktree isolation setup failed: ${summarizeError(error)}`);
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
const priorReports = getPhaseResults(workstream.id).filter((r) => r.itemId === item.id);
|
|
242
|
+
const outcome = await runPhase(workstream, item, phase, priorReports, {
|
|
243
|
+
agentManager: deps.agentManager,
|
|
244
|
+
configManager: deps.configManager,
|
|
245
|
+
runtimeBus: deps.runtimeBus,
|
|
246
|
+
projectRoot: deps.projectRoot,
|
|
247
|
+
sessionId,
|
|
248
|
+
createWorktree: deps.createWorktree,
|
|
249
|
+
cancellation,
|
|
250
|
+
priceUsage: deps.priceUsage,
|
|
251
|
+
skipClaimVerification: deps.skipClaimVerification,
|
|
252
|
+
launchDirtySnapshot,
|
|
253
|
+
itemWorktree,
|
|
254
|
+
});
|
|
255
|
+
// ── Bookkeeping region (AFTER the phase produced its outcome) ───────────
|
|
256
|
+
// From here on everything is bookkeeping layered on top of a verdict the
|
|
257
|
+
// phase has ALREADY reached (outcome.result.gate + agentStatus). It must
|
|
258
|
+
// never be able to turn a passed phase into a failed item: the item's
|
|
259
|
+
// terminal status derives ONLY from that phase outcome, plus the narrow
|
|
260
|
+
// negating set (bookkeeping.ts). A bookkeeping fault becomes a warning on a
|
|
261
|
+
// passed item (warnItem), never a failure — that is what makes "item failed
|
|
262
|
+
// while every phase passed and the commit landed" unrepresentable
|
|
263
|
+
// (DEBT-4 item 1). A throw BEFORE this point — inside runPhase, e.g. a gate
|
|
264
|
+
// subprocess that never yielded a verdict — legitimately reaches tick()'s
|
|
265
|
+
// catch and fails the item, because there is then no phase outcome to
|
|
266
|
+
// stand on.
|
|
267
|
+
try {
|
|
268
|
+
item.usage = mergeWorkItemUsage(item.usage, outcome.result.usage);
|
|
269
|
+
}
|
|
270
|
+
catch (error) {
|
|
271
|
+
warnItem(item, `usage rollup skipped: ${summarizeError(error)}`);
|
|
272
|
+
}
|
|
273
|
+
const results = completedResults.get(workstream.id) ?? [];
|
|
274
|
+
results.push(outcome.result);
|
|
275
|
+
completedResults.set(workstream.id, results);
|
|
276
|
+
emit({ type: 'workstream-persisted', workstreamId: workstream.id });
|
|
277
|
+
// kill() already transitioned the item to 'failed' synchronously before
|
|
278
|
+
// this promise settled — don't clobber that terminal state. Read through
|
|
279
|
+
// currentState() (not a direct `item.state` narrowing site) since TS's
|
|
280
|
+
// control-flow analysis otherwise "remembers" the 'in-phase' assignment
|
|
281
|
+
// above as if it still held after the `await`, even though kill() can
|
|
282
|
+
// mutate the same object concurrently while this call was in flight.
|
|
283
|
+
if (currentState(item) === 'failed')
|
|
284
|
+
return;
|
|
285
|
+
if (outcome.agentStatus === 'cancelled') {
|
|
286
|
+
failItem(workstream, item, 'cancelled by operator');
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
if (outcome.agentStatus === 'failed') {
|
|
290
|
+
failItem(workstream, item, outcome.result.report.summary);
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
if (outcome.result.gate.passed) {
|
|
294
|
+
// The PHASE PASSED. Post-gate commit bookkeeping can only WARN this item
|
|
295
|
+
// (or, for the narrow negating set, fail it) — it can never contradict
|
|
296
|
+
// the passed verdict the gate already reached.
|
|
297
|
+
const commit = outcome.result.commit;
|
|
298
|
+
if (commit?.status === 'failed' && commit.negating) {
|
|
299
|
+
// Negating set: the commit/merge left the workspace corrupted, so the
|
|
300
|
+
// recorded pass can no longer be trusted — this is the one post-gate
|
|
301
|
+
// condition that genuinely fails the item.
|
|
302
|
+
failItem(workstream, item, `phase gate passed but the workspace was left unrecorded/corrupted: ${commit.reason ?? 'commit failed'}`);
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
if (commit?.status === 'failed') {
|
|
306
|
+
// Non-negating: the gate passed and the workspace is coherent, so the
|
|
307
|
+
// work stands. Surface the miss as a warning, never a failure.
|
|
308
|
+
warnItem(item, `scoped commit did not complete (non-fatal): ${commit.reason ?? 'commit failed'}`);
|
|
309
|
+
}
|
|
310
|
+
// A fix phase's PASSING gate routes BACK to the review phase it was
|
|
311
|
+
// inserted after (dynamic insertion places 'fix' at an ordinal AFTER
|
|
312
|
+
// its review, per design (b) — "inserts a fix phase after review and
|
|
313
|
+
// re-routes that item back"), not forward past it. Every other kind
|
|
314
|
+
// advances to the next phase by ordinal as usual.
|
|
315
|
+
const forwardTarget = phase.kind === 'fix'
|
|
316
|
+
? (reviewPhaseBefore(workstream, phase) ?? nextPhaseAfter(workstream, phase.ordinal) ?? null)
|
|
317
|
+
: (nextPhaseAfter(workstream, phase.ordinal) ?? null);
|
|
318
|
+
routeItem(workstream, item, forwardTarget, phase.id);
|
|
319
|
+
// The item just terminated PASSED (no further phase) — in worktree mode
|
|
320
|
+
// its branch now enters the single sequential integration lane
|
|
321
|
+
// (completion order, not claim order). Fire-and-forget: the lane
|
|
322
|
+
// manages its own ordering and never rejects (see
|
|
323
|
+
// WorktreeIsolationManager.enqueueIntegration), so tick() is never
|
|
324
|
+
// blocked waiting on a merge that may itself await a sibling ahead of
|
|
325
|
+
// it in the lane.
|
|
326
|
+
if (forwardTarget === null && workstream.isolation === 'worktree') {
|
|
327
|
+
void worktreeIsolation.enqueueIntegration(workstream, item);
|
|
328
|
+
}
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
// A review's FAILING gate with unsatisfied constraints gets one more
|
|
332
|
+
// cycle through a (found-or-inserted) fix phase, bounded by visits. A
|
|
333
|
+
// fix phase's own FAILING gate (the fixer didn't actually fix anything —
|
|
334
|
+
// phantom guard or quality gates caught it) is a genuine terminal
|
|
335
|
+
// failure, not something to retry-loop.
|
|
336
|
+
const unsatisfied = outcome.result.gate.unsatisfiedConstraintIds ?? [];
|
|
337
|
+
if (phase.kind === 'review' && unsatisfied.length > 0 && visitsFor(item, phase.id) < maxPhaseVisits) {
|
|
338
|
+
const fixPhase = findOrInsertFixPhase(workstream, phase);
|
|
339
|
+
routeItem(workstream, item, fixPhase, phase.id);
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
failItem(workstream, item, outcome.result.gate.results.filter((r) => !r.passed).map((r) => `${r.gate}: ${r.output}`).join('; ') || 'gate failed');
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Dependency-gate pre-pass (BIG-3 item 2), run at the top of every tick
|
|
346
|
+
* BEFORE computeClaims. For each item still sitting at its FIRST phase in a
|
|
347
|
+
* pre-claim state (pending / awaiting-capacity / blocked-dependency) with
|
|
348
|
+
* declared dependencies, classify those dependencies and either release or
|
|
349
|
+
* refuse the item:
|
|
350
|
+
* - every dependency 'passed' → RELEASE: if it was 'blocked-dependency',
|
|
351
|
+
* restore it to 'pending' and clear blockedReason (emit
|
|
352
|
+
* item-dependency-cleared) so computeClaims can pick it up this same tick.
|
|
353
|
+
* - any dependency unmet → REFUSE: set 'blocked-dependency' with an honest
|
|
354
|
+
* blockedReason ('waiting on: …' or 'dependency failed: …'), recomputed
|
|
355
|
+
* every tick so it stays current as dependencies change; emit
|
|
356
|
+
* item-blocked-dependency only on a NEW block (never once per idle tick).
|
|
357
|
+
*
|
|
358
|
+
* Only FIRST-phase items are gated. Once an item's dependencies are all
|
|
359
|
+
* passed at its first claim they stay passed (passed is terminal), so a
|
|
360
|
+
* mid-pipeline item (currentPhaseId past the first phase) is never re-gated.
|
|
361
|
+
* A retried item (engine.retryItem) is reset back to the first phase and is
|
|
362
|
+
* therefore re-gated here — which is exactly why a failed dependency's
|
|
363
|
+
* dependents recover only once the dependency is retried AND passes.
|
|
364
|
+
* A FAILED dependency keeps the dependent blocked (recoverable), never fails
|
|
365
|
+
* it — refuse-not-kill.
|
|
366
|
+
*/
|
|
367
|
+
function applyDependencyGates(workstream) {
|
|
368
|
+
const first = firstPhase(workstream);
|
|
369
|
+
if (!first)
|
|
370
|
+
return;
|
|
371
|
+
for (const item of workstream.items) {
|
|
372
|
+
if (item.dependsOn.length === 0)
|
|
373
|
+
continue;
|
|
374
|
+
if (item.currentPhaseId !== first.id)
|
|
375
|
+
continue; // only gate at entry (first phase)
|
|
376
|
+
if (item.state !== 'pending' && item.state !== 'awaiting-capacity' && item.state !== 'blocked-dependency')
|
|
377
|
+
continue;
|
|
378
|
+
const status = dependencyStatus(workstream, item);
|
|
379
|
+
if (status.ready) {
|
|
380
|
+
if (item.state === 'blocked-dependency') {
|
|
381
|
+
item.state = 'pending';
|
|
382
|
+
item.blockedReason = undefined;
|
|
383
|
+
emit({ type: 'item-dependency-cleared', workstreamId: workstream.id, itemId: item.id });
|
|
384
|
+
}
|
|
385
|
+
continue;
|
|
386
|
+
}
|
|
387
|
+
const reason = status.failed.length > 0
|
|
388
|
+
? `dependency failed: ${status.failed.join(', ')}`
|
|
389
|
+
: `waiting on: ${status.waiting.join(', ')}`;
|
|
390
|
+
const wasAlreadyBlocked = item.state === 'blocked-dependency';
|
|
391
|
+
item.state = 'blocked-dependency';
|
|
392
|
+
item.blockedReason = reason;
|
|
393
|
+
if (!wasAlreadyBlocked) {
|
|
394
|
+
emit({
|
|
395
|
+
type: 'item-blocked-dependency',
|
|
396
|
+
workstreamId: workstream.id,
|
|
397
|
+
itemId: item.id,
|
|
398
|
+
phaseId: item.currentPhaseId ?? '',
|
|
399
|
+
reason,
|
|
400
|
+
deps: [...item.dependsOn],
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
function tick(workstreamId) {
|
|
406
|
+
if (disposed)
|
|
407
|
+
return;
|
|
408
|
+
const workstream = workstreams.get(workstreamId);
|
|
409
|
+
if (!workstream)
|
|
410
|
+
return;
|
|
411
|
+
// Dependency gate FIRST — release/refuse first-phase items by their
|
|
412
|
+
// dependencies before computeClaims decides capacity (which never sees a
|
|
413
|
+
// 'blocked-dependency' item, see scheduler.ts computeClaims).
|
|
414
|
+
applyDependencyGates(workstream);
|
|
415
|
+
const claims = computeClaims(workstream);
|
|
416
|
+
for (const { item, phase } of claims) {
|
|
417
|
+
const budgetCheck = checkBudget(workstream);
|
|
418
|
+
if (!budgetCheck.allowed) {
|
|
419
|
+
// Re-checked on every tick (computeClaims keeps 'blocked-budget'
|
|
420
|
+
// items in the waiting set — see scheduler.ts) rather than a
|
|
421
|
+
// one-time transition: the reason can change between checks (e.g.
|
|
422
|
+
// token ceiling was the blocker, then a cost ceiling is reached
|
|
423
|
+
// too), so keep it current even though the event only fires once
|
|
424
|
+
// per NEW block to avoid spamming listeners on every idle tick.
|
|
425
|
+
const wasAlreadyBlocked = item.state === 'blocked-budget';
|
|
426
|
+
item.state = 'blocked-budget';
|
|
427
|
+
item.blockedReason = budgetCheck.reason;
|
|
428
|
+
if (!wasAlreadyBlocked) {
|
|
429
|
+
emit({ type: 'item-blocked-budget', workstreamId, itemId: item.id, phaseId: phase.id, reason: budgetCheck.reason ?? 'budget ceiling reached' });
|
|
430
|
+
}
|
|
431
|
+
continue;
|
|
432
|
+
}
|
|
433
|
+
void runItemPhase(workstream, item, phase)
|
|
434
|
+
.catch((error) => {
|
|
435
|
+
// Reaching here means runItemPhase rejected BEFORE the phase produced
|
|
436
|
+
// an outcome — the run threw inside runPhase (spawn, gate execution,
|
|
437
|
+
// etc.) with no gate verdict to stand on. That is a genuine phase
|
|
438
|
+
// failure, so failing the item is honest. Post-outcome bookkeeping
|
|
439
|
+
// faults never reach here: runItemPhase converts them to warnings on
|
|
440
|
+
// a passed item (or, for the negating set, an explicit failItem) —
|
|
441
|
+
// see its bookkeeping region (DEBT-4 item 1).
|
|
442
|
+
logger.error('orchestration engine: phase run threw before producing an outcome', {
|
|
443
|
+
workstreamId, itemId: item.id, phaseId: phase.id, error: summarizeError(error),
|
|
444
|
+
});
|
|
445
|
+
failItem(workstream, item, summarizeError(error));
|
|
446
|
+
})
|
|
447
|
+
.finally(() => {
|
|
448
|
+
if (!disposed)
|
|
449
|
+
tick(workstreamId);
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
function start(workstreamId) {
|
|
454
|
+
tick(workstreamId);
|
|
455
|
+
}
|
|
456
|
+
function findItemAndWorkstream(itemId) {
|
|
457
|
+
for (const workstream of workstreams.values()) {
|
|
458
|
+
const item = workstream.items.find((i) => i.id === itemId);
|
|
459
|
+
if (item)
|
|
460
|
+
return { workstream, item };
|
|
461
|
+
}
|
|
462
|
+
return null;
|
|
463
|
+
}
|
|
464
|
+
function kill(itemId) {
|
|
465
|
+
const found = findItemAndWorkstream(itemId);
|
|
466
|
+
if (!found)
|
|
467
|
+
return false;
|
|
468
|
+
const { workstream, item } = found;
|
|
469
|
+
if (item.state === 'passed' || item.state === 'failed')
|
|
470
|
+
return false;
|
|
471
|
+
cancellation.abort(itemId);
|
|
472
|
+
if (item.agentId)
|
|
473
|
+
deps.agentManager.cancel(item.agentId, 'kill');
|
|
474
|
+
failItem(workstream, item, 'cancelled by operator');
|
|
475
|
+
emit({ type: 'item-cancelled', workstreamId: workstream.id, itemId, reason: 'cancelled by operator' });
|
|
476
|
+
return true;
|
|
477
|
+
}
|
|
478
|
+
function updateBudget(workstreamId, ceiling) {
|
|
479
|
+
const workstream = workstreams.get(workstreamId);
|
|
480
|
+
if (!workstream)
|
|
481
|
+
return false;
|
|
482
|
+
workstream.budget = ceiling;
|
|
483
|
+
tick(workstreamId);
|
|
484
|
+
return true;
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* See the OrchestrationEngine.retryItem doc. Resets a failed item to
|
|
488
|
+
* 'pending' at the first phase; clears the terminal fields and the per-phase
|
|
489
|
+
* visit budget (a fresh fix-cycle allowance for the retry) but RETAINS
|
|
490
|
+
* accumulated `usage` (monotone — a retry adds to the tally, never wipes it).
|
|
491
|
+
* In worktree mode a still-present KEPT worktree is reused (ensureWorktree is
|
|
492
|
+
* idempotent on worktreePath); a worktree already removed after the failure
|
|
493
|
+
* is recreated at the next first claim.
|
|
494
|
+
*/
|
|
495
|
+
function retryItem(itemId) {
|
|
496
|
+
const found = findItemAndWorkstream(itemId);
|
|
497
|
+
if (!found)
|
|
498
|
+
return false;
|
|
499
|
+
const { workstream, item } = found;
|
|
500
|
+
if (item.state !== 'failed')
|
|
501
|
+
return false;
|
|
502
|
+
const first = firstPhase(workstream);
|
|
503
|
+
if (!first)
|
|
504
|
+
return false;
|
|
505
|
+
item.state = 'pending';
|
|
506
|
+
item.currentPhaseId = first.id;
|
|
507
|
+
item.failureReason = undefined;
|
|
508
|
+
item.completedAt = undefined;
|
|
509
|
+
item.blockedReason = undefined;
|
|
510
|
+
item.visits.clear();
|
|
511
|
+
emit({ type: 'item-retried', workstreamId: workstream.id, itemId, reason: 'reset to re-run after failure' });
|
|
512
|
+
tick(workstream.id);
|
|
513
|
+
return true;
|
|
514
|
+
}
|
|
515
|
+
function serializeWorkstream(workstreamId) {
|
|
516
|
+
const workstream = workstreams.get(workstreamId);
|
|
517
|
+
if (!workstream)
|
|
518
|
+
return null;
|
|
519
|
+
return serializeWorkstreamSnapshot(workstream, getPhaseResults(workstreamId));
|
|
520
|
+
}
|
|
521
|
+
function isTerminalWorkstream(workstream) {
|
|
522
|
+
return workstream.items.every((item) => item.state === 'passed' || item.state === 'failed');
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* An item persisted as 'in-phase' was mid-run when the snapshot was
|
|
526
|
+
* written (the debounced writer, persistence.ts, captures state
|
|
527
|
+
* synchronously — see runItemPhase — so this is always a crash artifact,
|
|
528
|
+
* never a live agent this process could still be waiting on). Left
|
|
529
|
+
* verbatim, it would count as an OCCUPIED capacity slot forever
|
|
530
|
+
* (computeClaims, scheduler.ts) while never being in the re-claimable
|
|
531
|
+
* waiting set, permanently starving every sibling in the same phase.
|
|
532
|
+
* Requeue it as 'pending' and drop the stale agentId so the next tick()
|
|
533
|
+
* reclaims it like any other waiting item — its prior PhaseResult (if any)
|
|
534
|
+
* was only ever pushed AFTER phase completion (see runItemPhase), so
|
|
535
|
+
* re-running the phase from here cannot produce a duplicate result.
|
|
536
|
+
*/
|
|
537
|
+
function reconcileImportedItems(workstream) {
|
|
538
|
+
for (const item of workstream.items) {
|
|
539
|
+
if (item.state !== 'in-phase')
|
|
540
|
+
continue;
|
|
541
|
+
item.state = 'pending';
|
|
542
|
+
item.agentId = undefined;
|
|
543
|
+
emit({
|
|
544
|
+
type: 'item-requeued',
|
|
545
|
+
workstreamId: workstream.id,
|
|
546
|
+
itemId: item.id,
|
|
547
|
+
reason: 're-queued after restart — was in-phase when the snapshot was written',
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
function importWorkstream(snapshotJson, force = false) {
|
|
552
|
+
const snapshot = deserializeWorkstreamSnapshot(snapshotJson);
|
|
553
|
+
if (!snapshot)
|
|
554
|
+
return false;
|
|
555
|
+
const workstream = deserializeWorkstreamModel(snapshot.workstream);
|
|
556
|
+
const existing = workstreams.get(workstream.id);
|
|
557
|
+
if (existing && !isTerminalWorkstream(existing) && !force) {
|
|
558
|
+
logger.warn('orchestration engine: importWorkstream refused — existing workstream is non-terminal; use force=true to overwrite', {
|
|
559
|
+
workstreamId: workstream.id,
|
|
560
|
+
});
|
|
561
|
+
return false;
|
|
562
|
+
}
|
|
563
|
+
reconcileImportedItems(workstream);
|
|
564
|
+
workstreams.set(workstream.id, workstream);
|
|
565
|
+
completedResults.set(workstream.id, [...snapshot.completedResults]);
|
|
566
|
+
// Orphan worktree reconciliation (worktree mode only) — SYNCHRONOUS and
|
|
567
|
+
// done BEFORE this function returns, i.e. before any caller can call
|
|
568
|
+
// start()/tick() on this workstream. An on-disk `ws/<wsShort>/*` worktree
|
|
569
|
+
// not already recorded on one of the just-imported items is a crash
|
|
570
|
+
// artifact from a prior process; adopt it onto a matching unresolved item
|
|
571
|
+
// or report it for the operator (NEVER deleted on sight) — see
|
|
572
|
+
// WorktreeIsolationManager.reconcileOrphans for why this must not race
|
|
573
|
+
// the first tick()'s claim (it would otherwise risk creating a second
|
|
574
|
+
// worktree at the same deterministic path).
|
|
575
|
+
if (workstream.isolation === 'worktree') {
|
|
576
|
+
worktreeIsolation.reconcileOrphans(workstream);
|
|
577
|
+
}
|
|
578
|
+
return true;
|
|
579
|
+
}
|
|
580
|
+
function resumeWorkstream(workstreamId) {
|
|
581
|
+
if (!workstreams.has(workstreamId)) {
|
|
582
|
+
const snapshot = loadWorkstreamSnapshot(deps.projectRoot, workstreamId);
|
|
583
|
+
if (!snapshot)
|
|
584
|
+
return false;
|
|
585
|
+
if (!importWorkstream(JSON.stringify(snapshot)))
|
|
586
|
+
return false;
|
|
587
|
+
}
|
|
588
|
+
tick(workstreamId);
|
|
589
|
+
return true;
|
|
590
|
+
}
|
|
591
|
+
function resumeAllFromDisk() {
|
|
592
|
+
let count = 0;
|
|
593
|
+
for (const workstreamId of listSnapshotWorkstreamIds(deps.projectRoot)) {
|
|
594
|
+
if (resumeWorkstream(workstreamId))
|
|
595
|
+
count += 1;
|
|
596
|
+
}
|
|
597
|
+
return count;
|
|
598
|
+
}
|
|
599
|
+
function dispose() {
|
|
600
|
+
if (disposed)
|
|
601
|
+
return;
|
|
602
|
+
disposed = true;
|
|
603
|
+
unsubscribeWriter();
|
|
604
|
+
listeners.clear();
|
|
605
|
+
}
|
|
606
|
+
return {
|
|
607
|
+
createWorkstream,
|
|
608
|
+
getWorkstream,
|
|
609
|
+
listWorkstreams,
|
|
610
|
+
insertPhase,
|
|
611
|
+
start,
|
|
612
|
+
kill,
|
|
613
|
+
updateBudget,
|
|
614
|
+
retryItem,
|
|
615
|
+
getPhaseResults,
|
|
616
|
+
serializeWorkstream,
|
|
617
|
+
importWorkstream,
|
|
618
|
+
resumeWorkstream,
|
|
619
|
+
resumeAllFromDisk,
|
|
620
|
+
on,
|
|
621
|
+
dispose,
|
|
622
|
+
};
|
|
623
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
|
+
export type { BudgetCeiling, CommitExclusion, GateOutcome, ItemMergeState, OrchestrationEvent, OrchestrationEventListener, Phase, PhaseGateSpec, PhaseKind, PhaseResult, PhaseRole, PhaseSpec, SerializedWorkItem, SerializedWorkstream, WorkItem, WorkItemSpec, WorkItemState, WorkItemUsage, Workstream, WorkstreamIsolation, WorkstreamProvenance, WorkstreamSnapshot, } from './types.js';
|
|
3
|
+
export { CURRENT_WORKSTREAM_SCHEMA_VERSION, emptyWorkItemUsage } from './types.js';
|
|
4
|
+
export type { CreateWorkstreamInput, OrchestrationEngine, OrchestrationEngineDeps } from './engine.js';
|
|
5
|
+
export { createOrchestrationEngine } from './engine.js';
|
|
6
|
+
export type { CancellationRegistry } from './cancellation.js';
|
|
7
|
+
export { createCancellationRegistry } from './cancellation.js';
|
|
8
|
+
export type { BudgetCheck } from './budget.js';
|
|
9
|
+
export { checkBudget } from './budget.js';
|
|
10
|
+
export { deserializeWorkstream, deserializeWorkstreamSnapshot, listSnapshotWorkstreamIds, loadWorkstreamSnapshot, serializeWorkstream, serializeWorkstreamSnapshot, writeWorkstreamSnapshot, } from './persistence.js';
|
|
11
|
+
export { engineerReviewPhases, fromChainSpec } from './controller-compat.js';
|
|
12
|
+
export { fromPlanProposal } from './proposal-workstream.js';
|
|
13
|
+
export type { FromPlanProposalOptions } from './proposal-workstream.js';
|
|
14
|
+
export type { PhaseRunnerAgentManagerLike, PhaseRunnerDeps, PhaseRunOutcome, WrfcWorktreeOps } from './phase-runner.js';
|
|
15
|
+
export { runPhase } from './phase-runner.js';
|
|
16
|
+
export type { DirtyLaunchSnapshot, ScopedCommitExclusion } from './dirty-guard.js';
|
|
17
|
+
export { excludeUntouchedLaunchResidue, hashWorkingTreeFile, snapshotDirtyTree } from './dirty-guard.js';
|
|
18
|
+
export { computeClaims, dependencyStatus, firstPhase, nextPhaseAfter, phaseById, reviewPhaseBefore, sortedPhases, } from './scheduler.js';
|
|
19
|
+
export type { DependencyStatus, PhaseClaim } from './scheduler.js';
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/platform/orchestration/index.ts"],"names":[],"mappings":"AAAA,qFAAqF;AAMrF,YAAY,EACV,aAAa,EACb,eAAe,EACf,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,0BAA0B,EAC1B,KAAK,EACL,aAAa,EACb,SAAS,EACT,WAAW,EACX,SAAS,EACT,SAAS,EACT,kBAAkB,EAClB,oBAAoB,EACpB,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,aAAa,EACb,UAAU,EACV,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,iCAAiC,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEnF,YAAY,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACvG,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAExD,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAE/D,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EACL,qBAAqB,EACrB,6BAA6B,EAC7B,yBAAyB,EACzB,sBAAsB,EACtB,mBAAmB,EACnB,2BAA2B,EAC3B,uBAAuB,GACxB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,YAAY,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAExE,YAAY,EAAE,2BAA2B,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACxH,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,YAAY,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,EAAE,6BAA6B,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEzG,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,SAAS,EACT,iBAAiB,EACjB,YAAY,GACb,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
|
+
export { CURRENT_WORKSTREAM_SCHEMA_VERSION, emptyWorkItemUsage } from './types.js';
|
|
3
|
+
export { createOrchestrationEngine } from './engine.js';
|
|
4
|
+
export { createCancellationRegistry } from './cancellation.js';
|
|
5
|
+
export { checkBudget } from './budget.js';
|
|
6
|
+
export { deserializeWorkstream, deserializeWorkstreamSnapshot, listSnapshotWorkstreamIds, loadWorkstreamSnapshot, serializeWorkstream, serializeWorkstreamSnapshot, writeWorkstreamSnapshot, } from './persistence.js';
|
|
7
|
+
export { engineerReviewPhases, fromChainSpec } from './controller-compat.js';
|
|
8
|
+
export { fromPlanProposal } from './proposal-workstream.js';
|
|
9
|
+
export { runPhase } from './phase-runner.js';
|
|
10
|
+
export { excludeUntouchedLaunchResidue, hashWorkingTreeFile, snapshotDirtyTree } from './dirty-guard.js';
|
|
11
|
+
export { computeClaims, dependencyStatus, firstPhase, nextPhaseAfter, phaseById, reviewPhaseBefore, sortedPhases, } from './scheduler.js';
|