@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
package/dist/src/main.js
CHANGED
|
@@ -1,1063 +1,170 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
1
|
import { spawn } from 'node:child_process';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
import { createGitHubPullRequestActivitySource } from './adapters/github/github-pull-request-activity-source.js';
|
|
22
|
-
import { createGitHubPullRequestMergeActor } from './adapters/github/github-pull-request-merge-actor.js';
|
|
23
|
-
import { runAuditCommand } from './cli/audit-command.js';
|
|
24
|
-
import { runCorrelateCommand } from './cli/correlate-command.js';
|
|
25
|
-
import { runDoctorCommand } from './cli/doctor-command.js';
|
|
26
|
-
import { runInitCommand } from './cli/init-command.js';
|
|
27
|
-
import { runSandboxCommand } from './cli/sandbox-command.js';
|
|
28
|
-
import { runSandboxEntrypointCommand } from './cli/sandbox-entrypoint-command.js';
|
|
29
|
-
import { runSandboxSetupCommand } from './cli/sandbox-setup-command.js';
|
|
30
|
-
import { collectStartupPreflightFailures, runStartupPreflight } from './cli/startup-preflight.js';
|
|
31
|
-
import { runUiCommand } from './cli/ui-command.js';
|
|
32
|
-
import { loadWakeConfig } from './config/load-config.js';
|
|
33
|
-
import { createActiveRunRecovery } from './core/active-run-recovery.js';
|
|
34
|
-
import { createControlPlane } from './core/control-plane.js';
|
|
35
|
-
import { createOutboundSinkRouter, createWorkSourceFanIn } from './core/sink-router.js';
|
|
36
|
-
import { createScheduledWorkflowSource } from './core/scheduled-workflow-source.js';
|
|
37
|
-
import { createTickRunner } from './core/tick-runner.js';
|
|
38
|
-
import { systemClock } from './lib/clock.js';
|
|
39
|
-
import { createDetachedProcessLogSink } from './lib/detached-process-logging.js';
|
|
40
|
-
import { readJsonFile } from './lib/json-file.js';
|
|
41
|
-
import { resolveLogMaxBytes, resolveLogRotateCheckIntervalMs } from './lib/log-rotation.js';
|
|
42
|
-
import { StateHealthError } from './lib/state-health.js';
|
|
43
|
-
import { configuredTicketSource } from './domain/sources.js';
|
|
44
|
-
import { wakeVersion } from './version.js';
|
|
45
|
-
function commandArgsBeforeTerminator(args) {
|
|
46
|
-
const terminatorIndex = args.indexOf('--');
|
|
47
|
-
if (terminatorIndex === -1) {
|
|
48
|
-
return args;
|
|
49
|
-
}
|
|
50
|
-
return args.slice(0, terminatorIndex);
|
|
51
|
-
}
|
|
52
|
-
export function readFlagBeforeCommandTerminator(name, args) {
|
|
53
|
-
const scopedArgs = commandArgsBeforeTerminator(args);
|
|
54
|
-
const index = scopedArgs.indexOf(name);
|
|
55
|
-
if (index === -1) {
|
|
56
|
-
return undefined;
|
|
57
|
-
}
|
|
58
|
-
return scopedArgs[index + 1];
|
|
59
|
-
}
|
|
60
|
-
// Walks up from this file's own directory until it finds a package.json,
|
|
61
|
-
// rather than assuming a fixed number of directory levels — the file
|
|
62
|
-
// running is `dist/src/main.js` for a built/packaged install (two levels
|
|
63
|
-
// below the package root) but `src/main.ts` for a `tsx` dev invocation
|
|
64
|
-
// (only one level below), so a fixed `resolve(..., '..', '..')` overshoots
|
|
65
|
-
// the root by one directory in the latter case.
|
|
66
|
-
function resolvePackageRoot() {
|
|
67
|
-
let dir = dirname(fileURLToPath(import.meta.url));
|
|
68
|
-
for (;;) {
|
|
69
|
-
if (existsSync(join(dir, 'package.json'))) {
|
|
70
|
-
return dir;
|
|
71
|
-
}
|
|
72
|
-
const parent = dirname(dir);
|
|
73
|
-
if (parent === dir) {
|
|
74
|
-
throw new Error(`Could not locate package root (no package.json found above ${dir})`);
|
|
75
|
-
}
|
|
76
|
-
dir = parent;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
export async function hasDockerfile(wakeRoot) {
|
|
80
|
-
try {
|
|
81
|
-
await access(resolve(wakeRoot, 'docker', 'Dockerfile'));
|
|
82
|
-
return true;
|
|
83
|
-
}
|
|
84
|
-
catch {
|
|
85
|
-
return false;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
function routesOnlyToFake(config) {
|
|
89
|
-
return Object.values(config.tiers).every((candidates) => {
|
|
90
|
-
const first = candidates[0];
|
|
91
|
-
return first !== undefined && config.runners[first]?.kind === 'fake';
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
async function resolveSelfLogin(githubClient) {
|
|
95
|
-
if (githubClient === undefined) {
|
|
96
|
-
return undefined;
|
|
97
|
-
}
|
|
98
|
-
try {
|
|
99
|
-
return await githubClient.getAuthenticatedLogin();
|
|
100
|
-
}
|
|
101
|
-
catch (error) {
|
|
102
|
-
console.error(`wake: failed to resolve authenticated GitHub login; continuing without self-login bot detection: ${String(error)}`);
|
|
103
|
-
return undefined;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
export function formatTickFailureDetails(runRecord) {
|
|
107
|
-
if (runRecord === null) {
|
|
108
|
-
return null;
|
|
109
|
-
}
|
|
110
|
-
const summary = runRecord.summary?.trim();
|
|
111
|
-
const exitCode = runRecord.metadata !== undefined && typeof runRecord.metadata.exitCode === 'number'
|
|
112
|
-
? runRecord.metadata.exitCode
|
|
113
|
-
: undefined;
|
|
114
|
-
const stderr = runRecord.metadata !== undefined && typeof runRecord.metadata.stderr === 'string'
|
|
115
|
-
? runRecord.metadata.stderr.trim()
|
|
116
|
-
: '';
|
|
117
|
-
if (summary === undefined && exitCode === undefined && stderr.length === 0) {
|
|
118
|
-
return null;
|
|
119
|
-
}
|
|
120
|
-
const lines = ['Tick failure details:', `runId: ${runRecord.runId}`];
|
|
121
|
-
if (exitCode !== undefined) {
|
|
122
|
-
lines.push(`exitCode: ${exitCode}`);
|
|
123
|
-
}
|
|
124
|
-
if (summary !== undefined) {
|
|
125
|
-
lines.push('', 'Summary:', summary);
|
|
126
|
-
}
|
|
127
|
-
if (stderr.length > 0) {
|
|
128
|
-
lines.push('', 'stderr:', stderr);
|
|
2
|
+
import { access } from 'node:fs/promises';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { pathToFileURL } from 'node:url';
|
|
5
|
+
import { createCompositionRoot, createSurfaceApplications, initialiseWakeRoot, loadConfig, wakeVersion, } from './bootstrap/index.js';
|
|
6
|
+
import { parseWakeCommand, runWakeCommand, sandboxUsage, usage, } from './surfaces/index.js';
|
|
7
|
+
export async function main(argv = process.argv.slice(2), dependencies) {
|
|
8
|
+
const suppliedArguments = normalizeDeveloperAlias(argv);
|
|
9
|
+
const output = dependencies?.output ?? productionOutput();
|
|
10
|
+
if (writePrecompositionCommand(suppliedArguments, output))
|
|
11
|
+
return;
|
|
12
|
+
const resolvedDependencies = dependencies ?? productionDependencies();
|
|
13
|
+
const bypassSandbox = suppliedArguments.includes('--no-sandbox');
|
|
14
|
+
const command = parseWakeCommand(suppliedArguments.filter((argument) => argument !== '--no-sandbox'));
|
|
15
|
+
const wakeRoot = resolveWakeRoot(command);
|
|
16
|
+
if (command.kind === 'init') {
|
|
17
|
+
const result = await (resolvedDependencies.initialise ?? initialiseWakeRoot)(wakeRoot);
|
|
18
|
+
resolvedDependencies.output.write(`${JSON.stringify(result)}\n`);
|
|
19
|
+
return;
|
|
129
20
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
stdio: 'inherit',
|
|
138
|
-
});
|
|
139
|
-
child.on('error', reject);
|
|
140
|
-
child.on('close', (exitCode) => {
|
|
141
|
-
if (exitCode === 0) {
|
|
142
|
-
resolveRun();
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
reject(new Error(`${command} ${args.join(' ')} failed with exit code ${exitCode ?? 1}`));
|
|
21
|
+
if (resolvedDependencies.sandboxRuntime !== undefined) {
|
|
22
|
+
const sandboxRuntime = resolvedDependencies.sandboxRuntime;
|
|
23
|
+
const ranInSandbox = await runInSandboxIfAvailable({
|
|
24
|
+
commandKind: command.kind,
|
|
25
|
+
bypassSandbox,
|
|
26
|
+
hasDockerfile: () => sandboxRuntime.hasDockerfile(wakeRoot),
|
|
27
|
+
exec: () => sandboxRuntime.exec(wakeRoot, rewriteSandboxArguments(suppliedArguments)),
|
|
146
28
|
});
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
function parseGithubRepoSlug(remoteUrl) {
|
|
150
|
-
const match = /github\.com[:/]([^/]+\/[^/]+?)(?:\.git)?$/.exec(remoteUrl.trim());
|
|
151
|
-
if (match === null) {
|
|
152
|
-
throw new Error(`Could not parse a GitHub owner/repo from origin remote: ${remoteUrl}`);
|
|
29
|
+
if (ranInSandbox)
|
|
30
|
+
return;
|
|
153
31
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
});
|
|
163
|
-
let stdout = '';
|
|
164
|
-
child.stdout.on('data', (chunk) => {
|
|
165
|
-
stdout += chunk.toString();
|
|
32
|
+
const applications = await resolvedDependencies.compose(wakeRoot);
|
|
33
|
+
if (applications.sandboxRuntime !== undefined) {
|
|
34
|
+
const sandboxRuntime = applications.sandboxRuntime;
|
|
35
|
+
const ranInSandbox = await runInSandboxIfAvailable({
|
|
36
|
+
commandKind: command.kind,
|
|
37
|
+
bypassSandbox,
|
|
38
|
+
hasDockerfile: () => sandboxRuntime.hasDockerfile(),
|
|
39
|
+
exec: () => sandboxRuntime.exec(rewriteSandboxArguments(suppliedArguments)),
|
|
166
40
|
});
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
if (exitCode === 0) {
|
|
170
|
-
resolveRun(stdout);
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
reject(new Error(`${command} ${args.join(' ')} failed with exit code ${exitCode ?? 1}`));
|
|
174
|
-
});
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
const codexBootstrapHome = '/home/wake/.codex';
|
|
178
|
-
const codexRuntimeHome = '/home/wake/.codex-runtime';
|
|
179
|
-
const sshHome = '/home/wake/.ssh';
|
|
180
|
-
const sshKeyPath = join(sshHome, 'id_ed25519');
|
|
181
|
-
async function prepareCodexHome() {
|
|
182
|
-
await mkdir(codexRuntimeHome, { recursive: true });
|
|
183
|
-
const bootstrapConfig = join(codexBootstrapHome, 'config.toml');
|
|
184
|
-
if (existsSync(bootstrapConfig)) {
|
|
185
|
-
await copyFile(bootstrapConfig, join(codexRuntimeHome, 'config.toml'));
|
|
186
|
-
}
|
|
187
|
-
const bootstrapAuth = join(codexBootstrapHome, 'auth.json');
|
|
188
|
-
const runtimeAuth = join(codexRuntimeHome, 'auth.json');
|
|
189
|
-
if (existsSync(bootstrapAuth) && !existsSync(runtimeAuth)) {
|
|
190
|
-
await copyFile(bootstrapAuth, runtimeAuth);
|
|
191
|
-
}
|
|
192
|
-
process.env.CODEX_HOME = codexRuntimeHome;
|
|
193
|
-
}
|
|
194
|
-
async function ensureSshKey() {
|
|
195
|
-
if (!existsSync(sshKeyPath)) {
|
|
196
|
-
await mkdir(sshHome, { recursive: true, mode: 0o700 });
|
|
197
|
-
await chmod(sshHome, 0o700);
|
|
198
|
-
await runCommand('ssh-keygen', ['-t', 'ed25519', '-f', sshKeyPath, '-N', '']);
|
|
199
|
-
}
|
|
200
|
-
// Display the public key to the user
|
|
201
|
-
const publicKeyPath = join(sshHome, 'id_ed25519.pub');
|
|
202
|
-
const publicKey = await readFile(publicKeyPath, 'utf-8');
|
|
203
|
-
console.log(publicKey);
|
|
204
|
-
}
|
|
205
|
-
async function promptYesNo(message) {
|
|
206
|
-
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
207
|
-
try {
|
|
208
|
-
const answer = (await rl.question(`${message} `)).trim().toLowerCase();
|
|
209
|
-
return answer === 'y' || answer === 'yes';
|
|
210
|
-
}
|
|
211
|
-
finally {
|
|
212
|
-
rl.close();
|
|
41
|
+
if (ranInSandbox)
|
|
42
|
+
return;
|
|
213
43
|
}
|
|
44
|
+
await runWakeCommand(command, applications, resolvedDependencies.output, resolvedDependencies.signal);
|
|
214
45
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
ensureSshKey,
|
|
220
|
-
prepareCodexHome,
|
|
221
|
-
log: (message) => console.log(message),
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
const NGROK_TUNNELS_URL = 'http://127.0.0.1:4040/api/tunnels';
|
|
225
|
-
const NGROK_DISCOVERY_ATTEMPTS = 30;
|
|
226
|
-
const NGROK_DISCOVERY_INTERVAL_MS = 1000;
|
|
227
|
-
async function discoverNgrokUrl() {
|
|
228
|
-
for (let attempt = 0; attempt < NGROK_DISCOVERY_ATTEMPTS; attempt++) {
|
|
229
|
-
try {
|
|
230
|
-
const response = await fetch(NGROK_TUNNELS_URL, { signal: AbortSignal.timeout(1000) });
|
|
231
|
-
if (response.ok) {
|
|
232
|
-
const body = (await response.json());
|
|
233
|
-
const tunnels = body.tunnels ?? [];
|
|
234
|
-
const httpsTunnel = tunnels.find((tunnel) => typeof tunnel.public_url === 'string' && tunnel.public_url.startsWith('https://'));
|
|
235
|
-
const anyTunnel = httpsTunnel ?? tunnels.find((tunnel) => typeof tunnel.public_url === 'string');
|
|
236
|
-
if (typeof anyTunnel?.public_url === 'string') {
|
|
237
|
-
return anyTunnel.public_url;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
catch {
|
|
242
|
-
// ignore and retry
|
|
243
|
-
}
|
|
244
|
-
await new Promise((resolveSleep) => setTimeout(resolveSleep, NGROK_DISCOVERY_INTERVAL_MS));
|
|
245
|
-
}
|
|
246
|
-
return undefined;
|
|
46
|
+
function normalizeDeveloperAlias(arguments_) {
|
|
47
|
+
if (arguments_[0] !== 'dev' || arguments_[1] !== 'sandbox')
|
|
48
|
+
return arguments_;
|
|
49
|
+
return ['sandbox', ...arguments_.slice(2)];
|
|
247
50
|
}
|
|
248
|
-
function
|
|
249
|
-
|
|
250
|
-
return {
|
|
251
|
-
env: process.env,
|
|
252
|
-
spawnDetached: (command, args, options) => {
|
|
253
|
-
const logSink = options?.logFile !== undefined
|
|
254
|
-
? createDetachedProcessLogSink(options.logFile, {
|
|
255
|
-
maxBytes: resolveLogMaxBytes(process.env),
|
|
256
|
-
rotateCheckIntervalMs: resolveLogRotateCheckIntervalMs(process.env),
|
|
257
|
-
})
|
|
258
|
-
: undefined;
|
|
259
|
-
const child = spawn(command, args, {
|
|
260
|
-
cwd: process.cwd(),
|
|
261
|
-
env: process.env,
|
|
262
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
263
|
-
detached: true,
|
|
264
|
-
});
|
|
265
|
-
if (typeof child.pid === 'number') {
|
|
266
|
-
children.set(child.pid, child);
|
|
267
|
-
}
|
|
268
|
-
const forwardOutput = (chunk) => {
|
|
269
|
-
logSink?.write(chunk);
|
|
270
|
-
};
|
|
271
|
-
child.stdout?.on('data', forwardOutput);
|
|
272
|
-
child.stderr?.on('data', forwardOutput);
|
|
273
|
-
// Registered here (at spawn time) so it runs before any exit listener
|
|
274
|
-
// waitForExit attaches later — though it wouldn't matter either way:
|
|
275
|
-
// waitForExit captures the ChildProcess reference synchronously from
|
|
276
|
-
// `children` when it's called (before the child can possibly have
|
|
277
|
-
// exited) and attaches its own listener directly to that reference,
|
|
278
|
-
// so it never re-reads `children` inside the exit callback. Deleting
|
|
279
|
-
// the map entry here is therefore safe regardless of ordering.
|
|
280
|
-
child.on('exit', () => {
|
|
281
|
-
if (typeof child.pid === 'number') {
|
|
282
|
-
children.delete(child.pid);
|
|
283
|
-
}
|
|
284
|
-
logSink?.close().catch(() => { });
|
|
285
|
-
});
|
|
286
|
-
return { pid: child.pid ?? -1 };
|
|
287
|
-
},
|
|
288
|
-
waitForExit: (pid) => new Promise((resolveExit) => {
|
|
289
|
-
const child = children.get(pid);
|
|
290
|
-
if (child === undefined) {
|
|
291
|
-
resolveExit(1);
|
|
292
|
-
return;
|
|
293
|
-
}
|
|
294
|
-
child.on('exit', (code) => resolveExit(code ?? 1));
|
|
295
|
-
}),
|
|
296
|
-
writeFile: (path, content) => writeFile(path, content, 'utf-8'),
|
|
297
|
-
sleep: (ms) => new Promise((resolveSleep) => setTimeout(resolveSleep, ms)),
|
|
298
|
-
discoverNgrokUrl,
|
|
299
|
-
log: (message) => console.log(message),
|
|
300
|
-
ensureDir: async (path) => {
|
|
301
|
-
await mkdir(path, { recursive: true });
|
|
302
|
-
},
|
|
303
|
-
removeFile: (path) => rm(path, { force: true }),
|
|
304
|
-
};
|
|
51
|
+
function writePrecompositionCommand(arguments_, output) {
|
|
52
|
+
return writeMetaCommand(arguments_, output) || writeSandboxHelpCommand(arguments_, output);
|
|
305
53
|
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
try {
|
|
311
|
-
const request = await readJsonFile(path);
|
|
312
|
-
return typeof request.requestId === 'string' && request.requestId.length > 0
|
|
313
|
-
? request.requestId
|
|
314
|
-
: null;
|
|
54
|
+
function writeMetaCommand(arguments_, output) {
|
|
55
|
+
if (isHelpCommand(arguments_)) {
|
|
56
|
+
output.write(`${usage}\n`);
|
|
57
|
+
return true;
|
|
315
58
|
}
|
|
316
|
-
|
|
317
|
-
|
|
59
|
+
if (isVersionCommand(arguments_)) {
|
|
60
|
+
output.write(`${wakeVersion}\n`);
|
|
61
|
+
return true;
|
|
318
62
|
}
|
|
63
|
+
return false;
|
|
319
64
|
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
child.on('error', reject);
|
|
328
|
-
child.on('close', (exitCode) => {
|
|
329
|
-
resolveInspect(exitCode === 0);
|
|
330
|
-
});
|
|
331
|
-
});
|
|
332
|
-
}
|
|
333
|
-
async function inspectDockerContainer(containerName) {
|
|
334
|
-
return await new Promise((resolveInspect, reject) => {
|
|
335
|
-
const child = spawn('docker', ['container', 'inspect', '-f', '{{.State.Running}}', containerName], {
|
|
336
|
-
cwd: process.cwd(),
|
|
337
|
-
env: process.env,
|
|
338
|
-
stdio: ['ignore', 'pipe', 'ignore'],
|
|
339
|
-
});
|
|
340
|
-
let stdout = '';
|
|
341
|
-
child.stdout.on('data', (chunk) => {
|
|
342
|
-
stdout += chunk.toString();
|
|
343
|
-
});
|
|
344
|
-
child.on('error', reject);
|
|
345
|
-
child.on('close', (exitCode) => {
|
|
346
|
-
if (exitCode !== 0) {
|
|
347
|
-
resolveInspect(null);
|
|
348
|
-
return;
|
|
349
|
-
}
|
|
350
|
-
resolveInspect(stdout.trim() === 'true' ? 'running' : 'stopped');
|
|
351
|
-
});
|
|
352
|
-
});
|
|
353
|
-
}
|
|
354
|
-
async function inspectDockerContainerImage(containerName) {
|
|
355
|
-
return await new Promise((resolveInspect, reject) => {
|
|
356
|
-
const child = spawn('docker', ['container', 'inspect', '-f', '{{.Config.Image}}', containerName], {
|
|
357
|
-
cwd: process.cwd(),
|
|
358
|
-
env: process.env,
|
|
359
|
-
stdio: ['ignore', 'pipe', 'ignore'],
|
|
360
|
-
});
|
|
361
|
-
let stdout = '';
|
|
362
|
-
child.stdout.on('data', (chunk) => {
|
|
363
|
-
stdout += chunk.toString();
|
|
364
|
-
});
|
|
365
|
-
child.on('error', reject);
|
|
366
|
-
child.on('close', (exitCode) => {
|
|
367
|
-
if (exitCode !== 0) {
|
|
368
|
-
resolveInspect(null);
|
|
369
|
-
return;
|
|
370
|
-
}
|
|
371
|
-
const image = stdout.trim();
|
|
372
|
-
resolveInspect(image.length > 0 ? image : null);
|
|
373
|
-
});
|
|
374
|
-
});
|
|
375
|
-
}
|
|
376
|
-
async function dockerDaemonReachable() {
|
|
377
|
-
return await new Promise((resolveReachable) => {
|
|
378
|
-
const child = spawn('docker', ['info'], {
|
|
379
|
-
cwd: process.cwd(),
|
|
380
|
-
env: process.env,
|
|
381
|
-
stdio: 'ignore',
|
|
382
|
-
});
|
|
383
|
-
child.on('error', () => resolveReachable(false));
|
|
384
|
-
child.on('close', (exitCode) => resolveReachable(exitCode === 0));
|
|
385
|
-
});
|
|
65
|
+
function writeSandboxHelpCommand(arguments_, output) {
|
|
66
|
+
if (arguments_[0] !== 'sandbox')
|
|
67
|
+
return false;
|
|
68
|
+
if (arguments_.length !== 1 && !['--help', '-h', 'help'].includes(arguments_[1] ?? ''))
|
|
69
|
+
return false;
|
|
70
|
+
output.write(`${sandboxUsage}\n`);
|
|
71
|
+
return true;
|
|
386
72
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
* `wake doctor`'s Docker/sandbox reachability checks reuse one Docker CLI
|
|
390
|
-
* invocation implementation instead of duplicating it.
|
|
391
|
-
*/
|
|
392
|
-
function createHostDockerCli() {
|
|
393
|
-
return createDockerCli({
|
|
394
|
-
// BuildKit is required for the Dockerfile's cache-mount syntax
|
|
395
|
-
// (`RUN --mount=type=cache`), which keeps `npm`/`apt` package
|
|
396
|
-
// caches warm across builds even when a layer above them changes.
|
|
397
|
-
run: (dockerArgs) => runCommand('docker', dockerArgs, { ...process.env, DOCKER_BUILDKIT: '1' }),
|
|
398
|
-
inspectImage: inspectDockerImage,
|
|
399
|
-
inspectContainer: inspectDockerContainer,
|
|
400
|
-
inspectContainerImage: inspectDockerContainerImage,
|
|
401
|
-
spawnExec: (dockerArgs) => {
|
|
402
|
-
const child = spawn('docker', dockerArgs, {
|
|
403
|
-
cwd: process.cwd(),
|
|
404
|
-
env: process.env,
|
|
405
|
-
stdio: ['inherit', 'pipe', 'pipe'],
|
|
406
|
-
});
|
|
407
|
-
// stdio: ['inherit', 'pipe', 'pipe'] guarantees stdout/stderr are
|
|
408
|
-
// non-null pipes; child_process's types don't encode that.
|
|
409
|
-
return child;
|
|
410
|
-
},
|
|
411
|
-
});
|
|
73
|
+
function isHelpCommand(arguments_) {
|
|
74
|
+
return arguments_.length === 0 || ['--help', '-h', 'help'].includes(arguments_[0] ?? '');
|
|
412
75
|
}
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
* returns the trimmed stdout, so `wake doctor` can compare it against the
|
|
416
|
-
* installed host CLI version. Stderr is discarded (surfaced only as an
|
|
417
|
-
* empty/mismatched version, which the caller already treats as a notice).
|
|
418
|
-
*/
|
|
419
|
-
async function execVersionInContainer(docker, containerName, devMode) {
|
|
420
|
-
let stdout = '';
|
|
421
|
-
const command = devMode === 'source' ? ['node', '/app/dist/src/main.js', '--version'] : ['wake', '--version'];
|
|
422
|
-
await docker.execCaptured(containerName, command, {
|
|
423
|
-
onStdout: (line) => {
|
|
424
|
-
stdout += line;
|
|
425
|
-
},
|
|
426
|
-
onStderr: () => { },
|
|
427
|
-
});
|
|
428
|
-
return stdout.trim();
|
|
76
|
+
function isVersionCommand(arguments_) {
|
|
77
|
+
return ['--version', '-v'].includes(arguments_[0] ?? '');
|
|
429
78
|
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
return
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
79
|
+
function resolveWakeRoot(command) {
|
|
80
|
+
if ('wakeRoot' in command && command.wakeRoot !== undefined)
|
|
81
|
+
return command.wakeRoot;
|
|
82
|
+
if ('arguments' in command) {
|
|
83
|
+
const explicitWakeRoot = operationalWakeRoot(command.arguments);
|
|
84
|
+
if (explicitWakeRoot !== undefined)
|
|
85
|
+
return explicitWakeRoot;
|
|
86
|
+
if (command.kind === 'init')
|
|
87
|
+
return initWakeRoot(command.arguments) ?? process.cwd();
|
|
436
88
|
}
|
|
89
|
+
return process.cwd();
|
|
437
90
|
}
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
* `scaffold-assets.ts`/`sandbox-command.ts`'s `ensureDockerfile`) against the
|
|
442
|
-
* currently-shipped defaults under `resolvePackageRoot()`, byte-for-byte.
|
|
443
|
-
* Only files present in *both* locations are compared: a prompt file the
|
|
444
|
-
* user hasn't customized locally, or one only shipped in a newer/older CLI
|
|
445
|
-
* version, is not drift.
|
|
446
|
-
*/
|
|
447
|
-
async function diffPromptsAndDockerfile(input) {
|
|
448
|
-
const drifted = [];
|
|
449
|
-
let promptFileNames;
|
|
450
|
-
try {
|
|
451
|
-
promptFileNames = (await readdir(resolve(input.wakeRoot, 'prompts'))).filter((name) => name.endsWith('.md'));
|
|
452
|
-
}
|
|
453
|
-
catch {
|
|
454
|
-
promptFileNames = [];
|
|
455
|
-
}
|
|
456
|
-
for (const fileName of promptFileNames) {
|
|
457
|
-
const local = await readFileIfExists(resolve(input.wakeRoot, 'prompts', fileName));
|
|
458
|
-
const shipped = await readFileIfExists(resolve(input.packageRoot, 'prompts', fileName));
|
|
459
|
-
if (local !== null && shipped !== null && local !== shipped) {
|
|
460
|
-
drifted.push(`prompts/${fileName}`);
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
// Mirrors ensureDockerfile's template selection in sandbox-command.ts: a
|
|
464
|
-
// "source" dev mode wake-home was seeded from docker/Dockerfile, a
|
|
465
|
-
// "packaged" one from docker/Dockerfile.packaged.
|
|
466
|
-
const dockerfileTemplateName = (input.devMode ?? 'packaged') === 'source' ? 'Dockerfile' : 'Dockerfile.packaged';
|
|
467
|
-
const localDockerfile = await readFileIfExists(resolve(input.wakeRoot, 'docker', 'Dockerfile'));
|
|
468
|
-
const shippedDockerfile = await readFileIfExists(resolve(input.packageRoot, 'docker', dockerfileTemplateName));
|
|
469
|
-
if (localDockerfile !== null &&
|
|
470
|
-
shippedDockerfile !== null &&
|
|
471
|
-
localDockerfile !== shippedDockerfile) {
|
|
472
|
-
drifted.push('docker/Dockerfile');
|
|
473
|
-
}
|
|
474
|
-
return drifted;
|
|
91
|
+
function initWakeRoot(arguments_) {
|
|
92
|
+
const positional = arguments_[0];
|
|
93
|
+
return positional !== undefined && !positional.startsWith('--') ? positional : undefined;
|
|
475
94
|
}
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
await
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
const
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
: undefined;
|
|
504
|
-
const ticketingSystem = githubClient !== undefined
|
|
505
|
-
? createGitHubIssuesWorkSource({
|
|
506
|
-
client: githubClient,
|
|
507
|
-
stateStore,
|
|
508
|
-
config,
|
|
509
|
-
resourceIndex,
|
|
510
|
-
now: () => systemClock.now(),
|
|
511
|
-
...(selfLogin === undefined ? {} : { selfLogin }),
|
|
512
|
-
})
|
|
513
|
-
: await createFileBackedFakeTicketingSystem({
|
|
514
|
-
fixturePath: stateStore.paths.issueFixtureFile,
|
|
515
|
-
now: () => systemClock.now(),
|
|
516
|
-
});
|
|
517
|
-
const sourceName = configuredTicketSource(config);
|
|
518
|
-
const sinkName = sourceName;
|
|
519
|
-
const pullRequestActivitySource = prTrackingEnabled && githubClient !== undefined
|
|
520
|
-
? createGitHubPullRequestActivitySource({
|
|
521
|
-
client: githubClient,
|
|
522
|
-
stateStore,
|
|
523
|
-
config,
|
|
524
|
-
resourceIndex,
|
|
525
|
-
now: () => systemClock.now(),
|
|
526
|
-
...(selfLogin === undefined ? {} : { selfLogin }),
|
|
527
|
-
})
|
|
528
|
-
: null;
|
|
529
|
-
const workSource = createWorkSourceFanIn([
|
|
530
|
-
{
|
|
531
|
-
source: 'wake-schedule',
|
|
532
|
-
pollEvents: createScheduledWorkflowSource({
|
|
533
|
-
config,
|
|
534
|
-
stateStore,
|
|
535
|
-
now: () => systemClock.now(),
|
|
536
|
-
}).pollEvents,
|
|
537
|
-
},
|
|
538
|
-
{
|
|
539
|
-
source: sourceName,
|
|
540
|
-
pollEvents: ticketingSystem.pollEvents,
|
|
541
|
-
},
|
|
542
|
-
...(pullRequestActivitySource === null
|
|
543
|
-
? []
|
|
544
|
-
: [{ source: 'github-pr', pollEvents: pullRequestActivitySource.pollEvents }]),
|
|
545
|
-
]);
|
|
546
|
-
const outboundSink = createOutboundSinkRouter({
|
|
547
|
-
sinks: [
|
|
548
|
-
{
|
|
549
|
-
sink: sinkName,
|
|
550
|
-
deliverIntent: ticketingSystem.deliverIntent,
|
|
551
|
-
},
|
|
552
|
-
...(pullRequestActivitySource === null
|
|
553
|
-
? []
|
|
554
|
-
: [{ sink: 'github-pr', deliverIntent: pullRequestActivitySource.deliverIntent }]),
|
|
555
|
-
],
|
|
556
|
-
config,
|
|
557
|
-
});
|
|
558
|
-
const runnerOverride = readFlagBeforeCommandTerminator('--runner', args);
|
|
559
|
-
if (runnerOverride !== undefined &&
|
|
560
|
-
runnerOverride !== 'fake' &&
|
|
561
|
-
config.runners[runnerOverride] === undefined) {
|
|
562
|
-
throw new Error(`Unsupported runner override: ${runnerOverride}`);
|
|
563
|
-
}
|
|
564
|
-
const runner = createRegistryRunner({
|
|
565
|
-
config,
|
|
566
|
-
cwd: process.cwd(),
|
|
567
|
-
...(runnerOverride === undefined ? {} : { override: runnerOverride }),
|
|
568
|
-
});
|
|
569
|
-
const workspaceManager = (runnerOverride !== undefined
|
|
570
|
-
? runnerKindForOverride(config, runnerOverride) === 'fake'
|
|
571
|
-
: routesOnlyToFake(config))
|
|
572
|
-
? createFakeWorkspaceManager(stateStore.paths.workspaceRoot)
|
|
573
|
-
: createGitWorkspaceManager({ wakeRoot });
|
|
574
|
-
const tickRunner = createTickRunner({
|
|
575
|
-
clock: systemClock,
|
|
576
|
-
config,
|
|
577
|
-
stateStore,
|
|
578
|
-
workSource,
|
|
579
|
-
outboundSink,
|
|
580
|
-
runner,
|
|
581
|
-
workspaceManager,
|
|
582
|
-
resourceIndex,
|
|
583
|
-
...(artifactVerifier === undefined ? {} : { artifactVerifier }),
|
|
584
|
-
...(prMergeActor === undefined ? {} : { prMergeActor }),
|
|
585
|
-
});
|
|
95
|
+
async function runInSandboxIfAvailable(input) {
|
|
96
|
+
if (input.bypassSandbox || !isRuntimeCommand(input.commandKind))
|
|
97
|
+
return false;
|
|
98
|
+
if (!(await input.hasDockerfile()))
|
|
99
|
+
return false;
|
|
100
|
+
await input.exec();
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
function isRuntimeCommand(kind) {
|
|
104
|
+
return ['tick', 'start', 'ui', 'smoke', 'audit', 'correlate', 'validate-state'].includes(kind);
|
|
105
|
+
}
|
|
106
|
+
function rewriteSandboxArguments(arguments_) {
|
|
107
|
+
const withoutBypass = arguments_.filter((argument) => argument !== '--no-sandbox');
|
|
108
|
+
const wakeRootIndex = withoutBypass.indexOf('--wake-root');
|
|
109
|
+
const rewritten = wakeRootIndex === -1
|
|
110
|
+
? [...withoutBypass, '--wake-root', '/wake']
|
|
111
|
+
: withoutBypass.map((argument, index) => (index === wakeRootIndex + 1 ? '/wake' : argument));
|
|
112
|
+
return [...rewritten, '--no-sandbox'];
|
|
113
|
+
}
|
|
114
|
+
function operationalWakeRoot(arguments_) {
|
|
115
|
+
const index = arguments_.indexOf('--wake-root');
|
|
116
|
+
return index === -1 ? undefined : arguments_[index + 1];
|
|
117
|
+
}
|
|
118
|
+
function productionDependencies() {
|
|
119
|
+
const controller = new AbortController();
|
|
120
|
+
process.once('SIGINT', () => controller.abort());
|
|
121
|
+
process.once('SIGTERM', () => controller.abort());
|
|
586
122
|
return {
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
workspaceManager,
|
|
593
|
-
};
|
|
594
|
-
}
|
|
595
|
-
async function runTick(args) {
|
|
596
|
-
const runtime = await buildRuntime(args);
|
|
597
|
-
await runtime.stateStore.assertStateHealthy();
|
|
598
|
-
const outcome = await runtime.tickRunner.runTick();
|
|
599
|
-
console.log(JSON.stringify(outcome, null, 2));
|
|
600
|
-
if (outcome.status !== 'processed' ||
|
|
601
|
-
outcome.sentinel !== 'FAILED' ||
|
|
602
|
-
outcome.runId === undefined) {
|
|
603
|
-
return;
|
|
604
|
-
}
|
|
605
|
-
const runRecord = await runtime.stateStore.readRunRecord(outcome.runId);
|
|
606
|
-
const details = formatTickFailureDetails(runRecord);
|
|
607
|
-
if (details !== null) {
|
|
608
|
-
console.error(details);
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
export function createResidentControlPlane(runtime) {
|
|
612
|
-
return createControlPlane({
|
|
613
|
-
tickRunner: runtime.tickRunner,
|
|
614
|
-
intervalMs: runtime.config.scheduler.intervalMs,
|
|
615
|
-
maxIntervalMs: runtime.config.scheduler.maxIntervalMs,
|
|
616
|
-
isPaused: () => runtime.stateStore.isPaused(),
|
|
617
|
-
logger: {
|
|
618
|
-
info(message) {
|
|
619
|
-
console.log(message);
|
|
620
|
-
},
|
|
621
|
-
error(message) {
|
|
622
|
-
console.error(message);
|
|
623
|
-
},
|
|
624
|
-
},
|
|
625
|
-
sleep(ms) {
|
|
626
|
-
return new Promise((resolveSleep) => {
|
|
627
|
-
setTimeout(resolveSleep, ms);
|
|
628
|
-
});
|
|
123
|
+
initialise: initialiseWakeRoot,
|
|
124
|
+
sandboxRuntime: productionSandboxRuntime(),
|
|
125
|
+
async compose(wakeRoot) {
|
|
126
|
+
const root = await createCompositionRoot(wakeRoot);
|
|
127
|
+
return createSurfaceApplications(root).cli;
|
|
629
128
|
},
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
},
|
|
633
|
-
});
|
|
634
|
-
}
|
|
635
|
-
async function runStart(args) {
|
|
636
|
-
const runtime = await buildRuntime(args);
|
|
637
|
-
await runtime.stateStore.assertStateHealthy();
|
|
638
|
-
const runnerOverride = readFlagBeforeCommandTerminator('--runner', args);
|
|
639
|
-
await runStartupPreflight(runtime.config, {
|
|
640
|
-
...(runnerOverride === undefined ? {} : { runnerOverride }),
|
|
641
|
-
workspaceManager: runtime.workspaceManager,
|
|
642
|
-
});
|
|
643
|
-
const controlPlane = createResidentControlPlane(runtime);
|
|
644
|
-
const stop = () => controlPlane.stop();
|
|
645
|
-
process.on('SIGINT', stop);
|
|
646
|
-
process.on('SIGTERM', stop);
|
|
647
|
-
await controlPlane.start();
|
|
648
|
-
}
|
|
649
|
-
function printStateHealthReport(report) {
|
|
650
|
-
if (report.healthy) {
|
|
651
|
-
console.log('wake validate-state: control-plane state is healthy');
|
|
652
|
-
return;
|
|
653
|
-
}
|
|
654
|
-
console.error('wake validate-state: control-plane state is unhealthy');
|
|
655
|
-
for (const issue of report.issues) {
|
|
656
|
-
console.error(` - ${issue.surface} ${issue.kind}: ${issue.path}: ${issue.message}`);
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
async function runValidateState(args) {
|
|
660
|
-
const wakeRoot = resolve(readFlagBeforeCommandTerminator('--wake-root', args) ?? process.cwd());
|
|
661
|
-
const stateStore = createStateStore({ wakeRoot });
|
|
662
|
-
await stateStore.ensureWakeRoot();
|
|
663
|
-
const report = await stateStore.validateStateHealth();
|
|
664
|
-
printStateHealthReport(report);
|
|
665
|
-
if (!report.healthy) {
|
|
666
|
-
process.exitCode = 1;
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
function resolveSmokEntry(config, kind) {
|
|
670
|
-
for (const entry of Object.values(config.runners)) {
|
|
671
|
-
if (entry.kind === 'fake') {
|
|
672
|
-
continue;
|
|
673
|
-
}
|
|
674
|
-
if (kind === undefined || entry.kind === kind) {
|
|
675
|
-
return entry;
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
return null;
|
|
679
|
-
}
|
|
680
|
-
async function runUi(args) {
|
|
681
|
-
const wakeRoot = resolve(readFlagBeforeCommandTerminator('--wake-root', args) ?? process.cwd());
|
|
682
|
-
const stateStore = createStateStore({ wakeRoot });
|
|
683
|
-
await stateStore.ensureWakeRoot();
|
|
684
|
-
const config = await loadWakeConfig({
|
|
685
|
-
wakeRoot,
|
|
686
|
-
});
|
|
687
|
-
const server = await runUiCommand({
|
|
688
|
-
args,
|
|
689
|
-
stateStore,
|
|
690
|
-
resourceIndex: createResourceIndex({ paths: stateStore.paths }),
|
|
691
|
-
config,
|
|
692
|
-
readFlag: readFlagBeforeCommandTerminator,
|
|
693
|
-
});
|
|
694
|
-
const stop = () => {
|
|
695
|
-
void server.close().then(() => process.exit(0));
|
|
129
|
+
output: productionOutput(),
|
|
130
|
+
signal: controller.signal,
|
|
696
131
|
};
|
|
697
|
-
process.on('SIGINT', stop);
|
|
698
|
-
process.on('SIGTERM', stop);
|
|
699
|
-
await new Promise(() => { });
|
|
700
|
-
}
|
|
701
|
-
async function runCorrelate(args) {
|
|
702
|
-
const wakeRoot = resolve(readFlagBeforeCommandTerminator('--wake-root', args) ?? process.cwd());
|
|
703
|
-
const stateStore = createStateStore({ wakeRoot });
|
|
704
|
-
await stateStore.ensureWakeRoot();
|
|
705
|
-
await runCorrelateCommand({
|
|
706
|
-
args,
|
|
707
|
-
stateStore,
|
|
708
|
-
resourceIndex: createResourceIndex({ paths: stateStore.paths }),
|
|
709
|
-
clock: systemClock,
|
|
710
|
-
readFlag: readFlagBeforeCommandTerminator,
|
|
711
|
-
});
|
|
712
132
|
}
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
const stateStore = createStateStore({ wakeRoot });
|
|
716
|
-
await stateStore.ensureWakeRoot();
|
|
717
|
-
await runAuditCommand({
|
|
718
|
-
args,
|
|
719
|
-
stateStore,
|
|
720
|
-
});
|
|
133
|
+
function productionOutput() {
|
|
134
|
+
return { write: (value) => process.stdout.write(value) };
|
|
721
135
|
}
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
const smokeArgs = explicitKind === undefined ? args : args.slice(1);
|
|
726
|
-
const entry = resolveSmokEntry(runtime.config, explicitKind);
|
|
727
|
-
if (entry === null) {
|
|
728
|
-
throw new Error('Smoke tests require a real runner entry (`claude`, `codex`, or `cursor`) in config.runners.');
|
|
729
|
-
}
|
|
730
|
-
const runnerAdapter = createRunnerCliAdapter({
|
|
731
|
-
entry,
|
|
732
|
-
cwd: process.cwd(),
|
|
733
|
-
});
|
|
734
|
-
const result = await runnerAdapter.smoke(smokeArgs);
|
|
735
|
-
console.log(JSON.stringify(result, null, 2));
|
|
736
|
-
}
|
|
737
|
-
async function runDoctor(args) {
|
|
738
|
-
const wakeRoot = resolve(readFlagBeforeCommandTerminator('--wake-root', args) ?? process.cwd());
|
|
739
|
-
const stateStore = createStateStore({ wakeRoot });
|
|
740
|
-
await stateStore.ensureWakeRoot();
|
|
741
|
-
const config = await loadWakeConfig({
|
|
742
|
-
wakeRoot,
|
|
743
|
-
});
|
|
744
|
-
const docker = createHostDockerCli();
|
|
745
|
-
const packageRoot = resolvePackageRoot();
|
|
746
|
-
const containerName = config.sandbox.containerName;
|
|
747
|
-
const image = config.sandbox.image;
|
|
748
|
-
const workspaceManager = createGitWorkspaceManager({ wakeRoot });
|
|
749
|
-
const deps = {
|
|
750
|
-
collectPreflightFailures: (doctorConfig) => collectStartupPreflightFailures(doctorConfig, { workspaceManager }),
|
|
751
|
-
resolveGitHubToken,
|
|
752
|
-
hasDockerfile,
|
|
753
|
-
dockerReachable: dockerDaemonReachable,
|
|
754
|
-
inspectImage: async (imageToInspect) => {
|
|
136
|
+
function productionSandboxRuntime() {
|
|
137
|
+
return {
|
|
138
|
+
async hasDockerfile(wakeRoot) {
|
|
755
139
|
try {
|
|
756
|
-
|
|
140
|
+
await access(join(wakeRoot, 'docker', 'Dockerfile'));
|
|
141
|
+
return true;
|
|
757
142
|
}
|
|
758
143
|
catch {
|
|
759
144
|
return false;
|
|
760
145
|
}
|
|
761
146
|
},
|
|
762
|
-
wakeRoot,
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
147
|
+
async exec(wakeRoot, arguments_) {
|
|
148
|
+
const config = await loadConfig(wakeRoot);
|
|
149
|
+
const invocation = config.host.development.mode === 'source' ? ['node', '/app/dist/src/main.js'] : ['wake'];
|
|
150
|
+
await runDocker([
|
|
151
|
+
'exec',
|
|
152
|
+
'-i',
|
|
153
|
+
config.host.sandbox.containerName,
|
|
154
|
+
...invocation,
|
|
155
|
+
...arguments_,
|
|
156
|
+
]);
|
|
157
|
+
},
|
|
768
158
|
};
|
|
769
|
-
const report = await runDoctorCommand(config, deps);
|
|
770
|
-
if (report.failures.length > 0) {
|
|
771
|
-
console.log('Failures:');
|
|
772
|
-
for (const failure of report.failures) {
|
|
773
|
-
console.log(` - ${failure}`);
|
|
774
|
-
}
|
|
775
|
-
}
|
|
776
|
-
if (report.notices.length > 0) {
|
|
777
|
-
console.log('Notices:');
|
|
778
|
-
for (const notice of report.notices) {
|
|
779
|
-
console.log(` - ${notice}`);
|
|
780
|
-
}
|
|
781
|
-
}
|
|
782
|
-
if (report.failures.length === 0 && report.notices.length === 0) {
|
|
783
|
-
console.log('wake doctor: no issues found');
|
|
784
|
-
}
|
|
785
|
-
if (report.failures.length > 0) {
|
|
786
|
-
process.exitCode = 1;
|
|
787
|
-
}
|
|
788
159
|
}
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
'
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
' wake init <path> Scaffold a new Wake home directory',
|
|
797
|
-
' wake sandbox <subcommand> Build/run/manage the Docker sandbox (build, up, update, down, stop, self-update, setup, exec, logs, resume)',
|
|
798
|
-
' wake tick Run one control-plane tick',
|
|
799
|
-
' wake start Run the resident loop',
|
|
800
|
-
' wake validate-state Validate .wake/ control-plane state health',
|
|
801
|
-
' wake stop Stop the sandbox container gracefully',
|
|
802
|
-
' wake smoke Smoke-test the configured runner',
|
|
803
|
-
' wake ui Run the control-plane UI server',
|
|
804
|
-
' wake audit Show autonomous decision audit history',
|
|
805
|
-
' wake correlate Manually correlate a resource to a work item',
|
|
806
|
-
' wake doctor Diagnose config/GitHub/Docker/sandbox setup problems',
|
|
807
|
-
' wake --version Print the installed Wake version',
|
|
808
|
-
' wake --help Show this message',
|
|
809
|
-
'',
|
|
810
|
-
'Getting started:',
|
|
811
|
-
' 1. wake init ./wake-home',
|
|
812
|
-
' 2. cd wake-home && wake start',
|
|
813
|
-
'',
|
|
814
|
-
'Runtime commands (tick/start/ui/smoke/audit/correlate/validate-state) auto-delegate into the sandbox',
|
|
815
|
-
'when docker/Dockerfile exists at --wake-root (i.e. after `wake sandbox build`),',
|
|
816
|
-
'defaulting --wake-root to the current directory. Pass --no-sandbox to run',
|
|
817
|
-
'directly on the host instead.',
|
|
818
|
-
'',
|
|
819
|
-
].join('\n'));
|
|
820
|
-
}
|
|
821
|
-
const runtimeCommands = new Set([
|
|
822
|
-
'tick',
|
|
823
|
-
'start',
|
|
824
|
-
'ui',
|
|
825
|
-
'smoke',
|
|
826
|
-
'audit',
|
|
827
|
-
'correlate',
|
|
828
|
-
'validate-state',
|
|
829
|
-
]);
|
|
830
|
-
export async function dispatchMainCommand(input) {
|
|
831
|
-
const command = input.args[0] ?? 'help';
|
|
832
|
-
if (command === '--version' || command === '-v') {
|
|
833
|
-
console.log(wakeVersion);
|
|
834
|
-
return;
|
|
835
|
-
}
|
|
836
|
-
if (command === '--help' || command === '-h' || command === 'help') {
|
|
837
|
-
printUsage(process.stdout);
|
|
838
|
-
return;
|
|
839
|
-
}
|
|
840
|
-
if (command === 'init') {
|
|
841
|
-
await input.runInit(input.args.slice(1));
|
|
842
|
-
return;
|
|
843
|
-
}
|
|
844
|
-
if (command === 'sandbox') {
|
|
845
|
-
await input.runSandbox(input.args.slice(1));
|
|
846
|
-
return;
|
|
847
|
-
}
|
|
848
|
-
if (command === 'sandbox-setup') {
|
|
849
|
-
await input.runSandboxSetup(input.args.slice(1));
|
|
850
|
-
return;
|
|
851
|
-
}
|
|
852
|
-
if (command === 'sandbox-entrypoint') {
|
|
853
|
-
await input.runSandboxEntrypoint(input.args.slice(1));
|
|
854
|
-
return;
|
|
855
|
-
}
|
|
856
|
-
if (command === 'stop') {
|
|
857
|
-
await input.runSandbox(['stop', ...input.args.slice(1)]);
|
|
858
|
-
return;
|
|
859
|
-
}
|
|
860
|
-
if (command === 'doctor') {
|
|
861
|
-
// Host-only, like init/sandbox/stop above: doctor's job is to report on
|
|
862
|
-
// sandbox reachability from the outside, so it must never auto-delegate
|
|
863
|
-
// into the sandbox the way runtimeCommands below does.
|
|
864
|
-
await input.runDoctor(input.args.slice(1));
|
|
865
|
-
return;
|
|
866
|
-
}
|
|
867
|
-
if (runtimeCommands.has(command)) {
|
|
868
|
-
const commandArgs = input.args.slice(1);
|
|
869
|
-
const wakeRoot = resolve(readFlagBeforeCommandTerminator('--wake-root', commandArgs) ?? process.cwd());
|
|
870
|
-
const host = commandArgs.includes('--no-sandbox');
|
|
871
|
-
if (!host && (await hasDockerfile(wakeRoot))) {
|
|
872
|
-
await input.execIntoSandbox(input.args);
|
|
873
|
-
return;
|
|
874
|
-
}
|
|
875
|
-
const hostArgs = commandArgs.filter((arg) => arg !== '--no-sandbox');
|
|
876
|
-
if (command === 'tick') {
|
|
877
|
-
await input.runTick(hostArgs);
|
|
878
|
-
}
|
|
879
|
-
else if (command === 'start') {
|
|
880
|
-
await input.runStart(hostArgs);
|
|
881
|
-
}
|
|
882
|
-
else if (command === 'ui') {
|
|
883
|
-
await input.runUi(hostArgs);
|
|
884
|
-
}
|
|
885
|
-
else if (command === 'audit') {
|
|
886
|
-
if (input.runAudit === undefined) {
|
|
887
|
-
throw new CliUsageError('audit command is not available in this runtime');
|
|
888
|
-
}
|
|
889
|
-
await input.runAudit(hostArgs);
|
|
890
|
-
}
|
|
891
|
-
else if (command === 'smoke') {
|
|
892
|
-
await input.runSmoke(hostArgs);
|
|
893
|
-
}
|
|
894
|
-
else if (command === 'correlate') {
|
|
895
|
-
await input.runCorrelate(hostArgs);
|
|
896
|
-
}
|
|
897
|
-
else {
|
|
898
|
-
if (input.runValidateState === undefined) {
|
|
899
|
-
throw new CliUsageError('validate-state command is not available in this runtime');
|
|
900
|
-
}
|
|
901
|
-
await input.runValidateState(hostArgs);
|
|
902
|
-
}
|
|
903
|
-
return;
|
|
904
|
-
}
|
|
905
|
-
printUsage(process.stderr);
|
|
906
|
-
throw new CliUsageError(`Unknown command: ${input.args.join(' ')}`);
|
|
907
|
-
}
|
|
908
|
-
async function main() {
|
|
909
|
-
const args = process.argv.slice(2);
|
|
910
|
-
const runSandbox = async (commandArgs) => {
|
|
911
|
-
const wakeRoot = resolve(readFlagBeforeCommandTerminator('--wake-root', commandArgs) ?? process.cwd());
|
|
912
|
-
const stateStore = createStateStore({ wakeRoot });
|
|
913
|
-
await stateStore.ensureWakeRoot();
|
|
914
|
-
const config = await loadWakeConfig({
|
|
915
|
-
wakeRoot,
|
|
916
|
-
});
|
|
917
|
-
const docker = createHostDockerCli();
|
|
918
|
-
const recoverActiveRuns = createActiveRunRecovery({
|
|
919
|
-
clock: systemClock,
|
|
920
|
-
config,
|
|
921
|
-
stateStore,
|
|
922
|
-
resourceIndex: createResourceIndex({ paths: stateStore.paths }),
|
|
923
|
-
}).recoverActiveRuns;
|
|
924
|
-
const repoRoot = config.dev?.repoRoot;
|
|
925
|
-
const selfUpdate = commandArgs[0] === 'self-update' &&
|
|
926
|
-
config.dev?.mode === 'source' &&
|
|
927
|
-
repoRoot !== undefined &&
|
|
928
|
-
repoRoot.length > 0
|
|
929
|
-
? {
|
|
930
|
-
git: {
|
|
931
|
-
latestTag: async () => {
|
|
932
|
-
await runCommand('git', ['-C', repoRoot, 'fetch', '--tags']);
|
|
933
|
-
const output = await runCommandCapture('git', [
|
|
934
|
-
'-C',
|
|
935
|
-
repoRoot,
|
|
936
|
-
'tag',
|
|
937
|
-
'--list',
|
|
938
|
-
'v*',
|
|
939
|
-
'--sort=-v:refname',
|
|
940
|
-
]);
|
|
941
|
-
const [latest] = output.split('\n').filter((line) => line.trim().length > 0);
|
|
942
|
-
if (latest === undefined) {
|
|
943
|
-
throw new Error('No version tags found in repo');
|
|
944
|
-
}
|
|
945
|
-
return latest.trim();
|
|
946
|
-
},
|
|
947
|
-
isWorkingTreeClean: async () => {
|
|
948
|
-
const output = await runCommandCapture('git', [
|
|
949
|
-
'-C',
|
|
950
|
-
repoRoot,
|
|
951
|
-
'status',
|
|
952
|
-
'--porcelain',
|
|
953
|
-
]);
|
|
954
|
-
return output.trim().length === 0;
|
|
955
|
-
},
|
|
956
|
-
checkoutTag: async (tag) => {
|
|
957
|
-
await runCommand('git', ['-C', repoRoot, 'checkout', tag]);
|
|
958
|
-
},
|
|
959
|
-
},
|
|
960
|
-
issueReporter: {
|
|
961
|
-
createIssue: async (issue) => {
|
|
962
|
-
const remoteUrl = await runCommandCapture('git', [
|
|
963
|
-
'-C',
|
|
964
|
-
repoRoot,
|
|
965
|
-
'remote',
|
|
966
|
-
'get-url',
|
|
967
|
-
'origin',
|
|
968
|
-
]);
|
|
969
|
-
const repoSlug = parseGithubRepoSlug(remoteUrl);
|
|
970
|
-
await runCommand('gh', [
|
|
971
|
-
'issue',
|
|
972
|
-
'create',
|
|
973
|
-
'--repo',
|
|
974
|
-
repoSlug,
|
|
975
|
-
'--title',
|
|
976
|
-
issue.title,
|
|
977
|
-
'--body',
|
|
978
|
-
issue.body,
|
|
979
|
-
]);
|
|
980
|
-
},
|
|
981
|
-
},
|
|
982
|
-
readLedger: () => readSelfUpdateLedger(resolve(wakeRoot, 'self-update-ledger.json')),
|
|
983
|
-
writeLedger: (ledger) => writeSelfUpdateLedger(resolve(wakeRoot, 'self-update-ledger.json'), ledger),
|
|
984
|
-
}
|
|
985
|
-
: undefined;
|
|
986
|
-
await runSandboxCommand({
|
|
987
|
-
args: commandArgs,
|
|
988
|
-
config,
|
|
989
|
-
wakeRoot,
|
|
990
|
-
containerHomeRoot: stateStore.paths.containerHomeRoot,
|
|
991
|
-
docker,
|
|
992
|
-
packagedTemplatesRoot: resolve(resolvePackageRoot(), 'docker'),
|
|
993
|
-
stateStore,
|
|
994
|
-
recoverActiveRuns,
|
|
995
|
-
sleep: (ms) => new Promise((resolveSleep) => setTimeout(resolveSleep, ms)),
|
|
996
|
-
logger: {
|
|
997
|
-
info(message) {
|
|
998
|
-
console.log(message);
|
|
999
|
-
},
|
|
1000
|
-
error(message) {
|
|
1001
|
-
console.error(message);
|
|
1002
|
-
},
|
|
1003
|
-
},
|
|
1004
|
-
selfUpdate,
|
|
1005
|
-
});
|
|
1006
|
-
};
|
|
1007
|
-
await dispatchMainCommand({
|
|
1008
|
-
args,
|
|
1009
|
-
runInit: async (commandArgs) => {
|
|
1010
|
-
await runInitCommand({
|
|
1011
|
-
cwd: process.cwd(),
|
|
1012
|
-
args: commandArgs,
|
|
1013
|
-
repoRoot: resolvePackageRoot(),
|
|
1014
|
-
});
|
|
1015
|
-
},
|
|
1016
|
-
runSandbox,
|
|
1017
|
-
runSandboxSetup: async () => {
|
|
1018
|
-
await runSandboxSetup();
|
|
1019
|
-
},
|
|
1020
|
-
runSandboxEntrypoint: async () => {
|
|
1021
|
-
await runSandboxEntrypoint();
|
|
1022
|
-
},
|
|
1023
|
-
runTick,
|
|
1024
|
-
runStart,
|
|
1025
|
-
runSmoke,
|
|
1026
|
-
runUi,
|
|
1027
|
-
runAudit,
|
|
1028
|
-
runCorrelate,
|
|
1029
|
-
runValidateState,
|
|
1030
|
-
execIntoSandbox: async (commandArgs) => {
|
|
1031
|
-
const withoutBypassFlag = commandArgs.filter((arg) => arg !== '--no-sandbox');
|
|
1032
|
-
const wakeRootIndex = withoutBypassFlag.indexOf('--wake-root');
|
|
1033
|
-
const rewritten = wakeRootIndex === -1
|
|
1034
|
-
? [...withoutBypassFlag, '--wake-root', '/wake']
|
|
1035
|
-
: withoutBypassFlag.map((arg, index) => (index === wakeRootIndex + 1 ? '/wake' : arg));
|
|
1036
|
-
const wakeRoot = resolve(readFlagBeforeCommandTerminator('--wake-root', commandArgs) ?? process.cwd());
|
|
1037
|
-
const stateStore = createStateStore({ wakeRoot });
|
|
1038
|
-
await stateStore.ensureWakeRoot();
|
|
1039
|
-
const config = await loadWakeConfig({
|
|
1040
|
-
wakeRoot,
|
|
1041
|
-
});
|
|
1042
|
-
const wakeInvocation = config.dev?.mode === 'source' ? ['node', '/app/dist/src/main.js'] : ['wake'];
|
|
1043
|
-
await runSandbox(['exec', '--', ...wakeInvocation, ...rewritten]);
|
|
1044
|
-
},
|
|
1045
|
-
runDoctor,
|
|
160
|
+
function runDocker(arguments_) {
|
|
161
|
+
return new Promise((resolve, reject) => {
|
|
162
|
+
const child = spawn('docker', arguments_, { stdio: 'inherit' });
|
|
163
|
+
child.once('error', reject);
|
|
164
|
+
child.once('close', (code) => code === 0
|
|
165
|
+
? resolve()
|
|
166
|
+
: reject(new Error('docker ' + arguments_.join(' ') + ' exited with code ' + String(code))));
|
|
1046
167
|
});
|
|
1047
168
|
}
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
console.error(error.message);
|
|
1051
|
-
}
|
|
1052
|
-
else if (error instanceof StateHealthError) {
|
|
1053
|
-
console.error(error.message);
|
|
1054
|
-
for (const issue of error.issues) {
|
|
1055
|
-
console.error(` - ${issue.surface} ${issue.kind}: ${issue.path}: ${issue.message}`);
|
|
1056
|
-
}
|
|
1057
|
-
process.exitCode = 1;
|
|
1058
|
-
}
|
|
1059
|
-
else {
|
|
1060
|
-
console.error(error);
|
|
1061
|
-
}
|
|
1062
|
-
process.exitCode = 1;
|
|
1063
|
-
});
|
|
169
|
+
if (process.argv[1] !== undefined && import.meta.url === pathToFileURL(process.argv[1]).href)
|
|
170
|
+
await main();
|