cloving 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +525 -185
- package/dist/src/agent-harness-shell.d.ts +12 -0
- package/dist/src/agent-harness-shell.js +90 -0
- package/dist/src/agent-harness-versions.d.ts +8 -0
- package/dist/src/agent-harness-versions.js +49 -0
- package/dist/src/agent-harnesses.d.ts +4 -0
- package/dist/src/agent-harnesses.js +13 -0
- package/dist/src/authority/commands.d.ts +1 -0
- package/dist/src/authority/commands.js +24 -4
- package/dist/src/authority/gate-reduction.d.ts +1 -0
- package/dist/src/authority/gate-reduction.js +18 -3
- package/dist/src/authority/gates.d.ts +2 -1
- package/dist/src/authority/gates.js +5 -1
- package/dist/src/authority/operations.js +1 -1
- package/dist/src/authority/reduction.d.ts +1 -1
- package/dist/src/authority/reduction.js +6 -1
- package/dist/src/authority/status-input.d.ts +1 -1
- package/dist/src/authority/status.d.ts +1 -0
- package/dist/src/authority/status.js +27 -3
- package/dist/src/authority/transitions.d.ts +5 -5
- package/dist/src/authority/transitions.js +6 -0
- package/dist/src/broker/actor/authority-delivery.js +1 -0
- package/dist/src/broker/actor/authority-queries.d.ts +7 -1
- package/dist/src/broker/actor/authority-queries.js +17 -2
- package/dist/src/broker/actor/authority-receipts.js +11 -1
- package/dist/src/broker/actor/authority-session.js +2 -2
- package/dist/src/broker/actor/authority-settings.js +4 -0
- package/dist/src/broker/actor/delivery-intents.d.ts +2 -1
- package/dist/src/broker/actor/delivery-intents.js +4 -4
- package/dist/src/broker/actor/effect-delivery.js +4 -1
- package/dist/src/broker/actor/effect-queries.d.ts +1 -0
- package/dist/src/broker/actor/effect-queries.js +7 -0
- package/dist/src/broker/actor/pin-check.js +1 -1
- package/dist/src/broker/actor/stop-plan.js +1 -1
- package/dist/src/broker/actor/turn-state.js +1 -1
- package/dist/src/broker/authority-admission.js +22 -9
- package/dist/src/broker/authority-restore.js +1 -0
- package/dist/src/broker/decision-restore.js +4 -4
- package/dist/src/broker/socket-address.d.ts +3 -1
- package/dist/src/broker/socket-address.js +2 -2
- package/dist/src/cli/arguments.d.ts +11 -13
- package/dist/src/cli/arguments.js +37 -107
- package/dist/src/cli/command-effects.d.ts +7 -0
- package/dist/src/cli/command-effects.js +39 -0
- package/dist/src/cli/commands.js +11 -4
- package/dist/src/cli/config-arguments.d.ts +11 -0
- package/dist/src/cli/config-arguments.js +59 -0
- package/dist/src/cli/config-command.d.ts +2 -0
- package/dist/src/cli/config-command.js +105 -0
- package/dist/src/cli/config-file.d.ts +3 -0
- package/dist/src/cli/config-file.js +50 -0
- package/dist/src/cli/config-lock.d.ts +7 -0
- package/dist/src/cli/config-lock.js +61 -0
- package/dist/src/cli/config-notice.d.ts +5 -0
- package/dist/src/cli/config-notice.js +46 -0
- package/dist/src/cli/doctor-github.d.ts +9 -0
- package/dist/src/cli/doctor-github.js +138 -0
- package/dist/src/cli/doctor-harness.d.ts +13 -0
- package/dist/src/cli/doctor-harness.js +242 -0
- package/dist/src/cli/doctor-local.d.ts +18 -0
- package/dist/src/cli/doctor-local.js +77 -0
- package/dist/src/cli/doctor-runtime.d.ts +15 -0
- package/dist/src/cli/doctor-runtime.js +176 -0
- package/dist/src/cli/doctor-service.d.ts +1 -0
- package/dist/src/cli/doctor-service.js +11 -0
- package/dist/src/cli/doctor-workflows.d.ts +3 -0
- package/dist/src/cli/doctor-workflows.js +45 -0
- package/dist/src/cli/doctor.d.ts +15 -0
- package/dist/src/cli/doctor.js +190 -0
- package/dist/src/cli/github-ci-progress.d.ts +8 -0
- package/dist/src/cli/github-ci-progress.js +83 -0
- package/dist/src/cli/github-retry.d.ts +6 -0
- package/dist/src/cli/github-retry.js +47 -0
- package/dist/src/cli/harness-probes.d.ts +22 -0
- package/dist/src/cli/harness-probes.js +183 -0
- package/dist/src/cli/main.d.ts +7 -1
- package/dist/src/cli/main.js +39 -61
- package/dist/src/cli/phone-arguments.d.ts +14 -0
- package/dist/src/cli/phone-arguments.js +37 -0
- package/dist/src/cli/phone-client.d.ts +2 -0
- package/dist/src/cli/phone-client.js +32 -0
- package/dist/src/cli/phone-command.d.ts +13 -0
- package/dist/src/cli/phone-command.js +101 -0
- package/dist/src/cli/probe-command.d.ts +36 -0
- package/dist/src/cli/probe-command.js +59 -0
- package/dist/src/cli/project-settings.d.ts +4 -0
- package/dist/src/cli/project-settings.js +33 -0
- package/dist/src/cli/render.d.ts +2 -1
- package/dist/src/cli/render.js +44 -28
- package/dist/src/cli/report-github.d.ts +18 -0
- package/dist/src/cli/report-github.js +200 -0
- package/dist/src/cli/report.d.ts +17 -0
- package/dist/src/cli/report.js +192 -0
- package/dist/src/cli/repository-arguments.d.ts +5 -0
- package/dist/src/cli/repository-arguments.js +34 -0
- package/dist/src/cli/runtime-arguments.d.ts +4 -0
- package/dist/src/cli/runtime-arguments.js +15 -0
- package/dist/src/cli/runtime-directory.d.ts +6 -2
- package/dist/src/cli/runtime-directory.js +72 -14
- package/dist/src/cli/toolchain.d.ts +2 -0
- package/dist/src/cli/toolchain.js +22 -2
- package/dist/src/cli/usage-render.d.ts +5 -0
- package/dist/src/cli/usage-render.js +40 -1
- package/dist/src/cli/usage.d.ts +3 -3
- package/dist/src/cli/usage.js +70 -44
- package/dist/src/cli/watch-actions.d.ts +2 -0
- package/dist/src/cli/watch-actions.js +4 -4
- package/dist/src/cli/watch-board-view.d.ts +1 -1
- package/dist/src/cli/watch-board-view.js +8 -2
- package/dist/src/cli/watch-board.js +23 -10
- package/dist/src/cli/watch-card-forms.js +2 -2
- package/dist/src/cli/watch-client.d.ts +1 -1
- package/dist/src/cli/watch-client.js +7 -2
- package/dist/src/cli/watch-header-view.d.ts +27 -0
- package/dist/src/cli/watch-header-view.js +116 -0
- package/dist/src/cli/watch-model.js +17 -4
- package/dist/src/cli/watch-page.js +48 -12
- package/dist/src/cli/watch-phone-client.d.ts +1 -0
- package/dist/src/cli/watch-phone-client.js +84 -0
- package/dist/src/cli/watch-phone-view.d.ts +56 -0
- package/dist/src/cli/watch-phone-view.js +113 -0
- package/dist/src/cli/watch-phone.d.ts +5 -0
- package/dist/src/cli/watch-phone.js +53 -0
- package/dist/src/cli/watch-pull-request.d.ts +3 -1
- package/dist/src/cli/watch-pull-request.js +4 -0
- package/dist/src/cli/watch-render.d.ts +9 -1
- package/dist/src/cli/watch-server.js +23 -5
- package/dist/src/cli/watch-turn.d.ts +4 -1
- package/dist/src/cli/watch-turn.js +37 -1
- package/dist/src/cli/watch-usage.js +5 -1
- package/dist/src/cli/watch-view.d.ts +6 -20
- package/dist/src/cli/watch-view.js +14 -106
- package/dist/src/cli.js +106 -23
- package/dist/src/command-settings.d.ts +16 -0
- package/dist/src/command-settings.js +42 -0
- package/dist/src/configuration-change.d.ts +11 -0
- package/dist/src/configuration-change.js +62 -0
- package/dist/src/configuration-display.d.ts +21 -0
- package/dist/src/configuration-display.js +69 -0
- package/dist/src/configuration-schema.d.ts +49 -0
- package/dist/src/configuration-schema.js +159 -0
- package/dist/src/daemon/claude-turn.d.ts +19 -5
- package/dist/src/daemon/claude-turn.js +116 -53
- package/dist/src/daemon/claude-worker.d.ts +3 -3
- package/dist/src/daemon/claude-worker.js +65 -76
- package/dist/src/daemon/command-journal.d.ts +5 -0
- package/dist/src/daemon/command-journal.js +50 -0
- package/dist/src/daemon/command-process.d.ts +28 -0
- package/dist/src/daemon/command-process.js +164 -0
- package/dist/src/daemon/command-worker.d.ts +19 -0
- package/dist/src/daemon/command-worker.js +182 -0
- package/dist/src/daemon/cursor-stream.d.ts +4 -0
- package/dist/src/daemon/cursor-stream.js +154 -0
- package/dist/src/daemon/daemon-adapters.d.ts +58 -0
- package/dist/src/daemon/daemon-adapters.js +102 -0
- package/dist/src/daemon/daemon-loops.d.ts +14 -0
- package/dist/src/daemon/daemon-loops.js +39 -0
- package/dist/src/daemon/daemon.d.ts +2 -33
- package/dist/src/daemon/daemon.js +126 -132
- package/dist/src/daemon/declared-input.d.ts +3 -0
- package/dist/src/daemon/declared-input.js +9 -0
- package/dist/src/daemon/delivery-router.js +1 -1
- package/dist/src/daemon/gemini-stream.d.ts +4 -0
- package/dist/src/daemon/gemini-stream.js +129 -0
- package/dist/src/daemon/github-ci-rerun.d.ts +26 -0
- package/dist/src/daemon/github-ci-rerun.js +92 -0
- package/dist/src/daemon/github-ci.js +89 -8
- package/dist/src/daemon/github-merge-call.d.ts +2 -0
- package/dist/src/daemon/github-merge.js +7 -3
- package/dist/src/daemon/github-methods.js +10 -0
- package/dist/src/daemon/github-operation.d.ts +1 -0
- package/dist/src/daemon/github-retry.js +8 -44
- package/dist/src/daemon/issue-queue.d.ts +1 -0
- package/dist/src/daemon/issue-queue.js +3 -26
- package/dist/src/daemon/notify.js +2 -1
- package/dist/src/daemon/opencode-stream.d.ts +5 -0
- package/dist/src/daemon/opencode-stream.js +87 -0
- package/dist/src/daemon/queue-status.d.ts +4 -0
- package/dist/src/daemon/queue-status.js +38 -0
- package/dist/src/daemon/retry-worktree.d.ts +18 -0
- package/dist/src/daemon/retry-worktree.js +139 -0
- package/dist/src/daemon/retrying-turn.d.ts +2 -0
- package/dist/src/daemon/retrying-turn.js +108 -30
- package/dist/src/daemon/schedule-journal.d.ts +19 -0
- package/dist/src/daemon/schedule-journal.js +57 -0
- package/dist/src/daemon/text-output.d.ts +18 -0
- package/dist/src/daemon/text-output.js +44 -0
- package/dist/src/daemon/ticket-registration.d.ts +5 -7
- package/dist/src/daemon/ticket-registration.js +85 -40
- package/dist/src/daemon/turn-command.d.ts +10 -0
- package/dist/src/daemon/turn-command.js +33 -0
- package/dist/src/daemon/turn-report.d.ts +18 -0
- package/dist/src/daemon/turn-report.js +79 -0
- package/dist/src/daemon/work-tree.d.ts +2 -1
- package/dist/src/daemon/work-tree.js +15 -12
- package/dist/src/daemon/workflow-generations.d.ts +32 -0
- package/dist/src/daemon/workflow-generations.js +57 -0
- package/dist/src/daemon/workflow-replay.d.ts +16 -0
- package/dist/src/daemon/workflow-replay.js +58 -0
- package/dist/src/daemon/workflow-schedules.d.ts +27 -0
- package/dist/src/daemon/workflow-schedules.js +185 -0
- package/dist/src/decision-wait.d.ts +1 -0
- package/dist/src/decision-wait.js +3 -0
- package/dist/src/delivery-backoff.d.ts +1 -0
- package/dist/src/delivery-backoff.js +3 -0
- package/dist/src/doctor-report.d.ts +24 -0
- package/dist/src/doctor-report.js +70 -0
- package/dist/src/execution-pin.d.ts +5 -0
- package/dist/src/execution-pin.js +67 -4
- package/dist/src/grok-result.d.ts +12 -0
- package/dist/src/grok-result.js +61 -0
- package/dist/src/harness-defaults.d.ts +35 -0
- package/dist/src/harness-defaults.js +121 -0
- package/dist/src/host/decision-resume.d.ts +35 -0
- package/dist/src/host/decision-resume.js +86 -0
- package/dist/src/host/gate-bridge.d.ts +48 -0
- package/dist/src/host/gate-bridge.js +124 -0
- package/dist/src/host/run-wait.d.ts +26 -0
- package/dist/src/host/run-wait.js +37 -0
- package/dist/src/host/start-delivery.d.ts +1 -1
- package/dist/src/host/start-delivery.js +10 -3
- package/dist/src/host/step-bridge-host.d.ts +6 -20
- package/dist/src/host/step-bridge-host.js +44 -58
- package/dist/src/merge-request.d.ts +19 -0
- package/dist/src/merge-request.js +32 -0
- package/dist/src/phone/canonical-json.d.ts +1 -0
- package/dist/src/phone/canonical-json.js +16 -0
- package/dist/src/phone/phone-link.d.ts +7 -0
- package/dist/src/phone/phone-link.js +21 -0
- package/dist/src/phone/qr-data.d.ts +8 -0
- package/dist/src/phone/qr-data.js +133 -0
- package/dist/src/phone/qr-matrix.d.ts +6 -0
- package/dist/src/phone/qr-matrix.js +175 -0
- package/dist/src/phone/qr-penalty.d.ts +3 -0
- package/dist/src/phone/qr-penalty.js +67 -0
- package/dist/src/phone/qr-picture.d.ts +5 -0
- package/dist/src/phone/qr-picture.js +24 -0
- package/dist/src/private-config.schema.json +263 -0
- package/dist/src/project-config.schema.json +65 -0
- package/dist/src/project-settings.d.ts +19 -0
- package/dist/src/project-settings.js +131 -0
- package/dist/src/relay/answer-check.d.ts +24 -0
- package/dist/src/relay/answer-check.js +145 -0
- package/dist/src/relay/answer-inbox.d.ts +15 -0
- package/dist/src/relay/answer-inbox.js +173 -0
- package/dist/src/relay/daemon-keys.d.ts +16 -0
- package/dist/src/relay/daemon-keys.js +75 -0
- package/dist/src/relay/decision-check.d.ts +3 -0
- package/dist/src/relay/decision-check.js +77 -0
- package/dist/src/relay/decision-close.d.ts +6 -0
- package/dist/src/relay/decision-close.js +72 -0
- package/dist/src/relay/decision-envelopes.d.ts +29 -0
- package/dist/src/relay/decision-envelopes.js +93 -0
- package/dist/src/relay/decision-watch.d.ts +14 -0
- package/dist/src/relay/decision-watch.js +68 -0
- package/dist/src/relay/envelope-post.d.ts +8 -0
- package/dist/src/relay/envelope-post.js +71 -0
- package/dist/src/relay/envelope.d.ts +28 -0
- package/dist/src/relay/envelope.js +53 -0
- package/dist/src/relay/hpke.d.ts +25 -0
- package/dist/src/relay/hpke.js +108 -0
- package/dist/src/relay/pairing-checks.d.ts +42 -0
- package/dist/src/relay/pairing-checks.js +172 -0
- package/dist/src/relay/pairing-follow.d.ts +8 -0
- package/dist/src/relay/pairing-follow.js +95 -0
- package/dist/src/relay/pairing-session.d.ts +29 -0
- package/dist/src/relay/pairing-session.js +87 -0
- package/dist/src/relay/phone-delivery.d.ts +51 -0
- package/dist/src/relay/phone-delivery.js +139 -0
- package/dist/src/relay/phone-devices.d.ts +36 -0
- package/dist/src/relay/phone-devices.js +46 -0
- package/dist/src/relay/phone-inbox.d.ts +18 -0
- package/dist/src/relay/phone-inbox.js +17 -0
- package/dist/src/relay/phone-operations.d.ts +18 -0
- package/dist/src/relay/phone-operations.js +121 -0
- package/dist/src/relay/phone-outbox.d.ts +21 -0
- package/dist/src/relay/phone-outbox.js +25 -0
- package/dist/src/relay/phone-socket.d.ts +6 -0
- package/dist/src/relay/phone-socket.js +63 -0
- package/dist/src/relay/relay-control.d.ts +7 -0
- package/dist/src/relay/relay-control.js +24 -0
- package/dist/src/relay/relay-files.d.ts +2 -0
- package/dist/src/relay/relay-files.js +23 -0
- package/dist/src/relay/relay-heartbeat.d.ts +17 -0
- package/dist/src/relay/relay-heartbeat.js +81 -0
- package/dist/src/relay/relay-http.d.ts +14 -0
- package/dist/src/relay/relay-http.js +63 -0
- package/dist/src/relay/relay-registration.d.ts +15 -0
- package/dist/src/relay/relay-registration.js +63 -0
- package/dist/src/relay/relay-service.d.ts +25 -0
- package/dist/src/relay/relay-service.js +216 -0
- package/dist/src/relay/relay-store.d.ts +48 -0
- package/dist/src/relay/relay-store.js +131 -0
- package/dist/src/relay/sealed-post.d.ts +25 -0
- package/dist/src/relay/sealed-post.js +52 -0
- package/dist/src/relay.d.ts +1 -0
- package/dist/src/relay.js +8 -0
- package/dist/src/report-statistics.d.ts +50 -0
- package/dist/src/report-statistics.js +70 -0
- package/dist/src/report.d.ts +171 -0
- package/dist/src/report.js +119 -0
- package/dist/src/repository-identity.d.ts +4 -0
- package/dist/src/repository-identity.js +4 -0
- package/dist/src/review-subject.d.ts +41 -0
- package/dist/src/review-subject.js +91 -0
- package/dist/src/run-wait.d.ts +23 -0
- package/dist/src/run-wait.js +20 -0
- package/dist/src/service/active-tickets.d.ts +4 -0
- package/dist/src/service/active-tickets.js +49 -0
- package/dist/src/service/command-effects.d.ts +4 -0
- package/dist/src/service/command-effects.js +16 -0
- package/dist/src/service/decision-handler.d.ts +4 -0
- package/dist/src/service/decision-handler.js +39 -4
- package/dist/src/service/gateway.js +18 -3
- package/dist/src/service/registry.d.ts +16 -3
- package/dist/src/service/registry.js +34 -3
- package/dist/src/service/replies.d.ts +9 -1
- package/dist/src/service/replies.js +12 -0
- package/dist/src/service/run-handlers.js +14 -55
- package/dist/src/service/run-metadata.d.ts +8 -0
- package/dist/src/service/run-metadata.js +53 -0
- package/dist/src/service/run-waits.d.ts +3 -0
- package/dist/src/service/run-waits.js +41 -0
- package/dist/src/service/service.d.ts +18 -2
- package/dist/src/service/service.js +23 -7
- package/dist/src/service/submission-handler.d.ts +0 -1
- package/dist/src/service/submission-handler.js +6 -34
- package/dist/src/service/worker-port.d.ts +1 -0
- package/dist/src/service/worker-totals.js +8 -23
- package/dist/src/step-bridge.d.ts +23 -0
- package/dist/src/steps/decision-gate.d.ts +2 -1
- package/dist/src/steps/decision-gate.js +7 -0
- package/dist/src/steps/merge-by-person.d.ts +2 -0
- package/dist/src/steps/merge-by-person.js +18 -0
- package/dist/src/steps/merge-when-green.d.ts +2 -0
- package/dist/src/steps/merge-when-green.js +62 -0
- package/dist/src/steps/review-by-agent.d.ts +5 -0
- package/dist/src/steps/review-by-agent.js +124 -0
- package/dist/src/steps/review-by-person.d.ts +4 -0
- package/dist/src/steps/review-by-person.js +16 -0
- package/dist/src/steps/review-subject.d.ts +2 -0
- package/dist/src/steps/review-subject.js +11 -0
- package/dist/src/steps/run-command.d.ts +2 -0
- package/dist/src/steps/run-command.js +15 -0
- package/dist/src/steps/sleep.d.ts +3 -0
- package/dist/src/steps/sleep.js +19 -0
- package/dist/src/steps/wait-for-decision.d.ts +2 -0
- package/dist/src/steps/wait-for-decision.js +71 -0
- package/dist/src/steps/wait-for-run.d.ts +5 -0
- package/dist/src/steps/wait-for-run.js +9 -0
- package/dist/src/storage/decision-snapshots.d.ts +1 -0
- package/dist/src/storage/decision-snapshots.js +7 -1
- package/dist/src/submission.d.ts +4 -0
- package/dist/src/submission.js +6 -2
- package/dist/src/testing.d.ts +29 -0
- package/dist/src/testing.js +264 -0
- package/dist/src/ticket-status-stream.d.ts +9 -0
- package/dist/src/ticket-status-stream.js +94 -0
- package/dist/src/token-prices.d.ts +12 -4
- package/dist/src/token-prices.js +15 -2
- package/dist/src/turn-profile.d.ts +1 -0
- package/dist/src/turn-profile.js +8 -1
- package/dist/src/worker-usage.d.ts +16 -0
- package/dist/src/worker-usage.js +57 -0
- package/dist/src/workflow-admission.d.ts +5 -0
- package/dist/src/workflow-candidate.d.ts +7 -2
- package/dist/src/workflow-candidate.js +47 -5
- package/dist/src/workflow-declaration.d.ts +21 -3
- package/dist/src/workflow-declaration.js +77 -9
- package/dist/src/workflow-discovery.d.ts +2 -1
- package/dist/src/workflow-discovery.js +4 -1
- package/dist/src/workflow-refusals.js +3 -0
- package/dist/src/workflow-schedule.d.ts +22 -0
- package/dist/src/workflow-schedule.js +53 -0
- package/dist/src/workflows.d.ts +11 -1
- package/dist/src/workflows.js +8 -0
- package/dist/tools/admit-workflow.d.ts +1 -0
- package/dist/tools/admit-workflow.js +18 -5
- package/dist/tools/doctor-adoption.d.ts +1 -0
- package/dist/tools/doctor-adoption.js +11 -0
- package/dist/tools/project-configuration.d.ts +4 -0
- package/dist/tools/project-configuration.js +47 -0
- package/dist/tools/self-host-processes.d.ts +1 -0
- package/dist/tools/self-host-processes.js +33 -22
- package/dist/tools/self-host-project.d.ts +4 -0
- package/dist/tools/self-host-project.js +61 -14
- package/dist/tools/self-host-runtime.d.ts +16 -0
- package/dist/tools/self-host-runtime.js +60 -0
- package/dist/tools/self-host-workflows.d.ts +1 -0
- package/dist/tools/self-host-workflows.js +36 -1
- package/dist/tools/self-host.js +86 -61
- package/dist/tools/workflow-candidate-counts.d.ts +6 -2
- package/dist/tools/workflow-candidate-counts.js +31 -16
- package/dist/tools/workflow-candidate-fields.d.ts +5 -0
- package/dist/tools/workflow-candidate-fields.js +24 -0
- package/dist/tools/workflow-candidate-helper-counts.d.ts +10 -0
- package/dist/tools/workflow-candidate-helper-counts.js +129 -0
- package/dist/tools/workflow-candidate-program.d.ts +2 -0
- package/dist/tools/workflow-candidate-program.js +36 -8
- package/dist/tools/workflow-candidate-source.js +77 -15
- package/dist/tools/workflow-candidate-syntax.d.ts +8 -2
- package/dist/tools/workflow-candidate-syntax.js +70 -26
- package/dist/tools/workflow-command.d.ts +1 -0
- package/dist/tools/workflow-command.js +143 -0
- package/dist/tools/workflow-folder-capture.d.ts +1 -0
- package/dist/tools/workflow-folder-capture.js +47 -2
- package/dist/tools/workflow-folders.d.ts +17 -1
- package/dist/tools/workflow-folders.js +59 -6
- package/dist/tools/workflow-test-hook.d.ts +7 -0
- package/dist/tools/workflow-test-hook.js +16 -0
- package/dist/tools/workflow-test-loader.d.ts +1 -0
- package/dist/tools/workflow-test-loader.js +10 -0
- package/dist/workflows/develop-ticket.js +1 -1
- package/dist/workflows/ticket-prompts.js +5 -1
- package/package.json +46 -4
- package/templates/develop/README.md +78 -0
- package/templates/develop/develop/accept.ts +11 -0
- package/templates/develop/develop/flow-tests.ts +357 -0
- package/templates/develop/develop/local.ts +40 -0
- package/templates/develop/develop/option-tests.ts +174 -0
- package/templates/develop/develop/partial-choice.ts +29 -0
- package/templates/develop/develop/partial.ts +28 -0
- package/templates/develop/develop/pull.ts +152 -0
- package/templates/develop/develop/queue-partial.ts +39 -0
- package/templates/develop/develop/refusal-tests.ts +174 -0
- package/templates/develop/develop/report.ts +156 -0
- package/templates/develop/develop/round.ts +40 -0
- package/templates/develop/develop/scenarios.ts +87 -0
- package/templates/develop/develop/turn.ts +67 -0
- package/templates/develop/develop.declaration.json +24 -0
- package/templates/develop/develop.test.ts +287 -0
- package/templates/develop/develop.ts +30 -0
- package/templates/develop/template.json +153 -0
- package/dist/src/chats/analysis-batches.d.ts +0 -42
- package/dist/src/chats/analysis-batches.js +0 -97
- package/dist/src/chats/analysis-checkpoint.d.ts +0 -29
- package/dist/src/chats/analysis-checkpoint.js +0 -31
- package/dist/src/chats/analysis-contract.d.ts +0 -80
- package/dist/src/chats/analysis-contract.js +0 -16
- package/dist/src/chats/analysis-data.d.ts +0 -3
- package/dist/src/chats/analysis-data.js +0 -85
- package/dist/src/chats/analysis-input.d.ts +0 -18
- package/dist/src/chats/analysis-input.js +0 -97
- package/dist/src/chats/analysis-links.d.ts +0 -2
- package/dist/src/chats/analysis-links.js +0 -25
- package/dist/src/chats/analysis-merge.d.ts +0 -16
- package/dist/src/chats/analysis-merge.js +0 -134
- package/dist/src/chats/analysis-prompt.d.ts +0 -18
- package/dist/src/chats/analysis-prompt.js +0 -42
- package/dist/src/chats/analysis-proposal.d.ts +0 -4
- package/dist/src/chats/analysis-proposal.js +0 -41
- package/dist/src/chats/analysis-provenance.d.ts +0 -4
- package/dist/src/chats/analysis-provenance.js +0 -99
- package/dist/src/chats/analysis-shape.d.ts +0 -4
- package/dist/src/chats/analysis-shape.js +0 -235
- package/dist/src/chats/analysis.d.ts +0 -3
- package/dist/src/chats/analysis.js +0 -42
- package/dist/src/chats/corpus-input.d.ts +0 -5
- package/dist/src/chats/corpus-input.js +0 -288
- package/dist/src/chats/destination.d.ts +0 -4
- package/dist/src/chats/destination.js +0 -96
- package/dist/src/chats/import.d.ts +0 -15
- package/dist/src/chats/import.js +0 -243
- package/dist/src/chats/input-file.d.ts +0 -3
- package/dist/src/chats/input-file.js +0 -32
- package/dist/src/chats/normalize.d.ts +0 -29
- package/dist/src/chats/normalize.js +0 -155
- package/dist/src/chats/previous-import.d.ts +0 -5
- package/dist/src/chats/previous-import.js +0 -34
- package/dist/src/chats/reader.d.ts +0 -21
- package/dist/src/chats/reader.js +0 -118
- package/dist/src/chats/redact-import.d.ts +0 -14
- package/dist/src/chats/redact-import.js +0 -141
- package/dist/src/chats/redaction.d.ts +0 -41
- package/dist/src/chats/redaction.js +0 -161
- package/dist/src/chats/reference-mapping.d.ts +0 -16
- package/dist/src/chats/reference-mapping.js +0 -153
- package/dist/src/chats/revision-input.d.ts +0 -3
- package/dist/src/chats/revision-input.js +0 -180
- package/dist/src/chats/revision.d.ts +0 -48
- package/dist/src/chats/revision.js +0 -94
- package/dist/src/chats/selection.d.ts +0 -25
- package/dist/src/chats/selection.js +0 -109
- package/dist/src/chats/source.d.ts +0 -23
- package/dist/src/chats/source.js +0 -135
- package/dist/src/chats/structure.d.ts +0 -57
- package/dist/src/chats/structure.js +0 -216
- package/dist/src/chats/workflow-generation-projection.d.ts +0 -8
- package/dist/src/chats/workflow-generation-projection.js +0 -75
- package/dist/src/chats/workflow-generation-source.d.ts +0 -25
- package/dist/src/chats/workflow-generation-source.js +0 -124
- package/dist/src/chats/workflow-generation-text.d.ts +0 -23
- package/dist/src/chats/workflow-generation-text.js +0 -74
- package/dist/src/chats/workflow-generation.d.ts +0 -69
- package/dist/src/chats/workflow-generation.js +0 -142
- package/dist/src/daemon/analysis-launch.d.ts +0 -5
- package/dist/src/daemon/analysis-launch.js +0 -81
- package/dist/src/daemon/analysis-token.d.ts +0 -6
- package/dist/src/daemon/analysis-token.js +0 -88
- package/dist/src/daemon/analysis-worker.d.ts +0 -20
- package/dist/src/daemon/analysis-worker.js +0 -271
- package/dist/src/daemon/chats-batch-binding.d.ts +0 -23
- package/dist/src/daemon/chats-batch-binding.js +0 -99
- package/dist/src/daemon/chats-capture.d.ts +0 -18
- package/dist/src/daemon/chats-capture.js +0 -194
- package/dist/src/daemon/chats-checkpoints.d.ts +0 -41
- package/dist/src/daemon/chats-checkpoints.js +0 -186
- package/dist/src/daemon/chats-files.d.ts +0 -42
- package/dist/src/daemon/chats-files.js +0 -252
- package/dist/src/daemon/chats-follow-up.d.ts +0 -38
- package/dist/src/daemon/chats-follow-up.js +0 -180
- package/dist/src/daemon/chats-question.d.ts +0 -15
- package/dist/src/daemon/chats-question.js +0 -93
- package/dist/src/daemon/chats-worker.d.ts +0 -13
- package/dist/src/daemon/chats-worker.js +0 -201
- package/dist/workflows/analyze-chats.d.ts +0 -15
- package/dist/workflows/analyze-chats.declaration.json +0 -22
- package/dist/workflows/analyze-chats.js +0 -250
package/dist/src/workflows.d.ts
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
export { loadCycle, type CycleLoad } from "./steps/load-cycle.ts";
|
|
2
2
|
export { protectedEffect } from "./steps/protected-effect.ts";
|
|
3
3
|
export { decisionGate } from "./steps/decision-gate.ts";
|
|
4
|
+
export { waitForDecision } from "./steps/wait-for-decision.ts";
|
|
5
|
+
export { reviewByPerson } from "./steps/review-by-person.ts";
|
|
6
|
+
export { reviewByAgent } from "./steps/review-by-agent.ts";
|
|
7
|
+
export { mergeByPerson } from "./steps/merge-by-person.ts";
|
|
8
|
+
export { mergeWhenGreen } from "./steps/merge-when-green.ts";
|
|
9
|
+
export type { ReviewSubject, CommitReviewSubject, DraftReviewSubject, ReviewResult, Reviewer, } from "./review-subject.ts";
|
|
10
|
+
export type { MergeCheckName, MergeReason, MergeRequest, MergeResult, PullRequest, } from "./merge-request.ts";
|
|
4
11
|
export { handoff } from "./steps/handoff.ts";
|
|
5
|
-
export
|
|
12
|
+
export { waitForRun } from "./steps/wait-for-run.ts";
|
|
13
|
+
export { runCommand } from "./steps/run-command.ts";
|
|
14
|
+
export { sleep } from "./steps/sleep.ts";
|
|
15
|
+
export type { CommandRequest, GateRequest, GateResult, DecisionResult, HandoffRequest, HandoffValue, RunWaitRequest, RunWaitOutcome, ProtectedRequest, ProtectedResult, ProtectedScope, } from "./step-bridge.ts";
|
|
6
16
|
export type { CycleOutcome, DevelopmentInput } from "./workflow-contracts.ts";
|
|
7
17
|
export { ticketStatus, type TicketStatus } from "./ticket-status.ts";
|
package/dist/src/workflows.js
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
export { loadCycle } from "./steps/load-cycle.js";
|
|
2
2
|
export { protectedEffect } from "./steps/protected-effect.js";
|
|
3
3
|
export { decisionGate } from "./steps/decision-gate.js";
|
|
4
|
+
export { waitForDecision } from "./steps/wait-for-decision.js";
|
|
5
|
+
export { reviewByPerson } from "./steps/review-by-person.js";
|
|
6
|
+
export { reviewByAgent } from "./steps/review-by-agent.js";
|
|
7
|
+
export { mergeByPerson } from "./steps/merge-by-person.js";
|
|
8
|
+
export { mergeWhenGreen } from "./steps/merge-when-green.js";
|
|
4
9
|
export { handoff } from "./steps/handoff.js";
|
|
10
|
+
export { waitForRun } from "./steps/wait-for-run.js";
|
|
11
|
+
export { runCommand } from "./steps/run-command.js";
|
|
12
|
+
export { sleep } from "./steps/sleep.js";
|
|
5
13
|
export { ticketStatus } from "./ticket-status.js";
|
|
@@ -10,4 +10,5 @@ export type WorkflowCandidateAdmission = {
|
|
|
10
10
|
export declare function admitWorkflowCandidate(input: {
|
|
11
11
|
readonly source: string;
|
|
12
12
|
readonly declaration: unknown;
|
|
13
|
+
readonly helpers?: Readonly<Record<string, string>>;
|
|
13
14
|
}, installed?: CandidatePackageOptions): Promise<WorkflowCandidateAdmission>;
|
|
@@ -5,30 +5,34 @@ import { tmpdir } from "node:os";
|
|
|
5
5
|
import { findPackageJSON } from "node:module";
|
|
6
6
|
import { dirname, extname, join, resolve } from "node:path";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
|
-
import { checkWorkflowCandidate, } from "../src/workflow-candidate.js";
|
|
8
|
+
import { checkWorkflowCandidate, candidateDeclarationRefusals, workflowHelperPath, } from "../src/workflow-candidate.js";
|
|
9
9
|
import { candidatePackageRoot, } from "./workflow-candidate-program.js";
|
|
10
10
|
import { analyzeWorkflowCandidate } from "./workflow-candidate-source.js";
|
|
11
11
|
import { isWorkflowManifest } from "./workflow-manifest.js";
|
|
12
12
|
export async function admitWorkflowCandidate(input, installed = {}) {
|
|
13
13
|
const { source, declaration } = input;
|
|
14
|
+
const refusal = candidateDeclarationRefusals(declaration);
|
|
15
|
+
if (refusal.length > 0)
|
|
16
|
+
return { kind: "refused", codes: refusal };
|
|
14
17
|
if (Buffer.from(source, "utf8").toString("utf8") !== source)
|
|
15
18
|
return { kind: "refused", codes: ["unsupported-source"] };
|
|
16
19
|
try {
|
|
17
20
|
const packageRoot = resolve(installed.packageRoot ?? candidatePackageRoot);
|
|
18
|
-
const
|
|
21
|
+
const helpers = input.helpers ?? {};
|
|
22
|
+
const facts = analyzeWorkflowCandidate(source, { packageRoot, helpers });
|
|
19
23
|
const codes = checkWorkflowCandidate({ declaration, ...facts });
|
|
20
24
|
if (codes.length > 0)
|
|
21
25
|
return { kind: "refused", codes };
|
|
22
|
-
return await compiledCandidate(source, packageRoot);
|
|
26
|
+
return await compiledCandidate({ source, helpers, packageRoot });
|
|
23
27
|
}
|
|
24
28
|
catch {
|
|
25
29
|
return { kind: "refused", codes: ["compile-failed"] };
|
|
26
30
|
}
|
|
27
31
|
}
|
|
28
|
-
async function compiledCandidate(
|
|
32
|
+
async function compiledCandidate(input) {
|
|
29
33
|
const directory = await realpath(await mkdtemp(join(tmpdir(), "cloving-candidate-")));
|
|
30
34
|
try {
|
|
31
|
-
await prepareCandidateProject(directory,
|
|
35
|
+
await prepareCandidateProject(directory, input);
|
|
32
36
|
if (!(await compile(directory)))
|
|
33
37
|
return { kind: "refused", codes: ["compile-failed"] };
|
|
34
38
|
const artifactDirectory = join(directory, "artifacts");
|
|
@@ -37,6 +41,8 @@ async function compiledCandidate(source, packageRoot) {
|
|
|
37
41
|
Object.values(manifest.workflows ?? {}).flatMap((entries) => Object.values(entries)).length !== 1)
|
|
38
42
|
return { kind: "refused", codes: ["compile-failed"] };
|
|
39
43
|
const digest = createHash("sha256");
|
|
44
|
+
for (const [name, content] of Object.entries(input.helpers).sort(([left], [right]) => (left < right ? -1 : Number(left > right))))
|
|
45
|
+
digest.update(JSON.stringify([name, content]));
|
|
40
46
|
for (const name of [
|
|
41
47
|
"manifest.json",
|
|
42
48
|
"flow.mjs",
|
|
@@ -73,6 +79,13 @@ async function prepareCandidateProject(directory, input) {
|
|
|
73
79
|
include: ["workflows/candidate.ts"],
|
|
74
80
|
}));
|
|
75
81
|
await writeFile(join(directory, "workflows/candidate.ts"), source, "utf8");
|
|
82
|
+
for (const [name, content] of Object.entries(input.helpers)) {
|
|
83
|
+
if (workflowHelperPath("candidate.ts", `./${name}`) !== name)
|
|
84
|
+
throw new Error("invalid-workflow-helper");
|
|
85
|
+
const path = join(directory, "workflows", name);
|
|
86
|
+
await mkdir(dirname(path), { recursive: true });
|
|
87
|
+
await writeFile(path, content, "utf8");
|
|
88
|
+
}
|
|
76
89
|
}
|
|
77
90
|
function compile(directory) {
|
|
78
91
|
const extension = extname(fileURLToPath(import.meta.url));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { selectRuntimeDirectory } from "./self-host-runtime.js";
|
|
2
|
+
const [runtime, repository, legacyRuntime, adoptionRecord] = process.argv.slice(2);
|
|
3
|
+
if (runtime === undefined || repository === undefined)
|
|
4
|
+
process.exitCode = 1;
|
|
5
|
+
else
|
|
6
|
+
process.stdout.write(JSON.stringify(await selectRuntimeDirectory({
|
|
7
|
+
runtime,
|
|
8
|
+
repository,
|
|
9
|
+
legacyRuntime,
|
|
10
|
+
adoptionRecord,
|
|
11
|
+
})) + "\n");
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { resolveSettings } from "../src/project-settings.ts";
|
|
2
|
+
export declare function topLevel(given: string): string;
|
|
3
|
+
export declare function projectRoot(given: string): Promise<string>;
|
|
4
|
+
export declare function projectConfiguration(repository: string, environment: Readonly<NodeJS.ProcessEnv>): Promise<ReturnType<typeof resolveSettings>>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { readFile, realpath } from "node:fs/promises";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
import { basename, join, resolve } from "node:path";
|
|
6
|
+
import { configurationRoot, resolveSettings } from "../src/project-settings.js";
|
|
7
|
+
import { repositoryFileName } from "../src/repository-identity.js";
|
|
8
|
+
async function settingsFile(file) {
|
|
9
|
+
try {
|
|
10
|
+
return await readFile(file.path, "utf8");
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT")
|
|
14
|
+
return undefined;
|
|
15
|
+
throw new Error(`unreadable-config-file: ${file.scope}`, { cause: error });
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export function topLevel(given) {
|
|
19
|
+
try {
|
|
20
|
+
return execFileSync("git", ["-C", given, "rev-parse", "--show-toplevel"], {
|
|
21
|
+
encoding: "utf8",
|
|
22
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
23
|
+
}).trim();
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return given;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export function projectRoot(given) {
|
|
30
|
+
return realpath(topLevel(resolve(given)));
|
|
31
|
+
}
|
|
32
|
+
export async function projectConfiguration(repository, environment) {
|
|
33
|
+
const projectName = repositoryFileName({
|
|
34
|
+
name: basename(repository),
|
|
35
|
+
sha256: createHash("sha256").update(repository).digest("hex"),
|
|
36
|
+
});
|
|
37
|
+
return resolveSettings(environment, {
|
|
38
|
+
project: await settingsFile({
|
|
39
|
+
path: join(repository, ".cloving/config.json"),
|
|
40
|
+
scope: "project",
|
|
41
|
+
}),
|
|
42
|
+
private: await settingsFile({
|
|
43
|
+
path: join(configurationRoot(environment, homedir()), "cloving/projects", `${projectName}.json`),
|
|
44
|
+
scope: "private",
|
|
45
|
+
}),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
@@ -5,6 +5,7 @@ export interface HostProcesses {
|
|
|
5
5
|
readonly directory: string;
|
|
6
6
|
readonly repository: string;
|
|
7
7
|
readonly watchPort: string;
|
|
8
|
+
readonly phoneRelay: string;
|
|
8
9
|
readonly updateMilliseconds: number | undefined;
|
|
9
10
|
}
|
|
10
11
|
export declare function hostedPrograms(settings: HostProcesses): Promise<number>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { execFile, spawn } from "node:child_process";
|
|
2
2
|
import { addAbortListener } from "node:events";
|
|
3
|
+
import { rm } from "node:fs/promises";
|
|
3
4
|
import { extname, join } from "node:path";
|
|
4
5
|
import { setTimeout as delay } from "node:timers/promises";
|
|
5
6
|
import { promisify } from "node:util";
|
|
@@ -21,7 +22,8 @@ function launched(argumentsList, settings) {
|
|
|
21
22
|
}
|
|
22
23
|
async function stopped(programs) {
|
|
23
24
|
for (const program of programs)
|
|
24
|
-
program.child.
|
|
25
|
+
if (!program.child.killed)
|
|
26
|
+
program.child.kill("SIGTERM");
|
|
25
27
|
await Promise.all(programs.map((program) => program.ended));
|
|
26
28
|
}
|
|
27
29
|
function updatingGit(settings, stopping) {
|
|
@@ -51,8 +53,10 @@ function updatingGit(settings, stopping) {
|
|
|
51
53
|
};
|
|
52
54
|
}
|
|
53
55
|
async function polled(settings, lifecycle) {
|
|
54
|
-
if (settings.updateMilliseconds === undefined)
|
|
56
|
+
if (settings.updateMilliseconds === undefined) {
|
|
57
|
+
await rm(join(settings.directory, "pending-self-update"), { force: true });
|
|
55
58
|
return;
|
|
59
|
+
}
|
|
56
60
|
const cancelled = () => lifecycle.stopping.aborted;
|
|
57
61
|
const updater = selfUpdater({
|
|
58
62
|
directory: settings.directory,
|
|
@@ -87,33 +91,40 @@ async function polled(settings, lifecycle) {
|
|
|
87
91
|
}
|
|
88
92
|
return undefined;
|
|
89
93
|
}
|
|
94
|
+
function productChild(settings, argumentsList) {
|
|
95
|
+
const [program, ...rest] = argumentsList;
|
|
96
|
+
return launched([
|
|
97
|
+
join(settings.product, `src/${program}${extname(import.meta.filename)}`),
|
|
98
|
+
...rest,
|
|
99
|
+
], {
|
|
100
|
+
directory: settings.product,
|
|
101
|
+
environment: {
|
|
102
|
+
...process.env,
|
|
103
|
+
CLOVING_RUNTIME_DIR: settings.runtime,
|
|
104
|
+
CLOVING_WATCH_REPOSITORY: settings.repository,
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
}
|
|
90
108
|
function hostedChildren(settings) {
|
|
91
109
|
const daemon = launched([join(settings.project, "start.mjs")], {
|
|
92
110
|
directory: settings.project,
|
|
93
111
|
environment: process.env,
|
|
94
112
|
});
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
]
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
...process.env,
|
|
108
|
-
CLOVING_RUNTIME_DIR: settings.runtime,
|
|
109
|
-
CLOVING_WATCH_REPOSITORY: settings.repository,
|
|
110
|
-
},
|
|
111
|
-
}),
|
|
112
|
-
];
|
|
113
|
+
const watch = settings.watchPort === "off"
|
|
114
|
+
? []
|
|
115
|
+
: [
|
|
116
|
+
productChild(settings, [
|
|
117
|
+
"cli",
|
|
118
|
+
"watch",
|
|
119
|
+
"--port",
|
|
120
|
+
settings.watchPort,
|
|
121
|
+
]),
|
|
122
|
+
];
|
|
123
|
+
const relay = settings.phoneRelay === "off" ? [] : [productChild(settings, ["relay"])];
|
|
124
|
+
return { daemon, programs: [daemon, ...watch, ...relay] };
|
|
113
125
|
}
|
|
114
126
|
export async function hostedPrograms(settings) {
|
|
115
|
-
const programs = hostedChildren(settings);
|
|
116
|
-
const daemon = programs[0];
|
|
127
|
+
const { daemon, programs } = hostedChildren(settings);
|
|
117
128
|
const stopping = new AbortController();
|
|
118
129
|
let updating = false;
|
|
119
130
|
const interrupt = () => {
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { type DeclaredWorkflow } from "../src/workflow-declaration.ts";
|
|
2
2
|
import type { WorkflowRefusal } from "../src/workflow-refusals.ts";
|
|
3
|
+
import { type WorkflowListing } from "./workflow-folders.ts";
|
|
3
4
|
interface ProjectSettings {
|
|
4
5
|
readonly product: string;
|
|
5
6
|
readonly project: string;
|
|
6
7
|
readonly repository: string;
|
|
7
8
|
readonly home: string;
|
|
8
9
|
readonly xdgConfigHome?: string | undefined;
|
|
10
|
+
readonly userFolder?: string | undefined;
|
|
9
11
|
}
|
|
10
12
|
export interface RegisteredWorkflows {
|
|
13
|
+
readonly workflows: readonly WorkflowListing[];
|
|
11
14
|
readonly repository: string;
|
|
15
|
+
readonly bundleDigest: string;
|
|
12
16
|
readonly manifests: Readonly<Record<string, string>>;
|
|
13
17
|
readonly declarations: readonly DeclaredWorkflow[];
|
|
14
18
|
readonly workflowRefusals: readonly WorkflowRefusal[];
|
|
@@ -22,8 +22,13 @@ async function initializeProject(settings) {
|
|
|
22
22
|
await copyWorkflow(settings, file);
|
|
23
23
|
const modules = join(project, "node_modules");
|
|
24
24
|
await mkdir(join(modules, "cloving"), { recursive: true });
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
const dependencies = new Map(Object.keys(packageMetadata.dependencies).map((name) => [name, join(product, "package.json")]));
|
|
26
|
+
const sdk = findPackageJSON("workflow", join(product, "package.json"));
|
|
27
|
+
if (sdk === undefined)
|
|
28
|
+
throw new Error("missing-runtime-dependency: workflow");
|
|
29
|
+
dependencies.set("@workflow/core", sdk);
|
|
30
|
+
for (const [name, from] of dependencies) {
|
|
31
|
+
const location = findPackageJSON(name, from);
|
|
27
32
|
if (location === undefined)
|
|
28
33
|
throw new Error(`missing-runtime-dependency: ${name}`);
|
|
29
34
|
await mkdir(dirname(join(modules, name)), { recursive: true });
|
|
@@ -95,11 +100,21 @@ async function stageCandidates(project, candidates) {
|
|
|
95
100
|
candidate.baseName,
|
|
96
101
|
candidate.source,
|
|
97
102
|
candidate.declaration,
|
|
103
|
+
Object.entries(candidate.helpers).sort(([left], [right]) => left < right ? -1 : Number(left > right)),
|
|
98
104
|
]))
|
|
99
105
|
.digest("hex");
|
|
100
|
-
const
|
|
106
|
+
const root = Object.keys(candidate.helpers).length > 0
|
|
107
|
+
? join(directory, name)
|
|
108
|
+
: directory;
|
|
109
|
+
await mkdir(root, { recursive: true, mode: 0o700 });
|
|
110
|
+
const file = join(root, `${name}.ts`);
|
|
101
111
|
await writeFile(file, candidate.source);
|
|
102
|
-
await writeFile(join(
|
|
112
|
+
await writeFile(join(root, `${name}.declaration.json`), candidate.declaration);
|
|
113
|
+
for (const [path, source] of Object.entries(candidate.helpers)) {
|
|
114
|
+
const destination = join(root, path);
|
|
115
|
+
await mkdir(dirname(destination), { recursive: true, mode: 0o700 });
|
|
116
|
+
await writeFile(destination, source);
|
|
117
|
+
}
|
|
103
118
|
staged.push({ candidate, file });
|
|
104
119
|
}
|
|
105
120
|
return staged;
|
|
@@ -132,6 +147,37 @@ async function copyWorkflow(settings, file) {
|
|
|
132
147
|
if (declaration !== undefined)
|
|
133
148
|
await writeFile(join(project, "workflows", sidecar), declaration);
|
|
134
149
|
}
|
|
150
|
+
function bundledListings(input) {
|
|
151
|
+
const { product, files, manifests, declarations } = input;
|
|
152
|
+
const byFunction = new Map(declarations.map(({ functionName, ...declaration }) => [
|
|
153
|
+
functionName,
|
|
154
|
+
declaration,
|
|
155
|
+
]));
|
|
156
|
+
return Object.entries(manifests).map(([functionName, manifest]) => {
|
|
157
|
+
const declaration = byFunction.get(functionName);
|
|
158
|
+
const file = files.find((file) => basename(file, extname(file)) === manifest.name);
|
|
159
|
+
return {
|
|
160
|
+
scope: "bundled",
|
|
161
|
+
workflowId: declaration?.workflowId ?? manifest.name,
|
|
162
|
+
file: join(product, "workflows", file ?? manifest.name),
|
|
163
|
+
admitted: true,
|
|
164
|
+
codes: [],
|
|
165
|
+
...(declaration === undefined ? {} : { declaration }),
|
|
166
|
+
};
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
async function writeManifests(project, compiled) {
|
|
170
|
+
const manifests = {};
|
|
171
|
+
for (const [functionName, manifest] of Object.entries(compiled)) {
|
|
172
|
+
const path = join(project, `${manifest.name}.workflow.json`);
|
|
173
|
+
await writeFile(path, JSON.stringify(manifest));
|
|
174
|
+
Object.defineProperty(manifests, functionName, {
|
|
175
|
+
value: path,
|
|
176
|
+
enumerable: true,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
return manifests;
|
|
180
|
+
}
|
|
135
181
|
export async function preparedProject(settings) {
|
|
136
182
|
const { product, project } = settings;
|
|
137
183
|
const files = await initializeProject(settings);
|
|
@@ -149,27 +195,28 @@ export async function preparedProject(settings) {
|
|
|
149
195
|
...declarations,
|
|
150
196
|
...staged.map((candidate) => operatorDeclaration({ ...candidate, project }, compiled)),
|
|
151
197
|
];
|
|
152
|
-
const manifests =
|
|
153
|
-
for (const [functionName, manifest] of Object.entries(workflowManifests(compiled, combined))) {
|
|
154
|
-
const path = join(project, `${manifest.name}.workflow.json`);
|
|
155
|
-
await writeFile(path, JSON.stringify(manifest));
|
|
156
|
-
Object.defineProperty(manifests, functionName, {
|
|
157
|
-
value: path,
|
|
158
|
-
enumerable: true,
|
|
159
|
-
});
|
|
160
|
-
}
|
|
198
|
+
const manifests = await writeManifests(project, workflowManifests(compiled, combined));
|
|
161
199
|
await writeFile(join(project, "declarations.json"), JSON.stringify(combined));
|
|
162
200
|
await writeFile(join(project, "dependencies.json"), await workflowBundleDependencies({
|
|
163
201
|
product,
|
|
164
202
|
packages: Object.keys(packageMetadata.dependencies),
|
|
165
203
|
}));
|
|
166
|
-
await retainWorkflowBundle({
|
|
204
|
+
const bundleDigest = await retainWorkflowBundle({
|
|
167
205
|
project,
|
|
168
206
|
repository: folders.repository,
|
|
169
207
|
directory: join(dirname(project), "workflow-bundles"),
|
|
170
208
|
});
|
|
209
|
+
const workflows = bundledListings({
|
|
210
|
+
product,
|
|
211
|
+
files,
|
|
212
|
+
manifests: bundled,
|
|
213
|
+
declarations,
|
|
214
|
+
});
|
|
215
|
+
workflows.push(...folders.workflows);
|
|
171
216
|
return {
|
|
217
|
+
workflows,
|
|
172
218
|
repository: folders.repository,
|
|
219
|
+
bundleDigest,
|
|
173
220
|
manifests,
|
|
174
221
|
declarations: combined,
|
|
175
222
|
workflowRefusals: folders.refusals,
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
interface RuntimeSelection {
|
|
2
|
+
readonly runtime: string;
|
|
3
|
+
readonly repository: string;
|
|
4
|
+
readonly legacyRuntime: string | undefined;
|
|
5
|
+
readonly adoptionRecord: string | undefined;
|
|
6
|
+
}
|
|
7
|
+
export declare function selectRuntimeDirectory(input: RuntimeSelection): Promise<{
|
|
8
|
+
readonly runtime: string;
|
|
9
|
+
readonly note: string;
|
|
10
|
+
readonly adoptionRecord?: string;
|
|
11
|
+
}>;
|
|
12
|
+
export declare function adoptRuntimeDirectory(input: RuntimeSelection): Promise<{
|
|
13
|
+
readonly runtime: string;
|
|
14
|
+
readonly note: string;
|
|
15
|
+
}>;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { link, mkdir, readdir, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { readRetainedWorkflowBundle } from "./workflow-bundles.js";
|
|
5
|
+
export async function selectRuntimeDirectory(input) {
|
|
6
|
+
const { runtime, repository, legacyRuntime, adoptionRecord } = input;
|
|
7
|
+
if (legacyRuntime === undefined ||
|
|
8
|
+
adoptionRecord === undefined ||
|
|
9
|
+
runtime === legacyRuntime)
|
|
10
|
+
return { runtime, note: "" };
|
|
11
|
+
const directory = join(dirname(legacyRuntime), "workflow-bundles");
|
|
12
|
+
if (!(await belongsToRepository(directory, repository)))
|
|
13
|
+
return {
|
|
14
|
+
runtime,
|
|
15
|
+
note: `Legacy runtime ${legacyRuntime} was not adopted: retained bundles are absent, damaged or belong to another repository.`,
|
|
16
|
+
};
|
|
17
|
+
return { runtime: legacyRuntime, note: "", adoptionRecord };
|
|
18
|
+
}
|
|
19
|
+
export async function adoptRuntimeDirectory(input) {
|
|
20
|
+
const selected = await selectRuntimeDirectory(input);
|
|
21
|
+
const adoptionRecord = selected.adoptionRecord;
|
|
22
|
+
if (adoptionRecord === undefined)
|
|
23
|
+
return { runtime: selected.runtime, note: selected.note };
|
|
24
|
+
const { repository } = input;
|
|
25
|
+
const legacyRuntime = selected.runtime;
|
|
26
|
+
await mkdir(dirname(adoptionRecord), { recursive: true, mode: 0o700 });
|
|
27
|
+
const contents = JSON.stringify({
|
|
28
|
+
schemaVersion: 1,
|
|
29
|
+
repository,
|
|
30
|
+
runtimeDirectory: legacyRuntime,
|
|
31
|
+
});
|
|
32
|
+
const temporary = `${adoptionRecord}.${randomUUID()}.tmp`;
|
|
33
|
+
try {
|
|
34
|
+
await writeFile(temporary, contents, {
|
|
35
|
+
flag: "wx",
|
|
36
|
+
mode: 0o600,
|
|
37
|
+
flush: true,
|
|
38
|
+
});
|
|
39
|
+
await link(temporary, adoptionRecord);
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
await rm(temporary, { force: true });
|
|
43
|
+
}
|
|
44
|
+
return { runtime: legacyRuntime, note: "" };
|
|
45
|
+
}
|
|
46
|
+
async function belongsToRepository(directory, repository) {
|
|
47
|
+
try {
|
|
48
|
+
const ids = (await readdir(directory)).filter((id) => id !== ".history");
|
|
49
|
+
if (ids.length === 0)
|
|
50
|
+
return false;
|
|
51
|
+
for (const id of ids)
|
|
52
|
+
if ((await readRetainedWorkflowBundle({ directory, repository, id }))
|
|
53
|
+
.kind !== "available")
|
|
54
|
+
return false;
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -12,4 +12,5 @@ interface HostManifest {
|
|
|
12
12
|
export declare function workflowFiles(directory: string): Promise<string[]>;
|
|
13
13
|
export declare function workflowDeclarations(directory: string, manifests: Readonly<Record<string, HostManifest>>): Promise<readonly DeclaredWorkflow[]>;
|
|
14
14
|
export declare function workflowManifests(compiled: WorkflowManifest, declarations?: readonly DeclaredWorkflow[]): Readonly<Record<string, HostManifest>>;
|
|
15
|
+
export declare function workflowBundleLoader(): string;
|
|
15
16
|
export {};
|
|
@@ -6,7 +6,8 @@ export async function workflowFiles(directory) {
|
|
|
6
6
|
return entries
|
|
7
7
|
.filter((entry) => entry.isFile() &&
|
|
8
8
|
/\.(?:ts|js)$/.test(entry.name) &&
|
|
9
|
-
!entry.name.endsWith(".d.ts")
|
|
9
|
+
!entry.name.endsWith(".d.ts") &&
|
|
10
|
+
!entry.name.endsWith(".test.ts"))
|
|
10
11
|
.map((entry) => entry.name)
|
|
11
12
|
.sort();
|
|
12
13
|
}
|
|
@@ -76,3 +77,37 @@ export function workflowManifests(compiled, declarations = []) {
|
|
|
76
77
|
});
|
|
77
78
|
}));
|
|
78
79
|
}
|
|
80
|
+
export function workflowBundleLoader() {
|
|
81
|
+
return `
|
|
82
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
83
|
+
import { pathToFileURL } from "node:url";
|
|
84
|
+
const bundleRegistries = new AsyncLocalStorage();
|
|
85
|
+
const registryKeys = ["@workflow/core//registeredSteps", "workflow-class-registry"].map(Symbol.for);
|
|
86
|
+
for (const key of registryKeys) {
|
|
87
|
+
let current = globalThis[key] ?? new Map();
|
|
88
|
+
Object.defineProperty(globalThis, key, {
|
|
89
|
+
configurable: true,
|
|
90
|
+
get: () => bundleRegistries.getStore()?.get(key) ?? current,
|
|
91
|
+
set: (value) => {
|
|
92
|
+
const scope = bundleRegistries.getStore();
|
|
93
|
+
if (scope === undefined) current = value;
|
|
94
|
+
else scope.set(key, value);
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
const loadedBundles = new Map();
|
|
99
|
+
const loadWorkflowBundle = (directory) => {
|
|
100
|
+
const known = loadedBundles.get(directory);
|
|
101
|
+
if (known !== undefined) return known;
|
|
102
|
+
const scope = new Map(registryKeys.map((key) => [key, new Map()]));
|
|
103
|
+
const loaded = bundleRegistries.run(scope, async () => {
|
|
104
|
+
const workflows = await import(pathToFileURL(directory + "/artifacts/client.mjs").href);
|
|
105
|
+
const { POST } = await import(pathToFileURL(directory + "/artifacts/flow.mjs").href);
|
|
106
|
+
if (typeof POST !== "function") throw new Error("pinned-workflow-unavailable");
|
|
107
|
+
return { workflows, handler: (request) => bundleRegistries.run(scope, () => POST(request)) };
|
|
108
|
+
});
|
|
109
|
+
loadedBundles.set(directory, loaded);
|
|
110
|
+
return loaded;
|
|
111
|
+
};
|
|
112
|
+
`;
|
|
113
|
+
}
|