cloving 0.3.20 → 1.0.1
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/{LICENSE.md → LICENSE} +1 -1
- package/README.md +475 -182
- package/dist/src/authority/budgets.d.ts +12 -0
- package/dist/src/authority/budgets.js +42 -0
- package/dist/src/authority/commands.d.ts +7 -0
- package/dist/src/authority/commands.js +263 -0
- package/dist/src/authority/details.d.ts +28 -0
- package/dist/src/authority/details.js +33 -0
- package/dist/src/authority/dispatch-decision.d.ts +40 -0
- package/dist/src/authority/dispatch-decision.js +47 -0
- package/dist/src/authority/effect-requests.d.ts +2 -0
- package/dist/src/authority/effect-requests.js +139 -0
- package/dist/src/authority/effect-results.d.ts +4 -0
- package/dist/src/authority/effect-results.js +236 -0
- package/dist/src/authority/events.d.ts +2 -0
- package/dist/src/authority/events.js +45 -0
- package/dist/src/authority/gate-reduction.d.ts +8 -0
- package/dist/src/authority/gate-reduction.js +109 -0
- package/dist/src/authority/gates.d.ts +48 -0
- package/dist/src/authority/gates.js +77 -0
- package/dist/src/authority/history-state.d.ts +15 -0
- package/dist/src/authority/history-state.js +61 -0
- package/dist/src/authority/history.d.ts +13 -0
- package/dist/src/authority/history.js +37 -0
- package/dist/src/authority/instants.d.ts +3 -0
- package/dist/src/authority/instants.js +38 -0
- package/dist/src/authority/leases.d.ts +15 -0
- package/dist/src/authority/leases.js +113 -0
- package/dist/src/authority/operations.d.ts +101 -0
- package/dist/src/authority/operations.js +75 -0
- package/dist/src/authority/reconciliation.d.ts +27 -0
- package/dist/src/authority/reconciliation.js +147 -0
- package/dist/src/authority/reducer.d.ts +41 -0
- package/dist/src/authority/reducer.js +139 -0
- package/dist/src/authority/reduction-state.d.ts +36 -0
- package/dist/src/authority/reduction-state.js +68 -0
- package/dist/src/authority/reduction.d.ts +6 -0
- package/dist/src/authority/reduction.js +160 -0
- package/dist/src/authority/status-closure.d.ts +4 -0
- package/dist/src/authority/status-closure.js +57 -0
- package/dist/src/authority/status-effects.d.ts +17 -0
- package/dist/src/authority/status-effects.js +43 -0
- package/dist/src/authority/status-input.d.ts +45 -0
- package/dist/src/authority/status-input.js +9 -0
- package/dist/src/authority/status.d.ts +32 -0
- package/dist/src/authority/status.js +256 -0
- package/dist/src/authority/stop-sequence.d.ts +37 -0
- package/dist/src/authority/stop-sequence.js +91 -0
- package/dist/src/authority/transitions.d.ts +63 -0
- package/dist/src/authority/transitions.js +122 -0
- package/dist/src/broker/actor/adapter-calls.d.ts +13 -0
- package/dist/src/broker/actor/adapter-calls.js +34 -0
- package/dist/src/broker/actor/adapter-outcomes.d.ts +28 -0
- package/dist/src/broker/actor/adapter-outcomes.js +80 -0
- package/dist/src/broker/actor/authority-actor.d.ts +25 -0
- package/dist/src/broker/actor/authority-actor.js +169 -0
- package/dist/src/broker/actor/authority-changes.d.ts +31 -0
- package/dist/src/broker/actor/authority-changes.js +46 -0
- package/dist/src/broker/actor/authority-connection.d.ts +15 -0
- package/dist/src/broker/actor/authority-connection.js +44 -0
- package/dist/src/broker/actor/authority-conversion.d.ts +10 -0
- package/dist/src/broker/actor/authority-conversion.js +72 -0
- package/dist/src/broker/actor/authority-delivery.d.ts +13 -0
- package/dist/src/broker/actor/authority-delivery.js +162 -0
- package/dist/src/broker/actor/authority-logger.d.ts +2 -0
- package/dist/src/broker/actor/authority-logger.js +19 -0
- package/dist/src/broker/actor/authority-policy.d.ts +9 -0
- package/dist/src/broker/actor/authority-policy.js +11 -0
- package/dist/src/broker/actor/authority-queries.d.ts +45 -0
- package/dist/src/broker/actor/authority-queries.js +85 -0
- package/dist/src/broker/actor/authority-receipts.d.ts +28 -0
- package/dist/src/broker/actor/authority-receipts.js +84 -0
- package/dist/src/broker/actor/authority-release.d.ts +13 -0
- package/dist/src/broker/actor/authority-release.js +69 -0
- package/dist/src/broker/actor/authority-runtime.d.ts +60 -0
- package/dist/src/broker/actor/authority-runtime.js +204 -0
- package/dist/src/broker/actor/authority-session.d.ts +65 -0
- package/dist/src/broker/actor/authority-session.js +252 -0
- package/dist/src/broker/actor/authority-settings.d.ts +33 -0
- package/dist/src/broker/actor/authority-settings.js +63 -0
- package/dist/src/broker/actor/authority-upgrades.d.ts +16 -0
- package/dist/src/broker/actor/authority-upgrades.js +12 -0
- package/dist/src/broker/actor/authority-watchdog.d.ts +14 -0
- package/dist/src/broker/actor/authority-watchdog.js +41 -0
- package/dist/src/broker/actor/authority.d.ts +14 -0
- package/dist/src/broker/actor/authority.js +115 -0
- package/dist/src/broker/actor/delivery-intents.d.ts +68 -0
- package/dist/src/broker/actor/delivery-intents.js +77 -0
- package/dist/src/broker/actor/delivery-plan.d.ts +2 -0
- package/dist/src/broker/actor/delivery-plan.js +109 -0
- package/dist/src/broker/actor/delivery-results.d.ts +11 -0
- package/dist/src/broker/actor/delivery-results.js +63 -0
- package/dist/src/broker/actor/effect-delivery.d.ts +19 -0
- package/dist/src/broker/actor/effect-delivery.js +118 -0
- package/dist/src/broker/actor/effect-plan.d.ts +41 -0
- package/dist/src/broker/actor/effect-plan.js +173 -0
- package/dist/src/broker/actor/effect-queries.d.ts +27 -0
- package/dist/src/broker/actor/effect-queries.js +80 -0
- package/dist/src/broker/actor/effect-turn.d.ts +25 -0
- package/dist/src/broker/actor/effect-turn.js +84 -0
- package/dist/src/broker/actor/pin-check.d.ts +6 -0
- package/dist/src/broker/actor/pin-check.js +12 -0
- package/dist/src/broker/actor/runtime-parts.d.ts +23 -0
- package/dist/src/broker/actor/runtime-parts.js +34 -0
- package/dist/src/broker/actor/stop-plan.d.ts +20 -0
- package/dist/src/broker/actor/stop-plan.js +46 -0
- package/dist/src/broker/actor/stop-turn.d.ts +17 -0
- package/dist/src/broker/actor/stop-turn.js +42 -0
- package/dist/src/broker/actor/turn-draft.d.ts +31 -0
- package/dist/src/broker/actor/turn-draft.js +138 -0
- package/dist/src/broker/actor/turn-plan.d.ts +17 -0
- package/dist/src/broker/actor/turn-plan.js +136 -0
- package/dist/src/broker/actor/turn-refusals.d.ts +8 -0
- package/dist/src/broker/actor/turn-refusals.js +35 -0
- package/dist/src/broker/actor/turn-staging.d.ts +78 -0
- package/dist/src/broker/actor/turn-staging.js +34 -0
- package/dist/src/broker/actor/turn-state.d.ts +34 -0
- package/dist/src/broker/actor/turn-state.js +208 -0
- package/dist/src/broker/authority-admission.d.ts +21 -0
- package/dist/src/broker/authority-admission.js +70 -0
- package/dist/src/broker/authority-restore.d.ts +30 -0
- package/dist/src/broker/authority-restore.js +165 -0
- package/dist/src/broker/decision-restore.d.ts +16 -0
- package/dist/src/broker/decision-restore.js +158 -0
- package/dist/src/broker/decision-upgrade.d.ts +3 -0
- package/dist/src/broker/decision-upgrade.js +12 -0
- package/dist/src/broker/effect-restore.d.ts +20 -0
- package/dist/src/broker/effect-restore.js +111 -0
- package/dist/src/broker/effect-upgrade.d.ts +3 -0
- package/dist/src/broker/effect-upgrade.js +9 -0
- package/dist/src/broker/operation-digest.d.ts +1 -0
- package/dist/src/broker/operation-digest.js +4 -0
- package/dist/src/broker/socket-address.d.ts +9 -0
- package/dist/src/broker/socket-address.js +14 -0
- package/dist/src/broker/workflow-pin.d.ts +2 -0
- package/dist/src/broker/workflow-pin.js +5 -0
- package/dist/src/chats/destination.d.ts +4 -0
- package/dist/src/chats/destination.js +94 -0
- package/dist/src/chats/import.d.ts +13 -0
- package/dist/src/chats/import.js +71 -0
- package/dist/src/chats/normalize.d.ts +20 -0
- package/dist/src/chats/normalize.js +139 -0
- package/dist/src/chats/reader.d.ts +15 -0
- package/dist/src/chats/reader.js +87 -0
- package/dist/src/cli/arguments.d.ts +23 -0
- package/dist/src/cli/arguments.js +154 -0
- package/dist/src/cli/client.d.ts +15 -0
- package/dist/src/cli/client.js +122 -0
- package/dist/src/cli/commands.d.ts +14 -0
- package/dist/src/cli/commands.js +253 -0
- package/dist/src/cli/main.d.ts +1 -0
- package/dist/src/cli/main.js +80 -0
- package/dist/src/cli/render.d.ts +8 -0
- package/dist/src/cli/render.js +186 -0
- package/dist/src/cli/runtime-arguments.d.ts +73 -0
- package/dist/src/cli/runtime-arguments.js +248 -0
- package/dist/src/cli/runtime-directory.d.ts +4 -0
- package/dist/src/cli/runtime-directory.js +25 -0
- package/dist/src/cli/toolchain.d.ts +3 -0
- package/dist/src/cli/toolchain.js +74 -0
- package/dist/src/cli/usage.d.ts +4 -0
- package/dist/src/cli/usage.js +124 -0
- package/dist/src/cli/validate.d.ts +38 -0
- package/dist/src/cli/validate.js +116 -0
- package/dist/src/cli/watch-board-view.d.ts +22 -0
- package/dist/src/cli/watch-board-view.js +128 -0
- package/dist/src/cli/watch-board.d.ts +15 -0
- package/dist/src/cli/watch-board.js +174 -0
- package/dist/src/cli/watch-element.d.ts +11 -0
- package/dist/src/cli/watch-element.js +6 -0
- package/dist/src/cli/watch-model.d.ts +29 -0
- package/dist/src/cli/watch-model.js +261 -0
- package/dist/src/cli/watch-navigation.d.ts +9 -0
- package/dist/src/cli/watch-navigation.js +40 -0
- package/dist/src/cli/watch-page.d.ts +1 -0
- package/dist/src/cli/watch-page.js +272 -0
- package/dist/src/cli/watch-paths.d.ts +2 -0
- package/dist/src/cli/watch-paths.js +52 -0
- package/dist/src/cli/watch-phases.d.ts +7 -0
- package/dist/src/cli/watch-phases.js +148 -0
- package/dist/src/cli/watch-reads.d.ts +28 -0
- package/dist/src/cli/watch-reads.js +244 -0
- package/dist/src/cli/watch-render.d.ts +139 -0
- package/dist/src/cli/watch-render.js +95 -0
- package/dist/src/cli/watch-server.d.ts +10 -0
- package/dist/src/cli/watch-server.js +176 -0
- package/dist/src/cli/watch-stream.d.ts +11 -0
- package/dist/src/cli/watch-stream.js +128 -0
- package/dist/src/cli/watch-turn.d.ts +29 -0
- package/dist/src/cli/watch-turn.js +130 -0
- package/dist/src/cli/watch-view.d.ts +39 -0
- package/dist/src/cli/watch-view.js +223 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +62 -0
- package/dist/src/daemon/claude-turn.d.ts +28 -0
- package/dist/src/daemon/claude-turn.js +135 -0
- package/dist/src/daemon/claude-worker.d.ts +26 -0
- package/dist/src/daemon/claude-worker.js +224 -0
- package/dist/src/daemon/codex-stream.d.ts +4 -0
- package/dist/src/daemon/codex-stream.js +113 -0
- package/dist/src/daemon/daemon.d.ts +46 -0
- package/dist/src/daemon/daemon.js +186 -0
- package/dist/src/daemon/delivery-router.d.ts +10 -0
- package/dist/src/daemon/delivery-router.js +34 -0
- package/dist/src/daemon/github-calls.d.ts +29 -0
- package/dist/src/daemon/github-calls.js +127 -0
- package/dist/src/daemon/github-issue-methods.d.ts +3 -0
- package/dist/src/daemon/github-issue-methods.js +99 -0
- package/dist/src/daemon/github-issue-privacy.d.ts +6 -0
- package/dist/src/daemon/github-issue-privacy.js +131 -0
- package/dist/src/daemon/github-merge.d.ts +18 -0
- package/dist/src/daemon/github-merge.js +259 -0
- package/dist/src/daemon/github-methods.d.ts +5 -0
- package/dist/src/daemon/github-methods.js +198 -0
- package/dist/src/daemon/github-operation.d.ts +38 -0
- package/dist/src/daemon/github-operation.js +57 -0
- package/dist/src/daemon/github-worker.d.ts +17 -0
- package/dist/src/daemon/github-worker.js +281 -0
- package/dist/src/daemon/host-environment.d.ts +8 -0
- package/dist/src/daemon/host-environment.js +14 -0
- package/dist/src/daemon/issue-queue.d.ts +9 -0
- package/dist/src/daemon/issue-queue.js +163 -0
- package/dist/src/daemon/notify-message.d.ts +14 -0
- package/dist/src/daemon/notify-message.js +48 -0
- package/dist/src/daemon/notify.d.ts +12 -0
- package/dist/src/daemon/notify.js +161 -0
- package/dist/src/daemon/operation-journal.d.ts +42 -0
- package/dist/src/daemon/operation-journal.js +53 -0
- package/dist/src/daemon/ticket-registration.d.ts +33 -0
- package/dist/src/daemon/ticket-registration.js +177 -0
- package/dist/src/daemon/ticket-source.d.ts +17 -0
- package/dist/src/daemon/ticket-source.js +36 -0
- package/dist/src/daemon/work-tree.d.ts +26 -0
- package/dist/src/daemon/work-tree.js +206 -0
- package/dist/src/effect-authorization.d.ts +21 -0
- package/dist/src/effect-authorization.js +14 -0
- package/dist/src/execution-pin.d.ts +4 -0
- package/dist/src/execution-pin.js +68 -0
- package/dist/src/host/start-delivery.d.ts +41 -0
- package/dist/src/host/start-delivery.js +68 -0
- package/dist/src/host/step-bridge-host.d.ts +79 -0
- package/dist/src/host/step-bridge-host.js +205 -0
- package/dist/src/host/step-claims.d.ts +31 -0
- package/dist/src/host/step-claims.js +85 -0
- package/dist/src/host/world-host.d.ts +21 -0
- package/dist/src/host/world-host.js +51 -0
- package/dist/src/host/world-reconciliation.d.ts +37 -0
- package/dist/src/host/world-reconciliation.js +75 -0
- package/dist/src/host/world-runs.d.ts +14 -0
- package/dist/src/host/world-runs.js +61 -0
- package/dist/src/operation-identity.d.ts +7 -0
- package/dist/src/operation-identity.js +59 -0
- package/dist/src/protocol.d.ts +35 -0
- package/dist/src/protocol.js +64 -0
- package/dist/src/resource-files.d.ts +1 -0
- package/dist/src/resource-files.js +29 -0
- package/dist/src/service/changes.d.ts +11 -0
- package/dist/src/service/changes.js +32 -0
- package/dist/src/service/decision-handler.d.ts +9 -0
- package/dist/src/service/decision-handler.js +233 -0
- package/dist/src/service/event-handler.d.ts +10 -0
- package/dist/src/service/event-handler.js +70 -0
- package/dist/src/service/expiry.d.ts +13 -0
- package/dist/src/service/expiry.js +53 -0
- package/dist/src/service/gateway.d.ts +21 -0
- package/dist/src/service/gateway.js +120 -0
- package/dist/src/service/registry.d.ts +40 -0
- package/dist/src/service/registry.js +13 -0
- package/dist/src/service/replies.d.ts +26 -0
- package/dist/src/service/replies.js +56 -0
- package/dist/src/service/run-handlers.d.ts +4 -0
- package/dist/src/service/run-handlers.js +271 -0
- package/dist/src/service/service.d.ts +58 -0
- package/dist/src/service/service.js +212 -0
- package/dist/src/service/submission-handler.d.ts +4 -0
- package/dist/src/service/submission-handler.js +206 -0
- package/dist/src/service/transport.d.ts +16 -0
- package/dist/src/service/transport.js +141 -0
- package/dist/src/service/worker-port.d.ts +85 -0
- package/dist/src/service/worker-port.js +126 -0
- package/dist/src/step-bridge.d.ts +57 -0
- package/dist/src/step-bridge.js +4 -0
- package/dist/src/steps/decision-gate.d.ts +2 -0
- package/dist/src/steps/decision-gate.js +8 -0
- package/dist/src/steps/load-cycle.d.ts +10 -0
- package/dist/src/steps/load-cycle.js +11 -0
- package/dist/src/steps/protected-effect.d.ts +2 -0
- package/dist/src/steps/protected-effect.js +8 -0
- package/dist/src/storage/decision-rows.d.ts +54 -0
- package/dist/src/storage/decision-rows.js +72 -0
- package/dist/src/storage/decision-snapshots.d.ts +17 -0
- package/dist/src/storage/decision-snapshots.js +25 -0
- package/dist/src/storage/domain-changes.d.ts +48 -0
- package/dist/src/storage/domain-changes.js +213 -0
- package/dist/src/storage/domain-rows.d.ts +85 -0
- package/dist/src/storage/domain-rows.js +129 -0
- package/dist/src/storage/domain-schema.d.ts +32 -0
- package/dist/src/storage/domain-schema.js +193 -0
- package/dist/src/storage/effect-changes.d.ts +5 -0
- package/dist/src/storage/effect-changes.js +105 -0
- package/dist/src/storage/effect-rows.d.ts +67 -0
- package/dist/src/storage/effect-rows.js +74 -0
- package/dist/src/storage/effect-schema.d.ts +1 -0
- package/dist/src/storage/effect-schema.js +59 -0
- package/dist/src/storage/statements.d.ts +9 -0
- package/dist/src/storage/statements.js +8 -0
- package/dist/src/submission.d.ts +42 -0
- package/dist/src/submission.js +71 -0
- package/dist/src/turn-profile.d.ts +13 -0
- package/dist/src/turn-profile.js +100 -0
- package/dist/src/workflow-admission.d.ts +45 -0
- package/dist/src/workflow-admission.js +151 -0
- package/dist/src/workflow-contracts.d.ts +27 -0
- package/dist/src/workflow-contracts.js +88 -0
- package/dist/src/workflow-declaration.d.ts +11 -0
- package/dist/src/workflow-declaration.js +57 -0
- package/dist/src/workflow-resources.d.ts +8 -0
- package/dist/src/workflow-resources.js +14 -0
- package/dist/src/workflows.d.ts +5 -0
- package/dist/src/workflows.js +3 -0
- package/dist/tools/compile-workflows.d.ts +1 -0
- package/dist/tools/compile-workflows.js +33 -0
- package/dist/tools/self-host-processes.d.ts +10 -0
- package/dist/tools/self-host-processes.js +151 -0
- package/dist/tools/self-host-workflows.d.ts +15 -0
- package/dist/tools/self-host-workflows.js +78 -0
- package/dist/tools/self-host.d.ts +1 -0
- package/dist/tools/self-host.js +261 -0
- package/dist/tools/self-update-host.d.ts +6 -0
- package/dist/tools/self-update-host.js +41 -0
- package/dist/tools/self-update.d.ts +10 -0
- package/dist/tools/self-update.js +105 -0
- package/dist/tools/workflow-manifest.d.ts +3 -0
- package/dist/tools/workflow-manifest.js +34 -0
- package/dist/workflows/develop-prd.d.ts +7 -0
- package/dist/workflows/develop-prd.js +97 -0
- package/dist/workflows/develop-ticket.d.ts +15 -0
- package/dist/workflows/develop-ticket.js +301 -0
- package/dist/workflows/issue-labels.d.ts +14 -0
- package/dist/workflows/issue-labels.js +36 -0
- package/package.json +82 -75
- package/dist/abstract_gpt/index.js +0 -55
- package/dist/cloving_gpt/adapters/Adapter.js +0 -2
- package/dist/cloving_gpt/adapters/azureopenai.js +0 -69
- package/dist/cloving_gpt/adapters/claude.js +0 -128
- package/dist/cloving_gpt/adapters/gemini.js +0 -135
- package/dist/cloving_gpt/adapters/gpt4all.js +0 -29
- package/dist/cloving_gpt/adapters/index.js +0 -2
- package/dist/cloving_gpt/adapters/mistral.js +0 -128
- package/dist/cloving_gpt/adapters/ollama.js +0 -128
- package/dist/cloving_gpt/adapters/openai.js +0 -100
- package/dist/cloving_gpt/index.js +0 -192
- package/dist/commands/analyze.js +0 -47
- package/dist/commands/chat.js +0 -14
- package/dist/commands/check.js +0 -7
- package/dist/commands/commit.js +0 -44
- package/dist/commands/config.js +0 -167
- package/dist/commands/describe.js +0 -235
- package/dist/commands/generate/code.js +0 -21
- package/dist/commands/generate/commit.js +0 -11
- package/dist/commands/generate/context.js +0 -82
- package/dist/commands/generate/docs.js +0 -11
- package/dist/commands/generate/documentation.js +0 -11
- package/dist/commands/generate/fizzbuzz.js +0 -35
- package/dist/commands/generate/init.js +0 -15
- package/dist/commands/generate/review.js +0 -11
- package/dist/commands/generate/sh.js +0 -95
- package/dist/commands/generate/shell.js +0 -11
- package/dist/commands/generate/unit_tests.js +0 -11
- package/dist/commands/init.js +0 -13
- package/dist/commands/models.js +0 -22
- package/dist/commands/project/build.js +0 -88
- package/dist/commands/project/complete.js +0 -12
- package/dist/commands/project/init.js +0 -82
- package/dist/commands/project/plan.js +0 -108
- package/dist/commands/proxy.js +0 -11
- package/dist/commands/review.js +0 -50
- package/dist/commands/tokens.js +0 -75
- package/dist/commands/unit_tests.js +0 -150
- package/dist/commands/update.js +0 -7
- package/dist/file2.js +0 -4
- package/dist/index.js +0 -136
- package/dist/managers/BlockManager.js +0 -120
- package/dist/managers/ChatManager.js +0 -653
- package/dist/managers/ChunkManager.js +0 -32
- package/dist/managers/CodeManager.js +0 -185
- package/dist/managers/CommitManager.js +0 -78
- package/dist/managers/DocsManager.js +0 -88
- package/dist/managers/DocumentationManager.js +0 -114
- package/dist/managers/InitManager.js +0 -230
- package/dist/managers/ProxyManager.js +0 -210
- package/dist/managers/ReviewManager.js +0 -131
- package/dist/managers/ShellManager.js +0 -163
- package/dist/managers/StreamManager.js +0 -308
- package/dist/managers/UnitTestManager.js +0 -243
- package/dist/managers/src/managers/ProxyManager.js +0 -1
- package/dist/newfile.js +0 -2
- package/dist/package.json +0 -86
- package/dist/utils/command_utils.js +0 -384
- package/dist/utils/config_utils.js +0 -249
- package/dist/utils/gitUtils.js +0 -42
- package/dist/utils/git_utils.js +0 -217
- package/dist/utils/modelUtils.js +0 -7
- package/dist/utils/model_utils.js +0 -7
- package/dist/utils/prompt_utils.js +0 -333
- package/dist/utils/prompts/CODEGEN_COULDNT_APPLY.md +0 -5
- package/dist/utils/prompts/CODEGEN_EXAMPLES.md +0 -82
- package/dist/utils/prompts/CODEGEN_INSTRUCTIONS.md +0 -43
- package/dist/utils/prompts/DOCS_INSTRUCTIONS.md +0 -9
- package/dist/utils/prompts/INIT_INSTRUCTIONS.md +0 -132
- package/dist/utils/prompts/REVIEW_INSTRUCTIONS.md +0 -49
- package/dist/utils/prompts/SHELL_INSTRUCTIONS.md +0 -15
- package/dist/utils/prompts/SPECIAL_FILES.md +0 -66
- package/dist/utils/prompts/index.js +0 -27
- package/dist/utils/string_utils.js +0 -505
- package/dist/utils/types.js +0 -2
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
2
|
+
import { findingsOf, scoreOf } from "./github-calls.js";
|
|
3
|
+
import { merge } from "./github-merge.js";
|
|
4
|
+
import { createIssue, discard } from "./github-issue-methods.js";
|
|
5
|
+
import { existingTree, defaultBranch, changeChecked, field, githubTiming, repositoryPath, text, } from "./github-operation.js";
|
|
6
|
+
import { workTree } from "./work-tree.js";
|
|
7
|
+
const triggerText = "@greptileai";
|
|
8
|
+
export const methodReasons = new Set([
|
|
9
|
+
"draft-not-available",
|
|
10
|
+
"invalid-draft",
|
|
11
|
+
"post-uncertain",
|
|
12
|
+
"private-texts-not-set",
|
|
13
|
+
"github-call-failed",
|
|
14
|
+
"git-call-failed",
|
|
15
|
+
"check-failed",
|
|
16
|
+
"merge-conflict",
|
|
17
|
+
"check-required",
|
|
18
|
+
"base-moved",
|
|
19
|
+
"head-not-updated",
|
|
20
|
+
"uncommitted-change",
|
|
21
|
+
"invalid-payload",
|
|
22
|
+
"merged-other-commit",
|
|
23
|
+
"no-change",
|
|
24
|
+
"private-path-in-change",
|
|
25
|
+
"review-not-received",
|
|
26
|
+
"work-tree-not-available",
|
|
27
|
+
]);
|
|
28
|
+
function integer(operation, name) {
|
|
29
|
+
const value = operation.payload[name];
|
|
30
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value < 1)
|
|
31
|
+
throw new Error("invalid-payload");
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
async function prepare(operation) {
|
|
35
|
+
const { settings, calls, target, signal } = operation;
|
|
36
|
+
await calls.git(settings.repository, ["fetch", "--quiet", "origin"]);
|
|
37
|
+
const base = await defaultBranch(operation);
|
|
38
|
+
const tree = await workTree({
|
|
39
|
+
repository: settings.repository,
|
|
40
|
+
worktrees: settings.worktrees,
|
|
41
|
+
target,
|
|
42
|
+
signal,
|
|
43
|
+
base: `origin/${base}`,
|
|
44
|
+
}).catch(() => {
|
|
45
|
+
throw new Error("work-tree-not-available");
|
|
46
|
+
});
|
|
47
|
+
return {
|
|
48
|
+
branch: tree.branch,
|
|
49
|
+
worktree: tree.path,
|
|
50
|
+
base,
|
|
51
|
+
startCommit: tree.startCommit,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function labels(operation, name) {
|
|
55
|
+
const value = operation.payload[name];
|
|
56
|
+
if (!Array.isArray(value))
|
|
57
|
+
throw new Error("invalid-payload");
|
|
58
|
+
return value.map((label) => {
|
|
59
|
+
if (typeof label !== "string" || label.trim() === "")
|
|
60
|
+
throw new Error("invalid-payload");
|
|
61
|
+
return label;
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
async function label(operation) {
|
|
65
|
+
const repository = `${text(operation, "owner")}/${text(operation, "repository")}`;
|
|
66
|
+
const number = integer(operation, "number");
|
|
67
|
+
if (!/^[\w.-]+\/[\w.-]+$/.test(repository) || !Number.isSafeInteger(number))
|
|
68
|
+
throw new Error("invalid-payload");
|
|
69
|
+
const added = labels(operation, "add");
|
|
70
|
+
const removed = labels(operation, "remove");
|
|
71
|
+
for (const name of new Set([...added, ...removed]))
|
|
72
|
+
await operation.calls.gh([
|
|
73
|
+
"label",
|
|
74
|
+
"create",
|
|
75
|
+
name,
|
|
76
|
+
"--repo",
|
|
77
|
+
repository,
|
|
78
|
+
"--color",
|
|
79
|
+
"ededed",
|
|
80
|
+
"--force",
|
|
81
|
+
]);
|
|
82
|
+
await operation.calls.gh([
|
|
83
|
+
"issue",
|
|
84
|
+
"edit",
|
|
85
|
+
String(number),
|
|
86
|
+
"--repo",
|
|
87
|
+
repository,
|
|
88
|
+
...added.flatMap((name) => ["--add-label", name]),
|
|
89
|
+
...removed.flatMap((name) => ["--remove-label", name]),
|
|
90
|
+
]);
|
|
91
|
+
return { number };
|
|
92
|
+
}
|
|
93
|
+
async function pullOf(operation, branch) {
|
|
94
|
+
const listed = JSON.parse(await operation.calls.gh([
|
|
95
|
+
"pr",
|
|
96
|
+
"list",
|
|
97
|
+
"--head",
|
|
98
|
+
branch,
|
|
99
|
+
"--state",
|
|
100
|
+
"open",
|
|
101
|
+
"--json",
|
|
102
|
+
"number,url",
|
|
103
|
+
]));
|
|
104
|
+
const first = Array.isArray(listed) ? listed[0] : undefined;
|
|
105
|
+
if (first === undefined)
|
|
106
|
+
return undefined;
|
|
107
|
+
return {
|
|
108
|
+
number: Number(field(first, "number")),
|
|
109
|
+
url: String(field(first, "url")),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
async function created(operation, place) {
|
|
113
|
+
const printed = await operation.calls.gh([
|
|
114
|
+
"pr",
|
|
115
|
+
"create",
|
|
116
|
+
"--head",
|
|
117
|
+
place.tree.branch,
|
|
118
|
+
"--base",
|
|
119
|
+
place.base,
|
|
120
|
+
"--title",
|
|
121
|
+
text(operation, "title"),
|
|
122
|
+
"--body",
|
|
123
|
+
text(operation, "body"),
|
|
124
|
+
]);
|
|
125
|
+
const url = printed.trim().split("\n").at(-1) ?? "";
|
|
126
|
+
const number = Number(/\/pull\/(\d+)$/.exec(url)?.[1]);
|
|
127
|
+
if (!Number.isInteger(number))
|
|
128
|
+
throw new Error("github-call-failed");
|
|
129
|
+
return { number, url };
|
|
130
|
+
}
|
|
131
|
+
async function openPull(operation) {
|
|
132
|
+
const tree = existingTree(operation);
|
|
133
|
+
const base = await defaultBranch(operation);
|
|
134
|
+
await changeChecked(operation, { tree, base });
|
|
135
|
+
await operation.calls.git(tree.path, [
|
|
136
|
+
"push",
|
|
137
|
+
"--quiet",
|
|
138
|
+
"origin",
|
|
139
|
+
`HEAD:refs/heads/${tree.branch}`,
|
|
140
|
+
]);
|
|
141
|
+
const commit = (await operation.calls.git(tree.path, ["rev-parse", "HEAD"])).trim();
|
|
142
|
+
const pull = (await pullOf(operation, tree.branch)) ??
|
|
143
|
+
(await created(operation, { tree, base }));
|
|
144
|
+
return { number: pull.number, url: pull.url, commit };
|
|
145
|
+
}
|
|
146
|
+
async function reviewed(operation, pull) {
|
|
147
|
+
const { number, commit } = pull;
|
|
148
|
+
const read = async (path) => {
|
|
149
|
+
const value = JSON.parse(await operation.calls.gh(["api", `${repositoryPath}/${path}`]));
|
|
150
|
+
return value;
|
|
151
|
+
};
|
|
152
|
+
const scored = scoreOf(await read(`issues/${String(number)}/comments?per_page=100`), commit);
|
|
153
|
+
if (scored === undefined)
|
|
154
|
+
return undefined;
|
|
155
|
+
const lines = await read(`pulls/${String(number)}/comments?per_page=100`);
|
|
156
|
+
return { number, commit, ...scored, findings: findingsOf(lines, commit) };
|
|
157
|
+
}
|
|
158
|
+
async function waitReview(operation) {
|
|
159
|
+
const pull = {
|
|
160
|
+
number: integer(operation, "number"),
|
|
161
|
+
commit: text(operation, "commit"),
|
|
162
|
+
};
|
|
163
|
+
const timing = operation.settings.timing ?? githubTiming;
|
|
164
|
+
const startedAt = Date.now();
|
|
165
|
+
let triggered = false;
|
|
166
|
+
for (;;) {
|
|
167
|
+
const review = await reviewed(operation, pull).catch(() => undefined);
|
|
168
|
+
if (review !== undefined)
|
|
169
|
+
return review;
|
|
170
|
+
const waited = Date.now() - startedAt;
|
|
171
|
+
if (waited >= timing.limitMilliseconds)
|
|
172
|
+
throw new Error("review-not-received");
|
|
173
|
+
if (!triggered && waited >= timing.triggerMilliseconds) {
|
|
174
|
+
triggered = true;
|
|
175
|
+
await operation.calls
|
|
176
|
+
.gh(["pr", "comment", String(pull.number), "--body", triggerText])
|
|
177
|
+
.catch(() => undefined);
|
|
178
|
+
}
|
|
179
|
+
await delay(timing.pollMilliseconds, undefined, {
|
|
180
|
+
signal: operation.signal,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
export const methods = new Map([
|
|
185
|
+
["prepare", prepare],
|
|
186
|
+
["label", label],
|
|
187
|
+
["create-issue", createIssue],
|
|
188
|
+
["discard", discard],
|
|
189
|
+
["open-pr", openPull],
|
|
190
|
+
["wait-review", waitReview],
|
|
191
|
+
[
|
|
192
|
+
"merge",
|
|
193
|
+
(operation) => merge(operation, {
|
|
194
|
+
number: integer(operation, "number"),
|
|
195
|
+
commit: text(operation, "commit"),
|
|
196
|
+
}),
|
|
197
|
+
],
|
|
198
|
+
]);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { CallSettings, Calls } from "./github-calls.ts";
|
|
2
|
+
export interface GithubTiming {
|
|
3
|
+
readonly pollMilliseconds: number;
|
|
4
|
+
readonly triggerMilliseconds: number;
|
|
5
|
+
readonly limitMilliseconds: number;
|
|
6
|
+
}
|
|
7
|
+
export declare const githubTiming: GithubTiming;
|
|
8
|
+
export interface MethodSettings extends CallSettings {
|
|
9
|
+
readonly worktrees: string;
|
|
10
|
+
readonly timing?: GithubTiming;
|
|
11
|
+
readonly check?: readonly string[];
|
|
12
|
+
}
|
|
13
|
+
export interface Operation {
|
|
14
|
+
readonly settings: MethodSettings;
|
|
15
|
+
readonly calls: Calls;
|
|
16
|
+
readonly target: string;
|
|
17
|
+
readonly payload: Readonly<Record<string, unknown>>;
|
|
18
|
+
readonly signal: AbortSignal;
|
|
19
|
+
readonly folder: string;
|
|
20
|
+
}
|
|
21
|
+
export interface Place {
|
|
22
|
+
readonly path: string;
|
|
23
|
+
readonly branch: string;
|
|
24
|
+
}
|
|
25
|
+
export interface Pull {
|
|
26
|
+
readonly number: number;
|
|
27
|
+
readonly url: string;
|
|
28
|
+
}
|
|
29
|
+
export declare const repositoryPath = "repos/{owner}/{repo}";
|
|
30
|
+
export declare function text(operation: Operation, name: string): string;
|
|
31
|
+
export declare function field(value: unknown, name: string): unknown;
|
|
32
|
+
export declare function existingTree(operation: Operation): Place;
|
|
33
|
+
export declare function removeWorktree(operation: Operation, place: Place): Promise<void>;
|
|
34
|
+
export declare function defaultBranch(operation: Operation): Promise<string>;
|
|
35
|
+
export declare function changeChecked(operation: Operation, place: {
|
|
36
|
+
readonly tree: Place;
|
|
37
|
+
readonly base: string;
|
|
38
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { treePlace } from "./work-tree.js";
|
|
5
|
+
export const githubTiming = {
|
|
6
|
+
pollMilliseconds: 30_000,
|
|
7
|
+
triggerMilliseconds: 300_000,
|
|
8
|
+
limitMilliseconds: 3_600_000,
|
|
9
|
+
};
|
|
10
|
+
export const repositoryPath = "repos/{owner}/{repo}";
|
|
11
|
+
export function text(operation, name) {
|
|
12
|
+
const value = operation.payload[name];
|
|
13
|
+
if (typeof value !== "string" || value === "")
|
|
14
|
+
throw new Error("invalid-payload");
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
17
|
+
export function field(value, name) {
|
|
18
|
+
return Reflect.get(Object(value), name);
|
|
19
|
+
}
|
|
20
|
+
export function existingTree(operation) {
|
|
21
|
+
const place = treePlace({
|
|
22
|
+
worktrees: operation.settings.worktrees,
|
|
23
|
+
target: operation.target,
|
|
24
|
+
});
|
|
25
|
+
if (!existsSync(join(place.path, ".git")))
|
|
26
|
+
throw new Error("work-tree-not-available");
|
|
27
|
+
return place;
|
|
28
|
+
}
|
|
29
|
+
export async function removeWorktree(operation, place) {
|
|
30
|
+
const repository = (parts) => operation.calls.git(operation.settings.repository, parts);
|
|
31
|
+
if (existsSync(join(place.path, ".git")))
|
|
32
|
+
await repository(["worktree", "remove", "--force", place.path]);
|
|
33
|
+
if ((await repository(["branch", "--list", place.branch])).trim() !== "")
|
|
34
|
+
await repository(["branch", "-D", place.branch]);
|
|
35
|
+
}
|
|
36
|
+
export async function defaultBranch(operation) {
|
|
37
|
+
const reference = await operation.calls.git(operation.settings.repository, [
|
|
38
|
+
"symbolic-ref",
|
|
39
|
+
"--short",
|
|
40
|
+
"refs/remotes/origin/HEAD",
|
|
41
|
+
]);
|
|
42
|
+
return reference.trim().replace(/^origin[/]/, "");
|
|
43
|
+
}
|
|
44
|
+
export async function changeChecked(operation, place) {
|
|
45
|
+
const call = (parts) => operation.calls.git(place.tree.path, parts);
|
|
46
|
+
const range = `origin/${place.base}..HEAD`;
|
|
47
|
+
if (Number((await call(["rev-list", "--count", range])).trim()) === 0)
|
|
48
|
+
throw new Error("no-change");
|
|
49
|
+
const change = [
|
|
50
|
+
await call(["diff", `origin/${place.base}...HEAD`]),
|
|
51
|
+
await call(["log", "--format=%B", range]),
|
|
52
|
+
].join("\n");
|
|
53
|
+
const privateTexts = [homedir(), ...(operation.settings.privateTexts ?? [])];
|
|
54
|
+
const lowered = change.toLowerCase();
|
|
55
|
+
if (privateTexts.some((item) => item !== "" && lowered.includes(item.toLowerCase())))
|
|
56
|
+
throw new Error("private-path-in-change");
|
|
57
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Delivery } from "../broker/actor/delivery-intents.ts";
|
|
2
|
+
import { type MethodSettings } from "./github-methods.ts";
|
|
3
|
+
import { type WorkerReport } from "./operation-journal.ts";
|
|
4
|
+
export type { GithubTiming } from "./github-methods.ts";
|
|
5
|
+
export interface GithubWorkerSettings extends MethodSettings {
|
|
6
|
+
readonly journal: string;
|
|
7
|
+
readonly document: (digest: string) => Promise<string | undefined>;
|
|
8
|
+
readonly report: (report: WorkerReport) => Promise<unknown>;
|
|
9
|
+
readonly operationStatus: (operationId: string) => Promise<string | undefined>;
|
|
10
|
+
readonly runStatus: (runId: string) => Promise<string | undefined>;
|
|
11
|
+
}
|
|
12
|
+
export interface GithubWorker extends Delivery {
|
|
13
|
+
readonly stop: NonNullable<Delivery["stop"]>;
|
|
14
|
+
readonly scan: () => Promise<void>;
|
|
15
|
+
readonly close: () => Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
export declare function githubWorker(settings: GithubWorkerSettings): GithubWorker;
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { readdir } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { calls } from "./github-calls.js";
|
|
4
|
+
import { methodReasons, methods, } from "./github-methods.js";
|
|
5
|
+
import { interrupted, located, readRecord, replied, reportOf, writeRecord, } from "./operation-journal.js";
|
|
6
|
+
const worker = "github";
|
|
7
|
+
const closing = "github-worker-closed";
|
|
8
|
+
const endedRuns = new Set([
|
|
9
|
+
"cancelled",
|
|
10
|
+
"failed",
|
|
11
|
+
"completed",
|
|
12
|
+
]);
|
|
13
|
+
const unsettledOperations = new Set([
|
|
14
|
+
"dispatch-pending",
|
|
15
|
+
"running",
|
|
16
|
+
"recovering",
|
|
17
|
+
"blocked",
|
|
18
|
+
]);
|
|
19
|
+
const outcomes = ["completed", "failed", "stopped"];
|
|
20
|
+
function placed(parts, intent) {
|
|
21
|
+
return located(parts.settings.journal, intent.operationId);
|
|
22
|
+
}
|
|
23
|
+
async function reconciled(parts, intent) {
|
|
24
|
+
const { key, folder } = placed(parts, intent);
|
|
25
|
+
const identity = { receipt: key, worker };
|
|
26
|
+
const result = await readRecord(folder, "result.json");
|
|
27
|
+
if (result !== undefined)
|
|
28
|
+
return replied(identity, result);
|
|
29
|
+
if (parts.active.has(key))
|
|
30
|
+
return { kind: "accepted", ...identity };
|
|
31
|
+
if ((await readRecord(folder, "started.json")) === undefined)
|
|
32
|
+
return { kind: "absent" };
|
|
33
|
+
const ending = interrupted("github-call-interrupted");
|
|
34
|
+
await writeRecord(folder, { name: "result.json", value: ending });
|
|
35
|
+
return replied(identity, ending);
|
|
36
|
+
}
|
|
37
|
+
async function outcome(parts, run) {
|
|
38
|
+
const { intent, method, payload, signal } = run;
|
|
39
|
+
const { settings } = parts;
|
|
40
|
+
if (intent.target.startsWith("branch:"))
|
|
41
|
+
return interrupted("branch-target-not-supported");
|
|
42
|
+
try {
|
|
43
|
+
const result = await method({
|
|
44
|
+
settings,
|
|
45
|
+
folder: run.folder,
|
|
46
|
+
calls: calls(settings, signal),
|
|
47
|
+
target: intent.target,
|
|
48
|
+
payload,
|
|
49
|
+
signal,
|
|
50
|
+
});
|
|
51
|
+
return {
|
|
52
|
+
outcome: "completed",
|
|
53
|
+
result: JSON.stringify(result),
|
|
54
|
+
endedAt: new Date().toISOString(),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
if (signal.aborted)
|
|
59
|
+
return { outcome: "stopped", endedAt: new Date().toISOString() };
|
|
60
|
+
const reason = String(Reflect.get(Object(error), "message"));
|
|
61
|
+
const detail = Reflect.get(Object(error), "detail");
|
|
62
|
+
return {
|
|
63
|
+
...interrupted(methodReasons.has(reason) ? reason : "github-call-failed"),
|
|
64
|
+
...(typeof detail === "string" ? { detail } : {}),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async function reported(parts, ending) {
|
|
69
|
+
const { start, recorded } = ending;
|
|
70
|
+
const { key, intent } = start;
|
|
71
|
+
await parts.settings.report(reportOf({ intent, commandId: `github:${key}`, worker }, recorded));
|
|
72
|
+
}
|
|
73
|
+
async function ended(parts, ending) {
|
|
74
|
+
const { start, recorded } = ending;
|
|
75
|
+
await writeRecord(start.folder, { name: "result.json", value: recorded });
|
|
76
|
+
await reported(parts, ending);
|
|
77
|
+
}
|
|
78
|
+
function begun(parts, start) {
|
|
79
|
+
const { key } = start;
|
|
80
|
+
const stopping = new AbortController();
|
|
81
|
+
const concluded = (async () => {
|
|
82
|
+
const recorded = await outcome(parts, {
|
|
83
|
+
...start,
|
|
84
|
+
signal: stopping.signal,
|
|
85
|
+
});
|
|
86
|
+
if (stopping.signal.reason === closing)
|
|
87
|
+
return;
|
|
88
|
+
await ended(parts, { start, recorded });
|
|
89
|
+
})()
|
|
90
|
+
.catch(() => undefined)
|
|
91
|
+
.finally(() => parts.active.delete(key));
|
|
92
|
+
parts.active.set(key, { stopping, concluded });
|
|
93
|
+
}
|
|
94
|
+
function ownIntent(intent) {
|
|
95
|
+
return (intent.capability === worker &&
|
|
96
|
+
intent.method !== undefined &&
|
|
97
|
+
intent.target !== undefined &&
|
|
98
|
+
intent.payload !== undefined &&
|
|
99
|
+
intent.leaseGeneration !== undefined);
|
|
100
|
+
}
|
|
101
|
+
function payloadOf(text) {
|
|
102
|
+
try {
|
|
103
|
+
const value = JSON.parse(text);
|
|
104
|
+
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
105
|
+
? { ...value }
|
|
106
|
+
: undefined;
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function failure(reason) {
|
|
113
|
+
return { kind: "failed", reason };
|
|
114
|
+
}
|
|
115
|
+
async function delivered(parts, intent) {
|
|
116
|
+
if (!ownIntent(intent))
|
|
117
|
+
return failure("unsupported-effect");
|
|
118
|
+
if (intent.target.startsWith("branch:"))
|
|
119
|
+
return failure("branch-target-not-supported");
|
|
120
|
+
const method = methods.get(intent.method);
|
|
121
|
+
if (method === undefined)
|
|
122
|
+
return failure("unsupported-effect");
|
|
123
|
+
const known = await reconciled(parts, intent);
|
|
124
|
+
if (known.kind !== "absent")
|
|
125
|
+
return known;
|
|
126
|
+
const text = await parts.settings.document(intent.payload);
|
|
127
|
+
if (text === undefined)
|
|
128
|
+
return failure("payload-not-available");
|
|
129
|
+
const payload = payloadOf(text);
|
|
130
|
+
if (payload === undefined)
|
|
131
|
+
return failure("invalid-payload");
|
|
132
|
+
const place = placed(parts, intent);
|
|
133
|
+
await writeRecord(place.folder, {
|
|
134
|
+
name: "started.json",
|
|
135
|
+
value: {
|
|
136
|
+
operationId: intent.operationId,
|
|
137
|
+
method: intent.method,
|
|
138
|
+
target: intent.target,
|
|
139
|
+
startedAt: new Date().toISOString(),
|
|
140
|
+
runId: intent.runId,
|
|
141
|
+
inputDigest: intent.inputDigest,
|
|
142
|
+
leaseGeneration: intent.leaseGeneration,
|
|
143
|
+
payloadText: text,
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
begun(parts, { ...place, intent, method, payload });
|
|
147
|
+
return { receipt: place.key, worker };
|
|
148
|
+
}
|
|
149
|
+
async function halted(active, reason) {
|
|
150
|
+
active.stopping.abort(reason);
|
|
151
|
+
await active.concluded;
|
|
152
|
+
}
|
|
153
|
+
async function stopped(parts, intent) {
|
|
154
|
+
const active = parts.active.get(placed(parts, intent).key);
|
|
155
|
+
if (active !== undefined)
|
|
156
|
+
await halted(active, "github-operation-stopped");
|
|
157
|
+
return reconciled(parts, intent);
|
|
158
|
+
}
|
|
159
|
+
function textOf(value, name) {
|
|
160
|
+
const item = Reflect.get(Object(value), name);
|
|
161
|
+
return typeof item === "string" ? item : "";
|
|
162
|
+
}
|
|
163
|
+
function keptOf(value) {
|
|
164
|
+
const leaseGeneration = Reflect.get(Object(value), "leaseGeneration");
|
|
165
|
+
const kept = {
|
|
166
|
+
operationId: textOf(value, "operationId"),
|
|
167
|
+
runId: textOf(value, "runId"),
|
|
168
|
+
inputDigest: textOf(value, "inputDigest"),
|
|
169
|
+
method: textOf(value, "method"),
|
|
170
|
+
target: textOf(value, "target"),
|
|
171
|
+
payloadText: textOf(value, "payloadText"),
|
|
172
|
+
};
|
|
173
|
+
if (typeof leaseGeneration !== "number" || Object.values(kept).includes(""))
|
|
174
|
+
return undefined;
|
|
175
|
+
return { ...kept, leaseGeneration };
|
|
176
|
+
}
|
|
177
|
+
function startOf(parts, value) {
|
|
178
|
+
const kept = keptOf(value);
|
|
179
|
+
if (kept === undefined)
|
|
180
|
+
return undefined;
|
|
181
|
+
const method = methods.get(kept.method);
|
|
182
|
+
const payload = payloadOf(kept.payloadText);
|
|
183
|
+
if (method === undefined || payload === undefined)
|
|
184
|
+
return undefined;
|
|
185
|
+
const place = located(parts.settings.journal, kept.operationId);
|
|
186
|
+
return { ...place, intent: kept, method, payload };
|
|
187
|
+
}
|
|
188
|
+
function recordOf(value) {
|
|
189
|
+
const outcome = outcomes.find((item) => item === textOf(value, "outcome"));
|
|
190
|
+
if (outcome === undefined)
|
|
191
|
+
return undefined;
|
|
192
|
+
const result = Reflect.get(Object(value), "result");
|
|
193
|
+
const reason = Reflect.get(Object(value), "reason");
|
|
194
|
+
return {
|
|
195
|
+
outcome,
|
|
196
|
+
endedAt: textOf(value, "endedAt"),
|
|
197
|
+
...(typeof result === "string" ? { result } : {}),
|
|
198
|
+
...(typeof reason === "string" ? { reason } : {}),
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
async function unsettled(parts, kept) {
|
|
202
|
+
const status = await parts.settings.operationStatus(kept.operationId);
|
|
203
|
+
return unsettledOperations.has(status ?? "");
|
|
204
|
+
}
|
|
205
|
+
async function live(parts, kept) {
|
|
206
|
+
if (!(await unsettled(parts, kept)))
|
|
207
|
+
return false;
|
|
208
|
+
const run = await parts.settings.runStatus(kept.runId);
|
|
209
|
+
return run !== undefined && !endedRuns.has(run);
|
|
210
|
+
}
|
|
211
|
+
async function resent(parts, saved) {
|
|
212
|
+
const recorded = recordOf(saved.result);
|
|
213
|
+
if (recorded === undefined)
|
|
214
|
+
return;
|
|
215
|
+
if (!(await unsettled(parts, saved.start.intent)))
|
|
216
|
+
return;
|
|
217
|
+
await reported(parts, { start: saved.start, recorded });
|
|
218
|
+
}
|
|
219
|
+
async function continued(parts, start) {
|
|
220
|
+
if (await live(parts, start.intent)) {
|
|
221
|
+
begun(parts, start);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
const recorded = {
|
|
225
|
+
outcome: "stopped",
|
|
226
|
+
endedAt: new Date().toISOString(),
|
|
227
|
+
};
|
|
228
|
+
await ended(parts, { start, recorded });
|
|
229
|
+
}
|
|
230
|
+
async function resumed(parts, folder) {
|
|
231
|
+
const started = await readRecord(folder, "started.json");
|
|
232
|
+
if (started === undefined)
|
|
233
|
+
return;
|
|
234
|
+
const result = await readRecord(folder, "result.json");
|
|
235
|
+
const start = startOf(parts, started);
|
|
236
|
+
if (start !== undefined && result !== undefined) {
|
|
237
|
+
await resent(parts, { start, result });
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
if (start !== undefined) {
|
|
241
|
+
await continued(parts, start);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
if (result !== undefined)
|
|
245
|
+
return;
|
|
246
|
+
const ending = interrupted("github-call-interrupted");
|
|
247
|
+
await writeRecord(folder, { name: "result.json", value: ending });
|
|
248
|
+
}
|
|
249
|
+
async function scanned(parts) {
|
|
250
|
+
const { journal } = parts.settings;
|
|
251
|
+
const entries = await readdir(journal).catch(() => []);
|
|
252
|
+
await Promise.all(entries.map((entry) => resumed(parts, join(journal, entry)).catch(() => undefined)));
|
|
253
|
+
}
|
|
254
|
+
function scanning(parts) {
|
|
255
|
+
const scan = scanned(parts).finally(() => {
|
|
256
|
+
parts.scanned.resolve();
|
|
257
|
+
});
|
|
258
|
+
parts.scans.push(scan);
|
|
259
|
+
return scan;
|
|
260
|
+
}
|
|
261
|
+
export function githubWorker(settings) {
|
|
262
|
+
if (settings.gh.length === 0)
|
|
263
|
+
throw new Error("invalid-github-command");
|
|
264
|
+
const parts = {
|
|
265
|
+
settings,
|
|
266
|
+
active: new Map(),
|
|
267
|
+
scanned: Promise.withResolvers(),
|
|
268
|
+
scans: [],
|
|
269
|
+
};
|
|
270
|
+
const after = (call) => parts.scanned.promise.then(call);
|
|
271
|
+
return {
|
|
272
|
+
deliver: (intent) => after(() => delivered(parts, intent)),
|
|
273
|
+
reconcile: (intent) => after(() => reconciled(parts, intent)),
|
|
274
|
+
stop: (intent) => after(() => stopped(parts, intent)),
|
|
275
|
+
scan: () => scanning(parts),
|
|
276
|
+
close: async () => {
|
|
277
|
+
await Promise.all(parts.scans);
|
|
278
|
+
await Promise.all([...parts.active.values()].map((active) => halted(active, closing)));
|
|
279
|
+
},
|
|
280
|
+
};
|
|
281
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface HostPlace {
|
|
2
|
+
readonly directory: string;
|
|
3
|
+
readonly concurrency: number;
|
|
4
|
+
readonly leaseSeconds?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare const ownershipLeaseSeconds = 15;
|
|
7
|
+
export declare function worldDirectory(directory: string): string;
|
|
8
|
+
export declare function hostEnvironment(place: HostPlace): Readonly<Record<string, string>>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
export const ownershipLeaseSeconds = 15;
|
|
3
|
+
export function worldDirectory(directory) {
|
|
4
|
+
return join(directory, "world");
|
|
5
|
+
}
|
|
6
|
+
export function hostEnvironment(place) {
|
|
7
|
+
return {
|
|
8
|
+
WORKFLOW_TARGET_WORLD: "local",
|
|
9
|
+
WORKFLOW_LOCAL_DATA_DIR: worldDirectory(place.directory),
|
|
10
|
+
WORKFLOW_LOCAL_BASE_URL: "http://127.0.0.1:1",
|
|
11
|
+
WORKFLOW_LOCAL_QUEUE_CONCURRENCY: String(place.concurrency),
|
|
12
|
+
WORKFLOW_INLINE_OWNERSHIP_LEASE_SECONDS: String(place.leaseSeconds ?? ownershipLeaseSeconds),
|
|
13
|
+
};
|
|
14
|
+
}
|