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
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { ProtectedResult } from "cloving/workflows";
|
|
2
|
+
import { protectedEffect } from "cloving/workflows/steps/protected-effect";
|
|
3
|
+
|
|
4
|
+
export interface DevelopTurnInput {
|
|
5
|
+
readonly cycleId: string;
|
|
6
|
+
readonly repository: string;
|
|
7
|
+
readonly ticket?: string;
|
|
8
|
+
readonly prompt?: string;
|
|
9
|
+
readonly round: number;
|
|
10
|
+
readonly feedback: {
|
|
11
|
+
readonly reason: string;
|
|
12
|
+
readonly output: string;
|
|
13
|
+
readonly remaining: readonly string[];
|
|
14
|
+
} | null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function turnPrompt(input: DevelopTurnInput): string {
|
|
18
|
+
if (!Number.isSafeInteger(input.round) || input.round < 1 || input.round > 4)
|
|
19
|
+
throw new Error("invalid-development-round");
|
|
20
|
+
const task = input.ticket ?? input.prompt;
|
|
21
|
+
if (
|
|
22
|
+
(input.ticket !== undefined && input.prompt !== undefined) ||
|
|
23
|
+
typeof task !== "string" ||
|
|
24
|
+
task.trim() === ""
|
|
25
|
+
)
|
|
26
|
+
throw new Error("invalid-development-task");
|
|
27
|
+
const prompt = [
|
|
28
|
+
"Implement the task in this worktree, on its current branch.",
|
|
29
|
+
`The main checkout at ${input.repository} is read-only.`,
|
|
30
|
+
"Read AGENTS.md and CLAUDE.md. Use TDD: observe the intended test failure before implementing each behavior.",
|
|
31
|
+
"Run the repository checks, commit the changes, then run npm run check:clean if the repository provides it.",
|
|
32
|
+
"Do not push, publish, deploy, or switch branches.",
|
|
33
|
+
"The branch will become a public pull request. Keep local paths out of tracked files and commit messages.",
|
|
34
|
+
"Report the changes and check results. Finish with Ticket status: complete or Ticket status: partial. For partial work, precede the status with Remaining: and one unfinished item per '- ' line.",
|
|
35
|
+
"",
|
|
36
|
+
"Task:",
|
|
37
|
+
task,
|
|
38
|
+
].join("\n");
|
|
39
|
+
if (input.feedback === null) return prompt;
|
|
40
|
+
return [
|
|
41
|
+
prompt,
|
|
42
|
+
"",
|
|
43
|
+
`This is fix round ${String(input.round)}. Address ${input.feedback.reason}, then commit the fix.`,
|
|
44
|
+
"Reassess every unfinished item and retain unresolved items in the next Remaining: list:",
|
|
45
|
+
input.feedback.remaining.map((item) => `- ${item}`).join("\n"),
|
|
46
|
+
"",
|
|
47
|
+
"Output from the previous result:",
|
|
48
|
+
input.feedback.output,
|
|
49
|
+
].join("\n");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export async function developTurn(
|
|
53
|
+
input: DevelopTurnInput,
|
|
54
|
+
): Promise<ProtectedResult> {
|
|
55
|
+
return await protectedEffect({
|
|
56
|
+
scope: {
|
|
57
|
+
phase: "implement",
|
|
58
|
+
operation: "claude-turn",
|
|
59
|
+
round: input.round,
|
|
60
|
+
},
|
|
61
|
+
capability: "claude",
|
|
62
|
+
method: "run-turn",
|
|
63
|
+
target: input.cycleId,
|
|
64
|
+
payload: turnPrompt(input),
|
|
65
|
+
units: 1,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"workflow": {
|
|
3
|
+
"workflowId": "develop",
|
|
4
|
+
"effectLimit": 27,
|
|
5
|
+
"capabilities": ["claude", "github"],
|
|
6
|
+
"queue": true,
|
|
7
|
+
"input": {
|
|
8
|
+
"maximumBytes": 65536,
|
|
9
|
+
"fields": { "ticket": { "type": "ticket" } }
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"methods": {
|
|
13
|
+
"claude": ["run-turn"],
|
|
14
|
+
"github": [
|
|
15
|
+
"prepare",
|
|
16
|
+
"label",
|
|
17
|
+
"open-pr",
|
|
18
|
+
"wait-review",
|
|
19
|
+
"merge",
|
|
20
|
+
"close-issue",
|
|
21
|
+
"partial-issue"
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import { flowTests } from "./develop/flow-tests.ts";
|
|
2
|
+
import { refusalTests } from "./develop/refusal-tests.ts";
|
|
3
|
+
import assert from "node:assert/strict";
|
|
4
|
+
import { test } from "node:test";
|
|
5
|
+
import { fakeStepBridge } from "cloving/workflows/testing";
|
|
6
|
+
import { developTurn } from "./develop/turn.ts";
|
|
7
|
+
import { reviewPartial } from "./develop/partial.ts";
|
|
8
|
+
import { queuePartial } from "./develop/queue-partial.ts";
|
|
9
|
+
|
|
10
|
+
for (const scenario of flowTests.concat(refusalTests))
|
|
11
|
+
await test(scenario.name, scenario.run);
|
|
12
|
+
|
|
13
|
+
await test("CLV-221 invalid partial rounds never dispatch an effect or open a question", async () => {
|
|
14
|
+
using bridge = fakeStepBridge({});
|
|
15
|
+
for (const round of [0, -1, 1.5, 5, NaN, Infinity]) {
|
|
16
|
+
const input = {
|
|
17
|
+
cycleId: "run-1",
|
|
18
|
+
round,
|
|
19
|
+
issue: { owner: "acme", repository: "demo", number: 42 },
|
|
20
|
+
pullRequest: 7,
|
|
21
|
+
remaining: ["Test."],
|
|
22
|
+
};
|
|
23
|
+
await assert.rejects(queuePartial(input), {
|
|
24
|
+
message: "invalid-development-round",
|
|
25
|
+
});
|
|
26
|
+
await assert.rejects(reviewPartial(input), {
|
|
27
|
+
message: "invalid-development-round",
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
assert.deepEqual(bridge.requests, []);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
await test("CLV-221 partial questions use distinct rounds and stop after three fixes", async () => {
|
|
34
|
+
using bridge = fakeStepBridge({
|
|
35
|
+
decisions: [
|
|
36
|
+
{ decision: "answered", answer: "First fix." },
|
|
37
|
+
{ decision: "answered", answer: "Second fix." },
|
|
38
|
+
{ decision: "answered", answer: "Third fix." },
|
|
39
|
+
],
|
|
40
|
+
});
|
|
41
|
+
for (const round of [1, 2, 3]) {
|
|
42
|
+
assert.equal(
|
|
43
|
+
typeof (await reviewPartial({
|
|
44
|
+
cycleId: "run-1",
|
|
45
|
+
round,
|
|
46
|
+
remaining: ["Test."],
|
|
47
|
+
})),
|
|
48
|
+
"string",
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
assert.equal(
|
|
52
|
+
await reviewPartial({
|
|
53
|
+
cycleId: "run-1",
|
|
54
|
+
round: 4,
|
|
55
|
+
remaining: ["Test."],
|
|
56
|
+
}),
|
|
57
|
+
null,
|
|
58
|
+
);
|
|
59
|
+
assert.deepEqual(
|
|
60
|
+
bridge.requests.map((request) => {
|
|
61
|
+
assert.equal(request[0], "waitForDecision");
|
|
62
|
+
return request[1].gateId;
|
|
63
|
+
}),
|
|
64
|
+
["partial:run-1:1", "partial:run-1:2", "partial:run-1:3"],
|
|
65
|
+
);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
await test("CLV-221 partial work stops without an explicit nonempty answer", async () => {
|
|
69
|
+
for (const decision of [
|
|
70
|
+
{ decision: "answered" as const, answer: " \n" },
|
|
71
|
+
{ decision: "answered" as const, answer: null },
|
|
72
|
+
{ decision: "denied" as const, answer: "Do not continue." },
|
|
73
|
+
{ decision: "expired" as const, answer: "Stale feedback." },
|
|
74
|
+
{ decision: "approved" as const, answer: "Unexpected approval." },
|
|
75
|
+
]) {
|
|
76
|
+
using bridge = fakeStepBridge({ decisions: [decision] });
|
|
77
|
+
assert.equal(
|
|
78
|
+
await reviewPartial({ cycleId: "run-1", round: 2, remaining: ["Test."] }),
|
|
79
|
+
null,
|
|
80
|
+
);
|
|
81
|
+
assert.equal(bridge.requests.length, 1);
|
|
82
|
+
assert.equal(bridge.requests[0]?.[0], "waitForDecision");
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
await test("CLV-221 a person chooses the next fix for partial work", async () => {
|
|
87
|
+
using bridge = fakeStepBridge({
|
|
88
|
+
decisions: [{ decision: "answered", answer: " Add recovery first.\n" }],
|
|
89
|
+
});
|
|
90
|
+
const feedback = await reviewPartial({
|
|
91
|
+
cycleId: "run-1",
|
|
92
|
+
round: 1,
|
|
93
|
+
remaining: ["Add recovery.", "Verify restart."],
|
|
94
|
+
});
|
|
95
|
+
assert.equal(feedback, " Add recovery first.\n");
|
|
96
|
+
assert.equal(bridge.requests.length, 1);
|
|
97
|
+
const request = bridge.requests[0];
|
|
98
|
+
assert.ok(request && request[0] === "waitForDecision");
|
|
99
|
+
assert.equal(request[1].gateId, "partial:run-1:1");
|
|
100
|
+
assert.equal(request[1].kind, "question");
|
|
101
|
+
assert.match(request[1].prompt, /- Add recovery\.\n- Verify restart\./);
|
|
102
|
+
assert.match(request[1].prompt, /empty answer to stop/);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
await test("CLV-221 queued partial work records the merged pull request and remaining items", async () => {
|
|
106
|
+
const completed = {
|
|
107
|
+
kind: "completed" as const,
|
|
108
|
+
operationId: "partial-update",
|
|
109
|
+
receipt: null,
|
|
110
|
+
result: JSON.stringify({ number: 42, ticketStatus: "partial" }),
|
|
111
|
+
};
|
|
112
|
+
using bridge = fakeStepBridge({
|
|
113
|
+
effects: { "github partial-issue": [completed] },
|
|
114
|
+
});
|
|
115
|
+
const result = await queuePartial({
|
|
116
|
+
cycleId: "run-1",
|
|
117
|
+
round: 2,
|
|
118
|
+
issue: { owner: "acme", repository: "demo", number: 42 },
|
|
119
|
+
pullRequest: 7,
|
|
120
|
+
remaining: ["Add recovery.", "Verify restart."],
|
|
121
|
+
});
|
|
122
|
+
assert.deepEqual(result, completed);
|
|
123
|
+
assert.deepEqual(bridge.requests, [
|
|
124
|
+
[
|
|
125
|
+
"effect",
|
|
126
|
+
{
|
|
127
|
+
scope: {
|
|
128
|
+
phase: "pull-request",
|
|
129
|
+
operation: "github-partial-issue",
|
|
130
|
+
round: 2,
|
|
131
|
+
},
|
|
132
|
+
capability: "github",
|
|
133
|
+
method: "partial-issue",
|
|
134
|
+
target: "run-1",
|
|
135
|
+
units: 1,
|
|
136
|
+
payload: JSON.stringify({
|
|
137
|
+
owner: "acme",
|
|
138
|
+
repository: "demo",
|
|
139
|
+
number: 42,
|
|
140
|
+
pullRequest: 7,
|
|
141
|
+
remaining: ["Add recovery.", "Verify restart."],
|
|
142
|
+
}),
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
]);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
await test("CLV-221 queued partial work preserves broker failures and budget refusals", async () => {
|
|
149
|
+
const input = {
|
|
150
|
+
cycleId: "run-1",
|
|
151
|
+
round: 4,
|
|
152
|
+
issue: { owner: "acme", repository: "demo", number: 42 },
|
|
153
|
+
pullRequest: 7,
|
|
154
|
+
remaining: ["Add recovery."],
|
|
155
|
+
};
|
|
156
|
+
for (const kind of [
|
|
157
|
+
"failed",
|
|
158
|
+
"stopped",
|
|
159
|
+
"blocked",
|
|
160
|
+
"cancelled",
|
|
161
|
+
"refused",
|
|
162
|
+
"unavailable",
|
|
163
|
+
] as const) {
|
|
164
|
+
const failure = { kind, operationId: "update", reason: "update-failed" };
|
|
165
|
+
using bridge = fakeStepBridge({
|
|
166
|
+
effects: { "github partial-issue": [failure] },
|
|
167
|
+
});
|
|
168
|
+
assert.deepEqual(await queuePartial(input), failure);
|
|
169
|
+
assert.equal(bridge.requests.length, 1);
|
|
170
|
+
}
|
|
171
|
+
using bridge = fakeStepBridge({ effectLimit: 0 });
|
|
172
|
+
assert.deepEqual(await queuePartial(input), {
|
|
173
|
+
kind: "refused",
|
|
174
|
+
reason: "budget-exhausted",
|
|
175
|
+
});
|
|
176
|
+
assert.equal(bridge.spent, 0);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
await test("CLV-221 the template develops a ticket through the public step bridge", async () => {
|
|
180
|
+
const completed = {
|
|
181
|
+
kind: "completed" as const,
|
|
182
|
+
operationId: "turn-1",
|
|
183
|
+
receipt: null,
|
|
184
|
+
result: JSON.stringify({ summary: "Implemented the ticket." }),
|
|
185
|
+
};
|
|
186
|
+
using bridge = fakeStepBridge({ turn: completed });
|
|
187
|
+
const result = await developTurn({
|
|
188
|
+
cycleId: "run-1",
|
|
189
|
+
repository: "main-checkout",
|
|
190
|
+
ticket: "# Fix the counter\n\nPreserve its value after restart.",
|
|
191
|
+
round: 1,
|
|
192
|
+
feedback: null,
|
|
193
|
+
});
|
|
194
|
+
assert.deepEqual(result, completed);
|
|
195
|
+
assert.equal(bridge.requests.length, 1);
|
|
196
|
+
const request = bridge.requests[0];
|
|
197
|
+
assert.ok(request && request[0] === "effect");
|
|
198
|
+
assert.deepEqual(request[1].scope, {
|
|
199
|
+
phase: "implement",
|
|
200
|
+
operation: "claude-turn",
|
|
201
|
+
round: 1,
|
|
202
|
+
});
|
|
203
|
+
assert.equal(request[1].capability, "claude");
|
|
204
|
+
assert.equal(request[1].method, "run-turn");
|
|
205
|
+
assert.equal(request[1].target, "run-1");
|
|
206
|
+
assert.equal(request[1].units, 1);
|
|
207
|
+
assert.match(request[1].payload, /Preserve its value after restart\./);
|
|
208
|
+
assert.match(request[1].payload, /main-checkout/);
|
|
209
|
+
assert.match(request[1].payload, /Do not push/);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
await test("CLV-221 task text reaches the development turn without a ticket lookup", async () => {
|
|
213
|
+
using bridge = fakeStepBridge({});
|
|
214
|
+
await developTurn({
|
|
215
|
+
cycleId: "text-run",
|
|
216
|
+
repository: "main-checkout",
|
|
217
|
+
prompt: "Add an export for the parser.",
|
|
218
|
+
round: 1,
|
|
219
|
+
feedback: null,
|
|
220
|
+
});
|
|
221
|
+
assert.equal(bridge.requests.length, 1);
|
|
222
|
+
const request = bridge.requests[0];
|
|
223
|
+
assert.ok(request && request[0] === "effect");
|
|
224
|
+
assert.equal(request[1].method, "run-turn");
|
|
225
|
+
assert.match(request[1].payload, /Add an export for the parser\./);
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
for (const reason of ["check-failed", "merge-conflict", "ci-failed"]) {
|
|
229
|
+
await test(`CLV-221 a fix turn receives the full ${reason} output`, async () => {
|
|
230
|
+
const output =
|
|
231
|
+
"First diagnostic\n\n expected: 4\n actual: 3\nLast diagnostic\n";
|
|
232
|
+
using bridge = fakeStepBridge({});
|
|
233
|
+
await developTurn({
|
|
234
|
+
cycleId: "run-1",
|
|
235
|
+
repository: "main-checkout",
|
|
236
|
+
ticket: "Fix the counter.",
|
|
237
|
+
round: 2,
|
|
238
|
+
feedback: { reason, output, remaining: ["Add the restart test."] },
|
|
239
|
+
});
|
|
240
|
+
const request = bridge.requests[0];
|
|
241
|
+
assert.ok(request && request[0] === "effect");
|
|
242
|
+
assert.equal(request[1].scope.round, 2);
|
|
243
|
+
assert.match(request[1].payload, /Fix the counter\./);
|
|
244
|
+
assert.ok(request[1].payload.includes(reason));
|
|
245
|
+
assert.ok(request[1].payload.endsWith(output));
|
|
246
|
+
assert.match(request[1].payload, /- Add the restart test\./);
|
|
247
|
+
assert.match(request[1].payload, /round 2/);
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
await test("CLV-221 invalid turn inputs never dispatch a worker", async () => {
|
|
252
|
+
using bridge = fakeStepBridge({});
|
|
253
|
+
const common = {
|
|
254
|
+
cycleId: "run-1",
|
|
255
|
+
repository: "main-checkout",
|
|
256
|
+
round: 1,
|
|
257
|
+
feedback: null,
|
|
258
|
+
};
|
|
259
|
+
for (const task of [
|
|
260
|
+
{},
|
|
261
|
+
{ ticket: "" },
|
|
262
|
+
{ prompt: " \n" },
|
|
263
|
+
{ ticket: "Ticket", prompt: "Task" },
|
|
264
|
+
])
|
|
265
|
+
await assert.rejects(developTurn({ ...common, ...task }), {
|
|
266
|
+
message: "invalid-development-task",
|
|
267
|
+
});
|
|
268
|
+
for (const round of [0, -1, 1.5, 5, NaN, Infinity])
|
|
269
|
+
await assert.rejects(developTurn({ ...common, ticket: "Ticket", round }), {
|
|
270
|
+
message: "invalid-development-round",
|
|
271
|
+
});
|
|
272
|
+
assert.deepEqual(bridge.requests, []);
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
await test("CLV-221 the last allowed fix turn preserves a broker refusal", async () => {
|
|
276
|
+
using bridge = fakeStepBridge({ effectLimit: 0 });
|
|
277
|
+
const result = await developTurn({
|
|
278
|
+
cycleId: "run-1",
|
|
279
|
+
repository: "main-checkout",
|
|
280
|
+
ticket: "Fix the counter.",
|
|
281
|
+
round: 4,
|
|
282
|
+
feedback: { reason: "check-failed", output: "", remaining: [] },
|
|
283
|
+
});
|
|
284
|
+
assert.deepEqual(result, { kind: "refused", reason: "budget-exhausted" });
|
|
285
|
+
assert.equal(bridge.requests.length, 1);
|
|
286
|
+
assert.equal(bridge.spent, 0);
|
|
287
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { CycleOutcome } from "cloving/workflows";
|
|
2
|
+
import {
|
|
3
|
+
ticketInput,
|
|
4
|
+
type DevelopInput,
|
|
5
|
+
type DevelopFeedback,
|
|
6
|
+
} from "./develop/report.ts";
|
|
7
|
+
import { preparePull, labelTicket } from "./develop/pull.ts";
|
|
8
|
+
import { developRound } from "./develop/round.ts";
|
|
9
|
+
|
|
10
|
+
export async function develop(request: DevelopInput): Promise<CycleOutcome> {
|
|
11
|
+
"use workflow";
|
|
12
|
+
const input = ticketInput(request);
|
|
13
|
+
await preparePull(input.cycleId);
|
|
14
|
+
await labelTicket(input, { key: "start", round: 1 });
|
|
15
|
+
let endingRound = 1;
|
|
16
|
+
let feedback: DevelopFeedback | null = null;
|
|
17
|
+
let outcome: CycleOutcome | null = null;
|
|
18
|
+
for (let round = 1; round <= 4; round += 1) {
|
|
19
|
+
if (outcome === null) {
|
|
20
|
+
endingRound = round;
|
|
21
|
+
const next = await developRound({ input, round, feedback });
|
|
22
|
+
if ("kind" in next) outcome = next;
|
|
23
|
+
else feedback = next;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (outcome === null) throw new Error("development-round-limit");
|
|
27
|
+
if (outcome.kind === "blocked")
|
|
28
|
+
await labelTicket(input, { key: "blocked", round: endingRound });
|
|
29
|
+
return outcome;
|
|
30
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"name": "develop",
|
|
4
|
+
"summary": "Develop a ticket or task with explicit choices for selection, acceptance, merge and partial work. The first option at each point is the hands-off default.",
|
|
5
|
+
"points": [
|
|
6
|
+
{
|
|
7
|
+
"id": "input",
|
|
8
|
+
"question": "What should the workflow develop?",
|
|
9
|
+
"options": [
|
|
10
|
+
{
|
|
11
|
+
"id": "ticket",
|
|
12
|
+
"label": "A ticket",
|
|
13
|
+
"summary": "Resolve a ticket through the configured ticket command.",
|
|
14
|
+
"change": "In develop.declaration.json, set workflow.input.fields to { \"ticket\": { \"type\": \"ticket\" } }. In develop.ts use ticketInput(request) from develop/report.ts to pass the resolved ticket text to the turn.",
|
|
15
|
+
"requires": {},
|
|
16
|
+
"needs": ["ticket-command"]
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "task-text",
|
|
20
|
+
"label": "A task text",
|
|
21
|
+
"summary": "Develop the submitted prompt without a ticket lookup.",
|
|
22
|
+
"change": "In develop.declaration.json, set workflow.input.fields to { \"prompt\": { \"type\": \"string\" } }. In develop.ts replace ticketInput with promptInput in the import and call. promptInput(request) passes the submitted text without a ticket lookup.",
|
|
23
|
+
"requires": {
|
|
24
|
+
"select": ["person"],
|
|
25
|
+
"partial": ["person"]
|
|
26
|
+
},
|
|
27
|
+
"needs": []
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"id": "select",
|
|
33
|
+
"question": "Who selects the next ticket or task?",
|
|
34
|
+
"options": [
|
|
35
|
+
{
|
|
36
|
+
"id": "queue",
|
|
37
|
+
"label": "The queue",
|
|
38
|
+
"summary": "Select a ready ticket through the configured next-ticket command.",
|
|
39
|
+
"change": "In develop.declaration.json, set workflow.queue to true (\"queue\": true).",
|
|
40
|
+
"requires": {
|
|
41
|
+
"input": ["ticket"]
|
|
42
|
+
},
|
|
43
|
+
"needs": ["next-command", "queue-interval"]
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"id": "person",
|
|
47
|
+
"label": "A person",
|
|
48
|
+
"summary": "A person submits the ticket or task when starting a run.",
|
|
49
|
+
"change": "In develop.declaration.json, remove the workflow.queue field.",
|
|
50
|
+
"requires": {},
|
|
51
|
+
"needs": []
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"id": "accept",
|
|
57
|
+
"question": "Who accepts the developed work?",
|
|
58
|
+
"options": [
|
|
59
|
+
{
|
|
60
|
+
"id": "greptile",
|
|
61
|
+
"label": "Greptile at 5/5",
|
|
62
|
+
"summary": "Open or update the pull request and wait for Greptile to accept its commit at 5/5.",
|
|
63
|
+
"change": "In develop/accept.ts call reviewByAgent({ subject, reviewer: { kind: \"greptile\" } }). develop/round.ts opens or updates the pull request first and passes its immutable commit and target as subject. Declare github wait-review.",
|
|
64
|
+
"requires": {
|
|
65
|
+
"merge": ["person", "green"]
|
|
66
|
+
},
|
|
67
|
+
"needs": ["gh-login", "github-origin", "greptile-review"]
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"id": "person",
|
|
71
|
+
"label": "A person",
|
|
72
|
+
"summary": "Wait for a person's approval of the immutable commit. Denial with feedback requests another bounded turn.",
|
|
73
|
+
"change": "In develop/accept.ts replace the import and call with reviewByPerson({ subject }). Remove reviewer and github wait-review from the declaration. develop/local.ts already uses reviewByPerson with the clean full commit from the worker report and the run target.",
|
|
74
|
+
"requires": {},
|
|
75
|
+
"needs": []
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"id": "turn",
|
|
79
|
+
"label": "A review turn",
|
|
80
|
+
"summary": "Run the review profile and require its explicit accept verdict.",
|
|
81
|
+
"change": "In develop/accept.ts call reviewByAgent({ subject, reviewer: { kind: \"turn\", profile: \"review\" } }). For local merge replace reviewByPerson in develop/local.ts with that same call and its import. Declare claude run-turn:review and configure the review profile. Remove github wait-review from the declaration.",
|
|
82
|
+
"requires": {},
|
|
83
|
+
"needs": ["default-harness"]
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"id": "merge",
|
|
89
|
+
"question": "Who merges the accepted work?",
|
|
90
|
+
"options": [
|
|
91
|
+
{
|
|
92
|
+
"id": "green",
|
|
93
|
+
"label": "Cloving after the checks",
|
|
94
|
+
"summary": "Open or update a pull request and merge after acceptance, the beforeMerge check and CI. Pass result.output into a fix turn on failure.",
|
|
95
|
+
"change": "Call mergeWhenGreen({ pull, check: \"beforeMerge\" }) after acceptance. Use the pull returned by opening the pull request. Give the result.output to the next fix turn.",
|
|
96
|
+
"requires": {},
|
|
97
|
+
"needs": ["gh-login", "github-origin", "check-command"]
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"id": "person",
|
|
101
|
+
"label": "A person approves Cloving's merge",
|
|
102
|
+
"summary": "Open or update a pull request, wait for merge approval, then run the beforeMerge check and CI before merging.",
|
|
103
|
+
"change": "In develop/round.ts replace the mergeWhenGreen import and call with mergeByPerson({ pull, check: \"beforeMerge\", round }). Use the pull returned by openPull. repair passes the result.output unchanged to the next fix turn.",
|
|
104
|
+
"requires": {},
|
|
105
|
+
"needs": ["gh-login", "github-origin", "check-command"]
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"id": "local",
|
|
109
|
+
"label": "A person merges the local branch",
|
|
110
|
+
"summary": "Leave the accepted branch for a person to merge by hand. Do not push or open a pull request.",
|
|
111
|
+
"change": "In develop.ts import localRound as developRound from develop/local.ts. Remove the develop/pull.ts import, preparePull, both labelTicket calls and endingRound. The local round reviews the worker report commit, then returns the local branch outcome. Declare only claude capabilities and run-turn methods; include run-turn:review when selected. Do not push or open a pull request.",
|
|
112
|
+
"requires": {
|
|
113
|
+
"accept": ["person", "turn"],
|
|
114
|
+
"partial": ["person"]
|
|
115
|
+
},
|
|
116
|
+
"needs": []
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"id": "partial",
|
|
122
|
+
"question": "What happens when the work is partial?",
|
|
123
|
+
"options": [
|
|
124
|
+
{
|
|
125
|
+
"id": "queue",
|
|
126
|
+
"label": "Return the ticket to the queue",
|
|
127
|
+
"summary": "After merging partial work, record the remaining work and set cloving: ready for the first two partial runs. Set cloving: blocked from the third. Stop a run after three fix rounds.",
|
|
128
|
+
"change": "After a merged result, call protectedEffect with capability: \"github\", method: \"partial-issue\", and a payload containing owner, repository, number, pullRequest and remaining. Use an explicit scope with phase, operation and round. The GitHub worker records the partial run and applies ready or blocked.",
|
|
129
|
+
"requires": {
|
|
130
|
+
"input": ["ticket"],
|
|
131
|
+
"select": ["queue"],
|
|
132
|
+
"merge": ["person", "green"]
|
|
133
|
+
},
|
|
134
|
+
"needs": [
|
|
135
|
+
"gh-login",
|
|
136
|
+
"github-origin",
|
|
137
|
+
"ticket-command",
|
|
138
|
+
"next-command",
|
|
139
|
+
"queue-interval"
|
|
140
|
+
]
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"id": "person",
|
|
144
|
+
"label": "A person decides",
|
|
145
|
+
"summary": "Ask what to do with partial work. Use the answer as feedback for a bounded continuation, or stop and leave it for the person.",
|
|
146
|
+
"change": "For a pull-request workflow, in develop/round.ts import partialChoice from develop/partial-choice.ts. Immediately after developReport, call partialChoice({ input, round, report }) and return any non-null result. develop/local.ts already does this. The helper calls waitForDecision({ gateId: partialGateId, kind: \"question\", prompt: partialQuestion }); an explicit answer feeds the next bounded turn and an empty answer stops.",
|
|
147
|
+
"requires": {},
|
|
148
|
+
"needs": []
|
|
149
|
+
}
|
|
150
|
+
]
|
|
151
|
+
}
|
|
152
|
+
]
|
|
153
|
+
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import type { AnalysisResult } from "./analysis-contract.ts";
|
|
2
|
-
import { type AnalysisSnapshot } from "./analysis-input.ts";
|
|
3
|
-
import { type AnalysisBatchContext } from "./analysis-prompt.ts";
|
|
4
|
-
export interface AnalysisBatchPosition {
|
|
5
|
-
readonly nextRecordIndex: number;
|
|
6
|
-
readonly completedBatchCount: number;
|
|
7
|
-
readonly previousResult: AnalysisResult | null;
|
|
8
|
-
}
|
|
9
|
-
export interface AnalysisBatch {
|
|
10
|
-
readonly kind: "batch";
|
|
11
|
-
readonly batchIndex: number;
|
|
12
|
-
readonly firstRecordIndex: number;
|
|
13
|
-
readonly nextRecordIndex: number;
|
|
14
|
-
readonly totalRecords: number;
|
|
15
|
-
readonly snapshot: AnalysisSnapshot;
|
|
16
|
-
readonly prompt: string;
|
|
17
|
-
readonly launchBytes: number;
|
|
18
|
-
readonly adapterDocument: string;
|
|
19
|
-
readonly context: AnalysisBatchContext;
|
|
20
|
-
}
|
|
21
|
-
export type AnalysisBatchPreparation = AnalysisBatch | {
|
|
22
|
-
readonly kind: "refused";
|
|
23
|
-
readonly code: "analysis-input-refused" | "analysis-too-large" | "analysis-batch-limit";
|
|
24
|
-
};
|
|
25
|
-
export declare const analysisCaptureBytes = 52428800;
|
|
26
|
-
export declare function analysisBatchData(batch: AnalysisBatch, capture: {
|
|
27
|
-
readonly digest: string;
|
|
28
|
-
readonly snapshot?: AnalysisSnapshot;
|
|
29
|
-
}): {
|
|
30
|
-
snapshot: AnalysisSnapshot;
|
|
31
|
-
context?: never;
|
|
32
|
-
batch?: never;
|
|
33
|
-
} | {
|
|
34
|
-
snapshot: AnalysisSnapshot;
|
|
35
|
-
context: AnalysisBatchContext;
|
|
36
|
-
batch: {
|
|
37
|
-
batchIndex: number;
|
|
38
|
-
nextRecordIndex: number;
|
|
39
|
-
capturedDigest: string;
|
|
40
|
-
};
|
|
41
|
-
};
|
|
42
|
-
export declare function prepareAnalysisBatch(snapshot: AnalysisSnapshot, position: AnalysisBatchPosition): AnalysisBatchPreparation;
|