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
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { pullRequestTrigger, triggerKind, workflowApplies, } from "./github-ci-filters.js";
|
|
2
|
+
import { field, repositoryPath } from "./github-operation.js";
|
|
3
|
+
import { githubRead } from "./github-retry.js";
|
|
4
|
+
async function pullBase(operation) {
|
|
5
|
+
const pull = JSON.parse(await githubRead(operation, [
|
|
6
|
+
"api",
|
|
7
|
+
`${repositoryPath}/pulls/${String(operation.payload["number"])}`,
|
|
8
|
+
]));
|
|
9
|
+
if (typeof pull !== "object" || pull === null || !("base" in pull))
|
|
10
|
+
throw new Error("github-call-failed");
|
|
11
|
+
const baseData = pull.base;
|
|
12
|
+
if (typeof baseData !== "object" || baseData === null)
|
|
13
|
+
throw new Error("github-call-failed");
|
|
14
|
+
const base = field(baseData, "sha");
|
|
15
|
+
const branch = field(baseData, "ref");
|
|
16
|
+
if (typeof base !== "string" ||
|
|
17
|
+
!/^[0-9a-f]{40,64}$/.test(base) ||
|
|
18
|
+
typeof branch !== "string")
|
|
19
|
+
throw new Error("github-call-failed");
|
|
20
|
+
return { base, branch };
|
|
21
|
+
}
|
|
22
|
+
async function appliesToPull(operation, input) {
|
|
23
|
+
const { commit, trigger } = input;
|
|
24
|
+
if (trigger === false)
|
|
25
|
+
return false;
|
|
26
|
+
if (typeof trigger !== "object" || trigger === null)
|
|
27
|
+
return true;
|
|
28
|
+
if (!["paths", "paths-ignore", "branches", "branches-ignore"].some((key) => Object.hasOwn(trigger, key)))
|
|
29
|
+
return true;
|
|
30
|
+
const { base, branch } = await pullBase(operation);
|
|
31
|
+
await operation.calls.git(operation.settings.repository, [
|
|
32
|
+
"fetch",
|
|
33
|
+
"--quiet",
|
|
34
|
+
"--no-tags",
|
|
35
|
+
"origin",
|
|
36
|
+
base,
|
|
37
|
+
]);
|
|
38
|
+
const paths = await operation.calls.git(operation.settings.repository, [
|
|
39
|
+
"diff",
|
|
40
|
+
"--name-only",
|
|
41
|
+
"-z",
|
|
42
|
+
`${base}...${commit}`,
|
|
43
|
+
]);
|
|
44
|
+
return workflowApplies(trigger, {
|
|
45
|
+
branch,
|
|
46
|
+
paths: paths.split("\0").filter((path) => path !== ""),
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
export async function pullRequestWorkflows(operation, commit) {
|
|
50
|
+
const read = (parts) => operation.calls.git(operation.settings.repository, parts);
|
|
51
|
+
const paths = await read([
|
|
52
|
+
"ls-tree",
|
|
53
|
+
"-r",
|
|
54
|
+
"--name-only",
|
|
55
|
+
"-z",
|
|
56
|
+
commit,
|
|
57
|
+
"--",
|
|
58
|
+
".github/workflows",
|
|
59
|
+
]);
|
|
60
|
+
const workflows = [];
|
|
61
|
+
for (const path of paths.split("\0")) {
|
|
62
|
+
if (!/^\.github\/workflows\/[^/]+\.ya?ml$/.test(path))
|
|
63
|
+
continue;
|
|
64
|
+
const trigger = pullRequestTrigger(await read(["show", `${commit}:${path}`]));
|
|
65
|
+
if (await appliesToPull(operation, { commit, trigger }))
|
|
66
|
+
workflows.push({ path, kind: triggerKind(trigger) });
|
|
67
|
+
}
|
|
68
|
+
if (workflows.length === 0)
|
|
69
|
+
return workflows;
|
|
70
|
+
const inactive = await inactiveWorkflows(operation);
|
|
71
|
+
return workflows.filter((workflow) => !inactive.has(workflow.path));
|
|
72
|
+
}
|
|
73
|
+
function isList(value) {
|
|
74
|
+
return Array.isArray(value);
|
|
75
|
+
}
|
|
76
|
+
async function actionPages(operation, request) {
|
|
77
|
+
const pages = JSON.parse(await githubRead(operation, ["api", "--paginate", "--slurp", request.path]));
|
|
78
|
+
if (!isList(pages) || pages.length === 0)
|
|
79
|
+
throw new Error("github-call-failed");
|
|
80
|
+
return pages.flatMap((page) => {
|
|
81
|
+
if (typeof page !== "object" || page === null)
|
|
82
|
+
throw new Error("github-call-failed");
|
|
83
|
+
const items = field(page, request.key);
|
|
84
|
+
if (!isList(items))
|
|
85
|
+
throw new Error("github-call-failed");
|
|
86
|
+
return items;
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
async function inactiveWorkflows(operation) {
|
|
90
|
+
const workflows = await actionPages(operation, {
|
|
91
|
+
path: `${repositoryPath}/actions/workflows?per_page=100`,
|
|
92
|
+
key: "workflows",
|
|
93
|
+
});
|
|
94
|
+
const inactive = new Set();
|
|
95
|
+
for (const workflow of workflows) {
|
|
96
|
+
if (typeof workflow !== "object" || workflow === null)
|
|
97
|
+
throw new Error("github-call-failed");
|
|
98
|
+
const path = field(workflow, "path");
|
|
99
|
+
const state = field(workflow, "state");
|
|
100
|
+
if (typeof path !== "string" || typeof state !== "string")
|
|
101
|
+
throw new Error("github-call-failed");
|
|
102
|
+
if (state !== "active")
|
|
103
|
+
inactive.add(path);
|
|
104
|
+
}
|
|
105
|
+
return inactive;
|
|
106
|
+
}
|
|
107
|
+
function isWorkflowRun(value) {
|
|
108
|
+
if (typeof value !== "object" || value === null)
|
|
109
|
+
return false;
|
|
110
|
+
const conclusion = field(value, "conclusion");
|
|
111
|
+
return (typeof field(value, "id") === "number" &&
|
|
112
|
+
["path", "head_sha", "event", "status"].every((key) => typeof field(value, key) === "string") &&
|
|
113
|
+
(conclusion === null || typeof conclusion === "string"));
|
|
114
|
+
}
|
|
115
|
+
async function workflowRuns(operation, commit) {
|
|
116
|
+
const runs = await actionPages(operation, {
|
|
117
|
+
path: `${repositoryPath}/actions/runs?head_sha=${commit}&event=pull_request&per_page=100`,
|
|
118
|
+
key: "workflow_runs",
|
|
119
|
+
});
|
|
120
|
+
if (!runs.every(isWorkflowRun))
|
|
121
|
+
throw new Error("github-call-failed");
|
|
122
|
+
return runs;
|
|
123
|
+
}
|
|
124
|
+
export async function pendingWorkflows(operation, input) {
|
|
125
|
+
if (input.workflows.length === 0)
|
|
126
|
+
return [];
|
|
127
|
+
const paths = input.workflows.map((workflow) => workflow.path);
|
|
128
|
+
const latest = new Map();
|
|
129
|
+
for (const run of await workflowRuns(operation, input.commit)) {
|
|
130
|
+
if (run.head_sha !== input.commit || run.event !== "pull_request")
|
|
131
|
+
continue;
|
|
132
|
+
const path = paths
|
|
133
|
+
.filter((expected) => run.path === expected || run.path.startsWith(`${expected}@`))
|
|
134
|
+
.sort((left, right) => right.length - left.length)[0];
|
|
135
|
+
if (path === undefined)
|
|
136
|
+
continue;
|
|
137
|
+
if (run.id > (latest.get(path)?.id ?? -1))
|
|
138
|
+
latest.set(path, run);
|
|
139
|
+
}
|
|
140
|
+
const pending = input.workflows.filter((workflow) => {
|
|
141
|
+
const run = latest.get(workflow.path);
|
|
142
|
+
if (run === undefined)
|
|
143
|
+
return workflow.kind === "push";
|
|
144
|
+
return (run.status !== "completed" ||
|
|
145
|
+
!["success", "neutral", "skipped"].includes(run.conclusion ?? ""));
|
|
146
|
+
});
|
|
147
|
+
return pending.length === 0 ? [] : ["waiting for GitHub Actions checks"];
|
|
148
|
+
}
|
|
@@ -2,6 +2,7 @@ import { settingsEnvironment } from "../cli/project-settings.js";
|
|
|
2
2
|
import { setTimeout as delay } from "node:timers/promises";
|
|
3
3
|
import { githubText } from "./github-calls.js";
|
|
4
4
|
import { githubRead } from "./github-retry.js";
|
|
5
|
+
import { pendingWorkflows, pullRequestWorkflows, } from "./github-ci-workflows.js";
|
|
5
6
|
import { ciWait, workflowAttempt, attemptChecks, rerunCi, attemptOutput, } from "./github-ci-rerun.js";
|
|
6
7
|
import { field, githubTiming, repositoryPath, } from "./github-operation.js";
|
|
7
8
|
function isCheckRun(value) {
|
|
@@ -203,16 +204,29 @@ async function ciFailureOutput(operation, input) {
|
|
|
203
204
|
current,
|
|
204
205
|
]);
|
|
205
206
|
}
|
|
206
|
-
|
|
207
|
-
const
|
|
207
|
+
async function ciSettings(operation, commit) {
|
|
208
|
+
const timing = {
|
|
208
209
|
...githubTiming,
|
|
209
210
|
ciGraceMilliseconds: 60_000,
|
|
210
211
|
ciLimitMilliseconds: 5_400_000,
|
|
211
212
|
...operation.settings.timing,
|
|
212
213
|
};
|
|
214
|
+
const required = requiredChecks(operation);
|
|
215
|
+
const workflows = required === undefined ? await pullRequestWorkflows(operation, commit) : [];
|
|
216
|
+
return {
|
|
217
|
+
required,
|
|
218
|
+
workflows,
|
|
219
|
+
poll: timing.pollMilliseconds,
|
|
220
|
+
limit: timing.ciLimitMilliseconds,
|
|
221
|
+
grace: workflows.some((workflow) => workflow.kind === "push")
|
|
222
|
+
? Infinity
|
|
223
|
+
: timing.ciGraceMilliseconds,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
export async function waitForCi(operation, commit) {
|
|
213
227
|
const wait = await ciWait(operation, commit);
|
|
214
228
|
const started = wait.startedAt;
|
|
215
|
-
const required =
|
|
229
|
+
const { required, workflows, grace, poll, limit } = await ciSettings(operation, commit);
|
|
216
230
|
const names = new Set(required);
|
|
217
231
|
for (;;) {
|
|
218
232
|
const checks = latestRuns(await checkRuns(operation, commit), required);
|
|
@@ -232,7 +246,11 @@ export async function waitForCi(operation, commit) {
|
|
|
232
246
|
failed: retried.failures,
|
|
233
247
|
}),
|
|
234
248
|
};
|
|
235
|
-
const pending = [
|
|
249
|
+
const pending = [
|
|
250
|
+
...pendingChecks(checks, names),
|
|
251
|
+
...retried.pending,
|
|
252
|
+
...(await pendingWorkflows(operation, { commit, workflows })),
|
|
253
|
+
];
|
|
236
254
|
if (pending.length === 0 &&
|
|
237
255
|
(required !== undefined ||
|
|
238
256
|
names.size > 0 ||
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import { type Operation } from "./github-operation.ts";
|
|
2
|
+
export declare function repositoryName(reply: string): string;
|
|
3
|
+
export declare function captureDraft(operation: Operation): Promise<unknown>;
|
|
2
4
|
export declare function createIssue(operation: Operation): Promise<unknown>;
|
|
3
5
|
export declare function discard(operation: Operation): Promise<unknown>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
2
3
|
import { lstat, readFile } from "node:fs/promises";
|
|
3
4
|
import { basename, join } from "node:path";
|
|
4
5
|
import { existingTree, removeWorktree, repositoryPath, text, } from "./github-operation.js";
|
|
@@ -30,7 +31,7 @@ function issuePage(line) {
|
|
|
30
31
|
throw new Error("github-call-failed");
|
|
31
32
|
return page.map((issue) => issueOf(issue));
|
|
32
33
|
}
|
|
33
|
-
function repositoryName(reply) {
|
|
34
|
+
export function repositoryName(reply) {
|
|
34
35
|
const repository = JSON.parse(reply);
|
|
35
36
|
if (typeof repository !== "object" ||
|
|
36
37
|
repository === null ||
|
|
@@ -50,6 +51,28 @@ async function draftOf(operation) {
|
|
|
50
51
|
throw new Error("draft-not-available");
|
|
51
52
|
return readFile(path, "utf8");
|
|
52
53
|
}
|
|
54
|
+
function draftDigest(text) {
|
|
55
|
+
return "sha256:" + createHash("sha256").update(text).digest("hex");
|
|
56
|
+
}
|
|
57
|
+
export async function captureDraft(operation) {
|
|
58
|
+
const text = await draftOf(operation);
|
|
59
|
+
const capture = { text, digest: draftDigest(text) };
|
|
60
|
+
if (Buffer.byteLength(JSON.stringify(capture)) > 65_536)
|
|
61
|
+
throw new Error("draft-too-large");
|
|
62
|
+
return capture;
|
|
63
|
+
}
|
|
64
|
+
function checkDraftDigest(operation, draft) {
|
|
65
|
+
if (!Object.hasOwn(operation.payload, "expectedDigests"))
|
|
66
|
+
return;
|
|
67
|
+
const digests = operation.payload["expectedDigests"];
|
|
68
|
+
if (!Array.isArray(digests) ||
|
|
69
|
+
digests.length === 0 ||
|
|
70
|
+
!digests.every((digest) => typeof digest === "string" && /^sha256:[0-9a-f]{64}$/.test(digest)))
|
|
71
|
+
throw new Error("invalid-payload");
|
|
72
|
+
const current = draftDigest(draft);
|
|
73
|
+
if (!digests.every((digest) => digest === current))
|
|
74
|
+
throw new Error("draft-changed");
|
|
75
|
+
}
|
|
53
76
|
async function knownIssue(operation, marker) {
|
|
54
77
|
const output = await operation.calls.gh([
|
|
55
78
|
"api",
|
|
@@ -62,7 +85,10 @@ async function knownIssue(operation, marker) {
|
|
|
62
85
|
}
|
|
63
86
|
export async function createIssue(operation) {
|
|
64
87
|
operatorPrivateTexts(operation.settings);
|
|
65
|
-
const draft =
|
|
88
|
+
const draft = Object.hasOwn(operation.payload, "text")
|
|
89
|
+
? reportText(operation)
|
|
90
|
+
: await draftOf(operation);
|
|
91
|
+
checkDraftDigest(operation, draft);
|
|
66
92
|
const [heading = "", ...lines] = draft.split("\n");
|
|
67
93
|
if (!heading.startsWith("# ") || heading.slice(2).trim() === "")
|
|
68
94
|
throw new Error("invalid-draft");
|
|
@@ -89,6 +115,15 @@ export async function createIssue(operation) {
|
|
|
89
115
|
const url = printed.trim().split("\n").at(-1) ?? "";
|
|
90
116
|
return issueFromUrl(url);
|
|
91
117
|
}
|
|
118
|
+
function reportText(operation) {
|
|
119
|
+
if (Object.hasOwn(operation.payload, "draft") ||
|
|
120
|
+
Object.hasOwn(operation.payload, "expectedDigests"))
|
|
121
|
+
throw new Error("invalid-payload");
|
|
122
|
+
const report = text(operation, "text");
|
|
123
|
+
if (Buffer.byteLength(report) > 65536)
|
|
124
|
+
throw new Error("draft-too-large");
|
|
125
|
+
return report;
|
|
126
|
+
}
|
|
92
127
|
export async function discard(operation) {
|
|
93
128
|
const place = treePlace({
|
|
94
129
|
worktrees: operation.settings.worktrees,
|
|
@@ -9,8 +9,9 @@ export declare function knownMerge(operation: Operation, expected: ReviewedPull
|
|
|
9
9
|
readonly updated: string;
|
|
10
10
|
}): Promise<{
|
|
11
11
|
readonly head: string;
|
|
12
|
+
readonly open: boolean;
|
|
12
13
|
readonly merged: string | undefined;
|
|
13
14
|
}>;
|
|
14
15
|
export declare function mergePull(operation: Operation, pull: ReviewedPull & {
|
|
15
16
|
readonly updated: string;
|
|
16
|
-
}): Promise<string>;
|
|
17
|
+
}): Promise<string | Error>;
|
|
@@ -15,11 +15,12 @@ export async function knownMerge(operation, expected) {
|
|
|
15
15
|
`${repositoryPath}/pulls/${String(expected.number)}`,
|
|
16
16
|
]));
|
|
17
17
|
const head = commitOf(field(pull, "head"), "sha");
|
|
18
|
+
const open = field(pull, "state") === "open";
|
|
18
19
|
if (field(pull, "merged") !== true)
|
|
19
|
-
return { head, merged: undefined };
|
|
20
|
+
return { head, open, merged: undefined };
|
|
20
21
|
if (head !== expected.commit && head !== expected.updated)
|
|
21
22
|
throw new Error("merged-other-commit");
|
|
22
|
-
return { head, merged: commitOf(pull, "merge_commit_sha") };
|
|
23
|
+
return { head, open, merged: commitOf(pull, "merge_commit_sha") };
|
|
23
24
|
}
|
|
24
25
|
async function mergedNow(operation, pull) {
|
|
25
26
|
const reply = JSON.parse(await operation.calls.gh([
|
|
@@ -63,11 +64,17 @@ export function mergePull(operation, pull) {
|
|
|
63
64
|
},
|
|
64
65
|
statuses: pull.updated === pull.commit ? [] : [405, 409],
|
|
65
66
|
}).catch(async (error) => {
|
|
66
|
-
if (!(error instanceof Error)
|
|
67
|
+
if (!(error instanceof Error))
|
|
68
|
+
throw error;
|
|
69
|
+
const refused = error.message === "github-call-failed" &&
|
|
70
|
+
[405, 409].includes(Number(field(error, "status")));
|
|
71
|
+
if (error.message !== "github-network-failed" && !refused)
|
|
67
72
|
throw error;
|
|
68
73
|
const known = await knownMerge(operation, pull);
|
|
69
74
|
if (known.merged !== undefined)
|
|
70
75
|
return known.merged;
|
|
76
|
+
if (refused && known.open)
|
|
77
|
+
return error;
|
|
71
78
|
throw error;
|
|
72
79
|
});
|
|
73
80
|
}
|
|
@@ -136,35 +136,64 @@ async function readyHead(operation, pull) {
|
|
|
136
136
|
let recorded = pull.recorded;
|
|
137
137
|
let remote = pull.remote;
|
|
138
138
|
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
139
|
-
const updated = await
|
|
139
|
+
const updated = await pushedHead(operation, {
|
|
140
|
+
...pull,
|
|
140
141
|
tree,
|
|
141
|
-
commit: pull.commit,
|
|
142
142
|
recorded,
|
|
143
|
-
|
|
143
|
+
remote,
|
|
144
144
|
});
|
|
145
|
-
if (updated !== pull.commit && recorded !== updated)
|
|
146
|
-
await writeRecord(operation.folder, {
|
|
147
|
-
name: "updated-head.json",
|
|
148
|
-
value: { commit: pull.commit, updated },
|
|
149
|
-
});
|
|
150
|
-
if (updated !== pull.commit && remote !== updated)
|
|
151
|
-
await operation.calls.git(tree.path, [
|
|
152
|
-
"push",
|
|
153
|
-
"--quiet",
|
|
154
|
-
"origin",
|
|
155
|
-
`${updated}:refs/heads/${tree.branch}`,
|
|
156
|
-
]);
|
|
157
145
|
const ci = await waitForCi(operation, updated);
|
|
158
146
|
if (ci !== undefined)
|
|
159
147
|
return ci;
|
|
160
|
-
const newest = await fetched(operation, await defaultBranch(operation));
|
|
161
|
-
if ((await operation.calls.git(tree.path, ["merge-base", updated, newest])).trim() === newest)
|
|
162
|
-
return updated;
|
|
163
148
|
recorded = updated;
|
|
164
149
|
remote = updated;
|
|
150
|
+
if (!(await containsBase(operation, updated)))
|
|
151
|
+
continue;
|
|
152
|
+
const merged = await mergePull(operation, { ...pull, updated });
|
|
153
|
+
if (typeof merged === "string")
|
|
154
|
+
return { updated, merged };
|
|
155
|
+
if (await containsBase(operation, updated))
|
|
156
|
+
throw merged;
|
|
157
|
+
await recordRefusal(operation, { error: merged, updated, attempt });
|
|
165
158
|
}
|
|
166
159
|
throw new Error("base-moved");
|
|
167
160
|
}
|
|
161
|
+
async function recordRefusal(operation, refusal) {
|
|
162
|
+
const observation = await operation.observe?.({
|
|
163
|
+
condition: "working",
|
|
164
|
+
reason: "github-merge-refused",
|
|
165
|
+
evidence: `github-merge/HTTP-${String(field(refusal.error, "status"))}/head-${refusal.updated}/merge-main`,
|
|
166
|
+
attempt: refusal.attempt + 1,
|
|
167
|
+
limit: 3,
|
|
168
|
+
});
|
|
169
|
+
if (observation !== undefined &&
|
|
170
|
+
!["accepted", "duplicate"].includes(observation.kind))
|
|
171
|
+
throw new Error("github-call-failed");
|
|
172
|
+
}
|
|
173
|
+
async function pushedHead(operation, pull) {
|
|
174
|
+
const updated = await refreshed(operation, pull);
|
|
175
|
+
if (updated !== pull.commit && pull.recorded !== updated)
|
|
176
|
+
await writeRecord(operation.folder, {
|
|
177
|
+
name: "updated-head.json",
|
|
178
|
+
value: { commit: pull.commit, updated },
|
|
179
|
+
});
|
|
180
|
+
if (updated !== pull.commit && pull.remote !== updated)
|
|
181
|
+
await operation.calls.git(pull.tree.path, [
|
|
182
|
+
"push",
|
|
183
|
+
"--quiet",
|
|
184
|
+
"origin",
|
|
185
|
+
`${updated}:refs/heads/${pull.tree.branch}`,
|
|
186
|
+
]);
|
|
187
|
+
return updated;
|
|
188
|
+
}
|
|
189
|
+
async function containsBase(operation, updated) {
|
|
190
|
+
const newest = await fetched(operation, await defaultBranch(operation));
|
|
191
|
+
return ((await operation.calls.git(existingTree(operation).path, [
|
|
192
|
+
"merge-base",
|
|
193
|
+
updated,
|
|
194
|
+
newest,
|
|
195
|
+
])).trim() === newest);
|
|
196
|
+
}
|
|
168
197
|
function checkOutput(cause) {
|
|
169
198
|
return commandOutput(cause).slice(-6_000);
|
|
170
199
|
}
|
|
@@ -209,12 +238,11 @@ async function completedMerge(operation, pull) {
|
|
|
209
238
|
...pull,
|
|
210
239
|
updated: recorded ?? pull.commit,
|
|
211
240
|
});
|
|
212
|
-
const
|
|
241
|
+
const result = known.merged === undefined
|
|
213
242
|
? await readyHead(operation, { ...pull, recorded, remote: known.head })
|
|
214
|
-
:
|
|
215
|
-
if (
|
|
216
|
-
return
|
|
217
|
-
const merged = known.merged ?? (await mergePull(operation, { ...pull, updated }));
|
|
243
|
+
: { updated: recorded ?? pull.commit, merged: known.merged };
|
|
244
|
+
if ("reason" in result)
|
|
245
|
+
return result;
|
|
218
246
|
await removed(operation, place);
|
|
219
|
-
return { number: pull.number, commit: pull.commit,
|
|
247
|
+
return { number: pull.number, commit: pull.commit, ...result };
|
|
220
248
|
}
|
|
@@ -2,15 +2,21 @@ import { setTimeout as delay } from "node:timers/promises";
|
|
|
2
2
|
import { appendFile } from "node:fs/promises";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { findingsOf, scoreOf, } from "./github-calls.js";
|
|
5
|
+
import { attachAsset } from "./github-attach.js";
|
|
5
6
|
import { closeIssue, partialIssue } from "./github-ticket-status.js";
|
|
6
7
|
import { merge } from "./github-merge.js";
|
|
7
|
-
import {
|
|
8
|
+
import { inMergeTurn } from "./merge-turns.js";
|
|
9
|
+
import { captureDraft, createIssue, discard, repositoryName, } from "./github-issue-methods.js";
|
|
8
10
|
import { existingTree, defaultBranch, changeChecked, field, githubTiming, repositoryPath, text, } from "./github-operation.js";
|
|
9
11
|
import { workTree } from "./work-tree.js";
|
|
10
12
|
const triggerText = "@greptileai";
|
|
11
13
|
const maximumReviewRequests = 3;
|
|
12
14
|
export const methodReasons = new Set([
|
|
15
|
+
"attachment-not-available",
|
|
16
|
+
"attachment-too-large",
|
|
13
17
|
"draft-not-available",
|
|
18
|
+
"draft-changed",
|
|
19
|
+
"draft-too-large",
|
|
14
20
|
"invalid-draft",
|
|
15
21
|
"post-uncertain",
|
|
16
22
|
"private-texts-not-set",
|
|
@@ -77,7 +83,10 @@ function labels(operation, name) {
|
|
|
77
83
|
});
|
|
78
84
|
}
|
|
79
85
|
async function label(operation) {
|
|
80
|
-
const repository =
|
|
86
|
+
const repository = !Object.hasOwn(operation.payload, "owner") &&
|
|
87
|
+
!Object.hasOwn(operation.payload, "repository")
|
|
88
|
+
? repositoryName(await operation.calls.gh(["repo", "view", "--json", "nameWithOwner"]))
|
|
89
|
+
: `${text(operation, "owner")}/${text(operation, "repository")}`;
|
|
81
90
|
const number = integer(operation, "number");
|
|
82
91
|
if (!/^[\w.-]+\/[\w.-]+$/.test(repository) || !Number.isSafeInteger(number))
|
|
83
92
|
throw new Error("invalid-payload");
|
|
@@ -262,15 +271,20 @@ export const methods = new Map([
|
|
|
262
271
|
["partial-issue", partialIssue],
|
|
263
272
|
["label", label],
|
|
264
273
|
["create-issue", createIssue],
|
|
274
|
+
["capture-draft", captureDraft],
|
|
265
275
|
["discard", discard],
|
|
266
276
|
["open-pr", openPull],
|
|
277
|
+
["attach-asset", attachAsset],
|
|
267
278
|
["wait-review", waitReview],
|
|
268
279
|
[
|
|
269
280
|
"merge",
|
|
270
|
-
(operation) =>
|
|
281
|
+
(operation) => inMergeTurn({
|
|
282
|
+
repository: operation.settings.repository,
|
|
283
|
+
signal: operation.signal,
|
|
284
|
+
}, () => merge(operation, {
|
|
271
285
|
number: integer(operation, "number"),
|
|
272
286
|
commit: text(operation, "commit"),
|
|
273
287
|
check: mergeCheck(operation),
|
|
274
|
-
}),
|
|
288
|
+
})),
|
|
275
289
|
],
|
|
276
290
|
]);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CallSettings, Calls } from "./github-calls.ts";
|
|
2
|
+
import type { ObservationReport } from "../service/worker-port.ts";
|
|
2
3
|
export interface GithubTiming {
|
|
3
4
|
readonly pollMilliseconds: number;
|
|
4
5
|
readonly triggerMilliseconds: number;
|
|
@@ -20,6 +21,9 @@ export interface Operation {
|
|
|
20
21
|
readonly payload: Readonly<Record<string, unknown>>;
|
|
21
22
|
readonly signal: AbortSignal;
|
|
22
23
|
readonly folder: string;
|
|
24
|
+
readonly observe?: (report: Pick<ObservationReport, "condition" | "reason" | "evidence" | "attempt" | "limit">) => Promise<{
|
|
25
|
+
readonly kind: string;
|
|
26
|
+
} | undefined>;
|
|
23
27
|
}
|
|
24
28
|
export interface Place {
|
|
25
29
|
readonly path: string;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { homedir } from "node:os";
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
3
|
import { join } from "node:path";
|
|
4
|
+
import { rm } from "node:fs/promises";
|
|
5
|
+
import { attachmentFolder } from "./attachments.js";
|
|
4
6
|
import { treePlace } from "./work-tree.js";
|
|
5
7
|
export const githubTiming = {
|
|
6
8
|
pollMilliseconds: 30_000,
|
|
@@ -32,6 +34,10 @@ export async function removeWorktree(operation, place) {
|
|
|
32
34
|
await repository(["worktree", "remove", "--force", place.path]);
|
|
33
35
|
if ((await repository(["branch", "--list", place.branch])).trim() !== "")
|
|
34
36
|
await repository(["branch", "-D", place.branch]);
|
|
37
|
+
await rm(attachmentFolder({
|
|
38
|
+
worktrees: operation.settings.worktrees,
|
|
39
|
+
target: operation.target,
|
|
40
|
+
}), { recursive: true, force: true });
|
|
35
41
|
}
|
|
36
42
|
export async function defaultBranch(operation) {
|
|
37
43
|
const reference = await operation.calls.git(operation.settings.repository, [
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Delivery } from "../broker/actor/delivery-intents.ts";
|
|
2
|
+
import type { ObservationReport } from "../service/worker-port.ts";
|
|
2
3
|
import { type MethodSettings } from "./github-methods.ts";
|
|
3
4
|
import { type WorkerReport } from "./operation-journal.ts";
|
|
4
5
|
export type { GithubTiming } from "./github-methods.ts";
|
|
@@ -6,6 +7,9 @@ export interface GithubWorkerSettings extends MethodSettings {
|
|
|
6
7
|
readonly journal: string;
|
|
7
8
|
readonly document: (digest: string) => Promise<string | undefined>;
|
|
8
9
|
readonly report: (report: WorkerReport) => Promise<unknown>;
|
|
10
|
+
readonly observe?: (report: ObservationReport) => Promise<{
|
|
11
|
+
readonly kind: string;
|
|
12
|
+
}>;
|
|
9
13
|
readonly operationStatus: (operationId: string) => Promise<string | undefined>;
|
|
10
14
|
readonly runStatus: (runId: string) => Promise<string | undefined>;
|
|
11
15
|
}
|
|
@@ -47,6 +47,12 @@ async function outcome(parts, run) {
|
|
|
47
47
|
target: intent.target,
|
|
48
48
|
payload,
|
|
49
49
|
signal,
|
|
50
|
+
observe: async (observation) => settings.observe?.({
|
|
51
|
+
...observation,
|
|
52
|
+
runId: intent.runId,
|
|
53
|
+
operationId: intent.operationId,
|
|
54
|
+
commandId: `github:${run.key}:merge-refused:${String(observation.attempt)}`,
|
|
55
|
+
}),
|
|
50
56
|
});
|
|
51
57
|
return {
|
|
52
58
|
outcome: "completed",
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
import { type QueuePort } from "../queue-state.ts";
|
|
1
2
|
interface QueueSettings {
|
|
2
3
|
readonly directory: string;
|
|
3
4
|
readonly runtimeDirectory: string;
|
|
4
5
|
readonly intervalMilliseconds: number;
|
|
5
6
|
readonly lanes?: number;
|
|
6
7
|
readonly resetQueue?: boolean;
|
|
7
|
-
readonly workflowId
|
|
8
|
+
readonly workflowId: string;
|
|
8
9
|
}
|
|
9
10
|
export declare function issueQueue(settings: QueueSettings): {
|
|
10
11
|
readonly stop: () => Promise<void>;
|
|
12
|
+
readonly port: QueuePort;
|
|
13
|
+
readonly ready: Promise<void>;
|
|
11
14
|
};
|
|
12
15
|
export {};
|