@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
|
@@ -1,775 +0,0 @@
|
|
|
1
|
-
import { setTimeout as delay } from 'node:timers/promises';
|
|
2
|
-
import { access, appendFile, mkdir, readFile, readdir, rename } from 'node:fs/promises';
|
|
3
|
-
import { dirname, join } from 'node:path';
|
|
4
|
-
import { validateResourceIndex } from './resource-index.js';
|
|
5
|
-
import { parseEventEnvelope, parseIssueStateRecord, parseLedger, parseRunInputSnapshot, parseRunRecord, parseSourceStateRecord, } from '../../domain/schema.js';
|
|
6
|
-
import { isTerminalStage } from '../../domain/stages.js';
|
|
7
|
-
import { appendJsonLine, readJsonFile, writeJsonFile } from '../../lib/json-file.js';
|
|
8
|
-
import { acquireFileLock } from '../../lib/lock.js';
|
|
9
|
-
import { createWakePaths } from '../../lib/paths.js';
|
|
10
|
-
import { isMissingPathError, stateHealthIssue, StateHealthError, throwIfUnhealthy, } from '../../lib/state-health.js';
|
|
11
|
-
const runSummaryIndexLockTimeoutMs = 5_000;
|
|
12
|
-
const runSummaryIndexLockPollMs = 10;
|
|
13
|
-
async function readIssueStateFile(file) {
|
|
14
|
-
try {
|
|
15
|
-
return parseIssueStateRecord(await readJsonFile(file));
|
|
16
|
-
}
|
|
17
|
-
catch (error) {
|
|
18
|
-
if (isMissingPathError(error)) {
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
throw new StateHealthError([
|
|
22
|
-
stateHealthIssue({
|
|
23
|
-
surface: 'state',
|
|
24
|
-
kind: 'corrupted',
|
|
25
|
-
path: file,
|
|
26
|
-
message: error instanceof Error ? error.message : String(error),
|
|
27
|
-
}),
|
|
28
|
-
]);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
// The board/runs/metrics UI list many run records at once purely for their
|
|
32
|
-
// small fields (status, timing, routing) - metadata.stdout/stderr/raw and
|
|
33
|
-
// runtimeEvents are captured agent output that can run into single-digit MB
|
|
34
|
-
// per run, and holding all of them in memory for a full-history listing is
|
|
35
|
-
// what took the UI process OOM. Stripped only for bulk-list reads; single-run
|
|
36
|
-
// reads (readRunRecord) keep the full record since reconciliation code
|
|
37
|
-
// spreads a record's metadata back into a rewrite (see stale-run-reconciler).
|
|
38
|
-
function stripHeavyRunRecordFields(record) {
|
|
39
|
-
if (record.metadata === undefined && record.runtimeEvents === undefined) {
|
|
40
|
-
return record;
|
|
41
|
-
}
|
|
42
|
-
const { runtimeEvents: _runtimeEvents, metadata, ...rest } = record;
|
|
43
|
-
if (metadata === undefined) {
|
|
44
|
-
return rest;
|
|
45
|
-
}
|
|
46
|
-
const { stdout: _stdout, stderr: _stderr, raw: _raw, ...restMetadata } = metadata;
|
|
47
|
-
return { ...rest, metadata: restMetadata };
|
|
48
|
-
}
|
|
49
|
-
function compareIssueStatesForListing(left, right) {
|
|
50
|
-
return left.workItemKey.localeCompare(right.workItemKey);
|
|
51
|
-
}
|
|
52
|
-
function parseRunRecordSummaryIndex(input, date) {
|
|
53
|
-
if (input === null || typeof input !== 'object') {
|
|
54
|
-
throw new Error('Run summary index must be an object');
|
|
55
|
-
}
|
|
56
|
-
const record = input;
|
|
57
|
-
if (record.schemaVersion !== 1) {
|
|
58
|
-
throw new Error('Run summary index schemaVersion must be 1');
|
|
59
|
-
}
|
|
60
|
-
if (record.date !== date) {
|
|
61
|
-
throw new Error(`Run summary index date must be ${date}`);
|
|
62
|
-
}
|
|
63
|
-
if (!Array.isArray(record.entries)) {
|
|
64
|
-
throw new Error('Run summary index entries must be an array');
|
|
65
|
-
}
|
|
66
|
-
return {
|
|
67
|
-
schemaVersion: 1,
|
|
68
|
-
date,
|
|
69
|
-
entries: record.entries.map((entry) => parseRunRecord(entry)),
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
async function withRunSummaryIndexLock(paths, date, operation) {
|
|
73
|
-
const deadline = Date.now() + runSummaryIndexLockTimeoutMs;
|
|
74
|
-
while (true) {
|
|
75
|
-
const lock = await acquireFileLock(paths.runDateIndexLockFile(date), {
|
|
76
|
-
staleAfterMs: runSummaryIndexLockTimeoutMs,
|
|
77
|
-
});
|
|
78
|
-
if (lock.acquired) {
|
|
79
|
-
try {
|
|
80
|
-
return await operation();
|
|
81
|
-
}
|
|
82
|
-
finally {
|
|
83
|
-
await lock.release();
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
if (Date.now() >= deadline) {
|
|
87
|
-
throw new Error(`Timed out acquiring run summary index lock for ${date}`);
|
|
88
|
-
}
|
|
89
|
-
await delay(runSummaryIndexLockPollMs);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
async function readRunSummaryIndex(paths, date) {
|
|
93
|
-
return parseRunRecordSummaryIndex(await readJsonFile(paths.runDateIndexFile(date)), date);
|
|
94
|
-
}
|
|
95
|
-
async function writeRunSummaryIndex(paths, date, entries) {
|
|
96
|
-
await writeJsonFile(paths.runDateIndexFile(date), {
|
|
97
|
-
schemaVersion: 1,
|
|
98
|
-
date,
|
|
99
|
-
entries: entries.sort((left, right) => left.startedAt.localeCompare(right.startedAt)),
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
async function countRunDateBucketFiles(paths, date) {
|
|
103
|
-
return (await readdir(join(paths.dataRoot, 'runs', 'by-date', date), { withFileTypes: true }).catch((error) => {
|
|
104
|
-
if (isMissingPathError(error)) {
|
|
105
|
-
return [];
|
|
106
|
-
}
|
|
107
|
-
throw error;
|
|
108
|
-
})).filter((file) => file.isFile() && file.name.endsWith('.json') && file.name !== 'index.json')
|
|
109
|
-
.length;
|
|
110
|
-
}
|
|
111
|
-
async function rebuildRunSummaryIndexForDate(paths, date) {
|
|
112
|
-
const recordsById = new Map();
|
|
113
|
-
const bucketFiles = (await readdir(join(paths.dataRoot, 'runs', 'by-date', date)).catch(() => []))
|
|
114
|
-
.filter((file) => file.endsWith('.json') && file !== 'index.json')
|
|
115
|
-
.sort();
|
|
116
|
-
for (const file of bucketFiles) {
|
|
117
|
-
const record = await readRunRecordFile(join(paths.dataRoot, 'runs', 'by-date', date, file), {
|
|
118
|
-
summarize: true,
|
|
119
|
-
});
|
|
120
|
-
if (record !== null) {
|
|
121
|
-
recordsById.set(record.runId, record);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
const entries = [...recordsById.values()].sort((left, right) => left.startedAt.localeCompare(right.startedAt));
|
|
125
|
-
await writeRunSummaryIndex(paths, date, entries);
|
|
126
|
-
return entries;
|
|
127
|
-
}
|
|
128
|
-
async function upsertRunSummaryIndexEntry(paths, record) {
|
|
129
|
-
const date = record.startedAt.slice(0, 10);
|
|
130
|
-
const summary = stripHeavyRunRecordFields(record);
|
|
131
|
-
await withRunSummaryIndexLock(paths, date, async () => {
|
|
132
|
-
const entries = await readRunSummaryIndex(paths, date)
|
|
133
|
-
.then((index) => index.entries)
|
|
134
|
-
.catch(() => []);
|
|
135
|
-
const nextById = new Map(entries.map((entry) => [entry.runId, entry]));
|
|
136
|
-
nextById.set(summary.runId, summary);
|
|
137
|
-
await writeRunSummaryIndex(paths, date, [...nextById.values()]);
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
async function readRunRecordFile(file, options) {
|
|
141
|
-
try {
|
|
142
|
-
const record = parseRunRecord(await readJsonFile(file));
|
|
143
|
-
return options?.summarize === true ? stripHeavyRunRecordFields(record) : record;
|
|
144
|
-
}
|
|
145
|
-
catch {
|
|
146
|
-
return null;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
async function readEventFile(file) {
|
|
150
|
-
try {
|
|
151
|
-
const raw = await readFile(file, 'utf8');
|
|
152
|
-
const envelopes = [];
|
|
153
|
-
let lineNumber = 0;
|
|
154
|
-
for (const line of raw.split('\n')) {
|
|
155
|
-
lineNumber += 1;
|
|
156
|
-
const trimmed = line.trim();
|
|
157
|
-
if (trimmed.length === 0) {
|
|
158
|
-
continue;
|
|
159
|
-
}
|
|
160
|
-
try {
|
|
161
|
-
const parsed = JSON.parse(trimmed);
|
|
162
|
-
envelopes.push(parseEventEnvelope(parsed));
|
|
163
|
-
}
|
|
164
|
-
catch (error) {
|
|
165
|
-
throw new StateHealthError([
|
|
166
|
-
stateHealthIssue({
|
|
167
|
-
surface: 'events',
|
|
168
|
-
kind: 'corrupted',
|
|
169
|
-
path: `${file}:${lineNumber}`,
|
|
170
|
-
message: error instanceof Error ? error.message : String(error),
|
|
171
|
-
}),
|
|
172
|
-
]);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
return envelopes;
|
|
176
|
-
}
|
|
177
|
-
catch (error) {
|
|
178
|
-
if (isMissingPathError(error)) {
|
|
179
|
-
return [];
|
|
180
|
-
}
|
|
181
|
-
if (error instanceof StateHealthError) {
|
|
182
|
-
throw error;
|
|
183
|
-
}
|
|
184
|
-
throw new StateHealthError([
|
|
185
|
-
stateHealthIssue({
|
|
186
|
-
surface: 'events',
|
|
187
|
-
kind: 'corrupted',
|
|
188
|
-
path: file,
|
|
189
|
-
message: error instanceof Error ? error.message : String(error),
|
|
190
|
-
}),
|
|
191
|
-
]);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
async function collectIssueStateIssues(paths) {
|
|
195
|
-
const issues = [];
|
|
196
|
-
const visit = async (dir) => {
|
|
197
|
-
const entries = await readdir(dir, { withFileTypes: true }).catch((error) => {
|
|
198
|
-
if (isMissingPathError(error)) {
|
|
199
|
-
return [];
|
|
200
|
-
}
|
|
201
|
-
throw error;
|
|
202
|
-
});
|
|
203
|
-
for (const entry of entries) {
|
|
204
|
-
if (entry.isDirectory()) {
|
|
205
|
-
if (entry.name === 'index') {
|
|
206
|
-
continue;
|
|
207
|
-
}
|
|
208
|
-
await visit(join(dir, entry.name));
|
|
209
|
-
continue;
|
|
210
|
-
}
|
|
211
|
-
if (!entry.isFile() || !entry.name.endsWith('.json')) {
|
|
212
|
-
continue;
|
|
213
|
-
}
|
|
214
|
-
const file = join(dir, entry.name);
|
|
215
|
-
try {
|
|
216
|
-
parseIssueStateRecord(await readJsonFile(file));
|
|
217
|
-
}
|
|
218
|
-
catch (error) {
|
|
219
|
-
issues.push(stateHealthIssue({
|
|
220
|
-
surface: 'state',
|
|
221
|
-
kind: 'corrupted',
|
|
222
|
-
path: file,
|
|
223
|
-
message: error instanceof Error ? error.message : String(error),
|
|
224
|
-
}));
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
};
|
|
228
|
-
await visit(join(paths.dataRoot, 'state'));
|
|
229
|
-
return issues;
|
|
230
|
-
}
|
|
231
|
-
async function collectEventIssues(paths) {
|
|
232
|
-
const issues = [];
|
|
233
|
-
const eventLogFiles = await readdir(join(paths.dataRoot, 'events'), {
|
|
234
|
-
withFileTypes: true,
|
|
235
|
-
}).catch((error) => {
|
|
236
|
-
if (isMissingPathError(error)) {
|
|
237
|
-
return [];
|
|
238
|
-
}
|
|
239
|
-
throw error;
|
|
240
|
-
});
|
|
241
|
-
for (const entry of eventLogFiles) {
|
|
242
|
-
if (!entry.isFile() || !entry.name.endsWith('.jsonl')) {
|
|
243
|
-
continue;
|
|
244
|
-
}
|
|
245
|
-
try {
|
|
246
|
-
await readEventFile(join(paths.dataRoot, 'events', entry.name));
|
|
247
|
-
}
|
|
248
|
-
catch (error) {
|
|
249
|
-
if (error instanceof StateHealthError) {
|
|
250
|
-
issues.push(...error.issues);
|
|
251
|
-
}
|
|
252
|
-
else {
|
|
253
|
-
throw error;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
const eventEnvelopeFiles = await readdir(join(paths.dataRoot, 'events-by-id'), {
|
|
258
|
-
withFileTypes: true,
|
|
259
|
-
}).catch((error) => {
|
|
260
|
-
if (isMissingPathError(error)) {
|
|
261
|
-
return [];
|
|
262
|
-
}
|
|
263
|
-
throw error;
|
|
264
|
-
});
|
|
265
|
-
for (const entry of eventEnvelopeFiles) {
|
|
266
|
-
if (!entry.isFile() || !entry.name.endsWith('.json')) {
|
|
267
|
-
continue;
|
|
268
|
-
}
|
|
269
|
-
const file = join(paths.dataRoot, 'events-by-id', entry.name);
|
|
270
|
-
try {
|
|
271
|
-
parseEventEnvelope(await readJsonFile(file));
|
|
272
|
-
}
|
|
273
|
-
catch (error) {
|
|
274
|
-
issues.push(stateHealthIssue({
|
|
275
|
-
surface: 'events',
|
|
276
|
-
kind: 'corrupted',
|
|
277
|
-
path: file,
|
|
278
|
-
message: error instanceof Error ? error.message : String(error),
|
|
279
|
-
}));
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
return issues;
|
|
283
|
-
}
|
|
284
|
-
async function collectRunSummaryIndexIssues(paths) {
|
|
285
|
-
const issues = [];
|
|
286
|
-
const byDateRoot = join(paths.dataRoot, 'runs', 'by-date');
|
|
287
|
-
const dateDirs = await readdir(byDateRoot, { withFileTypes: true }).catch((error) => {
|
|
288
|
-
if (isMissingPathError(error)) {
|
|
289
|
-
return [];
|
|
290
|
-
}
|
|
291
|
-
throw error;
|
|
292
|
-
});
|
|
293
|
-
for (const entry of dateDirs) {
|
|
294
|
-
if (!entry.isDirectory()) {
|
|
295
|
-
continue;
|
|
296
|
-
}
|
|
297
|
-
const date = entry.name;
|
|
298
|
-
const runFileCount = await countRunDateBucketFiles(paths, date);
|
|
299
|
-
const indexFile = paths.runDateIndexFile(date);
|
|
300
|
-
try {
|
|
301
|
-
const index = await readRunSummaryIndex(paths, date);
|
|
302
|
-
if (index.entries.length !== runFileCount) {
|
|
303
|
-
issues.push(stateHealthIssue({
|
|
304
|
-
surface: 'runs',
|
|
305
|
-
kind: 'incomplete',
|
|
306
|
-
path: indexFile,
|
|
307
|
-
message: `Run summary index has ${index.entries.length} entries but ${runFileCount} run files exist for ${date}`,
|
|
308
|
-
}));
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
catch (error) {
|
|
312
|
-
issues.push(stateHealthIssue({
|
|
313
|
-
surface: 'runs',
|
|
314
|
-
kind: isMissingPathError(error) ? 'incomplete' : 'corrupted',
|
|
315
|
-
path: indexFile,
|
|
316
|
-
message: error instanceof Error ? error.message : String(error),
|
|
317
|
-
}));
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
return issues;
|
|
321
|
-
}
|
|
322
|
-
function issueArchiveAgeDate(item) {
|
|
323
|
-
const stageChangedAt = item.wake.stageHistory.at(-1)?.changedAt;
|
|
324
|
-
return ([stageChangedAt, item.wake.syncedAt, item.issue.updatedAt]
|
|
325
|
-
.filter((value) => value !== undefined)
|
|
326
|
-
.sort()
|
|
327
|
-
.at(-1) ?? item.wake.syncedAt);
|
|
328
|
-
}
|
|
329
|
-
function shouldArchiveIssueState(item, options) {
|
|
330
|
-
if (!isTerminalStage(item.wake.stage) && item.issue.state !== 'closed') {
|
|
331
|
-
return false;
|
|
332
|
-
}
|
|
333
|
-
const ageMs = options.now.getTime() - Date.parse(issueArchiveAgeDate(item));
|
|
334
|
-
return Number.isFinite(ageMs) && ageMs > options.archiveFreshnessDays * 24 * 60 * 60 * 1000;
|
|
335
|
-
}
|
|
336
|
-
async function listRunRecordsImpl(wakeRoot, options) {
|
|
337
|
-
const runsRoot = join(createWakePaths(wakeRoot).dataRoot, 'runs');
|
|
338
|
-
const recordsById = new Map();
|
|
339
|
-
try {
|
|
340
|
-
const files = (await readdir(runsRoot)).filter((file) => file.endsWith('.json')).sort();
|
|
341
|
-
for (const file of files) {
|
|
342
|
-
const record = await readRunRecordFile(join(runsRoot, file), options);
|
|
343
|
-
if (record !== null) {
|
|
344
|
-
recordsById.set(record.runId, record);
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
catch {
|
|
349
|
-
// The date-bucketed layout below may still exist.
|
|
350
|
-
}
|
|
351
|
-
try {
|
|
352
|
-
const byDateRoot = join(runsRoot, 'by-date');
|
|
353
|
-
const dateDirs = (await readdir(byDateRoot)).sort();
|
|
354
|
-
for (const dateDir of dateDirs) {
|
|
355
|
-
const files = (await readdir(join(byDateRoot, dateDir)).catch(() => []))
|
|
356
|
-
.filter((file) => file.endsWith('.json'))
|
|
357
|
-
.sort();
|
|
358
|
-
for (const file of files) {
|
|
359
|
-
const record = await readRunRecordFile(join(byDateRoot, dateDir, file), options);
|
|
360
|
-
if (record !== null) {
|
|
361
|
-
recordsById.set(record.runId, record);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
catch {
|
|
367
|
-
// Old wake homes only have root-level run files.
|
|
368
|
-
}
|
|
369
|
-
return [...recordsById.values()].sort((left, right) => left.startedAt.localeCompare(right.startedAt));
|
|
370
|
-
}
|
|
371
|
-
export async function listRunRecords(wakeRoot) {
|
|
372
|
-
return listRunRecordsImpl(wakeRoot);
|
|
373
|
-
}
|
|
374
|
-
// Same records as listRunRecords, but with metadata.stdout/stderr/raw and
|
|
375
|
-
// runtimeEvents stripped per-file as they're read - for callers (board/runs/
|
|
376
|
-
// metrics UI) that list every run and only need the small fields. See
|
|
377
|
-
// stripHeavyRunRecordFields for why this can't just be a post-hoc .map() over
|
|
378
|
-
// listRunRecords: that would still hold every full record in memory at once.
|
|
379
|
-
export async function listRunRecordSummaries(wakeRoot) {
|
|
380
|
-
const paths = createWakePaths(wakeRoot);
|
|
381
|
-
const byDateRoot = join(paths.dataRoot, 'runs', 'by-date');
|
|
382
|
-
const dateDirs = (await readdir(byDateRoot).catch(() => [])).sort();
|
|
383
|
-
if (dateDirs.length === 0) {
|
|
384
|
-
return listRunRecordsImpl(wakeRoot, { summarize: true });
|
|
385
|
-
}
|
|
386
|
-
const recordsById = new Map();
|
|
387
|
-
for (const dateDir of dateDirs) {
|
|
388
|
-
const records = await listRunRecordSummariesForDate(wakeRoot, dateDir);
|
|
389
|
-
for (const record of records) {
|
|
390
|
-
recordsById.set(record.runId, record);
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
return [...recordsById.values()].sort((left, right) => left.startedAt.localeCompare(right.startedAt));
|
|
394
|
-
}
|
|
395
|
-
async function listRunRecordsForDateImpl(wakeRoot, date, options) {
|
|
396
|
-
const runsRoot = join(createWakePaths(wakeRoot).dataRoot, 'runs');
|
|
397
|
-
const recordsById = new Map();
|
|
398
|
-
const bucketFiles = (await readdir(join(runsRoot, 'by-date', date)).catch(() => []))
|
|
399
|
-
.filter((file) => file.endsWith('.json'))
|
|
400
|
-
.sort();
|
|
401
|
-
for (const file of bucketFiles) {
|
|
402
|
-
const record = await readRunRecordFile(join(runsRoot, 'by-date', date, file), options);
|
|
403
|
-
if (record !== null) {
|
|
404
|
-
recordsById.set(record.runId, record);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
if (recordsById.size === 0) {
|
|
408
|
-
const legacyFiles = (await readdir(runsRoot).catch(() => []))
|
|
409
|
-
.filter((file) => file.endsWith('.json'))
|
|
410
|
-
.sort();
|
|
411
|
-
for (const file of legacyFiles) {
|
|
412
|
-
const record = await readRunRecordFile(join(runsRoot, file), options);
|
|
413
|
-
if (record?.startedAt.slice(0, 10) === date) {
|
|
414
|
-
recordsById.set(record.runId, record);
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
return [...recordsById.values()].sort((left, right) => left.startedAt.localeCompare(right.startedAt));
|
|
419
|
-
}
|
|
420
|
-
async function listRunRecordsForDate(wakeRoot, date) {
|
|
421
|
-
return listRunRecordsForDateImpl(wakeRoot, date);
|
|
422
|
-
}
|
|
423
|
-
async function listRunRecordSummariesForDate(wakeRoot, date) {
|
|
424
|
-
const paths = createWakePaths(wakeRoot);
|
|
425
|
-
try {
|
|
426
|
-
const index = await readRunSummaryIndex(paths, date);
|
|
427
|
-
const runFileCount = await countRunDateBucketFiles(paths, date);
|
|
428
|
-
if (index.entries.length === runFileCount && (index.entries.length > 0 || runFileCount > 0)) {
|
|
429
|
-
return index.entries;
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
catch {
|
|
433
|
-
// Rebuild below under the per-date lock.
|
|
434
|
-
}
|
|
435
|
-
const rebuilt = await withRunSummaryIndexLock(paths, date, async () => {
|
|
436
|
-
const runFileCount = await countRunDateBucketFiles(paths, date);
|
|
437
|
-
if (runFileCount === 0) {
|
|
438
|
-
return null;
|
|
439
|
-
}
|
|
440
|
-
try {
|
|
441
|
-
const index = await readRunSummaryIndex(paths, date);
|
|
442
|
-
if (index.entries.length === runFileCount) {
|
|
443
|
-
return index.entries;
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
catch {
|
|
447
|
-
// Rebuild below.
|
|
448
|
-
}
|
|
449
|
-
return rebuildRunSummaryIndexForDate(paths, date);
|
|
450
|
-
});
|
|
451
|
-
if (rebuilt !== null) {
|
|
452
|
-
return rebuilt;
|
|
453
|
-
}
|
|
454
|
-
return listRunRecordsForDateImpl(wakeRoot, date, { summarize: true });
|
|
455
|
-
}
|
|
456
|
-
async function listRecentRunRecords(wakeRoot, limit) {
|
|
457
|
-
const runsRoot = join(createWakePaths(wakeRoot).dataRoot, 'runs');
|
|
458
|
-
const recordsById = new Map();
|
|
459
|
-
const dateDirs = (await readdir(join(runsRoot, 'by-date')).catch(() => [])).sort().reverse();
|
|
460
|
-
for (const dateDir of dateDirs) {
|
|
461
|
-
const records = await listRunRecordsForDate(wakeRoot, dateDir);
|
|
462
|
-
for (const record of records.reverse()) {
|
|
463
|
-
recordsById.set(record.runId, record);
|
|
464
|
-
if (recordsById.size >= limit) {
|
|
465
|
-
return [...recordsById.values()].sort((left, right) => right.startedAt.localeCompare(left.startedAt));
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
if (recordsById.size === 0) {
|
|
470
|
-
return (await listRunRecords(wakeRoot))
|
|
471
|
-
.sort((left, right) => right.startedAt.localeCompare(left.startedAt))
|
|
472
|
-
.slice(0, limit);
|
|
473
|
-
}
|
|
474
|
-
return [...recordsById.values()].sort((left, right) => right.startedAt.localeCompare(left.startedAt));
|
|
475
|
-
}
|
|
476
|
-
export function createStateStore({ wakeRoot }) {
|
|
477
|
-
const paths = createWakePaths(wakeRoot);
|
|
478
|
-
return {
|
|
479
|
-
paths,
|
|
480
|
-
async ensureWakeRoot() {
|
|
481
|
-
await mkdir(wakeRoot, { recursive: true });
|
|
482
|
-
},
|
|
483
|
-
async writeLedger(record) {
|
|
484
|
-
const parsed = parseLedger(record);
|
|
485
|
-
await writeJsonFile(paths.ledgerFile, parsed);
|
|
486
|
-
return parsed;
|
|
487
|
-
},
|
|
488
|
-
async readLedger() {
|
|
489
|
-
try {
|
|
490
|
-
return parseLedger(await readJsonFile(paths.ledgerFile));
|
|
491
|
-
}
|
|
492
|
-
catch (error) {
|
|
493
|
-
if (isMissingPathError(error)) {
|
|
494
|
-
return null;
|
|
495
|
-
}
|
|
496
|
-
throw error;
|
|
497
|
-
}
|
|
498
|
-
},
|
|
499
|
-
async writeIssueState(record) {
|
|
500
|
-
const parsed = parseIssueStateRecord(record);
|
|
501
|
-
await writeJsonFile(paths.workItemStateFile(parsed.workItemKey), parsed);
|
|
502
|
-
return parsed;
|
|
503
|
-
},
|
|
504
|
-
async readIssueState(workId) {
|
|
505
|
-
return ((await readIssueStateFile(paths.workItemStateFile(workId))) ??
|
|
506
|
-
(await readIssueStateFile(paths.archivedWorkItemStateFile(workId))));
|
|
507
|
-
},
|
|
508
|
-
async writeRunRecord(record) {
|
|
509
|
-
const parsed = parseRunRecord(record);
|
|
510
|
-
await writeJsonFile(paths.runFile(parsed.runId), parsed);
|
|
511
|
-
await writeJsonFile(paths.runDateFile(parsed.startedAt.slice(0, 10), parsed.runId), parsed);
|
|
512
|
-
await upsertRunSummaryIndexEntry(paths, parsed);
|
|
513
|
-
return parsed;
|
|
514
|
-
},
|
|
515
|
-
async writeRunInputSnapshot(record) {
|
|
516
|
-
const parsed = parseRunInputSnapshot(record);
|
|
517
|
-
await writeJsonFile(paths.runInputSnapshotFile(parsed.snapshotId), parsed);
|
|
518
|
-
return parsed;
|
|
519
|
-
},
|
|
520
|
-
async readRunInputSnapshot(snapshotId) {
|
|
521
|
-
try {
|
|
522
|
-
return parseRunInputSnapshot(await readJsonFile(paths.runInputSnapshotFile(snapshotId)));
|
|
523
|
-
}
|
|
524
|
-
catch (error) {
|
|
525
|
-
if (isMissingPathError(error)) {
|
|
526
|
-
return null;
|
|
527
|
-
}
|
|
528
|
-
throw error;
|
|
529
|
-
}
|
|
530
|
-
},
|
|
531
|
-
async updateRunRecordIf(runId, input) {
|
|
532
|
-
const current = await this.readRunRecord(runId);
|
|
533
|
-
if (current === null || !input.expect(current)) {
|
|
534
|
-
return null;
|
|
535
|
-
}
|
|
536
|
-
return this.writeRunRecord(input.update(current));
|
|
537
|
-
},
|
|
538
|
-
async writeSourceState(record) {
|
|
539
|
-
const parsed = parseSourceStateRecord(record);
|
|
540
|
-
await writeJsonFile(paths.sourceStateFile(parsed.source, parsed.key), parsed);
|
|
541
|
-
return parsed;
|
|
542
|
-
},
|
|
543
|
-
async readRunRecord(runId) {
|
|
544
|
-
try {
|
|
545
|
-
return parseRunRecord(await readJsonFile(paths.runFile(runId)));
|
|
546
|
-
}
|
|
547
|
-
catch {
|
|
548
|
-
// buildBoard calls this once per work item (readRunRecord per
|
|
549
|
-
// lastRunId), so a missing flat file used to mean a full,
|
|
550
|
-
// unstripped listRecentRunRecords(500) scan - every heavy
|
|
551
|
-
// stdout/raw payload in the 500 most recent runs, parsed again for
|
|
552
|
-
// every item on the board. Scan summaries to locate the record's
|
|
553
|
-
// date bucket instead, then do one targeted full read of just that
|
|
554
|
-
// file so the caller still gets full fidelity.
|
|
555
|
-
const summaries = await listRunRecordSummaries(wakeRoot);
|
|
556
|
-
const match = summaries.find((record) => record.runId === runId);
|
|
557
|
-
if (match === undefined) {
|
|
558
|
-
return null;
|
|
559
|
-
}
|
|
560
|
-
try {
|
|
561
|
-
return parseRunRecord(await readJsonFile(paths.runDateFile(match.startedAt.slice(0, 10), runId)));
|
|
562
|
-
}
|
|
563
|
-
catch {
|
|
564
|
-
return match;
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
},
|
|
568
|
-
async listRunRecords() {
|
|
569
|
-
return listRunRecords(wakeRoot);
|
|
570
|
-
},
|
|
571
|
-
async listRunRecordSummaries() {
|
|
572
|
-
return listRunRecordSummaries(wakeRoot);
|
|
573
|
-
},
|
|
574
|
-
async listRunRecordsForDate(date) {
|
|
575
|
-
return listRunRecordsForDate(wakeRoot, date);
|
|
576
|
-
},
|
|
577
|
-
async listRunRecordSummariesForDate(date) {
|
|
578
|
-
return listRunRecordSummariesForDate(wakeRoot, date);
|
|
579
|
-
},
|
|
580
|
-
async listRecentRunRecords(limit = 10) {
|
|
581
|
-
return listRecentRunRecords(wakeRoot, limit);
|
|
582
|
-
},
|
|
583
|
-
async readSourceState(source, key) {
|
|
584
|
-
try {
|
|
585
|
-
return parseSourceStateRecord(await readJsonFile(paths.sourceStateFile(source, key)));
|
|
586
|
-
}
|
|
587
|
-
catch (error) {
|
|
588
|
-
if (isMissingPathError(error)) {
|
|
589
|
-
return null;
|
|
590
|
-
}
|
|
591
|
-
throw error;
|
|
592
|
-
}
|
|
593
|
-
},
|
|
594
|
-
async appendEventEnvelope(record) {
|
|
595
|
-
const parsed = parseEventEnvelope(record);
|
|
596
|
-
const existing = await this.readEventEnvelope(parsed.eventId);
|
|
597
|
-
if (existing !== null) {
|
|
598
|
-
return existing;
|
|
599
|
-
}
|
|
600
|
-
await appendJsonLine(paths.eventFile(parsed.ingestedAt.slice(0, 10)), parsed);
|
|
601
|
-
await writeJsonFile(paths.eventEnvelopeFile(parsed.eventId), parsed);
|
|
602
|
-
return parsed;
|
|
603
|
-
},
|
|
604
|
-
async readEventEnvelope(eventId) {
|
|
605
|
-
try {
|
|
606
|
-
return parseEventEnvelope(await readJsonFile(paths.eventEnvelopeFile(eventId)));
|
|
607
|
-
}
|
|
608
|
-
catch (error) {
|
|
609
|
-
if (isMissingPathError(error)) {
|
|
610
|
-
return null;
|
|
611
|
-
}
|
|
612
|
-
throw new StateHealthError([
|
|
613
|
-
stateHealthIssue({
|
|
614
|
-
surface: 'events',
|
|
615
|
-
kind: 'corrupted',
|
|
616
|
-
path: paths.eventEnvelopeFile(eventId),
|
|
617
|
-
message: error instanceof Error ? error.message : String(error),
|
|
618
|
-
}),
|
|
619
|
-
]);
|
|
620
|
-
}
|
|
621
|
-
},
|
|
622
|
-
async listIssueStates(options = {}) {
|
|
623
|
-
const stateRoot = join(paths.dataRoot, 'state');
|
|
624
|
-
const items = [];
|
|
625
|
-
const includeArchived = options.includeArchived ?? false;
|
|
626
|
-
const archiveOptions = options.archiveFreshnessDays === undefined
|
|
627
|
-
? null
|
|
628
|
-
: {
|
|
629
|
-
archiveFreshnessDays: options.archiveFreshnessDays,
|
|
630
|
-
now: options.now ?? new Date(),
|
|
631
|
-
};
|
|
632
|
-
// state/ is flat: state/<workId>.json, plus state/archive/ and the
|
|
633
|
-
// reverse index's own state/index/ shards. Only those two subdirectories
|
|
634
|
-
// exist, and index/ holds `{ resourceUri: workItemKey }` maps that are
|
|
635
|
-
// not projections at all — skip it rather than parse-and-discard.
|
|
636
|
-
const visit = async (dir, isArchive) => {
|
|
637
|
-
const entries = await readdir(dir, { withFileTypes: true }).catch((error) => {
|
|
638
|
-
if (isMissingPathError(error)) {
|
|
639
|
-
return [];
|
|
640
|
-
}
|
|
641
|
-
throw error;
|
|
642
|
-
});
|
|
643
|
-
for (const entry of entries) {
|
|
644
|
-
if (entry.isDirectory()) {
|
|
645
|
-
if (entry.name === 'index') {
|
|
646
|
-
continue;
|
|
647
|
-
}
|
|
648
|
-
if (entry.name === 'archive' && includeArchived) {
|
|
649
|
-
await visit(join(dir, entry.name), true);
|
|
650
|
-
}
|
|
651
|
-
continue;
|
|
652
|
-
}
|
|
653
|
-
if (!entry.isFile() || !entry.name.endsWith('.json')) {
|
|
654
|
-
continue;
|
|
655
|
-
}
|
|
656
|
-
const file = join(dir, entry.name);
|
|
657
|
-
const record = await readIssueStateFile(file);
|
|
658
|
-
if (record === null)
|
|
659
|
-
continue;
|
|
660
|
-
if (archiveOptions !== null &&
|
|
661
|
-
!isArchive &&
|
|
662
|
-
shouldArchiveIssueState(record, archiveOptions)) {
|
|
663
|
-
const archivePath = paths.archivedWorkItemStateFile(record.workItemKey);
|
|
664
|
-
await mkdir(dirname(archivePath), { recursive: true });
|
|
665
|
-
await rename(file, archivePath).catch(() => undefined);
|
|
666
|
-
continue;
|
|
667
|
-
}
|
|
668
|
-
items.push(record);
|
|
669
|
-
}
|
|
670
|
-
};
|
|
671
|
-
await visit(stateRoot, false);
|
|
672
|
-
const byWorkItemKey = new Map();
|
|
673
|
-
for (const item of items) {
|
|
674
|
-
byWorkItemKey.set(item.workItemKey, item);
|
|
675
|
-
}
|
|
676
|
-
return [...byWorkItemKey.values()].sort(compareIssueStatesForListing);
|
|
677
|
-
},
|
|
678
|
-
async listEventEnvelopes() {
|
|
679
|
-
const eventsRoot = join(paths.dataRoot, 'events');
|
|
680
|
-
try {
|
|
681
|
-
const files = (await readdir(eventsRoot)).sort();
|
|
682
|
-
const envelopes = [];
|
|
683
|
-
for (const file of files) {
|
|
684
|
-
envelopes.push(...(await readEventFile(join(eventsRoot, file))));
|
|
685
|
-
}
|
|
686
|
-
return envelopes;
|
|
687
|
-
}
|
|
688
|
-
catch (error) {
|
|
689
|
-
if (isMissingPathError(error)) {
|
|
690
|
-
return [];
|
|
691
|
-
}
|
|
692
|
-
throw error;
|
|
693
|
-
}
|
|
694
|
-
},
|
|
695
|
-
async listRecentEventEnvelopes(filter = {}) {
|
|
696
|
-
const limit = filter.limit ?? 200;
|
|
697
|
-
const eventsRoot = join(paths.dataRoot, 'events');
|
|
698
|
-
const files = (await readdir(eventsRoot).catch((error) => {
|
|
699
|
-
if (isMissingPathError(error)) {
|
|
700
|
-
return [];
|
|
701
|
-
}
|
|
702
|
-
throw error;
|
|
703
|
-
}))
|
|
704
|
-
.filter((file) => file.endsWith('.jsonl'))
|
|
705
|
-
.sort()
|
|
706
|
-
.reverse();
|
|
707
|
-
const results = [];
|
|
708
|
-
for (const file of files) {
|
|
709
|
-
const events = await readEventFile(join(eventsRoot, file));
|
|
710
|
-
for (const event of events.reverse()) {
|
|
711
|
-
if (filter.workItemKey !== undefined && event.workItemKey !== filter.workItemKey) {
|
|
712
|
-
continue;
|
|
713
|
-
}
|
|
714
|
-
if (filter.direction !== undefined && event.direction !== filter.direction) {
|
|
715
|
-
continue;
|
|
716
|
-
}
|
|
717
|
-
if (filter.type !== undefined && event.sourceEventType !== filter.type) {
|
|
718
|
-
continue;
|
|
719
|
-
}
|
|
720
|
-
results.push(event);
|
|
721
|
-
if (results.length >= limit) {
|
|
722
|
-
return results;
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
}
|
|
726
|
-
return results;
|
|
727
|
-
},
|
|
728
|
-
async listEventEnvelopesForWorkItem(workItemKey, limit = 10) {
|
|
729
|
-
const projection = await this.readIssueState(workItemKey);
|
|
730
|
-
const recentEventIds = projection?.wake.recentEventIds.slice(-limit) ?? [];
|
|
731
|
-
const envelopes = [];
|
|
732
|
-
for (const eventId of recentEventIds) {
|
|
733
|
-
const envelope = await this.readEventEnvelope(eventId);
|
|
734
|
-
if (envelope?.workItemKey === workItemKey) {
|
|
735
|
-
envelopes.push(envelope);
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
return envelopes;
|
|
739
|
-
},
|
|
740
|
-
async appendLog(date, line) {
|
|
741
|
-
await mkdir(wakeRoot, { recursive: true });
|
|
742
|
-
await appendFile(paths.logFile(date), `${line}\n`, 'utf8');
|
|
743
|
-
},
|
|
744
|
-
// Only the manual pause file is a hard stop on the whole loop. Quota
|
|
745
|
-
// pauses are now per-runner (ledger.runners, #67): a paused runner skips
|
|
746
|
-
// itself via routing fallback inside a tick, but the tick loop itself must
|
|
747
|
-
// keep running so polling, delivery retries, and other tiers still make
|
|
748
|
-
// progress while one runner is paused.
|
|
749
|
-
async isPaused(_now = new Date()) {
|
|
750
|
-
try {
|
|
751
|
-
await access(paths.pauseFile);
|
|
752
|
-
return true;
|
|
753
|
-
}
|
|
754
|
-
catch {
|
|
755
|
-
return false;
|
|
756
|
-
}
|
|
757
|
-
},
|
|
758
|
-
async readEventLog(date) {
|
|
759
|
-
return readFile(paths.eventFile(date), 'utf8');
|
|
760
|
-
},
|
|
761
|
-
async validateStateHealth() {
|
|
762
|
-
const issues = [
|
|
763
|
-
...(await collectEventIssues(paths)),
|
|
764
|
-
...(await collectIssueStateIssues(paths)),
|
|
765
|
-
...(await collectRunSummaryIndexIssues(paths)),
|
|
766
|
-
...(await validateResourceIndex(paths)),
|
|
767
|
-
];
|
|
768
|
-
return { healthy: issues.length === 0, issues };
|
|
769
|
-
},
|
|
770
|
-
async assertStateHealthy() {
|
|
771
|
-
const report = await this.validateStateHealth();
|
|
772
|
-
throwIfUnhealthy(report.issues);
|
|
773
|
-
},
|
|
774
|
-
};
|
|
775
|
-
}
|