@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,195 @@
|
|
|
1
|
+
import { runSelfUpdate } from '../surfaces/index.js';
|
|
2
|
+
import { UpdateMaintenancePhase } from './update-maintenance-lease.js';
|
|
3
|
+
export function createSelfUpdateApplication(input) {
|
|
4
|
+
return {
|
|
5
|
+
async update(tag, force = false) {
|
|
6
|
+
if (!force && (await input.ledger.isBad(tag)))
|
|
7
|
+
return false;
|
|
8
|
+
return startUpdateAttempt(input, tag, force);
|
|
9
|
+
},
|
|
10
|
+
async updateLatest(force = false) {
|
|
11
|
+
const candidates = await input.source.candidateTags();
|
|
12
|
+
const [latestCandidate] = candidates;
|
|
13
|
+
if (latestCandidate === undefined) {
|
|
14
|
+
throw new Error('No source version tags available');
|
|
15
|
+
}
|
|
16
|
+
for (const tag of candidates) {
|
|
17
|
+
if (!force && (await input.ledger.isBad(tag))) {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
const updated = await this.update(tag, force);
|
|
21
|
+
if (updated) {
|
|
22
|
+
return { tag, updated: true };
|
|
23
|
+
}
|
|
24
|
+
// If update returned false (same tag or skipped), try the next candidate
|
|
25
|
+
if (!force && (await input.ledger.read()) === tag) {
|
|
26
|
+
// Already on this tag, no need to try others
|
|
27
|
+
return { tag, updated: false };
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// All candidates exhausted
|
|
31
|
+
return { tag: latestCandidate, updated: false };
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
async function startUpdateAttempt(input, tag, force) {
|
|
36
|
+
if (input.quiesce?.exclusive !== undefined)
|
|
37
|
+
return input.quiesce.exclusive(tag, force, (lease) => updateAttempt(input, tag, force, lease));
|
|
38
|
+
return updateAttempt(input, tag, force, await input.quiesce?.acquire(tag, force));
|
|
39
|
+
}
|
|
40
|
+
async function updateAttempt(input, tag, force, lease) {
|
|
41
|
+
const maintenanceTag = lease?.tag ?? tag;
|
|
42
|
+
const attemptId = lease?.attemptId;
|
|
43
|
+
const context = {};
|
|
44
|
+
try {
|
|
45
|
+
return await performUpdateAttempt(input, tag, force, lease, context);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
await recordUpdateFailure(input, maintenanceTag, attemptId, context.deployError ?? error, error);
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async function performUpdateAttempt(input, tag, force, lease, context) {
|
|
53
|
+
if (lease !== undefined && requiresMaintenanceRecovery(lease)) {
|
|
54
|
+
await resumePendingMaintenance(input, lease);
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
if (!isStartableMaintenanceLease(lease, tag))
|
|
58
|
+
return false;
|
|
59
|
+
await quiesceForUpdate(input);
|
|
60
|
+
await recoverPendingUpdate(input.ledger, input.source);
|
|
61
|
+
if (!force && (await input.ledger.read()) === tag) {
|
|
62
|
+
await input.quiesce?.clear(lease?.attemptId);
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
return runForwardUpdate(input, tag, lease?.attemptId, context);
|
|
66
|
+
}
|
|
67
|
+
function requiresMaintenanceRecovery(lease) {
|
|
68
|
+
return (lease.phase !== UpdateMaintenancePhase.Quiescing &&
|
|
69
|
+
lease.phase !== UpdateMaintenancePhase.Failed);
|
|
70
|
+
}
|
|
71
|
+
function isStartableMaintenanceLease(lease, tag) {
|
|
72
|
+
return (lease === undefined || (lease.phase === UpdateMaintenancePhase.Quiescing && lease.tag === tag));
|
|
73
|
+
}
|
|
74
|
+
async function quiesceForUpdate(input) {
|
|
75
|
+
if (input.quiesce === undefined)
|
|
76
|
+
return;
|
|
77
|
+
await quiesceActiveRuns(input.quiesce, input.drainTimeoutMs ?? 30_000, input.cancellationTimeoutMs ?? 30_000);
|
|
78
|
+
}
|
|
79
|
+
async function runForwardUpdate(input, tag, attemptId, context) {
|
|
80
|
+
if (!(await input.source.isClean()))
|
|
81
|
+
throw new Error('Self-update requires a clean source checkout');
|
|
82
|
+
await input.ledger.begin(tag);
|
|
83
|
+
await input.quiesce?.transition(UpdateMaintenancePhase.Updating, attemptId);
|
|
84
|
+
const updated = await runSelfUpdate({
|
|
85
|
+
tag,
|
|
86
|
+
force: true,
|
|
87
|
+
readLedger: input.ledger.read,
|
|
88
|
+
writeLedger: input.ledger.write,
|
|
89
|
+
update: async (nextTag) => {
|
|
90
|
+
await input.source.checkout(nextTag);
|
|
91
|
+
context.deployError = await deployRollout(input.rollout, nextTag);
|
|
92
|
+
},
|
|
93
|
+
health: async () => context.deployError === undefined && input.source.healthy(),
|
|
94
|
+
rollback: async (priorTag) => rollbackUpdate(input, priorTag, attemptId),
|
|
95
|
+
});
|
|
96
|
+
await input.quiesce?.clear(attemptId);
|
|
97
|
+
return updated;
|
|
98
|
+
}
|
|
99
|
+
async function deployRollout(rollout, tag) {
|
|
100
|
+
if (rollout === undefined)
|
|
101
|
+
return undefined;
|
|
102
|
+
try {
|
|
103
|
+
await rollout.deploy(tag);
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
return error;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
async function rollbackUpdate(input, priorTag, attemptId) {
|
|
111
|
+
await input.quiesce?.transition(UpdateMaintenancePhase.RollingBack, attemptId);
|
|
112
|
+
await input.source.checkout(priorTag);
|
|
113
|
+
await input.rollout?.rollback(priorTag);
|
|
114
|
+
}
|
|
115
|
+
async function recordUpdateFailure(input, tag, attemptId, rolloutError, originalError) {
|
|
116
|
+
try {
|
|
117
|
+
await input.quiesce?.fail(originalError, attemptId);
|
|
118
|
+
}
|
|
119
|
+
catch (persistenceError) {
|
|
120
|
+
await input.ledger.recordBad(tag);
|
|
121
|
+
throw new Error(`Could not persist failed maintenance lease: ${formatError(persistenceError)}. ` +
|
|
122
|
+
`Quiesce remains unresolved: ${formatError(originalError)}`, { cause: persistenceError });
|
|
123
|
+
}
|
|
124
|
+
await recordRolloutFailure(input.rollout, tag, rolloutError);
|
|
125
|
+
await input.ledger.recordBad(tag);
|
|
126
|
+
}
|
|
127
|
+
async function recordRolloutFailure(rollout, tag, error) {
|
|
128
|
+
if (rollout === undefined)
|
|
129
|
+
return;
|
|
130
|
+
try {
|
|
131
|
+
await rollout.recordFailure(tag, error);
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
// Best-effort: a failure-log write must never mask the original update failure.
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* A restart must never repeat a forward deploy. The persisted phase tells us
|
|
139
|
+
* that source/rollout work may already have begun, so recover the prior
|
|
140
|
+
* healthy revision while the durable lease continues to pause the runtime.
|
|
141
|
+
*/
|
|
142
|
+
async function resumePendingMaintenance(input, lease) {
|
|
143
|
+
if (lease.phase === UpdateMaintenancePhase.Quiescing)
|
|
144
|
+
return;
|
|
145
|
+
const priorTag = await input.ledger.recover();
|
|
146
|
+
if (priorTag === null)
|
|
147
|
+
throw new Error(`Self-update recovery has no prior healthy tag for ${lease.tag}`);
|
|
148
|
+
await input.source.checkout(priorTag);
|
|
149
|
+
await input.rollout?.rollback(priorTag);
|
|
150
|
+
if (!(await input.source.healthy()))
|
|
151
|
+
throw new Error(`Self-update recovery could not verify the prior tag ${priorTag}`);
|
|
152
|
+
await input.ledger.recordBad(lease.tag);
|
|
153
|
+
await input.quiesce?.clear(lease.attemptId);
|
|
154
|
+
}
|
|
155
|
+
async function quiesceActiveRuns(quiesce, drainTimeoutMs, cancellationTimeoutMs) {
|
|
156
|
+
let remaining = await waitForActiveRunsToDrain(quiesce, drainTimeoutMs);
|
|
157
|
+
if (remaining.length === 0)
|
|
158
|
+
return;
|
|
159
|
+
const cancellationIds = remaining
|
|
160
|
+
.filter((run) => run.maintenanceCancellable)
|
|
161
|
+
.map((run) => run.runId);
|
|
162
|
+
let cancellationError;
|
|
163
|
+
try {
|
|
164
|
+
await quiesce.requestMaintenanceCancellation(cancellationIds);
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
cancellationError = error;
|
|
168
|
+
}
|
|
169
|
+
remaining = await waitForActiveRunsToDrain(quiesce, cancellationTimeoutMs);
|
|
170
|
+
if (remaining.length === 0)
|
|
171
|
+
return;
|
|
172
|
+
if (cancellationError !== undefined)
|
|
173
|
+
throw cancellationError;
|
|
174
|
+
throw new Error(`active Runs remain after maintenance cancellation: ${remaining.map((run) => run.runId).join(', ')}`);
|
|
175
|
+
}
|
|
176
|
+
function formatError(error) {
|
|
177
|
+
return error instanceof Error ? error.message : String(error);
|
|
178
|
+
}
|
|
179
|
+
async function waitForActiveRunsToDrain(quiesce, timeoutMs) {
|
|
180
|
+
const deadline = quiesce.now() + timeoutMs;
|
|
181
|
+
let activeRuns = await quiesce.activeRuns();
|
|
182
|
+
while (activeRuns.length > 0 && quiesce.now() < deadline) {
|
|
183
|
+
await quiesce.sleep(Math.min(100, deadline - quiesce.now()));
|
|
184
|
+
activeRuns = await quiesce.activeRuns();
|
|
185
|
+
}
|
|
186
|
+
return activeRuns;
|
|
187
|
+
}
|
|
188
|
+
async function recoverPendingUpdate(ledger, source) {
|
|
189
|
+
const priorTag = await ledger.recover();
|
|
190
|
+
if (priorTag === null)
|
|
191
|
+
return;
|
|
192
|
+
await source.checkout(priorTag);
|
|
193
|
+
if (!(await source.healthy()))
|
|
194
|
+
throw new Error(`Self-update recovery could not verify the prior tag ${priorTag}`);
|
|
195
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Persists the most recent self-update rollback so it can surface on the
|
|
5
|
+
* operator health screen instead of relying on a third-party notification —
|
|
6
|
+
* cleared the moment a later deploy succeeds.
|
|
7
|
+
*/
|
|
8
|
+
export function createSelfUpdateFailureLog(wakeRoot, now = () => new Date().toISOString()) {
|
|
9
|
+
const path = join(wakeRoot, '.wake', 'self-update-failure.json');
|
|
10
|
+
return {
|
|
11
|
+
async record(tag, error) {
|
|
12
|
+
const message = error instanceof Error ? (error.stack ?? error.message) : String(error);
|
|
13
|
+
const failure = { tag, message, occurredAt: now() };
|
|
14
|
+
await mkdir(dirname(path), { recursive: true });
|
|
15
|
+
const temporary = `${path}.${process.pid}.tmp`;
|
|
16
|
+
await writeFile(temporary, `${JSON.stringify(failure)}\n`, 'utf8');
|
|
17
|
+
await rename(temporary, path);
|
|
18
|
+
},
|
|
19
|
+
async clear() {
|
|
20
|
+
await rm(path, { force: true });
|
|
21
|
+
},
|
|
22
|
+
async read() {
|
|
23
|
+
try {
|
|
24
|
+
return JSON.parse(await readFile(path, 'utf8'));
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
if (error.code === 'ENOENT')
|
|
28
|
+
return null;
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { execFile as nodeExecFile } from 'node:child_process';
|
|
2
|
+
import { promisify } from 'node:util';
|
|
3
|
+
const execFile = promisify(nodeExecFile);
|
|
4
|
+
export function createSourceUpdatePort(input) {
|
|
5
|
+
const execute = input.execute ?? runProcess;
|
|
6
|
+
return {
|
|
7
|
+
async isClean() {
|
|
8
|
+
return (await execute('git', ['status', '--porcelain'], input.repoRoot)).trim().length === 0;
|
|
9
|
+
},
|
|
10
|
+
async latestTag() {
|
|
11
|
+
const tag = (await execute('git', ['tag', '--sort=-v:refname'], input.repoRoot))
|
|
12
|
+
.split(/\r?\n/u)
|
|
13
|
+
.find((value) => value.trim().length > 0)
|
|
14
|
+
?.trim();
|
|
15
|
+
if (tag === undefined)
|
|
16
|
+
throw new Error('No source version tag is available');
|
|
17
|
+
return tag;
|
|
18
|
+
},
|
|
19
|
+
async candidateTags() {
|
|
20
|
+
const output = await execute('git', ['tag', '--sort=-v:refname'], input.repoRoot);
|
|
21
|
+
return output
|
|
22
|
+
.split(/\r?\n/u)
|
|
23
|
+
.map((line) => line.trim())
|
|
24
|
+
.filter((line) => line.length > 0);
|
|
25
|
+
},
|
|
26
|
+
async checkout(tag) {
|
|
27
|
+
await execute('git', ['checkout', tag], input.repoRoot);
|
|
28
|
+
},
|
|
29
|
+
async healthy() {
|
|
30
|
+
try {
|
|
31
|
+
// Verify the checked-out code can be built (TypeScript compiles).
|
|
32
|
+
// This is the minimal meaningful health check: the code must at least compile.
|
|
33
|
+
const buildCommand = 'npm';
|
|
34
|
+
const buildArgs = ['exec', 'tsc', '--'];
|
|
35
|
+
await execute(buildCommand, [...buildArgs], input.repoRoot);
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
async function runProcess(command, args, cwd) {
|
|
45
|
+
const result = await execFile(command, args, { cwd, encoding: 'utf8' });
|
|
46
|
+
return result.stdout;
|
|
47
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ActivityExecutionKind, activityName, ActivityOutcomeKind, } from '../activities/index.js';
|
|
3
|
+
import { DeliveryIntentEventType } from '../integrations/index.js';
|
|
4
|
+
import { createEventDraft, EventActorKind, EventSourceKind, } from '../kernel/index.js';
|
|
5
|
+
import { resourceStream } from '../resources/index.js';
|
|
6
|
+
export function createStatusPublishActivity(journal) {
|
|
7
|
+
return {
|
|
8
|
+
name: activityName('status.publish'),
|
|
9
|
+
inputSchema: z.object({ body: z.string().min(1) }).strict(),
|
|
10
|
+
outcomeSchema: z.object({ kind: z.literal(ActivityOutcomeKind.Done) }).strict(),
|
|
11
|
+
outcomeKinds: [ActivityOutcomeKind.Done],
|
|
12
|
+
resources: [],
|
|
13
|
+
executionKind: ActivityExecutionKind.Deterministic,
|
|
14
|
+
handler: {
|
|
15
|
+
async execute(invocation) {
|
|
16
|
+
const resource = invocation.resources[0];
|
|
17
|
+
if (resource === undefined)
|
|
18
|
+
throw new Error('status.publish requires an intake resource');
|
|
19
|
+
const sequence = (await journal.readStream(resourceStream(resource.resourceId))).length;
|
|
20
|
+
await journal.append(resourceStream(resource.resourceId), sequence, [
|
|
21
|
+
createEventDraft({
|
|
22
|
+
eventId: `${invocation.activationId}:status.publish`,
|
|
23
|
+
eventType: DeliveryIntentEventType.StatusPublishRequested,
|
|
24
|
+
occurredAt: new Date().toISOString(),
|
|
25
|
+
correlationId: invocation.causationId,
|
|
26
|
+
causationId: invocation.causationId,
|
|
27
|
+
actor: { kind: EventActorKind.System, id: 'status.publish' },
|
|
28
|
+
source: { kind: EventSourceKind.Internal, id: 'status.publish' },
|
|
29
|
+
stream: resourceStream(resource.resourceId),
|
|
30
|
+
payload: {
|
|
31
|
+
workflowInstanceId: invocation.workflowInstanceId,
|
|
32
|
+
activationId: invocation.activationId,
|
|
33
|
+
resourceId: resource.resourceId,
|
|
34
|
+
body: invocation.input.body,
|
|
35
|
+
},
|
|
36
|
+
}),
|
|
37
|
+
]);
|
|
38
|
+
return { kind: ActivityOutcomeKind.Done };
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import { ControlStreamKind } from '../control-plane/index.js';
|
|
2
|
+
import { ApiCommandStatus, fromWorkItemKey, presentBoardCard, presentResource, presentStatus, presentWorkflowInstance, redactConfiguration, } from '../surfaces/index.js';
|
|
3
|
+
import { analyticsProjection } from './analytics-projection.js';
|
|
4
|
+
import { boardConditionCounts, boardProjection, } from './board-projection.js';
|
|
5
|
+
import { primaryExternalRef } from './external-ref.js';
|
|
6
|
+
import { createSelfUpdateFailureLog } from './self-update-failure-log.js';
|
|
7
|
+
import { createExecutionApplications } from './surface-api-execution-applications.js';
|
|
8
|
+
import { projectionMeta, sampledMeta } from './surface-api-metadata.js';
|
|
9
|
+
import { projectionPage } from './surface-api-projection-pages.js';
|
|
10
|
+
import { createSurfaceWorkApplications } from './surface-api-work-applications.js';
|
|
11
|
+
import { wakeVersion } from './version.js';
|
|
12
|
+
export function createSurfaceApiApplications(root, now) {
|
|
13
|
+
return {
|
|
14
|
+
now,
|
|
15
|
+
board: createBoardApplications(root, now),
|
|
16
|
+
status: createStatusApplications(root, now),
|
|
17
|
+
controlPlane: createControlPlaneApplications(root, now),
|
|
18
|
+
work: createSurfaceWorkApplications(root, now),
|
|
19
|
+
resources: createResourceApplications(root, now),
|
|
20
|
+
orchestration: createOrchestrationApplications(root, now),
|
|
21
|
+
execution: createExecutionApplications(root, now),
|
|
22
|
+
events: createEventApplications(root, now),
|
|
23
|
+
observability: createObservabilityApplications(root, now),
|
|
24
|
+
system: createSystemApplications(root, now),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function createBoardApplications(root, now) {
|
|
28
|
+
return {
|
|
29
|
+
async list(query) {
|
|
30
|
+
const nowMs = Date.parse(now());
|
|
31
|
+
const stored = await root.projections.read(boardProjection.name, 'global');
|
|
32
|
+
const cards = Object.values(stored?.value.cards ?? {}).sort((left, right) => cardRecency(right).localeCompare(cardRecency(left)));
|
|
33
|
+
const offset = query.cursor?.position ?? 0;
|
|
34
|
+
const page = cards.slice(offset, offset + query.limit);
|
|
35
|
+
const items = await Promise.all(page.map(async (card) => {
|
|
36
|
+
const externalRef = await primaryExternalRef(root, card.workItemId);
|
|
37
|
+
const { activeRun, ...withoutActiveRun } = card;
|
|
38
|
+
return presentBoardCard({
|
|
39
|
+
...withoutActiveRun,
|
|
40
|
+
totalDurationMs: card.totalDurationMs ?? 0,
|
|
41
|
+
...(externalRef === undefined ? {} : { externalRef }),
|
|
42
|
+
...(card.lastRunAt === undefined
|
|
43
|
+
? {}
|
|
44
|
+
: { lastRunAgeMs: elapsedSince(card.lastRunAt, nowMs) }),
|
|
45
|
+
...(activeRun === undefined
|
|
46
|
+
? {}
|
|
47
|
+
: {
|
|
48
|
+
activeRun: {
|
|
49
|
+
...activeRun,
|
|
50
|
+
elapsedMs: elapsedSince(activeRun.startedAt, nowMs),
|
|
51
|
+
},
|
|
52
|
+
}),
|
|
53
|
+
});
|
|
54
|
+
}));
|
|
55
|
+
return {
|
|
56
|
+
items,
|
|
57
|
+
total: cards.length,
|
|
58
|
+
...(offset + query.limit < cards.length ? { nextPosition: offset + query.limit } : {}),
|
|
59
|
+
conditionCounts: boardConditionCounts(stored?.value ?? boardProjection.initial('global')),
|
|
60
|
+
meta: await projectionMeta(root.journal, stored === null ? [] : [stored], now()),
|
|
61
|
+
};
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function createStatusApplications(root, now) {
|
|
66
|
+
return {
|
|
67
|
+
async get() {
|
|
68
|
+
const stored = await root.projections.read(boardProjection.name, 'global');
|
|
69
|
+
return {
|
|
70
|
+
data: presentStatus({
|
|
71
|
+
conditionCounts: boardConditionCounts(stored?.value ?? boardProjection.initial('global')),
|
|
72
|
+
}),
|
|
73
|
+
meta: await projectionMeta(root.journal, stored === null ? [] : [stored], now()),
|
|
74
|
+
};
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function createResourceApplications(root, now) {
|
|
79
|
+
return {
|
|
80
|
+
async list(query) {
|
|
81
|
+
const stored = (await root.projections.list('resources')).flatMap((entry) => (entry.value === null ? [] : [{ ...entry, value: entry.value }]));
|
|
82
|
+
return projectionPage(root.journal, stored, query, presentResource(root.resolveResourceLink), {
|
|
83
|
+
emptyAsOf: now(),
|
|
84
|
+
});
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function createOrchestrationApplications(root, now) {
|
|
89
|
+
return {
|
|
90
|
+
async list(query) {
|
|
91
|
+
const stored = (await root.projections.list('orchestration')).flatMap((entry) => entry.value.view === null ? [] : [{ ...entry, value: entry.value.view }]);
|
|
92
|
+
const filtered = stored.filter((entry) => query.state === undefined || entry.value.status === query.state);
|
|
93
|
+
return projectionPage(root.journal, filtered, query, presentWorkflowInstance, {
|
|
94
|
+
emptyAsOf: now(),
|
|
95
|
+
provenance: stored,
|
|
96
|
+
});
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function createEventApplications(root, now) {
|
|
101
|
+
return {
|
|
102
|
+
async list(query) {
|
|
103
|
+
const workItemKey = query.workItemKey;
|
|
104
|
+
const workItemId = workItemKey === undefined
|
|
105
|
+
? undefined
|
|
106
|
+
: (() => {
|
|
107
|
+
try {
|
|
108
|
+
return fromWorkItemKey(workItemKey);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return workItemKey;
|
|
112
|
+
}
|
|
113
|
+
})();
|
|
114
|
+
const events = await recentEvents(root.journal, query.cursor?.position, query.limit + 1, (event) => workItemId === undefined ||
|
|
115
|
+
event.stream.id === workItemId ||
|
|
116
|
+
(typeof event.payload === 'object' &&
|
|
117
|
+
event.payload !== null &&
|
|
118
|
+
'workItemId' in event.payload &&
|
|
119
|
+
event.payload.workItemId === workItemId));
|
|
120
|
+
const visible = events.slice(0, query.limit);
|
|
121
|
+
const newest = visible[0];
|
|
122
|
+
const oldest = visible.at(-1);
|
|
123
|
+
const meta = await projectionMeta(root.journal, newest === undefined
|
|
124
|
+
? query.cursor === undefined
|
|
125
|
+
? []
|
|
126
|
+
: [{ lastGlobalPosition: query.cursor.position }]
|
|
127
|
+
: [{ lastGlobalPosition: newest.globalPosition }], now());
|
|
128
|
+
return {
|
|
129
|
+
items: presentEvents(visible),
|
|
130
|
+
meta,
|
|
131
|
+
...(events.length > query.limit && oldest !== undefined
|
|
132
|
+
? { nextPosition: oldest.globalPosition }
|
|
133
|
+
: {}),
|
|
134
|
+
...(newest === undefined && query.cursor === undefined
|
|
135
|
+
? {}
|
|
136
|
+
: { continuationPosition: oldest?.globalPosition ?? query.cursor.position }),
|
|
137
|
+
};
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
async function recentEvents(journal, beforeGlobalPosition, limit, include) {
|
|
142
|
+
const batchSize = Math.max(limit, 200);
|
|
143
|
+
const selected = [];
|
|
144
|
+
let before = beforeGlobalPosition;
|
|
145
|
+
while (selected.length < limit) {
|
|
146
|
+
const batch = journal.readLatest === undefined
|
|
147
|
+
? (await journal.readAll(0))
|
|
148
|
+
.filter((event) => before === undefined || event.globalPosition < before)
|
|
149
|
+
.slice(-batchSize)
|
|
150
|
+
.reverse()
|
|
151
|
+
: await journal.readLatest(before, batchSize);
|
|
152
|
+
if (batch.length === 0)
|
|
153
|
+
return selected;
|
|
154
|
+
for (const event of batch) {
|
|
155
|
+
if (include(event))
|
|
156
|
+
selected.push(event);
|
|
157
|
+
if (selected.length === limit)
|
|
158
|
+
return selected;
|
|
159
|
+
}
|
|
160
|
+
const oldest = batch.at(-1);
|
|
161
|
+
if (oldest === undefined || batch.length < batchSize)
|
|
162
|
+
return selected;
|
|
163
|
+
before = oldest.globalPosition;
|
|
164
|
+
}
|
|
165
|
+
return selected;
|
|
166
|
+
}
|
|
167
|
+
function createObservabilityApplications(root, now) {
|
|
168
|
+
return {
|
|
169
|
+
async metrics(query = { days: 7 }) {
|
|
170
|
+
const collectedAt = now();
|
|
171
|
+
const stored = await root.projections.read(analyticsProjection.name, 'global');
|
|
172
|
+
const analytics = stored?.value ?? analyticsProjection.initial('global');
|
|
173
|
+
const window = analyticsWindow(analytics, collectedAt, query.days);
|
|
174
|
+
return {
|
|
175
|
+
data: { collectedAt, window: window.range, values: window.values },
|
|
176
|
+
meta: await projectionMeta(root.journal, stored === null ? [] : [stored], collectedAt),
|
|
177
|
+
};
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
function createSystemApplications(root, now) {
|
|
182
|
+
return {
|
|
183
|
+
async health() {
|
|
184
|
+
const checkedAt = now();
|
|
185
|
+
const selfUpdateFailure = await createSelfUpdateFailureLog(root.paths.wakeRoot).read();
|
|
186
|
+
const checks = [
|
|
187
|
+
{ name: 'journal', status: 'ok' },
|
|
188
|
+
{ name: 'projections', status: 'ok' },
|
|
189
|
+
{ name: 'checkpoints', status: 'ok' },
|
|
190
|
+
selfUpdateFailure === null
|
|
191
|
+
? { name: 'self-update', status: 'ok' }
|
|
192
|
+
: {
|
|
193
|
+
name: 'self-update',
|
|
194
|
+
status: 'degraded',
|
|
195
|
+
detail: `rolled back from ${selfUpdateFailure.tag} at ${selfUpdateFailure.occurredAt}: ${selfUpdateFailure.message}`,
|
|
196
|
+
},
|
|
197
|
+
];
|
|
198
|
+
return {
|
|
199
|
+
data: {
|
|
200
|
+
status: checks.some((check) => check.status === 'degraded') ? 'degraded' : 'ok',
|
|
201
|
+
version: wakeVersion,
|
|
202
|
+
checkedAt,
|
|
203
|
+
checks,
|
|
204
|
+
},
|
|
205
|
+
meta: sampledMeta(checkedAt),
|
|
206
|
+
};
|
|
207
|
+
},
|
|
208
|
+
async configuration() {
|
|
209
|
+
const sampledAt = now();
|
|
210
|
+
return {
|
|
211
|
+
data: { configuration: redactConfiguration(root.config) },
|
|
212
|
+
meta: sampledMeta(sampledAt),
|
|
213
|
+
};
|
|
214
|
+
},
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
function commandAccepted(command, acceptedAt) {
|
|
218
|
+
return {
|
|
219
|
+
commandId: 'control:' + command.idempotencyKey,
|
|
220
|
+
idempotencyKey: command.idempotencyKey,
|
|
221
|
+
acceptedAt,
|
|
222
|
+
status: ApiCommandStatus.Accepted,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
function createControlPlaneApplications(root, now) {
|
|
226
|
+
const activeTicks = new Map();
|
|
227
|
+
const recentTicks = new Map();
|
|
228
|
+
let commandSequence = 0;
|
|
229
|
+
return {
|
|
230
|
+
status: () => readControlPlaneStatus(root, now),
|
|
231
|
+
async pause(command) {
|
|
232
|
+
await root.controlPlane.pause(command.idempotencyKey);
|
|
233
|
+
return commandAccepted(command, now());
|
|
234
|
+
},
|
|
235
|
+
async resume(command) {
|
|
236
|
+
await root.controlPlane.resume(command.idempotencyKey);
|
|
237
|
+
return commandAccepted(command, now());
|
|
238
|
+
},
|
|
239
|
+
tick(command) {
|
|
240
|
+
const completed = recentTicks.get(command.idempotencyKey);
|
|
241
|
+
if (completed !== undefined)
|
|
242
|
+
return Promise.resolve(completed);
|
|
243
|
+
const active = activeTicks.get(command.idempotencyKey);
|
|
244
|
+
if (active !== undefined)
|
|
245
|
+
return active;
|
|
246
|
+
const pending = performTick(root, now, command, ++commandSequence).then((result) => {
|
|
247
|
+
activeTicks.delete(command.idempotencyKey);
|
|
248
|
+
rememberRecentTick(recentTicks, command.idempotencyKey, result);
|
|
249
|
+
return result;
|
|
250
|
+
}, (error) => {
|
|
251
|
+
activeTicks.delete(command.idempotencyKey);
|
|
252
|
+
throw error;
|
|
253
|
+
});
|
|
254
|
+
activeTicks.set(command.idempotencyKey, pending);
|
|
255
|
+
return pending;
|
|
256
|
+
},
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
const recentAdvanceLimit = 100;
|
|
260
|
+
function rememberRecentTick(commands, key, result) {
|
|
261
|
+
commands.set(key, result);
|
|
262
|
+
while (commands.size > recentAdvanceLimit) {
|
|
263
|
+
const oldest = commands.keys().next().value;
|
|
264
|
+
if (oldest === undefined)
|
|
265
|
+
return;
|
|
266
|
+
commands.delete(oldest);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
async function performTick(root, now, command, sequence) {
|
|
270
|
+
const acceptedAt = now();
|
|
271
|
+
await root.runnerPipeline.run({ maxProgress: 1 });
|
|
272
|
+
return {
|
|
273
|
+
commandId: `tick:${acceptedAt}:${sequence}`,
|
|
274
|
+
idempotencyKey: command.idempotencyKey,
|
|
275
|
+
acceptedAt,
|
|
276
|
+
status: ApiCommandStatus.Completed,
|
|
277
|
+
result: await readControlPlaneStatus(root, now),
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
async function readControlPlaneStatus(root, now) {
|
|
281
|
+
const stored = await root.projections.read(ControlStreamKind.Global, 'global');
|
|
282
|
+
const meta = await projectionMeta(root.journal, stored === null ? [] : [stored], now());
|
|
283
|
+
return {
|
|
284
|
+
data: {
|
|
285
|
+
paused: stored?.value.pausedUntil !== null && stored?.value.pausedUntil !== undefined,
|
|
286
|
+
...(stored?.value.pausedUntil == null ? {} : { pausedUntil: stored.value.pausedUntil }),
|
|
287
|
+
...(stored?.value.reason === undefined ? {} : { reason: stored.value.reason }),
|
|
288
|
+
updatedAt: meta.asOf,
|
|
289
|
+
},
|
|
290
|
+
meta,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
function cardRecency(card) {
|
|
294
|
+
return card.lastRunAt ?? card.dwellSince;
|
|
295
|
+
}
|
|
296
|
+
export function elapsedSince(timestamp, nowMs) {
|
|
297
|
+
return nowMs - Date.parse(timestamp);
|
|
298
|
+
}
|
|
299
|
+
function presentEvents(events) {
|
|
300
|
+
return events.map((event) => ({
|
|
301
|
+
id: event.eventId,
|
|
302
|
+
type: event.eventType,
|
|
303
|
+
occurredAt: event.occurredAt,
|
|
304
|
+
position: event.globalPosition,
|
|
305
|
+
stream: event.stream,
|
|
306
|
+
causationId: event.causationId,
|
|
307
|
+
correlationId: event.correlationId,
|
|
308
|
+
payload: event.payload,
|
|
309
|
+
}));
|
|
310
|
+
}
|
|
311
|
+
function analyticsWindow(analytics, collectedAt, days) {
|
|
312
|
+
const end = collectedAt.slice(0, 10);
|
|
313
|
+
const endDate = new Date(`${end}T00:00:00.000Z`);
|
|
314
|
+
const startDate = new Date(endDate);
|
|
315
|
+
startDate.setUTCDate(startDate.getUTCDate() - (days - 1));
|
|
316
|
+
const from = startDate.toISOString().slice(0, 10);
|
|
317
|
+
const values = Object.entries(analytics.days)
|
|
318
|
+
.filter(([day]) => day >= from && day <= end)
|
|
319
|
+
.reduce((totals, [, bucket]) => ({
|
|
320
|
+
events: totals.events + bucket.events,
|
|
321
|
+
workItems: totals.workItems + bucket.workItems,
|
|
322
|
+
runs: totals.runs + bucket.runs,
|
|
323
|
+
}), { events: 0, workItems: 0, runs: 0 });
|
|
324
|
+
return { range: { days, from, to: end }, values };
|
|
325
|
+
}
|