@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,81 +0,0 @@
|
|
|
1
|
-
import { currentProcessIdentity } from '../lib/process-identity.js';
|
|
2
|
-
function createEventQueue() {
|
|
3
|
-
const queue = [];
|
|
4
|
-
const waiters = [];
|
|
5
|
-
let closed = false;
|
|
6
|
-
function emit(value) {
|
|
7
|
-
const waiter = waiters.shift();
|
|
8
|
-
if (waiter !== undefined) {
|
|
9
|
-
waiter(value);
|
|
10
|
-
return;
|
|
11
|
-
}
|
|
12
|
-
queue.push(value);
|
|
13
|
-
}
|
|
14
|
-
async function nextQueued() {
|
|
15
|
-
const value = queue.shift();
|
|
16
|
-
if (value !== undefined)
|
|
17
|
-
return value;
|
|
18
|
-
if (closed)
|
|
19
|
-
return { kind: 'done' };
|
|
20
|
-
return new Promise((resolve) => waiters.push(resolve));
|
|
21
|
-
}
|
|
22
|
-
return {
|
|
23
|
-
push(event) {
|
|
24
|
-
if (!closed)
|
|
25
|
-
emit({ kind: 'event', event });
|
|
26
|
-
},
|
|
27
|
-
close() {
|
|
28
|
-
if (closed)
|
|
29
|
-
return;
|
|
30
|
-
closed = true;
|
|
31
|
-
emit({ kind: 'done' });
|
|
32
|
-
},
|
|
33
|
-
fail(error) {
|
|
34
|
-
if (closed)
|
|
35
|
-
return;
|
|
36
|
-
closed = true;
|
|
37
|
-
emit({ kind: 'error', error });
|
|
38
|
-
},
|
|
39
|
-
iterable: {
|
|
40
|
-
async *[Symbol.asyncIterator]() {
|
|
41
|
-
while (true) {
|
|
42
|
-
const value = await nextQueued();
|
|
43
|
-
if (value.kind === 'done')
|
|
44
|
-
return;
|
|
45
|
-
if (value.kind === 'error')
|
|
46
|
-
throw value.error;
|
|
47
|
-
yield value.event;
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
export function createAgentExecution(input, execute) {
|
|
54
|
-
const controller = new AbortController();
|
|
55
|
-
const events = createEventQueue();
|
|
56
|
-
const result = Promise.resolve()
|
|
57
|
-
.then(() => execute({
|
|
58
|
-
...input,
|
|
59
|
-
cancellationSignal: controller.signal,
|
|
60
|
-
onRuntimeEvent: async (event) => {
|
|
61
|
-
await input.onRuntimeEvent?.(event);
|
|
62
|
-
events.push(event);
|
|
63
|
-
},
|
|
64
|
-
}))
|
|
65
|
-
.then((value) => {
|
|
66
|
-
events.close();
|
|
67
|
-
return value;
|
|
68
|
-
}, (error) => {
|
|
69
|
-
events.fail(error);
|
|
70
|
-
throw error;
|
|
71
|
-
});
|
|
72
|
-
return {
|
|
73
|
-
runId: input.runId,
|
|
74
|
-
processIdentity: currentProcessIdentity(),
|
|
75
|
-
events: events.iterable,
|
|
76
|
-
async cancel(reason) {
|
|
77
|
-
controller.abort(reason);
|
|
78
|
-
},
|
|
79
|
-
result,
|
|
80
|
-
};
|
|
81
|
-
}
|
package/dist/src/core/outbox.js
DELETED
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import { LABELS_REQUESTED_EVENT, PUBLISH_CONFIRMED_EVENT, PUBLISH_FAILED_EVENT, PUBLISH_INTENT_REQUESTED_EVENT, PUBLISH_SENT_UNCONFIRMED_EVENT, } from '../domain/event-types.js';
|
|
3
|
-
import { createEventEnvelope } from '../lib/event-log.js';
|
|
4
|
-
const outboxMaxAttempts = 3;
|
|
5
|
-
const outboundIntentEventTypes = new Set([PUBLISH_INTENT_REQUESTED_EVENT, LABELS_REQUESTED_EVENT]);
|
|
6
|
-
const outboundConfirmationEventTypes = new Set([
|
|
7
|
-
'ticket.reply.published',
|
|
8
|
-
'ticket.labels.updated',
|
|
9
|
-
PUBLISH_CONFIRMED_EVENT,
|
|
10
|
-
'pr.comment.reply.published',
|
|
11
|
-
'pr.review-comment.reply.published',
|
|
12
|
-
]);
|
|
13
|
-
function intentId(event) {
|
|
14
|
-
const intentEventId = event.payload.intentEventId;
|
|
15
|
-
return typeof intentEventId === 'string' ? intentEventId : undefined;
|
|
16
|
-
}
|
|
17
|
-
// The outbox: outbound delivery (comments, labels) attempted independently of
|
|
18
|
-
// run-outcome recording, with a durable, bounded retry trace. Extracted from
|
|
19
|
-
// tick-runner.ts so it can be exercised in isolation; it has the cleanest
|
|
20
|
-
// boundary of the tick's collaborators — no dependency on candidate selection.
|
|
21
|
-
export function createOutbox(deps) {
|
|
22
|
-
async function recordDeliveryFailure(intentEvent, err) {
|
|
23
|
-
const occurredAt = deps.clock.now().toISOString();
|
|
24
|
-
const failureEvent = createEventEnvelope({
|
|
25
|
-
eventId: `${intentEvent.eventId}-delivery-failed-${randomUUID()}`,
|
|
26
|
-
workItemKey: intentEvent.workItemKey,
|
|
27
|
-
streamScope: 'work-item',
|
|
28
|
-
direction: 'internal',
|
|
29
|
-
sourceSystem: 'wake',
|
|
30
|
-
sourceEventType: PUBLISH_FAILED_EVENT,
|
|
31
|
-
sourceRefs: intentEvent.sourceRefs,
|
|
32
|
-
occurredAt,
|
|
33
|
-
ingestedAt: occurredAt,
|
|
34
|
-
trigger: 'context-only',
|
|
35
|
-
payload: {
|
|
36
|
-
intentEventId: intentEvent.eventId,
|
|
37
|
-
intentEventType: intentEvent.sourceEventType,
|
|
38
|
-
idempotencyKey: intentEvent.payload.idempotencyKey,
|
|
39
|
-
deliveryState: 'PENDING',
|
|
40
|
-
error: err instanceof Error ? err.message : String(err),
|
|
41
|
-
},
|
|
42
|
-
});
|
|
43
|
-
await deps.stateStore.appendEventEnvelope(failureEvent);
|
|
44
|
-
await deps.projectionUpdater.rebuildFromEvents([failureEvent]);
|
|
45
|
-
}
|
|
46
|
-
async function recordSentUnconfirmed(intentEvent) {
|
|
47
|
-
const occurredAt = deps.clock.now().toISOString();
|
|
48
|
-
const sentEvent = createEventEnvelope({
|
|
49
|
-
eventId: `${intentEvent.eventId}-sent-unconfirmed-${randomUUID()}`,
|
|
50
|
-
workItemKey: intentEvent.workItemKey,
|
|
51
|
-
streamScope: 'work-item',
|
|
52
|
-
direction: 'internal',
|
|
53
|
-
sourceSystem: 'wake',
|
|
54
|
-
sourceEventType: PUBLISH_SENT_UNCONFIRMED_EVENT,
|
|
55
|
-
sourceRefs: intentEvent.sourceRefs,
|
|
56
|
-
occurredAt,
|
|
57
|
-
ingestedAt: occurredAt,
|
|
58
|
-
trigger: 'context-only',
|
|
59
|
-
payload: {
|
|
60
|
-
intentEventId: intentEvent.eventId,
|
|
61
|
-
intentEventType: intentEvent.sourceEventType,
|
|
62
|
-
idempotencyKey: intentEvent.payload.idempotencyKey,
|
|
63
|
-
deliveryState: 'SENT_UNCONFIRMED',
|
|
64
|
-
},
|
|
65
|
-
});
|
|
66
|
-
await deps.stateStore.appendEventEnvelope(sentEvent);
|
|
67
|
-
await deps.projectionUpdater.rebuildFromEvents([sentEvent]);
|
|
68
|
-
}
|
|
69
|
-
async function recordConfirmed(intentEvent, payload = {}) {
|
|
70
|
-
const confirmedAt = deps.clock.now().toISOString();
|
|
71
|
-
const confirmedEvent = createEventEnvelope({
|
|
72
|
-
eventId: `${intentEvent.eventId}-confirmed`,
|
|
73
|
-
workItemKey: intentEvent.workItemKey,
|
|
74
|
-
streamScope: 'work-item',
|
|
75
|
-
direction: 'internal',
|
|
76
|
-
sourceSystem: 'wake',
|
|
77
|
-
sourceEventType: PUBLISH_CONFIRMED_EVENT,
|
|
78
|
-
sourceRefs: intentEvent.sourceRefs,
|
|
79
|
-
occurredAt: confirmedAt,
|
|
80
|
-
ingestedAt: confirmedAt,
|
|
81
|
-
trigger: 'context-only',
|
|
82
|
-
payload: {
|
|
83
|
-
intentEventId: intentEvent.eventId,
|
|
84
|
-
idempotencyKey: intentEvent.payload.idempotencyKey,
|
|
85
|
-
deliveryState: 'CONFIRMED',
|
|
86
|
-
...payload,
|
|
87
|
-
},
|
|
88
|
-
});
|
|
89
|
-
const appended = await deps.stateStore.appendEventEnvelope(confirmedEvent);
|
|
90
|
-
await deps.projectionUpdater.rebuildFromEvents([appended]);
|
|
91
|
-
}
|
|
92
|
-
// Outbound delivery (comments, labels) is attempted independently of run-outcome
|
|
93
|
-
// recording: a delivery failure must never rewrite an already-recorded run result
|
|
94
|
-
// (S1), and must always leave a durable, retryable trace instead of being lost
|
|
95
|
-
// (E5). This never throws — failures become a `wake.publish.failed` event.
|
|
96
|
-
async function attemptDelivery(event) {
|
|
97
|
-
if (deps.outboundSink === undefined) {
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
try {
|
|
101
|
-
await recordSentUnconfirmed(event);
|
|
102
|
-
const deliveryEvents = await deps.outboundSink.deliverIntent({ event });
|
|
103
|
-
for (const deliveryEvent of deliveryEvents) {
|
|
104
|
-
await deps.stateStore.appendEventEnvelope(deliveryEvent);
|
|
105
|
-
}
|
|
106
|
-
await deps.projectionUpdater.rebuildFromEvents(deliveryEvents);
|
|
107
|
-
if (deliveryEvents.length === 0) {
|
|
108
|
-
// No confirmation event was produced (e.g. a no-op label update) but the
|
|
109
|
-
// sink did not throw. Record that delivery was attempted successfully so
|
|
110
|
-
// the outbox scan below does not retry it indefinitely.
|
|
111
|
-
await recordConfirmed(event);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
catch (err) {
|
|
115
|
-
await recordDeliveryFailure(event, err);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
async function deliverOutboundEvent(event) {
|
|
119
|
-
await deps.stateStore.appendEventEnvelope(event);
|
|
120
|
-
await deps.projectionUpdater.rebuildFromEvents([event]);
|
|
121
|
-
await attemptDelivery(event);
|
|
122
|
-
}
|
|
123
|
-
async function suppressOutboundEvent(event, input) {
|
|
124
|
-
const suppressedEvent = await deps.stateStore.appendEventEnvelope({
|
|
125
|
-
...event,
|
|
126
|
-
payload: {
|
|
127
|
-
...event.payload,
|
|
128
|
-
deliveryState: 'CONFIRMED',
|
|
129
|
-
suppressedPublishReason: input.suppressedPublishReason,
|
|
130
|
-
},
|
|
131
|
-
});
|
|
132
|
-
await deps.projectionUpdater.rebuildFromEvents([suppressedEvent]);
|
|
133
|
-
await recordConfirmed(event, { suppressedPublishReason: input.suppressedPublishReason });
|
|
134
|
-
}
|
|
135
|
-
// Adopts the outbox pattern: an intent is only considered delivered once a
|
|
136
|
-
// matching confirmation event exists. Anything left unconfirmed by a prior tick
|
|
137
|
-
// (e.g. the process crashed mid-delivery) is retried here, bounded so a
|
|
138
|
-
// permanently failing sink dead-letters instead of retrying forever.
|
|
139
|
-
async function retryUnconfirmedDeliveries() {
|
|
140
|
-
if (deps.outboundSink === undefined) {
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
const events = await deps.stateStore.listEventEnvelopes();
|
|
144
|
-
const confirmedIntentIds = new Set();
|
|
145
|
-
const failureAttempts = new Map();
|
|
146
|
-
const uncertainIntentIds = new Set();
|
|
147
|
-
for (const event of events) {
|
|
148
|
-
const intentEventId = intentId(event);
|
|
149
|
-
if (intentEventId === undefined) {
|
|
150
|
-
continue;
|
|
151
|
-
}
|
|
152
|
-
if (outboundConfirmationEventTypes.has(event.sourceEventType)) {
|
|
153
|
-
confirmedIntentIds.add(intentEventId);
|
|
154
|
-
}
|
|
155
|
-
if (event.sourceEventType === PUBLISH_FAILED_EVENT) {
|
|
156
|
-
failureAttempts.set(intentEventId, (failureAttempts.get(intentEventId) ?? 0) + 1);
|
|
157
|
-
}
|
|
158
|
-
if (event.sourceEventType === PUBLISH_SENT_UNCONFIRMED_EVENT) {
|
|
159
|
-
uncertainIntentIds.add(intentEventId);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
for (const intent of events) {
|
|
163
|
-
if (!outboundIntentEventTypes.has(intent.sourceEventType)) {
|
|
164
|
-
continue;
|
|
165
|
-
}
|
|
166
|
-
if (confirmedIntentIds.has(intent.eventId)) {
|
|
167
|
-
continue;
|
|
168
|
-
}
|
|
169
|
-
if ((failureAttempts.get(intent.eventId) ?? 0) >= outboxMaxAttempts) {
|
|
170
|
-
continue;
|
|
171
|
-
}
|
|
172
|
-
if (uncertainIntentIds.has(intent.eventId) &&
|
|
173
|
-
deps.outboundSink.reconcileIntent !== undefined) {
|
|
174
|
-
try {
|
|
175
|
-
const reconciledEvents = await deps.outboundSink.reconcileIntent({ event: intent });
|
|
176
|
-
for (const reconciledEvent of reconciledEvents) {
|
|
177
|
-
await deps.stateStore.appendEventEnvelope(reconciledEvent);
|
|
178
|
-
}
|
|
179
|
-
await deps.projectionUpdater.rebuildFromEvents(reconciledEvents);
|
|
180
|
-
if (reconciledEvents.length > 0) {
|
|
181
|
-
continue;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
catch (err) {
|
|
185
|
-
await recordDeliveryFailure(intent, err);
|
|
186
|
-
continue;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
await attemptDelivery(intent);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
return {
|
|
193
|
-
attemptDelivery,
|
|
194
|
-
deliverOutboundEvent,
|
|
195
|
-
retryUnconfirmedDeliveries,
|
|
196
|
-
suppressOutboundEvent,
|
|
197
|
-
};
|
|
198
|
-
}
|
|
@@ -1,389 +0,0 @@
|
|
|
1
|
-
import { failedRunnerSentinel } from '../domain/stages.js';
|
|
2
|
-
import { resolveCustomCommand } from '../domain/custom-commands.js';
|
|
3
|
-
import { builtInDefaultWorkflowDefinition, chooseAction as chooseWorkflowAction, isKnownWorkflowStage, selectWorkflowForEvent, workflowForProjection, } from '../domain/workflows.js';
|
|
4
|
-
import { alwaysManualIgnoredLabels } from '../domain/manual-labels.js';
|
|
5
|
-
import { autoApprovalLabel } from './approval-intents.js';
|
|
6
|
-
function isAwaitingApproval(issue) {
|
|
7
|
-
const context = issue.context;
|
|
8
|
-
// pendingApprovalAction persists through a changes-requested review round
|
|
9
|
-
// within the same gated cycle (that fold path never touches it), so it's
|
|
10
|
-
// the faithful "is this item currently gated on human sign-off" signal —
|
|
11
|
-
// context.status alone flips between 'awaiting-approval' and
|
|
12
|
-
// 'changes-requested' within the same gated cycle and can't be used here.
|
|
13
|
-
// The lastRunSentinel fallback tolerates a projection folded before
|
|
14
|
-
// pendingApprovalAction was reliably set on every gated DONE.
|
|
15
|
-
return (typeof context.pendingApprovalAction === 'string' ||
|
|
16
|
-
context.lastRunSentinel === 'AWAITING_APPROVAL');
|
|
17
|
-
}
|
|
18
|
-
function belowFailureRetryLimit(issue, config) {
|
|
19
|
-
if (config === undefined) {
|
|
20
|
-
return true;
|
|
21
|
-
}
|
|
22
|
-
const context = issue.context;
|
|
23
|
-
const failureCount = typeof context.failureCount === 'number' && Number.isInteger(context.failureCount)
|
|
24
|
-
? context.failureCount
|
|
25
|
-
: 0;
|
|
26
|
-
return failureCount < config.retry.maxFailureRetries;
|
|
27
|
-
}
|
|
28
|
-
// Commands are matched as a token at the start of a (trimmed) line, not as a
|
|
29
|
-
// substring anywhere in the body — so "I have *not* /approved this yet" or a
|
|
30
|
-
// quoted reply containing /approved does not approve the gate.
|
|
31
|
-
const approvedCommandPattern = /^\/approved\b/i;
|
|
32
|
-
const changesCommandPattern = /^\/changes\b/i;
|
|
33
|
-
const prReviewApprovalMarker = '<!-- wake:pr-review-approved -->';
|
|
34
|
-
const prReviewChangesMarker = '<!-- wake:pr-review-changes-requested -->';
|
|
35
|
-
// The action Wake runs when a correlated PR gets new reviewer feedback while
|
|
36
|
-
// the work item is awaiting approval. Not configurable per workflow: it's a
|
|
37
|
-
// lateral response to a PR surface, not a workflow stage.
|
|
38
|
-
const reviewFeedbackAction = 'revise';
|
|
39
|
-
function matchesCommand(body, pattern) {
|
|
40
|
-
return body.split(/\r?\n/).some((line) => pattern.test(line.trim()));
|
|
41
|
-
}
|
|
42
|
-
function labelsAndAssigneesQualify(input) {
|
|
43
|
-
if (input.requiredLabels.length === 0 && input.requiredAssignees.length === 0) {
|
|
44
|
-
return false;
|
|
45
|
-
}
|
|
46
|
-
const labels = new Set(input.labels);
|
|
47
|
-
const assignees = new Set(input.assignees);
|
|
48
|
-
if (input.requiredLabels.some((label) => !labels.has(label))) {
|
|
49
|
-
return false;
|
|
50
|
-
}
|
|
51
|
-
const ignoredLabels = new Set([...input.ignoredLabels, ...alwaysManualIgnoredLabels]);
|
|
52
|
-
if ([...ignoredLabels].some((label) => labels.has(label))) {
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
if (input.requiredAssignees.length > 0 &&
|
|
56
|
-
!input.requiredAssignees.some((login) => assignees.has(login))) {
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
59
|
-
return true;
|
|
60
|
-
}
|
|
61
|
-
function latestUnhandledHumanComment(issue) {
|
|
62
|
-
const context = issue.context;
|
|
63
|
-
const handledCommentId = typeof context.lastHandledCommentId === 'string' ? context.lastHandledCommentId : undefined;
|
|
64
|
-
// Only consider human comments that appear after the last bot comment.
|
|
65
|
-
// A human /approved posted before Wake's approval-request comment must not
|
|
66
|
-
// be re-consumed as approval for a later awaiting-approval cycle.
|
|
67
|
-
const lastBotIndex = issue.comments.reduce((acc, c, i) => (c.isBotAuthored ? i : acc), -1);
|
|
68
|
-
const humanCommentsAfterBot = issue.comments
|
|
69
|
-
.slice(lastBotIndex + 1)
|
|
70
|
-
.filter((c) => !c.isBotAuthored);
|
|
71
|
-
const latestHumanComment = humanCommentsAfterBot.at(-1);
|
|
72
|
-
if (latestHumanComment === undefined || latestHumanComment.id === handledCommentId) {
|
|
73
|
-
return undefined;
|
|
74
|
-
}
|
|
75
|
-
return latestHumanComment;
|
|
76
|
-
}
|
|
77
|
-
function latestUnhandledComment(issue) {
|
|
78
|
-
const context = issue.context;
|
|
79
|
-
const handledCommentId = typeof context.lastHandledCommentId === 'string' ? context.lastHandledCommentId : undefined;
|
|
80
|
-
const lastBotIndex = issue.comments.reduce((acc, c, i) => (c.isBotAuthored ? i : acc), -1);
|
|
81
|
-
const latest = issue.comments.slice(lastBotIndex).at(-1);
|
|
82
|
-
if (latest === undefined || latest.id === handledCommentId) {
|
|
83
|
-
return undefined;
|
|
84
|
-
}
|
|
85
|
-
return latest;
|
|
86
|
-
}
|
|
87
|
-
export function createPolicyEngine() {
|
|
88
|
-
return {
|
|
89
|
-
isEligible(issue, config) {
|
|
90
|
-
if (issue.issue.state !== 'open') {
|
|
91
|
-
return false;
|
|
92
|
-
}
|
|
93
|
-
if (issue.issue.labels.some((label) => alwaysManualIgnoredLabels.includes(label))) {
|
|
94
|
-
return false;
|
|
95
|
-
}
|
|
96
|
-
// Defense-in-depth: the issues source filters PR-shaped items at poll
|
|
97
|
-
// time, so no NEW projection can ever have isPullRequest: true. But a
|
|
98
|
-
// pre-existing state/<workId>.json written by a pre-this-branch
|
|
99
|
-
// version of Wake could still hold isPullRequest: true, since the old
|
|
100
|
-
// fold created projections regardless of eligibility.
|
|
101
|
-
if (issue.issue.isPullRequest) {
|
|
102
|
-
return false;
|
|
103
|
-
}
|
|
104
|
-
// Source policy is always checked first — workflow selectors are optional secondary filter.
|
|
105
|
-
if (!labelsAndAssigneesQualify({
|
|
106
|
-
labels: issue.issue.labels,
|
|
107
|
-
assignees: issue.issue.assignees,
|
|
108
|
-
requiredLabels: config.sources.github.policy.requiredLabels,
|
|
109
|
-
ignoredLabels: config.sources.github.policy.ignoredLabels,
|
|
110
|
-
requiredAssignees: config.sources.github.policy.requiredAssignees,
|
|
111
|
-
})) {
|
|
112
|
-
return false;
|
|
113
|
-
}
|
|
114
|
-
// If workflow selectors are configured as the routing mechanism, the issue must have
|
|
115
|
-
// a workflow assigned (set by a matching selector when the issue was first minted).
|
|
116
|
-
if (config.workflowSelectors.length > 0) {
|
|
117
|
-
const context = issue.context;
|
|
118
|
-
return typeof context.workflow === 'string';
|
|
119
|
-
}
|
|
120
|
-
return true;
|
|
121
|
-
},
|
|
122
|
-
needsWakeAction(issue, workflow = builtInDefaultWorkflowDefinition, config) {
|
|
123
|
-
const context = issue.context;
|
|
124
|
-
const handledCommentId = typeof context.lastHandledCommentId === 'string' ? context.lastHandledCommentId : undefined;
|
|
125
|
-
const lastCompletedAction = typeof context.lastCompletedAction === 'string' ? context.lastCompletedAction : undefined;
|
|
126
|
-
const lastRunSentinel = typeof context.lastRunSentinel === 'string' ? context.lastRunSentinel : undefined;
|
|
127
|
-
const lastRetrySafety = typeof context.lastRetrySafety === 'string' ? context.lastRetrySafety : undefined;
|
|
128
|
-
if (issue.wake.lastRunId === undefined) {
|
|
129
|
-
return true;
|
|
130
|
-
}
|
|
131
|
-
if (issue.latestComment !== undefined &&
|
|
132
|
-
!issue.latestComment.isBotAuthored &&
|
|
133
|
-
issue.latestComment.id !== handledCommentId) {
|
|
134
|
-
if (lastRunSentinel === failedRunnerSentinel) {
|
|
135
|
-
return belowFailureRetryLimit(issue, config);
|
|
136
|
-
}
|
|
137
|
-
return true;
|
|
138
|
-
}
|
|
139
|
-
if (isAwaitingApproval(issue)) {
|
|
140
|
-
return false;
|
|
141
|
-
}
|
|
142
|
-
if (lastRunSentinel === failedRunnerSentinel) {
|
|
143
|
-
if (lastRetrySafety === 'SAFE_TO_RETRY' || lastRetrySafety === 'SAFE_TO_RESUME') {
|
|
144
|
-
return belowFailureRetryLimit(issue, config);
|
|
145
|
-
}
|
|
146
|
-
return false;
|
|
147
|
-
}
|
|
148
|
-
if (lastRunSentinel === 'REJECTED') {
|
|
149
|
-
return false;
|
|
150
|
-
}
|
|
151
|
-
if (lastRunSentinel === 'BLOCKED') {
|
|
152
|
-
return false;
|
|
153
|
-
}
|
|
154
|
-
const workflowAction = chooseWorkflowAction(issue, workflow);
|
|
155
|
-
return workflowAction !== null && lastCompletedAction !== workflowAction.action;
|
|
156
|
-
},
|
|
157
|
-
chooseAction(issue, workflow = builtInDefaultWorkflowDefinition) {
|
|
158
|
-
return chooseWorkflowAction(issue, workflow)?.action ?? null;
|
|
159
|
-
},
|
|
160
|
-
chooseRetryActionAfterHumanReply(issue, workflow = builtInDefaultWorkflowDefinition) {
|
|
161
|
-
const context = issue.context;
|
|
162
|
-
const failed = context.lastRunSentinel === failedRunnerSentinel;
|
|
163
|
-
const blocked = context.lastRunSentinel === 'BLOCKED';
|
|
164
|
-
if (failed && context.lastFailureClass === 'quota') {
|
|
165
|
-
return typeof context.lastRunAction === 'string' ? context.lastRunAction : null;
|
|
166
|
-
}
|
|
167
|
-
if (!blocked && !failed) {
|
|
168
|
-
return null;
|
|
169
|
-
}
|
|
170
|
-
if (latestUnhandledHumanComment(issue) === undefined) {
|
|
171
|
-
return null;
|
|
172
|
-
}
|
|
173
|
-
if (typeof context.blockedFromStage !== 'string') {
|
|
174
|
-
return null;
|
|
175
|
-
}
|
|
176
|
-
return (chooseWorkflowAction({
|
|
177
|
-
...issue,
|
|
178
|
-
wake: {
|
|
179
|
-
...issue.wake,
|
|
180
|
-
stage: context.blockedFromStage,
|
|
181
|
-
},
|
|
182
|
-
}, workflow)?.action ?? null);
|
|
183
|
-
},
|
|
184
|
-
resolveApprovalTransition(issue) {
|
|
185
|
-
if (!isAwaitingApproval(issue)) {
|
|
186
|
-
return null;
|
|
187
|
-
}
|
|
188
|
-
const context = issue.context;
|
|
189
|
-
const pendingAction = typeof context.pendingApprovalAction === 'string'
|
|
190
|
-
? context.pendingApprovalAction
|
|
191
|
-
: undefined;
|
|
192
|
-
// No new human comment since the last handled one; stay idle instead of
|
|
193
|
-
// falling through to the LLM while awaiting explicit approval feedback.
|
|
194
|
-
const latestHumanComment = latestUnhandledHumanComment(issue);
|
|
195
|
-
const latestComment = latestUnhandledComment(issue);
|
|
196
|
-
if (pendingAction === undefined) {
|
|
197
|
-
return null;
|
|
198
|
-
}
|
|
199
|
-
if (context.pendingApprovalAllowAutoApproval === true &&
|
|
200
|
-
issue.issue.labels.includes(autoApprovalLabel)) {
|
|
201
|
-
return {
|
|
202
|
-
approved: true,
|
|
203
|
-
pendingAction,
|
|
204
|
-
automatic: true,
|
|
205
|
-
reason: 'Issue has wake:auto and the pending action prompt declared allowAutoApproval: true.',
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
if (latestComment?.isBotAuthored === true &&
|
|
209
|
-
latestComment.resourceUri !== undefined &&
|
|
210
|
-
latestComment.body.includes(prReviewApprovalMarker)) {
|
|
211
|
-
return {
|
|
212
|
-
approved: true,
|
|
213
|
-
pendingAction,
|
|
214
|
-
targetResourceUri: latestComment.resourceUri,
|
|
215
|
-
triggeringCommentId: latestComment.id,
|
|
216
|
-
triggeringCommentBody: latestComment.body,
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
if (latestHumanComment === undefined) {
|
|
220
|
-
return null;
|
|
221
|
-
}
|
|
222
|
-
const approved = matchesCommand(latestHumanComment.body, approvedCommandPattern);
|
|
223
|
-
const changesRequested = matchesCommand(latestHumanComment.body, changesCommandPattern);
|
|
224
|
-
// Neither an explicit /approved nor /changes: treat this as
|
|
225
|
-
// conversation, not a decision. Stay idle rather than re-running the
|
|
226
|
-
// pending action off the back of an unmarked clarifying question (S2).
|
|
227
|
-
// The comment stays unhandled, so it's reconsidered on the next tick and
|
|
228
|
-
// by a human who follows up with an explicit command.
|
|
229
|
-
if (!approved && !changesRequested) {
|
|
230
|
-
return null;
|
|
231
|
-
}
|
|
232
|
-
return {
|
|
233
|
-
approved,
|
|
234
|
-
pendingAction,
|
|
235
|
-
...(changesRequested
|
|
236
|
-
? {
|
|
237
|
-
changesRequested: true,
|
|
238
|
-
triggeringCommentId: latestHumanComment.id,
|
|
239
|
-
triggeringCommentBody: latestHumanComment.body,
|
|
240
|
-
}
|
|
241
|
-
: {}),
|
|
242
|
-
};
|
|
243
|
-
},
|
|
244
|
-
// Callers must try resolveApprovalTransition first and only fall back to
|
|
245
|
-
// this when it returns null. resolveApprovalTransition doesn't check
|
|
246
|
-
// resourceUri, so a PR-surface comment that happens to carry an explicit
|
|
247
|
-
// /approved or /changes command is deliberately still routed
|
|
248
|
-
// there — this function only ever sees comments resolveApprovalTransition
|
|
249
|
-
// already passed on (plain PR feedback with no command).
|
|
250
|
-
resolvePendingReviewFeedback(issue) {
|
|
251
|
-
if (!isAwaitingApproval(issue)) {
|
|
252
|
-
return null;
|
|
253
|
-
}
|
|
254
|
-
const latestHumanComment = latestUnhandledHumanComment(issue);
|
|
255
|
-
const latestComment = latestUnhandledComment(issue);
|
|
256
|
-
if (latestComment?.isBotAuthored === true &&
|
|
257
|
-
latestComment.resourceUri !== undefined &&
|
|
258
|
-
latestComment.body.includes(prReviewChangesMarker)) {
|
|
259
|
-
return reviewFeedbackAction;
|
|
260
|
-
}
|
|
261
|
-
// resourceUri is set only on comments folded from a correlated PR/review
|
|
262
|
-
// surface (schema.ts's commentSnapshotSchema: "absent = the originating
|
|
263
|
-
// issue thread"). A comment on that surface is itself the deliberate
|
|
264
|
-
// act — unlike an issue-thread reply, it doesn't need an explicit
|
|
265
|
-
// /approved-style command to count as a decision.
|
|
266
|
-
if (latestHumanComment === undefined || latestHumanComment.resourceUri === undefined) {
|
|
267
|
-
return null;
|
|
268
|
-
}
|
|
269
|
-
return reviewFeedbackAction;
|
|
270
|
-
},
|
|
271
|
-
// A rejecting review watcher (or an already-folded /changes reply) sets
|
|
272
|
-
// context.status = 'changes-requested' with no fresh comment required —
|
|
273
|
-
// this is the gap #472 described: nothing distinguished a plan-review
|
|
274
|
-
// rejection from "never reviewed yet." Bounding (escalating to 'blocked'
|
|
275
|
-
// once config.retry.maxChangesRequestedRetries is exceeded) already
|
|
276
|
-
// happened at fold time, so this only has to check the current status.
|
|
277
|
-
resolveChangesRequestedAction(issue) {
|
|
278
|
-
if (!isAwaitingApproval(issue) || issue.context.status !== 'changes-requested') {
|
|
279
|
-
return null;
|
|
280
|
-
}
|
|
281
|
-
return typeof issue.context.pendingApprovalAction === 'string'
|
|
282
|
-
? issue.context.pendingApprovalAction
|
|
283
|
-
: null;
|
|
284
|
-
},
|
|
285
|
-
resolveCustomCommandRequest(issue, config) {
|
|
286
|
-
return resolveCustomCommand(issue, config);
|
|
287
|
-
},
|
|
288
|
-
// The single eligibility predicate: is this issue open, on a known workflow
|
|
289
|
-
// stage, and does it have a next action Wake should run? Returns the
|
|
290
|
-
// resolved action plus the workflow it belongs to, or null when there is
|
|
291
|
-
// nothing to do. This used to be duplicated as two independently-drifting
|
|
292
|
-
// copies (the pending-label marker and the runner's candidate `find`), which
|
|
293
|
-
// is exactly the class of "a rule change didn't propagate everywhere" that
|
|
294
|
-
// caused the #258 incident — keep it as the one source of truth.
|
|
295
|
-
resolveNextEligibleAction(issue, config) {
|
|
296
|
-
if (!this.isEligible(issue, config)) {
|
|
297
|
-
return null;
|
|
298
|
-
}
|
|
299
|
-
const workflow = workflowForProjection(issue, config);
|
|
300
|
-
if (workflow === null || !isKnownWorkflowStage(issue.wake.stage, workflow)) {
|
|
301
|
-
return null;
|
|
302
|
-
}
|
|
303
|
-
if (isAwaitingApproval(issue)) {
|
|
304
|
-
const customCommand = resolveCustomCommand(issue, config);
|
|
305
|
-
if (customCommand !== null) {
|
|
306
|
-
return { action: customCommand.action, workflow };
|
|
307
|
-
}
|
|
308
|
-
const approval = this.resolveApprovalTransition(issue);
|
|
309
|
-
if (approval !== null) {
|
|
310
|
-
return { action: approval.pendingAction, workflow };
|
|
311
|
-
}
|
|
312
|
-
const changesRequestedAction = this.resolveChangesRequestedAction(issue);
|
|
313
|
-
if (changesRequestedAction !== null) {
|
|
314
|
-
return { action: changesRequestedAction, workflow };
|
|
315
|
-
}
|
|
316
|
-
const reviewAction = this.resolvePendingReviewFeedback(issue);
|
|
317
|
-
if (reviewAction !== null) {
|
|
318
|
-
return { action: reviewAction, workflow };
|
|
319
|
-
}
|
|
320
|
-
return null;
|
|
321
|
-
}
|
|
322
|
-
const nextAction = resolveCustomCommand(issue, config)?.action ??
|
|
323
|
-
this.chooseAction(issue, workflow) ??
|
|
324
|
-
this.chooseRetryActionAfterHumanReply(issue, workflow);
|
|
325
|
-
if (nextAction === null || !this.needsWakeAction(issue, workflow, config)) {
|
|
326
|
-
return null;
|
|
327
|
-
}
|
|
328
|
-
return { action: nextAction, workflow };
|
|
329
|
-
},
|
|
330
|
-
qualifiesForMint(unresolved, config) {
|
|
331
|
-
const resourceUri = unresolved.sourceRefs.resourceUri;
|
|
332
|
-
if (resourceUri === undefined) {
|
|
333
|
-
return false;
|
|
334
|
-
}
|
|
335
|
-
const kind = resourceUri.split(':')[1];
|
|
336
|
-
if (kind === 'schedule') {
|
|
337
|
-
const workflow = unresolved.payload.workflow;
|
|
338
|
-
return typeof workflow === 'string' && config.workflows[workflow] !== undefined;
|
|
339
|
-
}
|
|
340
|
-
// Source policy enforcement is always checked first — workflow selectors are optional secondary routing.
|
|
341
|
-
if (kind === 'issue') {
|
|
342
|
-
// Real github source stamps payload.ticket (sourceEventType
|
|
343
|
-
// 'ticket.upsert'); the fake ticketing harness stamps payload.issue
|
|
344
|
-
// (sourceEventType 'fake.issue.upsert') — the same dual-key
|
|
345
|
-
// recognition projection-updater.ts's createProjectionFromIssueEvent
|
|
346
|
-
// already applies when folding these into a projection. Qualification
|
|
347
|
-
// must accept both or the fake never qualifies anything, which would
|
|
348
|
-
// silently defeat every fixture that exercises minting through it.
|
|
349
|
-
const ticket = (unresolved.payload.ticket ?? unresolved.payload.issue);
|
|
350
|
-
if (ticket === undefined) {
|
|
351
|
-
return false;
|
|
352
|
-
}
|
|
353
|
-
if (!labelsAndAssigneesQualify({
|
|
354
|
-
labels: Array.isArray(ticket.labels) ? ticket.labels : [],
|
|
355
|
-
assignees: Array.isArray(ticket.assignees) ? ticket.assignees : [],
|
|
356
|
-
requiredLabels: config.sources.github.policy.requiredLabels,
|
|
357
|
-
ignoredLabels: config.sources.github.policy.ignoredLabels,
|
|
358
|
-
requiredAssignees: config.sources.github.policy.requiredAssignees,
|
|
359
|
-
})) {
|
|
360
|
-
return false;
|
|
361
|
-
}
|
|
362
|
-
// Issue passed source policy; if workflow selectors are configured, also check routing.
|
|
363
|
-
if (config.workflowSelectors.length > 0) {
|
|
364
|
-
return selectWorkflowForEvent(unresolved, config) !== null;
|
|
365
|
-
}
|
|
366
|
-
return true;
|
|
367
|
-
}
|
|
368
|
-
if (kind === 'pr') {
|
|
369
|
-
if (!config.sources.github.pullRequests.enabled) {
|
|
370
|
-
return false;
|
|
371
|
-
}
|
|
372
|
-
const pr = unresolved.payload.pr;
|
|
373
|
-
const requiredAuthors = config.sources.github.pullRequests.policy.requiredAuthors;
|
|
374
|
-
// If requiredAuthors is empty, source policy allows any author.
|
|
375
|
-
if (requiredAuthors.length > 0) {
|
|
376
|
-
if (typeof pr?.author !== 'string' || !requiredAuthors.includes(pr.author)) {
|
|
377
|
-
return false;
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
// PR passed source policy; if workflow selectors are configured, also check routing.
|
|
381
|
-
if (config.workflowSelectors.length > 0) {
|
|
382
|
-
return selectWorkflowForEvent(unresolved, config) !== null;
|
|
383
|
-
}
|
|
384
|
-
return true;
|
|
385
|
-
}
|
|
386
|
-
return false;
|
|
387
|
-
},
|
|
388
|
-
};
|
|
389
|
-
}
|