@atolis-hq/wake 0.2.96 → 0.3.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/src/activities/agent/agent-activity-definition.js +26 -0
- package/dist/src/activities/agent/agent-activity.js +171 -0
- package/dist/src/activities/agent/agent-result.js +149 -0
- package/dist/src/activities/contracts/activity.js +10 -0
- package/dist/src/activities/contracts/config.js +2 -0
- package/dist/src/activities/contracts/event-schema.js +302 -0
- package/dist/src/activities/contracts/events.js +42 -0
- package/dist/src/activities/contracts/identifiers.js +29 -0
- package/dist/src/activities/contracts/registry.js +71 -0
- package/dist/src/activities/contracts/streams.js +17 -0
- package/dist/src/activities/contracts/vocabulary.js +58 -0
- package/dist/src/activities/index.js +21 -0
- package/dist/src/activities/pr/activity-support.js +111 -0
- package/dist/src/activities/pr/application.js +158 -0
- package/dist/src/activities/pr/approve.js +85 -0
- package/dist/src/activities/pr/capability.js +11 -0
- package/dist/src/activities/pr/decision-claim.js +76 -0
- package/dist/src/activities/pr/event-drafts.js +66 -0
- package/dist/src/activities/pr/intent.js +37 -0
- package/dist/src/activities/pr/merge-authority-gate.js +14 -0
- package/dist/src/activities/pr/merge.js +110 -0
- package/dist/src/activities/pr/policy.js +135 -0
- package/dist/src/activities/pr/projection.js +130 -0
- package/dist/src/activities/pr/vocabulary.js +30 -0
- package/dist/src/activities/review/authorization.js +22 -0
- package/dist/src/activities/review/contracts.js +22 -0
- package/dist/src/activities/review/signals.js +3 -0
- package/dist/src/bootstrap/analytics-projection.js +26 -0
- package/dist/src/bootstrap/board-projection.js +337 -0
- package/dist/src/bootstrap/composition-root.js +382 -0
- package/dist/src/bootstrap/config/load-config.js +51 -0
- package/dist/src/bootstrap/config/root-schema.js +134 -0
- package/dist/src/bootstrap/external-ref.js +12 -0
- package/dist/src/bootstrap/fake-provider-files.js +44 -0
- package/dist/src/bootstrap/fake-scenarios.js +22 -0
- package/dist/src/bootstrap/index.js +48 -0
- package/dist/src/bootstrap/initialise.js +434 -0
- package/dist/src/bootstrap/paths.js +15 -0
- package/dist/src/bootstrap/projection-runtime.js +27 -0
- package/dist/src/bootstrap/runner-quota-reporter.js +21 -0
- package/dist/src/bootstrap/runner-registry.js +30 -0
- package/dist/src/bootstrap/schedule-checkpoint-store.js +49 -0
- package/dist/src/bootstrap/self-update-application.js +195 -0
- package/dist/src/bootstrap/self-update-failure-log.js +33 -0
- package/dist/src/bootstrap/source-update-port.js +47 -0
- package/dist/src/bootstrap/status-publish-activity.js +42 -0
- package/dist/src/bootstrap/surface-api-applications.js +325 -0
- package/dist/src/bootstrap/surface-api-execution-applications.js +95 -0
- package/dist/src/bootstrap/surface-api-metadata.js +12 -0
- package/dist/src/bootstrap/surface-api-projection-pages.js +22 -0
- package/dist/src/bootstrap/surface-api-run-context.js +5 -0
- package/dist/src/bootstrap/surface-api-transcripts.js +57 -0
- package/dist/src/bootstrap/surface-api-work-applications.js +199 -0
- package/dist/src/bootstrap/surface-applications.js +7 -0
- package/dist/src/bootstrap/surface-cli-applications.js +701 -0
- package/dist/src/bootstrap/update-ledger.js +61 -0
- package/dist/src/bootstrap/update-maintenance-lease.js +176 -0
- package/dist/src/{version.js → bootstrap/version.js} +35 -51
- package/dist/src/control-plane/application/advance-once.js +184 -0
- package/dist/src/control-plane/application/control-plane-projection.js +42 -0
- package/dist/src/control-plane/application/control-plane-service.js +42 -0
- package/dist/src/control-plane/application/intake-pipeline.js +29 -0
- package/dist/src/control-plane/application/runner-control-service.js +66 -0
- package/dist/src/control-plane/application/runner-pipeline.js +57 -0
- package/dist/src/control-plane/application/schedule-service.js +47 -0
- package/dist/src/control-plane/application/work-cancellation-policy.js +31 -0
- package/dist/src/control-plane/contracts/commands.js +10 -0
- package/dist/src/control-plane/contracts/config.js +22 -0
- package/dist/src/control-plane/contracts/events.js +81 -0
- package/dist/src/control-plane/contracts/streams.js +5 -0
- package/dist/src/control-plane/domain/dispatch-policy.js +15 -0
- package/dist/src/control-plane/domain/quota-policy.js +26 -0
- package/dist/src/control-plane/domain/runner-quota.js +35 -0
- package/dist/src/control-plane/domain/schedule-policy.js +46 -0
- package/dist/src/control-plane/index.js +20 -0
- package/dist/src/control-plane/infrastructure/intake-host.js +24 -0
- package/dist/src/control-plane/infrastructure/resident-host.js +45 -0
- package/dist/src/control-plane/infrastructure/tick-host.js +35 -0
- package/dist/src/execution/application/activation-claim.js +50 -0
- package/dist/src/execution/application/active-run-cancellation.js +14 -0
- package/dist/src/execution/application/execution-activity.js +97 -0
- package/dist/src/execution/application/execution-projection.js +17 -0
- package/dist/src/execution/application/execution-service.js +372 -0
- package/dist/src/execution/application/execution-validation.js +26 -0
- package/dist/src/execution/application/recovery-service.js +212 -0
- package/dist/src/execution/application/run-lifecycle.js +115 -0
- package/dist/src/execution/application/run-liveness-service.js +80 -0
- package/dist/src/execution/application/run-repository.js +27 -0
- package/dist/src/execution/contracts/commands.js +1 -0
- package/dist/src/execution/contracts/config.js +35 -0
- package/dist/src/execution/contracts/control-plane.js +1 -0
- package/dist/src/execution/contracts/event-factory.js +53 -0
- package/dist/src/execution/contracts/events.js +274 -0
- package/dist/src/execution/contracts/identifiers.js +5 -0
- package/dist/src/execution/contracts/liveness.js +1 -0
- package/dist/src/execution/contracts/results.js +1 -0
- package/dist/src/execution/contracts/runner.js +15 -0
- package/dist/src/execution/contracts/streams.js +10 -0
- package/dist/src/execution/contracts/views.js +1 -0
- package/dist/src/execution/contracts/vocabulary.js +43 -0
- package/dist/src/execution/contracts/workspace.js +1 -0
- package/dist/src/execution/domain/run-result.js +34 -0
- package/dist/src/execution/domain/run.js +142 -0
- package/dist/src/execution/index.js +31 -0
- package/dist/src/execution/infrastructure/agent-runner-adapter.js +114 -0
- package/dist/src/execution/infrastructure/process-execution.js +29 -0
- package/dist/src/execution/infrastructure/prompt-templates.js +42 -0
- package/dist/src/execution/infrastructure/runners/claude.js +120 -0
- package/dist/src/execution/infrastructure/runners/codex.js +143 -0
- package/dist/src/execution/infrastructure/runners/command.js +4 -0
- package/dist/src/execution/infrastructure/runners/cursor.js +69 -0
- package/dist/src/execution/infrastructure/runners/fake-scenarios.js +99 -0
- package/dist/src/execution/infrastructure/runners/fake.js +65 -0
- package/dist/src/execution/infrastructure/runners/registry.js +26 -0
- package/dist/src/execution/infrastructure/transcript-store.js +223 -0
- package/dist/src/execution/infrastructure/transcripts.js +11 -0
- package/dist/src/execution/infrastructure/workspace/fake-workspace.js +19 -0
- package/dist/src/execution/infrastructure/workspace/git-workspace.js +241 -0
- package/dist/src/integrations/application/agent-run-publication-reactor.js +111 -0
- package/dist/src/integrations/application/artifact-registration-reactor.js +159 -0
- package/dist/src/integrations/application/poll-service.js +25 -0
- package/dist/src/integrations/application/terminal-agent-run-report.js +40 -0
- package/dist/src/integrations/application/work-admission.js +31 -0
- package/dist/src/integrations/application/work-conclusion.js +19 -0
- package/dist/src/integrations/contracts/artifact-events.js +60 -0
- package/dist/src/integrations/contracts/artifact-vocabulary.js +9 -0
- package/dist/src/integrations/contracts/config.js +14 -0
- package/dist/src/integrations/contracts/identifiers.js +5 -0
- package/dist/src/integrations/contracts/intake-rules.js +14 -0
- package/dist/src/integrations/contracts/intake.js +1 -0
- package/dist/src/integrations/contracts/outcome-vocabulary.js +7 -0
- package/dist/src/integrations/contracts/provider.js +37 -0
- package/dist/src/integrations/contracts/streams.js +10 -0
- package/dist/src/integrations/delivery/application/delivery-outcome-reactor.js +75 -0
- package/dist/src/integrations/delivery/application/delivery-projector.js +165 -0
- package/dist/src/integrations/delivery/application/delivery-service.js +173 -0
- package/dist/src/integrations/delivery/contracts/commands.js +1 -0
- package/dist/src/integrations/delivery/contracts/config.js +1 -0
- package/dist/src/integrations/delivery/contracts/event-factory.js +18 -0
- package/dist/src/integrations/delivery/contracts/events.js +86 -0
- package/dist/src/integrations/delivery/contracts/intents.js +89 -0
- package/dist/src/integrations/delivery/contracts/views.js +1 -0
- package/dist/src/integrations/delivery/contracts/vocabulary.js +22 -0
- package/dist/src/integrations/fake/durable-delivery-provider.js +48 -0
- package/dist/src/integrations/fake/external-sink.js +9 -0
- package/dist/src/integrations/fake/external-source.js +44 -0
- package/dist/src/integrations/fake/inbound-translator.js +130 -0
- package/dist/src/integrations/fake/provider.js +95 -0
- package/dist/src/integrations/github/application/agent-context-reader.js +54 -0
- package/dist/src/integrations/github/application/agent-run-comment.js +94 -0
- package/dist/src/integrations/github/application/comment-history-reader.js +43 -0
- package/dist/src/integrations/github/application/inbound-context.js +10 -0
- package/dist/src/integrations/github/application/inbound-review-signals.js +159 -0
- package/dist/src/integrations/github/application/inbound-translator.js +231 -0
- package/dist/src/integrations/github/application/inbound-watch-gate-signals.js +84 -0
- package/dist/src/integrations/github/application/intake-policy.js +23 -0
- package/dist/src/integrations/github/application/outbound-translator.js +47 -0
- package/dist/src/integrations/github/application/poll-service.js +29 -0
- package/dist/src/integrations/github/application/pull-request-translation.js +10 -0
- package/dist/src/integrations/github/application/resource-links.js +8 -0
- package/dist/src/integrations/github/application/review-command-translator.js +16 -0
- package/dist/src/integrations/github/application/wake-labels.js +95 -0
- package/dist/src/integrations/github/contracts/config.js +47 -0
- package/dist/src/integrations/github/contracts/events.js +127 -0
- package/dist/src/integrations/github/contracts/external-key.js +19 -0
- package/dist/src/integrations/github/contracts/payloads.js +9 -0
- package/dist/src/integrations/github/contracts/vocabulary.js +55 -0
- package/dist/src/integrations/github/index.js +31 -0
- package/dist/src/integrations/github/infrastructure/client-reads.js +214 -0
- package/dist/src/integrations/github/infrastructure/client.js +132 -0
- package/dist/src/integrations/github/infrastructure/content-fingerprint.js +10 -0
- package/dist/src/integrations/github/infrastructure/delivery.js +31 -0
- package/dist/src/integrations/github/infrastructure/etag-cache.js +56 -0
- package/dist/src/integrations/github/infrastructure/gh-auth.js +19 -0
- package/dist/src/integrations/github/infrastructure/issue-source.js +109 -0
- package/dist/src/integrations/github/infrastructure/pr-source.js +186 -0
- package/dist/src/integrations/github/infrastructure/review-source.js +70 -0
- package/dist/src/integrations/github/infrastructure/source.js +108 -0
- package/dist/src/integrations/github/provider.js +96 -0
- package/dist/src/integrations/index.js +30 -0
- package/dist/src/kernel/contracts/checkpoint-store.js +1 -0
- package/dist/src/kernel/contracts/clock.js +1 -0
- package/dist/src/kernel/contracts/commands.js +1 -0
- package/dist/src/kernel/contracts/event-journal.js +2 -0
- package/dist/src/kernel/contracts/event-schema.js +54 -0
- package/dist/src/kernel/contracts/events.js +11 -0
- package/dist/src/kernel/contracts/id-generator.js +1 -0
- package/dist/src/kernel/contracts/identifiers.js +8 -0
- package/dist/src/kernel/contracts/projection-store.js +1 -0
- package/dist/src/kernel/contracts/relations.js +1 -0
- package/dist/src/kernel/contracts/schema.js +17 -0
- package/dist/src/kernel/contracts/vocabulary.js +6 -0
- package/dist/src/kernel/domain/event-envelope.js +29 -0
- package/dist/src/kernel/domain/match-mode.js +11 -0
- package/dist/src/kernel/domain/relation.js +10 -0
- package/dist/src/kernel/index.js +17 -0
- package/dist/src/{lib/clock.js → kernel/infrastructure/system-clock.js} +3 -3
- package/dist/src/kernel/infrastructure/ulid-id-generator.js +9 -0
- package/dist/src/main.js +137 -1030
- package/dist/src/orchestration/application/accept-activity-outcome.js +25 -0
- package/dist/src/orchestration/application/accept-signal.js +35 -0
- package/dist/src/orchestration/application/advance-workflow.js +160 -0
- package/dist/src/orchestration/application/coordination-claims.js +107 -0
- package/dist/src/orchestration/application/group-budget-recorder.js +43 -0
- package/dist/src/orchestration/application/orchestration-projection.js +20 -0
- package/dist/src/orchestration/application/orchestration-repository.js +36 -0
- package/dist/src/orchestration/application/orchestration-service.js +82 -0
- package/dist/src/orchestration/application/request-child.js +118 -0
- package/dist/src/orchestration/application/signal-reactor.js +17 -0
- package/dist/src/orchestration/application/start-workflow.js +51 -0
- package/dist/src/orchestration/application/watch-reactor.js +82 -0
- package/dist/src/orchestration/contracts/activity-outcome.js +18 -0
- package/dist/src/orchestration/contracts/commands.js +1 -0
- package/dist/src/orchestration/contracts/config.js +128 -0
- package/dist/src/orchestration/contracts/event-decoder.js +263 -0
- package/dist/src/orchestration/contracts/events.js +41 -0
- package/dist/src/orchestration/contracts/identifiers.js +35 -0
- package/dist/src/orchestration/contracts/streams.js +38 -0
- package/dist/src/orchestration/contracts/views.js +1 -0
- package/dist/src/orchestration/contracts/vocabulary.js +30 -0
- package/dist/src/orchestration/domain/activation-policy.js +55 -0
- package/dist/src/orchestration/domain/approval-defaults.js +17 -0
- package/dist/src/orchestration/domain/child-policy.js +63 -0
- package/dist/src/orchestration/domain/compiler.js +162 -0
- package/dist/src/orchestration/domain/coordination-events.js +25 -0
- package/dist/src/orchestration/domain/decision-events.js +47 -0
- package/dist/src/orchestration/domain/interpreter.js +49 -0
- package/dist/src/orchestration/domain/operator-retry-policy.js +34 -0
- package/dist/src/orchestration/domain/retry-policy.js +26 -0
- package/dist/src/orchestration/domain/signal-policy.js +120 -0
- package/dist/src/orchestration/domain/supplemental-policy.js +61 -0
- package/dist/src/orchestration/domain/transition.js +55 -0
- package/dist/src/orchestration/domain/workflow-graph.js +41 -0
- package/dist/src/orchestration/domain/workflow-instance-events.js +236 -0
- package/dist/src/orchestration/domain/workflow-instance.js +41 -0
- package/dist/src/orchestration/domain/workflow-selector.js +21 -0
- package/dist/src/orchestration/index.js +19 -0
- package/dist/src/persistence/application/projection-runner.js +79 -0
- package/dist/src/persistence/filesystem/file-checkpoint-store.js +35 -0
- package/dist/src/persistence/filesystem/file-event-journal.js +143 -0
- package/dist/src/persistence/filesystem/file-lock.js +91 -0
- package/dist/src/persistence/filesystem/file-projection-store.js +64 -0
- package/dist/src/persistence/index.js +8 -0
- package/dist/src/persistence/memory/in-memory-checkpoint-store.js +14 -0
- package/dist/src/persistence/memory/in-memory-event-journal.js +88 -0
- package/dist/src/persistence/memory/in-memory-projection-store.js +17 -0
- package/dist/src/resources/application/lookup-projections.js +48 -0
- package/dist/src/resources/application/resource-lookup.js +16 -0
- package/dist/src/resources/application/resource-projections.js +81 -0
- package/dist/src/resources/application/resource-repository.js +18 -0
- package/dist/src/resources/application/resource-service.js +83 -0
- package/dist/src/resources/contracts/commands.js +1 -0
- package/dist/src/resources/contracts/config.js +2 -0
- package/dist/src/resources/contracts/events.js +83 -0
- package/dist/src/resources/contracts/identifiers.js +15 -0
- package/dist/src/resources/contracts/streams.js +6 -0
- package/dist/src/resources/contracts/views.js +1 -0
- package/dist/src/resources/contracts/vocabulary.js +67 -0
- package/dist/src/resources/domain/correlation.js +8 -0
- package/dist/src/resources/domain/resource.js +58 -0
- package/dist/src/resources/index.js +14 -0
- package/dist/src/surfaces/api/contracts/activities.js +1 -0
- package/dist/src/surfaces/api/contracts/board.js +2 -0
- package/dist/src/surfaces/api/contracts/common.js +46 -0
- package/dist/src/surfaces/api/contracts/control-plane.js +5 -0
- package/dist/src/surfaces/api/contracts/events.js +1 -0
- package/dist/src/surfaces/api/contracts/execution.js +1 -0
- package/dist/src/surfaces/api/contracts/index.js +13 -0
- package/dist/src/surfaces/api/contracts/observability.js +1 -0
- package/dist/src/surfaces/api/contracts/orchestration.js +1 -0
- package/dist/src/surfaces/api/contracts/resources.js +1 -0
- package/dist/src/surfaces/api/contracts/status.js +1 -0
- package/dist/src/surfaces/api/contracts/system.js +1 -0
- package/dist/src/surfaces/api/contracts/transport-values.js +39 -0
- package/dist/src/surfaces/api/contracts/work.js +17 -0
- package/dist/src/surfaces/api/http-server.js +121 -0
- package/dist/src/surfaces/api/presenters/activities.js +1 -0
- package/dist/src/surfaces/api/presenters/board.js +3 -0
- package/dist/src/surfaces/api/presenters/control-plane.js +1 -0
- package/dist/src/surfaces/api/presenters/events.js +1 -0
- package/dist/src/surfaces/api/presenters/execution.js +59 -0
- package/dist/src/surfaces/api/presenters/observability.js +1 -0
- package/dist/src/surfaces/api/presenters/orchestration.js +19 -0
- package/dist/src/surfaces/api/presenters/resources.js +15 -0
- package/dist/src/surfaces/api/presenters/status.js +3 -0
- package/dist/src/surfaces/api/presenters/system.js +14 -0
- package/dist/src/surfaces/api/presenters/work.js +16 -0
- package/dist/src/surfaces/api/problem-details.js +9 -0
- package/dist/src/surfaces/api/router.js +13 -0
- package/dist/src/surfaces/api/routes/activities.js +1 -0
- package/dist/src/surfaces/api/routes/applications.js +1 -0
- package/dist/src/surfaces/api/routes/commands.js +82 -0
- package/dist/src/surfaces/api/routes/control-plane.js +6 -0
- package/dist/src/surfaces/api/routes/events.js +1 -0
- package/dist/src/surfaces/api/routes/execution.js +8 -0
- package/dist/src/surfaces/api/routes/index.js +18 -0
- package/dist/src/surfaces/api/routes/observability.js +1 -0
- package/dist/src/surfaces/api/routes/orchestration.js +1 -0
- package/dist/src/surfaces/api/routes/pagination.js +78 -0
- package/dist/src/surfaces/api/routes/read.js +135 -0
- package/dist/src/surfaces/api/routes/resources.js +1 -0
- package/dist/src/surfaces/api/routes/responses.js +67 -0
- package/dist/src/surfaces/api/routes/system.js +1 -0
- package/dist/src/surfaces/api/routes/work.js +9 -0
- package/dist/src/surfaces/cli/commands/api.js +1 -0
- package/dist/src/surfaces/cli/commands/audit.js +10 -0
- package/dist/src/surfaces/cli/commands/correlate.js +2 -0
- package/dist/src/surfaces/cli/commands/doctor.js +6 -0
- package/dist/src/surfaces/cli/commands/init.js +39 -0
- package/dist/src/surfaces/cli/commands/sandbox-entrypoint.js +33 -0
- package/dist/src/surfaces/cli/commands/sandbox-setup.js +29 -0
- package/dist/src/surfaces/cli/commands/sandbox.js +105 -0
- package/dist/src/surfaces/cli/commands/self-update.js +38 -0
- package/dist/src/surfaces/cli/commands/smoke.js +16 -0
- package/dist/src/surfaces/cli/commands/start.js +1 -0
- package/dist/src/surfaces/cli/commands/stop.js +13 -0
- package/dist/src/surfaces/cli/commands/tick.js +1 -0
- package/dist/src/surfaces/cli/commands/ui.js +2 -0
- package/dist/src/surfaces/cli/commands/validate-state.js +5 -0
- package/dist/src/surfaces/cli/infrastructure/docker-cli.js +221 -0
- package/dist/src/surfaces/cli/infrastructure/process-log.js +86 -0
- package/dist/src/surfaces/cli/main.js +140 -0
- package/dist/src/surfaces/cli/usage.js +33 -0
- package/dist/src/surfaces/contracts/config.js +34 -0
- package/dist/src/surfaces/index.js +47 -0
- package/dist/src/surfaces/web-assets/assets/index-Bfn4FwZG.css +1 -0
- package/dist/src/surfaces/web-assets/assets/index-ipB6JPGU.js +1090 -0
- package/dist/src/surfaces/web-assets/index.html +13 -0
- package/dist/src/surfaces/web-host/asset-source.js +1 -0
- package/dist/src/surfaces/web-host/packaged-assets.js +44 -0
- package/dist/src/work/application/work-projection.js +59 -0
- package/dist/src/work/application/work-repository.js +18 -0
- package/dist/src/work/application/work-service.js +117 -0
- package/dist/src/work/contracts/commands.js +1 -0
- package/dist/src/work/contracts/config.js +2 -0
- package/dist/src/work/contracts/events.js +103 -0
- package/dist/src/work/contracts/identifiers.js +5 -0
- package/dist/src/work/contracts/streams.js +6 -0
- package/dist/src/work/contracts/views.js +1 -0
- package/dist/src/work/contracts/vocabulary.js +6 -0
- package/dist/src/work/domain/work-item.js +89 -0
- package/dist/src/work/index.js +11 -0
- package/docker/Dockerfile +10 -6
- package/docker/Dockerfile.packaged +3 -3
- package/package.json +29 -4
- package/prompts/implement.md +2 -2
- package/templates/SETUP.md +7 -7
- package/dist/src/adapters/claude/claude-runner.js +0 -529
- package/dist/src/adapters/codex/codex-runner.js +0 -503
- package/dist/src/adapters/cursor/cursor-runner.js +0 -418
- package/dist/src/adapters/docker/docker-cli.js +0 -150
- package/dist/src/adapters/fake/fake-artifact-verifier.js +0 -14
- package/dist/src/adapters/fake/fake-github-pull-request-activity-source.js +0 -77
- package/dist/src/adapters/fake/fake-resource-index.js +0 -21
- package/dist/src/adapters/fake/fake-runner.js +0 -77
- package/dist/src/adapters/fake/fake-ticketing-system.js +0 -185
- package/dist/src/adapters/fake/fake-workspace-manager.js +0 -81
- package/dist/src/adapters/fs/resource-index.js +0 -126
- package/dist/src/adapters/fs/self-update-ledger.js +0 -17
- package/dist/src/adapters/fs/state-store.js +0 -775
- package/dist/src/adapters/git/git-workspace-manager.js +0 -289
- package/dist/src/adapters/github/github-artifact-verifier.js +0 -38
- package/dist/src/adapters/github/github-auth.js +0 -16
- package/dist/src/adapters/github/github-client.js +0 -249
- package/dist/src/adapters/github/github-etag-cache.js +0 -57
- package/dist/src/adapters/github/github-issues-work-source.js +0 -692
- package/dist/src/adapters/github/github-pull-request-activity-source.js +0 -584
- package/dist/src/adapters/github/github-pull-request-merge-actor.js +0 -45
- package/dist/src/adapters/http/ui-assets.js +0 -1188
- package/dist/src/adapters/http/ui-data.js +0 -1107
- package/dist/src/adapters/http/ui-server.js +0 -458
- package/dist/src/adapters/runner/cli-command.js +0 -73
- package/dist/src/adapters/runner/prompt-templates.js +0 -76
- package/dist/src/adapters/runner/runner-cli-adapter.js +0 -112
- package/dist/src/adapters/runner/runner-registry.js +0 -139
- package/dist/src/adapters/runner/runtime-events.js +0 -32
- package/dist/src/adapters/runner/stage-prompt.js +0 -268
- package/dist/src/adapters/runner/transcripts.js +0 -25
- package/dist/src/cli/audit-command.js +0 -36
- package/dist/src/cli/correlate-command.js +0 -62
- package/dist/src/cli/doctor-command.js +0 -48
- package/dist/src/cli/init-command.js +0 -18
- package/dist/src/cli/sandbox-command.js +0 -258
- package/dist/src/cli/sandbox-entrypoint-command.js +0 -88
- package/dist/src/cli/sandbox-exec-logging.js +0 -7
- package/dist/src/cli/sandbox-resume.js +0 -79
- package/dist/src/cli/sandbox-setup-command.js +0 -31
- package/dist/src/cli/scaffold-assets.js +0 -100
- package/dist/src/cli/self-update-command.js +0 -198
- package/dist/src/cli/startup-preflight.js +0 -134
- package/dist/src/cli/stop-command.js +0 -46
- package/dist/src/cli/ui-command.js +0 -27
- package/dist/src/config/defaults.js +0 -10
- package/dist/src/config/discover-config-files.js +0 -11
- package/dist/src/config/load-config.js +0 -69
- package/dist/src/config/split-config.js +0 -14
- package/dist/src/core/active-run-recovery.js +0 -44
- package/dist/src/core/approval-intents.js +0 -16
- package/dist/src/core/audit-events.js +0 -82
- package/dist/src/core/control-plane.js +0 -192
- package/dist/src/core/event-builders.js +0 -153
- package/dist/src/core/event-resolver.js +0 -249
- package/dist/src/core/lifecycle-service.js +0 -8
- package/dist/src/core/live-execution.js +0 -81
- package/dist/src/core/outbox.js +0 -198
- package/dist/src/core/policy-engine.js +0 -389
- package/dist/src/core/projection-updater.js +0 -693
- package/dist/src/core/quota-backoff.js +0 -69
- package/dist/src/core/run-lease.js +0 -38
- package/dist/src/core/scheduled-workflow-source.js +0 -199
- package/dist/src/core/sink-router.js +0 -107
- package/dist/src/core/stale-run-reconciler.js +0 -352
- package/dist/src/core/tick-runner.js +0 -2365
- package/dist/src/core/workspace-cleanup.js +0 -117
- package/dist/src/domain/branch-naming.js +0 -14
- package/dist/src/domain/custom-commands.js +0 -58
- package/dist/src/domain/event-types.js +0 -158
- package/dist/src/domain/manual-labels.js +0 -1
- package/dist/src/domain/resource-uri.js +0 -38
- package/dist/src/domain/runner-routing.js +0 -127
- package/dist/src/domain/runtime-events.js +0 -36
- package/dist/src/domain/schema.js +0 -1233
- package/dist/src/domain/sources.js +0 -16
- package/dist/src/domain/stages.js +0 -36
- package/dist/src/domain/work-item-labels.js +0 -48
- package/dist/src/domain/work-item-lifecycle.js +0 -10
- package/dist/src/domain/work-item-status.js +0 -33
- package/dist/src/domain/workflows.js +0 -159
- package/dist/src/lib/deep-merge.js +0 -14
- package/dist/src/lib/detached-process-logging.js +0 -46
- package/dist/src/lib/event-log.js +0 -21
- package/dist/src/lib/format.js +0 -41
- package/dist/src/lib/json-file.js +0 -23
- package/dist/src/lib/lock.js +0 -181
- package/dist/src/lib/log-rotation.js +0 -42
- package/dist/src/lib/paths.js +0 -52
- package/dist/src/lib/process-identity.js +0 -54
- package/dist/src/lib/state-health.js +0 -30
- package/dist/src/lib/work-id.js +0 -19
- package/dist/src/lib/yaml-file.js +0 -20
- /package/dist/src/{core → activities/pr}/contracts.js +0 -0
- /package/dist/src/{domain/types.js → control-plane/contracts/views.js} +0 -0
|
@@ -0,0 +1,701 @@
|
|
|
1
|
+
import { execFile as nodeExecFile, spawn } from 'node:child_process';
|
|
2
|
+
import { once } from 'node:events';
|
|
3
|
+
import { access, copyFile, mkdir, writeFile as writeFileContent } from 'node:fs/promises';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { createInterface } from 'node:readline/promises';
|
|
6
|
+
import { promisify } from 'node:util';
|
|
7
|
+
import { BuiltInActivityName, agentActivityDefinition } from '../activities/index.js';
|
|
8
|
+
import { IntakeHost, ResidentHost, TickHost } from '../control-plane/index.js';
|
|
9
|
+
import { ExecutionCancellationReason, RunStatus, loadPromptTemplate } from '../execution/index.js';
|
|
10
|
+
import { EventActorKind, correlationId } from '../kernel/index.js';
|
|
11
|
+
import { ResourceCorrelationRole, resourceId } from '../resources/index.js';
|
|
12
|
+
import { createApiDispatcher, createApiHttpServer, createLoggedDockerCli, createPackagedAssetSource, createProcessLogSink, createSandboxDockerPort, drainProcessOutput, runDoctor, runSandbox, runSandboxEntrypoint, runSandboxSetup, runSelfUpdateLatestLoop, runTargetSmoke, verifyResidentStart, waitForActiveRuns, } from '../surfaces/index.js';
|
|
13
|
+
import { WorkStreamKind, workItemId } from '../work/index.js';
|
|
14
|
+
import { loadConfig } from './config/load-config.js';
|
|
15
|
+
import { runtimeProjectionDefinitions } from './projection-runtime.js';
|
|
16
|
+
import { createRunnerRegistry } from './runner-registry.js';
|
|
17
|
+
import { createSelfUpdateApplication, } from './self-update-application.js';
|
|
18
|
+
import { createSelfUpdateFailureLog } from './self-update-failure-log.js';
|
|
19
|
+
import { createSourceUpdatePort } from './source-update-port.js';
|
|
20
|
+
import { createUpdateLedger } from './update-ledger.js';
|
|
21
|
+
import { resolveWakeVersion, wakeVersion } from './version.js';
|
|
22
|
+
const execFile = promisify(nodeExecFile);
|
|
23
|
+
export function createSurfaceCliApplications(root, api, now) {
|
|
24
|
+
const runnerTick = new TickHost((options) => root.runnerPipeline.run(options));
|
|
25
|
+
const intakeHost = new IntakeHost((signal) => root.intakePipeline.run(signal));
|
|
26
|
+
const reportResidentError = (label) => async (error) => {
|
|
27
|
+
process.stderr.write(`Wake ${label} tick failed: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
28
|
+
};
|
|
29
|
+
// Only intake unconditionally polls a rate-limited external API (GitHub),
|
|
30
|
+
// so only its resident loop backs off exponentially when idle. The
|
|
31
|
+
// runner loop (schedules, reactors, Advancement, delivery, GitHub label
|
|
32
|
+
// maintenance) stays on a fast, fixed cadence when it simply has nothing
|
|
33
|
+
// to do locally — mirroring legacy src/core/control-plane.ts's
|
|
34
|
+
// `runIntakeTick`/`runRunnerTick` split (idleBackoff: true vs false), just
|
|
35
|
+
// as two ResidentHosts instead of two hand-rolled loops. But some runner
|
|
36
|
+
// stages (deliver, label maintenance) DO call that same external API, so a
|
|
37
|
+
// run of consecutive *errors* — as opposed to ordinary "no local work"
|
|
38
|
+
// idling — still backs off exponentially, or a live rate-limit window gets
|
|
39
|
+
// hammered every cycle instead of given a chance to recover.
|
|
40
|
+
const runnerResident = new ResidentHost(runnerTick, (signal, { consecutiveIdleTicks, consecutiveErrorTicks }) => {
|
|
41
|
+
if (consecutiveErrorTicks > 0)
|
|
42
|
+
return sleepUntilAbort(signal, nextIdleBackoffMs(root.config.controlPlane.resident, consecutiveErrorTicks));
|
|
43
|
+
return consecutiveIdleTicks === 0
|
|
44
|
+
? Promise.resolve()
|
|
45
|
+
: sleepUntilAbort(signal, root.config.controlPlane.resident?.idleBackoffMs ?? 1000);
|
|
46
|
+
}, reportResidentError('runner'));
|
|
47
|
+
const intakeResident = new ResidentHost(intakeHost, (signal, { consecutiveIdleTicks }) => sleepUntilAbort(signal, nextIdleBackoffMs(root.config.controlPlane.resident, consecutiveIdleTicks)), reportResidentError('intake'));
|
|
48
|
+
const servers = new Set();
|
|
49
|
+
const startHttp = createHttpStarter(root, api, servers);
|
|
50
|
+
return {
|
|
51
|
+
tick: {
|
|
52
|
+
async run(budget) {
|
|
53
|
+
// Mirrors legacy's combined one-shot `runTick`: intake once, then
|
|
54
|
+
// let the runner loop drain up to its own budget.
|
|
55
|
+
await intakeHost.run(budget);
|
|
56
|
+
return runnerTick.run(budget);
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
start: {
|
|
60
|
+
async run(signal, budget) {
|
|
61
|
+
if (root.config.surfaces.web.enabled)
|
|
62
|
+
await startHttp({}, true);
|
|
63
|
+
else if (root.config.surfaces.api.enabled)
|
|
64
|
+
await startHttp({}, false);
|
|
65
|
+
// Runs on its own cadence, independent of both resident loops:
|
|
66
|
+
// `advance()` blocks for an activity's full duration before the
|
|
67
|
+
// runner loop's own catchUpProjections runs again, so without this
|
|
68
|
+
// pump, projections (e.g. the board's active-run card) never
|
|
69
|
+
// reflect a run in progress — only its state before and after.
|
|
70
|
+
const projectionPump = runProjectionPump(root, signal);
|
|
71
|
+
const intakeRun = intakeResident.run(signal, budget);
|
|
72
|
+
try {
|
|
73
|
+
return await runnerResident.run(signal, budget);
|
|
74
|
+
}
|
|
75
|
+
finally {
|
|
76
|
+
await intakeRun;
|
|
77
|
+
await projectionPump;
|
|
78
|
+
await closeAll(servers);
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
stop: {
|
|
83
|
+
stop: async () => {
|
|
84
|
+
await waitForActiveRuns({
|
|
85
|
+
activeRunIds: () => activeExecutionRunIds(root),
|
|
86
|
+
sleep: async (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)),
|
|
87
|
+
});
|
|
88
|
+
await closeAll(servers);
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
api: { start: (options) => startHttp(options, false) },
|
|
92
|
+
ui: { start: (options) => startHttp(options, true) },
|
|
93
|
+
audit: {
|
|
94
|
+
async read(id) {
|
|
95
|
+
return (await root.journal.readAll(0))
|
|
96
|
+
.filter((event) => event.stream.kind === WorkStreamKind.WorkItem && event.stream.id === id)
|
|
97
|
+
.map((event) => ({
|
|
98
|
+
eventId: event.eventId,
|
|
99
|
+
eventType: event.eventType,
|
|
100
|
+
occurredAt: event.occurredAt,
|
|
101
|
+
stream: `${event.stream.kind}:${event.stream.id}`,
|
|
102
|
+
causationId: event.causationId,
|
|
103
|
+
correlationId: event.correlationId,
|
|
104
|
+
}));
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
correlate: {
|
|
108
|
+
async correlate(resource, work) {
|
|
109
|
+
return root.resources.correlate(resourceId(resource), workItemId(work), ResourceCorrelationRole.Primary, commandContext(`correlate:${resource}:${work}`, now()));
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
validateState: createValidationApplications(root),
|
|
113
|
+
sandboxRuntime: createSandboxRuntimeApplications(root),
|
|
114
|
+
operational: createOperationalApplications(root),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
export async function runProjectionPump(root, signal) {
|
|
118
|
+
const intervalMs = 1000;
|
|
119
|
+
while (!signal.aborted) {
|
|
120
|
+
try {
|
|
121
|
+
if (!(await root.isPaused()))
|
|
122
|
+
await root.projectionRunner.runRegisteredOnce();
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
process.stderr.write(`Wake projection pump failed: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
126
|
+
}
|
|
127
|
+
await sleepUntilAbort(signal, intervalMs);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function nextIdleBackoffMs(resident, consecutiveIdleTicks) {
|
|
131
|
+
const baseMs = resident?.idleBackoffMs ?? 1000;
|
|
132
|
+
const maxMs = resident?.maxIdleBackoffMs ?? baseMs * 16;
|
|
133
|
+
return Math.min(baseMs * 2 ** Math.min(consecutiveIdleTicks, 20), maxMs);
|
|
134
|
+
}
|
|
135
|
+
function sleepUntilAbort(signal, milliseconds) {
|
|
136
|
+
return new Promise((resolve) => {
|
|
137
|
+
if (signal.aborted)
|
|
138
|
+
return resolve();
|
|
139
|
+
const timeout = setTimeout(resolve, milliseconds);
|
|
140
|
+
signal.addEventListener('abort', () => {
|
|
141
|
+
clearTimeout(timeout);
|
|
142
|
+
resolve();
|
|
143
|
+
}, { once: true });
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
function createHttpStarter(root, api, servers) {
|
|
147
|
+
return async (options = {}, web = false) => {
|
|
148
|
+
const assets = web ? createPackagedAssetSource() : undefined;
|
|
149
|
+
if (web && (await assets.get('/index.html')) === undefined)
|
|
150
|
+
throw new Error('Packaged Wake web assets are missing');
|
|
151
|
+
const server = createApiHttpServer(createApiDispatcher(api), assets);
|
|
152
|
+
servers.add(server);
|
|
153
|
+
server.listen(options.port ?? root.config.surfaces.api.port, options.host ?? root.config.surfaces.api.host);
|
|
154
|
+
try {
|
|
155
|
+
await Promise.race([
|
|
156
|
+
once(server, 'listening'),
|
|
157
|
+
once(server, 'error').then(([error]) => Promise.reject(error)),
|
|
158
|
+
]);
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
servers.delete(server);
|
|
162
|
+
throw error;
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
function createDockerCliForRoot(root) {
|
|
167
|
+
return createLoggedDockerCli({
|
|
168
|
+
execute: (arguments_, onChunk, options) => spawnDocker(arguments_, onChunk, root.paths.wakeRoot, options),
|
|
169
|
+
}, createProcessLogSink(join(root.paths.wakeRoot, 'logs', 'sandbox.log'), { write: (value) => process.stdout.write(value) }, { maxBytes: 10 * 1024 * 1024 }));
|
|
170
|
+
}
|
|
171
|
+
function sandboxDockerOptions(root, overrides) {
|
|
172
|
+
return {
|
|
173
|
+
wakeRoot: root.paths.wakeRoot,
|
|
174
|
+
containerHomeRoot: root.paths.containerHomeRoot,
|
|
175
|
+
image: overrides?.image ?? root.config.host.sandbox.image,
|
|
176
|
+
development: root.config.host.development,
|
|
177
|
+
containerName: root.config.host.sandbox.containerName,
|
|
178
|
+
...(root.config.surfaces.api.enabled ? { publishedPort: root.config.surfaces.api.port } : {}),
|
|
179
|
+
wakeMountPath: root.config.host.sandbox.wakeMountPath,
|
|
180
|
+
containerHomeMountPath: root.config.host.sandbox.containerHomeMountPath,
|
|
181
|
+
extraMounts: root.config.host.sandbox.extraMounts,
|
|
182
|
+
startEnabled: root.config.host.sandbox.start.enabled,
|
|
183
|
+
inspect: createDockerInspection(root.paths.wakeRoot),
|
|
184
|
+
resolveBuildVersion: () => resolveSandboxBuildVersion(root),
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
function createSandboxDocker(root, overrides) {
|
|
188
|
+
return createSandboxDockerPort(createDockerCliForRoot(root), sandboxDockerOptions(root, overrides));
|
|
189
|
+
}
|
|
190
|
+
async function resolveSandboxBuildVersion(root) {
|
|
191
|
+
const development = root.config.host.development;
|
|
192
|
+
return development.mode === 'source' && development.repoRoot !== undefined
|
|
193
|
+
? resolveWakeVersion({ repoRoot: development.repoRoot })
|
|
194
|
+
: wakeVersion;
|
|
195
|
+
}
|
|
196
|
+
function sandboxWakeInvocation(root) {
|
|
197
|
+
return root.config.host.development.mode === 'source'
|
|
198
|
+
? ['node', '/app/dist/src/main.js']
|
|
199
|
+
: ['wake'];
|
|
200
|
+
}
|
|
201
|
+
async function activeExecutionRuns(root) {
|
|
202
|
+
return (await root.execution.list())
|
|
203
|
+
.filter((run) => run.status === RunStatus.Started || run.status === RunStatus.Ambiguous)
|
|
204
|
+
.map((run) => ({
|
|
205
|
+
runId: run.runId,
|
|
206
|
+
maintenanceCancellable: run.status === RunStatus.Started && run.cancellation === undefined,
|
|
207
|
+
}));
|
|
208
|
+
}
|
|
209
|
+
async function activeExecutionRunIds(root) {
|
|
210
|
+
return (await root.execution.list())
|
|
211
|
+
.filter((run) => run.status === RunStatus.Started)
|
|
212
|
+
.map((run) => run.runId);
|
|
213
|
+
}
|
|
214
|
+
/** The production maintenance boundary shared by the CLI update application. */
|
|
215
|
+
export function createSelfUpdateQuiescePort(root) {
|
|
216
|
+
return {
|
|
217
|
+
acquire: (tag, retryFailed) => root.maintenance.acquire(tag, retryFailed),
|
|
218
|
+
exclusive: (tag, retryFailed, operation) => root.maintenance.runExclusive(tag, retryFailed, operation),
|
|
219
|
+
activeRuns: () => activeExecutionRuns(root),
|
|
220
|
+
requestMaintenanceCancellation: async (runIds) => {
|
|
221
|
+
for (const runId of runIds)
|
|
222
|
+
await root.execution.requestCancellation(runId, ExecutionCancellationReason.Maintenance);
|
|
223
|
+
},
|
|
224
|
+
sleep: (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)),
|
|
225
|
+
now: () => Date.now(),
|
|
226
|
+
fail: async (error, attemptId) => {
|
|
227
|
+
await root.maintenance.fail(error, attemptId);
|
|
228
|
+
},
|
|
229
|
+
transition: async (phase, attemptId) => {
|
|
230
|
+
await root.maintenance.transition(phase, attemptId);
|
|
231
|
+
},
|
|
232
|
+
clear: (attemptId) => root.maintenance.clear(attemptId),
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
function createSandboxRuntimeApplications(root) {
|
|
236
|
+
const docker = createSandboxDocker(root);
|
|
237
|
+
const wakeInvocation = sandboxWakeInvocation(root);
|
|
238
|
+
return {
|
|
239
|
+
async hasDockerfile() {
|
|
240
|
+
try {
|
|
241
|
+
await access(join(root.paths.wakeRoot, 'docker', 'Dockerfile'));
|
|
242
|
+
return true;
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
exec: (arguments_) => docker.exec([...wakeInvocation, ...arguments_]),
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Builds a running self-update on the sandbox container onto a specific
|
|
253
|
+
* image tag: rebuild the image, swap the container onto it, and confirm the
|
|
254
|
+
* resident `wake start` process actually came back up. Reused for both the
|
|
255
|
+
* forward deploy and a same-shaped rollback to a previously-built tag.
|
|
256
|
+
*/
|
|
257
|
+
async function deploySandboxTag(root, docker, tag, image) {
|
|
258
|
+
const port = createSandboxDockerPort(docker, sandboxDockerOptions(root, { image }));
|
|
259
|
+
await port.build();
|
|
260
|
+
await port.update();
|
|
261
|
+
const wakeInvocation = sandboxWakeInvocation(root);
|
|
262
|
+
await verifyResidentStart(docker, root.config.host.sandbox.containerName, [...wakeInvocation, 'start', '--wake-root', '/wake'].join(' '));
|
|
263
|
+
await port.exec(['tick', '--wake-root', `/tmp/wake-self-update-healthcheck-${tag}`]);
|
|
264
|
+
}
|
|
265
|
+
async function rollbackSandboxTag(root, docker, image) {
|
|
266
|
+
const port = createSandboxDockerPort(docker, sandboxDockerOptions(root, { image }));
|
|
267
|
+
await port.update();
|
|
268
|
+
const wakeInvocation = sandboxWakeInvocation(root);
|
|
269
|
+
await verifyResidentStart(docker, root.config.host.sandbox.containerName, [...wakeInvocation, 'start', '--wake-root', '/wake'].join(' '));
|
|
270
|
+
}
|
|
271
|
+
function createOperationalApplications(root) {
|
|
272
|
+
return {
|
|
273
|
+
init: async () => unsupportedOperationalCommand('init'),
|
|
274
|
+
doctor: async (arguments_) => runDoctor({
|
|
275
|
+
rebuildProjections: arguments_.includes('--rebuild-projections'),
|
|
276
|
+
diagnose: async () => doctorDiagnostics(root),
|
|
277
|
+
projections: {
|
|
278
|
+
health: async () => projectionHealth(root),
|
|
279
|
+
rebuild: async () => {
|
|
280
|
+
for (const definition of runtimeProjectionDefinitions)
|
|
281
|
+
await root.projectionRunner.rebuild(definition);
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
}),
|
|
285
|
+
sandboxSetup: async (arguments_) => {
|
|
286
|
+
if (arguments_.length > 0)
|
|
287
|
+
throw new Error('wake sandbox-setup accepts no arguments');
|
|
288
|
+
await runSandboxSetup(createSandboxSetupDependencies(root.config.host.sandbox.containerHomeMountPath));
|
|
289
|
+
},
|
|
290
|
+
sandbox: async (arguments_) => runSandbox(arguments_, createSandboxDocker(root)),
|
|
291
|
+
sandboxEntrypoint: async () => {
|
|
292
|
+
await runSandboxEntrypoint(createSandboxEntrypointDependencies(root));
|
|
293
|
+
},
|
|
294
|
+
selfUpdate: async (arguments_) => {
|
|
295
|
+
if (root.config.host.development.mode !== 'source')
|
|
296
|
+
throw new Error('wake self-update requires host.development.mode: source');
|
|
297
|
+
const repoRoot = root.config.host.development.repoRoot;
|
|
298
|
+
if (repoRoot === undefined)
|
|
299
|
+
throw new Error('wake self-update requires host.development.repoRoot');
|
|
300
|
+
const tag = optionalOperationalOption(arguments_, '--tag');
|
|
301
|
+
const dockerCli = createDockerCliForRoot(root);
|
|
302
|
+
const imageRepository = root.config.host.sandbox.imageRepository;
|
|
303
|
+
const failureLog = createSelfUpdateFailureLog(root.paths.wakeRoot);
|
|
304
|
+
const application = createSelfUpdateApplication({
|
|
305
|
+
ledger: createUpdateLedger(root.paths.wakeRoot),
|
|
306
|
+
source: createSourceUpdatePort({ repoRoot }),
|
|
307
|
+
rollout: {
|
|
308
|
+
async deploy(deployTag) {
|
|
309
|
+
await waitForActiveRuns({
|
|
310
|
+
activeRunIds: () => activeExecutionRunIds(root),
|
|
311
|
+
sleep: async (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)),
|
|
312
|
+
});
|
|
313
|
+
await deploySandboxTag(root, dockerCli, deployTag, `${imageRepository}:${deployTag}`);
|
|
314
|
+
// A later deploy succeeding after a prior rollback clears the stale warning.
|
|
315
|
+
await failureLog.clear();
|
|
316
|
+
},
|
|
317
|
+
async rollback(rollbackTag) {
|
|
318
|
+
await rollbackSandboxTag(root, dockerCli, `${imageRepository}:${rollbackTag}`);
|
|
319
|
+
},
|
|
320
|
+
recordFailure: (failedTag, error) => failureLog.record(failedTag, error),
|
|
321
|
+
},
|
|
322
|
+
quiesce: createSelfUpdateQuiescePort(root),
|
|
323
|
+
drainTimeoutMs: root.config.host.selfUpdate.drainTimeoutMs,
|
|
324
|
+
cancellationTimeoutMs: root.config.host.selfUpdate.cancellationTimeoutMs,
|
|
325
|
+
});
|
|
326
|
+
const force = arguments_.includes('--force');
|
|
327
|
+
if (arguments_.includes('--loop')) {
|
|
328
|
+
const intervalMs = selfUpdateLoopInterval(arguments_);
|
|
329
|
+
if (tag !== undefined)
|
|
330
|
+
return runSelfUpdateLatestLoop(async () => application.update(tag, force), () => delay(intervalMs));
|
|
331
|
+
return runSelfUpdateLatestLoop(async () => application.updateLatest(force), () => delay(intervalMs));
|
|
332
|
+
}
|
|
333
|
+
if (tag !== undefined)
|
|
334
|
+
return { tag, updated: await application.update(tag, force) };
|
|
335
|
+
return application.updateLatest(force);
|
|
336
|
+
},
|
|
337
|
+
smoke: async () => runTargetSmoke(createRunnerRegistry(root.config.execution, root.fakeScenarios), root.config.execution.defaultRunnerPool, new AbortController().signal),
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
function createDockerInspection(wakeRoot) {
|
|
341
|
+
return {
|
|
342
|
+
async imageExists(image) {
|
|
343
|
+
try {
|
|
344
|
+
await execFile('docker', ['image', 'inspect', image], { cwd: wakeRoot });
|
|
345
|
+
return true;
|
|
346
|
+
}
|
|
347
|
+
catch {
|
|
348
|
+
return false;
|
|
349
|
+
}
|
|
350
|
+
},
|
|
351
|
+
async containerState(containerName) {
|
|
352
|
+
try {
|
|
353
|
+
const result = await execFile('docker', ['container', 'inspect', '-f', '{{.State.Running}}', containerName], { cwd: wakeRoot });
|
|
354
|
+
return result.stdout.trim() === 'true' ? 'live' : 'halted';
|
|
355
|
+
}
|
|
356
|
+
catch {
|
|
357
|
+
return null;
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Spawns `docker` directly (not execFile) so stdout/stderr chunks reach the
|
|
364
|
+
* caller as they arrive, letting the sandbox log sink write incrementally
|
|
365
|
+
* during a long `build`/`up` instead of buffering until exit. Rejects on a
|
|
366
|
+
* non-zero exit, matching execFile's throw-on-failure contract.
|
|
367
|
+
*/
|
|
368
|
+
function spawnDocker(arguments_, onChunk, cwd, options) {
|
|
369
|
+
return new Promise((resolve, reject) => {
|
|
370
|
+
const child = spawn('docker', [...arguments_], options?.interactive ? { cwd, stdio: 'inherit' } : { cwd });
|
|
371
|
+
if (options?.interactive) {
|
|
372
|
+
child.on('error', reject);
|
|
373
|
+
child.on('close', (code) => {
|
|
374
|
+
if (code === 0)
|
|
375
|
+
resolve();
|
|
376
|
+
else
|
|
377
|
+
reject(new Error('docker ' + arguments_.join(' ') + ' exited with code ' + String(code)));
|
|
378
|
+
});
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
let chain = Promise.resolve();
|
|
382
|
+
let stderrTail = '';
|
|
383
|
+
const enqueue = (stream, text) => {
|
|
384
|
+
if (stream === 'stderr')
|
|
385
|
+
stderrTail = `${stderrTail}${text}`.slice(-4000);
|
|
386
|
+
chain = chain.then(() => onChunk({ stream, text }));
|
|
387
|
+
};
|
|
388
|
+
child.stdout.on('data', (buffer) => enqueue('stdout', buffer.toString('utf8')));
|
|
389
|
+
child.stderr.on('data', (buffer) => enqueue('stderr', buffer.toString('utf8')));
|
|
390
|
+
child.on('error', (error) => {
|
|
391
|
+
void chain.then(() => reject(error));
|
|
392
|
+
});
|
|
393
|
+
child.on('close', (code) => {
|
|
394
|
+
void chain.then(() => {
|
|
395
|
+
if (code === 0)
|
|
396
|
+
resolve();
|
|
397
|
+
else {
|
|
398
|
+
const detail = stderrTail.trim();
|
|
399
|
+
reject(new Error(`docker ${arguments_.join(' ')} exited with code ${String(code)}` +
|
|
400
|
+
(detail.length > 0 ? `: ${detail}` : '')));
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
});
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
async function doctorDiagnostics(root) {
|
|
407
|
+
const failures = [];
|
|
408
|
+
const notices = [];
|
|
409
|
+
try {
|
|
410
|
+
createRunnerRegistry(root.config.execution, root.fakeScenarios).resolve(root.config.execution.defaultRunnerPool);
|
|
411
|
+
}
|
|
412
|
+
catch (error) {
|
|
413
|
+
failures.push(`runner pool availability: ${error.message}`);
|
|
414
|
+
}
|
|
415
|
+
try {
|
|
416
|
+
await loadConfig(root.paths.wakeRoot);
|
|
417
|
+
}
|
|
418
|
+
catch (error) {
|
|
419
|
+
failures.push(`configuration validation failed: ${error.message}`);
|
|
420
|
+
}
|
|
421
|
+
for (const name of referencedPromptTemplateNames(root.config.orchestration.workflows)) {
|
|
422
|
+
try {
|
|
423
|
+
await loadPromptTemplate(root.paths.wakeRoot, name);
|
|
424
|
+
}
|
|
425
|
+
catch (error) {
|
|
426
|
+
failures.push(`prompt template "${name}" is not readable: ${error.message}`);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
await checkProviders(root, failures, notices);
|
|
430
|
+
notices.push(...(await dockerSandboxHealthNotices(root)));
|
|
431
|
+
for (const [name, path] of Object.entries({
|
|
432
|
+
events: root.paths.eventsRoot,
|
|
433
|
+
projections: root.paths.projectionsRoot,
|
|
434
|
+
checkpoints: root.paths.checkpointsRoot,
|
|
435
|
+
locks: root.paths.locksRoot,
|
|
436
|
+
transcripts: root.paths.transcriptsRoot,
|
|
437
|
+
workspaces: root.paths.workspacesRoot,
|
|
438
|
+
})) {
|
|
439
|
+
try {
|
|
440
|
+
await access(path);
|
|
441
|
+
}
|
|
442
|
+
catch {
|
|
443
|
+
failures.push(name + ' runtime directory is not accessible: ' + path);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
return { failures, notices };
|
|
447
|
+
}
|
|
448
|
+
// Derives the prompt template names doctor must validate from what configured
|
|
449
|
+
// workflows actually reference, rather than a hardcoded filename that may not
|
|
450
|
+
// correspond to anything a given deployment's workflows use.
|
|
451
|
+
function referencedPromptTemplateNames(workflows) {
|
|
452
|
+
const names = new Set();
|
|
453
|
+
for (const workflow of Object.values(workflows)) {
|
|
454
|
+
for (const stage of Object.values(workflow.stages)) {
|
|
455
|
+
if (stage.activity !== BuiltInActivityName.Agent)
|
|
456
|
+
continue;
|
|
457
|
+
const parsed = agentActivityDefinition.inputSchema.safeParse(stage.with);
|
|
458
|
+
if (parsed.success && parsed.data.template !== undefined)
|
|
459
|
+
names.add(parsed.data.template);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
return [...names];
|
|
463
|
+
}
|
|
464
|
+
async function checkProviders(root, failures, notices) {
|
|
465
|
+
for (const provider of root.providers) {
|
|
466
|
+
if (provider.adapter.trim().length === 0) {
|
|
467
|
+
failures.push('configured provider has no adapter identity');
|
|
468
|
+
continue;
|
|
469
|
+
}
|
|
470
|
+
if (provider.checkConnectivity === undefined)
|
|
471
|
+
continue;
|
|
472
|
+
try {
|
|
473
|
+
await provider.checkConnectivity();
|
|
474
|
+
}
|
|
475
|
+
catch (error) {
|
|
476
|
+
failures.push(`provider "${provider.adapter}" is not reachable: ${error.message}`);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
for (const failure of root.providerFailures)
|
|
480
|
+
failures.push(`provider "${failure.adapter}" failed to initialize: ${failure.error}`);
|
|
481
|
+
if (root.providers.length === 0 &&
|
|
482
|
+
root.providerFailures.length === 0 &&
|
|
483
|
+
Object.keys(root.config.integrations).length > 0)
|
|
484
|
+
notices.push('no enabled integration provider is available');
|
|
485
|
+
}
|
|
486
|
+
// Docker/sandbox absence must never fail doctor: target deployments may not
|
|
487
|
+
// use the Docker sandbox at all, so every outcome here is informational.
|
|
488
|
+
async function dockerSandboxHealthNotices(root) {
|
|
489
|
+
const inspect = createDockerInspection(root.paths.wakeRoot);
|
|
490
|
+
const image = root.config.host.sandbox.image;
|
|
491
|
+
const containerName = root.config.host.sandbox.containerName;
|
|
492
|
+
if (!(await inspect.imageExists(image)))
|
|
493
|
+
return [
|
|
494
|
+
`Docker sandbox image "${image}" was not found (or Docker is unavailable) — run \`wake sandbox build\` if this deployment uses the Docker sandbox`,
|
|
495
|
+
];
|
|
496
|
+
const state = await inspect.containerState(containerName);
|
|
497
|
+
if (state === 'halted')
|
|
498
|
+
return [
|
|
499
|
+
`Docker sandbox container "${containerName}" is stopped — run \`wake sandbox up\` to resume it`,
|
|
500
|
+
];
|
|
501
|
+
if (state === null)
|
|
502
|
+
return [
|
|
503
|
+
`Docker sandbox container "${containerName}" was not found — run \`wake sandbox up\` if this deployment uses the Docker sandbox`,
|
|
504
|
+
];
|
|
505
|
+
return [];
|
|
506
|
+
}
|
|
507
|
+
async function projectionHealth(root) {
|
|
508
|
+
const failures = [];
|
|
509
|
+
try {
|
|
510
|
+
await root.journal.readAll(0, 1);
|
|
511
|
+
}
|
|
512
|
+
catch (error) {
|
|
513
|
+
failures.push(`journal: ${error.message}`);
|
|
514
|
+
}
|
|
515
|
+
for (const definition of runtimeProjectionDefinitions) {
|
|
516
|
+
try {
|
|
517
|
+
await root.projections.list(definition.name);
|
|
518
|
+
}
|
|
519
|
+
catch (error) {
|
|
520
|
+
failures.push(`${definition.name}: ${error.message}`);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
try {
|
|
524
|
+
await root.checkpoints.load('surface-health');
|
|
525
|
+
}
|
|
526
|
+
catch (error) {
|
|
527
|
+
failures.push(`checkpoints: ${error.message}`);
|
|
528
|
+
}
|
|
529
|
+
return {
|
|
530
|
+
journal: failures.some((failure) => failure.startsWith('journal:')) ? 'unhealthy' : 'ok',
|
|
531
|
+
projections: failures.filter((failure) => !failure.startsWith('journal:') && !failure.startsWith('checkpoints:')),
|
|
532
|
+
checkpoints: failures.some((failure) => failure.startsWith('checkpoints:'))
|
|
533
|
+
? 'unhealthy'
|
|
534
|
+
: 'ok',
|
|
535
|
+
};
|
|
536
|
+
}
|
|
537
|
+
function selfUpdateLoopInterval(arguments_) {
|
|
538
|
+
const value = optionalOperationalOption(arguments_, '--loop-interval-ms');
|
|
539
|
+
if (value === undefined)
|
|
540
|
+
return 60_000;
|
|
541
|
+
const interval = Number(value);
|
|
542
|
+
if (!Number.isInteger(interval) || interval <= 0)
|
|
543
|
+
throw new Error('wake self-update --loop-interval-ms must be a positive integer');
|
|
544
|
+
return interval;
|
|
545
|
+
}
|
|
546
|
+
function delay(milliseconds) {
|
|
547
|
+
return new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
548
|
+
}
|
|
549
|
+
function optionalOperationalOption(arguments_, option) {
|
|
550
|
+
const index = arguments_.indexOf(option);
|
|
551
|
+
if (index === -1)
|
|
552
|
+
return undefined;
|
|
553
|
+
const value = arguments_[index + 1];
|
|
554
|
+
if (value === undefined || value.startsWith('--'))
|
|
555
|
+
throw new Error(`wake self-update requires ${option} <value>`);
|
|
556
|
+
return value;
|
|
557
|
+
}
|
|
558
|
+
function unsupportedOperationalCommand(command) {
|
|
559
|
+
throw new Error(`wake ${command} has not been composed`);
|
|
560
|
+
}
|
|
561
|
+
function createValidationApplications(root) {
|
|
562
|
+
return {
|
|
563
|
+
async health() {
|
|
564
|
+
await root.journal.readAll(0, 1);
|
|
565
|
+
await root.projections.list('work');
|
|
566
|
+
await root.checkpoints.load('surface-health');
|
|
567
|
+
return { journal: 'ok', projections: 'ok', checkpoints: 'ok' };
|
|
568
|
+
},
|
|
569
|
+
async rebuildProjections() {
|
|
570
|
+
for (const definition of runtimeProjectionDefinitions)
|
|
571
|
+
await root.projectionRunner.rebuild(definition);
|
|
572
|
+
},
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
function commandContext(commandId, occurredAt) {
|
|
576
|
+
return {
|
|
577
|
+
commandId,
|
|
578
|
+
correlationId: correlationId(commandId),
|
|
579
|
+
occurredAt,
|
|
580
|
+
actor: { kind: EventActorKind.Operator, id: 'cli' },
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
async function closeAll(servers) {
|
|
584
|
+
await Promise.all([...servers].map(async (server) => {
|
|
585
|
+
if (!server.listening)
|
|
586
|
+
return;
|
|
587
|
+
server.close();
|
|
588
|
+
await once(server, 'close');
|
|
589
|
+
servers.delete(server);
|
|
590
|
+
}));
|
|
591
|
+
}
|
|
592
|
+
const DEFAULT_START_RESTART_DELAY_SECONDS = 10;
|
|
593
|
+
function createSandboxEntrypointDependencies(root) {
|
|
594
|
+
const logDirectory = join(root.paths.dataRoot, 'logs');
|
|
595
|
+
const pidFile = join(logDirectory, 'start.pid');
|
|
596
|
+
const startLogFile = join(logDirectory, 'start.log');
|
|
597
|
+
const children = new Map();
|
|
598
|
+
return {
|
|
599
|
+
startEnabled: process.env.WAKE_START_ENABLED === 'true',
|
|
600
|
+
restartDelaySeconds: resolveRestartDelaySeconds(process.env),
|
|
601
|
+
wakeInvocation: sandboxWakeInvocation(root),
|
|
602
|
+
pidFile,
|
|
603
|
+
startLogFile,
|
|
604
|
+
ensureLogDirectory: async () => {
|
|
605
|
+
await mkdir(logDirectory, { recursive: true });
|
|
606
|
+
},
|
|
607
|
+
spawnDetached: (command, arguments_, options) => {
|
|
608
|
+
const sink = createProcessLogSink(options.logFile, { write: () => { } }, { maxBytes: 10 * 1024 * 1024 });
|
|
609
|
+
const child = spawn(command, [...arguments_], {
|
|
610
|
+
cwd: root.paths.wakeRoot,
|
|
611
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
612
|
+
detached: true,
|
|
613
|
+
});
|
|
614
|
+
if (typeof child.pid !== 'number')
|
|
615
|
+
throw new Error('failed to spawn detached wake start process');
|
|
616
|
+
let closeStatus = 1;
|
|
617
|
+
const closed = new Promise((resolve) => {
|
|
618
|
+
child.once('close', (code) => {
|
|
619
|
+
closeStatus = code ?? 1;
|
|
620
|
+
resolve();
|
|
621
|
+
});
|
|
622
|
+
});
|
|
623
|
+
const drained = drainProcessOutput(child, sink, (error) => {
|
|
624
|
+
process.stderr.write(`Wake detached start log failure: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
625
|
+
});
|
|
626
|
+
const completion = closed.then(() => drained).then(() => closeStatus);
|
|
627
|
+
children.set(child.pid, completion);
|
|
628
|
+
void completion.then(() => children.delete(child.pid));
|
|
629
|
+
child.unref();
|
|
630
|
+
return { pid: child.pid };
|
|
631
|
+
},
|
|
632
|
+
waitForExit: async (pid) => children.get(pid) ?? 1,
|
|
633
|
+
writeFile: (path, content) => writeFileContent(path, content, 'utf8'),
|
|
634
|
+
sleep: (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)),
|
|
635
|
+
waitForever: () => new Promise(() => { }),
|
|
636
|
+
log: (message) => process.stdout.write(`${message}\n`),
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
function resolveRestartDelaySeconds(env) {
|
|
640
|
+
const value = env.WAKE_START_RESTART_DELAY_SECONDS;
|
|
641
|
+
if (value === undefined)
|
|
642
|
+
return DEFAULT_START_RESTART_DELAY_SECONDS;
|
|
643
|
+
const seconds = Number(value);
|
|
644
|
+
return Number.isFinite(seconds) && seconds > 0 ? seconds : DEFAULT_START_RESTART_DELAY_SECONDS;
|
|
645
|
+
}
|
|
646
|
+
function createSandboxSetupDependencies(home) {
|
|
647
|
+
const codexHome = join(home, '.codex');
|
|
648
|
+
const codexRuntimeHome = join(home, '.codex-runtime');
|
|
649
|
+
return {
|
|
650
|
+
prompt: async (message) => {
|
|
651
|
+
const readline = createInterface({ input: process.stdin, output: process.stdout });
|
|
652
|
+
try {
|
|
653
|
+
return /^(y|yes)$/i.test((await readline.question(`${message} `)).trim());
|
|
654
|
+
}
|
|
655
|
+
finally {
|
|
656
|
+
readline.close();
|
|
657
|
+
}
|
|
658
|
+
},
|
|
659
|
+
runInteractive,
|
|
660
|
+
ensureSshKey: async () => {
|
|
661
|
+
const sshDirectory = join(home, '.ssh');
|
|
662
|
+
const privateKey = join(sshDirectory, 'id_ed25519');
|
|
663
|
+
if (await isReadable(privateKey))
|
|
664
|
+
return;
|
|
665
|
+
await mkdir(sshDirectory, { recursive: true, mode: 0o700 });
|
|
666
|
+
await runInteractive('ssh-keygen', ['-t', 'ed25519', '-f', privateKey, '-N', '']);
|
|
667
|
+
},
|
|
668
|
+
prepareCodexHome: async () => {
|
|
669
|
+
await mkdir(codexRuntimeHome, { recursive: true });
|
|
670
|
+
const config = join(codexHome, 'config.toml');
|
|
671
|
+
if (await isReadable(config))
|
|
672
|
+
await copyFile(config, join(codexRuntimeHome, 'config.toml'));
|
|
673
|
+
const sourceAuth = join(codexHome, 'auth.json');
|
|
674
|
+
const targetAuth = join(codexRuntimeHome, 'auth.json');
|
|
675
|
+
if ((await isReadable(sourceAuth)) && !(await isReadable(targetAuth)))
|
|
676
|
+
await copyFile(sourceAuth, targetAuth);
|
|
677
|
+
},
|
|
678
|
+
log: (message) => process.stdout.write(`${message}\n`),
|
|
679
|
+
};
|
|
680
|
+
}
|
|
681
|
+
async function isReadable(path) {
|
|
682
|
+
try {
|
|
683
|
+
await access(path);
|
|
684
|
+
return true;
|
|
685
|
+
}
|
|
686
|
+
catch {
|
|
687
|
+
return false;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
function runInteractive(command, arguments_) {
|
|
691
|
+
return new Promise((resolve, reject) => {
|
|
692
|
+
const child = spawn(command, [...arguments_], { stdio: 'inherit' });
|
|
693
|
+
child.once('error', reject);
|
|
694
|
+
child.once('close', (code) => {
|
|
695
|
+
if (code === 0)
|
|
696
|
+
resolve();
|
|
697
|
+
else
|
|
698
|
+
reject(new Error(`${command} exited with code ${String(code)}`));
|
|
699
|
+
});
|
|
700
|
+
});
|
|
701
|
+
}
|