cloving 1.3.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +329 -215
- package/dist/src/agent-harness-shell.d.ts +2 -1
- package/dist/src/agent-harness-shell.js +8 -5
- package/dist/src/authority/command-wait-checks.d.ts +8 -0
- package/dist/src/authority/command-wait-checks.js +88 -0
- package/dist/src/authority/command-wait-results.d.ts +15 -0
- package/dist/src/authority/command-wait-results.js +73 -0
- package/dist/src/authority/command-wait-view.d.ts +21 -0
- package/dist/src/authority/command-wait-view.js +34 -0
- package/dist/src/authority/command-waits.d.ts +39 -0
- package/dist/src/authority/command-waits.js +97 -0
- package/dist/src/authority/commands.js +22 -1
- package/dist/src/authority/dispatch-decision.d.ts +8 -0
- package/dist/src/authority/dispatch-decision.js +26 -1
- package/dist/src/authority/effect-requests.js +6 -3
- package/dist/src/authority/effect-results.js +4 -2
- package/dist/src/authority/history-state.d.ts +2 -0
- package/dist/src/authority/history-state.js +13 -1
- package/dist/src/authority/instants.d.ts +1 -0
- package/dist/src/authority/instants.js +21 -0
- package/dist/src/authority/reduction-state.d.ts +2 -0
- package/dist/src/authority/reduction-state.js +5 -0
- package/dist/src/authority/reduction.js +24 -0
- package/dist/src/authority/status-input.d.ts +2 -0
- package/dist/src/authority/status.d.ts +2 -0
- package/dist/src/authority/status.js +1 -0
- package/dist/src/authority/stop-sequence.d.ts +1 -0
- package/dist/src/authority/stop-sequence.js +2 -1
- package/dist/src/authority/transitions.d.ts +6 -4
- package/dist/src/authority/transitions.js +7 -0
- package/dist/src/broker/actor/authority-health.d.ts +9 -0
- package/dist/src/broker/actor/authority-health.js +24 -0
- package/dist/src/broker/actor/authority-queries.d.ts +2 -1
- package/dist/src/broker/actor/authority-queries.js +14 -5
- package/dist/src/broker/actor/authority-receipts.js +1 -1
- package/dist/src/broker/actor/authority-runtime.d.ts +4 -2
- package/dist/src/broker/actor/authority-runtime.js +29 -20
- package/dist/src/broker/actor/authority-session.d.ts +6 -19
- package/dist/src/broker/actor/authority-session.js +66 -88
- package/dist/src/broker/actor/authority-settings.d.ts +2 -1
- package/dist/src/broker/actor/authority-settings.js +6 -3
- package/dist/src/broker/actor/authority-upgrades.d.ts +23 -2
- package/dist/src/broker/actor/authority-upgrades.js +8 -2
- package/dist/src/broker/actor/authority-watchdog.d.ts +6 -2
- package/dist/src/broker/actor/authority-watchdog.js +31 -9
- package/dist/src/broker/actor/authority.js +3 -1
- package/dist/src/broker/actor/delivery-intents.js +2 -0
- package/dist/src/broker/actor/effect-delivery.d.ts +1 -1
- package/dist/src/broker/actor/effect-delivery.js +15 -2
- package/dist/src/broker/actor/effect-plan.js +11 -2
- package/dist/src/broker/actor/effect-queries.d.ts +4 -0
- package/dist/src/broker/actor/effect-queries.js +9 -1
- package/dist/src/broker/actor/effect-turn.js +2 -0
- package/dist/src/broker/actor/projection-memory.d.ts +43 -0
- package/dist/src/broker/actor/projection-memory.js +207 -0
- package/dist/src/broker/actor/runtime-parts.d.ts +5 -0
- package/dist/src/broker/actor/runtime-parts.js +8 -3
- package/dist/src/broker/actor/stop-plan.js +9 -3
- package/dist/src/broker/actor/stop-turn.d.ts +2 -0
- package/dist/src/broker/actor/stop-turn.js +24 -11
- package/dist/src/broker/actor/turn-draft.d.ts +1 -0
- package/dist/src/broker/actor/turn-draft.js +4 -0
- package/dist/src/broker/actor/turn-state.js +5 -1
- package/dist/src/broker/authority-admission.js +60 -0
- package/dist/src/broker/authority-restore.d.ts +2 -0
- package/dist/src/broker/authority-restore.js +35 -1
- package/dist/src/broker/command-wait-restore.d.ts +31 -0
- package/dist/src/broker/command-wait-restore.js +86 -0
- package/dist/src/broker/decision-restore.d.ts +1 -1
- package/dist/src/broker/decision-restore.js +1 -0
- package/dist/src/broker/effect-upgrade.d.ts +3 -0
- package/dist/src/broker/effect-upgrade.js +11 -2
- package/dist/src/cli/arguments.d.ts +13 -0
- package/dist/src/cli/arguments.js +43 -3
- package/dist/src/cli/chat-stores.d.ts +2 -0
- package/dist/src/cli/chat-stores.js +113 -0
- package/dist/src/cli/client.d.ts +7 -2
- package/dist/src/cli/client.js +13 -7
- package/dist/src/cli/command-requests.d.ts +46 -0
- package/dist/src/cli/command-requests.js +84 -0
- package/dist/src/cli/command-waits.d.ts +9 -0
- package/dist/src/cli/command-waits.js +51 -0
- package/dist/src/cli/commands.js +70 -88
- package/dist/src/cli/config-file.d.ts +2 -2
- package/dist/src/cli/config-file.js +4 -2
- package/dist/src/cli/config-notice.js +5 -2
- package/dist/src/cli/doctor-retention.d.ts +2 -0
- package/dist/src/cli/doctor-retention.js +93 -0
- package/dist/src/cli/doctor-workflows.d.ts +5 -2
- package/dist/src/cli/doctor-workflows.js +12 -7
- package/dist/src/cli/doctor.js +11 -9
- package/dist/src/cli/harness-probes.d.ts +2 -0
- package/dist/src/cli/harness-probes.js +1 -1
- package/dist/src/cli/harness-processes.d.ts +6 -0
- package/dist/src/cli/harness-processes.js +36 -0
- package/dist/src/cli/init-command.d.ts +9 -0
- package/dist/src/cli/init-command.js +52 -0
- package/dist/src/cli/init-prompt-command.d.ts +10 -0
- package/dist/src/cli/init-prompt-command.js +145 -0
- package/dist/src/cli/init-prompt.d.ts +35 -0
- package/dist/src/cli/init-prompt.js +74 -0
- package/dist/src/cli/init-selection.d.ts +13 -0
- package/dist/src/cli/init-selection.js +75 -0
- package/dist/src/cli/main.d.ts +2 -0
- package/dist/src/cli/main.js +37 -7
- package/dist/src/cli/mcp-server.d.ts +1 -0
- package/dist/src/cli/mcp-server.js +156 -0
- package/dist/src/cli/mcp-tools.d.ts +15 -0
- package/dist/src/cli/mcp-tools.js +242 -0
- package/dist/src/cli/queue-arguments.d.ts +15 -0
- package/dist/src/cli/queue-arguments.js +31 -0
- package/dist/src/cli/queue-render.d.ts +3 -0
- package/dist/src/cli/queue-render.js +26 -0
- package/dist/src/cli/reload-render.d.ts +2 -0
- package/dist/src/cli/reload-render.js +12 -0
- package/dist/src/cli/render.d.ts +1 -1
- package/dist/src/cli/render.js +54 -38
- package/dist/src/cli/report-ci-jobs.d.ts +23 -0
- package/dist/src/cli/report-ci-jobs.js +103 -0
- package/dist/src/cli/report-ci-usage.d.ts +9 -0
- package/dist/src/cli/report-ci-usage.js +185 -0
- package/dist/src/cli/report-ci.d.ts +13 -0
- package/dist/src/cli/report-ci.js +74 -0
- package/dist/src/cli/report-closures.d.ts +6 -0
- package/dist/src/cli/report-closures.js +97 -0
- package/dist/src/cli/report-flow.d.ts +7 -0
- package/dist/src/cli/report-flow.js +122 -0
- package/dist/src/cli/report-github-reader.d.ts +29 -0
- package/dist/src/cli/report-github-reader.js +157 -0
- package/dist/src/cli/report-github.d.ts +15 -8
- package/dist/src/cli/report-github.js +131 -150
- package/dist/src/cli/report-operator.d.ts +3 -0
- package/dist/src/cli/report-operator.js +40 -0
- package/dist/src/cli/report-ready.d.ts +3 -0
- package/dist/src/cli/report-ready.js +96 -0
- package/dist/src/cli/report-text.d.ts +9 -0
- package/dist/src/cli/report-text.js +33 -0
- package/dist/src/cli/report.d.ts +1 -0
- package/dist/src/cli/report.js +104 -27
- package/dist/src/cli/runtime-arguments.d.ts +18 -3
- package/dist/src/cli/runtime-arguments.js +29 -20
- package/dist/src/cli/schedule-arguments.d.ts +14 -0
- package/dist/src/cli/schedule-arguments.js +26 -0
- package/dist/src/cli/schedule-render.d.ts +22 -0
- package/dist/src/cli/schedule-render.js +73 -0
- package/dist/src/cli/terminal-text.d.ts +3 -0
- package/dist/src/cli/terminal-text.js +28 -0
- package/dist/src/cli/toolchain.d.ts +1 -0
- package/dist/src/cli/toolchain.js +1 -0
- package/dist/src/cli/usage-render.d.ts +1 -0
- package/dist/src/cli/usage-render.js +28 -1
- package/dist/src/cli/usage.d.ts +2 -2
- package/dist/src/cli/usage.js +89 -11
- package/dist/src/cli/watch-actions.js +2 -2
- package/dist/src/cli/watch-api-document.d.ts +430 -0
- package/dist/src/cli/watch-api-document.js +291 -0
- package/dist/src/cli/watch-api-run.d.ts +56 -0
- package/dist/src/cli/watch-api-run.js +112 -0
- package/dist/src/cli/watch-api.d.ts +17 -0
- package/dist/src/cli/watch-api.js +230 -0
- package/dist/src/cli/watch-board-view.js +19 -2
- package/dist/src/cli/watch-board.d.ts +4 -2
- package/dist/src/cli/watch-board.js +53 -43
- package/dist/src/cli/watch-card-forms.d.ts +1 -1
- package/dist/src/cli/watch-card-forms.js +11 -10
- package/dist/src/cli/watch-client.d.ts +1 -1
- package/dist/src/cli/watch-client.js +2 -11
- package/dist/src/cli/watch-header-view.d.ts +1 -5
- package/dist/src/cli/watch-header-view.js +17 -21
- package/dist/src/cli/watch-model.d.ts +5 -1
- package/dist/src/cli/watch-model.js +20 -11
- package/dist/src/cli/watch-page.js +15 -15
- package/dist/src/cli/watch-phases.d.ts +12 -3
- package/dist/src/cli/watch-phases.js +68 -11
- package/dist/src/cli/watch-pr-board.js +1 -1
- package/dist/src/cli/watch-pr-command.d.ts +1 -0
- package/dist/src/cli/watch-pull-request.js +18 -8
- package/dist/src/cli/watch-reads.d.ts +3 -0
- package/dist/src/cli/watch-reads.js +22 -20
- package/dist/src/cli/watch-render.d.ts +15 -0
- package/dist/src/cli/watch-run-input.d.ts +0 -1
- package/dist/src/cli/watch-run-input.js +0 -13
- package/dist/src/cli/watch-server.js +24 -10
- package/dist/src/cli/watch-view.d.ts +0 -3
- package/dist/src/cli/watch-view.js +13 -13
- package/dist/src/cli.js +73 -12
- package/dist/src/command-wait.d.ts +4 -0
- package/dist/src/command-wait.js +45 -0
- package/dist/src/configuration-change.d.ts +7 -0
- package/dist/src/configuration-change.js +14 -0
- package/dist/src/configuration-display.js +2 -0
- package/dist/src/configuration-schema.d.ts +14 -0
- package/dist/src/configuration-schema.js +6 -2
- package/dist/src/daemon/attachment-file.d.ts +6 -0
- package/dist/src/daemon/attachment-file.js +86 -0
- package/dist/src/daemon/attachments.d.ts +14 -0
- package/dist/src/daemon/attachments.js +17 -0
- package/dist/src/daemon/claude-recovery.d.ts +50 -0
- package/dist/src/daemon/claude-recovery.js +208 -0
- package/dist/src/daemon/claude-stream.d.ts +27 -0
- package/dist/src/daemon/claude-stream.js +63 -0
- package/dist/src/daemon/claude-turn.d.ts +11 -25
- package/dist/src/daemon/claude-turn.js +64 -81
- package/dist/src/daemon/claude-worker.d.ts +5 -4
- package/dist/src/daemon/claude-worker.js +127 -126
- package/dist/src/daemon/daemon-adapters.d.ts +9 -0
- package/dist/src/daemon/daemon-adapters.js +33 -5
- package/dist/src/daemon/daemon-loops.d.ts +5 -1
- package/dist/src/daemon/daemon-loops.js +18 -10
- package/dist/src/daemon/daemon.js +80 -61
- package/dist/src/daemon/github-attach.d.ts +2 -0
- package/dist/src/daemon/github-attach.js +222 -0
- package/dist/src/daemon/github-calls.js +1 -1
- package/dist/src/daemon/github-ci-filters.d.ts +6 -0
- package/dist/src/daemon/github-ci-filters.js +138 -0
- package/dist/src/daemon/github-ci-workflows.d.ts +10 -0
- package/dist/src/daemon/github-ci-workflows.js +148 -0
- package/dist/src/daemon/github-ci.js +22 -4
- package/dist/src/daemon/github-issue-methods.d.ts +2 -0
- package/dist/src/daemon/github-issue-methods.js +37 -2
- package/dist/src/daemon/github-merge-call.d.ts +2 -1
- package/dist/src/daemon/github-merge-call.js +10 -3
- package/dist/src/daemon/github-merge.js +52 -24
- package/dist/src/daemon/github-methods.js +18 -4
- package/dist/src/daemon/github-operation.d.ts +4 -0
- package/dist/src/daemon/github-operation.js +6 -0
- package/dist/src/daemon/github-worker.d.ts +4 -0
- package/dist/src/daemon/github-worker.js +6 -0
- package/dist/src/daemon/issue-queue.d.ts +4 -1
- package/dist/src/daemon/issue-queue.js +76 -78
- package/dist/src/daemon/merge-turns.d.ts +10 -0
- package/dist/src/daemon/merge-turns.js +37 -0
- package/dist/src/daemon/notify-events.d.ts +6 -0
- package/dist/src/daemon/notify-events.js +84 -0
- package/dist/src/daemon/notify-journal.js +1 -1
- package/dist/src/daemon/notify-message.d.ts +4 -1
- package/dist/src/daemon/notify-message.js +36 -0
- package/dist/src/daemon/notify.d.ts +1 -1
- package/dist/src/daemon/notify.js +5 -77
- package/dist/src/daemon/operation-journal.d.ts +1 -0
- package/dist/src/daemon/queue-control.d.ts +13 -0
- package/dist/src/daemon/queue-control.js +86 -0
- package/dist/src/daemon/queue-journal.d.ts +20 -0
- package/dist/src/daemon/queue-journal.js +89 -0
- package/dist/src/daemon/queue-status.d.ts +9 -3
- package/dist/src/daemon/queue-status.js +17 -4
- package/dist/src/daemon/record-archive.d.ts +19 -0
- package/dist/src/daemon/record-archive.js +82 -0
- package/dist/src/daemon/record-sweep.d.ts +24 -0
- package/dist/src/daemon/record-sweep.js +147 -0
- package/dist/src/daemon/resume-index-lock.d.ts +13 -0
- package/dist/src/daemon/resume-index-lock.js +160 -0
- package/dist/src/daemon/resume-worktree.d.ts +7 -0
- package/dist/src/daemon/resume-worktree.js +29 -0
- package/dist/src/daemon/retrying-turn.d.ts +2 -12
- package/dist/src/daemon/retrying-turn.js +98 -172
- package/dist/src/daemon/schedule-control.d.ts +26 -0
- package/dist/src/daemon/schedule-control.js +110 -0
- package/dist/src/daemon/schedule-journal.d.ts +2 -15
- package/dist/src/daemon/schedule-journal.js +67 -4
- package/dist/src/daemon/settings-reload.d.ts +26 -0
- package/dist/src/daemon/settings-reload.js +82 -0
- package/dist/src/daemon/ticket-registration.d.ts +2 -7
- package/dist/src/daemon/ticket-registration.js +15 -81
- package/dist/src/daemon/turn-attempt-journal.d.ts +38 -0
- package/dist/src/daemon/turn-attempt-journal.js +136 -0
- package/dist/src/daemon/turn-attempts.d.ts +47 -0
- package/dist/src/daemon/turn-attempts.js +166 -0
- package/dist/src/daemon/turn-details.d.ts +4 -0
- package/dist/src/daemon/turn-details.js +33 -0
- package/dist/src/daemon/turn-report.d.ts +8 -1
- package/dist/src/daemon/turn-report.js +39 -0
- package/dist/src/daemon/work-tree.d.ts +9 -0
- package/dist/src/daemon/work-tree.js +20 -0
- package/dist/src/daemon/worker-profile.d.ts +9 -0
- package/dist/src/daemon/worker-profile.js +44 -0
- package/dist/src/daemon/workflow-generations.d.ts +7 -4
- package/dist/src/daemon/workflow-generations.js +22 -14
- package/dist/src/daemon/workflow-reload.d.ts +41 -0
- package/dist/src/daemon/workflow-reload.js +244 -0
- package/dist/src/daemon/workflow-replay.d.ts +2 -1
- package/dist/src/daemon/workflow-replay.js +7 -3
- package/dist/src/daemon/workflow-schedules.d.ts +3 -0
- package/dist/src/daemon/workflow-schedules.js +98 -45
- package/dist/src/daemon/worktree-processes.d.ts +9 -0
- package/dist/src/daemon/worktree-processes.js +151 -0
- package/dist/src/doctor-report.d.ts +4 -6
- package/dist/src/doctor-report.js +8 -13
- package/dist/src/harness-start.d.ts +15 -0
- package/dist/src/harness-start.js +37 -0
- package/dist/src/host/command-wait.d.ts +38 -0
- package/dist/src/host/command-wait.js +115 -0
- package/dist/src/host/start-delivery.d.ts +5 -7
- package/dist/src/host/start-delivery.js +3 -15
- package/dist/src/host/step-bridge-host.d.ts +2 -0
- package/dist/src/host/step-bridge-host.js +21 -0
- package/dist/src/operation-identity.d.ts +1 -0
- package/dist/src/operation-identity.js +4 -0
- package/dist/src/private-config.schema.json +71 -0
- package/dist/src/project-config.schema.json +40 -0
- package/dist/src/project-settings.d.ts +16 -2
- package/dist/src/project-settings.js +35 -1
- package/dist/src/queue-spend.d.ts +4 -0
- package/dist/src/queue-spend.js +21 -0
- package/dist/src/queue-state.d.ts +26 -0
- package/dist/src/queue-state.js +34 -0
- package/dist/src/record-retention.d.ts +46 -0
- package/dist/src/record-retention.js +81 -0
- package/dist/src/relay/relay-service.d.ts +3 -0
- package/dist/src/relay/relay-service.js +5 -3
- package/dist/src/report-ci.d.ts +164 -0
- package/dist/src/report-ci.js +32 -0
- package/dist/src/report-effects.d.ts +15 -0
- package/dist/src/report-effects.js +212 -0
- package/dist/src/report-flow-types.d.ts +38 -0
- package/dist/src/report-flow-types.js +7 -0
- package/dist/src/report-flow.d.ts +43 -0
- package/dist/src/report-flow.js +193 -0
- package/dist/src/report-operator.d.ts +67 -0
- package/dist/src/report-operator.js +25 -0
- package/dist/src/report-quality.d.ts +221 -0
- package/dist/src/report-quality.js +94 -0
- package/dist/src/report-ready.d.ts +23 -0
- package/dist/src/report-ready.js +117 -0
- package/dist/src/report-statistics.d.ts +2 -1
- package/dist/src/report-statistics.js +40 -4
- package/dist/src/report.d.ts +588 -47
- package/dist/src/report.js +156 -41
- package/dist/src/schedule-progress.d.ts +33 -0
- package/dist/src/schedule-progress.js +45 -0
- package/dist/src/service/active-tickets.js +11 -6
- package/dist/src/service/command-waits.d.ts +34 -0
- package/dist/src/service/command-waits.js +86 -0
- package/dist/src/service/dispatcher.d.ts +4 -0
- package/dist/src/service/dispatcher.js +33 -0
- package/dist/src/service/expiry.js +2 -0
- package/dist/src/service/gateway.js +3 -1
- package/dist/src/service/queue-handlers.d.ts +4 -0
- package/dist/src/service/queue-handlers.js +32 -0
- package/dist/src/service/queue-spend.d.ts +6 -0
- package/dist/src/service/queue-spend.js +68 -0
- package/dist/src/service/registry.d.ts +28 -2
- package/dist/src/service/registry.js +48 -0
- package/dist/src/service/replies.d.ts +22 -8
- package/dist/src/service/replies.js +16 -2
- package/dist/src/service/run-handlers.js +37 -12
- package/dist/src/service/run-metadata.d.ts +15 -1
- package/dist/src/service/run-metadata.js +93 -8
- package/dist/src/service/service.d.ts +11 -3
- package/dist/src/service/service.js +22 -37
- package/dist/src/service/submission-handler.js +18 -4
- package/dist/src/service/worker-port.js +9 -1
- package/dist/src/service/worker-totals.d.ts +6 -0
- package/dist/src/service/worker-totals.js +8 -1
- package/dist/src/service/workflow-reload.d.ts +35 -0
- package/dist/src/service/workflow-reload.js +52 -0
- package/dist/src/step-bridge.d.ts +20 -0
- package/dist/src/steps/command-wait.d.ts +12 -0
- package/dist/src/steps/command-wait.js +26 -0
- package/dist/src/steps/open-decision-wait.d.ts +2 -0
- package/dist/src/steps/{decision-gate.js → open-decision-wait.js} +0 -7
- package/dist/src/steps/review-by-person.js +4 -1
- package/dist/src/steps/wait-for-command.d.ts +3 -0
- package/dist/src/steps/wait-for-command.js +17 -0
- package/dist/src/steps/wait-for-decision.js +1 -1
- package/dist/src/storage/command-wait-rows.d.ts +30 -0
- package/dist/src/storage/command-wait-rows.js +96 -0
- package/dist/src/storage/decision-snapshots.d.ts +8 -2
- package/dist/src/storage/decision-snapshots.js +16 -8
- package/dist/src/storage/domain-changes.d.ts +3 -1
- package/dist/src/storage/domain-changes.js +4 -0
- package/dist/src/storage/domain-schema.d.ts +16 -1
- package/dist/src/storage/domain-schema.js +35 -4
- package/dist/src/storage/effect-schema.d.ts +2 -0
- package/dist/src/storage/effect-schema.js +9 -0
- package/dist/src/storage/projection-changes.d.ts +12 -0
- package/dist/src/storage/projection-changes.js +194 -0
- package/dist/src/storage/projection-lookups.d.ts +7 -0
- package/dist/src/storage/projection-lookups.js +30 -0
- package/dist/src/testing-requests.d.ts +15 -0
- package/dist/src/testing-requests.js +93 -0
- package/dist/src/testing.d.ts +4 -10
- package/dist/src/testing.js +33 -86
- package/dist/src/worker-usage.d.ts +1 -0
- package/dist/src/worker-usage.js +3 -0
- package/dist/src/workflow-candidate.d.ts +1 -0
- package/dist/src/workflow-candidate.js +12 -1
- package/dist/src/workflow-contracts.d.ts +1 -0
- package/dist/src/workflow-contracts.js +9 -2
- package/dist/src/workflow-declaration.d.ts +1 -0
- package/dist/src/workflow-declaration.js +3 -0
- package/dist/src/workflow-discovery.d.ts +2 -13
- package/dist/src/workflow-discovery.js +1 -13
- package/dist/src/workflow-refusals.js +0 -1
- package/dist/src/workflows.d.ts +1 -1
- package/dist/src/workflows.js +1 -1
- package/dist/tools/compile-workflows.js +3 -0
- package/dist/tools/project-configuration.d.ts +7 -2
- package/dist/tools/project-configuration.js +30 -1
- package/dist/tools/red-green-command.d.ts +1 -0
- package/dist/tools/red-green-command.js +174 -0
- package/dist/tools/red-green-process.d.ts +10 -0
- package/dist/tools/red-green-process.js +59 -0
- package/dist/tools/self-host-processes.d.ts +2 -0
- package/dist/tools/self-host-processes.js +69 -26
- package/dist/tools/self-host-project.d.ts +2 -0
- package/dist/tools/self-host-project.js +30 -77
- package/dist/tools/self-host-runtime.js +1 -1
- package/dist/tools/self-host.js +76 -34
- package/dist/tools/template-command.d.ts +1 -0
- package/dist/tools/template-command.js +160 -0
- package/dist/tools/template-copy.d.ts +11 -0
- package/dist/tools/template-copy.js +130 -0
- package/dist/tools/template-files.d.ts +17 -0
- package/dist/tools/template-files.js +74 -0
- package/dist/tools/workflow-bundles.js +1 -0
- package/dist/tools/workflow-candidate-counts.js +2 -2
- package/dist/tools/workflow-candidate-program.d.ts +4 -2
- package/dist/tools/workflow-candidate-program.js +30 -11
- package/dist/tools/workflow-candidate-shape.d.ts +3 -0
- package/dist/tools/workflow-candidate-shape.js +90 -0
- package/dist/tools/workflow-candidate-source.d.ts +1 -0
- package/dist/tools/workflow-candidate-source.js +26 -4
- package/dist/tools/workflow-candidate-syntax.d.ts +2 -2
- package/dist/tools/workflow-candidate-syntax.js +24 -94
- package/dist/tools/workflow-command.js +1 -2
- package/dist/tools/workflow-folders.d.ts +2 -3
- package/dist/tools/workflow-folders.js +1 -1
- package/package.json +17 -9
- package/templates/develop/README.md +93 -4
- package/templates/develop/develop/flow-tests.ts +38 -1
- package/templates/develop/develop/interruption-tests.ts +157 -0
- package/templates/develop/develop/local.ts +1 -0
- package/templates/develop/develop/option-tests.ts +138 -9
- package/templates/develop/develop/pull.ts +5 -1
- package/templates/develop/develop/red-green.ts +55 -0
- package/templates/develop/develop/refusal-tests.ts +77 -0
- package/templates/develop/develop/report.ts +31 -11
- package/templates/develop/develop/round.ts +1 -0
- package/templates/develop/develop/scenarios.ts +27 -0
- package/templates/develop/develop/turn.ts +28 -7
- package/templates/develop/develop.declaration.json +1 -1
- package/templates/develop/develop.test.ts +4 -0
- package/templates/develop/template.json +29 -2
- package/templates/idea-to-issue/README.md +27 -0
- package/templates/idea-to-issue/idea-to-issue/effects.ts +52 -0
- package/templates/idea-to-issue/idea-to-issue/leave.ts +10 -0
- package/templates/idea-to-issue/idea-to-issue/next.ts +29 -0
- package/templates/idea-to-issue/idea-to-issue/post-person.ts +18 -0
- package/templates/idea-to-issue/idea-to-issue/post.ts +50 -0
- package/templates/idea-to-issue/idea-to-issue/queue.ts +27 -0
- package/templates/idea-to-issue/idea-to-issue/review.ts +42 -0
- package/templates/idea-to-issue/idea-to-issue/scenarios.ts +50 -0
- package/templates/idea-to-issue/idea-to-issue/turn.ts +40 -0
- package/templates/idea-to-issue/idea-to-issue.declaration.json +16 -0
- package/templates/idea-to-issue/idea-to-issue.test.ts +79 -0
- package/templates/idea-to-issue/idea-to-issue.ts +49 -0
- package/templates/idea-to-issue/template.json +81 -0
- package/templates/review-day/README.md +97 -0
- package/templates/review-day/review-day/critique.ts +58 -0
- package/templates/review-day/review-day/decision.ts +29 -0
- package/templates/review-day/review-day/facts.ts +69 -0
- package/templates/review-day/review-day/label.ts +29 -0
- package/templates/review-day/review-day/next.ts +28 -0
- package/templates/review-day/review-day/post.ts +27 -0
- package/templates/review-day/review-day/report.ts +98 -0
- package/templates/review-day/review-day/rules.ts +12 -0
- package/templates/review-day/review-day/scenarios.ts +76 -0
- package/templates/review-day/review-day/turn.ts +73 -0
- package/templates/review-day/review-day.declaration.json +16 -0
- package/templates/review-day/review-day.test.ts +362 -0
- package/templates/review-day/review-day.ts +37 -0
- package/templates/review-day/template.json +56 -0
- package/dist/src/cli/watch-start-view.d.ts +0 -18
- package/dist/src/cli/watch-start-view.js +0 -77
- package/dist/src/steps/decision-gate.d.ts +0 -3
- package/dist/workflows/develop-prd.d.ts +0 -7
- package/dist/workflows/develop-prd.js +0 -165
- package/dist/workflows/develop-ticket.d.ts +0 -9
- package/dist/workflows/develop-ticket.js +0 -207
- package/dist/workflows/issue-labels.d.ts +0 -16
- package/dist/workflows/issue-labels.js +0 -70
- package/dist/workflows/ticket-prompts.d.ts +0 -35
- package/dist/workflows/ticket-prompts.js +0 -147
|
@@ -4,17 +4,16 @@ import { authorityTiming, openAuthority, } from "../broker/actor/authority.js";
|
|
|
4
4
|
import { socketAddress } from "../broker/socket-address.js";
|
|
5
5
|
import {} from "../workflow-refusals.js";
|
|
6
6
|
import { changeSignal } from "./changes.js";
|
|
7
|
-
import { decision, questions } from "./decision-handler.js";
|
|
8
|
-
import { events } from "./event-handler.js";
|
|
9
7
|
import { expiryScan } from "./expiry.js";
|
|
10
8
|
import { commandGateway, workerCommandBound } from "./gateway.js";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
9
|
+
import { workflowCatalog, } from "./registry.js";
|
|
10
|
+
import { reloadOperation } from "./workflow-reload.js";
|
|
11
|
+
import { errorMessage, queryMetadata, } from "./replies.js";
|
|
12
|
+
import { dispatcher } from "./dispatcher.js";
|
|
15
13
|
import { connectionLimits, listen, reachable } from "./transport.js";
|
|
16
14
|
import { workerPort } from "./worker-port.js";
|
|
17
15
|
import { runWaitTarget } from "./run-waits.js";
|
|
16
|
+
import { commandWaitPort } from "./command-waits.js";
|
|
18
17
|
export const serviceTiming = {
|
|
19
18
|
authority: authorityTiming,
|
|
20
19
|
expiryScanMilliseconds: 1_000,
|
|
@@ -55,30 +54,17 @@ async function endpoint(directory) {
|
|
|
55
54
|
function wallClock() {
|
|
56
55
|
return new Date().toISOString();
|
|
57
56
|
}
|
|
58
|
-
function
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
["run-command", (request) => runCommand(context, request.parameters)],
|
|
66
|
-
[
|
|
67
|
-
"events",
|
|
68
|
-
(request, connection) => events(context, { parameters: request.parameters, connection }),
|
|
69
|
-
],
|
|
70
|
-
]);
|
|
71
|
-
return (request, connection) => {
|
|
72
|
-
const operation = operations.get(request.operation);
|
|
73
|
-
if (operation === undefined)
|
|
74
|
-
return Promise.resolve(failed("unknown-operation", {
|
|
75
|
-
detail: `The service has no operation ${request.operation}.`,
|
|
76
|
-
}));
|
|
77
|
-
return operation(request, connection);
|
|
57
|
+
function catalogContext(options, catalog) {
|
|
58
|
+
return {
|
|
59
|
+
registry: catalog.registry,
|
|
60
|
+
workflowCatalog: catalog,
|
|
61
|
+
...(options.reload === undefined
|
|
62
|
+
? {}
|
|
63
|
+
: { reload: reloadOperation({ port: options.reload, catalog }) }),
|
|
78
64
|
};
|
|
79
65
|
}
|
|
80
66
|
async function started(authority, setup) {
|
|
81
|
-
const { options, path, timing,
|
|
67
|
+
const { options, path, timing, catalog, gateway, host } = setup;
|
|
82
68
|
const clock = options.clock ?? wallClock;
|
|
83
69
|
const { textBytes, documentBytes } = options.limits ?? serviceLimits;
|
|
84
70
|
await rm(path, { force: true });
|
|
@@ -88,7 +74,7 @@ async function started(authority, setup) {
|
|
|
88
74
|
limits: { idleMilliseconds: timing.idleMilliseconds },
|
|
89
75
|
handle: dispatcher({
|
|
90
76
|
authority,
|
|
91
|
-
|
|
77
|
+
...catalogContext(options, catalog),
|
|
92
78
|
...queryMetadata(options),
|
|
93
79
|
gateway,
|
|
94
80
|
clock,
|
|
@@ -136,7 +122,8 @@ export async function startService(options) {
|
|
|
136
122
|
if (typeof path !== "string")
|
|
137
123
|
return path;
|
|
138
124
|
const timing = options.timing ?? serviceTiming;
|
|
139
|
-
const
|
|
125
|
+
const catalog = workflowCatalog(options);
|
|
126
|
+
const { registry } = catalog;
|
|
140
127
|
const opening = await openAuthority(options.stateDirectory, {
|
|
141
128
|
delivery: options.delivery,
|
|
142
129
|
timing: timing.authority,
|
|
@@ -149,7 +136,7 @@ export async function startService(options) {
|
|
|
149
136
|
const { authority } = opening;
|
|
150
137
|
const gateway = serviceGateway(authority, { options, registry });
|
|
151
138
|
const worker = workerPort({ gateway, authority });
|
|
152
|
-
const host = await hosted(options, hostPorts(authority, { worker, registry }));
|
|
139
|
+
const host = await hosted(options, hostPorts(authority, { worker, registry, gateway }));
|
|
153
140
|
if (host.kind === "refused") {
|
|
154
141
|
await authority.close();
|
|
155
142
|
return host;
|
|
@@ -161,7 +148,7 @@ export async function startService(options) {
|
|
|
161
148
|
options,
|
|
162
149
|
path,
|
|
163
150
|
timing,
|
|
164
|
-
|
|
151
|
+
catalog,
|
|
165
152
|
gateway,
|
|
166
153
|
worker,
|
|
167
154
|
host: host.host,
|
|
@@ -169,8 +156,8 @@ export async function startService(options) {
|
|
|
169
156
|
};
|
|
170
157
|
}
|
|
171
158
|
catch (error) {
|
|
172
|
-
const unclosed = await released(authority, host.host).then(() => "", (failure) => `; the close failed: ${
|
|
173
|
-
return refused("transport-failure", `${
|
|
159
|
+
const unclosed = await released(authority, host.host).then(() => "", (failure) => `; the close failed: ${errorMessage(failure)}`);
|
|
160
|
+
return refused("transport-failure", `${errorMessage(error)}${unclosed}`);
|
|
174
161
|
}
|
|
175
162
|
}
|
|
176
163
|
function serviceGateway(authority, parts) {
|
|
@@ -186,6 +173,7 @@ function serviceGateway(authority, parts) {
|
|
|
186
173
|
function hostPorts(authority, parts) {
|
|
187
174
|
const { worker, registry } = parts;
|
|
188
175
|
return {
|
|
176
|
+
commandWait: commandWaitPort({ authority, gateway: parts.gateway }),
|
|
189
177
|
runWait: {
|
|
190
178
|
target: (runId) => runWaitTarget(authority, runId),
|
|
191
179
|
observe: worker.observe,
|
|
@@ -217,14 +205,11 @@ function hostPorts(authority, parts) {
|
|
|
217
205
|
},
|
|
218
206
|
};
|
|
219
207
|
}
|
|
220
|
-
function message(error) {
|
|
221
|
-
return String(Reflect.get(Object(error), "message"));
|
|
222
|
-
}
|
|
223
208
|
async function hosted(options, ports) {
|
|
224
209
|
try {
|
|
225
210
|
return { kind: "started", host: await options.host?.(ports) };
|
|
226
211
|
}
|
|
227
212
|
catch (error) {
|
|
228
|
-
return refused("host-unavailable",
|
|
213
|
+
return refused("host-unavailable", errorMessage(error));
|
|
229
214
|
}
|
|
230
215
|
}
|
|
@@ -7,6 +7,7 @@ import { documentDigest } from "../broker/decision-restore.js";
|
|
|
7
7
|
import { record } from "../protocol.js";
|
|
8
8
|
import { checkResolution, checkSubmission, hasTicketField, normalizedRequest, } from "../submission.js";
|
|
9
9
|
import { activeWorkflow } from "./active-tickets.js";
|
|
10
|
+
import { queueSpend } from "./queue-spend.js";
|
|
10
11
|
import { committed, failed, invalidRequest, publicReceipt, rejection, result, } from "./replies.js";
|
|
11
12
|
export function runIdentity(commandId) {
|
|
12
13
|
return `run-${createHash("sha256").update(commandId).digest("hex").slice(0, 32)}`;
|
|
@@ -125,6 +126,9 @@ async function admit(context, admission) {
|
|
|
125
126
|
const { input } = resolution;
|
|
126
127
|
if (Buffer.byteLength(input) > context.documentBytes)
|
|
127
128
|
return unresolved(context, { kind: "failure", commandId });
|
|
129
|
+
const held = await spendRefusal(context, admission);
|
|
130
|
+
if (held !== undefined)
|
|
131
|
+
return held;
|
|
128
132
|
const receipt = await context.gateway.execute({
|
|
129
133
|
principal: "operator",
|
|
130
134
|
command: {
|
|
@@ -155,9 +159,20 @@ async function admit(context, admission) {
|
|
|
155
159
|
replayed: receipt.kind === "duplicate",
|
|
156
160
|
});
|
|
157
161
|
}
|
|
162
|
+
async function spendRefusal(context, admission) {
|
|
163
|
+
if (admission.workflow.manifest.queue !== true)
|
|
164
|
+
return undefined;
|
|
165
|
+
const spend = record((await queueSpend(context))["spend"]);
|
|
166
|
+
return spend?.["holding"] === true
|
|
167
|
+
? failed("queue-spend-limit", {
|
|
168
|
+
commandId: admission.commandId,
|
|
169
|
+
detail: "Queue holding for spend limit.",
|
|
170
|
+
})
|
|
171
|
+
: undefined;
|
|
172
|
+
}
|
|
158
173
|
function admissionRefusal(workflow, request) {
|
|
159
|
-
const {
|
|
160
|
-
const tickets =
|
|
174
|
+
const { commandId, submission, activeTickets } = request;
|
|
175
|
+
const tickets = hasTicketField(workflow.submission);
|
|
161
176
|
if (tickets &&
|
|
162
177
|
typeof submission["ticket"] === "string" &&
|
|
163
178
|
activeTickets.some((input) => input["ticketId"] === submission["ticket"]))
|
|
@@ -235,8 +250,7 @@ export function submissionHandler(context) {
|
|
|
235
250
|
return (parameters) => {
|
|
236
251
|
const keys = [`command:${String(parameters["commandId"])}`];
|
|
237
252
|
const workflowId = String(parameters["workflowId"]);
|
|
238
|
-
if (workflowId
|
|
239
|
-
hasTicketField(context.registry.byId(workflowId)?.submission) ||
|
|
253
|
+
if (hasTicketField(context.registry.byId(workflowId)?.submission) ||
|
|
240
254
|
context.registry.byId(workflowId)?.admission !== undefined)
|
|
241
255
|
keys.push(`workflow:${workflowId}`);
|
|
242
256
|
const next = () => submitted(context, parameters);
|
|
@@ -86,7 +86,7 @@ function effectPort(parts) {
|
|
|
86
86
|
command: {
|
|
87
87
|
kind: "report-effect",
|
|
88
88
|
...rest,
|
|
89
|
-
...(
|
|
89
|
+
...reportedResult({ result, worker: report.worker }),
|
|
90
90
|
},
|
|
91
91
|
documents: result === undefined ? [] : [result],
|
|
92
92
|
epoch: epoch ?? authority.epoch,
|
|
@@ -124,3 +124,11 @@ export function workerPort(parts) {
|
|
|
124
124
|
...effectPort(parts),
|
|
125
125
|
};
|
|
126
126
|
}
|
|
127
|
+
function reportedResult(report) {
|
|
128
|
+
if (report.result === undefined)
|
|
129
|
+
return {};
|
|
130
|
+
return {
|
|
131
|
+
result: documentDigest(report.result),
|
|
132
|
+
...(report.worker === "command" ? { commandOutput: report.result } : {}),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import { type Fields } from "../protocol.ts";
|
|
1
2
|
import { type WorkerTotals } from "../worker-usage.ts";
|
|
2
3
|
import type { ServiceContext } from "./replies.ts";
|
|
4
|
+
export declare function reportFields(text: string | undefined): Fields;
|
|
3
5
|
export declare function usageTotals(context: ServiceContext, runId: string): Promise<WorkerTotals>;
|
|
6
|
+
export declare function turnDetailsOf(context: ServiceContext, run: {
|
|
7
|
+
readonly runId: string;
|
|
8
|
+
readonly totals: WorkerTotals;
|
|
9
|
+
}): Promise<Fields>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { record } from "../protocol.js";
|
|
2
2
|
import { priceOf, usageOf, attemptsOf, workerTotals, } from "../worker-usage.js";
|
|
3
|
-
function reportFields(text) {
|
|
3
|
+
export function reportFields(text) {
|
|
4
4
|
try {
|
|
5
5
|
return record(JSON.parse(text ?? "null")) ?? {};
|
|
6
6
|
}
|
|
@@ -35,3 +35,10 @@ export async function usageTotals(context, runId) {
|
|
|
35
35
|
}
|
|
36
36
|
return workerTotals(turns);
|
|
37
37
|
}
|
|
38
|
+
export async function turnDetailsOf(context, run) {
|
|
39
|
+
const details = await context.turnDetails?.({
|
|
40
|
+
runId: run.runId,
|
|
41
|
+
operationIds: run.totals.workerTurns.map((turn) => turn.operationId),
|
|
42
|
+
});
|
|
43
|
+
return details === undefined ? {} : { turnDetails: details };
|
|
44
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Fields, Reply } from "../protocol.ts";
|
|
2
|
+
import type { WorkflowRefusal } from "../workflow-refusals.ts";
|
|
3
|
+
import type { Registry, WorkflowCatalog, WorkflowRegistration } from "./registry.ts";
|
|
4
|
+
export interface SettingChanges {
|
|
5
|
+
readonly reloadedFields: readonly string[];
|
|
6
|
+
readonly restartFields: readonly string[];
|
|
7
|
+
}
|
|
8
|
+
export type WorkflowBundleReload = {
|
|
9
|
+
readonly kind: "reloaded";
|
|
10
|
+
readonly bundleDigest: string;
|
|
11
|
+
readonly workflows: readonly WorkflowRegistration[];
|
|
12
|
+
readonly workflowRefusals: readonly WorkflowRefusal[];
|
|
13
|
+
} | {
|
|
14
|
+
readonly kind: "unchanged";
|
|
15
|
+
readonly workflowRefusals: readonly WorkflowRefusal[];
|
|
16
|
+
} | {
|
|
17
|
+
readonly kind: "refused";
|
|
18
|
+
readonly code: string;
|
|
19
|
+
readonly detail: string;
|
|
20
|
+
};
|
|
21
|
+
export type WorkflowReload = (Exclude<WorkflowBundleReload, {
|
|
22
|
+
readonly kind: "refused";
|
|
23
|
+
}> & SettingChanges) | Extract<WorkflowBundleReload, {
|
|
24
|
+
readonly kind: "refused";
|
|
25
|
+
}>;
|
|
26
|
+
export type WorkflowReloadPort = () => Promise<WorkflowReload>;
|
|
27
|
+
export declare function workflowFields(context: {
|
|
28
|
+
readonly registry: Registry;
|
|
29
|
+
readonly workflowCatalog?: WorkflowCatalog;
|
|
30
|
+
}): Fields;
|
|
31
|
+
export declare function reloadOperation(parts: {
|
|
32
|
+
readonly port: WorkflowReloadPort;
|
|
33
|
+
readonly catalog: WorkflowCatalog;
|
|
34
|
+
}): () => Promise<Reply>;
|
|
35
|
+
export declare function reloadUnavailable(): Promise<Reply>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { failed, result } from "./replies.js";
|
|
2
|
+
export function workflowFields(context) {
|
|
3
|
+
const inventory = context.workflowCatalog?.inventory();
|
|
4
|
+
const stages = context.registry.workflowStages;
|
|
5
|
+
return {
|
|
6
|
+
...(inventory?.bundleDigest === undefined
|
|
7
|
+
? {}
|
|
8
|
+
: { bundleDigest: inventory.bundleDigest }),
|
|
9
|
+
workflows: context.registry.workflowIds,
|
|
10
|
+
workflowRefusals: inventory?.workflowRefusals ?? [],
|
|
11
|
+
...(Object.keys(stages).length === 0 ? {} : { workflowStages: stages }),
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function applied(catalog, reload) {
|
|
15
|
+
if (reload.kind === "refused")
|
|
16
|
+
return failed(reload.code, { detail: reload.detail });
|
|
17
|
+
const previousBundleDigest = catalog.inventory().bundleDigest ?? null;
|
|
18
|
+
if (reload.kind === "reloaded")
|
|
19
|
+
catalog.replace(reload);
|
|
20
|
+
else
|
|
21
|
+
catalog.replaceRefusals(reload.workflowRefusals);
|
|
22
|
+
return result("reload", {
|
|
23
|
+
status: reload.kind,
|
|
24
|
+
previousBundleDigest,
|
|
25
|
+
bundleDigest: reload.kind === "reloaded" ? reload.bundleDigest : previousBundleDigest,
|
|
26
|
+
workflows: catalog.registry.workflowIds,
|
|
27
|
+
workflowRefusals: reload.workflowRefusals,
|
|
28
|
+
reloadedFields: reload.reloadedFields,
|
|
29
|
+
restartFields: reload.restartFields,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
export function reloadOperation(parts) {
|
|
33
|
+
let reloading = false;
|
|
34
|
+
return async () => {
|
|
35
|
+
if (reloading)
|
|
36
|
+
return failed("reload-in-progress", {
|
|
37
|
+
detail: "A reload is in work. Wait for its reply.",
|
|
38
|
+
});
|
|
39
|
+
reloading = true;
|
|
40
|
+
try {
|
|
41
|
+
return applied(parts.catalog, await parts.port());
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
reloading = false;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export function reloadUnavailable() {
|
|
49
|
+
return Promise.resolve(failed("reload-unavailable", {
|
|
50
|
+
detail: "This service cannot reload the workflow files. Restart it to read them.",
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
@@ -64,6 +64,22 @@ export interface RunWaitOutcome {
|
|
|
64
64
|
readonly reason: string | null;
|
|
65
65
|
readonly promotionId: string | null;
|
|
66
66
|
}
|
|
67
|
+
export interface CommandWaitRequest {
|
|
68
|
+
readonly name: string;
|
|
69
|
+
readonly input: HandoffValue;
|
|
70
|
+
}
|
|
71
|
+
export type CommandWaitOutcome = {
|
|
72
|
+
readonly kind: "ready";
|
|
73
|
+
readonly value: HandoffValue;
|
|
74
|
+
} | {
|
|
75
|
+
readonly kind: "timed-out" | "failed" | "refused" | "unavailable";
|
|
76
|
+
readonly reason: string;
|
|
77
|
+
};
|
|
78
|
+
export type CommandWaitProgress = CommandWaitOutcome | {
|
|
79
|
+
readonly kind: "pending";
|
|
80
|
+
readonly deadline: number;
|
|
81
|
+
readonly nextCheckAt: number;
|
|
82
|
+
};
|
|
67
83
|
export interface CommandRequest {
|
|
68
84
|
readonly scope: ProtectedScope;
|
|
69
85
|
readonly name: string;
|
|
@@ -80,6 +96,10 @@ export type GateResult = {
|
|
|
80
96
|
readonly reason: string;
|
|
81
97
|
};
|
|
82
98
|
export interface StepBridge {
|
|
99
|
+
readonly openCommandWait?: (request: CommandWaitRequest) => Promise<CommandWaitProgress>;
|
|
100
|
+
readonly checkCommandWait?: (request: {
|
|
101
|
+
readonly name: string;
|
|
102
|
+
}) => Promise<CommandWaitProgress>;
|
|
83
103
|
readonly effect: (request: ProtectedRequest) => Promise<ProtectedResult>;
|
|
84
104
|
readonly gate: (request: GateRequest) => Promise<GateResult>;
|
|
85
105
|
readonly waitForDecision?: (request: GateRequest) => Promise<DecisionWait>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type CommandWaitRequest, type CommandWaitProgress } from "../command-wait.ts";
|
|
2
|
+
export declare function openCommandWait(request: CommandWaitRequest): Promise<CommandWaitProgress>;
|
|
3
|
+
export declare namespace openCommandWait {
|
|
4
|
+
var maxRetries: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function checkCommandWait(request: {
|
|
7
|
+
readonly name: string;
|
|
8
|
+
}): Promise<CommandWaitProgress>;
|
|
9
|
+
export declare namespace checkCommandWait {
|
|
10
|
+
var maxRetries: number;
|
|
11
|
+
}
|
|
12
|
+
export declare function commandWaitDate(milliseconds: number): Date;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { isStepBridge, stepBridgeKey } from "../step-bridge.js";
|
|
2
|
+
import { isCommandWaitRequest, } from "../command-wait.js";
|
|
3
|
+
export async function openCommandWait(request) {
|
|
4
|
+
"use step";
|
|
5
|
+
if (!isCommandWaitRequest(request))
|
|
6
|
+
return { kind: "refused", reason: "invalid-command-wait-request" };
|
|
7
|
+
const bridge = Reflect.get(globalThis, Symbol.for(stepBridgeKey));
|
|
8
|
+
if (!isStepBridge(bridge) || bridge.openCommandWait === undefined)
|
|
9
|
+
return { kind: "unavailable", reason: "cloving-host-unavailable" };
|
|
10
|
+
return await bridge.openCommandWait({
|
|
11
|
+
name: request.name,
|
|
12
|
+
input: request.input,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
export async function checkCommandWait(request) {
|
|
16
|
+
"use step";
|
|
17
|
+
const bridge = Reflect.get(globalThis, Symbol.for(stepBridgeKey));
|
|
18
|
+
if (!isStepBridge(bridge) || bridge.checkCommandWait === undefined)
|
|
19
|
+
return { kind: "unavailable", reason: "cloving-host-unavailable" };
|
|
20
|
+
return await bridge.checkCommandWait({ name: request.name });
|
|
21
|
+
}
|
|
22
|
+
openCommandWait.maxRetries = 0;
|
|
23
|
+
checkCommandWait.maxRetries = 0;
|
|
24
|
+
export function commandWaitDate(milliseconds) {
|
|
25
|
+
return new Date(milliseconds);
|
|
26
|
+
}
|
|
@@ -1,11 +1,4 @@
|
|
|
1
1
|
import { isStepBridge, stepBridgeKey, } from "../step-bridge.js";
|
|
2
|
-
export async function decisionGate(request) {
|
|
3
|
-
"use step";
|
|
4
|
-
const bridge = Reflect.get(globalThis, Symbol.for(stepBridgeKey));
|
|
5
|
-
if (!isStepBridge(bridge))
|
|
6
|
-
return { kind: "unavailable", reason: "cloving-host-unavailable" };
|
|
7
|
-
return await bridge.gate(request);
|
|
8
|
-
}
|
|
9
2
|
export async function openDecisionWait(request) {
|
|
10
3
|
"use step";
|
|
11
4
|
const bridge = Reflect.get(globalThis, Symbol.for(stepBridgeKey));
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { snapshotReviewSubject } from "./review-subject.js";
|
|
2
2
|
import { waitForDecision } from "./wait-for-decision.js";
|
|
3
3
|
export async function reviewByPerson(request) {
|
|
4
|
+
let draft = "draft" in request.subject ? request.subject.draft : null;
|
|
5
|
+
if (draft !== null && request.subject.commit !== undefined)
|
|
6
|
+
draft = `${request.subject.commit}\n${draft}`;
|
|
4
7
|
const snapshot = await snapshotReviewSubject(request.subject);
|
|
5
8
|
const decision = await waitForDecision({
|
|
6
9
|
gateId: `review:${snapshot.subjectDigest}`,
|
|
7
10
|
kind: "approval",
|
|
8
|
-
prompt: `Review this subject:\n${snapshot.prompt}`,
|
|
11
|
+
prompt: `Review this subject:\n${draft ?? snapshot.prompt}`,
|
|
9
12
|
});
|
|
10
13
|
return {
|
|
11
14
|
accepted: decision.decision === "approved",
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { sleep } from "workflow";
|
|
2
|
+
import { isCommandWaitRequest, } from "../command-wait.js";
|
|
3
|
+
import { openCommandWait, checkCommandWait, commandWaitDate, } from "./command-wait.js";
|
|
4
|
+
export async function waitForCommand(request) {
|
|
5
|
+
if (!isCommandWaitRequest(request))
|
|
6
|
+
return { kind: "refused", reason: "invalid-command-wait-request" };
|
|
7
|
+
let result = await openCommandWait({
|
|
8
|
+
name: request.name,
|
|
9
|
+
input: request.input,
|
|
10
|
+
});
|
|
11
|
+
while (result.kind === "pending") {
|
|
12
|
+
result = await checkCommandWait({ name: request.name });
|
|
13
|
+
if (result.kind === "pending")
|
|
14
|
+
await sleep(commandWaitDate(Math.min(result.deadline, result.nextCheckAt)));
|
|
15
|
+
}
|
|
16
|
+
return result;
|
|
17
|
+
}
|
|
@@ -51,7 +51,7 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
|
|
|
51
51
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
52
|
});
|
|
53
53
|
import { createHook } from "workflow";
|
|
54
|
-
import { openDecisionWait } from "./decision-
|
|
54
|
+
import { openDecisionWait } from "./open-decision-wait.js";
|
|
55
55
|
export async function waitForDecision(request) {
|
|
56
56
|
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
57
57
|
try {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type SqlConnection } from "./domain-rows.ts";
|
|
2
|
+
import { type Statement } from "./statements.ts";
|
|
3
|
+
export declare const commandWaitSchema = "\nCREATE TABLE command_waits (\n run_id TEXT NOT NULL REFERENCES runs (run_id) DEFERRABLE INITIALLY DEFERRED,\n name TEXT NOT NULL,\n command TEXT NOT NULL,\n input_digest TEXT NOT NULL REFERENCES documents (digest) DEFERRABLE INITIALLY DEFERRED,\n maximum_wait_seconds INTEGER NOT NULL,\n poll_every_seconds INTEGER NOT NULL,\n started_at INTEGER NOT NULL,\n deadline INTEGER NOT NULL,\n next_check_at INTEGER,\n state TEXT NOT NULL,\n settled_at INTEGER,\n reason TEXT,\n PRIMARY KEY (run_id, name)\n) STRICT;\n";
|
|
4
|
+
export declare const commandWaitCheckSchema = "\nALTER TABLE command_waits ADD COLUMN check_count INTEGER NOT NULL DEFAULT 0;\nALTER TABLE command_waits ADD COLUMN check_operation TEXT;\nALTER TABLE command_waits ADD COLUMN last_check_settled_at INTEGER;\nALTER TABLE command_waits ADD COLUMN result TEXT;\n";
|
|
5
|
+
export interface CommandWaitRow {
|
|
6
|
+
readonly runId: string;
|
|
7
|
+
readonly name: string;
|
|
8
|
+
readonly command: string;
|
|
9
|
+
readonly inputDigest: string;
|
|
10
|
+
readonly maximumWaitSeconds: number;
|
|
11
|
+
readonly pollEverySeconds: number;
|
|
12
|
+
readonly startedAt: number;
|
|
13
|
+
readonly deadline: number;
|
|
14
|
+
readonly nextCheckAt: number | null;
|
|
15
|
+
readonly state: string;
|
|
16
|
+
readonly checkCount: number;
|
|
17
|
+
readonly checkOperation: string | null;
|
|
18
|
+
readonly lastCheckSettledAt: number | null;
|
|
19
|
+
readonly result: string | null;
|
|
20
|
+
readonly settledAt: number | null;
|
|
21
|
+
readonly reason: string | null;
|
|
22
|
+
}
|
|
23
|
+
export declare function commandWaitRow(value: unknown): CommandWaitRow;
|
|
24
|
+
export declare function loadCommandWaits(connection: SqlConnection, scope?: {
|
|
25
|
+
readonly runId?: string;
|
|
26
|
+
readonly version?: "opened";
|
|
27
|
+
}): Promise<readonly CommandWaitRow[]>;
|
|
28
|
+
export declare function commandWaitStatements(rows: readonly CommandWaitRow[], scope?: {
|
|
29
|
+
readonly version?: "opened";
|
|
30
|
+
}): readonly Statement[];
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { integer, optionalInteger, optionalText, text, } from "./domain-rows.js";
|
|
2
|
+
import { upsert } from "./statements.js";
|
|
3
|
+
export const commandWaitSchema = `
|
|
4
|
+
CREATE TABLE command_waits (
|
|
5
|
+
run_id TEXT NOT NULL REFERENCES runs (run_id) DEFERRABLE INITIALLY DEFERRED,
|
|
6
|
+
name TEXT NOT NULL,
|
|
7
|
+
command TEXT NOT NULL,
|
|
8
|
+
input_digest TEXT NOT NULL REFERENCES documents (digest) DEFERRABLE INITIALLY DEFERRED,
|
|
9
|
+
maximum_wait_seconds INTEGER NOT NULL,
|
|
10
|
+
poll_every_seconds INTEGER NOT NULL,
|
|
11
|
+
started_at INTEGER NOT NULL,
|
|
12
|
+
deadline INTEGER NOT NULL,
|
|
13
|
+
next_check_at INTEGER,
|
|
14
|
+
state TEXT NOT NULL,
|
|
15
|
+
settled_at INTEGER,
|
|
16
|
+
reason TEXT,
|
|
17
|
+
PRIMARY KEY (run_id, name)
|
|
18
|
+
) STRICT;
|
|
19
|
+
`;
|
|
20
|
+
export const commandWaitCheckSchema = `
|
|
21
|
+
ALTER TABLE command_waits ADD COLUMN check_count INTEGER NOT NULL DEFAULT 0;
|
|
22
|
+
ALTER TABLE command_waits ADD COLUMN check_operation TEXT;
|
|
23
|
+
ALTER TABLE command_waits ADD COLUMN last_check_settled_at INTEGER;
|
|
24
|
+
ALTER TABLE command_waits ADD COLUMN result TEXT;
|
|
25
|
+
`;
|
|
26
|
+
const openingColumns = "run_id, name, command, input_digest, maximum_wait_seconds, poll_every_seconds, started_at, deadline, next_check_at, state, settled_at, reason";
|
|
27
|
+
const checkColumns = "check_count, check_operation, last_check_settled_at, result";
|
|
28
|
+
const columns = `${openingColumns}, ${checkColumns}`;
|
|
29
|
+
const save = upsert({
|
|
30
|
+
table: "command_waits",
|
|
31
|
+
names: columns.split(", "),
|
|
32
|
+
key: 2,
|
|
33
|
+
});
|
|
34
|
+
export function commandWaitRow(value) {
|
|
35
|
+
return {
|
|
36
|
+
runId: text(value, "run_id"),
|
|
37
|
+
name: text(value, "name"),
|
|
38
|
+
command: text(value, "command"),
|
|
39
|
+
inputDigest: text(value, "input_digest"),
|
|
40
|
+
maximumWaitSeconds: integer(value, "maximum_wait_seconds"),
|
|
41
|
+
pollEverySeconds: integer(value, "poll_every_seconds"),
|
|
42
|
+
startedAt: integer(value, "started_at"),
|
|
43
|
+
deadline: integer(value, "deadline"),
|
|
44
|
+
nextCheckAt: optionalInteger(value, "next_check_at"),
|
|
45
|
+
state: text(value, "state"),
|
|
46
|
+
checkCount: integer(value, "check_count"),
|
|
47
|
+
checkOperation: optionalText(value, "check_operation"),
|
|
48
|
+
lastCheckSettledAt: optionalInteger(value, "last_check_settled_at"),
|
|
49
|
+
result: optionalText(value, "result"),
|
|
50
|
+
settledAt: optionalInteger(value, "settled_at"),
|
|
51
|
+
reason: optionalText(value, "reason"),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export async function loadCommandWaits(connection, scope = {}) {
|
|
55
|
+
const { runId } = scope;
|
|
56
|
+
const selected = scope.version === "opened"
|
|
57
|
+
? `${openingColumns}, 0 AS check_count, NULL AS check_operation, NULL AS last_check_settled_at, NULL AS result`
|
|
58
|
+
: columns;
|
|
59
|
+
const rows = await connection.all(`SELECT ${selected} FROM command_waits` +
|
|
60
|
+
(runId === undefined ? "" : " WHERE run_id = ?") +
|
|
61
|
+
" ORDER BY run_id, name", runId === undefined ? [] : [runId]);
|
|
62
|
+
return rows.map(commandWaitRow);
|
|
63
|
+
}
|
|
64
|
+
export function commandWaitStatements(rows, scope = {}) {
|
|
65
|
+
return rows.map((row) => ({
|
|
66
|
+
sql: scope.version === "opened"
|
|
67
|
+
? upsert({
|
|
68
|
+
table: "command_waits",
|
|
69
|
+
names: openingColumns.split(", "),
|
|
70
|
+
key: 2,
|
|
71
|
+
})
|
|
72
|
+
: save,
|
|
73
|
+
parameters: [
|
|
74
|
+
row.runId,
|
|
75
|
+
row.name,
|
|
76
|
+
row.command,
|
|
77
|
+
row.inputDigest,
|
|
78
|
+
row.maximumWaitSeconds,
|
|
79
|
+
row.pollEverySeconds,
|
|
80
|
+
row.startedAt,
|
|
81
|
+
row.deadline,
|
|
82
|
+
row.nextCheckAt,
|
|
83
|
+
row.state,
|
|
84
|
+
row.settledAt,
|
|
85
|
+
row.reason,
|
|
86
|
+
...(scope.version === "opened"
|
|
87
|
+
? []
|
|
88
|
+
: [
|
|
89
|
+
row.checkCount,
|
|
90
|
+
row.checkOperation,
|
|
91
|
+
row.lastCheckSettledAt,
|
|
92
|
+
row.result,
|
|
93
|
+
]),
|
|
94
|
+
],
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type CommandWaitRow } from "./command-wait-rows.ts";
|
|
1
2
|
import { type DecisionRows, type DocumentRow } from "./decision-rows.ts";
|
|
2
3
|
import { type AttemptRow, type DomainSnapshot, type ProjectionRows, type SqlConnection } from "./domain-rows.ts";
|
|
3
4
|
import { type EffectRows } from "./effect-rows.ts";
|
|
@@ -5,14 +6,19 @@ export interface ProjectionSnapshot extends ProjectionRows, DecisionRows {
|
|
|
5
6
|
readonly deliveries: readonly AttemptRow[];
|
|
6
7
|
readonly pending: readonly string[];
|
|
7
8
|
readonly sequence: number;
|
|
9
|
+
readonly waits: readonly CommandWaitRow[];
|
|
8
10
|
}
|
|
9
11
|
export interface DecidedSnapshot extends DomainSnapshot, DecisionRows {
|
|
10
12
|
readonly documents: readonly DocumentRow[];
|
|
11
13
|
}
|
|
12
|
-
export interface
|
|
14
|
+
export interface EffectedSnapshot extends DecidedSnapshot {
|
|
13
15
|
readonly effects: EffectRows;
|
|
14
16
|
}
|
|
15
|
-
export
|
|
17
|
+
export interface CurrentSnapshot extends EffectedSnapshot {
|
|
18
|
+
readonly waits: readonly CommandWaitRow[];
|
|
19
|
+
}
|
|
16
20
|
export declare function loadProjections(connection: SqlConnection): Promise<ProjectionSnapshot>;
|
|
17
21
|
export declare function loadDecided(connection: SqlConnection): Promise<DecidedSnapshot>;
|
|
22
|
+
export declare function loadEffected(connection: SqlConnection): Promise<EffectedSnapshot>;
|
|
18
23
|
export declare function loadCurrent(connection: SqlConnection): Promise<CurrentSnapshot>;
|
|
24
|
+
export declare function loadWaiting(connection: SqlConnection): Promise<CurrentSnapshot>;
|