@atolis-hq/wake 0.2.97 → 0.3.1
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/README.md +5 -5
- 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 +436 -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/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 -2442
- 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/templates/SETUP.md +0 -115
- /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,59 @@
|
|
|
1
|
+
import { ActivityOutcomeKind } from '../../../activities/index.js';
|
|
2
|
+
import { agentTokenUsage, RunStatus, } from '../../../execution/index.js';
|
|
3
|
+
const outcomeSentinels = {
|
|
4
|
+
[ActivityOutcomeKind.Done]: 'DONE',
|
|
5
|
+
[ActivityOutcomeKind.Rejected]: 'REJECTED',
|
|
6
|
+
[ActivityOutcomeKind.Blocked]: 'BLOCKED',
|
|
7
|
+
[ActivityOutcomeKind.Failed]: 'FAILED',
|
|
8
|
+
[ActivityOutcomeKind.Waiting]: 'WAITING',
|
|
9
|
+
};
|
|
10
|
+
// The response preserves optional run facts without introducing a second view model.
|
|
11
|
+
// eslint-disable-next-line complexity
|
|
12
|
+
export function presentRun(value) {
|
|
13
|
+
const usage = agentTokenUsage(value.agent?.metadata);
|
|
14
|
+
const sentinel = value.outcome?.kind !== undefined && isActivityOutcomeKind(value.outcome.kind)
|
|
15
|
+
? outcomeSentinels[value.outcome.kind]
|
|
16
|
+
: value.status.toUpperCase();
|
|
17
|
+
return {
|
|
18
|
+
runId: value.runId,
|
|
19
|
+
activationId: value.activationId,
|
|
20
|
+
activity: value.activity,
|
|
21
|
+
...(value.stage === undefined ? {} : { stage: value.stage }),
|
|
22
|
+
workflowInstanceId: value.workflowInstanceId,
|
|
23
|
+
orchestrationGroupId: value.orchestrationGroupId,
|
|
24
|
+
attempt: value.attempt,
|
|
25
|
+
status: value.status,
|
|
26
|
+
active: value.status === RunStatus.Started,
|
|
27
|
+
startedAt: value.startedAt,
|
|
28
|
+
...(value.finishedAt === undefined ? {} : { finishedAt: value.finishedAt }),
|
|
29
|
+
...(value.outcome === undefined ? {} : { outcome: value.outcome }),
|
|
30
|
+
...(value.failure === undefined ? {} : { failure: { kind: value.failure.kind } }),
|
|
31
|
+
sentinel,
|
|
32
|
+
...(value.runner?.name === undefined ? {} : { runnerName: value.runner.name }),
|
|
33
|
+
...(value.runner?.model === undefined ? {} : { runnerModel: value.runner.model }),
|
|
34
|
+
totalTokens: usage.tokens,
|
|
35
|
+
...tokenBreakdown(value.agent?.metadata),
|
|
36
|
+
totalCostUsd: usage.costUsd,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function tokenBreakdown(metadata) {
|
|
40
|
+
const numeric = (key) => {
|
|
41
|
+
const value = metadata?.[key];
|
|
42
|
+
return typeof value === 'number' ? value : undefined;
|
|
43
|
+
};
|
|
44
|
+
const inputTokens = numeric('inputTokens');
|
|
45
|
+
const outputTokens = numeric('outputTokens');
|
|
46
|
+
if (inputTokens === undefined || outputTokens === undefined)
|
|
47
|
+
return {};
|
|
48
|
+
const cacheReadTokens = numeric('cacheReadTokens');
|
|
49
|
+
const cacheWriteTokens = numeric('cacheWriteTokens');
|
|
50
|
+
return {
|
|
51
|
+
inputTokens,
|
|
52
|
+
outputTokens,
|
|
53
|
+
...(cacheReadTokens === undefined ? {} : { cacheReadTokens }),
|
|
54
|
+
...(cacheWriteTokens === undefined ? {} : { cacheWriteTokens }),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function isActivityOutcomeKind(kind) {
|
|
58
|
+
return Object.values(ActivityOutcomeKind).includes(kind);
|
|
59
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { resourceResponse as presentMetrics } from '../contracts/common.js';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { isOperatorRetryEligible, } from '../../../orchestration/index.js';
|
|
2
|
+
import { toWorkItemKey } from '../contracts/work.js';
|
|
3
|
+
export function presentWorkflowInstance(value) {
|
|
4
|
+
return {
|
|
5
|
+
workflowInstanceId: value.workflowInstanceId,
|
|
6
|
+
workItemKey: toWorkItemKey(value.workItemId),
|
|
7
|
+
workflowName: value.workflowName,
|
|
8
|
+
orchestrationGroupId: value.orchestrationGroupId,
|
|
9
|
+
...(value.parentWorkflowInstanceId === undefined
|
|
10
|
+
? {}
|
|
11
|
+
: { parentWorkflowInstanceId: value.parentWorkflowInstanceId }),
|
|
12
|
+
status: value.status,
|
|
13
|
+
currentStage: value.currentStage,
|
|
14
|
+
...(isOperatorRetryEligible(value) ? { retryEligible: true } : {}),
|
|
15
|
+
...(value.waitingFor === undefined
|
|
16
|
+
? {}
|
|
17
|
+
: { waitingFor: { signalKind: value.waitingFor.signalKind } }),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function presentResource(resolveLink) {
|
|
2
|
+
return (value) => {
|
|
3
|
+
const externalUrl = resolveLink(value.externalKey);
|
|
4
|
+
return {
|
|
5
|
+
resourceId: value.resourceId,
|
|
6
|
+
adapter: value.externalKey.adapter,
|
|
7
|
+
kind: value.kind,
|
|
8
|
+
locatorLabel: `${value.kind} ${value.externalKey.key}`,
|
|
9
|
+
capabilities: value.capabilities,
|
|
10
|
+
...(value.title === undefined ? {} : { title: value.title }),
|
|
11
|
+
...(externalUrl === null ? {} : { externalUrl }),
|
|
12
|
+
...(value.revision === undefined ? {} : { revision: value.revision }),
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { resourceResponse as presentSystem } from '../contracts/common.js';
|
|
2
|
+
export function redactConfiguration(value) {
|
|
3
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [
|
|
4
|
+
key,
|
|
5
|
+
/secret|token|password|credential|key/i.test(key) ? '[redacted]' : redactValue(item),
|
|
6
|
+
]));
|
|
7
|
+
}
|
|
8
|
+
function redactValue(value) {
|
|
9
|
+
if (Array.isArray(value))
|
|
10
|
+
return value.map(redactValue);
|
|
11
|
+
if (typeof value === 'object' && value !== null)
|
|
12
|
+
return redactConfiguration(value);
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { toWorkItemKey } from '../contracts/work.js';
|
|
2
|
+
/** The current Wake work identity is the canonical transport key; retain the mapping centrally. */
|
|
3
|
+
export function presentWorkItem(work) {
|
|
4
|
+
return {
|
|
5
|
+
workItemKey: toWorkItemKey(work.workItemId),
|
|
6
|
+
workItemId: work.workItemId,
|
|
7
|
+
objective: work.objective,
|
|
8
|
+
state: work.state,
|
|
9
|
+
...(work.frozen === undefined ? {} : { frozen: work.frozen }),
|
|
10
|
+
...(work.deleted === undefined ? {} : { deleted: work.deleted }),
|
|
11
|
+
relatedWorkItems: work.relatedWorkItems.map((item) => ({
|
|
12
|
+
workItemKey: toWorkItemKey(item.workItemId),
|
|
13
|
+
relation: item.relation,
|
|
14
|
+
})),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { defineClosedVocabulary } from '../../kernel/index.js';
|
|
2
|
+
export const BrowserRouteOutcome = defineClosedVocabulary({
|
|
3
|
+
Spa: 'spa',
|
|
4
|
+
NotFound: 'not-found',
|
|
5
|
+
});
|
|
6
|
+
/** Browser history fallback must never mask a missing API or static asset. */
|
|
7
|
+
export function routeBrowserRequest(method, pathname) {
|
|
8
|
+
if (method !== 'GET' && method !== 'HEAD')
|
|
9
|
+
return BrowserRouteOutcome.NotFound;
|
|
10
|
+
if (pathname.startsWith('/api/') || /\/[^/]+\.[^/]+$/.test(pathname))
|
|
11
|
+
return BrowserRouteOutcome.NotFound;
|
|
12
|
+
return BrowserRouteOutcome.Spa;
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const activityRoutes = [];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { normalizePage } from './pagination.js';
|
|
2
|
+
import { accepted, ApiPathError, decodePathSegment, invalidPath, invalidQuery, invalidRequest, isObject, problem, unavailable, } from './responses.js';
|
|
3
|
+
export async function dispatchCommand(applications, url, body) {
|
|
4
|
+
if (url.search !== '')
|
|
5
|
+
return invalidQuery('Command routes do not accept query parameters');
|
|
6
|
+
const request = commandRequest(body);
|
|
7
|
+
if ('status' in request)
|
|
8
|
+
return request;
|
|
9
|
+
const work = await dispatchWorkCommand(applications, url.pathname, request);
|
|
10
|
+
if (work !== undefined)
|
|
11
|
+
return work;
|
|
12
|
+
const control = await dispatchControlCommand(applications, url.pathname, request);
|
|
13
|
+
if (control !== undefined)
|
|
14
|
+
return control;
|
|
15
|
+
const runner = await dispatchRunnerCommand(applications, url.pathname, request);
|
|
16
|
+
return runner ?? problem(404, 'Not Found', `No command route for ${url.pathname}`);
|
|
17
|
+
}
|
|
18
|
+
async function dispatchWorkCommand(applications, pathname, request) {
|
|
19
|
+
const match = /^\/api\/v1\/work-items\/([^/]+)\/commands\/(freeze|unfreeze|delete|retry)$/.exec(pathname);
|
|
20
|
+
if (match === null)
|
|
21
|
+
return undefined;
|
|
22
|
+
const decoded = decodePathSegment(match[1]);
|
|
23
|
+
if (decoded instanceof ApiPathError)
|
|
24
|
+
return invalidPath(decoded.message);
|
|
25
|
+
const name = match[2];
|
|
26
|
+
const operation = applications.work[name];
|
|
27
|
+
if (operation === undefined)
|
|
28
|
+
return unavailable(name, (await applications.work.detail(decoded))?.data);
|
|
29
|
+
const status = name === 'freeze' || name === 'unfreeze' ? 200 : 202;
|
|
30
|
+
return accepted(await operation(decoded, request), applications.now(), status);
|
|
31
|
+
}
|
|
32
|
+
async function dispatchControlCommand(applications, pathname, request) {
|
|
33
|
+
const name = controlCommandName(pathname);
|
|
34
|
+
if (name === undefined)
|
|
35
|
+
return undefined;
|
|
36
|
+
const status = await applications.controlPlane.status();
|
|
37
|
+
if (name === 'tick' && status.data.paused)
|
|
38
|
+
return problem(409, 'Conflict', 'Ticks are paused', { code: 'paused', current: status.data });
|
|
39
|
+
const operation = applications.controlPlane[name];
|
|
40
|
+
return operation === undefined
|
|
41
|
+
? unavailable(name, status.data)
|
|
42
|
+
: accepted(await operation(request), applications.now());
|
|
43
|
+
}
|
|
44
|
+
function controlCommandName(pathname) {
|
|
45
|
+
const prefix = '/api/v1/control-plane/commands/';
|
|
46
|
+
if (!pathname.startsWith(prefix))
|
|
47
|
+
return undefined;
|
|
48
|
+
const name = pathname.slice(prefix.length);
|
|
49
|
+
return name === 'pause' || name === 'resume' || name === 'tick' ? name : undefined;
|
|
50
|
+
}
|
|
51
|
+
async function dispatchRunnerCommand(applications, pathname, request) {
|
|
52
|
+
const match = /^\/api\/v1\/runners\/([^/]+)\/commands\/(pause|unpause)$/.exec(pathname);
|
|
53
|
+
if (match === null)
|
|
54
|
+
return undefined;
|
|
55
|
+
const runnerId = decodePathSegment(match[1]);
|
|
56
|
+
if (runnerId instanceof ApiPathError)
|
|
57
|
+
return invalidPath(runnerId.message);
|
|
58
|
+
const operation = match[2] === 'pause'
|
|
59
|
+
? applications.execution.pauseRunner
|
|
60
|
+
: applications.execution.unpauseRunner;
|
|
61
|
+
if (operation !== undefined)
|
|
62
|
+
return accepted(await operation(runnerId, request), applications.now());
|
|
63
|
+
return unavailable(`runner-${match[2]}`, await currentRunner(applications, runnerId));
|
|
64
|
+
}
|
|
65
|
+
async function currentRunner(applications, runnerId) {
|
|
66
|
+
if (applications.execution.runners === undefined)
|
|
67
|
+
return undefined;
|
|
68
|
+
const page = normalizePage(await applications.execution.runners({ limit: 200 }));
|
|
69
|
+
return page.items.find((item) => item.runnerId === runnerId);
|
|
70
|
+
}
|
|
71
|
+
function commandRequest(body) {
|
|
72
|
+
if (!isObject(body))
|
|
73
|
+
return invalidRequest('idempotencyKey', 'A JSON object with an idempotency key is required');
|
|
74
|
+
if (Object.keys(body).some((key) => key !== 'idempotencyKey'))
|
|
75
|
+
return invalidRequest('', 'The command body contains unknown fields');
|
|
76
|
+
const value = body.idempotencyKey;
|
|
77
|
+
if (typeof value !== 'string' || value.trim() === '')
|
|
78
|
+
return invalidRequest('idempotencyKey', 'Must be a non-empty string');
|
|
79
|
+
return value.length <= 200
|
|
80
|
+
? { idempotencyKey: value }
|
|
81
|
+
: invalidRequest('idempotencyKey', 'Must be at most 200 characters');
|
|
82
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const eventRoutes = ['/api/v1/events'];
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { dispatchCommand } from './commands.js';
|
|
2
|
+
import { dispatchRead } from './read.js';
|
|
3
|
+
import { problem } from './responses.js';
|
|
4
|
+
export function createApiDispatcher(applications) {
|
|
5
|
+
return {
|
|
6
|
+
async dispatch(method, target, body) {
|
|
7
|
+
const url = new URL(target, 'http://wake.local');
|
|
8
|
+
if (!url.pathname.startsWith('/api/'))
|
|
9
|
+
return undefined;
|
|
10
|
+
const response = await dispatchRead(applications, method, url);
|
|
11
|
+
if (response !== undefined)
|
|
12
|
+
return response;
|
|
13
|
+
if (method === 'POST')
|
|
14
|
+
return dispatchCommand(applications, url, body);
|
|
15
|
+
return problem(404, 'Not Found', `No route for ${url.pathname}`);
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const observabilityRoutes = ['/api/v1/observability/metrics'];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const orchestrationRoutes = ['/api/v1/workflow-instances'];
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { collectionResponse, decodeCursor, encodeCursor } from '../contracts/index.js';
|
|
2
|
+
import { invalidQuery, ok } from './responses.js';
|
|
3
|
+
export function parseCollectionQuery(parameters, allowed) {
|
|
4
|
+
const invalidParameter = validateParameterNames(parameters, allowed);
|
|
5
|
+
if (invalidParameter !== undefined)
|
|
6
|
+
return invalidParameter;
|
|
7
|
+
const limit = parseLimit(parameters.get('limit'));
|
|
8
|
+
if (typeof limit !== 'number')
|
|
9
|
+
return limit;
|
|
10
|
+
const cursor = parseCursor(parameters.get('cursor'));
|
|
11
|
+
if ('status' in cursor)
|
|
12
|
+
return cursor;
|
|
13
|
+
const text = parseTextFilters(parameters);
|
|
14
|
+
return 'status' in text
|
|
15
|
+
? text
|
|
16
|
+
: queryResult(limit, cursor.value, text.search, text.state, parameters.get('workItemKey') ?? undefined);
|
|
17
|
+
}
|
|
18
|
+
export function collection(page, query) {
|
|
19
|
+
const visible = page.items.slice(0, query.limit);
|
|
20
|
+
const hasMore = page.nextPosition !== undefined || page.items.length > query.limit;
|
|
21
|
+
const nextPosition = page.continuationPosition ??
|
|
22
|
+
page.nextPosition ??
|
|
23
|
+
(hasMore ? (query.cursor?.position ?? 0) + visible.length : undefined);
|
|
24
|
+
return ok(collectionResponse(visible, page.meta.asOf, {
|
|
25
|
+
nextCursor: nextPosition === undefined ? null : encodeCursor({ position: nextPosition }),
|
|
26
|
+
hasMore,
|
|
27
|
+
...(page.total === undefined ? {} : { total: page.total }),
|
|
28
|
+
}, page.meta.position));
|
|
29
|
+
}
|
|
30
|
+
export function normalizePage(result) {
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
function validateParameterNames(parameters, allowed) {
|
|
34
|
+
for (const key of parameters.keys()) {
|
|
35
|
+
if (!allowed.has(key))
|
|
36
|
+
return invalidQuery(`Unknown query parameter: ${key}`, key);
|
|
37
|
+
if (parameters.getAll(key).length !== 1)
|
|
38
|
+
return invalidQuery(`Query parameter must occur once: ${key}`, key);
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
function parseLimit(value) {
|
|
43
|
+
const limit = value === null ? 50 : Number(value);
|
|
44
|
+
return /^[1-9]\d*$/.test(value ?? '50') && Number.isSafeInteger(limit) && limit <= 200
|
|
45
|
+
? limit
|
|
46
|
+
: invalidQuery('limit must be an integer from 1 to 200', 'limit');
|
|
47
|
+
}
|
|
48
|
+
function parseCursor(value) {
|
|
49
|
+
if (value === null)
|
|
50
|
+
return {};
|
|
51
|
+
try {
|
|
52
|
+
return { value: decodeCursor(value) };
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return invalidQuery('cursor is malformed or unsupported', 'cursor');
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function parseTextFilters(parameters) {
|
|
59
|
+
const search = parameters.get('search')?.trim();
|
|
60
|
+
if (search !== undefined && search.length > 200)
|
|
61
|
+
return invalidQuery('search must be at most 200 characters', 'search');
|
|
62
|
+
const state = parameters.get('state')?.trim();
|
|
63
|
+
if (state !== undefined && (state === '' || state.length > 100))
|
|
64
|
+
return invalidQuery('state must be a non-empty value of at most 100 characters', 'state');
|
|
65
|
+
return {
|
|
66
|
+
...(search === undefined || search === '' ? {} : { search }),
|
|
67
|
+
...(state === undefined ? {} : { state }),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function queryResult(limit, cursor, search, state, workItemKey) {
|
|
71
|
+
return {
|
|
72
|
+
limit,
|
|
73
|
+
...(cursor === undefined ? {} : { cursor }),
|
|
74
|
+
...(search === undefined ? {} : { search }),
|
|
75
|
+
...(state === undefined ? {} : { state }),
|
|
76
|
+
...(workItemKey === undefined ? {} : { workItemKey }),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { collection, parseCollectionQuery } from './pagination.js';
|
|
2
|
+
import { ApiPathError, decodePathSegment, found, invalidPath, invalidQuery, noQuery, ok, unavailable, } from './responses.js';
|
|
3
|
+
const collectionRoutes = new Map([
|
|
4
|
+
['/api/v1/work-items', new Set(['cursor', 'limit', 'search', 'state'])],
|
|
5
|
+
['/api/v1/resources', new Set(['cursor', 'limit'])],
|
|
6
|
+
['/api/v1/workflow-instances', new Set(['cursor', 'limit', 'state'])],
|
|
7
|
+
['/api/v1/runs', new Set(['cursor', 'limit', 'state'])],
|
|
8
|
+
['/api/v1/runners', new Set(['cursor', 'limit'])],
|
|
9
|
+
['/api/v1/events', new Set(['cursor', 'limit', 'workItemKey'])],
|
|
10
|
+
['/api/v1/board', new Set(['cursor', 'limit'])],
|
|
11
|
+
]);
|
|
12
|
+
export async function dispatchRead(applications, method, url) {
|
|
13
|
+
if (method !== 'GET' && method !== 'HEAD')
|
|
14
|
+
return undefined;
|
|
15
|
+
const resource = await readSingleton(applications, url);
|
|
16
|
+
if (resource !== undefined)
|
|
17
|
+
return resource;
|
|
18
|
+
const page = await readCollection(applications, url);
|
|
19
|
+
if (page !== undefined)
|
|
20
|
+
return page;
|
|
21
|
+
if (url.search !== '')
|
|
22
|
+
return invalidQuery('This resource does not accept query parameters');
|
|
23
|
+
return readDetail(applications, url.pathname);
|
|
24
|
+
}
|
|
25
|
+
async function readSingleton(applications, url) {
|
|
26
|
+
switch (url.pathname) {
|
|
27
|
+
case '/api/v1/control-plane/status':
|
|
28
|
+
return noQuery(url, async () => ok(await applications.controlPlane.status()));
|
|
29
|
+
case '/api/v1/observability/metrics':
|
|
30
|
+
return readMetrics(applications, url);
|
|
31
|
+
case '/api/v1/status':
|
|
32
|
+
return applications.status === undefined
|
|
33
|
+
? unavailable('status')
|
|
34
|
+
: noQuery(url, async () => ok(await applications.status.get()));
|
|
35
|
+
case '/api/v1/system/health':
|
|
36
|
+
return noQuery(url, async () => ok(await applications.system.health()));
|
|
37
|
+
case '/api/v1/system/configuration':
|
|
38
|
+
return noQuery(url, async () => ok(await applications.system.configuration()));
|
|
39
|
+
default:
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
async function readMetrics(applications, url) {
|
|
44
|
+
const allowed = new Set(['days']);
|
|
45
|
+
for (const key of url.searchParams.keys()) {
|
|
46
|
+
if (!allowed.has(key) || url.searchParams.getAll(key).length !== 1)
|
|
47
|
+
return invalidQuery(`Unknown or repeated query parameter: ${key}`, key);
|
|
48
|
+
}
|
|
49
|
+
const raw = url.searchParams.get('days');
|
|
50
|
+
const days = raw === null ? 7 : Number(raw);
|
|
51
|
+
if (!/^[1-9]\d*$/.test(raw ?? '7') || !Number.isSafeInteger(days) || days > 31)
|
|
52
|
+
return invalidQuery('days must be an integer from 1 to 31', 'days');
|
|
53
|
+
return ok(await applications.observability.metrics({ days }));
|
|
54
|
+
}
|
|
55
|
+
async function readCollection(applications, url) {
|
|
56
|
+
const allowed = collectionRoutes.get(url.pathname);
|
|
57
|
+
if (allowed === undefined)
|
|
58
|
+
return undefined;
|
|
59
|
+
const query = parseCollectionQuery(url.searchParams, allowed);
|
|
60
|
+
if ('status' in query)
|
|
61
|
+
return query;
|
|
62
|
+
return collectionResult(applications, url.pathname, query);
|
|
63
|
+
}
|
|
64
|
+
async function collectionResult(applications, pathname, query) {
|
|
65
|
+
switch (pathname) {
|
|
66
|
+
case '/api/v1/work-items':
|
|
67
|
+
return collection(await applications.work.list(query), query);
|
|
68
|
+
case '/api/v1/resources':
|
|
69
|
+
return collection(await applications.resources.list(query), query);
|
|
70
|
+
case '/api/v1/workflow-instances':
|
|
71
|
+
return collection(await applications.orchestration.list(query), query);
|
|
72
|
+
case '/api/v1/runs':
|
|
73
|
+
return collection(await applications.execution.list(query), query);
|
|
74
|
+
case '/api/v1/runners':
|
|
75
|
+
return applications.execution.runners === undefined
|
|
76
|
+
? unavailable('runners')
|
|
77
|
+
: collection(await applications.execution.runners(query), query);
|
|
78
|
+
case '/api/v1/board': {
|
|
79
|
+
if (applications.board === undefined)
|
|
80
|
+
return unavailable('board');
|
|
81
|
+
const board = await applications.board.list(query);
|
|
82
|
+
const response = collection(board, query);
|
|
83
|
+
return {
|
|
84
|
+
...response,
|
|
85
|
+
body: { ...response.body, conditionCounts: board.conditionCounts },
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
default:
|
|
89
|
+
return collection(await applications.events.list(query), query);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async function readDetail(applications, pathname) {
|
|
93
|
+
const workTranscript = /^\/api\/v1\/work-items\/([^/]+)\/transcripts\/([^/]+)$/.exec(pathname);
|
|
94
|
+
if (workTranscript?.[1] !== undefined && workTranscript[2] !== undefined)
|
|
95
|
+
return readWorkTranscript(applications, workTranscript[1], workTranscript[2]);
|
|
96
|
+
const transcript = /^\/api\/v1\/runs\/([^/]+)\/transcript$/.exec(pathname)?.[1];
|
|
97
|
+
if (transcript !== undefined)
|
|
98
|
+
return readTranscript(applications, transcript);
|
|
99
|
+
const work = /^\/api\/v1\/work-items\/([^/]+)$/.exec(pathname)?.[1];
|
|
100
|
+
if (work !== undefined)
|
|
101
|
+
return readWork(applications, work);
|
|
102
|
+
const run = /^\/api\/v1\/runs\/([^/]+)$/.exec(pathname)?.[1];
|
|
103
|
+
return run === undefined ? undefined : readRun(applications, run);
|
|
104
|
+
}
|
|
105
|
+
async function readWorkTranscript(applications, keySegment, groupSegment) {
|
|
106
|
+
const key = decodePathSegment(keySegment);
|
|
107
|
+
const groupId = decodePathSegment(groupSegment);
|
|
108
|
+
if (key instanceof ApiPathError)
|
|
109
|
+
return invalidPath(key.message);
|
|
110
|
+
if (groupId instanceof ApiPathError)
|
|
111
|
+
return invalidPath(groupId.message);
|
|
112
|
+
if (applications.work.transcript === undefined)
|
|
113
|
+
return unavailable('transcript');
|
|
114
|
+
return found(await applications.work.transcript(key, groupId));
|
|
115
|
+
}
|
|
116
|
+
async function readTranscript(applications, segment) {
|
|
117
|
+
const runId = decodePathSegment(segment);
|
|
118
|
+
if (runId instanceof ApiPathError)
|
|
119
|
+
return invalidPath(runId.message);
|
|
120
|
+
if (applications.execution.transcript === undefined)
|
|
121
|
+
return unavailable('transcript', await applications.execution.get?.(runId));
|
|
122
|
+
return found(await applications.execution.transcript(runId));
|
|
123
|
+
}
|
|
124
|
+
async function readWork(applications, segment) {
|
|
125
|
+
const key = decodePathSegment(segment);
|
|
126
|
+
return key instanceof ApiPathError
|
|
127
|
+
? invalidPath(key.message)
|
|
128
|
+
: found(await applications.work.detail(key));
|
|
129
|
+
}
|
|
130
|
+
async function readRun(applications, segment) {
|
|
131
|
+
const runId = decodePathSegment(segment);
|
|
132
|
+
return runId instanceof ApiPathError
|
|
133
|
+
? invalidPath(runId.message)
|
|
134
|
+
: found(await applications.execution.get?.(runId));
|
|
135
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const resourceRoutes = ['/api/v1/resources'];
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { resourceResponse, } from '../contracts/index.js';
|
|
2
|
+
import { problemDetails } from '../problem-details.js';
|
|
3
|
+
export async function noQuery(url, operation) {
|
|
4
|
+
return url.search === ''
|
|
5
|
+
? operation()
|
|
6
|
+
: invalidQuery('This resource does not accept query parameters');
|
|
7
|
+
}
|
|
8
|
+
export function decodePathSegment(value) {
|
|
9
|
+
try {
|
|
10
|
+
return decodeURIComponent(value);
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return new ApiPathError('The route contains malformed percent encoding');
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export class ApiPathError extends Error {
|
|
17
|
+
}
|
|
18
|
+
export function accepted(value, asOf, status = 202) {
|
|
19
|
+
if ('conflict' in value)
|
|
20
|
+
return problem(409, 'Conflict', value.detail ?? 'The command conflicts with current state', {
|
|
21
|
+
code: value.code,
|
|
22
|
+
retryable: value.retryable ?? false,
|
|
23
|
+
...(value.current === undefined ? {} : { current: value.current }),
|
|
24
|
+
});
|
|
25
|
+
return {
|
|
26
|
+
status,
|
|
27
|
+
body: resourceResponse(value, 'acceptedAt' in value ? value.acceptedAt : asOf),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export function ok(body) {
|
|
31
|
+
return { status: 200, body };
|
|
32
|
+
}
|
|
33
|
+
export function found(value) {
|
|
34
|
+
return value === undefined ? problem(404, 'Not Found', 'Resource not found') : ok(value);
|
|
35
|
+
}
|
|
36
|
+
export function unavailable(commandName, current) {
|
|
37
|
+
return problem(409, 'Conflict', `The ${commandName} capability is unavailable`, {
|
|
38
|
+
code: 'command-unavailable',
|
|
39
|
+
retryable: false,
|
|
40
|
+
...(current === undefined ? {} : { current }),
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
export function invalidPath(detail) {
|
|
44
|
+
return problem(400, 'Bad Request', detail, { code: 'invalid-path' });
|
|
45
|
+
}
|
|
46
|
+
export function invalidQuery(detail, path = '') {
|
|
47
|
+
return problem(422, 'Unprocessable Content', detail, {
|
|
48
|
+
code: 'invalid-query',
|
|
49
|
+
violations: [{ path, message: detail }],
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
export function invalidRequest(path, message) {
|
|
53
|
+
return problem(422, 'Unprocessable Content', 'The command request is invalid', {
|
|
54
|
+
code: 'invalid-request',
|
|
55
|
+
violations: [{ path, message }],
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
export function problem(status, title, detail, extensions = {}) {
|
|
59
|
+
return {
|
|
60
|
+
status,
|
|
61
|
+
body: problemDetails(status, title, detail, extensions),
|
|
62
|
+
contentType: 'application/problem+json',
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export function isObject(value) {
|
|
66
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
67
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const systemRoutes = ['/api/v1/system/health', '/api/v1/system/configuration'];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const workRoutes = [
|
|
2
|
+
'/api/v1/work-items',
|
|
3
|
+
'/api/v1/work-items/:workItemKey',
|
|
4
|
+
'/api/v1/work-items/:workItemKey/transcripts/:groupId',
|
|
5
|
+
'/api/v1/work-items/:workItemKey/commands/freeze',
|
|
6
|
+
'/api/v1/work-items/:workItemKey/commands/unfreeze',
|
|
7
|
+
'/api/v1/work-items/:workItemKey/commands/delete',
|
|
8
|
+
'/api/v1/work-items/:workItemKey/commands/retry',
|
|
9
|
+
];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const api = (application) => application.start();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Reads canonical journal facts, not a projection, so it remains useful during rebuilds. */
|
|
2
|
+
export async function audit(journal, work, workItemId) {
|
|
3
|
+
await work.get(workItemId);
|
|
4
|
+
return (await journal.readAll(0))
|
|
5
|
+
.filter((event) => event.stream.id === workItemId)
|
|
6
|
+
.map((event) => ({
|
|
7
|
+
event,
|
|
8
|
+
causalLinks: { causationId: event.causationId, correlationId: event.correlationId },
|
|
9
|
+
}));
|
|
10
|
+
}
|