cloving 1.2.0 → 1.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/README.md +525 -185
- package/dist/src/agent-harness-shell.d.ts +12 -0
- package/dist/src/agent-harness-shell.js +90 -0
- package/dist/src/agent-harness-versions.d.ts +8 -0
- package/dist/src/agent-harness-versions.js +49 -0
- package/dist/src/agent-harnesses.d.ts +4 -0
- package/dist/src/agent-harnesses.js +13 -0
- package/dist/src/authority/commands.d.ts +1 -0
- package/dist/src/authority/commands.js +24 -4
- package/dist/src/authority/gate-reduction.d.ts +1 -0
- package/dist/src/authority/gate-reduction.js +18 -3
- package/dist/src/authority/gates.d.ts +2 -1
- package/dist/src/authority/gates.js +5 -1
- package/dist/src/authority/operations.js +1 -1
- package/dist/src/authority/reduction.d.ts +1 -1
- package/dist/src/authority/reduction.js +6 -1
- package/dist/src/authority/status-input.d.ts +1 -1
- package/dist/src/authority/status.d.ts +1 -0
- package/dist/src/authority/status.js +27 -3
- package/dist/src/authority/transitions.d.ts +5 -5
- package/dist/src/authority/transitions.js +6 -0
- package/dist/src/broker/actor/authority-delivery.js +1 -0
- package/dist/src/broker/actor/authority-queries.d.ts +7 -1
- package/dist/src/broker/actor/authority-queries.js +17 -2
- package/dist/src/broker/actor/authority-receipts.js +11 -1
- package/dist/src/broker/actor/authority-session.js +2 -2
- package/dist/src/broker/actor/authority-settings.js +4 -0
- package/dist/src/broker/actor/delivery-intents.d.ts +2 -1
- package/dist/src/broker/actor/delivery-intents.js +4 -4
- package/dist/src/broker/actor/effect-delivery.js +4 -1
- package/dist/src/broker/actor/effect-queries.d.ts +1 -0
- package/dist/src/broker/actor/effect-queries.js +7 -0
- package/dist/src/broker/actor/pin-check.js +1 -1
- package/dist/src/broker/actor/stop-plan.js +1 -1
- package/dist/src/broker/actor/turn-state.js +1 -1
- package/dist/src/broker/authority-admission.js +22 -9
- package/dist/src/broker/authority-restore.js +1 -0
- package/dist/src/broker/decision-restore.js +4 -4
- package/dist/src/broker/socket-address.d.ts +3 -1
- package/dist/src/broker/socket-address.js +2 -2
- package/dist/src/cli/arguments.d.ts +11 -13
- package/dist/src/cli/arguments.js +37 -107
- package/dist/src/cli/command-effects.d.ts +7 -0
- package/dist/src/cli/command-effects.js +39 -0
- package/dist/src/cli/commands.js +11 -4
- package/dist/src/cli/config-arguments.d.ts +11 -0
- package/dist/src/cli/config-arguments.js +59 -0
- package/dist/src/cli/config-command.d.ts +2 -0
- package/dist/src/cli/config-command.js +105 -0
- package/dist/src/cli/config-file.d.ts +3 -0
- package/dist/src/cli/config-file.js +50 -0
- package/dist/src/cli/config-lock.d.ts +7 -0
- package/dist/src/cli/config-lock.js +61 -0
- package/dist/src/cli/config-notice.d.ts +5 -0
- package/dist/src/cli/config-notice.js +46 -0
- package/dist/src/cli/doctor-github.d.ts +9 -0
- package/dist/src/cli/doctor-github.js +138 -0
- package/dist/src/cli/doctor-harness.d.ts +13 -0
- package/dist/src/cli/doctor-harness.js +242 -0
- package/dist/src/cli/doctor-local.d.ts +18 -0
- package/dist/src/cli/doctor-local.js +77 -0
- package/dist/src/cli/doctor-runtime.d.ts +15 -0
- package/dist/src/cli/doctor-runtime.js +176 -0
- package/dist/src/cli/doctor-service.d.ts +1 -0
- package/dist/src/cli/doctor-service.js +11 -0
- package/dist/src/cli/doctor-workflows.d.ts +3 -0
- package/dist/src/cli/doctor-workflows.js +45 -0
- package/dist/src/cli/doctor.d.ts +15 -0
- package/dist/src/cli/doctor.js +190 -0
- package/dist/src/cli/github-ci-progress.d.ts +8 -0
- package/dist/src/cli/github-ci-progress.js +83 -0
- package/dist/src/cli/github-retry.d.ts +6 -0
- package/dist/src/cli/github-retry.js +47 -0
- package/dist/src/cli/harness-probes.d.ts +22 -0
- package/dist/src/cli/harness-probes.js +183 -0
- package/dist/src/cli/main.d.ts +7 -1
- package/dist/src/cli/main.js +39 -61
- package/dist/src/cli/phone-arguments.d.ts +14 -0
- package/dist/src/cli/phone-arguments.js +37 -0
- package/dist/src/cli/phone-client.d.ts +2 -0
- package/dist/src/cli/phone-client.js +32 -0
- package/dist/src/cli/phone-command.d.ts +13 -0
- package/dist/src/cli/phone-command.js +101 -0
- package/dist/src/cli/probe-command.d.ts +36 -0
- package/dist/src/cli/probe-command.js +59 -0
- package/dist/src/cli/project-settings.d.ts +4 -0
- package/dist/src/cli/project-settings.js +33 -0
- package/dist/src/cli/render.d.ts +2 -1
- package/dist/src/cli/render.js +44 -28
- package/dist/src/cli/report-github.d.ts +18 -0
- package/dist/src/cli/report-github.js +200 -0
- package/dist/src/cli/report.d.ts +17 -0
- package/dist/src/cli/report.js +192 -0
- package/dist/src/cli/repository-arguments.d.ts +5 -0
- package/dist/src/cli/repository-arguments.js +34 -0
- package/dist/src/cli/runtime-arguments.d.ts +4 -0
- package/dist/src/cli/runtime-arguments.js +15 -0
- package/dist/src/cli/runtime-directory.d.ts +6 -2
- package/dist/src/cli/runtime-directory.js +72 -14
- package/dist/src/cli/toolchain.d.ts +2 -0
- package/dist/src/cli/toolchain.js +22 -2
- package/dist/src/cli/usage-render.d.ts +5 -0
- package/dist/src/cli/usage-render.js +40 -1
- package/dist/src/cli/usage.d.ts +3 -3
- package/dist/src/cli/usage.js +70 -44
- package/dist/src/cli/watch-actions.d.ts +2 -0
- package/dist/src/cli/watch-actions.js +4 -4
- package/dist/src/cli/watch-board-view.d.ts +1 -1
- package/dist/src/cli/watch-board-view.js +8 -2
- package/dist/src/cli/watch-board.js +23 -10
- package/dist/src/cli/watch-card-forms.js +2 -2
- package/dist/src/cli/watch-client.d.ts +1 -1
- package/dist/src/cli/watch-client.js +7 -2
- package/dist/src/cli/watch-header-view.d.ts +27 -0
- package/dist/src/cli/watch-header-view.js +116 -0
- package/dist/src/cli/watch-model.js +17 -4
- package/dist/src/cli/watch-page.js +48 -12
- package/dist/src/cli/watch-phone-client.d.ts +1 -0
- package/dist/src/cli/watch-phone-client.js +84 -0
- package/dist/src/cli/watch-phone-view.d.ts +56 -0
- package/dist/src/cli/watch-phone-view.js +113 -0
- package/dist/src/cli/watch-phone.d.ts +5 -0
- package/dist/src/cli/watch-phone.js +53 -0
- package/dist/src/cli/watch-pull-request.d.ts +3 -1
- package/dist/src/cli/watch-pull-request.js +4 -0
- package/dist/src/cli/watch-render.d.ts +9 -1
- package/dist/src/cli/watch-server.js +23 -5
- package/dist/src/cli/watch-turn.d.ts +4 -1
- package/dist/src/cli/watch-turn.js +37 -1
- package/dist/src/cli/watch-usage.js +5 -1
- package/dist/src/cli/watch-view.d.ts +6 -20
- package/dist/src/cli/watch-view.js +14 -106
- package/dist/src/cli.js +106 -23
- package/dist/src/command-settings.d.ts +16 -0
- package/dist/src/command-settings.js +42 -0
- package/dist/src/configuration-change.d.ts +11 -0
- package/dist/src/configuration-change.js +62 -0
- package/dist/src/configuration-display.d.ts +21 -0
- package/dist/src/configuration-display.js +69 -0
- package/dist/src/configuration-schema.d.ts +49 -0
- package/dist/src/configuration-schema.js +159 -0
- package/dist/src/daemon/claude-turn.d.ts +19 -5
- package/dist/src/daemon/claude-turn.js +116 -53
- package/dist/src/daemon/claude-worker.d.ts +3 -3
- package/dist/src/daemon/claude-worker.js +65 -76
- package/dist/src/daemon/command-journal.d.ts +5 -0
- package/dist/src/daemon/command-journal.js +50 -0
- package/dist/src/daemon/command-process.d.ts +28 -0
- package/dist/src/daemon/command-process.js +164 -0
- package/dist/src/daemon/command-worker.d.ts +19 -0
- package/dist/src/daemon/command-worker.js +182 -0
- package/dist/src/daemon/cursor-stream.d.ts +4 -0
- package/dist/src/daemon/cursor-stream.js +154 -0
- package/dist/src/daemon/daemon-adapters.d.ts +58 -0
- package/dist/src/daemon/daemon-adapters.js +102 -0
- package/dist/src/daemon/daemon-loops.d.ts +14 -0
- package/dist/src/daemon/daemon-loops.js +39 -0
- package/dist/src/daemon/daemon.d.ts +2 -33
- package/dist/src/daemon/daemon.js +126 -132
- package/dist/src/daemon/declared-input.d.ts +3 -0
- package/dist/src/daemon/declared-input.js +9 -0
- package/dist/src/daemon/delivery-router.js +1 -1
- package/dist/src/daemon/gemini-stream.d.ts +4 -0
- package/dist/src/daemon/gemini-stream.js +129 -0
- package/dist/src/daemon/github-ci-rerun.d.ts +26 -0
- package/dist/src/daemon/github-ci-rerun.js +92 -0
- package/dist/src/daemon/github-ci.js +89 -8
- package/dist/src/daemon/github-merge-call.d.ts +2 -0
- package/dist/src/daemon/github-merge.js +7 -3
- package/dist/src/daemon/github-methods.js +10 -0
- package/dist/src/daemon/github-operation.d.ts +1 -0
- package/dist/src/daemon/github-retry.js +8 -44
- package/dist/src/daemon/issue-queue.d.ts +1 -0
- package/dist/src/daemon/issue-queue.js +3 -26
- package/dist/src/daemon/notify.js +2 -1
- package/dist/src/daemon/opencode-stream.d.ts +5 -0
- package/dist/src/daemon/opencode-stream.js +87 -0
- package/dist/src/daemon/queue-status.d.ts +4 -0
- package/dist/src/daemon/queue-status.js +38 -0
- package/dist/src/daemon/retry-worktree.d.ts +18 -0
- package/dist/src/daemon/retry-worktree.js +139 -0
- package/dist/src/daemon/retrying-turn.d.ts +2 -0
- package/dist/src/daemon/retrying-turn.js +108 -30
- package/dist/src/daemon/schedule-journal.d.ts +19 -0
- package/dist/src/daemon/schedule-journal.js +57 -0
- package/dist/src/daemon/text-output.d.ts +18 -0
- package/dist/src/daemon/text-output.js +44 -0
- package/dist/src/daemon/ticket-registration.d.ts +5 -7
- package/dist/src/daemon/ticket-registration.js +85 -40
- package/dist/src/daemon/turn-command.d.ts +10 -0
- package/dist/src/daemon/turn-command.js +33 -0
- package/dist/src/daemon/turn-report.d.ts +18 -0
- package/dist/src/daemon/turn-report.js +79 -0
- package/dist/src/daemon/work-tree.d.ts +2 -1
- package/dist/src/daemon/work-tree.js +15 -12
- package/dist/src/daemon/workflow-generations.d.ts +32 -0
- package/dist/src/daemon/workflow-generations.js +57 -0
- package/dist/src/daemon/workflow-replay.d.ts +16 -0
- package/dist/src/daemon/workflow-replay.js +58 -0
- package/dist/src/daemon/workflow-schedules.d.ts +27 -0
- package/dist/src/daemon/workflow-schedules.js +185 -0
- package/dist/src/decision-wait.d.ts +1 -0
- package/dist/src/decision-wait.js +3 -0
- package/dist/src/delivery-backoff.d.ts +1 -0
- package/dist/src/delivery-backoff.js +3 -0
- package/dist/src/doctor-report.d.ts +24 -0
- package/dist/src/doctor-report.js +70 -0
- package/dist/src/execution-pin.d.ts +5 -0
- package/dist/src/execution-pin.js +67 -4
- package/dist/src/grok-result.d.ts +12 -0
- package/dist/src/grok-result.js +61 -0
- package/dist/src/harness-defaults.d.ts +35 -0
- package/dist/src/harness-defaults.js +121 -0
- package/dist/src/host/decision-resume.d.ts +35 -0
- package/dist/src/host/decision-resume.js +86 -0
- package/dist/src/host/gate-bridge.d.ts +48 -0
- package/dist/src/host/gate-bridge.js +124 -0
- package/dist/src/host/run-wait.d.ts +26 -0
- package/dist/src/host/run-wait.js +37 -0
- package/dist/src/host/start-delivery.d.ts +1 -1
- package/dist/src/host/start-delivery.js +10 -3
- package/dist/src/host/step-bridge-host.d.ts +6 -20
- package/dist/src/host/step-bridge-host.js +44 -58
- package/dist/src/merge-request.d.ts +19 -0
- package/dist/src/merge-request.js +32 -0
- package/dist/src/phone/canonical-json.d.ts +1 -0
- package/dist/src/phone/canonical-json.js +16 -0
- package/dist/src/phone/phone-link.d.ts +7 -0
- package/dist/src/phone/phone-link.js +21 -0
- package/dist/src/phone/qr-data.d.ts +8 -0
- package/dist/src/phone/qr-data.js +133 -0
- package/dist/src/phone/qr-matrix.d.ts +6 -0
- package/dist/src/phone/qr-matrix.js +175 -0
- package/dist/src/phone/qr-penalty.d.ts +3 -0
- package/dist/src/phone/qr-penalty.js +67 -0
- package/dist/src/phone/qr-picture.d.ts +5 -0
- package/dist/src/phone/qr-picture.js +24 -0
- package/dist/src/private-config.schema.json +263 -0
- package/dist/src/project-config.schema.json +65 -0
- package/dist/src/project-settings.d.ts +19 -0
- package/dist/src/project-settings.js +131 -0
- package/dist/src/relay/answer-check.d.ts +24 -0
- package/dist/src/relay/answer-check.js +145 -0
- package/dist/src/relay/answer-inbox.d.ts +15 -0
- package/dist/src/relay/answer-inbox.js +173 -0
- package/dist/src/relay/daemon-keys.d.ts +16 -0
- package/dist/src/relay/daemon-keys.js +75 -0
- package/dist/src/relay/decision-check.d.ts +3 -0
- package/dist/src/relay/decision-check.js +77 -0
- package/dist/src/relay/decision-close.d.ts +6 -0
- package/dist/src/relay/decision-close.js +72 -0
- package/dist/src/relay/decision-envelopes.d.ts +29 -0
- package/dist/src/relay/decision-envelopes.js +93 -0
- package/dist/src/relay/decision-watch.d.ts +14 -0
- package/dist/src/relay/decision-watch.js +68 -0
- package/dist/src/relay/envelope-post.d.ts +8 -0
- package/dist/src/relay/envelope-post.js +71 -0
- package/dist/src/relay/envelope.d.ts +28 -0
- package/dist/src/relay/envelope.js +53 -0
- package/dist/src/relay/hpke.d.ts +25 -0
- package/dist/src/relay/hpke.js +108 -0
- package/dist/src/relay/pairing-checks.d.ts +42 -0
- package/dist/src/relay/pairing-checks.js +172 -0
- package/dist/src/relay/pairing-follow.d.ts +8 -0
- package/dist/src/relay/pairing-follow.js +95 -0
- package/dist/src/relay/pairing-session.d.ts +29 -0
- package/dist/src/relay/pairing-session.js +87 -0
- package/dist/src/relay/phone-delivery.d.ts +51 -0
- package/dist/src/relay/phone-delivery.js +139 -0
- package/dist/src/relay/phone-devices.d.ts +36 -0
- package/dist/src/relay/phone-devices.js +46 -0
- package/dist/src/relay/phone-inbox.d.ts +18 -0
- package/dist/src/relay/phone-inbox.js +17 -0
- package/dist/src/relay/phone-operations.d.ts +18 -0
- package/dist/src/relay/phone-operations.js +121 -0
- package/dist/src/relay/phone-outbox.d.ts +21 -0
- package/dist/src/relay/phone-outbox.js +25 -0
- package/dist/src/relay/phone-socket.d.ts +6 -0
- package/dist/src/relay/phone-socket.js +63 -0
- package/dist/src/relay/relay-control.d.ts +7 -0
- package/dist/src/relay/relay-control.js +24 -0
- package/dist/src/relay/relay-files.d.ts +2 -0
- package/dist/src/relay/relay-files.js +23 -0
- package/dist/src/relay/relay-heartbeat.d.ts +17 -0
- package/dist/src/relay/relay-heartbeat.js +81 -0
- package/dist/src/relay/relay-http.d.ts +14 -0
- package/dist/src/relay/relay-http.js +63 -0
- package/dist/src/relay/relay-registration.d.ts +15 -0
- package/dist/src/relay/relay-registration.js +63 -0
- package/dist/src/relay/relay-service.d.ts +25 -0
- package/dist/src/relay/relay-service.js +216 -0
- package/dist/src/relay/relay-store.d.ts +48 -0
- package/dist/src/relay/relay-store.js +131 -0
- package/dist/src/relay/sealed-post.d.ts +25 -0
- package/dist/src/relay/sealed-post.js +52 -0
- package/dist/src/relay.d.ts +1 -0
- package/dist/src/relay.js +8 -0
- package/dist/src/report-statistics.d.ts +50 -0
- package/dist/src/report-statistics.js +70 -0
- package/dist/src/report.d.ts +171 -0
- package/dist/src/report.js +119 -0
- package/dist/src/repository-identity.d.ts +4 -0
- package/dist/src/repository-identity.js +4 -0
- package/dist/src/review-subject.d.ts +41 -0
- package/dist/src/review-subject.js +91 -0
- package/dist/src/run-wait.d.ts +23 -0
- package/dist/src/run-wait.js +20 -0
- package/dist/src/service/active-tickets.d.ts +4 -0
- package/dist/src/service/active-tickets.js +49 -0
- package/dist/src/service/command-effects.d.ts +4 -0
- package/dist/src/service/command-effects.js +16 -0
- package/dist/src/service/decision-handler.d.ts +4 -0
- package/dist/src/service/decision-handler.js +39 -4
- package/dist/src/service/gateway.js +18 -3
- package/dist/src/service/registry.d.ts +16 -3
- package/dist/src/service/registry.js +34 -3
- package/dist/src/service/replies.d.ts +9 -1
- package/dist/src/service/replies.js +12 -0
- package/dist/src/service/run-handlers.js +14 -55
- package/dist/src/service/run-metadata.d.ts +8 -0
- package/dist/src/service/run-metadata.js +53 -0
- package/dist/src/service/run-waits.d.ts +3 -0
- package/dist/src/service/run-waits.js +41 -0
- package/dist/src/service/service.d.ts +18 -2
- package/dist/src/service/service.js +23 -7
- package/dist/src/service/submission-handler.d.ts +0 -1
- package/dist/src/service/submission-handler.js +6 -34
- package/dist/src/service/worker-port.d.ts +1 -0
- package/dist/src/service/worker-totals.js +8 -23
- package/dist/src/step-bridge.d.ts +23 -0
- package/dist/src/steps/decision-gate.d.ts +2 -1
- package/dist/src/steps/decision-gate.js +7 -0
- package/dist/src/steps/merge-by-person.d.ts +2 -0
- package/dist/src/steps/merge-by-person.js +18 -0
- package/dist/src/steps/merge-when-green.d.ts +2 -0
- package/dist/src/steps/merge-when-green.js +62 -0
- package/dist/src/steps/review-by-agent.d.ts +5 -0
- package/dist/src/steps/review-by-agent.js +124 -0
- package/dist/src/steps/review-by-person.d.ts +4 -0
- package/dist/src/steps/review-by-person.js +16 -0
- package/dist/src/steps/review-subject.d.ts +2 -0
- package/dist/src/steps/review-subject.js +11 -0
- package/dist/src/steps/run-command.d.ts +2 -0
- package/dist/src/steps/run-command.js +15 -0
- package/dist/src/steps/sleep.d.ts +3 -0
- package/dist/src/steps/sleep.js +19 -0
- package/dist/src/steps/wait-for-decision.d.ts +2 -0
- package/dist/src/steps/wait-for-decision.js +71 -0
- package/dist/src/steps/wait-for-run.d.ts +5 -0
- package/dist/src/steps/wait-for-run.js +9 -0
- package/dist/src/storage/decision-snapshots.d.ts +1 -0
- package/dist/src/storage/decision-snapshots.js +7 -1
- package/dist/src/submission.d.ts +4 -0
- package/dist/src/submission.js +6 -2
- package/dist/src/testing.d.ts +29 -0
- package/dist/src/testing.js +264 -0
- package/dist/src/ticket-status-stream.d.ts +9 -0
- package/dist/src/ticket-status-stream.js +94 -0
- package/dist/src/token-prices.d.ts +12 -4
- package/dist/src/token-prices.js +15 -2
- package/dist/src/turn-profile.d.ts +1 -0
- package/dist/src/turn-profile.js +8 -1
- package/dist/src/worker-usage.d.ts +16 -0
- package/dist/src/worker-usage.js +57 -0
- package/dist/src/workflow-admission.d.ts +5 -0
- package/dist/src/workflow-candidate.d.ts +7 -2
- package/dist/src/workflow-candidate.js +47 -5
- package/dist/src/workflow-declaration.d.ts +21 -3
- package/dist/src/workflow-declaration.js +77 -9
- package/dist/src/workflow-discovery.d.ts +2 -1
- package/dist/src/workflow-discovery.js +4 -1
- package/dist/src/workflow-refusals.js +3 -0
- package/dist/src/workflow-schedule.d.ts +22 -0
- package/dist/src/workflow-schedule.js +53 -0
- package/dist/src/workflows.d.ts +11 -1
- package/dist/src/workflows.js +8 -0
- package/dist/tools/admit-workflow.d.ts +1 -0
- package/dist/tools/admit-workflow.js +18 -5
- package/dist/tools/doctor-adoption.d.ts +1 -0
- package/dist/tools/doctor-adoption.js +11 -0
- package/dist/tools/project-configuration.d.ts +4 -0
- package/dist/tools/project-configuration.js +47 -0
- package/dist/tools/self-host-processes.d.ts +1 -0
- package/dist/tools/self-host-processes.js +33 -22
- package/dist/tools/self-host-project.d.ts +4 -0
- package/dist/tools/self-host-project.js +61 -14
- package/dist/tools/self-host-runtime.d.ts +16 -0
- package/dist/tools/self-host-runtime.js +60 -0
- package/dist/tools/self-host-workflows.d.ts +1 -0
- package/dist/tools/self-host-workflows.js +36 -1
- package/dist/tools/self-host.js +86 -61
- package/dist/tools/workflow-candidate-counts.d.ts +6 -2
- package/dist/tools/workflow-candidate-counts.js +31 -16
- package/dist/tools/workflow-candidate-fields.d.ts +5 -0
- package/dist/tools/workflow-candidate-fields.js +24 -0
- package/dist/tools/workflow-candidate-helper-counts.d.ts +10 -0
- package/dist/tools/workflow-candidate-helper-counts.js +129 -0
- package/dist/tools/workflow-candidate-program.d.ts +2 -0
- package/dist/tools/workflow-candidate-program.js +36 -8
- package/dist/tools/workflow-candidate-source.js +77 -15
- package/dist/tools/workflow-candidate-syntax.d.ts +8 -2
- package/dist/tools/workflow-candidate-syntax.js +70 -26
- package/dist/tools/workflow-command.d.ts +1 -0
- package/dist/tools/workflow-command.js +143 -0
- package/dist/tools/workflow-folder-capture.d.ts +1 -0
- package/dist/tools/workflow-folder-capture.js +47 -2
- package/dist/tools/workflow-folders.d.ts +17 -1
- package/dist/tools/workflow-folders.js +59 -6
- package/dist/tools/workflow-test-hook.d.ts +7 -0
- package/dist/tools/workflow-test-hook.js +16 -0
- package/dist/tools/workflow-test-loader.d.ts +1 -0
- package/dist/tools/workflow-test-loader.js +10 -0
- package/dist/workflows/develop-ticket.js +1 -1
- package/dist/workflows/ticket-prompts.js +5 -1
- package/package.json +46 -4
- package/templates/develop/README.md +78 -0
- package/templates/develop/develop/accept.ts +11 -0
- package/templates/develop/develop/flow-tests.ts +357 -0
- package/templates/develop/develop/local.ts +40 -0
- package/templates/develop/develop/option-tests.ts +174 -0
- package/templates/develop/develop/partial-choice.ts +29 -0
- package/templates/develop/develop/partial.ts +28 -0
- package/templates/develop/develop/pull.ts +152 -0
- package/templates/develop/develop/queue-partial.ts +39 -0
- package/templates/develop/develop/refusal-tests.ts +174 -0
- package/templates/develop/develop/report.ts +156 -0
- package/templates/develop/develop/round.ts +40 -0
- package/templates/develop/develop/scenarios.ts +87 -0
- package/templates/develop/develop/turn.ts +67 -0
- package/templates/develop/develop.declaration.json +24 -0
- package/templates/develop/develop.test.ts +287 -0
- package/templates/develop/develop.ts +30 -0
- package/templates/develop/template.json +153 -0
- package/dist/src/chats/analysis-batches.d.ts +0 -42
- package/dist/src/chats/analysis-batches.js +0 -97
- package/dist/src/chats/analysis-checkpoint.d.ts +0 -29
- package/dist/src/chats/analysis-checkpoint.js +0 -31
- package/dist/src/chats/analysis-contract.d.ts +0 -80
- package/dist/src/chats/analysis-contract.js +0 -16
- package/dist/src/chats/analysis-data.d.ts +0 -3
- package/dist/src/chats/analysis-data.js +0 -85
- package/dist/src/chats/analysis-input.d.ts +0 -18
- package/dist/src/chats/analysis-input.js +0 -97
- package/dist/src/chats/analysis-links.d.ts +0 -2
- package/dist/src/chats/analysis-links.js +0 -25
- package/dist/src/chats/analysis-merge.d.ts +0 -16
- package/dist/src/chats/analysis-merge.js +0 -134
- package/dist/src/chats/analysis-prompt.d.ts +0 -18
- package/dist/src/chats/analysis-prompt.js +0 -42
- package/dist/src/chats/analysis-proposal.d.ts +0 -4
- package/dist/src/chats/analysis-proposal.js +0 -41
- package/dist/src/chats/analysis-provenance.d.ts +0 -4
- package/dist/src/chats/analysis-provenance.js +0 -99
- package/dist/src/chats/analysis-shape.d.ts +0 -4
- package/dist/src/chats/analysis-shape.js +0 -235
- package/dist/src/chats/analysis.d.ts +0 -3
- package/dist/src/chats/analysis.js +0 -42
- package/dist/src/chats/corpus-input.d.ts +0 -5
- package/dist/src/chats/corpus-input.js +0 -288
- package/dist/src/chats/destination.d.ts +0 -4
- package/dist/src/chats/destination.js +0 -96
- package/dist/src/chats/import.d.ts +0 -15
- package/dist/src/chats/import.js +0 -243
- package/dist/src/chats/input-file.d.ts +0 -3
- package/dist/src/chats/input-file.js +0 -32
- package/dist/src/chats/normalize.d.ts +0 -29
- package/dist/src/chats/normalize.js +0 -155
- package/dist/src/chats/previous-import.d.ts +0 -5
- package/dist/src/chats/previous-import.js +0 -34
- package/dist/src/chats/reader.d.ts +0 -21
- package/dist/src/chats/reader.js +0 -118
- package/dist/src/chats/redact-import.d.ts +0 -14
- package/dist/src/chats/redact-import.js +0 -141
- package/dist/src/chats/redaction.d.ts +0 -41
- package/dist/src/chats/redaction.js +0 -161
- package/dist/src/chats/reference-mapping.d.ts +0 -16
- package/dist/src/chats/reference-mapping.js +0 -153
- package/dist/src/chats/revision-input.d.ts +0 -3
- package/dist/src/chats/revision-input.js +0 -180
- package/dist/src/chats/revision.d.ts +0 -48
- package/dist/src/chats/revision.js +0 -94
- package/dist/src/chats/selection.d.ts +0 -25
- package/dist/src/chats/selection.js +0 -109
- package/dist/src/chats/source.d.ts +0 -23
- package/dist/src/chats/source.js +0 -135
- package/dist/src/chats/structure.d.ts +0 -57
- package/dist/src/chats/structure.js +0 -216
- package/dist/src/chats/workflow-generation-projection.d.ts +0 -8
- package/dist/src/chats/workflow-generation-projection.js +0 -75
- package/dist/src/chats/workflow-generation-source.d.ts +0 -25
- package/dist/src/chats/workflow-generation-source.js +0 -124
- package/dist/src/chats/workflow-generation-text.d.ts +0 -23
- package/dist/src/chats/workflow-generation-text.js +0 -74
- package/dist/src/chats/workflow-generation.d.ts +0 -69
- package/dist/src/chats/workflow-generation.js +0 -142
- package/dist/src/daemon/analysis-launch.d.ts +0 -5
- package/dist/src/daemon/analysis-launch.js +0 -81
- package/dist/src/daemon/analysis-token.d.ts +0 -6
- package/dist/src/daemon/analysis-token.js +0 -88
- package/dist/src/daemon/analysis-worker.d.ts +0 -20
- package/dist/src/daemon/analysis-worker.js +0 -271
- package/dist/src/daemon/chats-batch-binding.d.ts +0 -23
- package/dist/src/daemon/chats-batch-binding.js +0 -99
- package/dist/src/daemon/chats-capture.d.ts +0 -18
- package/dist/src/daemon/chats-capture.js +0 -194
- package/dist/src/daemon/chats-checkpoints.d.ts +0 -41
- package/dist/src/daemon/chats-checkpoints.js +0 -186
- package/dist/src/daemon/chats-files.d.ts +0 -42
- package/dist/src/daemon/chats-files.js +0 -252
- package/dist/src/daemon/chats-follow-up.d.ts +0 -38
- package/dist/src/daemon/chats-follow-up.js +0 -180
- package/dist/src/daemon/chats-question.d.ts +0 -15
- package/dist/src/daemon/chats-question.js +0 -93
- package/dist/src/daemon/chats-worker.d.ts +0 -13
- package/dist/src/daemon/chats-worker.js +0 -201
- package/dist/workflows/analyze-chats.d.ts +0 -15
- package/dist/workflows/analyze-chats.declaration.json +0 -22
- package/dist/workflows/analyze-chats.js +0 -250
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { admitCompiled } from "../cli/validate.js";
|
|
3
|
+
import { isCommandWaits, workflowQueueRefusals, } from "../workflow-declaration.js";
|
|
3
4
|
import { ticketCommandText, ticketText } from "./ticket-source.js";
|
|
5
|
+
import { declaredInput } from "./declared-input.js";
|
|
4
6
|
import { bundledWorkflowIds } from "../workflow-discovery.js";
|
|
5
7
|
import { declaredManifest } from "../execution-pin.js";
|
|
6
8
|
import { record } from "../protocol.js";
|
|
9
|
+
import { hasTicketField } from "../submission.js";
|
|
7
10
|
import { issueIdentity } from "../issue-identity.js";
|
|
8
11
|
import { ticketDependencyWaits, TicketDependencyReadError, } from "./ticket-dependency-waits.js";
|
|
9
12
|
export const ticketWorkflow = bundledWorkflowIds.ticket;
|
|
@@ -155,54 +158,48 @@ export function ticketRegistrationTable(source, declarations = []) {
|
|
|
155
158
|
submission: { maximumBytes: 65_536, fields: { prompt: "string" } },
|
|
156
159
|
resolver: promptResolver(source.repository),
|
|
157
160
|
},
|
|
158
|
-
...declarations.map((declaration) => ({
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
capabilities: declaration.capabilities,
|
|
163
|
-
submission: declaration.input,
|
|
164
|
-
...(declaration.stages === undefined
|
|
165
|
-
? {}
|
|
166
|
-
: { stages: declaration.stages }),
|
|
167
|
-
...(declaration.handoffs === undefined
|
|
168
|
-
? {}
|
|
169
|
-
: { handoffs: declaration.handoffs }),
|
|
170
|
-
resolver: declaredResolver(source.repository),
|
|
161
|
+
...declarations.map(({ input, ...declaration }) => ({
|
|
162
|
+
...declaration,
|
|
163
|
+
submission: input,
|
|
164
|
+
resolver: declaredResolver(source, input),
|
|
171
165
|
})),
|
|
172
166
|
];
|
|
173
167
|
}
|
|
174
|
-
function declaredResolver(
|
|
168
|
+
function declaredResolver(source, contract) {
|
|
169
|
+
const tickets = hasTicketField(contract) ? issueResolver(source) : undefined;
|
|
175
170
|
return {
|
|
176
171
|
id: "declared-input",
|
|
177
172
|
version: "1",
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
173
|
+
...(tickets?.skippedTickets === undefined
|
|
174
|
+
? {}
|
|
175
|
+
: { skippedTickets: tickets.skippedTickets }),
|
|
176
|
+
resolve: async (request) => {
|
|
177
|
+
const resolution = tickets !== undefined && Object.hasOwn(request.submission, "ticket")
|
|
178
|
+
? await tickets.resolve(request)
|
|
179
|
+
: undefined;
|
|
180
|
+
if (resolution?.kind === "rejected")
|
|
181
|
+
return resolution;
|
|
182
|
+
const ticket = resolution === undefined ? undefined : (record(resolution.input) ?? {});
|
|
183
|
+
const input = ticket === undefined
|
|
184
|
+
? request.submission
|
|
185
|
+
: {
|
|
186
|
+
...request.submission,
|
|
187
|
+
ticket: { id: ticket["ticketId"], text: ticket["ticket"] },
|
|
188
|
+
};
|
|
189
|
+
return {
|
|
190
|
+
kind: "resolved",
|
|
191
|
+
input: declaredInput(source.repository, {
|
|
192
|
+
commandId: request.commandId,
|
|
193
|
+
submission: input,
|
|
194
|
+
}),
|
|
195
|
+
};
|
|
196
|
+
},
|
|
186
197
|
};
|
|
187
198
|
}
|
|
188
199
|
export async function ticketRegistrations(manifests, options) {
|
|
189
|
-
const
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
return {
|
|
193
|
-
kind: "rejected",
|
|
194
|
-
detail: `duplicate-workflow-id: ${row.workflowId}`,
|
|
195
|
-
};
|
|
196
|
-
ids.add(row.workflowId);
|
|
197
|
-
}
|
|
198
|
-
for (const row of options.table) {
|
|
199
|
-
const unknown = row.handoffs?.find((target) => !ids.has(target));
|
|
200
|
-
if (unknown !== undefined)
|
|
201
|
-
return {
|
|
202
|
-
kind: "rejected",
|
|
203
|
-
detail: `unknown-handoff-target: ${row.workflowId} -> ${unknown}`,
|
|
204
|
-
};
|
|
205
|
-
}
|
|
200
|
+
const refusal = registrationRefusal(options.table, options.commands ?? {});
|
|
201
|
+
if (refusal !== undefined)
|
|
202
|
+
return { kind: "rejected", detail: refusal };
|
|
206
203
|
const registrations = [];
|
|
207
204
|
for (const row of options.table) {
|
|
208
205
|
const { functionName, capabilities = ticketCapabilities, ...registration } = row;
|
|
@@ -223,9 +220,57 @@ export async function ticketRegistrations(manifests, options) {
|
|
|
223
220
|
};
|
|
224
221
|
registrations.push({
|
|
225
222
|
...registration,
|
|
226
|
-
manifest: declaredManifest(admission.manifest,
|
|
223
|
+
manifest: declaredManifest(admission.manifest, {
|
|
224
|
+
...row,
|
|
225
|
+
bundleDigest: options.bundleDigest,
|
|
226
|
+
}),
|
|
227
227
|
availability: "available",
|
|
228
228
|
});
|
|
229
229
|
}
|
|
230
230
|
return { kind: "admitted", registrations };
|
|
231
231
|
}
|
|
232
|
+
function registrationRefusal(table, commands) {
|
|
233
|
+
const queueRefusal = queueRegistrationRefusal(table);
|
|
234
|
+
if (queueRefusal !== undefined)
|
|
235
|
+
return queueRefusal;
|
|
236
|
+
const ids = new Set();
|
|
237
|
+
for (const row of table) {
|
|
238
|
+
if (ids.has(row.workflowId))
|
|
239
|
+
return `duplicate-workflow-id: ${row.workflowId}`;
|
|
240
|
+
ids.add(row.workflowId);
|
|
241
|
+
}
|
|
242
|
+
for (const row of table) {
|
|
243
|
+
const unknown = row.handoffs?.find((target) => !ids.has(target));
|
|
244
|
+
if (unknown !== undefined)
|
|
245
|
+
return `unknown-handoff-target: ${row.workflowId} -> ${unknown}`;
|
|
246
|
+
}
|
|
247
|
+
for (const row of table) {
|
|
248
|
+
const refusal = commandRegistrationRefusal(row, commands);
|
|
249
|
+
if (refusal !== undefined)
|
|
250
|
+
return refusal;
|
|
251
|
+
}
|
|
252
|
+
return undefined;
|
|
253
|
+
}
|
|
254
|
+
function commandRegistrationRefusal(row, commands) {
|
|
255
|
+
if (Object.hasOwn(row, "commandWaits") &&
|
|
256
|
+
!isCommandWaits(row.commandWaits, {
|
|
257
|
+
capabilities: row.capabilities ?? ticketCapabilities,
|
|
258
|
+
commands: row.commands ?? [],
|
|
259
|
+
}))
|
|
260
|
+
return `invalid-command-waits: ${row.workflowId}`;
|
|
261
|
+
const unknown = row.commands?.find((name) => !Object.hasOwn(commands, name));
|
|
262
|
+
return unknown === undefined
|
|
263
|
+
? undefined
|
|
264
|
+
: `command-unknown: ${row.workflowId} -> ${unknown}`;
|
|
265
|
+
}
|
|
266
|
+
function queueRegistrationRefusal(table) {
|
|
267
|
+
const queued = table.filter((row) => row.queue === true);
|
|
268
|
+
if (queued.length > 1)
|
|
269
|
+
return `queue-workflow-conflict: ${queued.map((row) => row.workflowId).join(", ")}`;
|
|
270
|
+
for (const row of queued) {
|
|
271
|
+
const codes = workflowQueueRefusals({ queue: true, input: row.submission });
|
|
272
|
+
if (codes.length > 0)
|
|
273
|
+
return `${codes.join(", ")}: ${row.workflowId}`;
|
|
274
|
+
}
|
|
275
|
+
return undefined;
|
|
276
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface CommandStart {
|
|
2
|
+
readonly output?: string | undefined;
|
|
3
|
+
readonly worker?: string | undefined;
|
|
4
|
+
readonly command: readonly string[];
|
|
5
|
+
readonly prompt: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function turnCommand(start: CommandStart): {
|
|
8
|
+
readonly parts: readonly string[];
|
|
9
|
+
readonly standardInput: string | undefined;
|
|
10
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
function argumentPrompt(prompt) {
|
|
2
|
+
return Buffer.byteLength(prompt, "utf8") < 64 * 1024;
|
|
3
|
+
}
|
|
4
|
+
export function turnCommand(start) {
|
|
5
|
+
if (start.output === "text")
|
|
6
|
+
return {
|
|
7
|
+
parts: start.command.map((part) => part === "{prompt}" ? start.prompt : part),
|
|
8
|
+
standardInput: start.command.includes("{prompt}")
|
|
9
|
+
? undefined
|
|
10
|
+
: start.prompt,
|
|
11
|
+
};
|
|
12
|
+
if (start.worker === "gemini" && argumentPrompt(start.prompt))
|
|
13
|
+
return {
|
|
14
|
+
parts: [...start.command, "-p", start.prompt],
|
|
15
|
+
standardInput: undefined,
|
|
16
|
+
};
|
|
17
|
+
if (start.worker === "opencode")
|
|
18
|
+
return {
|
|
19
|
+
parts: [...start.command, start.prompt],
|
|
20
|
+
standardInput: undefined,
|
|
21
|
+
};
|
|
22
|
+
if (start.worker === "cursor-agent" && argumentPrompt(start.prompt))
|
|
23
|
+
return {
|
|
24
|
+
parts: [...start.command, start.prompt],
|
|
25
|
+
standardInput: undefined,
|
|
26
|
+
};
|
|
27
|
+
if (start.worker !== "grok")
|
|
28
|
+
return { parts: start.command, standardInput: start.prompt };
|
|
29
|
+
const command = [...start.command];
|
|
30
|
+
const index = command.findIndex((argument, position) => position > 0 && ["-p", "--single"].includes(argument));
|
|
31
|
+
command.splice(index < 0 ? command.length : index + 1, 0, start.prompt);
|
|
32
|
+
return { parts: command, standardInput: undefined };
|
|
33
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type WorkTree } from "./work-tree.ts";
|
|
2
|
+
import type { StreamResult } from "./claude-turn.ts";
|
|
3
|
+
interface ReportLimits {
|
|
4
|
+
readonly summaryCharacters: number;
|
|
5
|
+
readonly resultBytes: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function turnReport(start: {
|
|
8
|
+
readonly harness: {
|
|
9
|
+
readonly worker: string;
|
|
10
|
+
readonly output?: "text";
|
|
11
|
+
};
|
|
12
|
+
readonly tree: WorkTree;
|
|
13
|
+
readonly limits: ReportLimits;
|
|
14
|
+
}, result: StreamResult): Promise<{
|
|
15
|
+
readonly text?: string;
|
|
16
|
+
readonly reason?: string;
|
|
17
|
+
}>;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { ticketStatus } from "../ticket-status.js";
|
|
2
|
+
import { reviewReport } from "../review-subject.js";
|
|
3
|
+
import { sumPrices } from "../worker-usage.js";
|
|
4
|
+
import { changes } from "./work-tree.js";
|
|
5
|
+
function tailReport(fields, limit) {
|
|
6
|
+
let text = JSON.stringify({ ...fields, summary: "" });
|
|
7
|
+
if (Buffer.byteLength(text) > limit)
|
|
8
|
+
return undefined;
|
|
9
|
+
let minimum = 1;
|
|
10
|
+
let maximum = fields.summary.length;
|
|
11
|
+
while (minimum <= maximum) {
|
|
12
|
+
const kept = Math.floor((minimum + maximum) / 2);
|
|
13
|
+
const candidate = JSON.stringify({
|
|
14
|
+
...fields,
|
|
15
|
+
summary: fields.summary.slice(-kept),
|
|
16
|
+
});
|
|
17
|
+
if (Buffer.byteLength(candidate) > limit) {
|
|
18
|
+
maximum = kept - 1;
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
text = candidate;
|
|
22
|
+
minimum = kept + 1;
|
|
23
|
+
}
|
|
24
|
+
return text;
|
|
25
|
+
}
|
|
26
|
+
function boundedReport(fields, options) {
|
|
27
|
+
const text = JSON.stringify(fields);
|
|
28
|
+
const excess = Buffer.byteLength(text) - options.limit;
|
|
29
|
+
if (excess <= 0)
|
|
30
|
+
return { text };
|
|
31
|
+
if (options.output === "text") {
|
|
32
|
+
const shortened = tailReport(fields, options.limit);
|
|
33
|
+
return shortened === undefined
|
|
34
|
+
? { reason: "claude-result-too-large" }
|
|
35
|
+
: { text: shortened };
|
|
36
|
+
}
|
|
37
|
+
const kept = Math.max(0, fields.summary.length - excess);
|
|
38
|
+
const shortened = JSON.stringify({
|
|
39
|
+
...fields,
|
|
40
|
+
summary: fields.summary.slice(0, kept),
|
|
41
|
+
});
|
|
42
|
+
if (Buffer.byteLength(shortened) <= options.limit)
|
|
43
|
+
return { text: shortened };
|
|
44
|
+
const metadata = JSON.stringify({
|
|
45
|
+
...fields,
|
|
46
|
+
ticketStatus: undefined,
|
|
47
|
+
summary: "",
|
|
48
|
+
});
|
|
49
|
+
return {
|
|
50
|
+
reason: "claude-result-too-large",
|
|
51
|
+
...(Buffer.byteLength(metadata) <= options.limit ? { text: metadata } : {}),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export async function turnReport(start, result) {
|
|
55
|
+
if (result.ticketStatusTooLarge === true)
|
|
56
|
+
return { reason: "claude-result-too-large" };
|
|
57
|
+
const { harness, tree, limits } = start;
|
|
58
|
+
const review = reviewReport(result.text);
|
|
59
|
+
const feedback = result.reviewFeedback ?? review.feedback;
|
|
60
|
+
return boundedReport({
|
|
61
|
+
harness: harness.worker,
|
|
62
|
+
ticketStatus: ticketStatus(result.text, result.ticketStatus),
|
|
63
|
+
reviewVerdict: result.reviewVerdict === undefined
|
|
64
|
+
? review.reviewVerdict
|
|
65
|
+
: result.reviewVerdict,
|
|
66
|
+
summary: harness.output === "text"
|
|
67
|
+
? feedback.slice(-limits.summaryCharacters)
|
|
68
|
+
: feedback.slice(0, limits.summaryCharacters),
|
|
69
|
+
...(await changes(tree)),
|
|
70
|
+
worktree: tree.path,
|
|
71
|
+
costUsd: result.costUsd,
|
|
72
|
+
usage: result.usage,
|
|
73
|
+
model: result.model,
|
|
74
|
+
...(result.attempts === undefined ? {} : { attempts: result.attempts }),
|
|
75
|
+
estimatedCostUsd: sumPrices((result.attempts ?? []).map((attempt) => attempt.estimatedCostUsd)),
|
|
76
|
+
sessionId: result.sessionId,
|
|
77
|
+
turns: result.turns,
|
|
78
|
+
}, { ...harness, limit: limits.resultBytes });
|
|
79
|
+
}
|
|
@@ -12,9 +12,10 @@ export interface TreeRequest {
|
|
|
12
12
|
}
|
|
13
13
|
export interface Changes {
|
|
14
14
|
readonly branch: string;
|
|
15
|
+
readonly commit: string | null;
|
|
15
16
|
readonly commits: readonly string[];
|
|
16
17
|
readonly files: readonly string[];
|
|
17
|
-
readonly uncommitted: readonly string[];
|
|
18
|
+
readonly uncommitted: readonly string[] | null;
|
|
18
19
|
}
|
|
19
20
|
export declare function treeName(target: string): string;
|
|
20
21
|
export declare function treePlace(request: Pick<TreeRequest, "worktrees" | "target">): {
|
|
@@ -186,21 +186,24 @@ export function treeFailure(error) {
|
|
|
186
186
|
: "work-tree-not-available";
|
|
187
187
|
}
|
|
188
188
|
export async function changes(tree) {
|
|
189
|
-
const lines =
|
|
190
|
-
.split("\n")
|
|
191
|
-
.filter((line) => line.trim() !== "")
|
|
192
|
-
.slice(0, lineLimit)
|
|
193
|
-
.map((line) => line.slice(0, lineLength));
|
|
189
|
+
const lines = (parts) => changeLines({ directory: tree.path, parts });
|
|
194
190
|
const range = `${tree.startCommit}..HEAD`;
|
|
195
|
-
const
|
|
196
|
-
"rev-parse",
|
|
197
|
-
"--abbrev-ref",
|
|
198
|
-
"HEAD",
|
|
199
|
-
]);
|
|
191
|
+
const branch = (await lines(["rev-parse", "--abbrev-ref", "HEAD"]))?.[0] ?? tree.branch;
|
|
200
192
|
return {
|
|
201
193
|
branch,
|
|
202
|
-
|
|
203
|
-
|
|
194
|
+
commit: (await lines(["rev-parse", "HEAD"]))?.[0] ?? null,
|
|
195
|
+
commits: (await lines(["log", "--oneline", range])) ?? [],
|
|
196
|
+
files: (await lines(["diff", "--stat", range])) ?? [],
|
|
204
197
|
uncommitted: await lines(["status", "--short"]),
|
|
205
198
|
};
|
|
206
199
|
}
|
|
200
|
+
async function changeLines(call) {
|
|
201
|
+
const output = await git(call).catch(() => null);
|
|
202
|
+
if (output === null)
|
|
203
|
+
return null;
|
|
204
|
+
return output
|
|
205
|
+
.split("\n")
|
|
206
|
+
.filter((line) => line.trim() !== "")
|
|
207
|
+
.slice(0, lineLimit)
|
|
208
|
+
.map((line) => line.slice(0, lineLength));
|
|
209
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { HostPorts } from "../service/service.ts";
|
|
2
|
+
import type { WorkflowFunction } from "../host/start-delivery.ts";
|
|
3
|
+
import type { WorkflowHandler } from "../host/world-host.ts";
|
|
4
|
+
import type { ExecutionManifest } from "../workflow-admission.ts";
|
|
5
|
+
import { type WorkflowRegistration } from "../service/registry.ts";
|
|
6
|
+
export interface WorkflowGeneration {
|
|
7
|
+
readonly workflows: Readonly<Record<string, unknown>>;
|
|
8
|
+
readonly handler: WorkflowHandler;
|
|
9
|
+
}
|
|
10
|
+
export type WorkflowBundleLoader = (directory: string) => Promise<WorkflowGeneration>;
|
|
11
|
+
export declare function workflowGenerations(settings: {
|
|
12
|
+
readonly directory: string;
|
|
13
|
+
readonly repository: string;
|
|
14
|
+
readonly registrations: readonly WorkflowRegistration[];
|
|
15
|
+
readonly table: readonly {
|
|
16
|
+
readonly workflowId: string;
|
|
17
|
+
readonly functionName: string;
|
|
18
|
+
}[];
|
|
19
|
+
readonly workflows: Readonly<Record<string, WorkflowFunction | undefined>>;
|
|
20
|
+
readonly handler: WorkflowHandler;
|
|
21
|
+
readonly loadBundle?: WorkflowBundleLoader;
|
|
22
|
+
}): {
|
|
23
|
+
resolve: (manifest: ExecutionManifest | undefined) => Promise<{
|
|
24
|
+
workflow: WorkflowFunction;
|
|
25
|
+
handler: WorkflowHandler;
|
|
26
|
+
} | undefined>;
|
|
27
|
+
available: (manifest: ExecutionManifest) => Promise<ExecutionManifest | undefined>;
|
|
28
|
+
};
|
|
29
|
+
export declare function prepareWorkflowGenerations(ports: {
|
|
30
|
+
readonly state: HostPorts["state"];
|
|
31
|
+
readonly workflow: Pick<HostPorts["workflow"], "manifest">;
|
|
32
|
+
}, generations: Pick<ReturnType<typeof workflowGenerations>, "resolve">): Promise<void>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { workflowRegistry, } from "../service/registry.js";
|
|
3
|
+
import { workflowPin } from "../broker/workflow-pin.js";
|
|
4
|
+
export function workflowGenerations(settings) {
|
|
5
|
+
const functions = Object.fromEntries(settings.table.map((row) => [
|
|
6
|
+
row.workflowId,
|
|
7
|
+
settings.workflows[row.functionName],
|
|
8
|
+
]));
|
|
9
|
+
const registry = workflowRegistry(settings.registrations, {
|
|
10
|
+
workflowBundles: {
|
|
11
|
+
directory: join(settings.directory, "workflow-bundles"),
|
|
12
|
+
repository: settings.repository,
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
const resolve = async (manifest) => {
|
|
16
|
+
if (manifest === undefined)
|
|
17
|
+
return undefined;
|
|
18
|
+
const registered = registry.byPin(workflowPin(manifest));
|
|
19
|
+
if (registered !== undefined) {
|
|
20
|
+
const workflow = functions[registered.workflowId];
|
|
21
|
+
return workflow === undefined
|
|
22
|
+
? undefined
|
|
23
|
+
: { workflow, handler: settings.handler };
|
|
24
|
+
}
|
|
25
|
+
if (manifest.bundleDigest === undefined ||
|
|
26
|
+
settings.loadBundle === undefined)
|
|
27
|
+
return undefined;
|
|
28
|
+
const directory = await registry.bundle(manifest);
|
|
29
|
+
if (directory === undefined)
|
|
30
|
+
return undefined;
|
|
31
|
+
try {
|
|
32
|
+
const generation = await settings.loadBundle(directory);
|
|
33
|
+
const workflow = Object.values(generation.workflows).find((candidate) => typeof candidate === "function" &&
|
|
34
|
+
Reflect.get(candidate, "workflowId") === manifest.workflowId);
|
|
35
|
+
return workflow === undefined
|
|
36
|
+
? undefined
|
|
37
|
+
: { workflow, handler: generation.handler };
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
return {
|
|
44
|
+
resolve,
|
|
45
|
+
available: async (manifest) => (await resolve(manifest)) === undefined ? undefined : manifest,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export async function prepareWorkflowGenerations(ports, generations) {
|
|
49
|
+
const prepared = new Set();
|
|
50
|
+
for (const run of Object.values((await ports.state()).runs)) {
|
|
51
|
+
if (["completed", "failed", "cancelled"].includes(run.status) ||
|
|
52
|
+
prepared.has(run.workflow))
|
|
53
|
+
continue;
|
|
54
|
+
prepared.add(run.workflow);
|
|
55
|
+
await generations.resolve(await ports.workflow.manifest(run.runId));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { WorkflowHandler } from "../host/world-host.ts";
|
|
2
|
+
import type { AuthorityState } from "../authority/transitions.ts";
|
|
3
|
+
interface ReplayRun {
|
|
4
|
+
readonly runId: string;
|
|
5
|
+
readonly workflowId?: string;
|
|
6
|
+
}
|
|
7
|
+
interface ReplayPorts {
|
|
8
|
+
readonly state: () => Promise<Pick<AuthorityState, "details">>;
|
|
9
|
+
readonly run: (receipt: string) => Promise<ReplayRun | undefined>;
|
|
10
|
+
readonly available: (runId: string, workflowId?: string) => Promise<boolean>;
|
|
11
|
+
readonly submit: (command: Readonly<Record<string, unknown>>) => Promise<{
|
|
12
|
+
readonly kind: "accepted" | "duplicate" | "failed" | "rejected";
|
|
13
|
+
}>;
|
|
14
|
+
}
|
|
15
|
+
export declare function pinnedWorkflowHandler(handler: (request: Request, runId: string) => Promise<Response>, ports: ReplayPorts): WorkflowHandler;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { record } from "../protocol.js";
|
|
2
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
3
|
+
function seeded(value) {
|
|
4
|
+
const input = record(record(value)?.["runInput"]);
|
|
5
|
+
const runId = record(input?.["attributes"])?.["cloving.run"];
|
|
6
|
+
const workflowId = input?.["workflowName"];
|
|
7
|
+
return typeof runId === "string" && typeof workflowId === "string"
|
|
8
|
+
? { runId, workflowId }
|
|
9
|
+
: undefined;
|
|
10
|
+
}
|
|
11
|
+
async function located(ports, receipt) {
|
|
12
|
+
for (let attempt = 0; attempt < 20; attempt += 1) {
|
|
13
|
+
const run = await ports.run(receipt);
|
|
14
|
+
if (run !== undefined)
|
|
15
|
+
return run;
|
|
16
|
+
await delay(5);
|
|
17
|
+
}
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
async function observedReplay(ports, replay) {
|
|
21
|
+
const { runId, receipt, available } = replay;
|
|
22
|
+
const observation = (await ports.state()).details[runId]?.observation;
|
|
23
|
+
const unavailable = observation?.reason === "pinned-workflow-unavailable";
|
|
24
|
+
if (available !== unavailable)
|
|
25
|
+
return true;
|
|
26
|
+
const expectedObservation = observation?.sequence ?? 0;
|
|
27
|
+
const outcome = await ports.submit({
|
|
28
|
+
kind: "report-observation",
|
|
29
|
+
runId,
|
|
30
|
+
commandId: `pinned-workflow-${available ? "restored" : "unavailable"}:${receipt}:${String(expectedObservation)}`,
|
|
31
|
+
condition: available ? "working" : "infrastructure-failure",
|
|
32
|
+
reason: available ? "in-progress" : "pinned-workflow-unavailable",
|
|
33
|
+
expectedObservation,
|
|
34
|
+
});
|
|
35
|
+
return outcome.kind === "accepted" || outcome.kind === "duplicate";
|
|
36
|
+
}
|
|
37
|
+
export function pinnedWorkflowHandler(handler, ports) {
|
|
38
|
+
return async (request) => {
|
|
39
|
+
const value = await request
|
|
40
|
+
.clone()
|
|
41
|
+
.json()
|
|
42
|
+
.catch(() => undefined);
|
|
43
|
+
const receipt = record(value)?.["runId"];
|
|
44
|
+
if (typeof receipt !== "string")
|
|
45
|
+
return new Response("invalid-workflow-message", { status: 400 });
|
|
46
|
+
const run = (await ports.run(receipt)) ??
|
|
47
|
+
seeded(value) ??
|
|
48
|
+
(await located(ports, receipt));
|
|
49
|
+
if (run === undefined)
|
|
50
|
+
return new Response("unknown-world-run", { status: 503 });
|
|
51
|
+
const available = await ports.available(run.runId, run.workflowId);
|
|
52
|
+
if (!(await observedReplay(ports, { runId: run.runId, receipt, available })))
|
|
53
|
+
return new Response("workflow-observation-unavailable", { status: 503 });
|
|
54
|
+
if (available)
|
|
55
|
+
return handler(request, run.runId);
|
|
56
|
+
return new Response("pinned-workflow-unavailable", { status: 503 });
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { WorkerPort } from "../service/worker-port.ts";
|
|
2
|
+
import type { DeclaredWorkflow } from "../workflow-declaration.ts";
|
|
3
|
+
interface ScheduleSettings {
|
|
4
|
+
readonly directory: string;
|
|
5
|
+
readonly runtimeDirectory: string;
|
|
6
|
+
readonly declarations?: readonly DeclaredWorkflow[];
|
|
7
|
+
readonly scheduleClock?: () => number;
|
|
8
|
+
readonly submit: WorkerPort["submit"];
|
|
9
|
+
}
|
|
10
|
+
export declare function scheduledDeclarations(settings: {
|
|
11
|
+
readonly declarations?: readonly DeclaredWorkflow[];
|
|
12
|
+
readonly schedules?: unknown;
|
|
13
|
+
}, limits?: {
|
|
14
|
+
readonly repository: string;
|
|
15
|
+
readonly documentBytes: number;
|
|
16
|
+
}): {
|
|
17
|
+
readonly kind: "configured";
|
|
18
|
+
readonly declarations: readonly DeclaredWorkflow[];
|
|
19
|
+
} | {
|
|
20
|
+
readonly kind: "refused";
|
|
21
|
+
readonly reason: string;
|
|
22
|
+
readonly detail: string;
|
|
23
|
+
};
|
|
24
|
+
export declare function workflowSchedules(settings: ScheduleSettings): Promise<{
|
|
25
|
+
readonly stop: () => Promise<void>;
|
|
26
|
+
}>;
|
|
27
|
+
export {};
|