cloving 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +584 -144
- package/assets/watch-fonts/fira-code-OFL.md +93 -0
- package/assets/watch-fonts/fira-code-latin-400-normal.woff2 +0 -0
- package/assets/watch-fonts/fira-code-latin-500-normal.woff2 +0 -0
- package/assets/watch-fonts/heebo-OFL.md +93 -0
- package/assets/watch-fonts/heebo-latin-500-normal.woff2 +0 -0
- package/assets/watch-fonts/heebo-latin-700-normal.woff2 +0 -0
- package/assets/watch-fonts/heebo-latin-800-normal.woff2 +0 -0
- package/assets/watch-fonts/manifest.json +112 -0
- package/assets/watch-fonts/space-grotesk-OFL.md +93 -0
- package/assets/watch-fonts/space-grotesk-latin-400-normal.woff2 +0 -0
- package/assets/watch-fonts/space-grotesk-latin-500-normal.woff2 +0 -0
- package/assets/watch-fonts/space-grotesk-latin-600-normal.woff2 +0 -0
- package/assets/watch-fonts/space-grotesk-latin-700-normal.woff2 +0 -0
- package/dist/src/agent-harness-shell.d.ts +12 -0
- package/dist/src/agent-harness-shell.js +90 -0
- package/dist/src/agent-harness-versions.d.ts +8 -0
- package/dist/src/agent-harness-versions.js +49 -0
- package/dist/src/agent-harnesses.d.ts +4 -0
- package/dist/src/agent-harnesses.js +13 -0
- package/dist/src/authority/commands.d.ts +2 -0
- package/dist/src/authority/commands.js +49 -8
- package/dist/src/authority/dispatch-decision.d.ts +1 -0
- package/dist/src/authority/dispatch-decision.js +7 -4
- package/dist/src/authority/events.js +2 -2
- package/dist/src/authority/gate-reduction.d.ts +1 -0
- package/dist/src/authority/gate-reduction.js +18 -3
- package/dist/src/authority/gates.d.ts +2 -1
- package/dist/src/authority/gates.js +5 -1
- package/dist/src/authority/handoff-chain.d.ts +24 -0
- package/dist/src/authority/handoff-chain.js +46 -0
- package/dist/src/authority/operations.js +1 -1
- package/dist/src/authority/reconciliation.d.ts +1 -0
- package/dist/src/authority/reconciliation.js +18 -11
- package/dist/src/authority/reduction.d.ts +1 -1
- package/dist/src/authority/reduction.js +6 -1
- package/dist/src/authority/status-input.d.ts +1 -1
- package/dist/src/authority/status.d.ts +1 -0
- package/dist/src/authority/status.js +27 -3
- package/dist/src/authority/transitions.d.ts +5 -5
- package/dist/src/authority/transitions.js +9 -0
- package/dist/src/broker/actor/authority-delivery.js +1 -0
- package/dist/src/broker/actor/authority-queries.d.ts +11 -1
- package/dist/src/broker/actor/authority-queries.js +67 -3
- package/dist/src/broker/actor/authority-receipts.js +11 -1
- package/dist/src/broker/actor/authority-session.js +2 -2
- package/dist/src/broker/actor/authority-settings.js +4 -0
- package/dist/src/broker/actor/delivery-intents.d.ts +3 -1
- package/dist/src/broker/actor/delivery-intents.js +4 -4
- package/dist/src/broker/actor/effect-delivery.js +13 -1
- package/dist/src/broker/actor/effect-queries.d.ts +1 -0
- package/dist/src/broker/actor/effect-queries.js +7 -0
- package/dist/src/broker/actor/pin-check.js +1 -1
- package/dist/src/broker/actor/stop-plan.js +1 -1
- package/dist/src/broker/actor/turn-state.js +1 -1
- package/dist/src/broker/authority-admission.js +26 -5
- package/dist/src/broker/authority-restore.js +1 -0
- package/dist/src/broker/decision-restore.js +4 -4
- package/dist/src/broker/socket-address.d.ts +3 -1
- package/dist/src/broker/socket-address.js +2 -2
- package/dist/src/cli/arguments.d.ts +11 -13
- package/dist/src/cli/arguments.js +37 -107
- package/dist/src/cli/command-effects.d.ts +7 -0
- package/dist/src/cli/command-effects.js +39 -0
- package/dist/src/cli/commands.js +11 -4
- package/dist/src/cli/config-arguments.d.ts +11 -0
- package/dist/src/cli/config-arguments.js +59 -0
- package/dist/src/cli/config-command.d.ts +2 -0
- package/dist/src/cli/config-command.js +105 -0
- package/dist/src/cli/config-file.d.ts +3 -0
- package/dist/src/cli/config-file.js +50 -0
- package/dist/src/cli/config-lock.d.ts +7 -0
- package/dist/src/cli/config-lock.js +61 -0
- package/dist/src/cli/config-notice.d.ts +5 -0
- package/dist/src/cli/config-notice.js +46 -0
- package/dist/src/cli/doctor-github.d.ts +9 -0
- package/dist/src/cli/doctor-github.js +138 -0
- package/dist/src/cli/doctor-harness.d.ts +13 -0
- package/dist/src/cli/doctor-harness.js +242 -0
- package/dist/src/cli/doctor-local.d.ts +18 -0
- package/dist/src/cli/doctor-local.js +77 -0
- package/dist/src/cli/doctor-runtime.d.ts +15 -0
- package/dist/src/cli/doctor-runtime.js +176 -0
- package/dist/src/cli/doctor-service.d.ts +1 -0
- package/dist/src/cli/doctor-service.js +11 -0
- package/dist/src/cli/doctor-workflows.d.ts +3 -0
- package/dist/src/cli/doctor-workflows.js +45 -0
- package/dist/src/cli/doctor.d.ts +15 -0
- package/dist/src/cli/doctor.js +190 -0
- package/dist/src/cli/github-ci-progress.d.ts +8 -0
- package/dist/src/cli/github-ci-progress.js +83 -0
- package/dist/src/cli/github-retry.d.ts +6 -0
- package/dist/src/cli/github-retry.js +47 -0
- package/dist/src/cli/harness-probes.d.ts +22 -0
- package/dist/src/cli/harness-probes.js +183 -0
- package/dist/src/cli/main.d.ts +7 -1
- package/dist/src/cli/main.js +39 -61
- package/dist/src/cli/phone-arguments.d.ts +14 -0
- package/dist/src/cli/phone-arguments.js +37 -0
- package/dist/src/cli/phone-client.d.ts +2 -0
- package/dist/src/cli/phone-client.js +32 -0
- package/dist/src/cli/phone-command.d.ts +13 -0
- package/dist/src/cli/phone-command.js +101 -0
- package/dist/src/cli/probe-command.d.ts +36 -0
- package/dist/src/cli/probe-command.js +59 -0
- package/dist/src/cli/project-settings.d.ts +4 -0
- package/dist/src/cli/project-settings.js +33 -0
- package/dist/src/cli/render.d.ts +3 -1
- package/dist/src/cli/render.js +102 -39
- package/dist/src/cli/report-github.d.ts +18 -0
- package/dist/src/cli/report-github.js +200 -0
- package/dist/src/cli/report.d.ts +17 -0
- package/dist/src/cli/report.js +192 -0
- package/dist/src/cli/repository-arguments.d.ts +5 -0
- package/dist/src/cli/repository-arguments.js +34 -0
- package/dist/src/cli/runtime-arguments.d.ts +4 -0
- package/dist/src/cli/runtime-arguments.js +15 -0
- package/dist/src/cli/runtime-directory.d.ts +6 -2
- package/dist/src/cli/runtime-directory.js +72 -14
- package/dist/src/cli/toolchain.d.ts +2 -0
- package/dist/src/cli/toolchain.js +22 -2
- package/dist/src/cli/usage-render.d.ts +5 -0
- package/dist/src/cli/usage-render.js +40 -1
- package/dist/src/cli/usage.d.ts +3 -3
- package/dist/src/cli/usage.js +74 -45
- package/dist/src/cli/watch-actions.d.ts +2 -0
- package/dist/src/cli/watch-actions.js +4 -4
- package/dist/src/cli/watch-board-view.d.ts +12 -1
- package/dist/src/cli/watch-board-view.js +64 -12
- package/dist/src/cli/watch-board.d.ts +7 -1
- package/dist/src/cli/watch-board.js +61 -16
- package/dist/src/cli/watch-card-forms.js +2 -2
- package/dist/src/cli/watch-client.d.ts +1 -1
- package/dist/src/cli/watch-client.js +12 -3
- package/dist/src/cli/watch-header-view.d.ts +27 -0
- package/dist/src/cli/watch-header-view.js +116 -0
- package/dist/src/cli/watch-model.d.ts +10 -4
- package/dist/src/cli/watch-model.js +49 -59
- package/dist/src/cli/watch-page.js +67 -14
- package/dist/src/cli/watch-phases.js +3 -3
- package/dist/src/cli/watch-phone-client.d.ts +1 -0
- package/dist/src/cli/watch-phone-client.js +84 -0
- package/dist/src/cli/watch-phone-view.d.ts +56 -0
- package/dist/src/cli/watch-phone-view.js +113 -0
- package/dist/src/cli/watch-phone.d.ts +5 -0
- package/dist/src/cli/watch-phone.js +53 -0
- package/dist/src/cli/watch-pr-command.d.ts +5 -2
- package/dist/src/cli/watch-pr-command.js +41 -4
- package/dist/src/cli/watch-pr-identity.d.ts +14 -2
- package/dist/src/cli/watch-pr-identity.js +25 -0
- package/dist/src/cli/watch-pr-observer.d.ts +1 -0
- package/dist/src/cli/watch-pr-observer.js +48 -6
- package/dist/src/cli/watch-pull-request.d.ts +12 -0
- package/dist/src/cli/watch-pull-request.js +134 -0
- package/dist/src/cli/watch-reads.d.ts +7 -1
- package/dist/src/cli/watch-reads.js +42 -20
- package/dist/src/cli/watch-render.d.ts +23 -2
- package/dist/src/cli/watch-render.js +2 -1
- package/dist/src/cli/watch-server.js +56 -7
- package/dist/src/cli/watch-turn.d.ts +4 -1
- package/dist/src/cli/watch-turn.js +38 -2
- package/dist/src/cli/watch-usage.js +5 -1
- package/dist/src/cli/watch-view.d.ts +10 -17
- package/dist/src/cli/watch-view.js +33 -77
- package/dist/src/cli.js +106 -23
- package/dist/src/command-settings.d.ts +16 -0
- package/dist/src/command-settings.js +42 -0
- package/dist/src/configuration-change.d.ts +11 -0
- package/dist/src/configuration-change.js +62 -0
- package/dist/src/configuration-display.d.ts +21 -0
- package/dist/src/configuration-display.js +69 -0
- package/dist/src/configuration-schema.d.ts +49 -0
- package/dist/src/configuration-schema.js +159 -0
- package/dist/src/daemon/claude-turn.d.ts +20 -5
- package/dist/src/daemon/claude-turn.js +116 -53
- package/dist/src/daemon/claude-worker.d.ts +3 -5
- package/dist/src/daemon/claude-worker.js +64 -80
- package/dist/src/daemon/command-journal.d.ts +5 -0
- package/dist/src/daemon/command-journal.js +50 -0
- package/dist/src/daemon/command-process.d.ts +28 -0
- package/dist/src/daemon/command-process.js +164 -0
- package/dist/src/daemon/command-worker.d.ts +19 -0
- package/dist/src/daemon/command-worker.js +182 -0
- package/dist/src/daemon/cursor-stream.d.ts +4 -0
- package/dist/src/daemon/cursor-stream.js +154 -0
- package/dist/src/daemon/daemon-adapters.d.ts +58 -0
- package/dist/src/daemon/daemon-adapters.js +102 -0
- package/dist/src/daemon/daemon-loops.d.ts +14 -0
- package/dist/src/daemon/daemon-loops.js +39 -0
- package/dist/src/daemon/daemon.d.ts +3 -30
- package/dist/src/daemon/daemon.js +132 -110
- package/dist/src/daemon/declared-input.d.ts +3 -0
- package/dist/src/daemon/declared-input.js +9 -0
- package/dist/src/daemon/delivery-router.js +7 -1
- package/dist/src/daemon/gemini-stream.d.ts +4 -0
- package/dist/src/daemon/gemini-stream.js +129 -0
- package/dist/src/daemon/github-calls.d.ts +4 -0
- package/dist/src/daemon/github-calls.js +16 -7
- package/dist/src/daemon/github-ci-rerun.d.ts +26 -0
- package/dist/src/daemon/github-ci-rerun.js +92 -0
- package/dist/src/daemon/github-ci.d.ts +6 -0
- package/dist/src/daemon/github-ci.js +251 -0
- package/dist/src/daemon/github-merge-call.d.ts +16 -0
- package/dist/src/daemon/github-merge-call.js +73 -0
- package/dist/src/daemon/github-merge.d.ts +3 -5
- package/dist/src/daemon/github-merge.js +59 -98
- package/dist/src/daemon/github-methods.d.ts +28 -0
- package/dist/src/daemon/github-methods.js +90 -16
- package/dist/src/daemon/github-operation.d.ts +3 -0
- package/dist/src/daemon/github-retry.d.ts +6 -0
- package/dist/src/daemon/github-retry.js +13 -0
- package/dist/src/daemon/github-ticket-status.js +27 -1
- package/dist/src/daemon/github-worker.js +2 -1
- package/dist/src/daemon/handoff-worker.d.ts +10 -0
- package/dist/src/daemon/handoff-worker.js +232 -0
- package/dist/src/daemon/issue-queue.d.ts +2 -0
- package/dist/src/daemon/issue-queue.js +92 -63
- package/dist/src/daemon/notify-journal.d.ts +18 -0
- package/dist/src/daemon/notify-journal.js +108 -0
- package/dist/src/daemon/notify-message.js +2 -1
- package/dist/src/daemon/notify.js +177 -37
- package/dist/src/daemon/opencode-stream.d.ts +5 -0
- package/dist/src/daemon/opencode-stream.js +87 -0
- package/dist/src/daemon/queue-status.d.ts +4 -0
- package/dist/src/daemon/queue-status.js +38 -0
- package/dist/src/daemon/retry-worktree.d.ts +18 -0
- package/dist/src/daemon/retry-worktree.js +139 -0
- package/dist/src/daemon/retrying-turn.d.ts +5 -0
- package/dist/src/daemon/retrying-turn.js +145 -21
- package/dist/src/daemon/schedule-journal.d.ts +19 -0
- package/dist/src/daemon/schedule-journal.js +57 -0
- package/dist/src/daemon/text-output.d.ts +18 -0
- package/dist/src/daemon/text-output.js +44 -0
- package/dist/src/daemon/ticket-dependency-waits.d.ts +18 -0
- package/dist/src/daemon/ticket-dependency-waits.js +60 -0
- package/dist/src/daemon/ticket-registration.d.ts +10 -8
- package/dist/src/daemon/ticket-registration.js +146 -47
- package/dist/src/daemon/ticket-source.d.ts +4 -1
- package/dist/src/daemon/ticket-source.js +8 -2
- package/dist/src/daemon/turn-command.d.ts +10 -0
- package/dist/src/daemon/turn-command.js +33 -0
- package/dist/src/daemon/turn-report.d.ts +18 -0
- package/dist/src/daemon/turn-report.js +79 -0
- package/dist/src/daemon/work-tree.d.ts +2 -1
- package/dist/src/daemon/work-tree.js +15 -12
- package/dist/src/daemon/workflow-generations.d.ts +32 -0
- package/dist/src/daemon/workflow-generations.js +57 -0
- package/dist/src/daemon/workflow-replay.d.ts +16 -0
- package/dist/src/daemon/workflow-replay.js +58 -0
- package/dist/src/daemon/workflow-schedules.d.ts +27 -0
- package/dist/src/daemon/workflow-schedules.js +185 -0
- package/dist/src/decision-visibility.d.ts +2 -0
- package/dist/src/decision-visibility.js +10 -0
- package/dist/src/decision-wait.d.ts +1 -0
- package/dist/src/decision-wait.js +3 -0
- package/dist/src/delivery-backoff.d.ts +1 -0
- package/dist/src/delivery-backoff.js +3 -0
- package/dist/src/doctor-report.d.ts +24 -0
- package/dist/src/doctor-report.js +70 -0
- package/dist/src/execution-pin.d.ts +9 -0
- package/dist/src/execution-pin.js +86 -2
- package/dist/src/grok-result.d.ts +12 -0
- package/dist/src/grok-result.js +61 -0
- package/dist/src/harness-defaults.d.ts +35 -0
- package/dist/src/harness-defaults.js +121 -0
- package/dist/src/host/decision-resume.d.ts +35 -0
- package/dist/src/host/decision-resume.js +86 -0
- package/dist/src/host/gate-bridge.d.ts +48 -0
- package/dist/src/host/gate-bridge.js +124 -0
- package/dist/src/host/run-wait.d.ts +26 -0
- package/dist/src/host/run-wait.js +37 -0
- package/dist/src/host/start-delivery.d.ts +3 -2
- package/dist/src/host/start-delivery.js +11 -4
- package/dist/src/host/step-bridge-host.d.ts +6 -19
- package/dist/src/host/step-bridge-host.js +57 -55
- package/dist/src/host/world-reconciliation.d.ts +1 -0
- package/dist/src/host/world-reconciliation.js +3 -0
- package/dist/src/host/world-runs.js +5 -0
- package/dist/src/issue-identity.d.ts +6 -0
- package/dist/src/issue-identity.js +23 -0
- package/dist/src/merge-request.d.ts +19 -0
- package/dist/src/merge-request.js +32 -0
- package/dist/src/phone/canonical-json.d.ts +1 -0
- package/dist/src/phone/canonical-json.js +16 -0
- package/dist/src/phone/phone-link.d.ts +7 -0
- package/dist/src/phone/phone-link.js +21 -0
- package/dist/src/phone/qr-data.d.ts +8 -0
- package/dist/src/phone/qr-data.js +133 -0
- package/dist/src/phone/qr-matrix.d.ts +6 -0
- package/dist/src/phone/qr-matrix.js +175 -0
- package/dist/src/phone/qr-penalty.d.ts +3 -0
- package/dist/src/phone/qr-penalty.js +67 -0
- package/dist/src/phone/qr-picture.d.ts +5 -0
- package/dist/src/phone/qr-picture.js +24 -0
- package/dist/src/private-config.schema.json +263 -0
- package/dist/src/project-config.schema.json +65 -0
- package/dist/src/project-settings.d.ts +19 -0
- package/dist/src/project-settings.js +131 -0
- package/dist/src/relay/answer-check.d.ts +24 -0
- package/dist/src/relay/answer-check.js +145 -0
- package/dist/src/relay/answer-inbox.d.ts +15 -0
- package/dist/src/relay/answer-inbox.js +173 -0
- package/dist/src/relay/daemon-keys.d.ts +16 -0
- package/dist/src/relay/daemon-keys.js +75 -0
- package/dist/src/relay/decision-check.d.ts +3 -0
- package/dist/src/relay/decision-check.js +77 -0
- package/dist/src/relay/decision-close.d.ts +6 -0
- package/dist/src/relay/decision-close.js +72 -0
- package/dist/src/relay/decision-envelopes.d.ts +29 -0
- package/dist/src/relay/decision-envelopes.js +93 -0
- package/dist/src/relay/decision-watch.d.ts +14 -0
- package/dist/src/relay/decision-watch.js +68 -0
- package/dist/src/relay/envelope-post.d.ts +8 -0
- package/dist/src/relay/envelope-post.js +71 -0
- package/dist/src/relay/envelope.d.ts +28 -0
- package/dist/src/relay/envelope.js +53 -0
- package/dist/src/relay/hpke.d.ts +25 -0
- package/dist/src/relay/hpke.js +108 -0
- package/dist/src/relay/pairing-checks.d.ts +42 -0
- package/dist/src/relay/pairing-checks.js +172 -0
- package/dist/src/relay/pairing-follow.d.ts +8 -0
- package/dist/src/relay/pairing-follow.js +95 -0
- package/dist/src/relay/pairing-session.d.ts +29 -0
- package/dist/src/relay/pairing-session.js +87 -0
- package/dist/src/relay/phone-delivery.d.ts +51 -0
- package/dist/src/relay/phone-delivery.js +139 -0
- package/dist/src/relay/phone-devices.d.ts +36 -0
- package/dist/src/relay/phone-devices.js +46 -0
- package/dist/src/relay/phone-inbox.d.ts +18 -0
- package/dist/src/relay/phone-inbox.js +17 -0
- package/dist/src/relay/phone-operations.d.ts +18 -0
- package/dist/src/relay/phone-operations.js +121 -0
- package/dist/src/relay/phone-outbox.d.ts +21 -0
- package/dist/src/relay/phone-outbox.js +25 -0
- package/dist/src/relay/phone-socket.d.ts +6 -0
- package/dist/src/relay/phone-socket.js +63 -0
- package/dist/src/relay/relay-control.d.ts +7 -0
- package/dist/src/relay/relay-control.js +24 -0
- package/dist/src/relay/relay-files.d.ts +2 -0
- package/dist/src/relay/relay-files.js +23 -0
- package/dist/src/relay/relay-heartbeat.d.ts +17 -0
- package/dist/src/relay/relay-heartbeat.js +81 -0
- package/dist/src/relay/relay-http.d.ts +14 -0
- package/dist/src/relay/relay-http.js +63 -0
- package/dist/src/relay/relay-registration.d.ts +15 -0
- package/dist/src/relay/relay-registration.js +63 -0
- package/dist/src/relay/relay-service.d.ts +25 -0
- package/dist/src/relay/relay-service.js +216 -0
- package/dist/src/relay/relay-store.d.ts +48 -0
- package/dist/src/relay/relay-store.js +131 -0
- package/dist/src/relay/sealed-post.d.ts +25 -0
- package/dist/src/relay/sealed-post.js +52 -0
- package/dist/src/relay.d.ts +1 -0
- package/dist/src/relay.js +8 -0
- package/dist/src/report-statistics.d.ts +50 -0
- package/dist/src/report-statistics.js +70 -0
- package/dist/src/report.d.ts +171 -0
- package/dist/src/report.js +119 -0
- package/dist/src/repository-identity.d.ts +4 -0
- package/dist/src/repository-identity.js +4 -0
- package/dist/src/review-subject.d.ts +41 -0
- package/dist/src/review-subject.js +91 -0
- package/dist/src/run-wait.d.ts +23 -0
- package/dist/src/run-wait.js +20 -0
- package/dist/src/service/active-tickets.d.ts +4 -0
- package/dist/src/service/active-tickets.js +49 -0
- package/dist/src/service/command-effects.d.ts +4 -0
- package/dist/src/service/command-effects.js +16 -0
- package/dist/src/service/decision-handler.d.ts +4 -0
- package/dist/src/service/decision-handler.js +39 -4
- package/dist/src/service/gateway.js +18 -3
- package/dist/src/service/queue-runs.d.ts +3 -0
- package/dist/src/service/queue-runs.js +39 -0
- package/dist/src/service/registry.d.ts +22 -3
- package/dist/src/service/registry.js +51 -8
- package/dist/src/service/replies.d.ts +10 -0
- package/dist/src/service/replies.js +12 -0
- package/dist/src/service/run-handlers.js +45 -54
- package/dist/src/service/run-metadata.d.ts +8 -0
- package/dist/src/service/run-metadata.js +53 -0
- package/dist/src/service/run-waits.d.ts +3 -0
- package/dist/src/service/run-waits.js +41 -0
- package/dist/src/service/service.d.ts +21 -2
- package/dist/src/service/service.js +23 -5
- package/dist/src/service/submission-handler.js +70 -19
- package/dist/src/service/worker-port.d.ts +1 -0
- package/dist/src/service/worker-totals.js +10 -1
- package/dist/src/step-bridge.d.ts +32 -0
- package/dist/src/steps/decision-gate.d.ts +2 -1
- package/dist/src/steps/decision-gate.js +7 -0
- package/dist/src/steps/handoff.d.ts +2 -0
- package/dist/src/steps/handoff.js +13 -0
- package/dist/src/steps/merge-by-person.d.ts +2 -0
- package/dist/src/steps/merge-by-person.js +18 -0
- package/dist/src/steps/merge-when-green.d.ts +2 -0
- package/dist/src/steps/merge-when-green.js +62 -0
- package/dist/src/steps/review-by-agent.d.ts +5 -0
- package/dist/src/steps/review-by-agent.js +124 -0
- package/dist/src/steps/review-by-person.d.ts +4 -0
- package/dist/src/steps/review-by-person.js +16 -0
- package/dist/src/steps/review-subject.d.ts +2 -0
- package/dist/src/steps/review-subject.js +11 -0
- package/dist/src/steps/run-command.d.ts +2 -0
- package/dist/src/steps/run-command.js +15 -0
- package/dist/src/steps/sleep.d.ts +3 -0
- package/dist/src/steps/sleep.js +19 -0
- package/dist/src/steps/wait-for-decision.d.ts +2 -0
- package/dist/src/steps/wait-for-decision.js +71 -0
- package/dist/src/steps/wait-for-run.d.ts +5 -0
- package/dist/src/steps/wait-for-run.js +9 -0
- package/dist/src/storage/decision-snapshots.d.ts +1 -0
- package/dist/src/storage/decision-snapshots.js +7 -1
- package/dist/src/submission.d.ts +4 -0
- package/dist/src/submission.js +6 -2
- package/dist/src/testing.d.ts +29 -0
- package/dist/src/testing.js +264 -0
- package/dist/src/ticket-dependencies.d.ts +1 -0
- package/dist/src/ticket-dependencies.js +15 -0
- package/dist/src/ticket-status-stream.d.ts +9 -0
- package/dist/src/ticket-status-stream.js +94 -0
- package/dist/src/ticket-status.js +7 -4
- package/dist/src/token-prices.d.ts +14 -4
- package/dist/src/token-prices.js +56 -11
- package/dist/src/turn-profile.d.ts +1 -0
- package/dist/src/turn-profile.js +8 -1
- package/dist/src/worker-usage.d.ts +25 -0
- package/dist/src/worker-usage.js +58 -1
- package/dist/src/workflow-admission.d.ts +6 -0
- package/dist/src/workflow-candidate.d.ts +7 -2
- package/dist/src/workflow-candidate.js +48 -5
- package/dist/src/workflow-contracts.d.ts +2 -0
- package/dist/src/workflow-contracts.js +8 -3
- package/dist/src/workflow-declaration.d.ts +31 -2
- package/dist/src/workflow-declaration.js +140 -16
- package/dist/src/workflow-discovery.d.ts +19 -0
- package/dist/src/workflow-discovery.js +36 -0
- package/dist/src/workflow-refusals.d.ts +6 -0
- package/dist/src/workflow-refusals.js +42 -0
- package/dist/src/workflow-schedule.d.ts +22 -0
- package/dist/src/workflow-schedule.js +53 -0
- package/dist/src/workflows.d.ts +12 -1
- package/dist/src/workflows.js +9 -0
- package/dist/tools/admit-workflow.d.ts +14 -0
- package/dist/tools/admit-workflow.js +107 -0
- package/dist/tools/doctor-adoption.d.ts +1 -0
- package/dist/tools/doctor-adoption.js +11 -0
- package/dist/tools/project-configuration.d.ts +4 -0
- package/dist/tools/project-configuration.js +47 -0
- package/dist/tools/self-host-processes.d.ts +1 -0
- package/dist/tools/self-host-processes.js +33 -22
- package/dist/tools/self-host-project.d.ts +21 -0
- package/dist/tools/self-host-project.js +224 -0
- package/dist/tools/self-host-runtime.d.ts +16 -0
- package/dist/tools/self-host-runtime.js +60 -0
- package/dist/tools/self-host-workflows.d.ts +1 -0
- package/dist/tools/self-host-workflows.js +36 -1
- package/dist/tools/self-host.js +106 -135
- package/dist/tools/workflow-bundle-dependencies.d.ts +5 -0
- package/dist/tools/workflow-bundle-dependencies.js +93 -0
- package/dist/tools/workflow-bundles.d.ts +20 -0
- package/dist/tools/workflow-bundles.js +173 -0
- package/dist/tools/workflow-candidate-counts.d.ts +12 -0
- package/dist/tools/workflow-candidate-counts.js +266 -0
- package/dist/tools/workflow-candidate-fields.d.ts +5 -0
- package/dist/tools/workflow-candidate-fields.js +24 -0
- package/dist/tools/workflow-candidate-helper-counts.d.ts +10 -0
- package/dist/tools/workflow-candidate-helper-counts.js +129 -0
- package/dist/tools/workflow-candidate-program.d.ts +13 -0
- package/dist/tools/workflow-candidate-program.js +106 -0
- package/dist/tools/workflow-candidate-source.d.ts +6 -0
- package/dist/tools/workflow-candidate-source.js +169 -0
- package/dist/tools/workflow-candidate-syntax.d.ts +21 -0
- package/dist/tools/workflow-candidate-syntax.js +263 -0
- package/dist/tools/workflow-command.d.ts +1 -0
- package/dist/tools/workflow-command.js +143 -0
- package/dist/tools/workflow-folder-capture.d.ts +18 -0
- package/dist/tools/workflow-folder-capture.js +261 -0
- package/dist/tools/workflow-folders.d.ts +49 -0
- package/dist/tools/workflow-folders.js +203 -0
- package/dist/tools/workflow-source-effects.d.ts +10 -0
- package/dist/tools/workflow-source-effects.js +213 -0
- package/dist/tools/workflow-test-hook.d.ts +7 -0
- package/dist/tools/workflow-test-hook.js +16 -0
- package/dist/tools/workflow-test-loader.d.ts +1 -0
- package/dist/tools/workflow-test-loader.js +10 -0
- package/dist/workflows/develop-prd.js +71 -3
- package/dist/workflows/develop-ticket.js +6 -1
- package/dist/workflows/ticket-prompts.js +17 -3
- package/package.json +66 -6
- package/templates/develop/README.md +78 -0
- package/templates/develop/develop/accept.ts +11 -0
- package/templates/develop/develop/flow-tests.ts +357 -0
- package/templates/develop/develop/local.ts +40 -0
- package/templates/develop/develop/option-tests.ts +174 -0
- package/templates/develop/develop/partial-choice.ts +29 -0
- package/templates/develop/develop/partial.ts +28 -0
- package/templates/develop/develop/pull.ts +152 -0
- package/templates/develop/develop/queue-partial.ts +39 -0
- package/templates/develop/develop/refusal-tests.ts +174 -0
- package/templates/develop/develop/report.ts +156 -0
- package/templates/develop/develop/round.ts +40 -0
- package/templates/develop/develop/scenarios.ts +87 -0
- package/templates/develop/develop/turn.ts +67 -0
- package/templates/develop/develop.declaration.json +24 -0
- package/templates/develop/develop.test.ts +287 -0
- package/templates/develop/develop.ts +30 -0
- package/templates/develop/template.json +153 -0
- package/dist/src/chats/analysis-batches.d.ts +0 -24
- package/dist/src/chats/analysis-batches.js +0 -83
- package/dist/src/chats/analysis-contract.d.ts +0 -80
- package/dist/src/chats/analysis-contract.js +0 -16
- package/dist/src/chats/analysis-data.d.ts +0 -3
- package/dist/src/chats/analysis-data.js +0 -85
- package/dist/src/chats/analysis-input.d.ts +0 -12
- package/dist/src/chats/analysis-input.js +0 -83
- package/dist/src/chats/analysis-links.d.ts +0 -2
- package/dist/src/chats/analysis-links.js +0 -25
- package/dist/src/chats/analysis-prompt.d.ts +0 -10
- package/dist/src/chats/analysis-prompt.js +0 -16
- package/dist/src/chats/analysis-proposal.d.ts +0 -2
- package/dist/src/chats/analysis-proposal.js +0 -32
- package/dist/src/chats/analysis-provenance.d.ts +0 -4
- package/dist/src/chats/analysis-provenance.js +0 -99
- package/dist/src/chats/analysis-shape.d.ts +0 -3
- package/dist/src/chats/analysis-shape.js +0 -228
- package/dist/src/chats/analysis.d.ts +0 -3
- package/dist/src/chats/analysis.js +0 -42
- package/dist/src/chats/corpus-input.d.ts +0 -5
- package/dist/src/chats/corpus-input.js +0 -288
- package/dist/src/chats/destination.d.ts +0 -4
- package/dist/src/chats/destination.js +0 -96
- package/dist/src/chats/import.d.ts +0 -15
- package/dist/src/chats/import.js +0 -243
- package/dist/src/chats/input-file.d.ts +0 -3
- package/dist/src/chats/input-file.js +0 -32
- package/dist/src/chats/normalize.d.ts +0 -29
- package/dist/src/chats/normalize.js +0 -155
- package/dist/src/chats/previous-import.d.ts +0 -5
- package/dist/src/chats/previous-import.js +0 -34
- package/dist/src/chats/reader.d.ts +0 -21
- package/dist/src/chats/reader.js +0 -118
- package/dist/src/chats/redact-import.d.ts +0 -14
- package/dist/src/chats/redact-import.js +0 -141
- package/dist/src/chats/redaction.d.ts +0 -41
- package/dist/src/chats/redaction.js +0 -161
- package/dist/src/chats/revision-input.d.ts +0 -3
- package/dist/src/chats/revision-input.js +0 -180
- package/dist/src/chats/revision.d.ts +0 -48
- package/dist/src/chats/revision.js +0 -94
- package/dist/src/chats/selection.d.ts +0 -25
- package/dist/src/chats/selection.js +0 -109
- package/dist/src/chats/source.d.ts +0 -23
- package/dist/src/chats/source.js +0 -135
- package/dist/src/chats/structure.d.ts +0 -57
- package/dist/src/chats/structure.js +0 -216
- package/dist/src/daemon/analysis-launch.d.ts +0 -5
- package/dist/src/daemon/analysis-launch.js +0 -81
- package/dist/src/daemon/analysis-token.d.ts +0 -6
- package/dist/src/daemon/analysis-token.js +0 -88
- package/dist/src/daemon/analysis-worker.d.ts +0 -22
- package/dist/src/daemon/analysis-worker.js +0 -219
- package/dist/src/daemon/chats-files.d.ts +0 -15
- package/dist/src/daemon/chats-files.js +0 -113
- package/dist/src/daemon/chats-worker.d.ts +0 -12
- package/dist/src/daemon/chats-worker.js +0 -200
- package/dist/workflows/analyze-chats.d.ts +0 -10
- package/dist/workflows/analyze-chats.declaration.json +0 -9
- package/dist/workflows/analyze-chats.js +0 -73
package/dist/src/cli.js
CHANGED
|
@@ -1,11 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createProbeRunner } from "./cli/probe-command.js";
|
|
3
|
+
import { settingsEnvironment } from "./cli/project-settings.js";
|
|
2
4
|
import { addAbortListener } from "node:events";
|
|
3
|
-
import { execFile, spawn } from "node:child_process";
|
|
4
|
-
import {
|
|
5
|
+
import { execFile, execFileSync, spawn } from "node:child_process";
|
|
6
|
+
import { existsSync, realpathSync } from "node:fs";
|
|
7
|
+
import { parseArgs } from "node:util";
|
|
8
|
+
import { delimiter, dirname, extname, join, resolve } from "node:path";
|
|
5
9
|
import { main } from "./cli/main.js";
|
|
6
|
-
import {
|
|
10
|
+
import { parseInvocation } from "./cli/arguments.js";
|
|
11
|
+
import { adoptionRecordPath, clientCommand, legacyRuntimeDirectory, runtimeDirectory, } from "./cli/runtime-directory.js";
|
|
7
12
|
import { commandUsage } from "./cli/usage.js";
|
|
8
13
|
const [command, ...options] = process.argv.slice(2);
|
|
14
|
+
function repositoryDirectory(directory) {
|
|
15
|
+
try {
|
|
16
|
+
return realpathSync(execFileSync("git", ["-C", resolve(directory), "rev-parse", "--show-toplevel"], {
|
|
17
|
+
encoding: "utf8",
|
|
18
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
19
|
+
}).trim());
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
9
25
|
const watchCommand = async (request) => {
|
|
10
26
|
const [command = "", ...argumentsList] = request.command;
|
|
11
27
|
const completed = Promise.withResolvers();
|
|
@@ -42,17 +58,30 @@ const watchCommand = async (request) => {
|
|
|
42
58
|
listener[Symbol.dispose]();
|
|
43
59
|
}
|
|
44
60
|
};
|
|
45
|
-
function
|
|
46
|
-
const
|
|
61
|
+
function startArguments(input) {
|
|
62
|
+
const { runtime, repository, argumentsList } = input;
|
|
47
63
|
const located = [
|
|
48
64
|
"--runtime",
|
|
49
|
-
runtime,
|
|
65
|
+
runtimeDirectory(process.env, repository) ?? runtime,
|
|
50
66
|
"--repository",
|
|
51
|
-
process.cwd(),
|
|
67
|
+
repository ?? process.cwd(),
|
|
52
68
|
"--client",
|
|
53
|
-
clientCommand(process.env),
|
|
69
|
+
clientCommand(process.env, repository),
|
|
54
70
|
];
|
|
55
|
-
const
|
|
71
|
+
const record = repository === undefined
|
|
72
|
+
? undefined
|
|
73
|
+
: adoptionRecordPath(process.env, repository);
|
|
74
|
+
const legacy = legacyRuntimeDirectory(process.env);
|
|
75
|
+
if (!process.env["CLOVING_RUNTIME_DIR"] &&
|
|
76
|
+
record !== undefined &&
|
|
77
|
+
!existsSync(record) &&
|
|
78
|
+
legacy !== undefined)
|
|
79
|
+
located.push("--legacy-runtime", resolve(legacy), "--adoption-record", resolve(record));
|
|
80
|
+
return [...located, ...argumentsList];
|
|
81
|
+
}
|
|
82
|
+
function toolProcess(input) {
|
|
83
|
+
const program = join(import.meta.dirname, "..", "tools", `${input.tool}${extname(import.meta.filename)}`);
|
|
84
|
+
const child = spawn(process.execPath, [program, ...input.argumentsList], {
|
|
56
85
|
stdio: "inherit",
|
|
57
86
|
env: {
|
|
58
87
|
...process.env,
|
|
@@ -78,27 +107,81 @@ function started(runtime, argumentsList) {
|
|
|
78
107
|
});
|
|
79
108
|
});
|
|
80
109
|
}
|
|
110
|
+
function started(input) {
|
|
111
|
+
return toolProcess({
|
|
112
|
+
tool: "self-host",
|
|
113
|
+
argumentsList: startArguments(input),
|
|
114
|
+
});
|
|
115
|
+
}
|
|
81
116
|
async function start() {
|
|
82
117
|
if (options.includes("--help")) {
|
|
83
118
|
process.stdout.write(String(commandUsage["start"]));
|
|
84
119
|
return 0;
|
|
85
120
|
}
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
121
|
+
const parsed = parseArgs({
|
|
122
|
+
args: options,
|
|
123
|
+
options: { repository: { type: "string" } },
|
|
124
|
+
strict: false,
|
|
125
|
+
allowPositionals: true,
|
|
126
|
+
});
|
|
127
|
+
const selected = parsed.values["repository"];
|
|
128
|
+
if (Object.hasOwn(parsed.values, "repository") &&
|
|
129
|
+
(typeof selected !== "string" || selected === "")) {
|
|
130
|
+
process.stderr.write("missing-value: --repository needs a directory.\n");
|
|
131
|
+
return 1;
|
|
93
132
|
}
|
|
94
|
-
|
|
95
|
-
|
|
133
|
+
if (parsed.positionals.length > 0) {
|
|
134
|
+
process.stderr.write("unexpected-argument: run cloving start --help for usage.\n");
|
|
135
|
+
return 1;
|
|
136
|
+
}
|
|
137
|
+
const repository = repositoryDirectory(typeof selected === "string" ? selected : process.cwd());
|
|
138
|
+
const runtime = runtimeDirectory(process.env, repository);
|
|
139
|
+
if (runtime === undefined) {
|
|
140
|
+
process.stderr.write("repository-unknown: Change to the service repository, use --repository <directory>, or set CLOVING_RUNTIME_DIR.\n");
|
|
141
|
+
return 1;
|
|
142
|
+
}
|
|
143
|
+
let status = await started({ runtime, argumentsList: options, repository });
|
|
144
|
+
const restarting = options.filter((option) => option !== "--reset-queue");
|
|
145
|
+
while (status === 75)
|
|
146
|
+
status = await started({
|
|
147
|
+
runtime,
|
|
148
|
+
argumentsList: restarting,
|
|
149
|
+
repository,
|
|
150
|
+
});
|
|
151
|
+
return status === 0 ? 0 : 1;
|
|
96
152
|
}
|
|
97
|
-
if (command === "
|
|
153
|
+
if (command === "workflows" && ["list", "test"].includes(options[0] ?? ""))
|
|
154
|
+
process.exitCode = await toolProcess({
|
|
155
|
+
tool: "workflow-command",
|
|
156
|
+
argumentsList: options,
|
|
157
|
+
});
|
|
158
|
+
else if (command === "templates")
|
|
159
|
+
process.exitCode = await toolProcess({
|
|
160
|
+
tool: "template-command",
|
|
161
|
+
argumentsList: options,
|
|
162
|
+
});
|
|
163
|
+
else if (command === "start")
|
|
98
164
|
process.exitCode = await start();
|
|
99
|
-
else
|
|
165
|
+
else {
|
|
166
|
+
const invocation = parseInvocation(process.argv.slice(2));
|
|
167
|
+
const repository = repositoryDirectory("repository" in invocation
|
|
168
|
+
? (invocation.repository ?? process.cwd())
|
|
169
|
+
: process.cwd());
|
|
170
|
+
const settingsRepository = process.env["CLOVING_WATCH_REPOSITORY"] ?? repository;
|
|
171
|
+
const environment = invocation.kind === "watch" && settingsRepository !== undefined
|
|
172
|
+
? settingsEnvironment(process.env, settingsRepository)
|
|
173
|
+
: process.env;
|
|
100
174
|
await main(process.argv.slice(2), {
|
|
101
|
-
repository
|
|
102
|
-
|
|
103
|
-
|
|
175
|
+
repository,
|
|
176
|
+
environment,
|
|
177
|
+
doctorProbe: createProbeRunner({
|
|
178
|
+
spawn: (input) => spawn(input.executable, input.arguments, input.options),
|
|
179
|
+
kill: (identifier, signal) => process.kill(identifier, signal),
|
|
180
|
+
}),
|
|
181
|
+
watchPr: {
|
|
182
|
+
repository: process.env["CLOVING_WATCH_REPOSITORY"],
|
|
183
|
+
githubCommand: environment["CLOVING_GH_COMMAND"],
|
|
184
|
+
execute: watchCommand,
|
|
185
|
+
},
|
|
104
186
|
});
|
|
187
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type LocalCommands = Readonly<Record<string, readonly string[]>>;
|
|
2
|
+
export declare const commandLimits: {
|
|
3
|
+
stdoutBytes: number;
|
|
4
|
+
stderrBytes: number;
|
|
5
|
+
resultBytes: number;
|
|
6
|
+
};
|
|
7
|
+
export interface CommandEffect {
|
|
8
|
+
readonly operationId: string;
|
|
9
|
+
readonly name: string;
|
|
10
|
+
readonly state: string;
|
|
11
|
+
readonly exitCode: number | null;
|
|
12
|
+
readonly durationMilliseconds: number | null;
|
|
13
|
+
}
|
|
14
|
+
export type CommandEffects = (effects: readonly CommandEffect[]) => Promise<readonly CommandEffect[]>;
|
|
15
|
+
export declare function parseCommands(text: string | undefined): LocalCommands;
|
|
16
|
+
export declare function parseCommandSeconds(text: string | undefined): number;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { record } from "./protocol.js";
|
|
2
|
+
export const commandLimits = {
|
|
3
|
+
stdoutBytes: 1_048_576,
|
|
4
|
+
stderrBytes: 65_536,
|
|
5
|
+
resultBytes: 3_145_728,
|
|
6
|
+
};
|
|
7
|
+
function argumentsList(value) {
|
|
8
|
+
return (Array.isArray(value) &&
|
|
9
|
+
typeof value[0] === "string" &&
|
|
10
|
+
value[0].startsWith("/") &&
|
|
11
|
+
Array.from(value).every((argument) => typeof argument === "string" && !argument.includes("\u0000")));
|
|
12
|
+
}
|
|
13
|
+
export function parseCommands(text) {
|
|
14
|
+
if (text === undefined)
|
|
15
|
+
return {};
|
|
16
|
+
try {
|
|
17
|
+
const fields = record(JSON.parse(text));
|
|
18
|
+
if (fields === undefined)
|
|
19
|
+
throw new Error("invalid-commands");
|
|
20
|
+
const commands = {};
|
|
21
|
+
for (const [name, argumentList] of Object.entries(fields)) {
|
|
22
|
+
if (!/^[A-Za-z0-9-]{1,64}$/.test(name) || !argumentsList(argumentList))
|
|
23
|
+
throw new Error("invalid-commands");
|
|
24
|
+
commands[name] = [...argumentList];
|
|
25
|
+
}
|
|
26
|
+
return commands;
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
throw new Error("invalid-commands");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export function parseCommandSeconds(text) {
|
|
33
|
+
if (text === undefined)
|
|
34
|
+
return 60;
|
|
35
|
+
const seconds = Number(text);
|
|
36
|
+
if (!/^\d+$/.test(text) ||
|
|
37
|
+
!Number.isInteger(seconds) ||
|
|
38
|
+
seconds < 1 ||
|
|
39
|
+
seconds > 3600)
|
|
40
|
+
throw new Error("invalid-command-seconds");
|
|
41
|
+
return seconds;
|
|
42
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface SettingChange {
|
|
2
|
+
readonly field: string;
|
|
3
|
+
readonly action: "set" | "unset";
|
|
4
|
+
readonly value?: string;
|
|
5
|
+
readonly scope: "project" | "private";
|
|
6
|
+
}
|
|
7
|
+
export type JsonValue = null | boolean | number | string | readonly JsonValue[] | {
|
|
8
|
+
readonly [name: string]: JsonValue;
|
|
9
|
+
};
|
|
10
|
+
export declare function settingValue(text: string): JsonValue;
|
|
11
|
+
export declare function changedConfiguration(contents: string | undefined, change: SettingChange): string;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { configuration, settingScope, validateSetting, } from "./configuration-schema.js";
|
|
2
|
+
import { configurationValues, parseConfiguration } from "./project-settings.js";
|
|
3
|
+
import { record } from "./protocol.js";
|
|
4
|
+
function isJsonValue(value) {
|
|
5
|
+
if (value === null || typeof value === "boolean" || typeof value === "string")
|
|
6
|
+
return true;
|
|
7
|
+
if (typeof value === "number")
|
|
8
|
+
return Number.isFinite(value);
|
|
9
|
+
if (Array.isArray(value))
|
|
10
|
+
return value.every(isJsonValue);
|
|
11
|
+
const object = record(value);
|
|
12
|
+
return object !== undefined && Object.values(object).every(isJsonValue);
|
|
13
|
+
}
|
|
14
|
+
export function settingValue(text) {
|
|
15
|
+
let value;
|
|
16
|
+
try {
|
|
17
|
+
value = JSON.parse(text);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return text;
|
|
21
|
+
}
|
|
22
|
+
if (!isJsonValue(value))
|
|
23
|
+
throw new Error("invalid-setting-value");
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
function trimHarness(root, field) {
|
|
27
|
+
const order = ["harness.name", "harness.kind", "harness.path"];
|
|
28
|
+
const index = order.indexOf(field);
|
|
29
|
+
const harness = record(root["harness"]);
|
|
30
|
+
if (index < 0 || harness === undefined)
|
|
31
|
+
return;
|
|
32
|
+
const names = ["name", "kind", "path"].slice(0, index + 1);
|
|
33
|
+
root["harness"] = Object.fromEntries(Object.entries(harness).filter(([name]) => names.includes(name)));
|
|
34
|
+
}
|
|
35
|
+
function assign(root, change) {
|
|
36
|
+
const [name = "", ...tail] = change.field.split(".");
|
|
37
|
+
if (tail.length === 0 && change.action === "unset")
|
|
38
|
+
return Object.fromEntries(Object.entries(root).filter(([key]) => key !== name));
|
|
39
|
+
if (tail.length === 0)
|
|
40
|
+
return { ...root, [name]: settingValue(change.value ?? "") };
|
|
41
|
+
const child = assign({ ...record(root[name]) }, { ...change, field: tail.join(".") });
|
|
42
|
+
if (Object.keys(child).length === 0)
|
|
43
|
+
return Object.fromEntries(Object.entries(root).filter(([key]) => key !== name));
|
|
44
|
+
return { ...root, [name]: child };
|
|
45
|
+
}
|
|
46
|
+
export function changedConfiguration(contents, change) {
|
|
47
|
+
settingScope(change.field);
|
|
48
|
+
if (change.action === "set")
|
|
49
|
+
validateSetting(change.field, settingValue(change.value ?? ""));
|
|
50
|
+
const previous = parseConfiguration(contents, change.scope);
|
|
51
|
+
const root = {
|
|
52
|
+
version: 1,
|
|
53
|
+
...previous,
|
|
54
|
+
};
|
|
55
|
+
if (change.action === "unset" ||
|
|
56
|
+
configurationValues(previous)[change.field] !==
|
|
57
|
+
settingValue(change.value ?? ""))
|
|
58
|
+
trimHarness(root, change.field);
|
|
59
|
+
const next = assign(root, change);
|
|
60
|
+
configuration(next, change.scope);
|
|
61
|
+
return JSON.stringify(next, null, 2) + "\n";
|
|
62
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type SettingValue } from "./project-settings.ts";
|
|
2
|
+
import { type JsonValue } from "./configuration-change.ts";
|
|
3
|
+
import type { TurnProfiles } from "./turn-profile.ts";
|
|
4
|
+
type Source = "environment" | "private" | "project" | "default";
|
|
5
|
+
type DisplayValue = SettingValue | JsonValue;
|
|
6
|
+
interface ValueSource {
|
|
7
|
+
readonly value: DisplayValue;
|
|
8
|
+
readonly source: Source;
|
|
9
|
+
}
|
|
10
|
+
export interface SettingEntry extends ValueSource {
|
|
11
|
+
readonly field: string;
|
|
12
|
+
readonly hidden: readonly ValueSource[];
|
|
13
|
+
}
|
|
14
|
+
export declare function configurationEntries(input: {
|
|
15
|
+
readonly project: string | undefined;
|
|
16
|
+
readonly private: string | undefined;
|
|
17
|
+
readonly environment: Readonly<NodeJS.ProcessEnv>;
|
|
18
|
+
readonly field?: string;
|
|
19
|
+
readonly profiles?: TurnProfiles;
|
|
20
|
+
}): readonly SettingEntry[];
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { settingFields, settingScope } from "./configuration-schema.js";
|
|
2
|
+
import { configurationValues, parseConfiguration, settingVariables, } from "./project-settings.js";
|
|
3
|
+
import { settingValue } from "./configuration-change.js";
|
|
4
|
+
import { harnessDefaults, nativeHarness } from "./harness-defaults.js";
|
|
5
|
+
import { builtInPriceTable, parseTokenPrices } from "./token-prices.js";
|
|
6
|
+
const defaults = {
|
|
7
|
+
"queue.lanes": 1,
|
|
8
|
+
"harness.name": "claude",
|
|
9
|
+
"harness.output": "text",
|
|
10
|
+
tokenPrices: builtInPriceTable.prices,
|
|
11
|
+
fallbackModels: [],
|
|
12
|
+
profiles: {},
|
|
13
|
+
"watch.port": 3663,
|
|
14
|
+
"watch.actions": "on",
|
|
15
|
+
"github.command": ["gh"],
|
|
16
|
+
};
|
|
17
|
+
function effectiveValue(setting) {
|
|
18
|
+
const { field, value } = setting;
|
|
19
|
+
if (field === "tokenPrices")
|
|
20
|
+
return parseTokenPrices(JSON.stringify(value));
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
export function configurationEntries(input) {
|
|
24
|
+
const project = configurationValues(parseConfiguration(input.project, "project"));
|
|
25
|
+
const privateFile = configurationValues(parseConfiguration(input.private, "private"));
|
|
26
|
+
const name = input.environment["CLOVING_WORKER"] ?? privateFile["harness.name"];
|
|
27
|
+
const harness = typeof name === "string" && !nativeHarness(name)
|
|
28
|
+
? undefined
|
|
29
|
+
: harnessDefaults(name);
|
|
30
|
+
const environment = Object.fromEntries(Object.entries({
|
|
31
|
+
...settingVariables,
|
|
32
|
+
profiles: "CLOVING_PROFILES",
|
|
33
|
+
...(harness?.variable === undefined
|
|
34
|
+
? {}
|
|
35
|
+
: { "harness.command": harness.variable }),
|
|
36
|
+
}).flatMap(([field, variable]) => {
|
|
37
|
+
const value = input.environment[variable];
|
|
38
|
+
return value === undefined ? [] : [[field, settingValue(value)]];
|
|
39
|
+
}));
|
|
40
|
+
if (input.profiles !== undefined)
|
|
41
|
+
environment["profiles"] = input.profiles;
|
|
42
|
+
const effectiveDefaults = {
|
|
43
|
+
...defaults,
|
|
44
|
+
...(harness === undefined ? {} : { "harness.command": harness.command }),
|
|
45
|
+
};
|
|
46
|
+
const fields = input.field === undefined ? settingFields() : [input.field];
|
|
47
|
+
const layers = [
|
|
48
|
+
["environment", environment],
|
|
49
|
+
["private", privateFile],
|
|
50
|
+
["project", project],
|
|
51
|
+
];
|
|
52
|
+
return fields.map((field) => {
|
|
53
|
+
settingScope(field);
|
|
54
|
+
const [effective, ...hidden] = layers.flatMap(([source, values]) => {
|
|
55
|
+
const value = values[field];
|
|
56
|
+
return value === undefined ? [] : [{ source, value }];
|
|
57
|
+
});
|
|
58
|
+
const selected = effective ?? {
|
|
59
|
+
source: "default",
|
|
60
|
+
value: effectiveDefaults[field] ?? null,
|
|
61
|
+
};
|
|
62
|
+
return {
|
|
63
|
+
field,
|
|
64
|
+
...selected,
|
|
65
|
+
value: effectiveValue({ field, value: selected.value }),
|
|
66
|
+
hidden,
|
|
67
|
+
};
|
|
68
|
+
});
|
|
69
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { TurnProfiles } from "./turn-profile.ts";
|
|
2
|
+
import type { TokenPrices } from "./token-prices.ts";
|
|
3
|
+
export interface Configuration {
|
|
4
|
+
readonly version: 1;
|
|
5
|
+
readonly checks?: {
|
|
6
|
+
readonly beforeMerge?: readonly string[];
|
|
7
|
+
readonly required?: readonly string[];
|
|
8
|
+
};
|
|
9
|
+
readonly tickets?: {
|
|
10
|
+
readonly command?: readonly string[];
|
|
11
|
+
readonly nextCommand?: readonly string[];
|
|
12
|
+
};
|
|
13
|
+
readonly queue?: {
|
|
14
|
+
readonly everySeconds?: number;
|
|
15
|
+
readonly lanes?: number;
|
|
16
|
+
};
|
|
17
|
+
readonly harness?: {
|
|
18
|
+
readonly name?: string;
|
|
19
|
+
readonly turn?: readonly string[];
|
|
20
|
+
readonly output?: "text";
|
|
21
|
+
readonly kind?: "file" | "shell";
|
|
22
|
+
readonly path?: string;
|
|
23
|
+
readonly command?: readonly string[];
|
|
24
|
+
};
|
|
25
|
+
readonly profiles?: TurnProfiles;
|
|
26
|
+
readonly fallbackModels?: readonly string[];
|
|
27
|
+
readonly tokenPrices?: TokenPrices;
|
|
28
|
+
readonly privateTexts?: readonly string[];
|
|
29
|
+
readonly notify?: {
|
|
30
|
+
readonly command?: readonly string[];
|
|
31
|
+
};
|
|
32
|
+
readonly watch?: {
|
|
33
|
+
readonly port?: number | "off";
|
|
34
|
+
readonly actions?: "on" | "off";
|
|
35
|
+
};
|
|
36
|
+
readonly selfUpdate?: {
|
|
37
|
+
readonly everySeconds?: number;
|
|
38
|
+
};
|
|
39
|
+
readonly github?: {
|
|
40
|
+
readonly command?: readonly string[];
|
|
41
|
+
};
|
|
42
|
+
readonly workflows?: {
|
|
43
|
+
readonly folder?: string;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export declare function configuration(value: unknown, scope: "project" | "private"): Configuration;
|
|
47
|
+
export declare function settingScope(field: string): "project" | "private";
|
|
48
|
+
export declare function validateSetting(field: string, value: unknown): void;
|
|
49
|
+
export declare function settingFields(): readonly string[];
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import project from "./project-config.schema.json" with { type: "json" };
|
|
2
|
+
import privateConfig from "./private-config.schema.json" with { type: "json" };
|
|
3
|
+
import { record } from "./protocol.js";
|
|
4
|
+
import { isTurnCommand } from "./harness-defaults.js";
|
|
5
|
+
const schemas = {
|
|
6
|
+
project,
|
|
7
|
+
private: privateConfig,
|
|
8
|
+
};
|
|
9
|
+
function invalid(field) {
|
|
10
|
+
throw new Error(`invalid-setting: ${field}`);
|
|
11
|
+
}
|
|
12
|
+
function text(value, { schema, field }) {
|
|
13
|
+
if (typeof value !== "string")
|
|
14
|
+
invalid(field);
|
|
15
|
+
if (schema.pattern !== undefined && !new RegExp(schema.pattern).test(value))
|
|
16
|
+
invalid(field);
|
|
17
|
+
}
|
|
18
|
+
function number(value, { schema, field }) {
|
|
19
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
20
|
+
invalid(field);
|
|
21
|
+
if (schema.type === "integer" && !Number.isInteger(value))
|
|
22
|
+
invalid(field);
|
|
23
|
+
bounds(value, { schema, field });
|
|
24
|
+
}
|
|
25
|
+
function bounds(value, { schema, field }) {
|
|
26
|
+
if (schema.minimum !== undefined && value < schema.minimum)
|
|
27
|
+
invalid(field);
|
|
28
|
+
if (schema.maximum !== undefined && value > schema.maximum)
|
|
29
|
+
invalid(field);
|
|
30
|
+
if (schema.exclusiveMinimum !== undefined && value <= schema.exclusiveMinimum)
|
|
31
|
+
invalid(field);
|
|
32
|
+
}
|
|
33
|
+
function scalar(value, checked) {
|
|
34
|
+
const { schema, field } = checked;
|
|
35
|
+
if (field === "harness.turn" && !isTurnCommand(value))
|
|
36
|
+
invalid(field);
|
|
37
|
+
if ("const" in schema && value !== schema.const)
|
|
38
|
+
invalid(field);
|
|
39
|
+
if (schema.enum !== undefined && !schema.enum.includes(value))
|
|
40
|
+
invalid(field);
|
|
41
|
+
if (schema.type === "string")
|
|
42
|
+
text(value, checked);
|
|
43
|
+
if (schema.type === "number" || schema.type === "integer")
|
|
44
|
+
number(value, checked);
|
|
45
|
+
}
|
|
46
|
+
function childSchema(name, { schema, field }) {
|
|
47
|
+
const properties = schema.properties ?? {};
|
|
48
|
+
const child = Object.hasOwn(properties, name)
|
|
49
|
+
? properties[name]
|
|
50
|
+
: schema.additionalProperties;
|
|
51
|
+
if (child === false || child === undefined)
|
|
52
|
+
throw new Error(`unknown-setting: ${field}`);
|
|
53
|
+
if (schema.propertyNames !== undefined &&
|
|
54
|
+
!new RegExp(schema.propertyNames.pattern).test(name))
|
|
55
|
+
invalid(field);
|
|
56
|
+
return child;
|
|
57
|
+
}
|
|
58
|
+
function validateObject(value, { schema, field }) {
|
|
59
|
+
const object = record(value);
|
|
60
|
+
if (object === undefined)
|
|
61
|
+
invalid(field);
|
|
62
|
+
for (const required of schema.required ?? [])
|
|
63
|
+
if (!Object.hasOwn(object, required))
|
|
64
|
+
invalid(`${field}.${required}`);
|
|
65
|
+
for (const [name, item] of Object.entries(object)) {
|
|
66
|
+
const path = field === "" ? name : `${field}.${name}`;
|
|
67
|
+
const child = childSchema(name, { schema, field: path });
|
|
68
|
+
if (typeof child === "object")
|
|
69
|
+
validate(item, { schema: child, field: path });
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function matches(value, schema) {
|
|
73
|
+
try {
|
|
74
|
+
validate(value, { schema, field: "" });
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function validate(value, checked) {
|
|
82
|
+
const { schema, field } = checked;
|
|
83
|
+
if (schema.anyOf !== undefined) {
|
|
84
|
+
if (!schema.anyOf.some((option) => matches(value, option)))
|
|
85
|
+
invalid(field);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
scalar(value, checked);
|
|
89
|
+
if (schema.type === "object")
|
|
90
|
+
validateObject(value, checked);
|
|
91
|
+
if (schema.type !== "array")
|
|
92
|
+
return;
|
|
93
|
+
if (!Array.isArray(value))
|
|
94
|
+
invalid(field);
|
|
95
|
+
if (schema.maxItems !== undefined && value.length > schema.maxItems)
|
|
96
|
+
invalid(field);
|
|
97
|
+
if (schema.items === undefined)
|
|
98
|
+
return;
|
|
99
|
+
for (const [index, item] of value.entries())
|
|
100
|
+
validate(item, {
|
|
101
|
+
schema: schema.items,
|
|
102
|
+
field: `${field}.${String(index)}`,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
function validateConfiguration(value, scope) {
|
|
106
|
+
const object = record(value);
|
|
107
|
+
if (object === undefined)
|
|
108
|
+
invalid("$");
|
|
109
|
+
if (object["version"] !== 1)
|
|
110
|
+
throw new Error("unsupported-config-version: version");
|
|
111
|
+
if (scope === "project") {
|
|
112
|
+
for (const field of Object.keys(object))
|
|
113
|
+
if (Object.hasOwn(privateConfig.properties, field) &&
|
|
114
|
+
!Object.hasOwn(project.properties, field))
|
|
115
|
+
throw new Error(`private-setting-in-project-file: ${field}`);
|
|
116
|
+
}
|
|
117
|
+
validate(object, { schema: schemas[scope] ?? {}, field: "" });
|
|
118
|
+
}
|
|
119
|
+
export function configuration(value, scope) {
|
|
120
|
+
validateConfiguration(value, scope);
|
|
121
|
+
return value;
|
|
122
|
+
}
|
|
123
|
+
export function settingScope(field) {
|
|
124
|
+
fieldSchema(field);
|
|
125
|
+
const root = field.split(".")[0] ?? "";
|
|
126
|
+
return Object.hasOwn(project.properties, root) ? "project" : "private";
|
|
127
|
+
}
|
|
128
|
+
function fieldSchema(field) {
|
|
129
|
+
if (!settingFields().includes(field))
|
|
130
|
+
throw new Error(`unknown-setting: ${field}`);
|
|
131
|
+
let schema = privateConfig;
|
|
132
|
+
for (const name of field.split(".")) {
|
|
133
|
+
if (schema.type !== "object")
|
|
134
|
+
throw new Error(`unknown-setting: ${field}`);
|
|
135
|
+
const child = childSchema(name, { schema, field });
|
|
136
|
+
if (typeof child !== "object")
|
|
137
|
+
throw new Error(`unknown-setting: ${field}`);
|
|
138
|
+
schema = child;
|
|
139
|
+
}
|
|
140
|
+
return schema;
|
|
141
|
+
}
|
|
142
|
+
export function validateSetting(field, value) {
|
|
143
|
+
const schema = fieldSchema(field);
|
|
144
|
+
if (schema.minimum !== undefined &&
|
|
145
|
+
schema.maximum !== undefined &&
|
|
146
|
+
typeof value === "number" &&
|
|
147
|
+
(value < schema.minimum || value > schema.maximum))
|
|
148
|
+
throw new Error(`invalid-setting: ${field} must be from ${String(schema.minimum)} to ${String(schema.maximum)}`);
|
|
149
|
+
validate(value, { schema, field });
|
|
150
|
+
}
|
|
151
|
+
export function settingFields() {
|
|
152
|
+
return Object.entries(privateConfig.properties).flatMap(([name, schema]) => {
|
|
153
|
+
if (name === "version")
|
|
154
|
+
return [];
|
|
155
|
+
return "properties" in schema
|
|
156
|
+
? Object.keys(schema.properties).map((child) => `${name}.${child}`)
|
|
157
|
+
: [name];
|
|
158
|
+
});
|
|
159
|
+
}
|
|
@@ -1,6 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import type { ReviewVerdict } from "../review-subject.ts";
|
|
2
|
+
import type { TicketStatus } from "../ticket-status.ts";
|
|
3
|
+
import { type WorkerUsage, type WorkerAttemptUsage, type WorkerModelUsage, type RetryKind } from "../worker-usage.ts";
|
|
4
|
+
export type Worker = string;
|
|
3
5
|
export interface StreamResult {
|
|
6
|
+
readonly reviewFeedback?: string;
|
|
7
|
+
readonly reviewVerdict?: ReviewVerdict | null;
|
|
8
|
+
readonly models?: readonly WorkerModelUsage[];
|
|
9
|
+
readonly ticketStatusTooLarge?: true;
|
|
10
|
+
readonly ticketStatus?: TicketStatus;
|
|
11
|
+
readonly attempts?: readonly WorkerAttemptUsage[];
|
|
12
|
+
readonly pricingModel?: string | null;
|
|
4
13
|
readonly subtype?: string;
|
|
5
14
|
readonly errorType?: string;
|
|
6
15
|
readonly model: string | null;
|
|
@@ -12,13 +21,16 @@ export interface StreamResult {
|
|
|
12
21
|
readonly turns: number | null;
|
|
13
22
|
}
|
|
14
23
|
export interface TurnEnd {
|
|
24
|
+
readonly reason?: string;
|
|
25
|
+
readonly detail?: string;
|
|
15
26
|
readonly stopped?: boolean;
|
|
16
27
|
readonly exitCode: number | null;
|
|
17
28
|
readonly result: StreamResult | undefined;
|
|
18
29
|
}
|
|
19
30
|
export interface TurnStart {
|
|
20
|
-
readonly
|
|
21
|
-
readonly
|
|
31
|
+
readonly resultBytes?: number;
|
|
32
|
+
readonly output?: "text";
|
|
33
|
+
readonly shell?: string;
|
|
22
34
|
readonly worker?: Worker;
|
|
23
35
|
readonly turnId?: string;
|
|
24
36
|
readonly environment?: Readonly<Record<string, string>>;
|
|
@@ -34,5 +46,8 @@ export interface RunningTurn {
|
|
|
34
46
|
readonly stop: (graceMilliseconds: number) => void;
|
|
35
47
|
}
|
|
36
48
|
export declare function capacityRefusal(result: StreamResult | undefined): boolean;
|
|
37
|
-
export declare function
|
|
49
|
+
export declare function retryKind(result: StreamResult | undefined): RetryKind | null;
|
|
50
|
+
export declare function succeeded(end: TurnEnd): boolean;
|
|
51
|
+
export declare function streamResult(line: string, worker?: Worker): StreamResult | undefined;
|
|
52
|
+
export declare function turnEnvironment(configuration: string, start: TurnStart): NodeJS.ProcessEnv;
|
|
38
53
|
export declare function startTurn(start: TurnStart): RunningTurn;
|