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
|
@@ -1,94 +1,109 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
1
|
import { turnHarness } from "../harness-defaults.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { attachmentEnvironment } from "./attachments.js";
|
|
3
|
+
import { profileCommand } from "../turn-profile.js";
|
|
4
|
+
import {} from "./claude-turn.js";
|
|
5
|
+
import { turnOutcome } from "./turn-report.js";
|
|
6
6
|
import { startRetriedTurn } from "./retrying-turn.js";
|
|
7
|
-
import {
|
|
8
|
-
import { treeFailure, workTree } from "./work-tree.js";
|
|
7
|
+
import { located, readRecord as read, replied, reportOf, writeRecord as written, } from "./operation-journal.js";
|
|
8
|
+
import { firstTurn, treeFailure, workTree, } from "./work-tree.js";
|
|
9
|
+
import { recordedHarness, interruptedReply, processAlive, uncertainProcess, resumePlan, recordedField, resumableHarness, recoverTurn, turnIntent, } from "./claude-recovery.js";
|
|
10
|
+
import { checkedProfiles, selectedProfile } from "./worker-profile.js";
|
|
9
11
|
export const claudeLimits = {
|
|
10
12
|
summaryCharacters: 16_000,
|
|
11
13
|
resultBytes: 48_000,
|
|
12
|
-
stopMilliseconds:
|
|
14
|
+
stopMilliseconds: 15_000,
|
|
13
15
|
};
|
|
14
16
|
const worker = "claude";
|
|
15
|
-
|
|
16
|
-
const {
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
catch (error) {
|
|
29
|
-
return Reflect.get(Object(error), "code") === "EPERM";
|
|
30
|
-
}
|
|
17
|
+
function reconciled(parts, call) {
|
|
18
|
+
const { intent } = call;
|
|
19
|
+
const { key } = located(parts.settings.journal, intent.operationId);
|
|
20
|
+
const pending = parts.reconciling.get(key);
|
|
21
|
+
if (pending !== undefined)
|
|
22
|
+
return pending;
|
|
23
|
+
const reconciliation = reconcileOperation(parts, call).finally(() => {
|
|
24
|
+
if (parts.reconciling.get(key) === reconciliation)
|
|
25
|
+
parts.reconciling.delete(key);
|
|
26
|
+
});
|
|
27
|
+
parts.reconciling.set(key, reconciliation);
|
|
28
|
+
return reconciliation;
|
|
31
29
|
}
|
|
32
|
-
async function
|
|
30
|
+
async function reconcileOperation(parts, call) {
|
|
31
|
+
const { intent, signal } = call;
|
|
33
32
|
const { key, folder } = located(parts.settings.journal, intent.operationId);
|
|
34
33
|
const result = await read(folder, "result.json");
|
|
35
|
-
if (result !== undefined
|
|
34
|
+
if (result !== undefined &&
|
|
35
|
+
(recordedField(result, "stoppedBy") !== "daemon-shutdown" ||
|
|
36
|
+
parts.stopping.signal.aborted))
|
|
36
37
|
return replied({ receipt: key, worker }, result);
|
|
37
38
|
if (parts.active.has(key))
|
|
38
39
|
return { kind: "accepted", receipt: key, worker };
|
|
39
40
|
const started = await read(folder, "started.json");
|
|
40
41
|
if (started === undefined)
|
|
41
42
|
return { kind: "absent" };
|
|
42
|
-
if (
|
|
43
|
+
if (await uncertainProcess(started))
|
|
43
44
|
return { kind: "unknown", evidence: `claude-turn:${key}` };
|
|
44
|
-
|
|
45
|
-
await written(folder, { name: "result.json", value: ending });
|
|
46
|
-
return replied({ receipt: key, worker }, ending);
|
|
45
|
+
return resumed(parts, { intent, key, folder, started, signal });
|
|
47
46
|
}
|
|
48
|
-
async function
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (
|
|
60
|
-
return
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
47
|
+
async function resumed(parts, request) {
|
|
48
|
+
const { intent, started, key, folder, signal } = request;
|
|
49
|
+
const aborted = () => signal.aborted;
|
|
50
|
+
if (!turnIntent(intent))
|
|
51
|
+
return interruptedReply(request, "claude-turn-interrupted");
|
|
52
|
+
if (aborted())
|
|
53
|
+
return failure("claude-start-aborted");
|
|
54
|
+
const current = parts.settings.turnSettings();
|
|
55
|
+
const plan = await resumePlan({ ...parts.settings, ...current }, { folder, started, intent, signal });
|
|
56
|
+
if (aborted())
|
|
57
|
+
return failure("claude-start-aborted");
|
|
58
|
+
if (typeof plan === "string")
|
|
59
|
+
return interruptedReply(request, plan);
|
|
60
|
+
const prompt = await parts.settings.document(intent.payload);
|
|
61
|
+
if (aborted())
|
|
62
|
+
return failure("claude-start-aborted");
|
|
63
|
+
if (prompt === undefined)
|
|
64
|
+
return interruptedReply(request, "claude-turn-interrupted");
|
|
65
|
+
await begun(parts, {
|
|
66
|
+
key,
|
|
67
|
+
folder,
|
|
68
|
+
intent,
|
|
69
|
+
...plan,
|
|
70
|
+
signal,
|
|
71
|
+
prompt,
|
|
72
|
+
turnSettings: current,
|
|
73
|
+
});
|
|
74
|
+
return { kind: "accepted", receipt: key, worker };
|
|
70
75
|
}
|
|
71
76
|
async function concluded(parts, running) {
|
|
72
77
|
const { intent, key } = running;
|
|
73
|
-
const recorded = await
|
|
78
|
+
const recorded = await turnOutcome({ ...running, limits: claudeLimits }, await running.turn.ended);
|
|
74
79
|
await written(running.folder, { name: "result.json", value: recorded });
|
|
80
|
+
if (recorded.stoppedBy === "daemon-shutdown")
|
|
81
|
+
return;
|
|
75
82
|
await parts.settings.report(reportOf({ intent, commandId: `claude-turn:${key}`, worker }, recorded));
|
|
76
83
|
}
|
|
77
84
|
async function begun(parts, start) {
|
|
78
85
|
const { intent, key, folder, tree, prompt } = start;
|
|
79
86
|
const { harness } = start;
|
|
80
87
|
const stopping = { requested: false, controller: new AbortController() };
|
|
88
|
+
const cancel = () => {
|
|
89
|
+
stopping.controller.abort();
|
|
90
|
+
};
|
|
91
|
+
start.signal.addEventListener("abort", cancel, { once: true });
|
|
92
|
+
if (start.signal.aborted)
|
|
93
|
+
cancel();
|
|
81
94
|
const turn = startRetriedTurn({
|
|
82
95
|
...harness,
|
|
83
96
|
resultBytes: claudeLimits.resultBytes,
|
|
84
97
|
command: profileCommand(harness.command, start.profile),
|
|
85
|
-
environment:
|
|
98
|
+
environment: await attachmentEnvironment(parts.settings, start),
|
|
86
99
|
turnId: `${intent.runId}-${key}`,
|
|
87
100
|
directory: tree.path,
|
|
88
101
|
folder,
|
|
89
102
|
prompt,
|
|
90
103
|
}, {
|
|
91
104
|
...parts.settings,
|
|
105
|
+
...start.turnSettings,
|
|
106
|
+
...(start.resume === undefined ? {} : { resume: start.resume }),
|
|
92
107
|
stopping: stopping.controller,
|
|
93
108
|
metadata: {
|
|
94
109
|
harness: harness.worker,
|
|
@@ -100,6 +115,7 @@ async function begun(parts, start) {
|
|
|
100
115
|
},
|
|
101
116
|
});
|
|
102
117
|
parts.active.set(key, {
|
|
118
|
+
worker: harness.worker,
|
|
103
119
|
turn,
|
|
104
120
|
stopping,
|
|
105
121
|
concluded: turn
|
|
@@ -107,74 +123,13 @@ async function begun(parts, start) {
|
|
|
107
123
|
.catch(() => undefined)
|
|
108
124
|
.finally(() => parts.active.delete(key)),
|
|
109
125
|
});
|
|
110
|
-
await turn
|
|
111
|
-
|
|
112
|
-
async function firstTurn(settings, opening) {
|
|
113
|
-
const { tree, intent } = opening;
|
|
114
|
-
const { target, runId } = intent;
|
|
115
|
-
const folder = target.startsWith("branch:")
|
|
116
|
-
? join(settings.journal, "runs", operationKey(runId), "targets")
|
|
117
|
-
: join(settings.journal, "targets");
|
|
118
|
-
const name = `${operationKey(target)}.json`;
|
|
119
|
-
const startCommit = Reflect.get(Object(await read(folder, name)), "startCommit");
|
|
120
|
-
if (typeof startCommit === "string")
|
|
121
|
-
return { ...tree, startCommit };
|
|
122
|
-
await written(folder, {
|
|
123
|
-
name,
|
|
124
|
-
value: { target, startCommit: tree.startCommit },
|
|
126
|
+
await turn.finally(() => {
|
|
127
|
+
start.signal.removeEventListener("abort", cancel);
|
|
125
128
|
});
|
|
126
|
-
return tree;
|
|
127
|
-
}
|
|
128
|
-
function turnIntent(intent) {
|
|
129
|
-
return (intent.capability === worker &&
|
|
130
|
-
(intent.method === "run-turn" ||
|
|
131
|
-
/^run-turn:[A-Za-z0-9_-]{1,119}$/.test(intent.method ?? "")) &&
|
|
132
|
-
intent.target !== undefined &&
|
|
133
|
-
intent.payload !== undefined &&
|
|
134
|
-
intent.leaseGeneration !== undefined);
|
|
135
129
|
}
|
|
136
130
|
function failure(reason) {
|
|
137
131
|
return { kind: "failed", reason };
|
|
138
132
|
}
|
|
139
|
-
async function runWorkflow(settings, runId) {
|
|
140
|
-
try {
|
|
141
|
-
return await settings.workflowId?.(runId);
|
|
142
|
-
}
|
|
143
|
-
catch {
|
|
144
|
-
return undefined;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
function unsupportedProfile(profile, harness) {
|
|
148
|
-
if (harness.output === "text" && profile.model !== undefined)
|
|
149
|
-
return "profile-model-not-supported";
|
|
150
|
-
if (harness.worker === "claude")
|
|
151
|
-
return undefined;
|
|
152
|
-
return [
|
|
153
|
-
profile.allowedTools,
|
|
154
|
-
profile.permissionMode,
|
|
155
|
-
profile.maxBudgetUsd,
|
|
156
|
-
].some((value) => value !== undefined)
|
|
157
|
-
? "profile-needs-claude"
|
|
158
|
-
: undefined;
|
|
159
|
-
}
|
|
160
|
-
async function selectedProfile(settings, intent) {
|
|
161
|
-
if (intent.method === "run-turn")
|
|
162
|
-
return {};
|
|
163
|
-
const name = intent.method.slice("run-turn:".length);
|
|
164
|
-
const profiles = settings.profiles ?? {};
|
|
165
|
-
const profile = Object.hasOwn(profiles, name) ? profiles[name] : undefined;
|
|
166
|
-
if (profile === undefined)
|
|
167
|
-
return "unknown-profile";
|
|
168
|
-
const unsupported = unsupportedProfile(profile, turnHarness(settings, profile));
|
|
169
|
-
if (unsupported !== undefined)
|
|
170
|
-
return unsupported;
|
|
171
|
-
if (profile.workflows === undefined)
|
|
172
|
-
return profile;
|
|
173
|
-
const workflowId = await runWorkflow(settings, intent.runId);
|
|
174
|
-
if (workflowId === undefined || !profile.workflows.includes(workflowId))
|
|
175
|
-
return "profile-not-allowed";
|
|
176
|
-
return profile;
|
|
177
|
-
}
|
|
178
133
|
async function delivered(parts, call) {
|
|
179
134
|
const { intent, signal } = call;
|
|
180
135
|
const { settings } = parts;
|
|
@@ -183,10 +138,11 @@ async function delivered(parts, call) {
|
|
|
183
138
|
return failure("unsupported-effect");
|
|
184
139
|
if (aborted())
|
|
185
140
|
return failure("claude-start-aborted");
|
|
186
|
-
const known = await reconciled(parts,
|
|
141
|
+
const known = await reconciled(parts, call);
|
|
187
142
|
if (known.kind !== "absent")
|
|
188
143
|
return known;
|
|
189
|
-
const
|
|
144
|
+
const current = settings.turnSettings();
|
|
145
|
+
const profile = await selectedProfile({ ...settings, ...current }, intent);
|
|
190
146
|
if (typeof profile === "string")
|
|
191
147
|
return failure(profile);
|
|
192
148
|
const prompt = await settings.document(intent.payload);
|
|
@@ -213,6 +169,8 @@ async function delivered(parts, call) {
|
|
|
213
169
|
prompt,
|
|
214
170
|
profile,
|
|
215
171
|
harness: turnHarness(settings, profile),
|
|
172
|
+
signal,
|
|
173
|
+
turnSettings: current,
|
|
216
174
|
});
|
|
217
175
|
return { receipt: place.key, worker };
|
|
218
176
|
}
|
|
@@ -224,37 +182,80 @@ async function halted(parts, active) {
|
|
|
224
182
|
await active.concluded;
|
|
225
183
|
}
|
|
226
184
|
async function stopped(parts, intent) {
|
|
227
|
-
const { key } = located(parts.settings.journal, intent.operationId);
|
|
185
|
+
const { key, folder } = located(parts.settings.journal, intent.operationId);
|
|
228
186
|
const active = parts.active.get(key);
|
|
229
|
-
if (active !== undefined)
|
|
187
|
+
if (active !== undefined) {
|
|
188
|
+
delete active.stopping.stoppedBy;
|
|
230
189
|
await halted(parts, active);
|
|
231
|
-
|
|
190
|
+
}
|
|
191
|
+
const result = await read(folder, "result.json");
|
|
192
|
+
if (result !== undefined &&
|
|
193
|
+
recordedField(result, "stoppedBy") !== "daemon-shutdown")
|
|
194
|
+
return replied({ receipt: key, worker }, result);
|
|
195
|
+
const started = await read(folder, "started.json");
|
|
196
|
+
if (started === undefined)
|
|
197
|
+
return { kind: "absent" };
|
|
198
|
+
if (!resumableHarness(recordedField(started, "harness")))
|
|
199
|
+
return reconcileOperation(parts, { intent, signal: parts.stopping.signal });
|
|
200
|
+
if (processAlive(recordedField(started, "processId")))
|
|
201
|
+
return { kind: "unknown", evidence: `claude-turn:${key}` };
|
|
202
|
+
if (!turnIntent(intent))
|
|
203
|
+
return failure("unsupported-effect");
|
|
204
|
+
const recorded = {
|
|
205
|
+
outcome: "stopped",
|
|
206
|
+
endedAt: new Date().toISOString(),
|
|
207
|
+
};
|
|
208
|
+
await written(folder, { name: "result.json", value: recorded });
|
|
209
|
+
await parts.settings.report(reportOf({ intent, commandId: `claude-turn:${key}`, worker }, recorded));
|
|
210
|
+
return replied({ receipt: key, worker }, recorded);
|
|
211
|
+
}
|
|
212
|
+
function stoppingOperation(parts, intent) {
|
|
213
|
+
const { key } = located(parts.settings.journal, intent.operationId);
|
|
214
|
+
const pending = parts.reconciling.get(key);
|
|
215
|
+
const stop = () => stopped(parts, intent);
|
|
216
|
+
const stopping = pending === undefined ? stop() : pending.then(stop, stop);
|
|
217
|
+
const settled = stopping.finally(() => {
|
|
218
|
+
if (parts.reconciling.get(key) === settled)
|
|
219
|
+
parts.reconciling.delete(key);
|
|
220
|
+
});
|
|
221
|
+
parts.reconciling.set(key, settled);
|
|
222
|
+
return settled;
|
|
232
223
|
}
|
|
233
224
|
export function claudeWorker(settings) {
|
|
234
225
|
if (settings.command.length === 0)
|
|
235
226
|
throw new Error("invalid-claude-command");
|
|
236
227
|
turnHarness(settings);
|
|
237
|
-
|
|
238
|
-
turnHarness(settings, profile);
|
|
228
|
+
checkedProfiles(settings, settings.turnSettings().profiles);
|
|
239
229
|
const parts = {
|
|
240
230
|
settings,
|
|
241
231
|
active: new Map(),
|
|
232
|
+
reconciling: new Map(),
|
|
242
233
|
stopping: new AbortController(),
|
|
243
234
|
};
|
|
244
235
|
const guarded = (intent, run) => intent.method === "run-turn:analyze-chats"
|
|
245
236
|
? Promise.resolve(failure("unsupported-effect"))
|
|
246
237
|
: run();
|
|
247
238
|
return {
|
|
239
|
+
recover: (intent) => turnIntent(intent)
|
|
240
|
+
? recoverTurn({ ...settings, intent, signal: parts.stopping.signal }, () => reconciled(parts, { intent, signal: parts.stopping.signal }))
|
|
241
|
+
: Promise.resolve(),
|
|
248
242
|
harness: (operationId) => recordedHarness(settings.journal, operationId),
|
|
249
243
|
deliver: (intent, signal) => guarded(intent, () => delivered(parts, {
|
|
250
244
|
intent,
|
|
251
245
|
signal: AbortSignal.any([signal, parts.stopping.signal]),
|
|
252
246
|
})),
|
|
253
|
-
reconcile: (intent) => guarded(intent, () => reconciled(parts,
|
|
254
|
-
|
|
247
|
+
reconcile: (intent, signal) => guarded(intent, () => reconciled(parts, {
|
|
248
|
+
intent,
|
|
249
|
+
signal: AbortSignal.any([signal, parts.stopping.signal]),
|
|
250
|
+
})),
|
|
251
|
+
stop: (intent) => guarded(intent, () => stoppingOperation(parts, intent)),
|
|
255
252
|
close: async () => {
|
|
256
253
|
parts.stopping.abort();
|
|
257
|
-
await Promise.all([...parts.active.values()].map((active) =>
|
|
254
|
+
await Promise.all([...parts.active.values()].map((active) => {
|
|
255
|
+
if (resumableHarness(active.worker) && !active.stopping.requested)
|
|
256
|
+
active.stopping.stoppedBy = "daemon-shutdown";
|
|
257
|
+
return halted(parts, active);
|
|
258
|
+
}));
|
|
258
259
|
},
|
|
259
260
|
};
|
|
260
261
|
}
|
|
@@ -12,12 +12,15 @@ import type { LocalCommands } from "../command-settings.ts";
|
|
|
12
12
|
import type { DeclaredWorkflow } from "../workflow-declaration.ts";
|
|
13
13
|
import type { WorkflowRefusal } from "../workflow-refusals.ts";
|
|
14
14
|
import type { HarnessSettings } from "../harness-defaults.ts";
|
|
15
|
+
import type { RetentionSettings } from "../record-retention.ts";
|
|
16
|
+
import { type SettingDigests, type TurnSettingsSource } from "./settings-reload.ts";
|
|
15
17
|
export interface DaemonSettings extends HarnessSettings {
|
|
16
18
|
readonly commands?: LocalCommands;
|
|
17
19
|
readonly commandSeconds?: number;
|
|
18
20
|
readonly fallbackModels?: readonly string[];
|
|
19
21
|
readonly tokenPrices?: TokenPrices;
|
|
20
22
|
readonly profiles?: TurnProfiles;
|
|
23
|
+
readonly settingDigests?: SettingDigests;
|
|
21
24
|
readonly directory: string;
|
|
22
25
|
readonly runtimeDirectory: string;
|
|
23
26
|
readonly repository: string;
|
|
@@ -28,6 +31,7 @@ export interface DaemonSettings extends HarnessSettings {
|
|
|
28
31
|
readonly workflows: Readonly<Record<string, WorkflowFunction | undefined>>;
|
|
29
32
|
readonly handler: WorkflowHandler;
|
|
30
33
|
readonly loadBundle?: WorkflowBundleLoader;
|
|
34
|
+
readonly reloadCommand?: readonly string[];
|
|
31
35
|
readonly command: readonly string[];
|
|
32
36
|
readonly ticketCommand?: readonly string[];
|
|
33
37
|
readonly nextCommand?: readonly string[];
|
|
@@ -35,8 +39,11 @@ export interface DaemonSettings extends HarnessSettings {
|
|
|
35
39
|
readonly notifyMilliseconds?: number;
|
|
36
40
|
readonly queueMilliseconds?: number;
|
|
37
41
|
readonly scheduleClock?: () => number;
|
|
42
|
+
readonly retention?: RetentionSettings;
|
|
43
|
+
readonly retentionClock?: () => number;
|
|
38
44
|
readonly schedules?: unknown;
|
|
39
45
|
readonly queueLanes?: number;
|
|
46
|
+
readonly queueDailySpendLimitUsd?: number;
|
|
40
47
|
readonly resetQueue?: boolean;
|
|
41
48
|
readonly githubCommand?: readonly string[];
|
|
42
49
|
readonly requiredChecks?: readonly string[] | null;
|
|
@@ -46,6 +53,7 @@ export interface DaemonSettings extends HarnessSettings {
|
|
|
46
53
|
}
|
|
47
54
|
export interface Adapters {
|
|
48
55
|
readonly worker: ClaudeWorker;
|
|
56
|
+
readonly turnSettings: TurnSettingsSource;
|
|
49
57
|
readonly github: GithubWorker;
|
|
50
58
|
readonly runs: StartDelivery;
|
|
51
59
|
readonly handoff: EffectDelivery;
|
|
@@ -56,3 +64,4 @@ export declare function adapters(settings: DaemonSettings, options: {
|
|
|
56
64
|
readonly generations: ReturnType<typeof workflowGenerations>;
|
|
57
65
|
}): Adapters;
|
|
58
66
|
export declare function recoverCommands(commands: CommandWorker, ports: HostPorts): Promise<void>;
|
|
67
|
+
export declare function recoverClaude(worker: Pick<ClaudeWorker, "harness" | "recover">, ports: Pick<HostPorts, "state" | "operations">): Promise<void>;
|
|
@@ -6,11 +6,14 @@ import { claudeWorker } from "./claude-worker.js";
|
|
|
6
6
|
import { githubWorker } from "./github-worker.js";
|
|
7
7
|
import { commandWorker } from "./command-worker.js";
|
|
8
8
|
import { handoffWorker } from "./handoff-worker.js";
|
|
9
|
+
import { resumableHarness } from "./claude-recovery.js";
|
|
10
|
+
import { turnSettingsSource, } from "./settings-reload.js";
|
|
9
11
|
function githubOf(settings, given) {
|
|
10
12
|
const { directory, repository, checkCommand } = settings;
|
|
11
13
|
return githubWorker({
|
|
12
14
|
document: async (digest) => (await given).document(digest),
|
|
13
15
|
report: async (effect) => (await given).reportEffect(effect),
|
|
16
|
+
observe: async (observation) => (await given).submit({ kind: "report-observation", ...observation }),
|
|
14
17
|
operationStatus: async (operationId) => (await (await given).operation(operationId))?.status,
|
|
15
18
|
runStatus: async (runId) => (await (await given).state()).runs[runId]?.status,
|
|
16
19
|
repository,
|
|
@@ -40,11 +43,14 @@ export function adapters(settings, options) {
|
|
|
40
43
|
const { given, generations } = options;
|
|
41
44
|
const document = async (digest) => (await given).document(digest);
|
|
42
45
|
const report = async (effect) => (await given).reportEffect(effect);
|
|
43
|
-
const
|
|
46
|
+
const turnSettings = turnSettingsSource({
|
|
47
|
+
profiles: settings.profiles ?? {},
|
|
44
48
|
fallbackModels: settings.fallbackModels ?? [],
|
|
45
49
|
tokenPrices: settings.tokenPrices ?? {},
|
|
50
|
+
});
|
|
51
|
+
const worker = claudeWorker({
|
|
46
52
|
...workerHarness(settings),
|
|
47
|
-
|
|
53
|
+
turnSettings: turnSettings.current,
|
|
48
54
|
workflowId: async (runId) => (await given).workflow.id(runId),
|
|
49
55
|
repository,
|
|
50
56
|
document,
|
|
@@ -70,7 +76,7 @@ export function adapters(settings, options) {
|
|
|
70
76
|
document,
|
|
71
77
|
report,
|
|
72
78
|
});
|
|
73
|
-
return { worker, github, runs, handoff, commands };
|
|
79
|
+
return { worker, github, runs, handoff, commands, turnSettings };
|
|
74
80
|
}
|
|
75
81
|
function handoffOf(settings, given) {
|
|
76
82
|
return handoffWorker({
|
|
@@ -81,11 +87,33 @@ function handoffOf(settings, given) {
|
|
|
81
87
|
});
|
|
82
88
|
}
|
|
83
89
|
export async function recoverCommands(commands, ports) {
|
|
90
|
+
await commands.recover(await recoveryCalls(ports, "command"));
|
|
91
|
+
}
|
|
92
|
+
export async function recoverClaude(worker, ports) {
|
|
93
|
+
for (const intent of await recoveryCalls(ports, "claude")) {
|
|
94
|
+
if (!resumableHarness(await worker.harness(intent.operationId)))
|
|
95
|
+
continue;
|
|
96
|
+
if (!(await stillRecoverable(ports, intent)))
|
|
97
|
+
continue;
|
|
98
|
+
await worker.recover(intent);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
async function stillRecoverable(ports, intent) {
|
|
102
|
+
const operation = (await ports.operations(intent.runId)).find((current) => current.operationId === intent.operationId);
|
|
103
|
+
const run = (await ports.state()).runs[intent.runId];
|
|
104
|
+
return (run?.status === "running" &&
|
|
105
|
+
operation !== undefined &&
|
|
106
|
+
operation.leaseGeneration === intent.leaseGeneration &&
|
|
107
|
+
["running", "recovering", "dispatch-pending"].includes(operation.status));
|
|
108
|
+
}
|
|
109
|
+
async function recoveryCalls(ports, capability) {
|
|
84
110
|
const state = await ports.state();
|
|
85
111
|
const calls = [];
|
|
86
112
|
for (const run of Object.values(state.runs)) {
|
|
113
|
+
if (capability === "claude" && run.status !== "running")
|
|
114
|
+
continue;
|
|
87
115
|
for (const operation of await ports.operations(run.runId)) {
|
|
88
|
-
if (operation.capability !==
|
|
116
|
+
if (operation.capability !== capability ||
|
|
89
117
|
operation.leaseGeneration === null ||
|
|
90
118
|
!["running", "recovering", "dispatch-pending"].includes(operation.status))
|
|
91
119
|
continue;
|
|
@@ -98,5 +126,5 @@ export async function recoverCommands(commands, ports) {
|
|
|
98
126
|
});
|
|
99
127
|
}
|
|
100
128
|
}
|
|
101
|
-
|
|
129
|
+
return calls;
|
|
102
130
|
}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
+
import type { scheduleConnection } from "./schedule-control.ts";
|
|
2
|
+
import type { queueConnection } from "./queue-control.ts";
|
|
1
3
|
import { workflowSchedules } from "./workflow-schedules.ts";
|
|
2
4
|
interface LoopSettings extends ParametersOfSchedules {
|
|
5
|
+
readonly scheduleConnection?: ReturnType<typeof scheduleConnection>;
|
|
6
|
+
readonly queueConnection?: ReturnType<typeof queueConnection>;
|
|
3
7
|
readonly notifyCommand?: readonly string[];
|
|
4
8
|
readonly notifyMilliseconds?: number;
|
|
5
9
|
readonly queueMilliseconds?: number;
|
|
6
10
|
readonly queueLanes?: number;
|
|
7
11
|
readonly resetQueue?: boolean;
|
|
8
|
-
readonly queueWorkflowId: string;
|
|
12
|
+
readonly queueWorkflowId: string | undefined;
|
|
9
13
|
}
|
|
10
14
|
type ParametersOfSchedules = Parameters<typeof workflowSchedules>[0];
|
|
11
15
|
export declare function daemonLoops(settings: LoopSettings): Promise<{
|
|
@@ -1,8 +1,25 @@
|
|
|
1
1
|
import { workflowSchedules } from "./workflow-schedules.js";
|
|
2
2
|
import { issueQueue } from "./issue-queue.js";
|
|
3
3
|
import { notifyRuns } from "./notify.js";
|
|
4
|
+
async function startedQueue(settings) {
|
|
5
|
+
if (settings.queueMilliseconds === undefined ||
|
|
6
|
+
settings.queueWorkflowId === undefined)
|
|
7
|
+
return undefined;
|
|
8
|
+
const queue = issueQueue({
|
|
9
|
+
directory: settings.directory,
|
|
10
|
+
runtimeDirectory: settings.runtimeDirectory,
|
|
11
|
+
intervalMilliseconds: settings.queueMilliseconds,
|
|
12
|
+
lanes: settings.queueLanes ?? 1,
|
|
13
|
+
resetQueue: settings.resetQueue ?? false,
|
|
14
|
+
workflowId: settings.queueWorkflowId,
|
|
15
|
+
});
|
|
16
|
+
settings.queueConnection?.connect(queue.port);
|
|
17
|
+
await queue.ready;
|
|
18
|
+
return queue;
|
|
19
|
+
}
|
|
4
20
|
export async function daemonLoops(settings) {
|
|
5
21
|
const schedules = await workflowSchedules(settings);
|
|
22
|
+
settings.scheduleConnection?.connect(schedules.request);
|
|
6
23
|
try {
|
|
7
24
|
const notifier = settings.notifyCommand === undefined
|
|
8
25
|
? undefined
|
|
@@ -14,16 +31,7 @@ export async function daemonLoops(settings) {
|
|
|
14
31
|
? {}
|
|
15
32
|
: { intervalMilliseconds: settings.notifyMilliseconds }),
|
|
16
33
|
});
|
|
17
|
-
const queue = settings
|
|
18
|
-
? undefined
|
|
19
|
-
: issueQueue({
|
|
20
|
-
directory: settings.directory,
|
|
21
|
-
runtimeDirectory: settings.runtimeDirectory,
|
|
22
|
-
intervalMilliseconds: settings.queueMilliseconds,
|
|
23
|
-
lanes: settings.queueLanes ?? 1,
|
|
24
|
-
resetQueue: settings.resetQueue ?? false,
|
|
25
|
-
workflowId: settings.queueWorkflowId,
|
|
26
|
-
});
|
|
34
|
+
const queue = await startedQueue(settings);
|
|
27
35
|
return {
|
|
28
36
|
stop: async () => {
|
|
29
37
|
await schedules.stop();
|