cloving 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +525 -185
- package/dist/src/agent-harness-shell.d.ts +12 -0
- package/dist/src/agent-harness-shell.js +90 -0
- package/dist/src/agent-harness-versions.d.ts +8 -0
- package/dist/src/agent-harness-versions.js +49 -0
- package/dist/src/agent-harnesses.d.ts +4 -0
- package/dist/src/agent-harnesses.js +13 -0
- package/dist/src/authority/commands.d.ts +1 -0
- package/dist/src/authority/commands.js +24 -4
- package/dist/src/authority/gate-reduction.d.ts +1 -0
- package/dist/src/authority/gate-reduction.js +18 -3
- package/dist/src/authority/gates.d.ts +2 -1
- package/dist/src/authority/gates.js +5 -1
- package/dist/src/authority/operations.js +1 -1
- package/dist/src/authority/reduction.d.ts +1 -1
- package/dist/src/authority/reduction.js +6 -1
- package/dist/src/authority/status-input.d.ts +1 -1
- package/dist/src/authority/status.d.ts +1 -0
- package/dist/src/authority/status.js +27 -3
- package/dist/src/authority/transitions.d.ts +5 -5
- package/dist/src/authority/transitions.js +6 -0
- package/dist/src/broker/actor/authority-delivery.js +1 -0
- package/dist/src/broker/actor/authority-queries.d.ts +7 -1
- package/dist/src/broker/actor/authority-queries.js +17 -2
- package/dist/src/broker/actor/authority-receipts.js +11 -1
- package/dist/src/broker/actor/authority-session.js +2 -2
- package/dist/src/broker/actor/authority-settings.js +4 -0
- package/dist/src/broker/actor/delivery-intents.d.ts +2 -1
- package/dist/src/broker/actor/delivery-intents.js +4 -4
- package/dist/src/broker/actor/effect-delivery.js +4 -1
- package/dist/src/broker/actor/effect-queries.d.ts +1 -0
- package/dist/src/broker/actor/effect-queries.js +7 -0
- package/dist/src/broker/actor/pin-check.js +1 -1
- package/dist/src/broker/actor/stop-plan.js +1 -1
- package/dist/src/broker/actor/turn-state.js +1 -1
- package/dist/src/broker/authority-admission.js +22 -9
- package/dist/src/broker/authority-restore.js +1 -0
- package/dist/src/broker/decision-restore.js +4 -4
- package/dist/src/broker/socket-address.d.ts +3 -1
- package/dist/src/broker/socket-address.js +2 -2
- package/dist/src/cli/arguments.d.ts +11 -13
- package/dist/src/cli/arguments.js +37 -107
- package/dist/src/cli/command-effects.d.ts +7 -0
- package/dist/src/cli/command-effects.js +39 -0
- package/dist/src/cli/commands.js +11 -4
- package/dist/src/cli/config-arguments.d.ts +11 -0
- package/dist/src/cli/config-arguments.js +59 -0
- package/dist/src/cli/config-command.d.ts +2 -0
- package/dist/src/cli/config-command.js +105 -0
- package/dist/src/cli/config-file.d.ts +3 -0
- package/dist/src/cli/config-file.js +50 -0
- package/dist/src/cli/config-lock.d.ts +7 -0
- package/dist/src/cli/config-lock.js +61 -0
- package/dist/src/cli/config-notice.d.ts +5 -0
- package/dist/src/cli/config-notice.js +46 -0
- package/dist/src/cli/doctor-github.d.ts +9 -0
- package/dist/src/cli/doctor-github.js +138 -0
- package/dist/src/cli/doctor-harness.d.ts +13 -0
- package/dist/src/cli/doctor-harness.js +242 -0
- package/dist/src/cli/doctor-local.d.ts +18 -0
- package/dist/src/cli/doctor-local.js +77 -0
- package/dist/src/cli/doctor-runtime.d.ts +15 -0
- package/dist/src/cli/doctor-runtime.js +176 -0
- package/dist/src/cli/doctor-service.d.ts +1 -0
- package/dist/src/cli/doctor-service.js +11 -0
- package/dist/src/cli/doctor-workflows.d.ts +3 -0
- package/dist/src/cli/doctor-workflows.js +45 -0
- package/dist/src/cli/doctor.d.ts +15 -0
- package/dist/src/cli/doctor.js +190 -0
- package/dist/src/cli/github-ci-progress.d.ts +8 -0
- package/dist/src/cli/github-ci-progress.js +83 -0
- package/dist/src/cli/github-retry.d.ts +6 -0
- package/dist/src/cli/github-retry.js +47 -0
- package/dist/src/cli/harness-probes.d.ts +22 -0
- package/dist/src/cli/harness-probes.js +183 -0
- package/dist/src/cli/main.d.ts +7 -1
- package/dist/src/cli/main.js +39 -61
- package/dist/src/cli/phone-arguments.d.ts +14 -0
- package/dist/src/cli/phone-arguments.js +37 -0
- package/dist/src/cli/phone-client.d.ts +2 -0
- package/dist/src/cli/phone-client.js +32 -0
- package/dist/src/cli/phone-command.d.ts +13 -0
- package/dist/src/cli/phone-command.js +101 -0
- package/dist/src/cli/probe-command.d.ts +36 -0
- package/dist/src/cli/probe-command.js +59 -0
- package/dist/src/cli/project-settings.d.ts +4 -0
- package/dist/src/cli/project-settings.js +33 -0
- package/dist/src/cli/render.d.ts +2 -1
- package/dist/src/cli/render.js +44 -28
- package/dist/src/cli/report-github.d.ts +18 -0
- package/dist/src/cli/report-github.js +200 -0
- package/dist/src/cli/report.d.ts +17 -0
- package/dist/src/cli/report.js +192 -0
- package/dist/src/cli/repository-arguments.d.ts +5 -0
- package/dist/src/cli/repository-arguments.js +34 -0
- package/dist/src/cli/runtime-arguments.d.ts +4 -0
- package/dist/src/cli/runtime-arguments.js +15 -0
- package/dist/src/cli/runtime-directory.d.ts +6 -2
- package/dist/src/cli/runtime-directory.js +72 -14
- package/dist/src/cli/toolchain.d.ts +2 -0
- package/dist/src/cli/toolchain.js +22 -2
- package/dist/src/cli/usage-render.d.ts +5 -0
- package/dist/src/cli/usage-render.js +40 -1
- package/dist/src/cli/usage.d.ts +3 -3
- package/dist/src/cli/usage.js +70 -44
- package/dist/src/cli/watch-actions.d.ts +2 -0
- package/dist/src/cli/watch-actions.js +4 -4
- package/dist/src/cli/watch-board-view.d.ts +1 -1
- package/dist/src/cli/watch-board-view.js +8 -2
- package/dist/src/cli/watch-board.js +23 -10
- package/dist/src/cli/watch-card-forms.js +2 -2
- package/dist/src/cli/watch-client.d.ts +1 -1
- package/dist/src/cli/watch-client.js +7 -2
- package/dist/src/cli/watch-header-view.d.ts +27 -0
- package/dist/src/cli/watch-header-view.js +116 -0
- package/dist/src/cli/watch-model.js +17 -4
- package/dist/src/cli/watch-page.js +48 -12
- package/dist/src/cli/watch-phone-client.d.ts +1 -0
- package/dist/src/cli/watch-phone-client.js +84 -0
- package/dist/src/cli/watch-phone-view.d.ts +56 -0
- package/dist/src/cli/watch-phone-view.js +113 -0
- package/dist/src/cli/watch-phone.d.ts +5 -0
- package/dist/src/cli/watch-phone.js +53 -0
- package/dist/src/cli/watch-pull-request.d.ts +3 -1
- package/dist/src/cli/watch-pull-request.js +4 -0
- package/dist/src/cli/watch-render.d.ts +9 -1
- package/dist/src/cli/watch-server.js +23 -5
- package/dist/src/cli/watch-turn.d.ts +4 -1
- package/dist/src/cli/watch-turn.js +37 -1
- package/dist/src/cli/watch-usage.js +5 -1
- package/dist/src/cli/watch-view.d.ts +6 -20
- package/dist/src/cli/watch-view.js +14 -106
- package/dist/src/cli.js +106 -23
- package/dist/src/command-settings.d.ts +16 -0
- package/dist/src/command-settings.js +42 -0
- package/dist/src/configuration-change.d.ts +11 -0
- package/dist/src/configuration-change.js +62 -0
- package/dist/src/configuration-display.d.ts +21 -0
- package/dist/src/configuration-display.js +69 -0
- package/dist/src/configuration-schema.d.ts +49 -0
- package/dist/src/configuration-schema.js +159 -0
- package/dist/src/daemon/claude-turn.d.ts +19 -5
- package/dist/src/daemon/claude-turn.js +116 -53
- package/dist/src/daemon/claude-worker.d.ts +3 -3
- package/dist/src/daemon/claude-worker.js +65 -76
- package/dist/src/daemon/command-journal.d.ts +5 -0
- package/dist/src/daemon/command-journal.js +50 -0
- package/dist/src/daemon/command-process.d.ts +28 -0
- package/dist/src/daemon/command-process.js +164 -0
- package/dist/src/daemon/command-worker.d.ts +19 -0
- package/dist/src/daemon/command-worker.js +182 -0
- package/dist/src/daemon/cursor-stream.d.ts +4 -0
- package/dist/src/daemon/cursor-stream.js +154 -0
- package/dist/src/daemon/daemon-adapters.d.ts +58 -0
- package/dist/src/daemon/daemon-adapters.js +102 -0
- package/dist/src/daemon/daemon-loops.d.ts +14 -0
- package/dist/src/daemon/daemon-loops.js +39 -0
- package/dist/src/daemon/daemon.d.ts +2 -33
- package/dist/src/daemon/daemon.js +126 -132
- package/dist/src/daemon/declared-input.d.ts +3 -0
- package/dist/src/daemon/declared-input.js +9 -0
- package/dist/src/daemon/delivery-router.js +1 -1
- package/dist/src/daemon/gemini-stream.d.ts +4 -0
- package/dist/src/daemon/gemini-stream.js +129 -0
- package/dist/src/daemon/github-ci-rerun.d.ts +26 -0
- package/dist/src/daemon/github-ci-rerun.js +92 -0
- package/dist/src/daemon/github-ci.js +89 -8
- package/dist/src/daemon/github-merge-call.d.ts +2 -0
- package/dist/src/daemon/github-merge.js +7 -3
- package/dist/src/daemon/github-methods.js +10 -0
- package/dist/src/daemon/github-operation.d.ts +1 -0
- package/dist/src/daemon/github-retry.js +8 -44
- package/dist/src/daemon/issue-queue.d.ts +1 -0
- package/dist/src/daemon/issue-queue.js +3 -26
- package/dist/src/daemon/notify.js +2 -1
- package/dist/src/daemon/opencode-stream.d.ts +5 -0
- package/dist/src/daemon/opencode-stream.js +87 -0
- package/dist/src/daemon/queue-status.d.ts +4 -0
- package/dist/src/daemon/queue-status.js +38 -0
- package/dist/src/daemon/retry-worktree.d.ts +18 -0
- package/dist/src/daemon/retry-worktree.js +139 -0
- package/dist/src/daemon/retrying-turn.d.ts +2 -0
- package/dist/src/daemon/retrying-turn.js +108 -30
- package/dist/src/daemon/schedule-journal.d.ts +19 -0
- package/dist/src/daemon/schedule-journal.js +57 -0
- package/dist/src/daemon/text-output.d.ts +18 -0
- package/dist/src/daemon/text-output.js +44 -0
- package/dist/src/daemon/ticket-registration.d.ts +5 -7
- package/dist/src/daemon/ticket-registration.js +85 -40
- package/dist/src/daemon/turn-command.d.ts +10 -0
- package/dist/src/daemon/turn-command.js +33 -0
- package/dist/src/daemon/turn-report.d.ts +18 -0
- package/dist/src/daemon/turn-report.js +79 -0
- package/dist/src/daemon/work-tree.d.ts +2 -1
- package/dist/src/daemon/work-tree.js +15 -12
- package/dist/src/daemon/workflow-generations.d.ts +32 -0
- package/dist/src/daemon/workflow-generations.js +57 -0
- package/dist/src/daemon/workflow-replay.d.ts +16 -0
- package/dist/src/daemon/workflow-replay.js +58 -0
- package/dist/src/daemon/workflow-schedules.d.ts +27 -0
- package/dist/src/daemon/workflow-schedules.js +185 -0
- package/dist/src/decision-wait.d.ts +1 -0
- package/dist/src/decision-wait.js +3 -0
- package/dist/src/delivery-backoff.d.ts +1 -0
- package/dist/src/delivery-backoff.js +3 -0
- package/dist/src/doctor-report.d.ts +24 -0
- package/dist/src/doctor-report.js +70 -0
- package/dist/src/execution-pin.d.ts +5 -0
- package/dist/src/execution-pin.js +67 -4
- package/dist/src/grok-result.d.ts +12 -0
- package/dist/src/grok-result.js +61 -0
- package/dist/src/harness-defaults.d.ts +35 -0
- package/dist/src/harness-defaults.js +121 -0
- package/dist/src/host/decision-resume.d.ts +35 -0
- package/dist/src/host/decision-resume.js +86 -0
- package/dist/src/host/gate-bridge.d.ts +48 -0
- package/dist/src/host/gate-bridge.js +124 -0
- package/dist/src/host/run-wait.d.ts +26 -0
- package/dist/src/host/run-wait.js +37 -0
- package/dist/src/host/start-delivery.d.ts +1 -1
- package/dist/src/host/start-delivery.js +10 -3
- package/dist/src/host/step-bridge-host.d.ts +6 -20
- package/dist/src/host/step-bridge-host.js +44 -58
- package/dist/src/merge-request.d.ts +19 -0
- package/dist/src/merge-request.js +32 -0
- package/dist/src/phone/canonical-json.d.ts +1 -0
- package/dist/src/phone/canonical-json.js +16 -0
- package/dist/src/phone/phone-link.d.ts +7 -0
- package/dist/src/phone/phone-link.js +21 -0
- package/dist/src/phone/qr-data.d.ts +8 -0
- package/dist/src/phone/qr-data.js +133 -0
- package/dist/src/phone/qr-matrix.d.ts +6 -0
- package/dist/src/phone/qr-matrix.js +175 -0
- package/dist/src/phone/qr-penalty.d.ts +3 -0
- package/dist/src/phone/qr-penalty.js +67 -0
- package/dist/src/phone/qr-picture.d.ts +5 -0
- package/dist/src/phone/qr-picture.js +24 -0
- package/dist/src/private-config.schema.json +263 -0
- package/dist/src/project-config.schema.json +65 -0
- package/dist/src/project-settings.d.ts +19 -0
- package/dist/src/project-settings.js +131 -0
- package/dist/src/relay/answer-check.d.ts +24 -0
- package/dist/src/relay/answer-check.js +145 -0
- package/dist/src/relay/answer-inbox.d.ts +15 -0
- package/dist/src/relay/answer-inbox.js +173 -0
- package/dist/src/relay/daemon-keys.d.ts +16 -0
- package/dist/src/relay/daemon-keys.js +75 -0
- package/dist/src/relay/decision-check.d.ts +3 -0
- package/dist/src/relay/decision-check.js +77 -0
- package/dist/src/relay/decision-close.d.ts +6 -0
- package/dist/src/relay/decision-close.js +72 -0
- package/dist/src/relay/decision-envelopes.d.ts +29 -0
- package/dist/src/relay/decision-envelopes.js +93 -0
- package/dist/src/relay/decision-watch.d.ts +14 -0
- package/dist/src/relay/decision-watch.js +68 -0
- package/dist/src/relay/envelope-post.d.ts +8 -0
- package/dist/src/relay/envelope-post.js +71 -0
- package/dist/src/relay/envelope.d.ts +28 -0
- package/dist/src/relay/envelope.js +53 -0
- package/dist/src/relay/hpke.d.ts +25 -0
- package/dist/src/relay/hpke.js +108 -0
- package/dist/src/relay/pairing-checks.d.ts +42 -0
- package/dist/src/relay/pairing-checks.js +172 -0
- package/dist/src/relay/pairing-follow.d.ts +8 -0
- package/dist/src/relay/pairing-follow.js +95 -0
- package/dist/src/relay/pairing-session.d.ts +29 -0
- package/dist/src/relay/pairing-session.js +87 -0
- package/dist/src/relay/phone-delivery.d.ts +51 -0
- package/dist/src/relay/phone-delivery.js +139 -0
- package/dist/src/relay/phone-devices.d.ts +36 -0
- package/dist/src/relay/phone-devices.js +46 -0
- package/dist/src/relay/phone-inbox.d.ts +18 -0
- package/dist/src/relay/phone-inbox.js +17 -0
- package/dist/src/relay/phone-operations.d.ts +18 -0
- package/dist/src/relay/phone-operations.js +121 -0
- package/dist/src/relay/phone-outbox.d.ts +21 -0
- package/dist/src/relay/phone-outbox.js +25 -0
- package/dist/src/relay/phone-socket.d.ts +6 -0
- package/dist/src/relay/phone-socket.js +63 -0
- package/dist/src/relay/relay-control.d.ts +7 -0
- package/dist/src/relay/relay-control.js +24 -0
- package/dist/src/relay/relay-files.d.ts +2 -0
- package/dist/src/relay/relay-files.js +23 -0
- package/dist/src/relay/relay-heartbeat.d.ts +17 -0
- package/dist/src/relay/relay-heartbeat.js +81 -0
- package/dist/src/relay/relay-http.d.ts +14 -0
- package/dist/src/relay/relay-http.js +63 -0
- package/dist/src/relay/relay-registration.d.ts +15 -0
- package/dist/src/relay/relay-registration.js +63 -0
- package/dist/src/relay/relay-service.d.ts +25 -0
- package/dist/src/relay/relay-service.js +216 -0
- package/dist/src/relay/relay-store.d.ts +48 -0
- package/dist/src/relay/relay-store.js +131 -0
- package/dist/src/relay/sealed-post.d.ts +25 -0
- package/dist/src/relay/sealed-post.js +52 -0
- package/dist/src/relay.d.ts +1 -0
- package/dist/src/relay.js +8 -0
- package/dist/src/report-statistics.d.ts +50 -0
- package/dist/src/report-statistics.js +70 -0
- package/dist/src/report.d.ts +171 -0
- package/dist/src/report.js +119 -0
- package/dist/src/repository-identity.d.ts +4 -0
- package/dist/src/repository-identity.js +4 -0
- package/dist/src/review-subject.d.ts +41 -0
- package/dist/src/review-subject.js +91 -0
- package/dist/src/run-wait.d.ts +23 -0
- package/dist/src/run-wait.js +20 -0
- package/dist/src/service/active-tickets.d.ts +4 -0
- package/dist/src/service/active-tickets.js +49 -0
- package/dist/src/service/command-effects.d.ts +4 -0
- package/dist/src/service/command-effects.js +16 -0
- package/dist/src/service/decision-handler.d.ts +4 -0
- package/dist/src/service/decision-handler.js +39 -4
- package/dist/src/service/gateway.js +18 -3
- package/dist/src/service/registry.d.ts +16 -3
- package/dist/src/service/registry.js +34 -3
- package/dist/src/service/replies.d.ts +9 -1
- package/dist/src/service/replies.js +12 -0
- package/dist/src/service/run-handlers.js +14 -55
- package/dist/src/service/run-metadata.d.ts +8 -0
- package/dist/src/service/run-metadata.js +53 -0
- package/dist/src/service/run-waits.d.ts +3 -0
- package/dist/src/service/run-waits.js +41 -0
- package/dist/src/service/service.d.ts +18 -2
- package/dist/src/service/service.js +23 -7
- package/dist/src/service/submission-handler.d.ts +0 -1
- package/dist/src/service/submission-handler.js +6 -34
- package/dist/src/service/worker-port.d.ts +1 -0
- package/dist/src/service/worker-totals.js +8 -23
- package/dist/src/step-bridge.d.ts +23 -0
- package/dist/src/steps/decision-gate.d.ts +2 -1
- package/dist/src/steps/decision-gate.js +7 -0
- package/dist/src/steps/merge-by-person.d.ts +2 -0
- package/dist/src/steps/merge-by-person.js +18 -0
- package/dist/src/steps/merge-when-green.d.ts +2 -0
- package/dist/src/steps/merge-when-green.js +62 -0
- package/dist/src/steps/review-by-agent.d.ts +5 -0
- package/dist/src/steps/review-by-agent.js +124 -0
- package/dist/src/steps/review-by-person.d.ts +4 -0
- package/dist/src/steps/review-by-person.js +16 -0
- package/dist/src/steps/review-subject.d.ts +2 -0
- package/dist/src/steps/review-subject.js +11 -0
- package/dist/src/steps/run-command.d.ts +2 -0
- package/dist/src/steps/run-command.js +15 -0
- package/dist/src/steps/sleep.d.ts +3 -0
- package/dist/src/steps/sleep.js +19 -0
- package/dist/src/steps/wait-for-decision.d.ts +2 -0
- package/dist/src/steps/wait-for-decision.js +71 -0
- package/dist/src/steps/wait-for-run.d.ts +5 -0
- package/dist/src/steps/wait-for-run.js +9 -0
- package/dist/src/storage/decision-snapshots.d.ts +1 -0
- package/dist/src/storage/decision-snapshots.js +7 -1
- package/dist/src/submission.d.ts +4 -0
- package/dist/src/submission.js +6 -2
- package/dist/src/testing.d.ts +29 -0
- package/dist/src/testing.js +264 -0
- package/dist/src/ticket-status-stream.d.ts +9 -0
- package/dist/src/ticket-status-stream.js +94 -0
- package/dist/src/token-prices.d.ts +12 -4
- package/dist/src/token-prices.js +15 -2
- package/dist/src/turn-profile.d.ts +1 -0
- package/dist/src/turn-profile.js +8 -1
- package/dist/src/worker-usage.d.ts +16 -0
- package/dist/src/worker-usage.js +57 -0
- package/dist/src/workflow-admission.d.ts +5 -0
- package/dist/src/workflow-candidate.d.ts +7 -2
- package/dist/src/workflow-candidate.js +47 -5
- package/dist/src/workflow-declaration.d.ts +21 -3
- package/dist/src/workflow-declaration.js +77 -9
- package/dist/src/workflow-discovery.d.ts +2 -1
- package/dist/src/workflow-discovery.js +4 -1
- package/dist/src/workflow-refusals.js +3 -0
- package/dist/src/workflow-schedule.d.ts +22 -0
- package/dist/src/workflow-schedule.js +53 -0
- package/dist/src/workflows.d.ts +11 -1
- package/dist/src/workflows.js +8 -0
- package/dist/tools/admit-workflow.d.ts +1 -0
- package/dist/tools/admit-workflow.js +18 -5
- package/dist/tools/doctor-adoption.d.ts +1 -0
- package/dist/tools/doctor-adoption.js +11 -0
- package/dist/tools/project-configuration.d.ts +4 -0
- package/dist/tools/project-configuration.js +47 -0
- package/dist/tools/self-host-processes.d.ts +1 -0
- package/dist/tools/self-host-processes.js +33 -22
- package/dist/tools/self-host-project.d.ts +4 -0
- package/dist/tools/self-host-project.js +61 -14
- package/dist/tools/self-host-runtime.d.ts +16 -0
- package/dist/tools/self-host-runtime.js +60 -0
- package/dist/tools/self-host-workflows.d.ts +1 -0
- package/dist/tools/self-host-workflows.js +36 -1
- package/dist/tools/self-host.js +86 -61
- package/dist/tools/workflow-candidate-counts.d.ts +6 -2
- package/dist/tools/workflow-candidate-counts.js +31 -16
- package/dist/tools/workflow-candidate-fields.d.ts +5 -0
- package/dist/tools/workflow-candidate-fields.js +24 -0
- package/dist/tools/workflow-candidate-helper-counts.d.ts +10 -0
- package/dist/tools/workflow-candidate-helper-counts.js +129 -0
- package/dist/tools/workflow-candidate-program.d.ts +2 -0
- package/dist/tools/workflow-candidate-program.js +36 -8
- package/dist/tools/workflow-candidate-source.js +77 -15
- package/dist/tools/workflow-candidate-syntax.d.ts +8 -2
- package/dist/tools/workflow-candidate-syntax.js +70 -26
- package/dist/tools/workflow-command.d.ts +1 -0
- package/dist/tools/workflow-command.js +143 -0
- package/dist/tools/workflow-folder-capture.d.ts +1 -0
- package/dist/tools/workflow-folder-capture.js +47 -2
- package/dist/tools/workflow-folders.d.ts +17 -1
- package/dist/tools/workflow-folders.js +59 -6
- package/dist/tools/workflow-test-hook.d.ts +7 -0
- package/dist/tools/workflow-test-hook.js +16 -0
- package/dist/tools/workflow-test-loader.d.ts +1 -0
- package/dist/tools/workflow-test-loader.js +10 -0
- package/dist/workflows/develop-ticket.js +1 -1
- package/dist/workflows/ticket-prompts.js +5 -1
- package/package.json +46 -4
- package/templates/develop/README.md +78 -0
- package/templates/develop/develop/accept.ts +11 -0
- package/templates/develop/develop/flow-tests.ts +357 -0
- package/templates/develop/develop/local.ts +40 -0
- package/templates/develop/develop/option-tests.ts +174 -0
- package/templates/develop/develop/partial-choice.ts +29 -0
- package/templates/develop/develop/partial.ts +28 -0
- package/templates/develop/develop/pull.ts +152 -0
- package/templates/develop/develop/queue-partial.ts +39 -0
- package/templates/develop/develop/refusal-tests.ts +174 -0
- package/templates/develop/develop/report.ts +156 -0
- package/templates/develop/develop/round.ts +40 -0
- package/templates/develop/develop/scenarios.ts +87 -0
- package/templates/develop/develop/turn.ts +67 -0
- package/templates/develop/develop.declaration.json +24 -0
- package/templates/develop/develop.test.ts +287 -0
- package/templates/develop/develop.ts +30 -0
- package/templates/develop/template.json +153 -0
- package/dist/src/chats/analysis-batches.d.ts +0 -42
- package/dist/src/chats/analysis-batches.js +0 -97
- package/dist/src/chats/analysis-checkpoint.d.ts +0 -29
- package/dist/src/chats/analysis-checkpoint.js +0 -31
- package/dist/src/chats/analysis-contract.d.ts +0 -80
- package/dist/src/chats/analysis-contract.js +0 -16
- package/dist/src/chats/analysis-data.d.ts +0 -3
- package/dist/src/chats/analysis-data.js +0 -85
- package/dist/src/chats/analysis-input.d.ts +0 -18
- package/dist/src/chats/analysis-input.js +0 -97
- package/dist/src/chats/analysis-links.d.ts +0 -2
- package/dist/src/chats/analysis-links.js +0 -25
- package/dist/src/chats/analysis-merge.d.ts +0 -16
- package/dist/src/chats/analysis-merge.js +0 -134
- package/dist/src/chats/analysis-prompt.d.ts +0 -18
- package/dist/src/chats/analysis-prompt.js +0 -42
- package/dist/src/chats/analysis-proposal.d.ts +0 -4
- package/dist/src/chats/analysis-proposal.js +0 -41
- package/dist/src/chats/analysis-provenance.d.ts +0 -4
- package/dist/src/chats/analysis-provenance.js +0 -99
- package/dist/src/chats/analysis-shape.d.ts +0 -4
- package/dist/src/chats/analysis-shape.js +0 -235
- package/dist/src/chats/analysis.d.ts +0 -3
- package/dist/src/chats/analysis.js +0 -42
- package/dist/src/chats/corpus-input.d.ts +0 -5
- package/dist/src/chats/corpus-input.js +0 -288
- package/dist/src/chats/destination.d.ts +0 -4
- package/dist/src/chats/destination.js +0 -96
- package/dist/src/chats/import.d.ts +0 -15
- package/dist/src/chats/import.js +0 -243
- package/dist/src/chats/input-file.d.ts +0 -3
- package/dist/src/chats/input-file.js +0 -32
- package/dist/src/chats/normalize.d.ts +0 -29
- package/dist/src/chats/normalize.js +0 -155
- package/dist/src/chats/previous-import.d.ts +0 -5
- package/dist/src/chats/previous-import.js +0 -34
- package/dist/src/chats/reader.d.ts +0 -21
- package/dist/src/chats/reader.js +0 -118
- package/dist/src/chats/redact-import.d.ts +0 -14
- package/dist/src/chats/redact-import.js +0 -141
- package/dist/src/chats/redaction.d.ts +0 -41
- package/dist/src/chats/redaction.js +0 -161
- package/dist/src/chats/reference-mapping.d.ts +0 -16
- package/dist/src/chats/reference-mapping.js +0 -153
- package/dist/src/chats/revision-input.d.ts +0 -3
- package/dist/src/chats/revision-input.js +0 -180
- package/dist/src/chats/revision.d.ts +0 -48
- package/dist/src/chats/revision.js +0 -94
- package/dist/src/chats/selection.d.ts +0 -25
- package/dist/src/chats/selection.js +0 -109
- package/dist/src/chats/source.d.ts +0 -23
- package/dist/src/chats/source.js +0 -135
- package/dist/src/chats/structure.d.ts +0 -57
- package/dist/src/chats/structure.js +0 -216
- package/dist/src/chats/workflow-generation-projection.d.ts +0 -8
- package/dist/src/chats/workflow-generation-projection.js +0 -75
- package/dist/src/chats/workflow-generation-source.d.ts +0 -25
- package/dist/src/chats/workflow-generation-source.js +0 -124
- package/dist/src/chats/workflow-generation-text.d.ts +0 -23
- package/dist/src/chats/workflow-generation-text.js +0 -74
- package/dist/src/chats/workflow-generation.d.ts +0 -69
- package/dist/src/chats/workflow-generation.js +0 -142
- package/dist/src/daemon/analysis-launch.d.ts +0 -5
- package/dist/src/daemon/analysis-launch.js +0 -81
- package/dist/src/daemon/analysis-token.d.ts +0 -6
- package/dist/src/daemon/analysis-token.js +0 -88
- package/dist/src/daemon/analysis-worker.d.ts +0 -20
- package/dist/src/daemon/analysis-worker.js +0 -271
- package/dist/src/daemon/chats-batch-binding.d.ts +0 -23
- package/dist/src/daemon/chats-batch-binding.js +0 -99
- package/dist/src/daemon/chats-capture.d.ts +0 -18
- package/dist/src/daemon/chats-capture.js +0 -194
- package/dist/src/daemon/chats-checkpoints.d.ts +0 -41
- package/dist/src/daemon/chats-checkpoints.js +0 -186
- package/dist/src/daemon/chats-files.d.ts +0 -42
- package/dist/src/daemon/chats-files.js +0 -252
- package/dist/src/daemon/chats-follow-up.d.ts +0 -38
- package/dist/src/daemon/chats-follow-up.js +0 -180
- package/dist/src/daemon/chats-question.d.ts +0 -15
- package/dist/src/daemon/chats-question.js +0 -93
- package/dist/src/daemon/chats-worker.d.ts +0 -13
- package/dist/src/daemon/chats-worker.js +0 -201
- package/dist/workflows/analyze-chats.d.ts +0 -15
- package/dist/workflows/analyze-chats.declaration.json +0 -22
- package/dist/workflows/analyze-chats.js +0 -250
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { record } from "./protocol.js";
|
|
2
|
+
export function reviewSubjectText(subject) {
|
|
3
|
+
if (record(subject) === undefined)
|
|
4
|
+
throw new Error("invalid-review-subject");
|
|
5
|
+
if ("draft" in subject)
|
|
6
|
+
return draftReviewText(subject);
|
|
7
|
+
if (!commitId(subject.commit) ||
|
|
8
|
+
typeof subject.target !== "string" ||
|
|
9
|
+
subject.target.trim() === "")
|
|
10
|
+
throw new Error("invalid-review-subject");
|
|
11
|
+
const identity = [
|
|
12
|
+
"cloving-review-subject",
|
|
13
|
+
1,
|
|
14
|
+
"commit",
|
|
15
|
+
subject.target,
|
|
16
|
+
subject.commit,
|
|
17
|
+
];
|
|
18
|
+
if (subject.number !== undefined)
|
|
19
|
+
identity.push(subject.number);
|
|
20
|
+
return JSON.stringify(identity);
|
|
21
|
+
}
|
|
22
|
+
function draftReviewText(subject) {
|
|
23
|
+
if (typeof subject.draft !== "string" ||
|
|
24
|
+
subject.draft.trim() === "" ||
|
|
25
|
+
(subject.commit !== undefined && !commitId(subject.commit)))
|
|
26
|
+
throw new Error("invalid-review-subject");
|
|
27
|
+
return JSON.stringify([
|
|
28
|
+
"cloving-review-subject",
|
|
29
|
+
1,
|
|
30
|
+
"draft",
|
|
31
|
+
subject.commit ?? null,
|
|
32
|
+
subject.draft,
|
|
33
|
+
]);
|
|
34
|
+
}
|
|
35
|
+
export function commitId(value) {
|
|
36
|
+
return (typeof value === "string" && /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/.test(value));
|
|
37
|
+
}
|
|
38
|
+
export function reviewReport(text) {
|
|
39
|
+
const trimmed = text.trimEnd();
|
|
40
|
+
const start = trimmed.lastIndexOf("\n") + 1;
|
|
41
|
+
const line = trimmed.slice(start);
|
|
42
|
+
const verdict = line.slice("Review verdict: ".length);
|
|
43
|
+
if (!line.startsWith("Review verdict: ") ||
|
|
44
|
+
(verdict !== "accept" && verdict !== "change"))
|
|
45
|
+
return { reviewVerdict: null, feedback: text };
|
|
46
|
+
return {
|
|
47
|
+
reviewVerdict: verdict,
|
|
48
|
+
feedback: trimmed.slice(0, start).trimEnd(),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export function reviewReportStream(limit) {
|
|
52
|
+
let text = "";
|
|
53
|
+
let trailing = "";
|
|
54
|
+
let prefix = "";
|
|
55
|
+
let length = 0;
|
|
56
|
+
let contentLength = 0;
|
|
57
|
+
let verdict = null;
|
|
58
|
+
const finish = () => {
|
|
59
|
+
if (contentLength > 0)
|
|
60
|
+
verdict =
|
|
61
|
+
contentLength > 24
|
|
62
|
+
? null
|
|
63
|
+
: reviewReport(prefix.slice(0, contentLength)).reviewVerdict;
|
|
64
|
+
prefix = "";
|
|
65
|
+
length = 0;
|
|
66
|
+
contentLength = 0;
|
|
67
|
+
};
|
|
68
|
+
return {
|
|
69
|
+
write: (chunk) => {
|
|
70
|
+
const trimmed = chunk.trimEnd();
|
|
71
|
+
if (trimmed === "")
|
|
72
|
+
trailing = (trailing + chunk).slice(-limit);
|
|
73
|
+
if (trimmed !== "") {
|
|
74
|
+
text = (text + trailing + trimmed).slice(-limit);
|
|
75
|
+
trailing = chunk.slice(trimmed.length).slice(-limit);
|
|
76
|
+
}
|
|
77
|
+
for (const [index, part] of chunk.split("\n").entries()) {
|
|
78
|
+
if (index > 0)
|
|
79
|
+
finish();
|
|
80
|
+
if (part.trimEnd() !== "")
|
|
81
|
+
contentLength = Math.min(25, length + part.trimEnd().length);
|
|
82
|
+
prefix = (prefix + part).slice(0, 24);
|
|
83
|
+
length = Math.min(25, length + part.length);
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
result: () => {
|
|
87
|
+
finish();
|
|
88
|
+
return { reviewVerdict: verdict, feedback: reviewReport(text).feedback };
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { RunWaitOutcome, RunWaitRequest } from "./step-bridge.ts";
|
|
2
|
+
export interface RunWaitTarget {
|
|
3
|
+
readonly parentRunId: string | null;
|
|
4
|
+
readonly status: string;
|
|
5
|
+
readonly endedAt: number | null;
|
|
6
|
+
readonly outcome: RunWaitOutcome | null;
|
|
7
|
+
}
|
|
8
|
+
export type RunWaitResult = {
|
|
9
|
+
readonly kind: "waiting";
|
|
10
|
+
readonly deadline: number;
|
|
11
|
+
} | {
|
|
12
|
+
readonly kind: "completed";
|
|
13
|
+
readonly outcome: RunWaitOutcome;
|
|
14
|
+
} | {
|
|
15
|
+
readonly kind: "refused";
|
|
16
|
+
readonly reason: string;
|
|
17
|
+
};
|
|
18
|
+
export declare function runWaitResult(request: RunWaitRequest, context: {
|
|
19
|
+
readonly callerRunId: string;
|
|
20
|
+
readonly startedAt: number;
|
|
21
|
+
readonly now: number;
|
|
22
|
+
readonly target: RunWaitTarget | undefined;
|
|
23
|
+
}): RunWaitResult;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
function validSeconds(seconds) {
|
|
2
|
+
return Number.isInteger(seconds) && seconds >= 1 && seconds <= 86400;
|
|
3
|
+
}
|
|
4
|
+
export function runWaitResult(request, context) {
|
|
5
|
+
const { target, callerRunId, startedAt, now } = context;
|
|
6
|
+
const seconds = request.maximumWaitSeconds;
|
|
7
|
+
if (!validSeconds(seconds) ||
|
|
8
|
+
target?.parentRunId !== callerRunId ||
|
|
9
|
+
request.runId === callerRunId)
|
|
10
|
+
return { kind: "refused", reason: "run-wait-refused" };
|
|
11
|
+
const deadline = startedAt + seconds * 1000;
|
|
12
|
+
if (["completed", "failed", "cancelled"].includes(target.status) &&
|
|
13
|
+
target.outcome !== null &&
|
|
14
|
+
target.endedAt !== null &&
|
|
15
|
+
target.endedAt <= deadline)
|
|
16
|
+
return { kind: "completed", outcome: target.outcome };
|
|
17
|
+
if (now >= deadline)
|
|
18
|
+
return { kind: "refused", reason: "run-wait-timeout" };
|
|
19
|
+
return { kind: "waiting", deadline };
|
|
20
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type Fields } from "../protocol.ts";
|
|
2
|
+
import type { ServiceContext } from "./replies.ts";
|
|
3
|
+
export declare function activeWorkflow(context: ServiceContext, workflowId: string): Promise<Fields[]>;
|
|
4
|
+
export declare function queueOverview(context: ServiceContext): Promise<Fields>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { record } from "../protocol.js";
|
|
2
|
+
export async function activeWorkflow(context, workflowId) {
|
|
3
|
+
const workflows = await context.authority.queries.workflowIds();
|
|
4
|
+
const state = await context.authority.state();
|
|
5
|
+
const queueRun = async (runId) => workflows[runId] === "develop-issue" ||
|
|
6
|
+
(await context.authority.queries.manifest(runId))?.queue === true;
|
|
7
|
+
const runs = Object.values(state.runs).filter((run) => !["completed", "failed", "cancelled"].includes(run.status));
|
|
8
|
+
const own = runs.filter((run) => workflows[run.runId] === workflowId);
|
|
9
|
+
const queued = workflowId === "develop-issue" ||
|
|
10
|
+
context.registry.byId(workflowId)?.queue === true ||
|
|
11
|
+
(await Promise.all(own.map((run) => queueRun(run.runId)))).includes(true);
|
|
12
|
+
const active = await Promise.all(runs.map(async (run) => {
|
|
13
|
+
if (workflows[run.runId] !== workflowId &&
|
|
14
|
+
!(queued && (await queueRun(run.runId))))
|
|
15
|
+
return undefined;
|
|
16
|
+
return storedTicket(context, state.details[run.runId]?.input);
|
|
17
|
+
}));
|
|
18
|
+
return active.filter((input) => input !== undefined);
|
|
19
|
+
}
|
|
20
|
+
export async function queueOverview(context) {
|
|
21
|
+
const workflow = context.registry.workflowIds
|
|
22
|
+
.map((id) => context.registry.byId(id))
|
|
23
|
+
.find((workflow) => workflow?.admission !== undefined);
|
|
24
|
+
if (workflow?.admission === undefined)
|
|
25
|
+
return {};
|
|
26
|
+
const active = await activeWorkflow(context, workflow.workflowId);
|
|
27
|
+
return {
|
|
28
|
+
queue: {
|
|
29
|
+
lanes: workflow.admission === "when-idle" ? 1 : workflow.admission,
|
|
30
|
+
busy: active.length,
|
|
31
|
+
skipped: [
|
|
32
|
+
...active.flatMap((input) => typeof input["ticketId"] === "string"
|
|
33
|
+
? [{ ticketId: input["ticketId"], reason: "ticket-active" }]
|
|
34
|
+
: []),
|
|
35
|
+
...(workflow.resolver.skippedTickets?.() ?? []),
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
async function storedTicket(context, digest) {
|
|
41
|
+
const text = digest
|
|
42
|
+
? await context.authority.queries.document(digest)
|
|
43
|
+
: undefined;
|
|
44
|
+
const input = record(JSON.parse(text ?? "null")) ?? {};
|
|
45
|
+
const ticket = record(record(input["input"])?.["ticket"]);
|
|
46
|
+
return ticket === undefined
|
|
47
|
+
? input
|
|
48
|
+
: { ...input, ticketId: ticket["id"], ticket: ticket["text"] };
|
|
49
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ServiceContext } from "./replies.ts";
|
|
2
|
+
import type { Fields } from "../protocol.ts";
|
|
3
|
+
import type { OperationView } from "../broker/actor/authority.ts";
|
|
4
|
+
export declare function commandFields(context: ServiceContext, operations: readonly OperationView[]): Promise<Fields>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export async function commandFields(context, operations) {
|
|
2
|
+
const effects = operations
|
|
3
|
+
.filter((operation) => operation.capability === "command")
|
|
4
|
+
.map((operation) => ({
|
|
5
|
+
operationId: operation.operationId,
|
|
6
|
+
name: operation.method.slice(4),
|
|
7
|
+
state: operation.status,
|
|
8
|
+
exitCode: null,
|
|
9
|
+
durationMilliseconds: null,
|
|
10
|
+
}));
|
|
11
|
+
if (effects.length === 0)
|
|
12
|
+
return {};
|
|
13
|
+
return {
|
|
14
|
+
commandEffects: (await context.commandEffects?.(effects)) ?? effects,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -5,5 +5,9 @@ export declare function feedbackOf(context: ServiceContext, scope: {
|
|
|
5
5
|
readonly state: StoredState;
|
|
6
6
|
readonly runId: string;
|
|
7
7
|
}): Promise<readonly Fields[]>;
|
|
8
|
+
export declare function decidedOf(context: ServiceContext, scope: {
|
|
9
|
+
readonly state: StoredState;
|
|
10
|
+
readonly runId: string;
|
|
11
|
+
}): Promise<readonly Fields[]>;
|
|
8
12
|
export declare function questions(context: ServiceContext, parameters: Fields): Promise<Reply>;
|
|
9
13
|
export declare function decision(context: ServiceContext, parameters: Fields): Promise<Reply>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { delivers, gateKey } from "../authority/gates.js";
|
|
2
|
+
import { isDeviceActor } from "../authority/commands.js";
|
|
3
|
+
import { gateDelivery } from "../authority/reduction.js";
|
|
3
4
|
import { documentDigest } from "../broker/decision-restore.js";
|
|
4
5
|
import { committed, failed, invalidRequest, isIdentifier, publicReceipt, rejection, result, wholeNumber, } from "./replies.js";
|
|
5
6
|
const decisions = {
|
|
@@ -43,6 +44,25 @@ export async function feedbackOf(context, scope) {
|
|
|
43
44
|
}
|
|
44
45
|
return shown;
|
|
45
46
|
}
|
|
47
|
+
export async function decidedOf(context, scope) {
|
|
48
|
+
const decided = typed(scope.state).filter((gate) => gate.runId === scope.runId &&
|
|
49
|
+
gate.outcome !== null &&
|
|
50
|
+
gate.outcome.decision !== null);
|
|
51
|
+
const shown = [];
|
|
52
|
+
for (const gate of decided) {
|
|
53
|
+
const page = await context.authority.queries.eventsAfter({
|
|
54
|
+
after: (gate.outcome?.sequence ?? 1) - 1,
|
|
55
|
+
limit: 1,
|
|
56
|
+
});
|
|
57
|
+
const actor = page.events[0]?.payload["actor"];
|
|
58
|
+
shown.push({
|
|
59
|
+
decisionId: decisionId(gate),
|
|
60
|
+
decision: gate.outcome?.decision ?? null,
|
|
61
|
+
actor: typeof actor === "string" ? actor : "local",
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return shown;
|
|
65
|
+
}
|
|
46
66
|
async function described(context, shown) {
|
|
47
67
|
const { state, gate } = shown;
|
|
48
68
|
const { queries } = context.authority;
|
|
@@ -120,7 +140,20 @@ function textLimit(context, command) {
|
|
|
120
140
|
? { bytes: feedbackBytes, name: "A feedback text" }
|
|
121
141
|
: { bytes: context.textBytes, name: "An answer" };
|
|
122
142
|
}
|
|
143
|
+
function actorOf(parameters) {
|
|
144
|
+
const actor = parameters["actor"] ?? null;
|
|
145
|
+
if (actor === null)
|
|
146
|
+
return null;
|
|
147
|
+
return isDeviceActor(actor) ? actor : undefined;
|
|
148
|
+
}
|
|
123
149
|
function decisionRequest(parameters) {
|
|
150
|
+
const actor = actorOf(parameters);
|
|
151
|
+
const fields = decisionFields(parameters);
|
|
152
|
+
if (actor === undefined || fields === undefined)
|
|
153
|
+
return undefined;
|
|
154
|
+
return { ...fields, actor };
|
|
155
|
+
}
|
|
156
|
+
function decisionFields(parameters) {
|
|
124
157
|
const { command, reference, expectedRevision, generation } = parameters;
|
|
125
158
|
const { subjectDigest, commandId } = parameters;
|
|
126
159
|
const text = parameters["text"] ?? null;
|
|
@@ -183,6 +216,7 @@ export async function decision(context, parameters) {
|
|
|
183
216
|
generation: request.generation,
|
|
184
217
|
subject: request.subjectDigest,
|
|
185
218
|
...(text === null ? {} : { answer: documentDigest(text) }),
|
|
219
|
+
...(request.actor === null ? {} : { actor: request.actor }),
|
|
186
220
|
},
|
|
187
221
|
documents: text === null ? [] : [text],
|
|
188
222
|
});
|
|
@@ -203,9 +237,9 @@ export async function decision(context, parameters) {
|
|
|
203
237
|
}
|
|
204
238
|
async function continuationState(context, decided) {
|
|
205
239
|
const { gate, run } = decided;
|
|
206
|
-
if (!
|
|
240
|
+
if (!delivers(gate))
|
|
207
241
|
return "held";
|
|
208
|
-
const { operationId } =
|
|
242
|
+
const { operationId } = gateDelivery(gate);
|
|
209
243
|
const operation = (await context.authority.operations()).find((item) => item.operationId === operationId);
|
|
210
244
|
if (operation?.deliveries.some((delivery) => delivery.outcome === "sent"))
|
|
211
245
|
return "admitted";
|
|
@@ -224,6 +258,7 @@ async function recorded(context, outcome) {
|
|
|
224
258
|
decisionId: decisionId(gate),
|
|
225
259
|
runId,
|
|
226
260
|
decision: gate.outcome?.decision ?? null,
|
|
261
|
+
actor: stored.command.actor ?? null,
|
|
227
262
|
commandId,
|
|
228
263
|
replayed: outcome.replayed,
|
|
229
264
|
receipt: publicReceipt(stored),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { invalidCommand, serializable, textList, unserializable, } from "../broker/actor/authority-receipts.js";
|
|
2
2
|
import { record } from "../protocol.js";
|
|
3
|
+
import { commandLimits } from "../command-settings.js";
|
|
3
4
|
export const workerCommandBound = 1_000;
|
|
4
5
|
const permitted = {
|
|
5
6
|
operator: [
|
|
@@ -10,6 +11,7 @@ const permitted = {
|
|
|
10
11
|
"cancel-run",
|
|
11
12
|
],
|
|
12
13
|
worker: [
|
|
14
|
+
"record-schedule-skip",
|
|
13
15
|
"mark-started",
|
|
14
16
|
"open-gate",
|
|
15
17
|
"register-wait",
|
|
@@ -64,8 +66,17 @@ function refusal(submission, textBytes) {
|
|
|
64
66
|
};
|
|
65
67
|
return undefined;
|
|
66
68
|
}
|
|
69
|
+
async function reportLimit(parts, submission) {
|
|
70
|
+
if (submission.command["kind"] !== "report-effect" ||
|
|
71
|
+
!submission.documents.some((text) => Buffer.byteLength(text) > parts.textBytes))
|
|
72
|
+
return parts.textBytes;
|
|
73
|
+
const operation = await parts.authority.effects.operation(String(submission.command["operationId"]));
|
|
74
|
+
return operation?.capability === "command"
|
|
75
|
+
? commandLimits.resultBytes
|
|
76
|
+
: parts.textBytes;
|
|
77
|
+
}
|
|
67
78
|
export function commandGateway(parts) {
|
|
68
|
-
const { authority, registry, clock
|
|
79
|
+
const { authority, registry, clock } = parts;
|
|
69
80
|
const bound = parts.pendingWorkerCommands ?? workerCommandBound;
|
|
70
81
|
let pending = 0;
|
|
71
82
|
async function manifest(command) {
|
|
@@ -74,7 +85,11 @@ export function commandGateway(parts) {
|
|
|
74
85
|
return registry.byPin(String(command["workflow"]))?.manifest;
|
|
75
86
|
if (!pinned.includes(kind))
|
|
76
87
|
return undefined;
|
|
77
|
-
const
|
|
88
|
+
const runId = String(command["runId"]);
|
|
89
|
+
const stored = await authority.queries.manifest(runId);
|
|
90
|
+
if (stored?.bundleDigest !== undefined)
|
|
91
|
+
return stored;
|
|
92
|
+
const run = (await authority.state()).runs[runId];
|
|
78
93
|
return registry.byPin(run?.workflow ?? "")?.manifest;
|
|
79
94
|
}
|
|
80
95
|
async function forwarded(submission) {
|
|
@@ -109,7 +124,7 @@ export function commandGateway(parts) {
|
|
|
109
124
|
const submission = checked(given.principal, copy);
|
|
110
125
|
if (submission === undefined)
|
|
111
126
|
return invalidCommand;
|
|
112
|
-
const refused = refusal(submission,
|
|
127
|
+
const refused = refusal(submission, await reportLimit(parts, submission));
|
|
113
128
|
if (refused !== undefined)
|
|
114
129
|
return refused;
|
|
115
130
|
return submission.principal === "worker"
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import type { WorkflowStage, WorkflowStages } from "../workflow-declaration.ts";
|
|
1
|
+
import type { CommandWaits, WorkflowStage, WorkflowStages } from "../workflow-declaration.ts";
|
|
2
2
|
import type { SubmissionContract } from "../submission.ts";
|
|
3
3
|
import type { ExecutionManifest } from "../workflow-admission.ts";
|
|
4
|
+
import type { AvailableManifest } from "../broker/actor/delivery-intents.ts";
|
|
5
|
+
export interface WorkflowBundleStore {
|
|
6
|
+
readonly directory: string;
|
|
7
|
+
readonly repository: string;
|
|
8
|
+
}
|
|
4
9
|
export type Resolution = {
|
|
5
10
|
readonly kind: "resolved";
|
|
6
11
|
readonly input: unknown;
|
|
@@ -23,6 +28,7 @@ export interface Resolver {
|
|
|
23
28
|
readonly skippedTickets?: () => readonly Readonly<Record<string, unknown>>[];
|
|
24
29
|
}
|
|
25
30
|
export interface WorkflowRegistration {
|
|
31
|
+
readonly queue?: boolean;
|
|
26
32
|
readonly workflowId: string;
|
|
27
33
|
readonly manifest: ExecutionManifest;
|
|
28
34
|
readonly availability: "available" | "unavailable";
|
|
@@ -31,6 +37,8 @@ export interface WorkflowRegistration {
|
|
|
31
37
|
readonly effectLimit?: number;
|
|
32
38
|
readonly stages?: readonly WorkflowStage[];
|
|
33
39
|
readonly handoffs?: readonly string[];
|
|
40
|
+
readonly commands?: readonly string[];
|
|
41
|
+
readonly commandWaits?: CommandWaits;
|
|
34
42
|
readonly admission?: "when-idle" | number;
|
|
35
43
|
}
|
|
36
44
|
export interface Registered extends WorkflowRegistration {
|
|
@@ -41,6 +49,11 @@ export interface Registry {
|
|
|
41
49
|
readonly workflowStages: WorkflowStages;
|
|
42
50
|
readonly byId: (workflowId: string) => Registered | undefined;
|
|
43
51
|
readonly byPin: (pin: string) => Registered | undefined;
|
|
44
|
-
readonly
|
|
52
|
+
readonly bundle: (pinned: ExecutionManifest) => Promise<string | undefined>;
|
|
53
|
+
readonly available: AvailableManifest;
|
|
45
54
|
}
|
|
46
|
-
export declare function workflowRegistry(workflows: readonly WorkflowRegistration[],
|
|
55
|
+
export declare function workflowRegistry(workflows: readonly WorkflowRegistration[], options?: {
|
|
56
|
+
readonly retainedWorkflows?: readonly WorkflowRegistration[];
|
|
57
|
+
readonly workflowBundles?: WorkflowBundleStore;
|
|
58
|
+
readonly retainedWorkflow?: AvailableManifest;
|
|
59
|
+
}): Registry;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { workflowPin } from "../broker/workflow-pin.js";
|
|
2
2
|
import { declaredManifest } from "../execution-pin.js";
|
|
3
|
+
import { readRetainedWorkflowBundle } from "../../tools/workflow-bundles.js";
|
|
3
4
|
function registered(workflow) {
|
|
4
5
|
const manifest = declaredManifest(workflow.manifest, workflow);
|
|
5
6
|
return {
|
|
@@ -9,10 +10,32 @@ function registered(workflow) {
|
|
|
9
10
|
pin: workflowPin(manifest),
|
|
10
11
|
};
|
|
11
12
|
}
|
|
12
|
-
|
|
13
|
+
function availableVersions(workflow) {
|
|
14
|
+
if (workflow.availability !== "available")
|
|
15
|
+
return [];
|
|
16
|
+
if (workflow.manifest.bundleDigest === undefined)
|
|
17
|
+
return [workflow];
|
|
18
|
+
const manifest = { ...workflow.manifest };
|
|
19
|
+
delete manifest.bundleDigest;
|
|
20
|
+
return [workflow, { ...workflow, manifest, pin: workflowPin(manifest) }];
|
|
21
|
+
}
|
|
22
|
+
export function workflowRegistry(workflows, options = {}) {
|
|
13
23
|
const current = workflows.map(registered);
|
|
14
|
-
const available = [
|
|
24
|
+
const available = [
|
|
25
|
+
...current,
|
|
26
|
+
...(options.retainedWorkflows ?? []).map(registered),
|
|
27
|
+
].flatMap(availableVersions);
|
|
15
28
|
const byPin = (pin) => available.find((workflow) => workflow.pin === pin);
|
|
29
|
+
const bundle = async (pinned) => {
|
|
30
|
+
if (pinned.bundleDigest === undefined ||
|
|
31
|
+
options.workflowBundles === undefined)
|
|
32
|
+
return undefined;
|
|
33
|
+
const retained = await readRetainedWorkflowBundle({
|
|
34
|
+
...options.workflowBundles,
|
|
35
|
+
id: pinned.bundleDigest,
|
|
36
|
+
});
|
|
37
|
+
return retained.kind === "available" ? retained.directory : undefined;
|
|
38
|
+
};
|
|
16
39
|
return {
|
|
17
40
|
workflowIds: current.map((workflow) => workflow.workflowId),
|
|
18
41
|
workflowStages: Object.fromEntries(current.flatMap((workflow) => workflow.stages === undefined
|
|
@@ -20,6 +43,14 @@ export function workflowRegistry(workflows, retainedWorkflows = []) {
|
|
|
20
43
|
: [[workflow.workflowId, workflow.stages]])),
|
|
21
44
|
byId: (workflowId) => current.find((workflow) => workflow.workflowId === workflowId),
|
|
22
45
|
byPin,
|
|
23
|
-
|
|
46
|
+
bundle,
|
|
47
|
+
available: (pinned) => {
|
|
48
|
+
const manifest = byPin(workflowPin(pinned))?.manifest;
|
|
49
|
+
if (pinned.bundleDigest === undefined)
|
|
50
|
+
return manifest;
|
|
51
|
+
return bundle(pinned).then((directory) => directory !== undefined
|
|
52
|
+
? (manifest ?? options.retainedWorkflow?.(pinned))
|
|
53
|
+
: undefined);
|
|
54
|
+
},
|
|
24
55
|
};
|
|
25
56
|
}
|
|
@@ -3,8 +3,11 @@ import type { Fields, Reply } from "../protocol.ts";
|
|
|
3
3
|
import type { ChangeSignal } from "./changes.ts";
|
|
4
4
|
import type { Gateway } from "./gateway.ts";
|
|
5
5
|
import type { Registry } from "./registry.ts";
|
|
6
|
-
import type
|
|
6
|
+
import { type WorkflowRefusal } from "../workflow-refusals.ts";
|
|
7
|
+
import type { CommandEffects } from "../command-settings.ts";
|
|
7
8
|
export interface ServiceContext {
|
|
9
|
+
readonly workerHarness?: (operationId: string) => Promise<string | undefined>;
|
|
10
|
+
readonly commandEffects?: CommandEffects;
|
|
8
11
|
readonly authority: Authority;
|
|
9
12
|
readonly registry: Registry;
|
|
10
13
|
readonly workflowRefusals?: readonly WorkflowRefusal[];
|
|
@@ -18,6 +21,11 @@ export interface ServiceContext {
|
|
|
18
21
|
readonly worldReports?: () => readonly unknown[];
|
|
19
22
|
readonly changed?: ChangeSignal["next"];
|
|
20
23
|
}
|
|
24
|
+
export declare function queryMetadata(options: {
|
|
25
|
+
readonly workerHarness?: ServiceContext["workerHarness"];
|
|
26
|
+
readonly commandEffects?: CommandEffects;
|
|
27
|
+
readonly workflowRefusals?: readonly WorkflowRefusal[];
|
|
28
|
+
}): Pick<ServiceContext, "workerHarness" | "commandEffects" | "workflowRefusals">;
|
|
21
29
|
export declare function result(kind: string, fields: Fields): Reply;
|
|
22
30
|
export declare function failed(code: string, extra: Fields): Reply;
|
|
23
31
|
export declare function invalidRequest(detail: string): Reply;
|
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import { isRecordKey } from "../authority/commands.js";
|
|
2
|
+
import { workflowRefusals, } from "../workflow-refusals.js";
|
|
3
|
+
export function queryMetadata(options) {
|
|
4
|
+
return {
|
|
5
|
+
...(options.workerHarness === undefined
|
|
6
|
+
? {}
|
|
7
|
+
: { workerHarness: options.workerHarness }),
|
|
8
|
+
...(options.commandEffects === undefined
|
|
9
|
+
? {}
|
|
10
|
+
: { commandEffects: options.commandEffects }),
|
|
11
|
+
workflowRefusals: workflowRefusals(options.workflowRefusals),
|
|
12
|
+
};
|
|
13
|
+
}
|
|
2
14
|
const codes = {
|
|
3
15
|
"invalid-command": "invalid-request",
|
|
4
16
|
"request-too-large": "input-too-large",
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { metadataOf, outcomeOf } from "./run-metadata.js";
|
|
2
2
|
import { linksOf } from "../authority/handoff-chain.js";
|
|
3
3
|
import { runView, unresolvedEffects, } from "../authority/status.js";
|
|
4
4
|
import { record } from "../protocol.js";
|
|
5
5
|
import { committed, failed, invalidRequest, isIdentifier, publicReceipt, rejection, result, wholeNumber, } from "./replies.js";
|
|
6
6
|
import { usageTotals } from "./worker-totals.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { commandFields } from "./command-effects.js";
|
|
8
|
+
import { decidedOf, feedbackOf } from "./decision-handler.js";
|
|
9
|
+
import { queueOverview } from "./active-tickets.js";
|
|
9
10
|
import { queueRunStatuses } from "./queue-runs.js";
|
|
10
11
|
async function snapshot(context) {
|
|
11
12
|
const { authority } = context;
|
|
@@ -44,6 +45,7 @@ async function effectInput(context, runId) {
|
|
|
44
45
|
const budget = await effects.budget(runId);
|
|
45
46
|
const stored = await effects.operations(runId);
|
|
46
47
|
return {
|
|
48
|
+
commandOperations: stored.filter((operation) => operation.capability === "command"),
|
|
47
49
|
budget: budget ? { limit: budget.limit, spent: budget.spent } : null,
|
|
48
50
|
effects: stored.map((operation) => ({
|
|
49
51
|
operationId: operation.operationId,
|
|
@@ -62,8 +64,9 @@ async function viewOf(context, scope) {
|
|
|
62
64
|
if (run === undefined)
|
|
63
65
|
return undefined;
|
|
64
66
|
const details = state.details[run.runId];
|
|
67
|
+
const effects = await effectInput(context, run.runId);
|
|
65
68
|
const input = {
|
|
66
|
-
...
|
|
69
|
+
...effects,
|
|
67
70
|
closure: run.status === "cancelled"
|
|
68
71
|
? await context.authority.effects.closure(run.runId)
|
|
69
72
|
: null,
|
|
@@ -81,6 +84,7 @@ async function viewOf(context, scope) {
|
|
|
81
84
|
};
|
|
82
85
|
return {
|
|
83
86
|
...runView(input),
|
|
87
|
+
commandOperations: effects.commandOperations,
|
|
84
88
|
...linksOf({ runId: run.runId, ...scope.snapshot.links[run.runId] }),
|
|
85
89
|
input: await submittedInput(context, details?.submission),
|
|
86
90
|
workflowId: scope.snapshot.workflowIds[run.runId] ?? run.workflow,
|
|
@@ -97,6 +101,7 @@ function summary(view) {
|
|
|
97
101
|
workflowId: view.workflowId,
|
|
98
102
|
state: view.state,
|
|
99
103
|
condition: view.condition,
|
|
104
|
+
awaitedRunId: view.awaitedRunId,
|
|
100
105
|
revision: view.revision,
|
|
101
106
|
latestSequence: view.latestSequence,
|
|
102
107
|
latestAt: view.latestAt,
|
|
@@ -122,57 +127,6 @@ function full(view) {
|
|
|
122
127
|
feedback: view.feedback,
|
|
123
128
|
};
|
|
124
129
|
}
|
|
125
|
-
async function outcomeOf(context, view) {
|
|
126
|
-
if (view.state !== "completed")
|
|
127
|
-
return null;
|
|
128
|
-
const event = await context.authority.queries.latestCompletion({
|
|
129
|
-
runId: view.runId,
|
|
130
|
-
atOrBefore: view.latestSequence,
|
|
131
|
-
});
|
|
132
|
-
const payload = event?.payload ?? {};
|
|
133
|
-
const kind = payload["outcome"];
|
|
134
|
-
if (kind === undefined)
|
|
135
|
-
return null;
|
|
136
|
-
const { ticketStatus, promotionId, outcomeReason, issueUpdate } = payload;
|
|
137
|
-
return {
|
|
138
|
-
kind,
|
|
139
|
-
reason: outcomeReason ?? null,
|
|
140
|
-
...(promotionId === undefined ? {} : { promotionId }),
|
|
141
|
-
...(ticketStatus === undefined ? {} : { ticketStatus }),
|
|
142
|
-
...(issueUpdate === "failed" ? { issueUpdate } : {}),
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
function titleOf(input, workflowId) {
|
|
146
|
-
const ticket = input?.["ticket"];
|
|
147
|
-
if (typeof ticket !== "string")
|
|
148
|
-
return null;
|
|
149
|
-
const fallback = `Cloving task ${String(input?.["cycleId"])}`;
|
|
150
|
-
const lines = ticket.split("\n");
|
|
151
|
-
if (workflowId === "develop-prompt") {
|
|
152
|
-
const first = lines.find((line) => /\S/.test(line));
|
|
153
|
-
return first === undefined
|
|
154
|
-
? fallback
|
|
155
|
-
: first.replace(/^# /, "").trim().slice(0, 200);
|
|
156
|
-
}
|
|
157
|
-
const first = lines[0] ?? "";
|
|
158
|
-
return first.startsWith("# ")
|
|
159
|
-
? first.slice(2).trim().slice(0, 200)
|
|
160
|
-
: fallback;
|
|
161
|
-
}
|
|
162
|
-
async function metadataOf(context, source) {
|
|
163
|
-
const document = source.digest
|
|
164
|
-
? await context.authority.queries.document(source.digest)
|
|
165
|
-
: undefined;
|
|
166
|
-
const input = record(JSON.parse(document ?? "null"));
|
|
167
|
-
const ticketId = input?.["ticketId"];
|
|
168
|
-
return {
|
|
169
|
-
ticketId: typeof ticketId === "string" && ticketId !== "" ? ticketId : null,
|
|
170
|
-
title: titleOf(input, source.workflowId),
|
|
171
|
-
...(source.workflowId === "develop-issue"
|
|
172
|
-
? { issueIdentity: issueIdentity(input?.["ticket"]) }
|
|
173
|
-
: {}),
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
130
|
async function submittedInput(context, digest) {
|
|
177
131
|
const document = digest
|
|
178
132
|
? await context.authority.queries.document(digest)
|
|
@@ -228,7 +182,12 @@ export async function status(context, parameters) {
|
|
|
228
182
|
return result("run-status", {
|
|
229
183
|
run: {
|
|
230
184
|
...full({ ...view, ...totals }),
|
|
185
|
+
...(await commandFields(context, view.commandOperations)),
|
|
231
186
|
outcome: await outcomeOf(context, view),
|
|
187
|
+
decisions: await decidedOf(context, {
|
|
188
|
+
state: current.state,
|
|
189
|
+
runId: view.runId,
|
|
190
|
+
}),
|
|
232
191
|
...(await metadataOf(context, {
|
|
233
192
|
workflowId: view.workflowId,
|
|
234
193
|
digest: current.state.details[view.runId]?.input,
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type Fields } from "../protocol.ts";
|
|
2
|
+
import type { RunView } from "../authority/status.ts";
|
|
3
|
+
import type { ServiceContext } from "./replies.ts";
|
|
4
|
+
export declare function outcomeOf(context: ServiceContext, view: Pick<RunView, "state" | "runId" | "latestSequence">): Promise<Fields | null>;
|
|
5
|
+
export declare function metadataOf(context: ServiceContext, source: {
|
|
6
|
+
readonly workflowId: string;
|
|
7
|
+
readonly digest: string | null | undefined;
|
|
8
|
+
}): Promise<Fields>;
|