cloving 1.3.0 → 1.5.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 +329 -215
- package/dist/src/agent-harness-shell.d.ts +2 -1
- package/dist/src/agent-harness-shell.js +8 -5
- package/dist/src/authority/command-wait-checks.d.ts +8 -0
- package/dist/src/authority/command-wait-checks.js +88 -0
- package/dist/src/authority/command-wait-results.d.ts +15 -0
- package/dist/src/authority/command-wait-results.js +73 -0
- package/dist/src/authority/command-wait-view.d.ts +21 -0
- package/dist/src/authority/command-wait-view.js +34 -0
- package/dist/src/authority/command-waits.d.ts +39 -0
- package/dist/src/authority/command-waits.js +97 -0
- package/dist/src/authority/commands.js +22 -1
- package/dist/src/authority/dispatch-decision.d.ts +8 -0
- package/dist/src/authority/dispatch-decision.js +26 -1
- package/dist/src/authority/effect-requests.js +6 -3
- package/dist/src/authority/effect-results.js +4 -2
- package/dist/src/authority/history-state.d.ts +2 -0
- package/dist/src/authority/history-state.js +13 -1
- package/dist/src/authority/instants.d.ts +1 -0
- package/dist/src/authority/instants.js +21 -0
- package/dist/src/authority/reduction-state.d.ts +2 -0
- package/dist/src/authority/reduction-state.js +5 -0
- package/dist/src/authority/reduction.js +24 -0
- package/dist/src/authority/status-input.d.ts +2 -0
- package/dist/src/authority/status.d.ts +2 -0
- package/dist/src/authority/status.js +1 -0
- package/dist/src/authority/stop-sequence.d.ts +1 -0
- package/dist/src/authority/stop-sequence.js +2 -1
- package/dist/src/authority/transitions.d.ts +6 -4
- package/dist/src/authority/transitions.js +7 -0
- package/dist/src/broker/actor/authority-health.d.ts +9 -0
- package/dist/src/broker/actor/authority-health.js +24 -0
- package/dist/src/broker/actor/authority-queries.d.ts +2 -1
- package/dist/src/broker/actor/authority-queries.js +14 -5
- package/dist/src/broker/actor/authority-receipts.js +1 -1
- package/dist/src/broker/actor/authority-runtime.d.ts +4 -2
- package/dist/src/broker/actor/authority-runtime.js +29 -20
- package/dist/src/broker/actor/authority-session.d.ts +6 -19
- package/dist/src/broker/actor/authority-session.js +66 -88
- package/dist/src/broker/actor/authority-settings.d.ts +2 -1
- package/dist/src/broker/actor/authority-settings.js +6 -3
- package/dist/src/broker/actor/authority-upgrades.d.ts +23 -2
- package/dist/src/broker/actor/authority-upgrades.js +8 -2
- package/dist/src/broker/actor/authority-watchdog.d.ts +6 -2
- package/dist/src/broker/actor/authority-watchdog.js +31 -9
- package/dist/src/broker/actor/authority.js +3 -1
- package/dist/src/broker/actor/delivery-intents.js +2 -0
- package/dist/src/broker/actor/effect-delivery.d.ts +1 -1
- package/dist/src/broker/actor/effect-delivery.js +15 -2
- package/dist/src/broker/actor/effect-plan.js +11 -2
- package/dist/src/broker/actor/effect-queries.d.ts +4 -0
- package/dist/src/broker/actor/effect-queries.js +9 -1
- package/dist/src/broker/actor/effect-turn.js +2 -0
- package/dist/src/broker/actor/projection-memory.d.ts +43 -0
- package/dist/src/broker/actor/projection-memory.js +207 -0
- package/dist/src/broker/actor/runtime-parts.d.ts +5 -0
- package/dist/src/broker/actor/runtime-parts.js +8 -3
- package/dist/src/broker/actor/stop-plan.js +9 -3
- package/dist/src/broker/actor/stop-turn.d.ts +2 -0
- package/dist/src/broker/actor/stop-turn.js +24 -11
- package/dist/src/broker/actor/turn-draft.d.ts +1 -0
- package/dist/src/broker/actor/turn-draft.js +4 -0
- package/dist/src/broker/actor/turn-state.js +5 -1
- package/dist/src/broker/authority-admission.js +60 -0
- package/dist/src/broker/authority-restore.d.ts +2 -0
- package/dist/src/broker/authority-restore.js +35 -1
- package/dist/src/broker/command-wait-restore.d.ts +31 -0
- package/dist/src/broker/command-wait-restore.js +86 -0
- package/dist/src/broker/decision-restore.d.ts +1 -1
- package/dist/src/broker/decision-restore.js +1 -0
- package/dist/src/broker/effect-upgrade.d.ts +3 -0
- package/dist/src/broker/effect-upgrade.js +11 -2
- package/dist/src/cli/arguments.d.ts +13 -0
- package/dist/src/cli/arguments.js +43 -3
- package/dist/src/cli/chat-stores.d.ts +2 -0
- package/dist/src/cli/chat-stores.js +113 -0
- package/dist/src/cli/client.d.ts +7 -2
- package/dist/src/cli/client.js +13 -7
- package/dist/src/cli/command-requests.d.ts +46 -0
- package/dist/src/cli/command-requests.js +84 -0
- package/dist/src/cli/command-waits.d.ts +9 -0
- package/dist/src/cli/command-waits.js +51 -0
- package/dist/src/cli/commands.js +70 -88
- package/dist/src/cli/config-file.d.ts +2 -2
- package/dist/src/cli/config-file.js +4 -2
- package/dist/src/cli/config-notice.js +5 -2
- package/dist/src/cli/doctor-retention.d.ts +2 -0
- package/dist/src/cli/doctor-retention.js +93 -0
- package/dist/src/cli/doctor-workflows.d.ts +5 -2
- package/dist/src/cli/doctor-workflows.js +12 -7
- package/dist/src/cli/doctor.js +11 -9
- package/dist/src/cli/harness-probes.d.ts +2 -0
- package/dist/src/cli/harness-probes.js +1 -1
- package/dist/src/cli/harness-processes.d.ts +6 -0
- package/dist/src/cli/harness-processes.js +36 -0
- package/dist/src/cli/init-command.d.ts +9 -0
- package/dist/src/cli/init-command.js +52 -0
- package/dist/src/cli/init-prompt-command.d.ts +10 -0
- package/dist/src/cli/init-prompt-command.js +145 -0
- package/dist/src/cli/init-prompt.d.ts +35 -0
- package/dist/src/cli/init-prompt.js +74 -0
- package/dist/src/cli/init-selection.d.ts +13 -0
- package/dist/src/cli/init-selection.js +75 -0
- package/dist/src/cli/main.d.ts +2 -0
- package/dist/src/cli/main.js +37 -7
- package/dist/src/cli/mcp-server.d.ts +1 -0
- package/dist/src/cli/mcp-server.js +156 -0
- package/dist/src/cli/mcp-tools.d.ts +15 -0
- package/dist/src/cli/mcp-tools.js +242 -0
- package/dist/src/cli/queue-arguments.d.ts +15 -0
- package/dist/src/cli/queue-arguments.js +31 -0
- package/dist/src/cli/queue-render.d.ts +3 -0
- package/dist/src/cli/queue-render.js +26 -0
- package/dist/src/cli/reload-render.d.ts +2 -0
- package/dist/src/cli/reload-render.js +12 -0
- package/dist/src/cli/render.d.ts +1 -1
- package/dist/src/cli/render.js +54 -38
- package/dist/src/cli/report-ci-jobs.d.ts +23 -0
- package/dist/src/cli/report-ci-jobs.js +103 -0
- package/dist/src/cli/report-ci-usage.d.ts +9 -0
- package/dist/src/cli/report-ci-usage.js +185 -0
- package/dist/src/cli/report-ci.d.ts +13 -0
- package/dist/src/cli/report-ci.js +74 -0
- package/dist/src/cli/report-closures.d.ts +6 -0
- package/dist/src/cli/report-closures.js +97 -0
- package/dist/src/cli/report-flow.d.ts +7 -0
- package/dist/src/cli/report-flow.js +122 -0
- package/dist/src/cli/report-github-reader.d.ts +29 -0
- package/dist/src/cli/report-github-reader.js +157 -0
- package/dist/src/cli/report-github.d.ts +15 -8
- package/dist/src/cli/report-github.js +131 -150
- package/dist/src/cli/report-operator.d.ts +3 -0
- package/dist/src/cli/report-operator.js +40 -0
- package/dist/src/cli/report-ready.d.ts +3 -0
- package/dist/src/cli/report-ready.js +96 -0
- package/dist/src/cli/report-text.d.ts +9 -0
- package/dist/src/cli/report-text.js +33 -0
- package/dist/src/cli/report.d.ts +1 -0
- package/dist/src/cli/report.js +104 -27
- package/dist/src/cli/runtime-arguments.d.ts +18 -3
- package/dist/src/cli/runtime-arguments.js +29 -20
- package/dist/src/cli/schedule-arguments.d.ts +14 -0
- package/dist/src/cli/schedule-arguments.js +26 -0
- package/dist/src/cli/schedule-render.d.ts +22 -0
- package/dist/src/cli/schedule-render.js +73 -0
- package/dist/src/cli/terminal-text.d.ts +3 -0
- package/dist/src/cli/terminal-text.js +28 -0
- package/dist/src/cli/toolchain.d.ts +1 -0
- package/dist/src/cli/toolchain.js +1 -0
- package/dist/src/cli/usage-render.d.ts +1 -0
- package/dist/src/cli/usage-render.js +28 -1
- package/dist/src/cli/usage.d.ts +2 -2
- package/dist/src/cli/usage.js +89 -11
- package/dist/src/cli/watch-actions.js +2 -2
- package/dist/src/cli/watch-api-document.d.ts +430 -0
- package/dist/src/cli/watch-api-document.js +291 -0
- package/dist/src/cli/watch-api-run.d.ts +56 -0
- package/dist/src/cli/watch-api-run.js +112 -0
- package/dist/src/cli/watch-api.d.ts +17 -0
- package/dist/src/cli/watch-api.js +230 -0
- package/dist/src/cli/watch-board-view.js +19 -2
- package/dist/src/cli/watch-board.d.ts +4 -2
- package/dist/src/cli/watch-board.js +53 -43
- package/dist/src/cli/watch-card-forms.d.ts +1 -1
- package/dist/src/cli/watch-card-forms.js +11 -10
- package/dist/src/cli/watch-client.d.ts +1 -1
- package/dist/src/cli/watch-client.js +2 -11
- package/dist/src/cli/watch-header-view.d.ts +1 -5
- package/dist/src/cli/watch-header-view.js +17 -21
- package/dist/src/cli/watch-model.d.ts +5 -1
- package/dist/src/cli/watch-model.js +20 -11
- package/dist/src/cli/watch-page.js +15 -15
- package/dist/src/cli/watch-phases.d.ts +12 -3
- package/dist/src/cli/watch-phases.js +68 -11
- package/dist/src/cli/watch-pr-board.js +1 -1
- package/dist/src/cli/watch-pr-command.d.ts +1 -0
- package/dist/src/cli/watch-pull-request.js +18 -8
- package/dist/src/cli/watch-reads.d.ts +3 -0
- package/dist/src/cli/watch-reads.js +22 -20
- package/dist/src/cli/watch-render.d.ts +15 -0
- package/dist/src/cli/watch-run-input.d.ts +0 -1
- package/dist/src/cli/watch-run-input.js +0 -13
- package/dist/src/cli/watch-server.js +24 -10
- package/dist/src/cli/watch-view.d.ts +0 -3
- package/dist/src/cli/watch-view.js +13 -13
- package/dist/src/cli.js +73 -12
- package/dist/src/command-wait.d.ts +4 -0
- package/dist/src/command-wait.js +45 -0
- package/dist/src/configuration-change.d.ts +7 -0
- package/dist/src/configuration-change.js +14 -0
- package/dist/src/configuration-display.js +2 -0
- package/dist/src/configuration-schema.d.ts +14 -0
- package/dist/src/configuration-schema.js +6 -2
- package/dist/src/daemon/attachment-file.d.ts +6 -0
- package/dist/src/daemon/attachment-file.js +86 -0
- package/dist/src/daemon/attachments.d.ts +14 -0
- package/dist/src/daemon/attachments.js +17 -0
- package/dist/src/daemon/claude-recovery.d.ts +50 -0
- package/dist/src/daemon/claude-recovery.js +208 -0
- package/dist/src/daemon/claude-stream.d.ts +27 -0
- package/dist/src/daemon/claude-stream.js +63 -0
- package/dist/src/daemon/claude-turn.d.ts +11 -25
- package/dist/src/daemon/claude-turn.js +64 -81
- package/dist/src/daemon/claude-worker.d.ts +5 -4
- package/dist/src/daemon/claude-worker.js +127 -126
- package/dist/src/daemon/daemon-adapters.d.ts +9 -0
- package/dist/src/daemon/daemon-adapters.js +33 -5
- package/dist/src/daemon/daemon-loops.d.ts +5 -1
- package/dist/src/daemon/daemon-loops.js +18 -10
- package/dist/src/daemon/daemon.js +80 -61
- package/dist/src/daemon/github-attach.d.ts +2 -0
- package/dist/src/daemon/github-attach.js +222 -0
- package/dist/src/daemon/github-calls.js +1 -1
- package/dist/src/daemon/github-ci-filters.d.ts +6 -0
- package/dist/src/daemon/github-ci-filters.js +138 -0
- package/dist/src/daemon/github-ci-workflows.d.ts +10 -0
- package/dist/src/daemon/github-ci-workflows.js +148 -0
- package/dist/src/daemon/github-ci.js +22 -4
- package/dist/src/daemon/github-issue-methods.d.ts +2 -0
- package/dist/src/daemon/github-issue-methods.js +37 -2
- package/dist/src/daemon/github-merge-call.d.ts +2 -1
- package/dist/src/daemon/github-merge-call.js +10 -3
- package/dist/src/daemon/github-merge.js +52 -24
- package/dist/src/daemon/github-methods.js +18 -4
- package/dist/src/daemon/github-operation.d.ts +4 -0
- package/dist/src/daemon/github-operation.js +6 -0
- package/dist/src/daemon/github-worker.d.ts +4 -0
- package/dist/src/daemon/github-worker.js +6 -0
- package/dist/src/daemon/issue-queue.d.ts +4 -1
- package/dist/src/daemon/issue-queue.js +76 -78
- package/dist/src/daemon/merge-turns.d.ts +10 -0
- package/dist/src/daemon/merge-turns.js +37 -0
- package/dist/src/daemon/notify-events.d.ts +6 -0
- package/dist/src/daemon/notify-events.js +84 -0
- package/dist/src/daemon/notify-journal.js +1 -1
- package/dist/src/daemon/notify-message.d.ts +4 -1
- package/dist/src/daemon/notify-message.js +36 -0
- package/dist/src/daemon/notify.d.ts +1 -1
- package/dist/src/daemon/notify.js +5 -77
- package/dist/src/daemon/operation-journal.d.ts +1 -0
- package/dist/src/daemon/queue-control.d.ts +13 -0
- package/dist/src/daemon/queue-control.js +86 -0
- package/dist/src/daemon/queue-journal.d.ts +20 -0
- package/dist/src/daemon/queue-journal.js +89 -0
- package/dist/src/daemon/queue-status.d.ts +9 -3
- package/dist/src/daemon/queue-status.js +17 -4
- package/dist/src/daemon/record-archive.d.ts +19 -0
- package/dist/src/daemon/record-archive.js +82 -0
- package/dist/src/daemon/record-sweep.d.ts +24 -0
- package/dist/src/daemon/record-sweep.js +147 -0
- package/dist/src/daemon/resume-index-lock.d.ts +13 -0
- package/dist/src/daemon/resume-index-lock.js +160 -0
- package/dist/src/daemon/resume-worktree.d.ts +7 -0
- package/dist/src/daemon/resume-worktree.js +29 -0
- package/dist/src/daemon/retrying-turn.d.ts +2 -12
- package/dist/src/daemon/retrying-turn.js +98 -172
- package/dist/src/daemon/schedule-control.d.ts +26 -0
- package/dist/src/daemon/schedule-control.js +110 -0
- package/dist/src/daemon/schedule-journal.d.ts +2 -15
- package/dist/src/daemon/schedule-journal.js +67 -4
- package/dist/src/daemon/settings-reload.d.ts +26 -0
- package/dist/src/daemon/settings-reload.js +82 -0
- package/dist/src/daemon/ticket-registration.d.ts +2 -7
- package/dist/src/daemon/ticket-registration.js +15 -81
- package/dist/src/daemon/turn-attempt-journal.d.ts +38 -0
- package/dist/src/daemon/turn-attempt-journal.js +136 -0
- package/dist/src/daemon/turn-attempts.d.ts +47 -0
- package/dist/src/daemon/turn-attempts.js +166 -0
- package/dist/src/daemon/turn-details.d.ts +4 -0
- package/dist/src/daemon/turn-details.js +33 -0
- package/dist/src/daemon/turn-report.d.ts +8 -1
- package/dist/src/daemon/turn-report.js +39 -0
- package/dist/src/daemon/work-tree.d.ts +9 -0
- package/dist/src/daemon/work-tree.js +20 -0
- package/dist/src/daemon/worker-profile.d.ts +9 -0
- package/dist/src/daemon/worker-profile.js +44 -0
- package/dist/src/daemon/workflow-generations.d.ts +7 -4
- package/dist/src/daemon/workflow-generations.js +22 -14
- package/dist/src/daemon/workflow-reload.d.ts +41 -0
- package/dist/src/daemon/workflow-reload.js +244 -0
- package/dist/src/daemon/workflow-replay.d.ts +2 -1
- package/dist/src/daemon/workflow-replay.js +7 -3
- package/dist/src/daemon/workflow-schedules.d.ts +3 -0
- package/dist/src/daemon/workflow-schedules.js +98 -45
- package/dist/src/daemon/worktree-processes.d.ts +9 -0
- package/dist/src/daemon/worktree-processes.js +151 -0
- package/dist/src/doctor-report.d.ts +4 -6
- package/dist/src/doctor-report.js +8 -13
- package/dist/src/harness-start.d.ts +15 -0
- package/dist/src/harness-start.js +37 -0
- package/dist/src/host/command-wait.d.ts +38 -0
- package/dist/src/host/command-wait.js +115 -0
- package/dist/src/host/start-delivery.d.ts +5 -7
- package/dist/src/host/start-delivery.js +3 -15
- package/dist/src/host/step-bridge-host.d.ts +2 -0
- package/dist/src/host/step-bridge-host.js +21 -0
- package/dist/src/operation-identity.d.ts +1 -0
- package/dist/src/operation-identity.js +4 -0
- package/dist/src/private-config.schema.json +71 -0
- package/dist/src/project-config.schema.json +40 -0
- package/dist/src/project-settings.d.ts +16 -2
- package/dist/src/project-settings.js +35 -1
- package/dist/src/queue-spend.d.ts +4 -0
- package/dist/src/queue-spend.js +21 -0
- package/dist/src/queue-state.d.ts +26 -0
- package/dist/src/queue-state.js +34 -0
- package/dist/src/record-retention.d.ts +46 -0
- package/dist/src/record-retention.js +81 -0
- package/dist/src/relay/relay-service.d.ts +3 -0
- package/dist/src/relay/relay-service.js +5 -3
- package/dist/src/report-ci.d.ts +164 -0
- package/dist/src/report-ci.js +32 -0
- package/dist/src/report-effects.d.ts +15 -0
- package/dist/src/report-effects.js +212 -0
- package/dist/src/report-flow-types.d.ts +38 -0
- package/dist/src/report-flow-types.js +7 -0
- package/dist/src/report-flow.d.ts +43 -0
- package/dist/src/report-flow.js +193 -0
- package/dist/src/report-operator.d.ts +67 -0
- package/dist/src/report-operator.js +25 -0
- package/dist/src/report-quality.d.ts +221 -0
- package/dist/src/report-quality.js +94 -0
- package/dist/src/report-ready.d.ts +23 -0
- package/dist/src/report-ready.js +117 -0
- package/dist/src/report-statistics.d.ts +2 -1
- package/dist/src/report-statistics.js +40 -4
- package/dist/src/report.d.ts +588 -47
- package/dist/src/report.js +156 -41
- package/dist/src/schedule-progress.d.ts +33 -0
- package/dist/src/schedule-progress.js +45 -0
- package/dist/src/service/active-tickets.js +11 -6
- package/dist/src/service/command-waits.d.ts +34 -0
- package/dist/src/service/command-waits.js +86 -0
- package/dist/src/service/dispatcher.d.ts +4 -0
- package/dist/src/service/dispatcher.js +33 -0
- package/dist/src/service/expiry.js +2 -0
- package/dist/src/service/gateway.js +3 -1
- package/dist/src/service/queue-handlers.d.ts +4 -0
- package/dist/src/service/queue-handlers.js +32 -0
- package/dist/src/service/queue-spend.d.ts +6 -0
- package/dist/src/service/queue-spend.js +68 -0
- package/dist/src/service/registry.d.ts +28 -2
- package/dist/src/service/registry.js +48 -0
- package/dist/src/service/replies.d.ts +22 -8
- package/dist/src/service/replies.js +16 -2
- package/dist/src/service/run-handlers.js +37 -12
- package/dist/src/service/run-metadata.d.ts +15 -1
- package/dist/src/service/run-metadata.js +93 -8
- package/dist/src/service/service.d.ts +11 -3
- package/dist/src/service/service.js +22 -37
- package/dist/src/service/submission-handler.js +18 -4
- package/dist/src/service/worker-port.js +9 -1
- package/dist/src/service/worker-totals.d.ts +6 -0
- package/dist/src/service/worker-totals.js +8 -1
- package/dist/src/service/workflow-reload.d.ts +35 -0
- package/dist/src/service/workflow-reload.js +52 -0
- package/dist/src/step-bridge.d.ts +20 -0
- package/dist/src/steps/command-wait.d.ts +12 -0
- package/dist/src/steps/command-wait.js +26 -0
- package/dist/src/steps/open-decision-wait.d.ts +2 -0
- package/dist/src/steps/{decision-gate.js → open-decision-wait.js} +0 -7
- package/dist/src/steps/review-by-person.js +4 -1
- package/dist/src/steps/wait-for-command.d.ts +3 -0
- package/dist/src/steps/wait-for-command.js +17 -0
- package/dist/src/steps/wait-for-decision.js +1 -1
- package/dist/src/storage/command-wait-rows.d.ts +30 -0
- package/dist/src/storage/command-wait-rows.js +96 -0
- package/dist/src/storage/decision-snapshots.d.ts +8 -2
- package/dist/src/storage/decision-snapshots.js +16 -8
- package/dist/src/storage/domain-changes.d.ts +3 -1
- package/dist/src/storage/domain-changes.js +4 -0
- package/dist/src/storage/domain-schema.d.ts +16 -1
- package/dist/src/storage/domain-schema.js +35 -4
- package/dist/src/storage/effect-schema.d.ts +2 -0
- package/dist/src/storage/effect-schema.js +9 -0
- package/dist/src/storage/projection-changes.d.ts +12 -0
- package/dist/src/storage/projection-changes.js +194 -0
- package/dist/src/storage/projection-lookups.d.ts +7 -0
- package/dist/src/storage/projection-lookups.js +30 -0
- package/dist/src/testing-requests.d.ts +15 -0
- package/dist/src/testing-requests.js +93 -0
- package/dist/src/testing.d.ts +4 -10
- package/dist/src/testing.js +33 -86
- package/dist/src/worker-usage.d.ts +1 -0
- package/dist/src/worker-usage.js +3 -0
- package/dist/src/workflow-candidate.d.ts +1 -0
- package/dist/src/workflow-candidate.js +12 -1
- package/dist/src/workflow-contracts.d.ts +1 -0
- package/dist/src/workflow-contracts.js +9 -2
- package/dist/src/workflow-declaration.d.ts +1 -0
- package/dist/src/workflow-declaration.js +3 -0
- package/dist/src/workflow-discovery.d.ts +2 -13
- package/dist/src/workflow-discovery.js +1 -13
- package/dist/src/workflow-refusals.js +0 -1
- package/dist/src/workflows.d.ts +1 -1
- package/dist/src/workflows.js +1 -1
- package/dist/tools/compile-workflows.js +3 -0
- package/dist/tools/project-configuration.d.ts +7 -2
- package/dist/tools/project-configuration.js +30 -1
- package/dist/tools/red-green-command.d.ts +1 -0
- package/dist/tools/red-green-command.js +174 -0
- package/dist/tools/red-green-process.d.ts +10 -0
- package/dist/tools/red-green-process.js +59 -0
- package/dist/tools/self-host-processes.d.ts +2 -0
- package/dist/tools/self-host-processes.js +69 -26
- package/dist/tools/self-host-project.d.ts +2 -0
- package/dist/tools/self-host-project.js +30 -77
- package/dist/tools/self-host-runtime.js +1 -1
- package/dist/tools/self-host.js +76 -34
- package/dist/tools/template-command.d.ts +1 -0
- package/dist/tools/template-command.js +160 -0
- package/dist/tools/template-copy.d.ts +11 -0
- package/dist/tools/template-copy.js +130 -0
- package/dist/tools/template-files.d.ts +17 -0
- package/dist/tools/template-files.js +74 -0
- package/dist/tools/workflow-bundles.js +1 -0
- package/dist/tools/workflow-candidate-counts.js +2 -2
- package/dist/tools/workflow-candidate-program.d.ts +4 -2
- package/dist/tools/workflow-candidate-program.js +30 -11
- package/dist/tools/workflow-candidate-shape.d.ts +3 -0
- package/dist/tools/workflow-candidate-shape.js +90 -0
- package/dist/tools/workflow-candidate-source.d.ts +1 -0
- package/dist/tools/workflow-candidate-source.js +26 -4
- package/dist/tools/workflow-candidate-syntax.d.ts +2 -2
- package/dist/tools/workflow-candidate-syntax.js +24 -94
- package/dist/tools/workflow-command.js +1 -2
- package/dist/tools/workflow-folders.d.ts +2 -3
- package/dist/tools/workflow-folders.js +1 -1
- package/package.json +17 -9
- package/templates/develop/README.md +93 -4
- package/templates/develop/develop/flow-tests.ts +38 -1
- package/templates/develop/develop/interruption-tests.ts +157 -0
- package/templates/develop/develop/local.ts +1 -0
- package/templates/develop/develop/option-tests.ts +138 -9
- package/templates/develop/develop/pull.ts +5 -1
- package/templates/develop/develop/red-green.ts +55 -0
- package/templates/develop/develop/refusal-tests.ts +77 -0
- package/templates/develop/develop/report.ts +31 -11
- package/templates/develop/develop/round.ts +1 -0
- package/templates/develop/develop/scenarios.ts +27 -0
- package/templates/develop/develop/turn.ts +28 -7
- package/templates/develop/develop.declaration.json +1 -1
- package/templates/develop/develop.test.ts +4 -0
- package/templates/develop/template.json +29 -2
- package/templates/idea-to-issue/README.md +27 -0
- package/templates/idea-to-issue/idea-to-issue/effects.ts +52 -0
- package/templates/idea-to-issue/idea-to-issue/leave.ts +10 -0
- package/templates/idea-to-issue/idea-to-issue/next.ts +29 -0
- package/templates/idea-to-issue/idea-to-issue/post-person.ts +18 -0
- package/templates/idea-to-issue/idea-to-issue/post.ts +50 -0
- package/templates/idea-to-issue/idea-to-issue/queue.ts +27 -0
- package/templates/idea-to-issue/idea-to-issue/review.ts +42 -0
- package/templates/idea-to-issue/idea-to-issue/scenarios.ts +50 -0
- package/templates/idea-to-issue/idea-to-issue/turn.ts +40 -0
- package/templates/idea-to-issue/idea-to-issue.declaration.json +16 -0
- package/templates/idea-to-issue/idea-to-issue.test.ts +79 -0
- package/templates/idea-to-issue/idea-to-issue.ts +49 -0
- package/templates/idea-to-issue/template.json +81 -0
- package/templates/review-day/README.md +97 -0
- package/templates/review-day/review-day/critique.ts +58 -0
- package/templates/review-day/review-day/decision.ts +29 -0
- package/templates/review-day/review-day/facts.ts +69 -0
- package/templates/review-day/review-day/label.ts +29 -0
- package/templates/review-day/review-day/next.ts +28 -0
- package/templates/review-day/review-day/post.ts +27 -0
- package/templates/review-day/review-day/report.ts +98 -0
- package/templates/review-day/review-day/rules.ts +12 -0
- package/templates/review-day/review-day/scenarios.ts +76 -0
- package/templates/review-day/review-day/turn.ts +73 -0
- package/templates/review-day/review-day.declaration.json +16 -0
- package/templates/review-day/review-day.test.ts +362 -0
- package/templates/review-day/review-day.ts +37 -0
- package/templates/review-day/template.json +56 -0
- package/dist/src/cli/watch-start-view.d.ts +0 -18
- package/dist/src/cli/watch-start-view.js +0 -77
- package/dist/src/steps/decision-gate.d.ts +0 -3
- package/dist/workflows/develop-prd.d.ts +0 -7
- package/dist/workflows/develop-prd.js +0 -165
- package/dist/workflows/develop-ticket.d.ts +0 -9
- package/dist/workflows/develop-ticket.js +0 -207
- package/dist/workflows/issue-labels.d.ts +0 -16
- package/dist/workflows/issue-labels.js +0 -70
- package/dist/workflows/ticket-prompts.d.ts +0 -35
- package/dist/workflows/ticket-prompts.js +0 -147
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import {
|
|
3
|
+
fakeStepBridge,
|
|
4
|
+
type ScenarioRequest,
|
|
5
|
+
} from "cloving/workflows/testing";
|
|
6
|
+
import { develop } from "../develop.ts";
|
|
7
|
+
import {
|
|
8
|
+
approved,
|
|
9
|
+
callName,
|
|
10
|
+
completeCalls,
|
|
11
|
+
requestInput,
|
|
12
|
+
scenarioEffects,
|
|
13
|
+
} from "./option-tests.ts";
|
|
14
|
+
import { developReport, ticketInput } from "./report.ts";
|
|
15
|
+
import { completed, input } from "./scenarios.ts";
|
|
16
|
+
|
|
17
|
+
const interrupted = {
|
|
18
|
+
kind: "failed" as const,
|
|
19
|
+
operationId: "interrupted-turn",
|
|
20
|
+
reason: "claude-turn-interrupted",
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
function turns(requests: readonly ScenarioRequest[]) {
|
|
24
|
+
return requests.flatMap((request) =>
|
|
25
|
+
request[0] === "effect" && request[1].method === "run-turn"
|
|
26
|
+
? [request[1]]
|
|
27
|
+
: [],
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const interruptionTests = [
|
|
32
|
+
{
|
|
33
|
+
name: "CLV-272 an interrupted turn runs again once in the same work tree",
|
|
34
|
+
run: async () => {
|
|
35
|
+
const scenario = scenarioEffects();
|
|
36
|
+
using bridge = fakeStepBridge({
|
|
37
|
+
effects: {
|
|
38
|
+
...scenario,
|
|
39
|
+
"claude run-turn": [interrupted, ...scenario["claude run-turn"]],
|
|
40
|
+
},
|
|
41
|
+
decisions: [approved, approved],
|
|
42
|
+
});
|
|
43
|
+
assert.equal((await develop(requestInput())).kind, "handoff_requested");
|
|
44
|
+
const expected = completeCalls();
|
|
45
|
+
expected.splice(expected.indexOf("run-turn"), 0, "run-turn");
|
|
46
|
+
assert.deepEqual(bridge.requests.map(callName), expected);
|
|
47
|
+
const [first, second] = turns(bridge.requests);
|
|
48
|
+
assert.ok(first && second);
|
|
49
|
+
assert.deepEqual(first.scope, {
|
|
50
|
+
phase: "implement",
|
|
51
|
+
operation: "claude-turn",
|
|
52
|
+
round: 1,
|
|
53
|
+
});
|
|
54
|
+
assert.ok(!first.payload.includes("stopped before its report"));
|
|
55
|
+
assert.deepEqual(second.scope, {
|
|
56
|
+
phase: "implement",
|
|
57
|
+
operation: "claude-turn",
|
|
58
|
+
round: 1,
|
|
59
|
+
key: "continuation",
|
|
60
|
+
});
|
|
61
|
+
assert.equal(second.target, first.target);
|
|
62
|
+
assert.ok(second.payload.endsWith(first.payload));
|
|
63
|
+
for (const sentence of [
|
|
64
|
+
"The earlier turn of round 1 stopped before its report.",
|
|
65
|
+
"The work tree holds the work of that turn.",
|
|
66
|
+
"Before you continue, check the work tree, the commits since the start of the round, and the ticket.",
|
|
67
|
+
])
|
|
68
|
+
assert.ok(second.payload.includes(sentence), sentence);
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: "CLV-272 a second interruption of the same turn blocks the run",
|
|
73
|
+
run: async () => {
|
|
74
|
+
using bridge = fakeStepBridge({
|
|
75
|
+
effects: {
|
|
76
|
+
...scenarioEffects(),
|
|
77
|
+
"claude run-turn": [interrupted, interrupted],
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
assert.deepEqual(await develop(requestInput()), {
|
|
81
|
+
kind: "blocked",
|
|
82
|
+
cycleId: requestInput().cycleId,
|
|
83
|
+
reason: "turn-interrupted",
|
|
84
|
+
evidenceId: "implement",
|
|
85
|
+
});
|
|
86
|
+
assert.deepEqual(bridge.requests.map(callName), stoppedCalls());
|
|
87
|
+
const labels = bridge.requests.flatMap((request) =>
|
|
88
|
+
request[0] === "effect" && request[1].method === "label"
|
|
89
|
+
? [request[1].payload]
|
|
90
|
+
: [],
|
|
91
|
+
);
|
|
92
|
+
for (const payload of labels.slice(1))
|
|
93
|
+
assert.match(payload, /"add":\["cloving: blocked"\]/);
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: "CLV-272 an interrupted fix turn continues with its round and feedback",
|
|
98
|
+
run: async () => {
|
|
99
|
+
using bridge = fakeStepBridge({
|
|
100
|
+
effects: {
|
|
101
|
+
"claude run-turn": [
|
|
102
|
+
interrupted,
|
|
103
|
+
completed({ summary: "Fixed.\nTicket status: complete" }),
|
|
104
|
+
],
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
const output = "Check output.\n";
|
|
108
|
+
const report = await developReport({
|
|
109
|
+
input: ticketInput(input),
|
|
110
|
+
round: 2,
|
|
111
|
+
feedback: { reason: "check-failed", output, remaining: ["Add it."] },
|
|
112
|
+
});
|
|
113
|
+
assert.ok(!("kind" in report));
|
|
114
|
+
assert.equal(report.summary, "Fixed.\nTicket status: complete");
|
|
115
|
+
const [first, second] = turns(bridge.requests);
|
|
116
|
+
assert.ok(first && second);
|
|
117
|
+
assert.equal(first.scope.round, 2);
|
|
118
|
+
assert.equal(second.scope.round, 2);
|
|
119
|
+
assert.equal(second.scope.key, "continuation");
|
|
120
|
+
assert.ok(
|
|
121
|
+
second.payload.startsWith(
|
|
122
|
+
"The earlier turn of round 2 stopped before its report.",
|
|
123
|
+
),
|
|
124
|
+
);
|
|
125
|
+
assert.ok(second.payload.endsWith(first.payload));
|
|
126
|
+
assert.ok(second.payload.endsWith(output));
|
|
127
|
+
assert.match(
|
|
128
|
+
second.payload,
|
|
129
|
+
/This is fix round 2\. Address check-failed/,
|
|
130
|
+
);
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
...[
|
|
134
|
+
{ kind: "failed" as const, operationId: "turn", reason: "worker-failed" },
|
|
135
|
+
{ kind: "refused" as const, reason: "budget-exhausted" },
|
|
136
|
+
].map((failure) => ({
|
|
137
|
+
name: `CLV-272 a ${failure.reason} continuation fails the run`,
|
|
138
|
+
run: async () => {
|
|
139
|
+
using bridge = fakeStepBridge({
|
|
140
|
+
effects: {
|
|
141
|
+
...scenarioEffects(),
|
|
142
|
+
"claude run-turn": [interrupted, failure],
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
await assert.rejects(develop(requestInput()), {
|
|
146
|
+
message: failure.reason,
|
|
147
|
+
});
|
|
148
|
+
assert.deepEqual(bridge.requests.map(callName), stoppedCalls());
|
|
149
|
+
},
|
|
150
|
+
})),
|
|
151
|
+
];
|
|
152
|
+
|
|
153
|
+
function stoppedCalls(): string[] {
|
|
154
|
+
const complete = completeCalls();
|
|
155
|
+
const started = complete.slice(0, complete.indexOf("run-turn") + 1);
|
|
156
|
+
return started.concat("run-turn", started.includes("label") ? ["label"] : []);
|
|
157
|
+
}
|
|
@@ -13,6 +13,7 @@ export async function localRound(
|
|
|
13
13
|
): Promise<CycleOutcome | DevelopFeedback> {
|
|
14
14
|
const { input, round } = state;
|
|
15
15
|
const report = await developReport(state);
|
|
16
|
+
if ("kind" in report) return report;
|
|
16
17
|
const partial = await partialChoice({ input, round, report });
|
|
17
18
|
if (partial !== null) return partial;
|
|
18
19
|
if (
|
|
@@ -4,12 +4,20 @@ import {
|
|
|
4
4
|
type ScenarioRequest,
|
|
5
5
|
} from "cloving/workflows/testing";
|
|
6
6
|
import { develop } from "../develop.ts";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
commit,
|
|
9
|
+
input,
|
|
10
|
+
completed,
|
|
11
|
+
effects,
|
|
12
|
+
selection,
|
|
13
|
+
repairVerdicts,
|
|
14
|
+
verificationEffects,
|
|
15
|
+
} from "./scenarios.ts";
|
|
8
16
|
|
|
9
17
|
const taskText =
|
|
10
18
|
"Develop the submitted task text.\n\nGitHub issue: acme/demo#42 (open)";
|
|
11
19
|
|
|
12
|
-
function requestInput() {
|
|
20
|
+
export function requestInput() {
|
|
13
21
|
return selection.input === "ticket"
|
|
14
22
|
? input
|
|
15
23
|
: {
|
|
@@ -19,7 +27,7 @@ function requestInput() {
|
|
|
19
27
|
};
|
|
20
28
|
}
|
|
21
29
|
|
|
22
|
-
function scenarioEffects() {
|
|
30
|
+
export function scenarioEffects() {
|
|
23
31
|
return {
|
|
24
32
|
...effects(),
|
|
25
33
|
"claude run-turn": [
|
|
@@ -33,10 +41,13 @@ function scenarioEffects() {
|
|
|
33
41
|
completed({ summary: "Reviewed.", reviewVerdict: "accept" }),
|
|
34
42
|
],
|
|
35
43
|
"github partial-issue": [completed({ ticketStatus: "partial" })],
|
|
44
|
+
"command run:red-green": [
|
|
45
|
+
completed({ verdict: "accepted", output: "Passed." }),
|
|
46
|
+
],
|
|
36
47
|
};
|
|
37
48
|
}
|
|
38
49
|
|
|
39
|
-
function completeCalls(): string[] {
|
|
50
|
+
export function completeCalls(): string[] {
|
|
40
51
|
const review: Readonly<Record<string, string>> = {
|
|
41
52
|
greptile: "wait-review",
|
|
42
53
|
person: "approval",
|
|
@@ -46,15 +57,17 @@ function completeCalls(): string[] {
|
|
|
46
57
|
if (selection.merge === "local") return acceptance;
|
|
47
58
|
return ["prepare"].concat(
|
|
48
59
|
selection.input === "ticket" ? ["label"] : [],
|
|
49
|
-
["run-turn", "open-pr"
|
|
60
|
+
["run-turn", "open-pr"],
|
|
61
|
+
selection.verify === "red-green" ? ["run:red-green"] : [],
|
|
62
|
+
[review[selection.accept] ?? "unknown-review"],
|
|
50
63
|
selection.merge === "person" ? ["approval", "merge"] : ["merge"],
|
|
51
64
|
selection.input === "ticket" ? ["close-issue"] : [],
|
|
52
65
|
);
|
|
53
66
|
}
|
|
54
67
|
|
|
55
|
-
const approved = { decision: "approved" as const, answer: null };
|
|
68
|
+
export const approved = { decision: "approved" as const, answer: null };
|
|
56
69
|
|
|
57
|
-
function callName(request: ScenarioRequest): string {
|
|
70
|
+
export function callName(request: ScenarioRequest): string {
|
|
58
71
|
if (request[0] === "effect") return request[1].method;
|
|
59
72
|
if (request[0] === "waitForDecision") return request[1].kind;
|
|
60
73
|
return request[0];
|
|
@@ -67,7 +80,7 @@ export const optionTests = [
|
|
|
67
80
|
using bridge = fakeStepBridge({
|
|
68
81
|
effects: scenarioEffects(),
|
|
69
82
|
decisions: [approved, approved],
|
|
70
|
-
effectLimit:
|
|
83
|
+
effectLimit: selection.verify === "red-green" ? 35 : 31,
|
|
71
84
|
});
|
|
72
85
|
assert.deepEqual(await develop(requestInput()), {
|
|
73
86
|
kind: "handoff_requested",
|
|
@@ -171,4 +184,120 @@ export const optionTests = [
|
|
|
171
184
|
assert.equal(updates.length, Number(selection.partial === "queue"));
|
|
172
185
|
},
|
|
173
186
|
},
|
|
174
|
-
];
|
|
187
|
+
].concat(selection.verify === "red-green" ? verificationTests() : []);
|
|
188
|
+
|
|
189
|
+
function verificationTests() {
|
|
190
|
+
return repairTests().concat(passingTests(), unavailableTests(), limitTests());
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function repairTests() {
|
|
194
|
+
return repairVerdicts.map((verdict) => ({
|
|
195
|
+
name: `CLV-249 ${verdict} starts a fix turn with the full tool output`,
|
|
196
|
+
run: async () => {
|
|
197
|
+
using bridge = fakeStepBridge({
|
|
198
|
+
effects: verificationEffects([verdict, "accepted"]),
|
|
199
|
+
decisions: [approved, approved],
|
|
200
|
+
effectLimit: 35,
|
|
201
|
+
});
|
|
202
|
+
assert.equal((await develop(requestInput())).kind, "handoff_requested");
|
|
203
|
+
const expected = completeCalls();
|
|
204
|
+
expected.splice(
|
|
205
|
+
expected.indexOf("run:red-green") + 1,
|
|
206
|
+
0,
|
|
207
|
+
"run-turn",
|
|
208
|
+
"open-pr",
|
|
209
|
+
"run:red-green",
|
|
210
|
+
);
|
|
211
|
+
assert.deepEqual(bridge.requests.map(callName), expected);
|
|
212
|
+
const fix = bridge.requests.find(
|
|
213
|
+
(request) =>
|
|
214
|
+
request[0] === "effect" &&
|
|
215
|
+
request[1].method === "run-turn" &&
|
|
216
|
+
request[1].scope.round === 2,
|
|
217
|
+
);
|
|
218
|
+
assert.ok(fix && fix[0] === "effect");
|
|
219
|
+
assert.ok(fix[1].payload.includes(`Address ${verdict}`));
|
|
220
|
+
assert.ok(fix[1].payload.endsWith(`${verdict}\nFull test output.`));
|
|
221
|
+
},
|
|
222
|
+
}));
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function passingTests() {
|
|
226
|
+
return ["accepted", "no-test-change"].map((verdict) => ({
|
|
227
|
+
name: `CLV-249 ${verdict} continues to review and merge`,
|
|
228
|
+
run: async () => {
|
|
229
|
+
using bridge = fakeStepBridge({
|
|
230
|
+
effects: verificationEffects([verdict]),
|
|
231
|
+
decisions: [approved, approved],
|
|
232
|
+
});
|
|
233
|
+
assert.equal((await develop(requestInput())).kind, "handoff_requested");
|
|
234
|
+
assert.deepEqual(bridge.requests.map(callName), completeCalls());
|
|
235
|
+
},
|
|
236
|
+
}));
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function limitTests() {
|
|
240
|
+
return [
|
|
241
|
+
{
|
|
242
|
+
name: "CLV-249 verification repairs stop after four development rounds",
|
|
243
|
+
run: async () => {
|
|
244
|
+
using bridge = fakeStepBridge({
|
|
245
|
+
effects: verificationEffects(Array(4).fill("false-red")),
|
|
246
|
+
effectLimit: 35,
|
|
247
|
+
});
|
|
248
|
+
assert.deepEqual(await develop(requestInput()), {
|
|
249
|
+
kind: "blocked",
|
|
250
|
+
cycleId: input.cycleId,
|
|
251
|
+
reason: "false-red",
|
|
252
|
+
evidenceId: "merge",
|
|
253
|
+
});
|
|
254
|
+
const names = bridge.requests.map(callName);
|
|
255
|
+
assert.equal(names.filter((name) => name === "run-turn").length, 4);
|
|
256
|
+
assert.equal(
|
|
257
|
+
names.filter((name) => name === "run:red-green").length,
|
|
258
|
+
4,
|
|
259
|
+
);
|
|
260
|
+
assert.ok(!names.includes("wait-review") && !names.includes("merge"));
|
|
261
|
+
},
|
|
262
|
+
},
|
|
263
|
+
];
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function unavailableTests() {
|
|
267
|
+
const unavailable = [
|
|
268
|
+
completed({
|
|
269
|
+
verdict: "prepare-failed",
|
|
270
|
+
output: "Dependency preparation failed.",
|
|
271
|
+
}),
|
|
272
|
+
{ kind: "failed" as const, operationId: "command", reason: "exit-1" },
|
|
273
|
+
{ kind: "unavailable" as const, reason: "cloving-host-unavailable" },
|
|
274
|
+
{ ...completed(null), result: "invalid JSON" },
|
|
275
|
+
completed(null),
|
|
276
|
+
completed({ verdict: "unknown", output: "Unknown verdict." }),
|
|
277
|
+
completed({ verdict: "accepted" }),
|
|
278
|
+
completed({ verdict: "false-red", output: 42 }),
|
|
279
|
+
];
|
|
280
|
+
return unavailable.map((result, index) => ({
|
|
281
|
+
name: `CLV-249 unavailable verification ${String(index)} blocks without a fix turn`,
|
|
282
|
+
run: async () => {
|
|
283
|
+
using bridge = fakeStepBridge({
|
|
284
|
+
effects: {
|
|
285
|
+
...verificationEffects(["accepted"]),
|
|
286
|
+
"command run:red-green": [result],
|
|
287
|
+
},
|
|
288
|
+
});
|
|
289
|
+
assert.deepEqual(await develop(requestInput()), {
|
|
290
|
+
kind: "blocked",
|
|
291
|
+
cycleId: input.cycleId,
|
|
292
|
+
reason: "red-green-unavailable",
|
|
293
|
+
evidenceId: "red-green",
|
|
294
|
+
});
|
|
295
|
+
const complete = completeCalls();
|
|
296
|
+
const expected = complete.slice(0, complete.indexOf("run:red-green") + 1);
|
|
297
|
+
assert.deepEqual(
|
|
298
|
+
bridge.requests.map(callName),
|
|
299
|
+
expected.concat(selection.input === "ticket" ? ["label"] : []),
|
|
300
|
+
);
|
|
301
|
+
},
|
|
302
|
+
}));
|
|
303
|
+
}
|
|
@@ -21,6 +21,7 @@ export async function openPull(request: {
|
|
|
21
21
|
readonly round: number;
|
|
22
22
|
}): Promise<PullRequest> {
|
|
23
23
|
const { input, round } = request;
|
|
24
|
+
const issue = input.issue;
|
|
24
25
|
const result = await protectedEffect({
|
|
25
26
|
scope: { phase: "pull-request", operation: "github-open-pr", round: round },
|
|
26
27
|
capability: "github",
|
|
@@ -30,7 +31,10 @@ export async function openPull(request: {
|
|
|
30
31
|
title: (input.ticket.split("\n")[0] ?? "Develop task")
|
|
31
32
|
.replace(/^#+\s*/, "")
|
|
32
33
|
.slice(0, 200),
|
|
33
|
-
body:
|
|
34
|
+
body:
|
|
35
|
+
issue === null
|
|
36
|
+
? "Cloving made this change for this task."
|
|
37
|
+
: `Refs ${issue.owner}/${issue.repository}#${String(issue.number)}\n\nCloving made this change for the ticket ${String(issue.number)}.`,
|
|
34
38
|
}),
|
|
35
39
|
units: 1,
|
|
36
40
|
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { runCommand } from "cloving/workflows/steps/run-command";
|
|
2
|
+
import type { CycleOutcome } from "cloving/workflows";
|
|
3
|
+
|
|
4
|
+
type VerificationFeedback = {
|
|
5
|
+
readonly reason: string;
|
|
6
|
+
readonly output: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export async function verifyRedGreen(input: {
|
|
10
|
+
readonly cycleId: string;
|
|
11
|
+
readonly head: string;
|
|
12
|
+
readonly round: number;
|
|
13
|
+
}): Promise<CycleOutcome | VerificationFeedback | null> {
|
|
14
|
+
const unavailable: CycleOutcome = {
|
|
15
|
+
kind: "blocked",
|
|
16
|
+
cycleId: input.cycleId,
|
|
17
|
+
reason: "red-green-unavailable",
|
|
18
|
+
evidenceId: "red-green",
|
|
19
|
+
};
|
|
20
|
+
try {
|
|
21
|
+
const result = await runCommand({
|
|
22
|
+
name: "red-green",
|
|
23
|
+
scope: { phase: "verify", operation: "red-green", round: input.round },
|
|
24
|
+
input: { head: input.head },
|
|
25
|
+
});
|
|
26
|
+
if (result.kind !== "completed") return unavailable;
|
|
27
|
+
const feedback = verdictFeedback(result.result);
|
|
28
|
+
return feedback === undefined ? unavailable : feedback;
|
|
29
|
+
} catch {
|
|
30
|
+
return unavailable;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function verdictFeedback(
|
|
35
|
+
text: string | null,
|
|
36
|
+
): VerificationFeedback | null | undefined {
|
|
37
|
+
const value: unknown = JSON.parse(text ?? "null");
|
|
38
|
+
if (
|
|
39
|
+
typeof value !== "object" ||
|
|
40
|
+
value === null ||
|
|
41
|
+
!("verdict" in value) ||
|
|
42
|
+
typeof value.verdict !== "string" ||
|
|
43
|
+
!("output" in value) ||
|
|
44
|
+
typeof value.output !== "string"
|
|
45
|
+
)
|
|
46
|
+
return undefined;
|
|
47
|
+
if (["accepted", "no-test-change"].includes(value.verdict)) return null;
|
|
48
|
+
if (
|
|
49
|
+
["false-red", "red-not-assertion", "skipped-test", "green-failed"].includes(
|
|
50
|
+
value.verdict,
|
|
51
|
+
)
|
|
52
|
+
)
|
|
53
|
+
return { reason: value.verdict, output: value.output };
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
@@ -9,6 +9,83 @@ import { effects } from "./scenarios.ts";
|
|
|
9
9
|
|
|
10
10
|
export const refusalTests: FlowTest[] = [];
|
|
11
11
|
|
|
12
|
+
refusalTests.push({
|
|
13
|
+
name: "CLV-260 a linked pull request names the issue and preserves the ticket title",
|
|
14
|
+
run: async () => {
|
|
15
|
+
using bridge = fakeStepBridge({
|
|
16
|
+
turn: completed({ number: 7, url: "pull/7", commit }),
|
|
17
|
+
});
|
|
18
|
+
await openPull({
|
|
19
|
+
input: {
|
|
20
|
+
cycleId: input.cycleId,
|
|
21
|
+
repository: input.repository,
|
|
22
|
+
ticket:
|
|
23
|
+
"# CLV-228: Stop the registration of the bundled workflows\n\nGitHub issue: cloving-ai/cloving-ai#375 (open)",
|
|
24
|
+
issue: { owner: "cloving-ai", repository: "cloving-ai", number: 375 },
|
|
25
|
+
},
|
|
26
|
+
round: 1,
|
|
27
|
+
});
|
|
28
|
+
assert.equal(bridge.requests.length, 1);
|
|
29
|
+
const opened = bridge.requests[0];
|
|
30
|
+
assert.ok(opened && opened[0] === "effect");
|
|
31
|
+
assert.equal(opened[1].method, "open-pr");
|
|
32
|
+
assert.deepEqual(JSON.parse(opened[1].payload), {
|
|
33
|
+
title: "CLV-228: Stop the registration of the bundled workflows",
|
|
34
|
+
body: "Refs cloving-ai/cloving-ai#375\n\nCloving made this change for the ticket 375.",
|
|
35
|
+
});
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
refusalTests.push({
|
|
40
|
+
name: "CLV-260 a task without an issue opens a pull request without a reference",
|
|
41
|
+
run: async () => {
|
|
42
|
+
using bridge = fakeStepBridge({
|
|
43
|
+
turn: completed({ number: 7, url: "pull/7", commit }),
|
|
44
|
+
});
|
|
45
|
+
await openPull({
|
|
46
|
+
input: {
|
|
47
|
+
cycleId: input.cycleId,
|
|
48
|
+
repository: input.repository,
|
|
49
|
+
ticket: "### Manual task\n\nGitHub issue: acme/demo#42 (open)",
|
|
50
|
+
issue: null,
|
|
51
|
+
},
|
|
52
|
+
round: 1,
|
|
53
|
+
});
|
|
54
|
+
assert.equal(bridge.requests.length, 1);
|
|
55
|
+
const opened = bridge.requests[0];
|
|
56
|
+
assert.ok(opened && opened[0] === "effect");
|
|
57
|
+
assert.equal(opened[1].method, "open-pr");
|
|
58
|
+
assert.deepEqual(JSON.parse(opened[1].payload), {
|
|
59
|
+
title: "Manual task",
|
|
60
|
+
body: "Cloving made this change for this task.",
|
|
61
|
+
});
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
refusalTests.push({
|
|
66
|
+
name: "CLV-260 pull request titles use at most 200 characters from the first line",
|
|
67
|
+
run: async () => {
|
|
68
|
+
using bridge = fakeStepBridge({
|
|
69
|
+
turn: completed({ number: 7, url: "pull/7", commit }),
|
|
70
|
+
});
|
|
71
|
+
await openPull({
|
|
72
|
+
input: {
|
|
73
|
+
cycleId: input.cycleId,
|
|
74
|
+
repository: input.repository,
|
|
75
|
+
ticket: `### ${"Title".repeat(50)}\nSecond line`,
|
|
76
|
+
issue: null,
|
|
77
|
+
},
|
|
78
|
+
round: 1,
|
|
79
|
+
});
|
|
80
|
+
const opened = bridge.requests[0];
|
|
81
|
+
assert.ok(opened && opened[0] === "effect");
|
|
82
|
+
assert.deepEqual(JSON.parse(opened[1].payload), {
|
|
83
|
+
title: "Title".repeat(40),
|
|
84
|
+
body: "Cloving made this change for this task.",
|
|
85
|
+
});
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
|
|
12
89
|
for (const operation of [
|
|
13
90
|
"claude run-turn",
|
|
14
91
|
"github open-pr",
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
type ProtectedResult,
|
|
5
5
|
type TicketStatus,
|
|
6
6
|
} from "cloving/workflows";
|
|
7
|
-
import { developTurn } from "./turn.ts";
|
|
7
|
+
import { developTurn, type DevelopTurnInput } from "./turn.ts";
|
|
8
8
|
|
|
9
9
|
export interface DevelopInput {
|
|
10
10
|
readonly cycleId: string;
|
|
@@ -72,16 +72,36 @@ export interface DevelopState {
|
|
|
72
72
|
|
|
73
73
|
export async function developReport(
|
|
74
74
|
state: DevelopState,
|
|
75
|
-
): Promise<DevelopReport> {
|
|
76
|
-
const
|
|
77
|
-
return reportOf(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
75
|
+
): Promise<DevelopReport | CycleOutcome> {
|
|
76
|
+
const first = await developTurn(turnRequest(state, "initial"));
|
|
77
|
+
if (!interrupted(first)) return reportOf(first);
|
|
78
|
+
const second = await developTurn(turnRequest(state, "continuation"));
|
|
79
|
+
if (!interrupted(second)) return reportOf(second);
|
|
80
|
+
return {
|
|
81
|
+
kind: "blocked",
|
|
82
|
+
cycleId: state.input.cycleId,
|
|
83
|
+
reason: "turn-interrupted",
|
|
84
|
+
evidenceId: "implement",
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function turnRequest(
|
|
89
|
+
state: DevelopState,
|
|
90
|
+
attempt: "initial" | "continuation",
|
|
91
|
+
): DevelopTurnInput {
|
|
92
|
+
return {
|
|
93
|
+
cycleId: state.input.cycleId,
|
|
94
|
+
repository: state.input.repository,
|
|
95
|
+
ticket: state.input.ticket,
|
|
96
|
+
round: state.round,
|
|
97
|
+
attempt,
|
|
98
|
+
feedback: state.feedback,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function interrupted(result: ProtectedResult): boolean {
|
|
103
|
+
return (
|
|
104
|
+
result.kind !== "completed" && result.reason === "claude-turn-interrupted"
|
|
85
105
|
);
|
|
86
106
|
}
|
|
87
107
|
|
|
@@ -13,6 +13,7 @@ export async function developRound(state: {
|
|
|
13
13
|
const { input, round } = state;
|
|
14
14
|
try {
|
|
15
15
|
const report = await developReport(state);
|
|
16
|
+
if ("kind" in report) return report;
|
|
16
17
|
const pull = await openPull({ input, round });
|
|
17
18
|
const subject = {
|
|
18
19
|
target: pull.target,
|
|
@@ -2,6 +2,7 @@ export const commit = "a".repeat(40);
|
|
|
2
2
|
export const selection = {
|
|
3
3
|
input: "ticket",
|
|
4
4
|
select: "queue",
|
|
5
|
+
verify: "none",
|
|
5
6
|
accept: "greptile",
|
|
6
7
|
merge: "green",
|
|
7
8
|
partial: "queue",
|
|
@@ -52,6 +53,32 @@ export function effects() {
|
|
|
52
53
|
};
|
|
53
54
|
}
|
|
54
55
|
|
|
56
|
+
export const repairVerdicts = [
|
|
57
|
+
"false-red",
|
|
58
|
+
"red-not-assertion",
|
|
59
|
+
"skipped-test",
|
|
60
|
+
"green-failed",
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
export function verificationEffects(verdicts: readonly string[]) {
|
|
64
|
+
const scenario = effects();
|
|
65
|
+
return {
|
|
66
|
+
...scenario,
|
|
67
|
+
"claude run-turn": verdicts.map(() =>
|
|
68
|
+
completed({ summary: "Implemented.\nTicket status: complete" }),
|
|
69
|
+
),
|
|
70
|
+
"github open-pr": verdicts.map(() =>
|
|
71
|
+
completed({ number: 7, url: "pull/7", commit }),
|
|
72
|
+
),
|
|
73
|
+
"command run:red-green": verdicts.map((verdict) =>
|
|
74
|
+
completed({ verdict, output: `${verdict}\nFull test output.` }),
|
|
75
|
+
),
|
|
76
|
+
"claude run-turn:review": [
|
|
77
|
+
completed({ summary: "Reviewed.", reviewVerdict: "accept" }),
|
|
78
|
+
],
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
55
82
|
export function partialEffects(
|
|
56
83
|
pullRequest: number,
|
|
57
84
|
remaining: readonly string[],
|