cloving 1.1.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 +584 -144
- package/assets/watch-fonts/fira-code-OFL.md +93 -0
- package/assets/watch-fonts/fira-code-latin-400-normal.woff2 +0 -0
- package/assets/watch-fonts/fira-code-latin-500-normal.woff2 +0 -0
- package/assets/watch-fonts/heebo-OFL.md +93 -0
- package/assets/watch-fonts/heebo-latin-500-normal.woff2 +0 -0
- package/assets/watch-fonts/heebo-latin-700-normal.woff2 +0 -0
- package/assets/watch-fonts/heebo-latin-800-normal.woff2 +0 -0
- package/assets/watch-fonts/manifest.json +112 -0
- package/assets/watch-fonts/space-grotesk-OFL.md +93 -0
- package/assets/watch-fonts/space-grotesk-latin-400-normal.woff2 +0 -0
- package/assets/watch-fonts/space-grotesk-latin-500-normal.woff2 +0 -0
- package/assets/watch-fonts/space-grotesk-latin-600-normal.woff2 +0 -0
- package/assets/watch-fonts/space-grotesk-latin-700-normal.woff2 +0 -0
- 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 +2 -0
- package/dist/src/authority/commands.js +49 -8
- package/dist/src/authority/dispatch-decision.d.ts +1 -0
- package/dist/src/authority/dispatch-decision.js +7 -4
- package/dist/src/authority/events.js +2 -2
- 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/handoff-chain.d.ts +24 -0
- package/dist/src/authority/handoff-chain.js +46 -0
- package/dist/src/authority/operations.js +1 -1
- package/dist/src/authority/reconciliation.d.ts +1 -0
- package/dist/src/authority/reconciliation.js +18 -11
- 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 +9 -0
- package/dist/src/broker/actor/authority-delivery.js +1 -0
- package/dist/src/broker/actor/authority-queries.d.ts +11 -1
- package/dist/src/broker/actor/authority-queries.js +67 -3
- 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 +3 -1
- package/dist/src/broker/actor/delivery-intents.js +4 -4
- package/dist/src/broker/actor/effect-delivery.js +13 -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 +26 -5
- 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 +3 -1
- package/dist/src/cli/render.js +102 -39
- 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 +74 -45
- 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 +12 -1
- package/dist/src/cli/watch-board-view.js +64 -12
- package/dist/src/cli/watch-board.d.ts +7 -1
- package/dist/src/cli/watch-board.js +61 -16
- 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 +12 -3
- 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.d.ts +10 -4
- package/dist/src/cli/watch-model.js +49 -59
- package/dist/src/cli/watch-page.js +67 -14
- package/dist/src/cli/watch-phases.js +3 -3
- 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-pr-command.d.ts +5 -2
- package/dist/src/cli/watch-pr-command.js +41 -4
- package/dist/src/cli/watch-pr-identity.d.ts +14 -2
- package/dist/src/cli/watch-pr-identity.js +25 -0
- package/dist/src/cli/watch-pr-observer.d.ts +1 -0
- package/dist/src/cli/watch-pr-observer.js +48 -6
- package/dist/src/cli/watch-pull-request.d.ts +12 -0
- package/dist/src/cli/watch-pull-request.js +134 -0
- package/dist/src/cli/watch-reads.d.ts +7 -1
- package/dist/src/cli/watch-reads.js +42 -20
- package/dist/src/cli/watch-render.d.ts +23 -2
- package/dist/src/cli/watch-render.js +2 -1
- package/dist/src/cli/watch-server.js +56 -7
- package/dist/src/cli/watch-turn.d.ts +4 -1
- package/dist/src/cli/watch-turn.js +38 -2
- package/dist/src/cli/watch-usage.js +5 -1
- package/dist/src/cli/watch-view.d.ts +10 -17
- package/dist/src/cli/watch-view.js +33 -77
- 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 +20 -5
- package/dist/src/daemon/claude-turn.js +116 -53
- package/dist/src/daemon/claude-worker.d.ts +3 -5
- package/dist/src/daemon/claude-worker.js +64 -80
- 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 +3 -30
- package/dist/src/daemon/daemon.js +132 -110
- 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 +7 -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-calls.d.ts +4 -0
- package/dist/src/daemon/github-calls.js +16 -7
- 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.d.ts +6 -0
- package/dist/src/daemon/github-ci.js +251 -0
- package/dist/src/daemon/github-merge-call.d.ts +16 -0
- package/dist/src/daemon/github-merge-call.js +73 -0
- package/dist/src/daemon/github-merge.d.ts +3 -5
- package/dist/src/daemon/github-merge.js +59 -98
- package/dist/src/daemon/github-methods.d.ts +28 -0
- package/dist/src/daemon/github-methods.js +90 -16
- package/dist/src/daemon/github-operation.d.ts +3 -0
- package/dist/src/daemon/github-retry.d.ts +6 -0
- package/dist/src/daemon/github-retry.js +13 -0
- package/dist/src/daemon/github-ticket-status.js +27 -1
- package/dist/src/daemon/github-worker.js +2 -1
- package/dist/src/daemon/handoff-worker.d.ts +10 -0
- package/dist/src/daemon/handoff-worker.js +232 -0
- package/dist/src/daemon/issue-queue.d.ts +2 -0
- package/dist/src/daemon/issue-queue.js +92 -63
- package/dist/src/daemon/notify-journal.d.ts +18 -0
- package/dist/src/daemon/notify-journal.js +108 -0
- package/dist/src/daemon/notify-message.js +2 -1
- package/dist/src/daemon/notify.js +177 -37
- 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 +5 -0
- package/dist/src/daemon/retrying-turn.js +145 -21
- 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-dependency-waits.d.ts +18 -0
- package/dist/src/daemon/ticket-dependency-waits.js +60 -0
- package/dist/src/daemon/ticket-registration.d.ts +10 -8
- package/dist/src/daemon/ticket-registration.js +146 -47
- package/dist/src/daemon/ticket-source.d.ts +4 -1
- package/dist/src/daemon/ticket-source.js +8 -2
- 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-visibility.d.ts +2 -0
- package/dist/src/decision-visibility.js +10 -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 +9 -0
- package/dist/src/execution-pin.js +86 -2
- 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 +3 -2
- package/dist/src/host/start-delivery.js +11 -4
- package/dist/src/host/step-bridge-host.d.ts +6 -19
- package/dist/src/host/step-bridge-host.js +57 -55
- package/dist/src/host/world-reconciliation.d.ts +1 -0
- package/dist/src/host/world-reconciliation.js +3 -0
- package/dist/src/host/world-runs.js +5 -0
- package/dist/src/issue-identity.d.ts +6 -0
- package/dist/src/issue-identity.js +23 -0
- 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/queue-runs.d.ts +3 -0
- package/dist/src/service/queue-runs.js +39 -0
- package/dist/src/service/registry.d.ts +22 -3
- package/dist/src/service/registry.js +51 -8
- package/dist/src/service/replies.d.ts +10 -0
- package/dist/src/service/replies.js +12 -0
- package/dist/src/service/run-handlers.js +45 -54
- 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 +21 -2
- package/dist/src/service/service.js +23 -5
- package/dist/src/service/submission-handler.js +70 -19
- package/dist/src/service/worker-port.d.ts +1 -0
- package/dist/src/service/worker-totals.js +10 -1
- package/dist/src/step-bridge.d.ts +32 -0
- package/dist/src/steps/decision-gate.d.ts +2 -1
- package/dist/src/steps/decision-gate.js +7 -0
- package/dist/src/steps/handoff.d.ts +2 -0
- package/dist/src/steps/handoff.js +13 -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-dependencies.d.ts +1 -0
- package/dist/src/ticket-dependencies.js +15 -0
- package/dist/src/ticket-status-stream.d.ts +9 -0
- package/dist/src/ticket-status-stream.js +94 -0
- package/dist/src/ticket-status.js +7 -4
- package/dist/src/token-prices.d.ts +14 -4
- package/dist/src/token-prices.js +56 -11
- package/dist/src/turn-profile.d.ts +1 -0
- package/dist/src/turn-profile.js +8 -1
- package/dist/src/worker-usage.d.ts +25 -0
- package/dist/src/worker-usage.js +58 -1
- package/dist/src/workflow-admission.d.ts +6 -0
- package/dist/src/workflow-candidate.d.ts +7 -2
- package/dist/src/workflow-candidate.js +48 -5
- package/dist/src/workflow-contracts.d.ts +2 -0
- package/dist/src/workflow-contracts.js +8 -3
- package/dist/src/workflow-declaration.d.ts +31 -2
- package/dist/src/workflow-declaration.js +140 -16
- package/dist/src/workflow-discovery.d.ts +19 -0
- package/dist/src/workflow-discovery.js +36 -0
- package/dist/src/workflow-refusals.d.ts +6 -0
- package/dist/src/workflow-refusals.js +42 -0
- package/dist/src/workflow-schedule.d.ts +22 -0
- package/dist/src/workflow-schedule.js +53 -0
- package/dist/src/workflows.d.ts +12 -1
- package/dist/src/workflows.js +9 -0
- package/dist/tools/admit-workflow.d.ts +14 -0
- package/dist/tools/admit-workflow.js +107 -0
- 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 +21 -0
- package/dist/tools/self-host-project.js +224 -0
- 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 +106 -135
- package/dist/tools/workflow-bundle-dependencies.d.ts +5 -0
- package/dist/tools/workflow-bundle-dependencies.js +93 -0
- package/dist/tools/workflow-bundles.d.ts +20 -0
- package/dist/tools/workflow-bundles.js +173 -0
- package/dist/tools/workflow-candidate-counts.d.ts +12 -0
- package/dist/tools/workflow-candidate-counts.js +266 -0
- 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 +13 -0
- package/dist/tools/workflow-candidate-program.js +106 -0
- package/dist/tools/workflow-candidate-source.d.ts +6 -0
- package/dist/tools/workflow-candidate-source.js +169 -0
- package/dist/tools/workflow-candidate-syntax.d.ts +21 -0
- package/dist/tools/workflow-candidate-syntax.js +263 -0
- 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 +18 -0
- package/dist/tools/workflow-folder-capture.js +261 -0
- package/dist/tools/workflow-folders.d.ts +49 -0
- package/dist/tools/workflow-folders.js +203 -0
- package/dist/tools/workflow-source-effects.d.ts +10 -0
- package/dist/tools/workflow-source-effects.js +213 -0
- 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-prd.js +71 -3
- package/dist/workflows/develop-ticket.js +6 -1
- package/dist/workflows/ticket-prompts.js +17 -3
- package/package.json +66 -6
- 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 -24
- package/dist/src/chats/analysis-batches.js +0 -83
- 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 -12
- package/dist/src/chats/analysis-input.js +0 -83
- package/dist/src/chats/analysis-links.d.ts +0 -2
- package/dist/src/chats/analysis-links.js +0 -25
- package/dist/src/chats/analysis-prompt.d.ts +0 -10
- package/dist/src/chats/analysis-prompt.js +0 -16
- package/dist/src/chats/analysis-proposal.d.ts +0 -2
- package/dist/src/chats/analysis-proposal.js +0 -32
- 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 -3
- package/dist/src/chats/analysis-shape.js +0 -228
- 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/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/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 -22
- package/dist/src/daemon/analysis-worker.js +0 -219
- package/dist/src/daemon/chats-files.d.ts +0 -15
- package/dist/src/daemon/chats-files.js +0 -113
- package/dist/src/daemon/chats-worker.d.ts +0 -12
- package/dist/src/daemon/chats-worker.js +0 -200
- package/dist/workflows/analyze-chats.d.ts +0 -10
- package/dist/workflows/analyze-chats.declaration.json +0 -9
- package/dist/workflows/analyze-chats.js +0 -73
|
@@ -1,9 +1,17 @@
|
|
|
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";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
import { declaredInput } from "./declared-input.js";
|
|
6
|
+
import { bundledWorkflowIds } from "../workflow-discovery.js";
|
|
7
|
+
import { declaredManifest } from "../execution-pin.js";
|
|
8
|
+
import { record } from "../protocol.js";
|
|
9
|
+
import { hasTicketField } from "../submission.js";
|
|
10
|
+
import { issueIdentity } from "../issue-identity.js";
|
|
11
|
+
import { ticketDependencyWaits, TicketDependencyReadError, } from "./ticket-dependency-waits.js";
|
|
12
|
+
export const ticketWorkflow = bundledWorkflowIds.ticket;
|
|
13
|
+
export const promptWorkflow = bundledWorkflowIds.prompt;
|
|
14
|
+
export const issueWorkflow = bundledWorkflowIds.issue;
|
|
7
15
|
export const ticketCapabilities = ["claude", "github"];
|
|
8
16
|
const ticketIdentifier = /^[A-Za-z0-9._:-]{1,64}$/;
|
|
9
17
|
function rejected(code, detail) {
|
|
@@ -38,7 +46,15 @@ async function ticket(source, request) {
|
|
|
38
46
|
async function nextTicket(source, request) {
|
|
39
47
|
if (source.nextCommand === undefined)
|
|
40
48
|
return rejected("next-source-not-configured", "The daemon has no next-ticket command. Set CLOVING_NEXT_COMMAND.");
|
|
41
|
-
const selected = await ticketCommandText(source.nextCommand,
|
|
49
|
+
const selected = await ticketCommandText(source.nextCommand, {
|
|
50
|
+
signal: request.signal,
|
|
51
|
+
skipTickets: [
|
|
52
|
+
...new Set([
|
|
53
|
+
...(request.activeTickets ?? []).flatMap((input) => typeof input["ticketId"] === "string" ? [input["ticketId"]] : []),
|
|
54
|
+
...(source.skipTickets ?? []),
|
|
55
|
+
]),
|
|
56
|
+
].sort(),
|
|
57
|
+
});
|
|
42
58
|
if (selected.kind === "failed")
|
|
43
59
|
return rejected("next-ticket-not-available", selected.detail);
|
|
44
60
|
if (selected.text === "")
|
|
@@ -55,18 +71,43 @@ export function ticketResolver(source) {
|
|
|
55
71
|
};
|
|
56
72
|
}
|
|
57
73
|
export function issueResolver(source) {
|
|
74
|
+
const waits = ticketDependencyWaits(source);
|
|
58
75
|
return {
|
|
59
76
|
id: "issue-command",
|
|
60
77
|
version: "1",
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (
|
|
64
|
-
|
|
65
|
-
return
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
78
|
+
skippedTickets: waits.skipped,
|
|
79
|
+
resolve: (request) => issueTicket({ source, waits }, request).catch((error) => {
|
|
80
|
+
if (!(error instanceof TicketDependencyReadError))
|
|
81
|
+
throw error;
|
|
82
|
+
return rejected("ticket-not-available", "The ticket dependencies could not be read. Retry this command.");
|
|
83
|
+
}),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
async function issueTicket(context, request) {
|
|
87
|
+
const { source, waits } = context;
|
|
88
|
+
const skipTickets = request.submission["ticket"] === "next"
|
|
89
|
+
? await waits.refresh(request.signal)
|
|
90
|
+
: [];
|
|
91
|
+
const resolution = await ticket({ ...source, skipTickets }, request);
|
|
92
|
+
if (resolution.kind === "rejected")
|
|
93
|
+
return resolution;
|
|
94
|
+
const input = record(resolution.input) ?? {};
|
|
95
|
+
const identity = issueIdentity(input["ticket"]);
|
|
96
|
+
if ((request.activeTickets ?? []).some((active) => active["ticketId"] === input["ticketId"] ||
|
|
97
|
+
(identity !== null &&
|
|
98
|
+
JSON.stringify(issueIdentity(active["ticket"])) ===
|
|
99
|
+
JSON.stringify(identity))))
|
|
100
|
+
return rejected("ticket-active", "An active run already works on this ticket.");
|
|
101
|
+
const dependencies = await waits.check({
|
|
102
|
+
ticketId: String(input["ticketId"]),
|
|
103
|
+
ticket: String(input["ticket"]),
|
|
104
|
+
signal: request.signal,
|
|
105
|
+
});
|
|
106
|
+
if (dependencies.length > 0)
|
|
107
|
+
return rejected("ticket-dependency-open", `Ticket ${String(input["ticketId"])} needs open issues: ${dependencies.map((id) => `#${id}`).join(", ")}.`);
|
|
108
|
+
return {
|
|
109
|
+
kind: "resolved",
|
|
110
|
+
input: { ...input, delivery: "pull-request" },
|
|
70
111
|
};
|
|
71
112
|
}
|
|
72
113
|
export function promptResolver(repository) {
|
|
@@ -89,6 +130,7 @@ export function ticketRegistrationTable(source, declarations = []) {
|
|
|
89
130
|
workflowId: ticketWorkflow,
|
|
90
131
|
functionName: "developTicket",
|
|
91
132
|
effectLimit: 8,
|
|
133
|
+
handoffs: [],
|
|
92
134
|
submission: { maximumBytes: 4_096, fields: { ticket: "string" } },
|
|
93
135
|
resolver: ticketResolver(source),
|
|
94
136
|
},
|
|
@@ -96,13 +138,15 @@ export function ticketRegistrationTable(source, declarations = []) {
|
|
|
96
138
|
workflowId: issueWorkflow,
|
|
97
139
|
functionName: "developTicket",
|
|
98
140
|
effectLimit: 20,
|
|
141
|
+
handoffs: [],
|
|
99
142
|
submission: { maximumBytes: 4_096, fields: { ticket: "string" } },
|
|
100
143
|
resolver: issueResolver(source),
|
|
101
144
|
},
|
|
102
145
|
{
|
|
103
|
-
workflowId:
|
|
146
|
+
workflowId: bundledWorkflowIds.prd,
|
|
104
147
|
functionName: "developPrd",
|
|
105
148
|
effectLimit: 8,
|
|
149
|
+
handoffs: [issueWorkflow],
|
|
106
150
|
submission: { maximumBytes: 65_536, fields: { prompt: "string" } },
|
|
107
151
|
resolver: promptResolver(source.repository),
|
|
108
152
|
},
|
|
@@ -110,54 +154,64 @@ export function ticketRegistrationTable(source, declarations = []) {
|
|
|
110
154
|
workflowId: promptWorkflow,
|
|
111
155
|
functionName: "developTicket",
|
|
112
156
|
effectLimit: 8,
|
|
157
|
+
handoffs: [],
|
|
113
158
|
submission: { maximumBytes: 65_536, fields: { prompt: "string" } },
|
|
114
159
|
resolver: promptResolver(source.repository),
|
|
115
160
|
},
|
|
116
|
-
...declarations.map((declaration) => ({
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
capabilities: declaration.capabilities,
|
|
121
|
-
submission: declaration.input,
|
|
122
|
-
resolver: declaredResolver(source.repository),
|
|
161
|
+
...declarations.map(({ input, ...declaration }) => ({
|
|
162
|
+
...declaration,
|
|
163
|
+
submission: input,
|
|
164
|
+
resolver: declaredResolver(source, input),
|
|
123
165
|
})),
|
|
124
166
|
];
|
|
125
167
|
}
|
|
126
|
-
function declaredResolver(
|
|
168
|
+
function declaredResolver(source, contract) {
|
|
169
|
+
const tickets = hasTicketField(contract) ? issueResolver(source) : undefined;
|
|
127
170
|
return {
|
|
128
171
|
id: "declared-input",
|
|
129
172
|
version: "1",
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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
|
+
},
|
|
138
197
|
};
|
|
139
198
|
}
|
|
140
199
|
export async function ticketRegistrations(manifests, options) {
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
return {
|
|
145
|
-
kind: "rejected",
|
|
146
|
-
detail: `duplicate-workflow-id: ${row.workflowId}`,
|
|
147
|
-
};
|
|
148
|
-
ids.add(row.workflowId);
|
|
149
|
-
}
|
|
200
|
+
const refusal = registrationRefusal(options.table, options.commands ?? {});
|
|
201
|
+
if (refusal !== undefined)
|
|
202
|
+
return { kind: "rejected", detail: refusal };
|
|
150
203
|
const registrations = [];
|
|
151
204
|
for (const row of options.table) {
|
|
152
|
-
const
|
|
205
|
+
const { functionName, capabilities = ticketCapabilities, ...registration } = row;
|
|
206
|
+
const manifest = manifests[functionName];
|
|
153
207
|
if (manifest === undefined)
|
|
154
208
|
return {
|
|
155
209
|
kind: "rejected",
|
|
156
|
-
detail: `Missing manifest for workflow function ${
|
|
210
|
+
detail: `Missing manifest for workflow function ${functionName}.`,
|
|
157
211
|
};
|
|
158
212
|
const admission = await admitCompiled(manifest, {
|
|
159
213
|
file: manifest,
|
|
160
|
-
capabilities
|
|
214
|
+
capabilities,
|
|
161
215
|
});
|
|
162
216
|
if (admission.kind === "rejected")
|
|
163
217
|
return {
|
|
@@ -165,13 +219,58 @@ export async function ticketRegistrations(manifests, options) {
|
|
|
165
219
|
detail: `${admission.error.code}: ${admission.error.detail}`,
|
|
166
220
|
};
|
|
167
221
|
registrations.push({
|
|
168
|
-
|
|
169
|
-
manifest: admission.manifest,
|
|
222
|
+
...registration,
|
|
223
|
+
manifest: declaredManifest(admission.manifest, {
|
|
224
|
+
...row,
|
|
225
|
+
bundleDigest: options.bundleDigest,
|
|
226
|
+
}),
|
|
170
227
|
availability: "available",
|
|
171
|
-
effectLimit: row.effectLimit,
|
|
172
|
-
submission: row.submission,
|
|
173
|
-
resolver: row.resolver,
|
|
174
228
|
});
|
|
175
229
|
}
|
|
176
230
|
return { kind: "admitted", registrations };
|
|
177
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
|
+
}
|
|
@@ -14,4 +14,7 @@ export interface TicketRequest {
|
|
|
14
14
|
readonly signal: AbortSignal;
|
|
15
15
|
}
|
|
16
16
|
export declare function ticketText(command: readonly string[], request: TicketRequest): Promise<TicketRead>;
|
|
17
|
-
export declare function ticketCommandText(command: readonly string[],
|
|
17
|
+
export declare function ticketCommandText(command: readonly string[], request: AbortSignal | {
|
|
18
|
+
readonly signal: AbortSignal;
|
|
19
|
+
readonly skipTickets: readonly string[];
|
|
20
|
+
}): Promise<TicketRead>;
|
|
@@ -26,10 +26,16 @@ export function ticketText(command, request) {
|
|
|
26
26
|
const [executable = "", ...fixed] = command;
|
|
27
27
|
return ticketCommandText([executable, ...fixed, request.ticketId], request.signal).then((result) => result.kind === "failed" ? result : printed(result.text));
|
|
28
28
|
}
|
|
29
|
-
export function ticketCommandText(command,
|
|
29
|
+
export function ticketCommandText(command, request) {
|
|
30
30
|
const [executable = "", ...fixed] = command;
|
|
31
31
|
return executed(executable, fixed, {
|
|
32
|
-
signal,
|
|
32
|
+
signal: request instanceof AbortSignal ? request : request.signal,
|
|
33
|
+
env: request instanceof AbortSignal
|
|
34
|
+
? process.env
|
|
35
|
+
: {
|
|
36
|
+
...process.env,
|
|
37
|
+
CLOVING_SKIP_TICKETS: request.skipTickets.join(" "),
|
|
38
|
+
},
|
|
33
39
|
maxBuffer: 4 * ticketLimits.textBytes,
|
|
34
40
|
encoding: "utf8",
|
|
35
41
|
}).then((output) => ({ kind: "read", text: output.stdout.trim() }), ended);
|
|
@@ -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
|
+
}
|