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
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join, resolve } from "node:path";
|
|
5
|
+
import { pathToFileURL } from "node:url";
|
|
6
|
+
import { workflowTestLoader } from "../tools/workflow-test-loader.js";
|
|
7
|
+
import { authorizeEffect } from "./effect-authorization.js";
|
|
8
|
+
import { record } from "./protocol.js";
|
|
9
|
+
import { stepBridgeKey, } from "./step-bridge.js";
|
|
10
|
+
export function fakeStepBridge(scenario) {
|
|
11
|
+
const { bridge, requests, budget } = scenarioBridge(scenario);
|
|
12
|
+
const key = Symbol.for(stepBridgeKey);
|
|
13
|
+
const sleepKey = Symbol.for("WORKFLOW_SLEEP");
|
|
14
|
+
const previous = Object.getOwnPropertyDescriptor(globalThis, key);
|
|
15
|
+
const previousSleep = Object.getOwnPropertyDescriptor(globalThis, sleepKey);
|
|
16
|
+
if (Reflect.get(globalThis, key) !== undefined ||
|
|
17
|
+
Reflect.get(globalThis, sleepKey) !== undefined)
|
|
18
|
+
throw new Error("workflow-testing-host-active");
|
|
19
|
+
if (previous?.configurable === false || previousSleep?.configurable === false)
|
|
20
|
+
throw new Error("workflow-testing-host-locked");
|
|
21
|
+
Object.defineProperty(globalThis, key, { configurable: true, value: bridge });
|
|
22
|
+
Object.defineProperty(globalThis, sleepKey, {
|
|
23
|
+
configurable: true,
|
|
24
|
+
value: (milliseconds) => {
|
|
25
|
+
requests.push(["sleep", { seconds: milliseconds / 1000 }]);
|
|
26
|
+
return Promise.resolve();
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
return {
|
|
30
|
+
requests,
|
|
31
|
+
get spent() {
|
|
32
|
+
return budget.spent;
|
|
33
|
+
},
|
|
34
|
+
[Symbol.dispose]() {
|
|
35
|
+
if (previous === undefined)
|
|
36
|
+
Reflect.deleteProperty(globalThis, key);
|
|
37
|
+
else
|
|
38
|
+
Object.defineProperty(globalThis, key, previous);
|
|
39
|
+
if (previousSleep === undefined)
|
|
40
|
+
Reflect.deleteProperty(globalThis, sleepKey);
|
|
41
|
+
else
|
|
42
|
+
Object.defineProperty(globalThis, sleepKey, previousSleep);
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function scenarioBridge(scenario) {
|
|
47
|
+
const requests = [];
|
|
48
|
+
const waits = [...(scenario.waits ?? [])];
|
|
49
|
+
const decisions = [...(scenario.decisions ?? [])];
|
|
50
|
+
const budget = { spent: 0 };
|
|
51
|
+
const bridge = {
|
|
52
|
+
...scenarioEffects(scenario, { requests, budget }),
|
|
53
|
+
gate: (request) => {
|
|
54
|
+
requests.push(["gate", request]);
|
|
55
|
+
return Promise.resolve(scenario.gate ?? {
|
|
56
|
+
kind: "unavailable",
|
|
57
|
+
reason: "no-scenario-result",
|
|
58
|
+
});
|
|
59
|
+
},
|
|
60
|
+
waitForDecision: (request) => {
|
|
61
|
+
requests.push(["waitForDecision", request]);
|
|
62
|
+
const decision = decisions.shift();
|
|
63
|
+
if (decision === undefined)
|
|
64
|
+
return Promise.reject(new Error("no-scenario-result"));
|
|
65
|
+
return Promise.resolve(decision);
|
|
66
|
+
},
|
|
67
|
+
waitForRun: (request) => {
|
|
68
|
+
requests.push(["waitForRun", request]);
|
|
69
|
+
return Promise.resolve(waits.shift() ?? {
|
|
70
|
+
kind: "unavailable",
|
|
71
|
+
reason: "no-scenario-result",
|
|
72
|
+
promotionId: null,
|
|
73
|
+
});
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
return { bridge, requests, budget };
|
|
77
|
+
}
|
|
78
|
+
function scenarioEffects(scenario, state) {
|
|
79
|
+
const { requests, budget } = state;
|
|
80
|
+
const effects = new Map(Object.entries(scenario.effects ?? {}).map(([key, values]) => [
|
|
81
|
+
key,
|
|
82
|
+
[...values],
|
|
83
|
+
]));
|
|
84
|
+
return {
|
|
85
|
+
effect: (request) => {
|
|
86
|
+
requests.push(["effect", request]);
|
|
87
|
+
const refusal = spend(scenario, { budget, request });
|
|
88
|
+
if (refusal !== undefined)
|
|
89
|
+
return Promise.resolve(refusal);
|
|
90
|
+
const result = scenario.effects === undefined
|
|
91
|
+
? scenario.turn
|
|
92
|
+
: effects.get(request.capability + " " + request.method)?.shift();
|
|
93
|
+
return Promise.resolve(result ?? { kind: "unavailable", reason: "no-scenario-result" });
|
|
94
|
+
},
|
|
95
|
+
handoff: (request) => {
|
|
96
|
+
requests.push(["handoff", request]);
|
|
97
|
+
const refusal = spend(scenario, {
|
|
98
|
+
budget,
|
|
99
|
+
request: { capability: "handoff", units: 1 },
|
|
100
|
+
});
|
|
101
|
+
if (refusal !== undefined)
|
|
102
|
+
return Promise.resolve(refusal);
|
|
103
|
+
return Promise.resolve(effects.get("handoff")?.shift() ?? {
|
|
104
|
+
kind: "completed",
|
|
105
|
+
operationId: "handoff",
|
|
106
|
+
receipt: null,
|
|
107
|
+
result: "target-run",
|
|
108
|
+
});
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function spend(scenario, effect) {
|
|
113
|
+
const { budget, request } = effect;
|
|
114
|
+
if (scenario.effectLimit === undefined)
|
|
115
|
+
return undefined;
|
|
116
|
+
const allowed = authorizeEffect({ capabilities: ["claude", "github", "command", "handoff"] }, {
|
|
117
|
+
budget: { limit: scenario.effectLimit, spent: budget.spent },
|
|
118
|
+
request,
|
|
119
|
+
});
|
|
120
|
+
if (allowed.kind === "rejected")
|
|
121
|
+
return { kind: "refused", reason: allowed.reason };
|
|
122
|
+
budget.spent = allowed.spent;
|
|
123
|
+
return undefined;
|
|
124
|
+
}
|
|
125
|
+
function scenarioScript(scenario) {
|
|
126
|
+
const workflow = scenario.workflow.startsWith("file:")
|
|
127
|
+
? scenario.workflow
|
|
128
|
+
: pathToFileURL(resolve(scenario.workflow)).href;
|
|
129
|
+
return `import { writeFile } from "node:fs/promises";
|
|
130
|
+
import { fakeStepBridge } from ${JSON.stringify(import.meta.url)};
|
|
131
|
+
import * as workflows from ${JSON.stringify(workflow)};
|
|
132
|
+
const given = ${JSON.stringify(scenario)};
|
|
133
|
+
const workflow = workflows[given.exportName];
|
|
134
|
+
if (typeof workflow !== "function") throw new Error("workflow-test-export-missing");
|
|
135
|
+
using bridge = fakeStepBridge(given);
|
|
136
|
+
const outcome = await workflow(given.input, given.decision);
|
|
137
|
+
await writeFile(process.argv[2], JSON.stringify({ outcome, requests: bridge.requests,
|
|
138
|
+
...(given.effectLimit === undefined ? {} : { spent: bridge.spent }) }));`;
|
|
139
|
+
}
|
|
140
|
+
function scenarioResult(value) {
|
|
141
|
+
const result = record(value);
|
|
142
|
+
return (result !== undefined &&
|
|
143
|
+
Object.hasOwn(result, "outcome") &&
|
|
144
|
+
Array.isArray(result["requests"]) &&
|
|
145
|
+
result["requests"].every(scenarioRequest) &&
|
|
146
|
+
(result["spent"] === undefined || typeof result["spent"] === "number"));
|
|
147
|
+
}
|
|
148
|
+
function scenarioRequest(value) {
|
|
149
|
+
if (!Array.isArray(value) || value.length !== 2)
|
|
150
|
+
return false;
|
|
151
|
+
const request = record(value[1]);
|
|
152
|
+
if (request === undefined)
|
|
153
|
+
return false;
|
|
154
|
+
switch (value[0]) {
|
|
155
|
+
case "effect":
|
|
156
|
+
return protectedRequest(request);
|
|
157
|
+
case "gate":
|
|
158
|
+
case "waitForDecision":
|
|
159
|
+
return gateRequest(request);
|
|
160
|
+
case "handoff":
|
|
161
|
+
return handoffRequest(request);
|
|
162
|
+
case "waitForRun":
|
|
163
|
+
return runWaitRequest(request);
|
|
164
|
+
case "sleep":
|
|
165
|
+
return sleepRequest(request);
|
|
166
|
+
default:
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function runWaitRequest(request) {
|
|
171
|
+
return (typeof request["runId"] === "string" &&
|
|
172
|
+
typeof request["maximumWaitSeconds"] === "number");
|
|
173
|
+
}
|
|
174
|
+
function sleepRequest(request) {
|
|
175
|
+
const seconds = request["seconds"];
|
|
176
|
+
return (typeof seconds === "number" &&
|
|
177
|
+
Number.isInteger(seconds) &&
|
|
178
|
+
seconds >= 1 &&
|
|
179
|
+
seconds <= 86400);
|
|
180
|
+
}
|
|
181
|
+
function gateRequest(request) {
|
|
182
|
+
return (typeof request["gateId"] === "string" &&
|
|
183
|
+
(request["kind"] === "question" || request["kind"] === "approval") &&
|
|
184
|
+
typeof request["prompt"] === "string" &&
|
|
185
|
+
optionalText(request["expiresAt"]));
|
|
186
|
+
}
|
|
187
|
+
function handoffRequest(request) {
|
|
188
|
+
const input = record(request["input"]);
|
|
189
|
+
return (typeof request["workflowId"] === "string" &&
|
|
190
|
+
input !== undefined &&
|
|
191
|
+
Object.values(input).every(handoffValue));
|
|
192
|
+
}
|
|
193
|
+
function protectedRequest(request) {
|
|
194
|
+
return (protectedScope(request["scope"]) &&
|
|
195
|
+
["capability", "method", "target", "payload"].every((key) => typeof request[key] === "string") &&
|
|
196
|
+
typeof request["units"] === "number" &&
|
|
197
|
+
optionalText(request["resource"]));
|
|
198
|
+
}
|
|
199
|
+
function protectedScope(value) {
|
|
200
|
+
const scope = record(value);
|
|
201
|
+
if (scope === undefined)
|
|
202
|
+
return false;
|
|
203
|
+
const stage = record(scope["stage"]);
|
|
204
|
+
return (typeof scope["phase"] === "string" &&
|
|
205
|
+
typeof scope["operation"] === "string" &&
|
|
206
|
+
typeof scope["round"] === "number" &&
|
|
207
|
+
optionalText(scope["key"]) &&
|
|
208
|
+
(scope["stage"] === undefined ||
|
|
209
|
+
(stage !== undefined &&
|
|
210
|
+
["id", "visit", "branch"].every((key) => typeof stage[key] === "string"))));
|
|
211
|
+
}
|
|
212
|
+
function optionalText(value) {
|
|
213
|
+
return value === undefined || typeof value === "string";
|
|
214
|
+
}
|
|
215
|
+
function handoffValue(value) {
|
|
216
|
+
if (value === null || ["string", "boolean", "number"].includes(typeof value))
|
|
217
|
+
return true;
|
|
218
|
+
if (Array.isArray(value))
|
|
219
|
+
return value.every(handoffValue);
|
|
220
|
+
const fields = record(value);
|
|
221
|
+
return fields !== undefined && Object.values(fields).every(handoffValue);
|
|
222
|
+
}
|
|
223
|
+
export async function runScenario(scenario) {
|
|
224
|
+
const temporary = await mkdtemp(join(tmpdir(), "cloving-scenario-"));
|
|
225
|
+
try {
|
|
226
|
+
const script = join(temporary, "scenario.mjs");
|
|
227
|
+
const resultFile = join(temporary, "result.json");
|
|
228
|
+
await writeFile(script, scenarioScript(scenario));
|
|
229
|
+
await executeScenario(script, resultFile);
|
|
230
|
+
const value = JSON.parse(await readFile(resultFile, "utf8"));
|
|
231
|
+
if (!scenarioResult(value))
|
|
232
|
+
throw new Error("invalid-workflow-scenario-result");
|
|
233
|
+
return value;
|
|
234
|
+
}
|
|
235
|
+
finally {
|
|
236
|
+
await rm(temporary, { recursive: true, force: true });
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
function executeScenario(script, resultFile) {
|
|
240
|
+
return new Promise((settle, reject) => {
|
|
241
|
+
const child = spawn(process.execPath, [
|
|
242
|
+
"--experimental-strip-types",
|
|
243
|
+
"--import",
|
|
244
|
+
workflowTestLoader(),
|
|
245
|
+
script,
|
|
246
|
+
resultFile,
|
|
247
|
+
], {
|
|
248
|
+
env: { ...process.env, NODE_TEST_CONTEXT: undefined },
|
|
249
|
+
stdio: ["ignore", "ignore", "pipe"],
|
|
250
|
+
});
|
|
251
|
+
let diagnostics = "";
|
|
252
|
+
child.stderr.setEncoding("utf8");
|
|
253
|
+
child.stderr.on("data", (text) => {
|
|
254
|
+
diagnostics = (diagnostics + text).slice(-65536);
|
|
255
|
+
});
|
|
256
|
+
child.once("error", reject);
|
|
257
|
+
child.once("close", (code, signal) => {
|
|
258
|
+
if (code === 0)
|
|
259
|
+
settle();
|
|
260
|
+
else
|
|
261
|
+
reject(new Error(`workflow-scenario-failed: ${String(code ?? signal)}\n${diagnostics}`));
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function hardDependencies(ticket: string): readonly string[];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function hardDependencies(ticket) {
|
|
2
|
+
const lines = ticket.split(/\r?\n/);
|
|
3
|
+
const start = lines.findIndex((line) => /^## Dependencies\s*$/.test(line));
|
|
4
|
+
if (start === -1)
|
|
5
|
+
return [];
|
|
6
|
+
const following = lines.slice(start + 1);
|
|
7
|
+
const end = following.findIndex((line) => /^#{1,2} /.test(line));
|
|
8
|
+
const section = (end === -1 ? following : following.slice(0, end)).join("\n");
|
|
9
|
+
const sentences = section
|
|
10
|
+
.replace(/\b(?:e\.g|i\.e)\./g, "example")
|
|
11
|
+
.matchAll(/(?:^|[.!?]\s+|\n)\s*(?:[-*+]\s+|\d+\.\s+)?Needs\b([\s\S]*?)(?=[.!?](?:\s|$)|$)/g);
|
|
12
|
+
return [
|
|
13
|
+
...new Set([...sentences].flatMap((sentence) => [...String(sentence[1]).matchAll(/#([1-9]\d*)\b/g)].map((match) => String(match[1])))),
|
|
14
|
+
];
|
|
15
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type TicketStatus } from "./ticket-status.ts";
|
|
2
|
+
export interface StreamedTicketStatus {
|
|
3
|
+
readonly ticketStatus: TicketStatus;
|
|
4
|
+
readonly ticketStatusTooLarge?: true;
|
|
5
|
+
}
|
|
6
|
+
export declare function ticketStatusStream(limit: number): {
|
|
7
|
+
write: (chunk: string) => void;
|
|
8
|
+
result: () => StreamedTicketStatus;
|
|
9
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { ticketStatus } from "./ticket-status.js";
|
|
2
|
+
function emptyLine() {
|
|
3
|
+
return {
|
|
4
|
+
text: "",
|
|
5
|
+
length: 0,
|
|
6
|
+
contentLength: 0,
|
|
7
|
+
breaks: 0,
|
|
8
|
+
trailingCarriage: false,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
function remainingLine(stream, line) {
|
|
12
|
+
if (line.length <= stream.limit && line.text === "Remaining:") {
|
|
13
|
+
stream.remaining = [];
|
|
14
|
+
stream.characters = 0;
|
|
15
|
+
stream.valid = true;
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (!stream.valid)
|
|
19
|
+
return;
|
|
20
|
+
if (line.breaks > 0 || !/^- \S.*$/.test(line.text)) {
|
|
21
|
+
stream.valid = false;
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
stream.characters = Math.min(stream.limit + 1, stream.characters + line.length + 1);
|
|
25
|
+
if (stream.characters <= stream.limit)
|
|
26
|
+
stream.remaining.push(line.text.slice(2));
|
|
27
|
+
}
|
|
28
|
+
function receivedLine(stream) {
|
|
29
|
+
const line = stream.line;
|
|
30
|
+
stream.line = emptyLine();
|
|
31
|
+
if (line.contentLength === 0)
|
|
32
|
+
return;
|
|
33
|
+
if (line.trailingCarriage)
|
|
34
|
+
line.breaks--;
|
|
35
|
+
if (line.length <= stream.limit + 1 && line.trailingCarriage) {
|
|
36
|
+
line.text = line.text.slice(0, -1);
|
|
37
|
+
line.length--;
|
|
38
|
+
}
|
|
39
|
+
if (stream.last !== undefined)
|
|
40
|
+
remainingLine(stream, stream.last);
|
|
41
|
+
if (/^Ticket status:/i.test(line.text))
|
|
42
|
+
stream.statuses = Math.min(2, stream.statuses + 1);
|
|
43
|
+
stream.last = line;
|
|
44
|
+
}
|
|
45
|
+
function writeStatus(stream, chunk) {
|
|
46
|
+
const parts = chunk.split("\n");
|
|
47
|
+
for (const [index, part] of parts.entries()) {
|
|
48
|
+
const { line, limit } = stream;
|
|
49
|
+
const content = part.trimEnd();
|
|
50
|
+
line.breaks = Math.min(2, line.breaks + (part.match(/[\r\u2028\u2029]/g)?.length ?? 0));
|
|
51
|
+
if (part !== "")
|
|
52
|
+
line.trailingCarriage = part.endsWith("\r");
|
|
53
|
+
if (content !== "")
|
|
54
|
+
line.contentLength = Math.min(limit + 1, line.length + content.length);
|
|
55
|
+
line.text = (line.text + part).slice(0, limit + 1);
|
|
56
|
+
line.length = Math.min(limit + 2, line.length + part.length);
|
|
57
|
+
if (index < parts.length - 1)
|
|
58
|
+
receivedLine(stream);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function statusResult(stream) {
|
|
62
|
+
receivedLine(stream);
|
|
63
|
+
const last = stream.last;
|
|
64
|
+
if (stream.statuses !== 1 || last === undefined)
|
|
65
|
+
return { ticketStatus: ticketStatus("") };
|
|
66
|
+
const status = last.contentLength > stream.limit ? "" : last.text.trimEnd();
|
|
67
|
+
if (status !== "Ticket status: partial" || !stream.valid)
|
|
68
|
+
return { ticketStatus: ticketStatus(status) };
|
|
69
|
+
if (stream.characters > stream.limit)
|
|
70
|
+
return {
|
|
71
|
+
ticketStatus: ticketStatus(status),
|
|
72
|
+
ticketStatusTooLarge: true,
|
|
73
|
+
};
|
|
74
|
+
return {
|
|
75
|
+
ticketStatus: ticketStatus(`Remaining:\n${stream.remaining.map((item) => `- ${item}`).join("\n")}\n${status}`),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
export function ticketStatusStream(limit) {
|
|
79
|
+
const stream = {
|
|
80
|
+
limit,
|
|
81
|
+
line: emptyLine(),
|
|
82
|
+
last: undefined,
|
|
83
|
+
statuses: 0,
|
|
84
|
+
remaining: [],
|
|
85
|
+
characters: 0,
|
|
86
|
+
valid: false,
|
|
87
|
+
};
|
|
88
|
+
return {
|
|
89
|
+
write: (chunk) => {
|
|
90
|
+
writeStatus(stream, chunk);
|
|
91
|
+
},
|
|
92
|
+
result: () => statusResult(stream),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
@@ -8,11 +8,14 @@ function parsedStatus(summary) {
|
|
|
8
8
|
if (status !== "Ticket status: partial")
|
|
9
9
|
return undefined;
|
|
10
10
|
const heading = lines.lastIndexOf("Remaining:");
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
const items = heading === -1
|
|
12
|
+
? []
|
|
13
|
+
: lines.slice(heading + 1).filter((line) => line.trim() !== "");
|
|
14
14
|
if (items.length === 0 || items.some((line) => !/^- \S.*$/.test(line)))
|
|
15
|
-
return
|
|
15
|
+
return {
|
|
16
|
+
kind: "partial",
|
|
17
|
+
remaining: ["The worker report has an unreadable Remaining: list."],
|
|
18
|
+
};
|
|
16
19
|
return { kind: "partial", remaining: items.map((line) => line.slice(2)) };
|
|
17
20
|
}
|
|
18
21
|
function preservedStatus(value) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type WorkerUsage } from "./worker-usage.ts";
|
|
1
|
+
import { type WorkerUsage, type WorkerModelUsage } from "./worker-usage.ts";
|
|
2
|
+
import type { NativeHarness } from "./harness-defaults.ts";
|
|
2
3
|
export interface TokenPrice {
|
|
3
4
|
readonly input: number;
|
|
4
5
|
readonly cachedInput: number;
|
|
@@ -11,9 +12,18 @@ export declare const builtInPriceTable: {
|
|
|
11
12
|
readonly prices: TokenPrices;
|
|
12
13
|
};
|
|
13
14
|
export declare function parseTokenPrices(value: string | undefined): TokenPrices;
|
|
15
|
+
export declare function parseFallbackModels(value: string | undefined): readonly string[];
|
|
14
16
|
export declare function priceForModel(prices: TokenPrices, model: string | null): TokenPrice | undefined;
|
|
15
17
|
export declare function commandModel(command: readonly string[]): string | null;
|
|
16
|
-
export declare function
|
|
17
|
-
|
|
18
|
+
export declare function replaceCommandModel(command: readonly string[], model: string): readonly string[];
|
|
19
|
+
interface SinglePricing {
|
|
20
|
+
readonly worker: NativeHarness;
|
|
18
21
|
readonly price: TokenPrice | undefined;
|
|
19
|
-
}
|
|
22
|
+
}
|
|
23
|
+
interface ModelPricing {
|
|
24
|
+
readonly worker: "gemini";
|
|
25
|
+
readonly models: readonly WorkerModelUsage[];
|
|
26
|
+
readonly prices: TokenPrices;
|
|
27
|
+
}
|
|
28
|
+
export declare function estimatedCostUsd(usage: WorkerUsage, pricing: SinglePricing | ModelPricing): number | null;
|
|
29
|
+
export {};
|
package/dist/src/token-prices.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { priceOf, usageOf } from "./worker-usage.js";
|
|
1
|
+
import { priceOf, sumPrices, usageOf, } from "./worker-usage.js";
|
|
2
2
|
import { record } from "./protocol.js";
|
|
3
3
|
export const builtInPriceTable = {
|
|
4
4
|
date: "2026-10-18",
|
|
@@ -36,38 +36,83 @@ export function parseTokenPrices(value) {
|
|
|
36
36
|
throw new Error("Invalid CLOVING_TOKEN_PRICES");
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
+
export function parseFallbackModels(value) {
|
|
40
|
+
if (value === undefined)
|
|
41
|
+
return [];
|
|
42
|
+
try {
|
|
43
|
+
const models = JSON.parse(value);
|
|
44
|
+
if (Array.isArray(models) &&
|
|
45
|
+
models.length <= 3 &&
|
|
46
|
+
models.every((model) => typeof model === "string" && model.trim().length > 0))
|
|
47
|
+
return models.map(String);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
throw new Error("The daemon did not start: invalid-fallback-models");
|
|
51
|
+
}
|
|
52
|
+
throw new Error("The daemon did not start: invalid-fallback-models");
|
|
53
|
+
}
|
|
39
54
|
export function priceForModel(prices, model) {
|
|
40
55
|
return model !== null && Object.hasOwn(prices, model)
|
|
41
56
|
? prices[model]
|
|
42
57
|
: undefined;
|
|
43
58
|
}
|
|
44
|
-
|
|
45
|
-
let
|
|
46
|
-
|
|
59
|
+
function modelIndex(command) {
|
|
60
|
+
let selected;
|
|
61
|
+
const separator = command.indexOf("--", 1);
|
|
62
|
+
const end = separator === -1 ? command.length : separator;
|
|
63
|
+
for (let index = 1; index < end; index += 1) {
|
|
47
64
|
const argument = command[index] ?? "";
|
|
48
|
-
if (argument === "--")
|
|
49
|
-
break;
|
|
50
65
|
if (argument.startsWith("--model="))
|
|
51
|
-
|
|
52
|
-
if (
|
|
66
|
+
selected = argument.slice(8) ? index : undefined;
|
|
67
|
+
if (["--model", "-m"].includes(argument)) {
|
|
53
68
|
const next = command[index + 1];
|
|
54
|
-
|
|
69
|
+
selected = next && !next.startsWith("-") ? index + 1 : undefined;
|
|
55
70
|
index += 1;
|
|
56
71
|
}
|
|
57
72
|
}
|
|
58
|
-
return
|
|
73
|
+
return selected;
|
|
74
|
+
}
|
|
75
|
+
export function commandModel(command) {
|
|
76
|
+
const index = modelIndex(command);
|
|
77
|
+
if (index === undefined)
|
|
78
|
+
return null;
|
|
79
|
+
const argument = command[index] ?? "";
|
|
80
|
+
return argument.startsWith("--model=") ? argument.slice(8) : argument;
|
|
81
|
+
}
|
|
82
|
+
export function replaceCommandModel(command, model) {
|
|
83
|
+
const index = modelIndex(command);
|
|
84
|
+
if (index === undefined)
|
|
85
|
+
return command;
|
|
86
|
+
return command.map((argument, position) => {
|
|
87
|
+
if (position !== index)
|
|
88
|
+
return argument;
|
|
89
|
+
return argument.startsWith("--model=") ? `--model=${model}` : model;
|
|
90
|
+
});
|
|
59
91
|
}
|
|
60
92
|
export function estimatedCostUsd(usage, pricing) {
|
|
93
|
+
return "models" in pricing
|
|
94
|
+
? modelCostUsd(pricing)
|
|
95
|
+
: singleCostUsd(usage, pricing);
|
|
96
|
+
}
|
|
97
|
+
function modelCostUsd(pricing) {
|
|
98
|
+
return sumPrices(pricing.models.map(({ model, usage: counts }) => singleCostUsd(counts, {
|
|
99
|
+
worker: "gemini",
|
|
100
|
+
price: priceForModel(pricing.prices, model),
|
|
101
|
+
})));
|
|
102
|
+
}
|
|
103
|
+
function singleCostUsd(usage, pricing) {
|
|
61
104
|
const { worker, price } = pricing;
|
|
62
105
|
const counts = usageOf(usage);
|
|
63
106
|
const cached = counts.cache_read_input_tokens;
|
|
64
107
|
const output = counts.output_tokens;
|
|
65
108
|
if (price === undefined ||
|
|
109
|
+
(worker === "cursor-agent" && counts.cache_creation_input_tokens !== 0) ||
|
|
66
110
|
counts.input_tokens === null ||
|
|
67
111
|
cached === null ||
|
|
68
112
|
output === null)
|
|
69
113
|
return null;
|
|
70
|
-
const input = counts.input_tokens -
|
|
114
|
+
const input = counts.input_tokens -
|
|
115
|
+
(worker === "codex" || worker === "gemini" ? cached : 0);
|
|
71
116
|
if (input < 0)
|
|
72
117
|
return null;
|
|
73
118
|
return priceOf((input / 1_000_000) * price.input +
|
package/dist/src/turn-profile.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const fields = [
|
|
2
|
+
"harness",
|
|
2
3
|
"env",
|
|
3
4
|
"allowedTools",
|
|
4
5
|
"model",
|
|
@@ -29,6 +30,8 @@ function environment(value) {
|
|
|
29
30
|
text(item)));
|
|
30
31
|
}
|
|
31
32
|
function validField(name, value) {
|
|
33
|
+
if (name === "harness")
|
|
34
|
+
return typeof value === "string" && /^[a-z][a-z0-9-]{0,63}$/.test(value);
|
|
32
35
|
if (name === "env")
|
|
33
36
|
return environment(value);
|
|
34
37
|
if (name === "allowedTools" || name === "workflows")
|
|
@@ -71,7 +74,11 @@ function retained(argumentsList, values) {
|
|
|
71
74
|
for (let index = 0; index < argumentsList.length;) {
|
|
72
75
|
const argument = argumentsList[index] ?? "";
|
|
73
76
|
const name = argument.split("=")[0] ?? "";
|
|
74
|
-
const
|
|
77
|
+
const aliases = {
|
|
78
|
+
"--allowed-tools": "--allowedTools",
|
|
79
|
+
"-m": "--model",
|
|
80
|
+
};
|
|
81
|
+
const flag = aliases[name] ?? name;
|
|
75
82
|
if (!values.has(flag)) {
|
|
76
83
|
kept.push(argument);
|
|
77
84
|
index += 1;
|
|
@@ -1,14 +1,34 @@
|
|
|
1
|
+
export type RetryKind = "capacity" | "network";
|
|
1
2
|
export interface WorkerUsage {
|
|
3
|
+
readonly cache_creation_input_tokens?: number | null;
|
|
2
4
|
readonly input_tokens: number | null;
|
|
3
5
|
readonly cache_read_input_tokens: number | null;
|
|
4
6
|
readonly output_tokens: number | null;
|
|
5
7
|
}
|
|
6
8
|
export interface WorkerTurnUsage {
|
|
9
|
+
readonly model?: string;
|
|
10
|
+
readonly summary?: string;
|
|
11
|
+
readonly harness?: string;
|
|
12
|
+
readonly attempts?: readonly WorkerAttemptUsage[];
|
|
7
13
|
readonly estimatedCostUsd: number | null;
|
|
8
14
|
readonly operationId: string;
|
|
9
15
|
readonly usage: WorkerUsage;
|
|
10
16
|
readonly costUsd: number | null;
|
|
11
17
|
}
|
|
18
|
+
export interface WorkerAttemptUsage {
|
|
19
|
+
readonly models?: readonly WorkerModelUsage[];
|
|
20
|
+
readonly retryKind?: RetryKind | null;
|
|
21
|
+
readonly attempt: number;
|
|
22
|
+
readonly model: string | null;
|
|
23
|
+
readonly usage: WorkerUsage;
|
|
24
|
+
readonly costUsd: number | null;
|
|
25
|
+
readonly estimatedCostUsd: number | null;
|
|
26
|
+
}
|
|
27
|
+
export interface WorkerModelUsage {
|
|
28
|
+
readonly model: string;
|
|
29
|
+
readonly usage: WorkerUsage;
|
|
30
|
+
}
|
|
31
|
+
export declare function modelUsageOf(value: unknown): readonly WorkerModelUsage[] | undefined;
|
|
12
32
|
export interface WorkerTotals {
|
|
13
33
|
readonly estimatedCostUsd: number | null;
|
|
14
34
|
readonly workerTurns: readonly WorkerTurnUsage[];
|
|
@@ -19,4 +39,9 @@ export declare function priceOf(value: unknown): number | null;
|
|
|
19
39
|
export declare function tokenCount(value: unknown): number | null;
|
|
20
40
|
export declare function usageOf(value: unknown): WorkerUsage;
|
|
21
41
|
export declare function sumUsage(values: readonly WorkerUsage[]): WorkerUsage;
|
|
42
|
+
export declare function sumPrices(values: readonly (number | null)[]): number | null;
|
|
22
43
|
export declare function workerTotals(workerTurns: readonly WorkerTurnUsage[]): WorkerTotals;
|
|
44
|
+
export declare function attemptsOf(value: unknown): readonly WorkerAttemptUsage[] | undefined;
|
|
45
|
+
export declare function attemptFields(value: unknown): {
|
|
46
|
+
readonly attempts?: readonly WorkerAttemptUsage[];
|
|
47
|
+
};
|