@vercel/factory 0.0.14 → 0.0.16
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/CHANGELOG.md +356 -0
- package/README.md +96 -2
- package/dist/agent-routes.d.mts +113 -0
- package/dist/agent-routes.mjs +91 -0
- package/dist/agent-routes.mjs.map +1 -0
- package/dist/api-contracts.d.mts +1768 -0
- package/dist/api-contracts.mjs +119 -0
- package/dist/api-contracts.mjs.map +1 -0
- package/dist/api-images.d.mts +30 -0
- package/dist/api-images.mjs +28 -0
- package/dist/api-images.mjs.map +1 -0
- package/dist/api-task-graph.mjs +57 -0
- package/dist/api-task-graph.mjs.map +1 -0
- package/dist/api.d.mts +111 -216
- package/dist/api.mjs +1063 -99
- package/dist/api.mjs.map +1 -1
- package/dist/approval-access.d.mts +39 -0
- package/dist/approval-access.mjs +62 -0
- package/dist/approval-access.mjs.map +1 -0
- package/dist/approval-contracts.d.mts +698 -0
- package/dist/approval-contracts.mjs +27 -0
- package/dist/approval-contracts.mjs.map +1 -0
- package/dist/approval.d.mts +49 -0
- package/dist/approval.mjs +39 -0
- package/dist/approval.mjs.map +1 -0
- package/dist/blob/artifacts.d.mts +37 -0
- package/dist/blob/artifacts.mjs +45 -0
- package/dist/blob/artifacts.mjs.map +1 -0
- package/dist/blob/index.d.mts +84 -12
- package/dist/blob/index.mjs +179 -45
- package/dist/blob/index.mjs.map +1 -1
- package/dist/budget.d.mts +115 -0
- package/dist/budget.mjs +147 -0
- package/dist/budget.mjs.map +1 -0
- package/dist/budgets.d.mts +4 -0
- package/dist/budgets.mjs +4 -0
- package/dist/build-factory.d.mts +7 -4
- package/dist/build-factory.mjs +2 -1
- package/dist/build-factory.mjs.map +1 -1
- package/dist/change-verification/brief.d.mts +9 -0
- package/dist/change-verification/brief.mjs +13 -0
- package/dist/change-verification/brief.mjs.map +1 -0
- package/dist/change-verification/dispatch.d.mts +37 -0
- package/dist/change-verification/dispatch.mjs +83 -0
- package/dist/change-verification/dispatch.mjs.map +1 -0
- package/dist/change-verification/eve-tool.d.mts +61 -0
- package/dist/change-verification/eve-tool.mjs +89 -0
- package/dist/change-verification/eve-tool.mjs.map +1 -0
- package/dist/change-verification/result.mjs +130 -0
- package/dist/change-verification/result.mjs.map +1 -0
- package/dist/changes/eve-record-change.d.mts +56 -0
- package/dist/changes/eve-record-change.mjs +131 -0
- package/dist/changes/eve-record-change.mjs.map +1 -0
- package/dist/changes/presentation.d.mts +14 -0
- package/dist/changes.d.mts +24 -0
- package/dist/changes.mjs +29 -0
- package/dist/changes.mjs.map +1 -0
- package/dist/client-events.d.mts +25 -0
- package/dist/client-events.mjs +45 -0
- package/dist/client-events.mjs.map +1 -0
- package/dist/client-stream.d.mts +28 -0
- package/dist/client-stream.mjs +210 -0
- package/dist/client-stream.mjs.map +1 -0
- package/dist/client-transcript.d.mts +41 -0
- package/dist/client-transcript.mjs +233 -0
- package/dist/client-transcript.mjs.map +1 -0
- package/dist/client.d.mts +343 -0
- package/dist/client.mjs +366 -0
- package/dist/client.mjs.map +1 -0
- package/dist/code-review/contracts.d.mts +27 -0
- package/dist/code-review/eve-post-review.d.mts +70 -0
- package/dist/code-review/eve-post-review.mjs +195 -0
- package/dist/code-review/eve-post-review.mjs.map +1 -0
- package/dist/code-review/eve-review-comments.d.mts +75 -0
- package/dist/code-review/eve-review-comments.mjs +193 -0
- package/dist/code-review/eve-review-comments.mjs.map +1 -0
- package/dist/code-review/github-contracts.d.mts +10 -0
- package/dist/code-review/github-reporter.d.mts +46 -0
- package/dist/code-review/github-reporter.mjs +262 -0
- package/dist/code-review/github-reporter.mjs.map +1 -0
- package/dist/code-review/preparation.d.mts +34 -0
- package/dist/code-review/preparation.mjs +23 -0
- package/dist/code-review/preparation.mjs.map +1 -0
- package/dist/code-review/stall.d.mts +17 -0
- package/dist/code-review/stall.mjs +30 -0
- package/dist/code-review/stall.mjs.map +1 -0
- package/dist/code-review.d.mts +7 -0
- package/dist/code-review.mjs +5 -0
- package/dist/communication.d.mts +9 -0
- package/dist/communication.mjs +9 -0
- package/dist/connectors/github.d.mts +26 -0
- package/dist/connectors/github.mjs +55 -0
- package/dist/connectors/github.mjs.map +1 -0
- package/dist/connectors/index.d.mts +35 -3
- package/dist/connectors/index.mjs +3 -52
- package/dist/connectors/index.mjs.map +1 -1
- package/dist/connectors/outbox.d.mts +34 -0
- package/dist/connectors/outbox.mjs +50 -0
- package/dist/connectors/outbox.mjs.map +1 -0
- package/dist/connectors/slack-approval-blocks.mjs +136 -0
- package/dist/connectors/slack-approval-blocks.mjs.map +1 -0
- package/dist/connectors/slack-approvals.d.mts +29 -0
- package/dist/connectors/slack-approvals.mjs +346 -0
- package/dist/connectors/slack-approvals.mjs.map +1 -0
- package/dist/connectors/slack.d.mts +35 -52
- package/dist/connectors/slack.mjs +13 -85
- package/dist/connectors/slack.mjs.map +1 -1
- package/dist/deepsec/eve-tool.d.mts +110 -0
- package/dist/deepsec/eve-tool.mjs +166 -0
- package/dist/deepsec/eve-tool.mjs.map +1 -0
- package/dist/deepsec/finding.d.mts +84 -0
- package/dist/deepsec/finding.mjs +56 -0
- package/dist/deepsec/finding.mjs.map +1 -0
- package/dist/deepsec.d.mts +3 -0
- package/dist/delivery-metrics/metrics.d.mts +93 -0
- package/dist/delivery-metrics/metrics.mjs +200 -0
- package/dist/delivery-metrics/metrics.mjs.map +1 -0
- package/dist/delivery-metrics.d.mts +2 -0
- package/dist/delivery-metrics.mjs +2 -0
- package/dist/dispatch.d.mts +152 -0
- package/dist/dispatch.mjs +199 -0
- package/dist/dispatch.mjs.map +1 -0
- package/dist/errors.d.mts +15 -0
- package/dist/errors.mjs +38 -0
- package/dist/errors.mjs.map +1 -0
- package/dist/eve/index.d.mts +209 -1277
- package/dist/eve/index.mjs +312 -1073
- package/dist/eve/index.mjs.map +1 -1
- package/dist/eve/invoke.d.mts +144 -0
- package/dist/eve/invoke.mjs +254 -0
- package/dist/eve/invoke.mjs.map +1 -0
- package/dist/eve/session-client.d.mts +186 -0
- package/dist/eve/session-client.mjs +245 -0
- package/dist/eve/session-client.mjs.map +1 -0
- package/dist/eve/task-execution.d.mts +380 -0
- package/dist/eve/task-execution.mjs +73 -0
- package/dist/eve/task-execution.mjs.map +1 -0
- package/dist/eve/task-session.d.mts +129 -0
- package/dist/eve/task-session.mjs +245 -0
- package/dist/eve/task-session.mjs.map +1 -0
- package/dist/eve/transcript.d.mts +37 -0
- package/dist/eve/transcript.mjs +69 -0
- package/dist/eve/transcript.mjs.map +1 -0
- package/dist/execution-public.d.mts +8 -0
- package/dist/execution-public.mjs +7 -0
- package/dist/execution.d.mts +183 -0
- package/dist/execution.mjs +223 -0
- package/dist/execution.mjs.map +1 -0
- package/dist/finding-remediation/admission.d.mts +53 -0
- package/dist/finding-remediation/admission.mjs +90 -0
- package/dist/finding-remediation/admission.mjs.map +1 -0
- package/dist/finding-remediation/brief.d.mts +14 -0
- package/dist/finding-remediation/brief.mjs +25 -0
- package/dist/finding-remediation/brief.mjs.map +1 -0
- package/dist/finding-remediation/eve-tool.d.mts +29 -0
- package/dist/finding-remediation/eve-tool.mjs +34 -0
- package/dist/finding-remediation/eve-tool.mjs.map +1 -0
- package/dist/findings/fingerprint.d.mts +14 -0
- package/dist/findings/fingerprint.mjs +28 -0
- package/dist/findings/fingerprint.mjs.map +1 -0
- package/dist/findings.d.mts +7 -0
- package/dist/findings.mjs +6 -0
- package/dist/github-app.d.mts +54 -0
- package/dist/github-app.mjs +121 -0
- package/dist/github-app.mjs.map +1 -0
- package/dist/github-publication.d.mts +199 -0
- package/dist/github-publication.mjs +442 -0
- package/dist/github-publication.mjs.map +1 -0
- package/dist/github-transfer.d.mts +81 -0
- package/dist/github-transfer.mjs +273 -0
- package/dist/github-transfer.mjs.map +1 -0
- package/dist/github.d.mts +446 -2
- package/dist/github.mjs +357 -56
- package/dist/github.mjs.map +1 -1
- package/dist/image-input.d.mts +51 -0
- package/dist/image-input.mjs +63 -0
- package/dist/image-input.mjs.map +1 -0
- package/dist/inbox-activity.d.mts +53 -0
- package/dist/inbox-activity.mjs +41 -0
- package/dist/inbox-activity.mjs.map +1 -0
- package/dist/index.d.mts +16 -484
- package/dist/index.mjs +15 -522
- package/dist/intake-contracts.d.mts +55 -0
- package/dist/intake-contracts.mjs +33 -0
- package/dist/intake-contracts.mjs.map +1 -0
- package/dist/integrations/deepsec.d.mts +5 -0
- package/dist/integrations/deepsec.mjs +3 -0
- package/dist/integrations/github.d.mts +11 -0
- package/dist/integrations/github.mjs +9 -0
- package/dist/integrations/slack.d.mts +5 -0
- package/dist/integrations/slack.mjs +5 -0
- package/dist/integrations/vercel.d.mts +5 -0
- package/dist/integrations/vercel.mjs +4 -0
- package/dist/merge-resolution/contracts.d.mts +17 -0
- package/dist/merge-resolution/contracts.mjs +19 -0
- package/dist/merge-resolution/contracts.mjs.map +1 -0
- package/dist/merge-resolution/eve-tools.d.mts +47 -0
- package/dist/merge-resolution/eve-tools.mjs +122 -0
- package/dist/merge-resolution/eve-tools.mjs.map +1 -0
- package/dist/model-settings.d.mts +41 -0
- package/dist/model-settings.mjs +35 -0
- package/dist/model-settings.mjs.map +1 -0
- package/dist/multi-repository-changes/coordination.d.mts +49 -0
- package/dist/multi-repository-changes/coordination.mjs +115 -0
- package/dist/multi-repository-changes/coordination.mjs.map +1 -0
- package/dist/planning/cancellation.mjs +82 -0
- package/dist/planning/cancellation.mjs.map +1 -0
- package/dist/planning/configuration.d.mts +23 -0
- package/dist/planning/configuration.mjs +56 -0
- package/dist/planning/configuration.mjs.map +1 -0
- package/dist/planning/contracts.d.mts +136 -0
- package/dist/planning/contracts.mjs +42 -0
- package/dist/planning/contracts.mjs.map +1 -0
- package/dist/planning/dependencies.mjs +44 -0
- package/dist/planning/dependencies.mjs.map +1 -0
- package/dist/planning/effects.mjs +122 -0
- package/dist/planning/effects.mjs.map +1 -0
- package/dist/planning/reconcile.mjs +279 -0
- package/dist/planning/reconcile.mjs.map +1 -0
- package/dist/planning/runtime.d.mts +27 -0
- package/dist/planning/runtime.mjs +25 -0
- package/dist/planning/runtime.mjs.map +1 -0
- package/dist/planning/state.mjs +92 -0
- package/dist/planning/state.mjs.map +1 -0
- package/dist/planning/turns.mjs +262 -0
- package/dist/planning/turns.mjs.map +1 -0
- package/dist/planning/validation.mjs +106 -0
- package/dist/planning/validation.mjs.map +1 -0
- package/dist/postgres/index.d.mts +48 -1
- package/dist/postgres/index.mjs +45 -3
- package/dist/postgres/index.mjs.map +1 -1
- package/dist/presets/software-development/approval.d.mts +14 -0
- package/dist/presets/software-development/approval.mjs +21 -0
- package/dist/presets/software-development/approval.mjs.map +1 -0
- package/dist/presets/software-development/deepsec-brief.d.mts +8 -0
- package/dist/presets/software-development/deepsec-brief.mjs +14 -0
- package/dist/presets/software-development/deepsec-brief.mjs.map +1 -0
- package/dist/presets/software-development/dispatch.d.mts +56 -0
- package/dist/presets/software-development/dispatch.mjs +67 -0
- package/dist/presets/software-development/dispatch.mjs.map +1 -0
- package/dist/presets/software-development/eve-delegation-policy.d.mts +7 -0
- package/dist/presets/software-development/eve-delegation-policy.mjs +34 -0
- package/dist/presets/software-development/eve-delegation-policy.mjs.map +1 -0
- package/dist/presets/software-development/eve.d.mts +18 -0
- package/dist/presets/software-development/eve.mjs +19 -0
- package/dist/presets/software-development/eve.mjs.map +1 -0
- package/dist/presets/software-development/finish-task-policy.d.mts +7 -0
- package/dist/presets/software-development/finish-task-policy.mjs +9 -0
- package/dist/presets/software-development/finish-task-policy.mjs.map +1 -0
- package/dist/presets/software-development/recovery.d.mts +32 -0
- package/dist/presets/software-development/recovery.mjs +120 -0
- package/dist/presets/software-development/recovery.mjs.map +1 -0
- package/dist/presets/software-development/task-communication.d.mts +24 -0
- package/dist/presets/software-development/task-communication.mjs +157 -0
- package/dist/presets/software-development/task-communication.mjs.map +1 -0
- package/dist/presets/software-development.d.mts +10 -0
- package/dist/presets/software-development.mjs +9 -0
- package/dist/pull-requests/contracts.d.mts +72 -0
- package/dist/pull-requests/eve-fetch.d.mts +57 -0
- package/dist/pull-requests/eve-fetch.mjs +151 -0
- package/dist/pull-requests/eve-fetch.mjs.map +1 -0
- package/dist/pull-requests/github-label-manager.d.mts +27 -0
- package/dist/pull-requests/github-label-manager.mjs +40 -0
- package/dist/pull-requests/github-label-manager.mjs.map +1 -0
- package/dist/pull-requests/github-publisher.d.mts +67 -0
- package/dist/pull-requests/github-publisher.mjs +405 -0
- package/dist/pull-requests/github-publisher.mjs.map +1 -0
- package/dist/pull-requests.d.mts +6 -0
- package/dist/pull-requests.mjs +4 -0
- package/dist/receipts.d.mts +4 -0
- package/dist/receipts.mjs +3 -0
- package/dist/repositories.d.mts +18 -0
- package/dist/repositories.mjs +33 -0
- package/dist/repositories.mjs.map +1 -0
- package/dist/sandbox/command.d.mts +18 -0
- package/dist/sandbox/execution-abort.d.mts +16 -0
- package/dist/sandbox/execution-abort.mjs +49 -0
- package/dist/sandbox/execution-abort.mjs.map +1 -0
- package/dist/sandbox/execution-environment.d.mts +25 -0
- package/dist/sandbox/execution-run-ledger.d.mts +115 -0
- package/dist/sandbox/execution-run-ledger.mjs +209 -0
- package/dist/sandbox/execution-run-ledger.mjs.map +1 -0
- package/dist/sandbox/execution.d.mts +54 -0
- package/dist/sandbox/execution.mjs +228 -0
- package/dist/sandbox/execution.mjs.map +1 -0
- package/dist/sandbox/harness-runner.d.mts +79 -0
- package/dist/sandbox/harness-runner.mjs +162 -0
- package/dist/sandbox/harness-runner.mjs.map +1 -0
- package/dist/sandbox/index.d.mts +10 -0
- package/dist/sandbox/index.mjs +7 -0
- package/dist/sandbox/task-environment.d.mts +50 -0
- package/dist/sandbox/task-environment.mjs +140 -0
- package/dist/sandbox/task-environment.mjs.map +1 -0
- package/dist/sandbox/workspace.d.mts +29 -0
- package/dist/sandbox/workspace.mjs +28 -0
- package/dist/sandbox/workspace.mjs.map +1 -0
- package/dist/schema/agent-route.d.mts +40 -0
- package/dist/schema/agent-route.mjs +33 -0
- package/dist/schema/agent-route.mjs.map +1 -0
- package/dist/schema/answer.d.mts +23 -0
- package/dist/schema/answer.mjs +21 -0
- package/dist/schema/answer.mjs.map +1 -0
- package/dist/schema/budget.d.mts +38 -0
- package/dist/schema/budget.mjs +30 -0
- package/dist/schema/budget.mjs.map +1 -0
- package/dist/schema/catalog.mjs +72 -0
- package/dist/schema/catalog.mjs.map +1 -0
- package/dist/schema/change.d.mts +117 -0
- package/dist/schema/change.mjs +68 -0
- package/dist/schema/change.mjs.map +1 -0
- package/dist/schema/common.d.mts +33 -0
- package/dist/{id-BLIkCVue.mjs → schema/common.mjs} +7 -16
- package/dist/schema/common.mjs.map +1 -0
- package/dist/schema/communication.d.mts +52 -0
- package/dist/{communication-Kd9nU5RP.mjs → schema/communication.mjs} +8 -3
- package/dist/schema/communication.mjs.map +1 -0
- package/dist/schema/execution.d.mts +101 -0
- package/dist/schema/execution.mjs +86 -0
- package/dist/schema/execution.mjs.map +1 -0
- package/dist/schema/factory-config.d.mts +122 -0
- package/dist/schema/factory-config.mjs +90 -0
- package/dist/schema/factory-config.mjs.map +1 -0
- package/dist/schema/finding.d.mts +125 -0
- package/dist/schema/finding.mjs +67 -0
- package/dist/schema/finding.mjs.map +1 -0
- package/dist/schema/id.d.mts +43 -0
- package/dist/schema/id.mjs +32 -0
- package/dist/schema/id.mjs.map +1 -0
- package/dist/schema/outbox.d.mts +240 -0
- package/dist/schema/outbox.mjs +53 -0
- package/dist/schema/outbox.mjs.map +1 -0
- package/dist/schema/question-route.mjs +16 -0
- package/dist/schema/question-route.mjs.map +1 -0
- package/dist/schema/receipt.d.mts +81 -0
- package/dist/schema/receipt.mjs +94 -0
- package/dist/schema/receipt.mjs.map +1 -0
- package/dist/schema/repository.d.mts +30 -0
- package/dist/schema/repository.mjs +29 -0
- package/dist/schema/repository.mjs.map +1 -0
- package/dist/schema/session.d.mts +136 -0
- package/dist/schema/session.mjs +54 -0
- package/dist/schema/session.mjs.map +1 -0
- package/dist/schema/signal.d.mts +105 -0
- package/dist/schema/signal.mjs +81 -0
- package/dist/schema/signal.mjs.map +1 -0
- package/dist/schema/slack-pr-notifications.d.mts +12 -0
- package/dist/schema/slack-pr-notifications.mjs +11 -0
- package/dist/schema/slack-pr-notifications.mjs.map +1 -0
- package/dist/schema/stored-session.mjs +10 -0
- package/dist/schema/stored-session.mjs.map +1 -0
- package/dist/schema/stored-task.mjs +20 -0
- package/dist/schema/stored-task.mjs.map +1 -0
- package/dist/schema/task-effect.d.mts +39 -0
- package/dist/schema/task-effect.mjs +29 -0
- package/dist/schema/task-effect.mjs.map +1 -0
- package/dist/schema/task-graph.d.mts +3173 -0
- package/dist/schema/task-graph.mjs +97 -0
- package/dist/schema/task-graph.mjs.map +1 -0
- package/dist/schema/task-message.d.mts +254 -0
- package/dist/schema/task-message.mjs +189 -0
- package/dist/schema/task-message.mjs.map +1 -0
- package/dist/schema/task.d.mts +273 -0
- package/dist/schema/task.mjs +200 -0
- package/dist/schema/task.mjs.map +1 -0
- package/dist/schema/transcript.d.mts +176 -0
- package/dist/schema/transcript.mjs +87 -0
- package/dist/schema/transcript.mjs.map +1 -0
- package/dist/schema/transitions.d.mts +50 -0
- package/dist/schema/transitions.mjs +303 -0
- package/dist/schema/transitions.mjs.map +1 -0
- package/dist/schema/work.d.mts +150 -0
- package/dist/schema/work.mjs +102 -0
- package/dist/schema/work.mjs.map +1 -0
- package/dist/session-previews.d.mts +76 -0
- package/dist/session-previews.mjs +55 -0
- package/dist/session-previews.mjs.map +1 -0
- package/dist/session-review.d.mts +120 -0
- package/dist/session-review.mjs +79 -0
- package/dist/session-review.mjs.map +1 -0
- package/dist/signal-triage.d.mts +20 -0
- package/dist/signal-triage.mjs +85 -0
- package/dist/signal-triage.mjs.map +1 -0
- package/dist/signals.d.mts +20 -0
- package/dist/signals.mjs +19 -0
- package/dist/signals.mjs.map +1 -0
- package/dist/stall.d.mts +41 -0
- package/dist/stall.mjs +83 -0
- package/dist/stall.mjs.map +1 -0
- package/dist/storage.d.mts +4 -0
- package/dist/storage.mjs +4 -0
- package/dist/store/driver.d.mts +65 -0
- package/dist/store/driver.mjs +42 -0
- package/dist/store/driver.mjs.map +1 -0
- package/dist/store/engine.d.mts +683 -0
- package/dist/store/engine.mjs +2309 -0
- package/dist/store/engine.mjs.map +1 -0
- package/dist/store/memory.d.mts +24 -0
- package/dist/store/memory.mjs +69 -0
- package/dist/store/memory.mjs.map +1 -0
- package/dist/store/slack-pr-notifications.d.mts +44 -0
- package/dist/store/slack-pr-notifications.mjs +121 -0
- package/dist/store/slack-pr-notifications.mjs.map +1 -0
- package/dist/store/task-effects.d.mts +38 -0
- package/dist/store/task-effects.mjs +118 -0
- package/dist/store/task-effects.mjs.map +1 -0
- package/dist/store/task-graphs.d.mts +60 -0
- package/dist/store/task-graphs.mjs +212 -0
- package/dist/store/task-graphs.mjs.map +1 -0
- package/dist/store/task-messages.d.mts +136 -0
- package/dist/store/task-messages.mjs +475 -0
- package/dist/store/task-messages.mjs.map +1 -0
- package/dist/store/task-work.d.mts +180 -0
- package/dist/store/task-work.mjs +137 -0
- package/dist/store/task-work.mjs.map +1 -0
- package/dist/store/work-notifications.d.mts +19 -0
- package/dist/store/work-notifications.mjs +48 -0
- package/dist/store/work-notifications.mjs.map +1 -0
- package/dist/sweep.d.mts +79 -0
- package/dist/sweep.mjs +171 -0
- package/dist/sweep.mjs.map +1 -0
- package/dist/task-communication.d.mts +35 -0
- package/dist/task-communication.mjs +47 -0
- package/dist/task-communication.mjs.map +1 -0
- package/dist/task-graph-view.d.mts +267 -0
- package/dist/task-graph-view.mjs +17 -0
- package/dist/task-graph-view.mjs.map +1 -0
- package/dist/task-message-processing.d.mts +60 -0
- package/dist/task-message-processing.mjs +200 -0
- package/dist/task-message-processing.mjs.map +1 -0
- package/dist/task-protocols.d.mts +80 -0
- package/dist/task-protocols.mjs +47 -0
- package/dist/task-protocols.mjs.map +1 -0
- package/dist/tasks.d.mts +17 -0
- package/dist/tasks.mjs +17 -0
- package/dist/vercel-git.d.mts +53 -0
- package/dist/vercel-git.mjs +344 -0
- package/dist/vercel-git.mjs.map +1 -0
- package/dist/vercel-github-api.d.mts +103 -0
- package/dist/vercel-github-api.mjs +363 -0
- package/dist/vercel-github-api.mjs.map +1 -0
- package/dist/vercel.d.mts +34 -2
- package/dist/vercel.mjs +49 -3
- package/dist/vercel.mjs.map +1 -1
- package/dist/work-triage/eve-tool.d.mts +29 -0
- package/dist/work-triage/eve-tool.mjs +32 -0
- package/dist/work-triage/eve-tool.mjs.map +1 -0
- package/dist/work-triage/find-existing-work.d.mts +32 -0
- package/dist/work-triage/find-existing-work.mjs +31 -0
- package/dist/work-triage/find-existing-work.mjs.map +1 -0
- package/dist/work-triage/github.d.mts +15 -0
- package/dist/work-triage/github.mjs +14 -0
- package/dist/work-triage/github.mjs.map +1 -0
- package/dist/work-triage.d.mts +4 -0
- package/dist/work-triage.mjs +3 -0
- package/dist/workflows.d.mts +146 -0
- package/dist/workflows.mjs +139 -0
- package/dist/workflows.mjs.map +1 -0
- package/dist/workspace-diff-assembly.d.mts +33 -0
- package/dist/workspace-diff-assembly.mjs +95 -0
- package/dist/workspace-diff-assembly.mjs.map +1 -0
- package/dist/workspace-diff.d.mts +90 -0
- package/dist/workspace-diff.mjs +61 -0
- package/dist/workspace-diff.mjs.map +1 -0
- package/dist/workspace-files-git.d.mts +15 -0
- package/dist/workspace-files-git.mjs +61 -0
- package/dist/workspace-files-git.mjs.map +1 -0
- package/dist/workspace-files.d.mts +107 -0
- package/dist/workspace-files.mjs +74 -0
- package/dist/workspace-files.mjs.map +1 -0
- package/dist/workspace-snapshot.d.mts +26 -0
- package/dist/workspace-snapshot.mjs +80 -0
- package/dist/workspace-snapshot.mjs.map +1 -0
- package/docs/getting-started.md +104 -0
- package/docs/index.md +100 -0
- package/docs/recipes/cancellation.md +215 -0
- package/docs/recipes/custom-workflow.md +153 -0
- package/docs/recipes/dependent-tasks.md +207 -0
- package/docs/recipes/eve-agent.md +277 -0
- package/docs/recipes/human-input.md +204 -0
- package/docs/recipes/persistence-recovery.md +268 -0
- package/docs/recipes/retry-recovery.md +241 -0
- package/docs/recipes/task-messaging.md +215 -0
- package/docs/recipes/typed-eve-result.md +161 -0
- package/docs/runtime-integration.md +137 -0
- package/package.json +142 -46
- package/dist/approval-JX2Px9IC.mjs +0 -132
- package/dist/approval-JX2Px9IC.mjs.map +0 -1
- package/dist/budget-DzSiIA4t.mjs +0 -42
- package/dist/budget-DzSiIA4t.mjs.map +0 -1
- package/dist/change-D2U6v7Ek.mjs +0 -554
- package/dist/change-D2U6v7Ek.mjs.map +0 -1
- package/dist/communication-Kd9nU5RP.mjs.map +0 -1
- package/dist/coordination-Cq08hb1l.mjs +0 -76
- package/dist/coordination-Cq08hb1l.mjs.map +0 -1
- package/dist/dispatch-BaZS3PT8.d.mts +0 -76
- package/dist/driver-BC0Mt5KG.d.mts +0 -34
- package/dist/driver-Bbd25rNM.mjs +0 -23
- package/dist/driver-Bbd25rNM.mjs.map +0 -1
- package/dist/engine-DFHU2Pe-.d.mts +0 -781
- package/dist/engine-WaUM2cGA.mjs +0 -1068
- package/dist/engine-WaUM2cGA.mjs.map +0 -1
- package/dist/factory-config-BoRXOw43.mjs +0 -50
- package/dist/factory-config-BoRXOw43.mjs.map +0 -1
- package/dist/factory-config-D2yU3G0c.d.mts +0 -58
- package/dist/github-C5HNBN6p.d.mts +0 -279
- package/dist/id-BLIkCVue.mjs.map +0 -1
- package/dist/index-Bw6hggoH.d.mts +0 -40
- package/dist/index.mjs.map +0 -1
- package/dist/task-CcOyOJ3k.mjs +0 -154
- package/dist/task-CcOyOJ3k.mjs.map +0 -1
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { TaskId } from "../schema/id.mjs";
|
|
2
|
+
import { Repository, RepositorySlug } from "../schema/repository.mjs";
|
|
3
|
+
import { Change } from "../schema/change.mjs";
|
|
4
|
+
import { FactoryStores } from "../store/engine.mjs";
|
|
5
|
+
import { OpenPullRequestInput, PublishedPullRequest, PullRequestPublicationGateInput, PullRequestPublicationGateResult, PullRequestPublicationOwner, PushCheckpointInput, TaskPullRequest } from "./contracts.mjs";
|
|
6
|
+
import { CommittedGitChange, CreatedGitHubPublicationPullRequest, GitHubPublicationClient, GitHubPublicationClientOptions, SandboxGit } from "../github-publication.mjs";
|
|
7
|
+
//#region src/pull-requests/github-publisher.d.ts
|
|
8
|
+
/** Repository credential and client factories required by software publication. */
|
|
9
|
+
interface GitHubPullRequestPublisherOptions {
|
|
10
|
+
tokenForRepository(repositorySlug: RepositorySlug): Promise<string>;
|
|
11
|
+
fetch?: typeof globalThis.fetch;
|
|
12
|
+
createClient?: (options: GitHubPublicationClientOptions) => GitHubPublicationClient;
|
|
13
|
+
/** Publishes the initial commit, branch, and pull request through an application credential boundary. */
|
|
14
|
+
publishPullRequest?: (input: {
|
|
15
|
+
repository: RepositorySlug;
|
|
16
|
+
baseCommit: string;
|
|
17
|
+
tree: CommittedGitChange["tree"];
|
|
18
|
+
commitMessage: string;
|
|
19
|
+
branch: string;
|
|
20
|
+
title: string;
|
|
21
|
+
body: string;
|
|
22
|
+
baseBranch: string;
|
|
23
|
+
draft: boolean;
|
|
24
|
+
}) => Promise<CreatedGitHubPublicationPullRequest & {
|
|
25
|
+
commitSha: string;
|
|
26
|
+
}>;
|
|
27
|
+
}
|
|
28
|
+
/** Task- and session-aware operations for idempotent GitHub pull-request publication. */
|
|
29
|
+
interface GitHubPullRequestPublisher {
|
|
30
|
+
requireTaskPullRequest(input: RequireTaskPullRequestInput): Promise<TaskPullRequest>;
|
|
31
|
+
openPullRequest(input: PublishGitHubPullRequestInput): Promise<PublishedPullRequest>;
|
|
32
|
+
pushCheckpoint(input: PushGitHubCheckpointInput): Promise<PublishedPullRequest>;
|
|
33
|
+
}
|
|
34
|
+
/** Repository and Task whose owned pull request must already exist. */
|
|
35
|
+
interface RequireTaskPullRequestInput {
|
|
36
|
+
repository: Repository;
|
|
37
|
+
taskId: TaskId;
|
|
38
|
+
}
|
|
39
|
+
/** Sandbox checkout and publication request used to open a GitHub pull request. */
|
|
40
|
+
interface PublishGitHubPullRequestInput {
|
|
41
|
+
sandbox: SandboxGit;
|
|
42
|
+
repository: Repository;
|
|
43
|
+
owner: PullRequestPublicationOwner;
|
|
44
|
+
pullRequest: OpenPullRequestInput;
|
|
45
|
+
}
|
|
46
|
+
/** Sandbox checkout and optional linked Change used to publish a checkpoint. */
|
|
47
|
+
interface PushGitHubCheckpointInput {
|
|
48
|
+
sandbox: SandboxGit;
|
|
49
|
+
repository: Repository;
|
|
50
|
+
owner: PullRequestPublicationOwner;
|
|
51
|
+
checkpoint: PushCheckpointInput;
|
|
52
|
+
linkedChange?: Pick<Change, "prNumber" | "prUrl">;
|
|
53
|
+
}
|
|
54
|
+
/** Supplied software workflow for safe Task- and session-owned GitHub publication. */
|
|
55
|
+
declare function createGitHubPullRequestPublisher(options: GitHubPullRequestPublisherOptions): GitHubPullRequestPublisher;
|
|
56
|
+
/** Store and repository lookup dependencies for the pull-request publication gate. */
|
|
57
|
+
interface GitHubPullRequestPublicationGateOptions extends GitHubPullRequestPublisherOptions {
|
|
58
|
+
stores: Pick<FactoryStores, "tasks" | "changes">;
|
|
59
|
+
repositoryForTask(taskId: TaskId): Promise<Repository>;
|
|
60
|
+
}
|
|
61
|
+
/** Validates that one pull request belongs to its exact GitHub Task and Change context. */
|
|
62
|
+
type GitHubPullRequestPublicationGate = (input: PullRequestPublicationGateInput) => Promise<PullRequestPublicationGateResult>;
|
|
63
|
+
/** Fail-closed gate for the pull request a supplied code-change workflow records. */
|
|
64
|
+
declare function createGitHubPullRequestPublicationGate(options: GitHubPullRequestPublicationGateOptions): GitHubPullRequestPublicationGate;
|
|
65
|
+
//#endregion
|
|
66
|
+
export { GitHubPullRequestPublicationGate, GitHubPullRequestPublicationGateOptions, GitHubPullRequestPublisher, GitHubPullRequestPublisherOptions, PublishGitHubPullRequestInput, PushGitHubCheckpointInput, RequireTaskPullRequestInput, createGitHubPullRequestPublicationGate, createGitHubPullRequestPublisher };
|
|
67
|
+
//# sourceMappingURL=github-publisher.d.mts.map
|
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
import { redactedErrorMessage } from "../errors.mjs";
|
|
2
|
+
import { GitHubPublicationApiError, createGitHubPublicationClient, factorySessionBranch, factoryTaskBranch, isSafeGitRef, readCommittedGitChange, runSandboxGit } from "../github-publication.mjs";
|
|
3
|
+
//#region src/pull-requests/github-publisher.ts
|
|
4
|
+
async function clientForRepository(options, repository) {
|
|
5
|
+
const token = await options.tokenForRepository(repository.slug);
|
|
6
|
+
return (options.createClient ?? createGitHubPublicationClient)({
|
|
7
|
+
repository: repository.slug,
|
|
8
|
+
token,
|
|
9
|
+
fetch: options.fetch
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
function repositoryOwner(repository) {
|
|
13
|
+
const owner = repository.slug.split("/")[0];
|
|
14
|
+
if (owner === void 0 || owner === "") throw new Error(`invalid repository slug: ${repository.slug}`);
|
|
15
|
+
return owner;
|
|
16
|
+
}
|
|
17
|
+
async function findOpenPullRequest(client, repository, taskId) {
|
|
18
|
+
const branch = factoryTaskBranch(taskId);
|
|
19
|
+
const pull = (await client.pullRequests({
|
|
20
|
+
state: "open",
|
|
21
|
+
head: `${repositoryOwner(repository)}:${branch}`
|
|
22
|
+
})).find((candidate) => candidate.head.repository === repository.slug);
|
|
23
|
+
if (pull === void 0) throw new Error(`no open pull request on ${branch}; call open_pull_request first`);
|
|
24
|
+
return {
|
|
25
|
+
...pull,
|
|
26
|
+
branch
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
async function findLinkedPullRequest(client, repository, change) {
|
|
30
|
+
const pull = await client.pullRequest({ pullRequestNumber: change.prNumber });
|
|
31
|
+
const branch = pull.head.branch;
|
|
32
|
+
if (pull.state !== "open" || pull.pullRequestUrl !== change.prUrl || pull.head.repository !== repository.slug || !isSafeGitRef(branch)) throw new Error(`Change pull request #${change.prNumber} is not an open same-repository branch`);
|
|
33
|
+
return {
|
|
34
|
+
...pull,
|
|
35
|
+
branch
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
async function createCommit(client, change, message, parent = change.base) {
|
|
39
|
+
const baseCommit = await client.commit({ sha: change.base });
|
|
40
|
+
const tree = await client.createTree({
|
|
41
|
+
baseTreeSha: baseCommit.treeSha,
|
|
42
|
+
entries: change.tree
|
|
43
|
+
});
|
|
44
|
+
return client.createCommit({
|
|
45
|
+
message,
|
|
46
|
+
treeSha: tree,
|
|
47
|
+
parentShas: [parent]
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
async function sessionPullRequest(client, repository, branch) {
|
|
51
|
+
const pull = (await client.pullRequests({
|
|
52
|
+
state: "all",
|
|
53
|
+
head: `${repositoryOwner(repository)}:${branch}`
|
|
54
|
+
})).find((candidate) => candidate.head.branch === branch && candidate.head.repository === repository.slug);
|
|
55
|
+
if (pull !== void 0 && pull.state !== "open") throw new Error("This session's pull request is merged or closed. Start a new session for a new pull request.");
|
|
56
|
+
return pull;
|
|
57
|
+
}
|
|
58
|
+
async function sessionHead(sandbox) {
|
|
59
|
+
const result = await sandbox.run({ command: "git -C repo config --get factory.publishedHead" });
|
|
60
|
+
if (result.exitCode === 1) return "";
|
|
61
|
+
if (result.exitCode !== void 0 && result.exitCode !== 0) throw new Error("Could not read the session's published head.");
|
|
62
|
+
return result.stdout.trim();
|
|
63
|
+
}
|
|
64
|
+
async function rememberSessionHead(sandbox, sha) {
|
|
65
|
+
if (!/^[0-9a-f]{40}$/u.test(sha)) throw new Error("GitHub returned an invalid commit SHA.");
|
|
66
|
+
await runSandboxGit({
|
|
67
|
+
sandbox,
|
|
68
|
+
args: [
|
|
69
|
+
"config",
|
|
70
|
+
"factory.publishedHead",
|
|
71
|
+
sha
|
|
72
|
+
]
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
async function assertSessionCheckout(sandbox, repository) {
|
|
76
|
+
if ((await runSandboxGit({
|
|
77
|
+
sandbox,
|
|
78
|
+
args: [
|
|
79
|
+
"remote",
|
|
80
|
+
"get-url",
|
|
81
|
+
"origin"
|
|
82
|
+
]
|
|
83
|
+
})).trim() !== `https://github.com/${repository.slug}.git`) throw new Error(`sandbox checkout does not match session repository ${repository.slug}`);
|
|
84
|
+
if ((await runSandboxGit({
|
|
85
|
+
sandbox,
|
|
86
|
+
args: ["status", "--porcelain"]
|
|
87
|
+
})).trim() !== "") throw new Error("Commit your changes before publishing the pull request.");
|
|
88
|
+
}
|
|
89
|
+
async function acceptSessionHead(sandbox, client, sha) {
|
|
90
|
+
const expected = await sessionHead(sandbox);
|
|
91
|
+
const commit = await client.commit({ sha });
|
|
92
|
+
const unchanged = commit.treeSha === (await runSandboxGit({
|
|
93
|
+
sandbox,
|
|
94
|
+
args: ["rev-parse", "HEAD^{tree}"]
|
|
95
|
+
})).trim();
|
|
96
|
+
const recovered = unchanged && (expected === "" || commit.parentShas.includes(expected));
|
|
97
|
+
if (expected !== sha && !recovered) throw new Error("The session PR changed since checkout or publication. Refusing to overwrite newer commits; reload its checkout before continuing.");
|
|
98
|
+
await rememberSessionHead(sandbox, sha);
|
|
99
|
+
return unchanged;
|
|
100
|
+
}
|
|
101
|
+
function sessionPublication(pull, branch, changedFiles = 0) {
|
|
102
|
+
return {
|
|
103
|
+
prNumber: pull.pullRequestNumber,
|
|
104
|
+
prUrl: pull.pullRequestUrl,
|
|
105
|
+
branch,
|
|
106
|
+
changedFiles,
|
|
107
|
+
draft: pull.draft
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/** Supplied software workflow for safe Task- and session-owned GitHub publication. */
|
|
111
|
+
function createGitHubPullRequestPublisher(options) {
|
|
112
|
+
async function requireTaskPullRequest(input) {
|
|
113
|
+
const pull = await findOpenPullRequest(await clientForRepository(options, input.repository), input.repository, input.taskId);
|
|
114
|
+
return {
|
|
115
|
+
prNumber: pull.pullRequestNumber,
|
|
116
|
+
prUrl: pull.pullRequestUrl,
|
|
117
|
+
branch: pull.branch
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
async function openSessionPullRequest(sandbox, repository, sessionId, input) {
|
|
121
|
+
const branch = factorySessionBranch(sessionId);
|
|
122
|
+
await assertSessionCheckout(sandbox, repository);
|
|
123
|
+
if (options.publishPullRequest !== void 0) {
|
|
124
|
+
const change = await readCommittedGitChange({
|
|
125
|
+
sandbox,
|
|
126
|
+
repositorySlug: repository.slug
|
|
127
|
+
});
|
|
128
|
+
const published = await options.publishPullRequest({
|
|
129
|
+
repository: repository.slug,
|
|
130
|
+
baseCommit: change.base,
|
|
131
|
+
tree: change.tree,
|
|
132
|
+
commitMessage: change.commitMessage,
|
|
133
|
+
branch,
|
|
134
|
+
title: input.title,
|
|
135
|
+
body: input.body,
|
|
136
|
+
baseBranch: repository.defaultBranch,
|
|
137
|
+
draft: true
|
|
138
|
+
});
|
|
139
|
+
await rememberSessionHead(sandbox, published.commitSha);
|
|
140
|
+
return {
|
|
141
|
+
prNumber: published.pullRequestNumber,
|
|
142
|
+
prUrl: published.pullRequestUrl,
|
|
143
|
+
branch,
|
|
144
|
+
changedFiles: change.changedFiles,
|
|
145
|
+
draft: published.draft
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
const client = await clientForRepository(options, repository);
|
|
149
|
+
const existing = await sessionPullRequest(client, repository, branch);
|
|
150
|
+
if (existing !== void 0) {
|
|
151
|
+
await acceptSessionHead(sandbox, client, existing.head.sha);
|
|
152
|
+
return sessionPublication(existing, branch);
|
|
153
|
+
}
|
|
154
|
+
let sha = await client.branchHead({ branch });
|
|
155
|
+
let changedFiles = 0;
|
|
156
|
+
if (sha === null) {
|
|
157
|
+
const change = await readCommittedGitChange({
|
|
158
|
+
sandbox,
|
|
159
|
+
repositorySlug: repository.slug
|
|
160
|
+
});
|
|
161
|
+
changedFiles = change.changedFiles;
|
|
162
|
+
sha = await createCommit(client, change, `${input.title}\n\n${input.body}`);
|
|
163
|
+
try {
|
|
164
|
+
await client.createBranch({
|
|
165
|
+
branch,
|
|
166
|
+
sha
|
|
167
|
+
});
|
|
168
|
+
} catch (error) {
|
|
169
|
+
if (await client.branchHead({ branch }) !== sha) throw error;
|
|
170
|
+
}
|
|
171
|
+
await rememberSessionHead(sandbox, sha);
|
|
172
|
+
} else await acceptSessionHead(sandbox, client, sha);
|
|
173
|
+
try {
|
|
174
|
+
const pull = await client.createPullRequest({
|
|
175
|
+
title: input.title,
|
|
176
|
+
body: input.body,
|
|
177
|
+
head: branch,
|
|
178
|
+
base: repository.defaultBranch,
|
|
179
|
+
draft: true
|
|
180
|
+
});
|
|
181
|
+
return {
|
|
182
|
+
prNumber: pull.pullRequestNumber,
|
|
183
|
+
prUrl: pull.pullRequestUrl,
|
|
184
|
+
branch,
|
|
185
|
+
changedFiles,
|
|
186
|
+
draft: pull.draft
|
|
187
|
+
};
|
|
188
|
+
} catch (error) {
|
|
189
|
+
const created = await sessionPullRequest(client, repository, branch);
|
|
190
|
+
if (created === void 0) throw error;
|
|
191
|
+
return sessionPublication(created, branch, changedFiles);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
async function openPullRequest(input) {
|
|
195
|
+
if (typeof input.owner !== "string") return openSessionPullRequest(input.sandbox, input.repository, input.owner.sessionId, input.pullRequest);
|
|
196
|
+
const change = await readCommittedGitChange({
|
|
197
|
+
sandbox: input.sandbox,
|
|
198
|
+
repositorySlug: input.repository.slug
|
|
199
|
+
});
|
|
200
|
+
if (options.publishPullRequest !== void 0) {
|
|
201
|
+
const branch = factoryTaskBranch(input.owner);
|
|
202
|
+
const published = await options.publishPullRequest({
|
|
203
|
+
repository: input.repository.slug,
|
|
204
|
+
baseCommit: change.base,
|
|
205
|
+
tree: change.tree,
|
|
206
|
+
commitMessage: change.commitMessage,
|
|
207
|
+
branch,
|
|
208
|
+
title: input.pullRequest.title,
|
|
209
|
+
body: input.pullRequest.body,
|
|
210
|
+
baseBranch: input.repository.defaultBranch,
|
|
211
|
+
draft: true
|
|
212
|
+
});
|
|
213
|
+
return {
|
|
214
|
+
prNumber: published.pullRequestNumber,
|
|
215
|
+
prUrl: published.pullRequestUrl,
|
|
216
|
+
branch,
|
|
217
|
+
changedFiles: change.changedFiles,
|
|
218
|
+
draft: published.draft
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
const client = await clientForRepository(options, input.repository);
|
|
222
|
+
const branch = factoryTaskBranch(input.owner);
|
|
223
|
+
const existing = (await client.pullRequests({
|
|
224
|
+
state: "all",
|
|
225
|
+
head: `${repositoryOwner(input.repository)}:${branch}`
|
|
226
|
+
})).find((pull) => pull.head.branch === branch && pull.head.repository === input.repository.slug);
|
|
227
|
+
if (existing !== void 0) {
|
|
228
|
+
if (existing.state !== "open") throw new Error("This Task's pull request is merged or closed. Start new work for a new pull request.");
|
|
229
|
+
return {
|
|
230
|
+
prNumber: existing.pullRequestNumber,
|
|
231
|
+
prUrl: existing.pullRequestUrl,
|
|
232
|
+
branch,
|
|
233
|
+
changedFiles: 0,
|
|
234
|
+
draft: existing.draft
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
const sha = await createCommit(client, change, `${input.pullRequest.title}\n\n${input.pullRequest.body}`);
|
|
238
|
+
await client.createBranch({
|
|
239
|
+
branch,
|
|
240
|
+
sha
|
|
241
|
+
});
|
|
242
|
+
const pull = await client.createPullRequest({
|
|
243
|
+
title: input.pullRequest.title,
|
|
244
|
+
body: input.pullRequest.body,
|
|
245
|
+
head: branch,
|
|
246
|
+
base: input.repository.defaultBranch,
|
|
247
|
+
draft: true
|
|
248
|
+
});
|
|
249
|
+
return {
|
|
250
|
+
prNumber: pull.pullRequestNumber,
|
|
251
|
+
prUrl: pull.pullRequestUrl,
|
|
252
|
+
branch,
|
|
253
|
+
changedFiles: change.changedFiles,
|
|
254
|
+
draft: pull.draft
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
async function pushSessionCheckpoint(sandbox, repository, sessionId, input) {
|
|
258
|
+
const branch = factorySessionBranch(sessionId);
|
|
259
|
+
await assertSessionCheckout(sandbox, repository);
|
|
260
|
+
const client = await clientForRepository(options, repository);
|
|
261
|
+
const pull = await sessionPullRequest(client, repository, branch);
|
|
262
|
+
if (pull === void 0) throw new Error(`no open pull request on ${branch}; call open_pull_request first`);
|
|
263
|
+
const unchanged = await acceptSessionHead(sandbox, client, pull.head.sha);
|
|
264
|
+
let changedFiles = 0;
|
|
265
|
+
if (!unchanged) {
|
|
266
|
+
const change = await readCommittedGitChange({
|
|
267
|
+
sandbox,
|
|
268
|
+
repositorySlug: repository.slug,
|
|
269
|
+
allowEmpty: true
|
|
270
|
+
});
|
|
271
|
+
changedFiles = change.changedFiles;
|
|
272
|
+
const sha = await createCommit(client, change, `${pull.title}\n\n${pull.body ?? ""}`, pull.head.sha);
|
|
273
|
+
await client.updateBranch({
|
|
274
|
+
branch,
|
|
275
|
+
sha,
|
|
276
|
+
force: false
|
|
277
|
+
});
|
|
278
|
+
await rememberSessionHead(sandbox, sha);
|
|
279
|
+
}
|
|
280
|
+
const published = sessionPublication(pull, branch, changedFiles);
|
|
281
|
+
if (input.ready && published.draft) {
|
|
282
|
+
await client.markReady({ nodeId: pull.nodeId });
|
|
283
|
+
published.draft = false;
|
|
284
|
+
}
|
|
285
|
+
return published;
|
|
286
|
+
}
|
|
287
|
+
async function pushCheckpoint(input) {
|
|
288
|
+
if (typeof input.owner !== "string") return pushSessionCheckpoint(input.sandbox, input.repository, input.owner.sessionId, input.checkpoint);
|
|
289
|
+
const client = await clientForRepository(options, input.repository);
|
|
290
|
+
const pull = input.linkedChange === void 0 ? await findOpenPullRequest(client, input.repository, input.owner) : await findLinkedPullRequest(client, input.repository, input.linkedChange);
|
|
291
|
+
const change = await readCommittedGitChange({
|
|
292
|
+
sandbox: input.sandbox,
|
|
293
|
+
repositorySlug: input.repository.slug,
|
|
294
|
+
baseRef: input.linkedChange === void 0 ? "origin/HEAD" : `refs/remotes/origin/pr-${input.linkedChange.prNumber}`
|
|
295
|
+
});
|
|
296
|
+
if (input.linkedChange !== void 0 && change.base !== pull.head.sha) throw new Error(`pull request #${input.linkedChange.prNumber} changed since it was fetched; fetch it again`);
|
|
297
|
+
const sha = await createCommit(client, change, `${pull.title}\n\n${pull.body ?? ""}`);
|
|
298
|
+
await client.updateBranch({
|
|
299
|
+
branch: pull.branch,
|
|
300
|
+
sha,
|
|
301
|
+
force: input.linkedChange === void 0
|
|
302
|
+
});
|
|
303
|
+
let draft = pull.draft;
|
|
304
|
+
if (input.checkpoint.ready && draft) {
|
|
305
|
+
await client.markReady({ nodeId: pull.nodeId });
|
|
306
|
+
draft = false;
|
|
307
|
+
}
|
|
308
|
+
return {
|
|
309
|
+
prNumber: pull.pullRequestNumber,
|
|
310
|
+
prUrl: pull.pullRequestUrl,
|
|
311
|
+
branch: pull.branch,
|
|
312
|
+
changedFiles: change.changedFiles,
|
|
313
|
+
draft
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
return Object.freeze({
|
|
317
|
+
requireTaskPullRequest,
|
|
318
|
+
openPullRequest,
|
|
319
|
+
pushCheckpoint
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
/** Fail-closed gate for the pull request a supplied code-change workflow records. */
|
|
323
|
+
function createGitHubPullRequestPublicationGate(options) {
|
|
324
|
+
return async (input) => {
|
|
325
|
+
let repository;
|
|
326
|
+
let linkedChange;
|
|
327
|
+
try {
|
|
328
|
+
repository = await options.repositoryForTask(input.taskId);
|
|
329
|
+
if (repository.id !== input.repositoryId) return {
|
|
330
|
+
ok: false,
|
|
331
|
+
code: "repository_mismatch",
|
|
332
|
+
reason: "repositoryId does not match the task repository"
|
|
333
|
+
};
|
|
334
|
+
const task = await options.stores.tasks.get(input.taskId);
|
|
335
|
+
if (task === null) return {
|
|
336
|
+
ok: false,
|
|
337
|
+
code: "task_not_found",
|
|
338
|
+
reason: `task ${input.taskId} does not exist`
|
|
339
|
+
};
|
|
340
|
+
linkedChange = task.changeId === void 0 ? null : await options.stores.changes.get(task.changeId);
|
|
341
|
+
if (task.changeId !== void 0 && linkedChange === null) return {
|
|
342
|
+
ok: false,
|
|
343
|
+
code: "change_not_found",
|
|
344
|
+
reason: `change ${task.changeId} does not exist`
|
|
345
|
+
};
|
|
346
|
+
if (linkedChange !== null && (linkedChange.repositoryId !== repository.id || linkedChange.prNumber !== input.prNumber || linkedChange.prUrl !== input.prUrl)) return {
|
|
347
|
+
ok: false,
|
|
348
|
+
code: "linked_change_mismatch",
|
|
349
|
+
reason: "pull request does not match the Change linked to this task"
|
|
350
|
+
};
|
|
351
|
+
} catch (error) {
|
|
352
|
+
return {
|
|
353
|
+
ok: false,
|
|
354
|
+
code: "repository_lookup_failed",
|
|
355
|
+
reason: redactedErrorMessage(error)
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
let client;
|
|
359
|
+
try {
|
|
360
|
+
client = await clientForRepository(options, repository);
|
|
361
|
+
} catch (error) {
|
|
362
|
+
return {
|
|
363
|
+
ok: false,
|
|
364
|
+
code: "authentication_failed",
|
|
365
|
+
reason: `could not authenticate to GitHub: ${redactedErrorMessage(error)}`
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
let pull;
|
|
369
|
+
try {
|
|
370
|
+
pull = await client.pullRequest({ pullRequestNumber: input.prNumber });
|
|
371
|
+
} catch (error) {
|
|
372
|
+
return {
|
|
373
|
+
ok: false,
|
|
374
|
+
code: error instanceof GitHubPublicationApiError && error.status === 404 ? "pull_request_not_found" : "pull_request_lookup_failed",
|
|
375
|
+
reason: error instanceof GitHubPublicationApiError && error.status === 404 ? `pull request #${input.prNumber} does not exist on ${repository.slug}` : `could not verify pull request #${input.prNumber} on ${repository.slug}`
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
if (pull.pullRequestUrl !== input.prUrl) return {
|
|
379
|
+
ok: false,
|
|
380
|
+
code: "pull_request_url_mismatch",
|
|
381
|
+
reason: `prUrl does not match pull request #${input.prNumber} on ${repository.slug}`
|
|
382
|
+
};
|
|
383
|
+
if (pull.state !== "open") return {
|
|
384
|
+
ok: false,
|
|
385
|
+
code: "pull_request_closed",
|
|
386
|
+
reason: `pull request #${input.prNumber} is not open`
|
|
387
|
+
};
|
|
388
|
+
const branch = factoryTaskBranch(input.taskId);
|
|
389
|
+
if (pull.head.repository !== repository.slug || linkedChange === null && pull.head.branch !== branch) return {
|
|
390
|
+
ok: false,
|
|
391
|
+
code: "pull_request_branch_mismatch",
|
|
392
|
+
reason: linkedChange === null ? `pull request #${input.prNumber} is not on this task's branch ${branch}` : `pull request #${input.prNumber} is not a same-repository branch`
|
|
393
|
+
};
|
|
394
|
+
if (pull.draft) return {
|
|
395
|
+
ok: false,
|
|
396
|
+
code: "pull_request_draft",
|
|
397
|
+
reason: `pull request #${input.prNumber} is still a draft; call push_checkpoint with ready: true first`
|
|
398
|
+
};
|
|
399
|
+
return { ok: true };
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
//#endregion
|
|
403
|
+
export { createGitHubPullRequestPublicationGate, createGitHubPullRequestPublisher };
|
|
404
|
+
|
|
405
|
+
//# sourceMappingURL=github-publisher.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-publisher.mjs","names":[],"sources":["../../src/pull-requests/github-publisher.ts"],"sourcesContent":["import { redactedErrorMessage } from \"../errors\";\nimport {\n createGitHubPublicationClient,\n factorySessionBranch,\n factoryTaskBranch,\n GitHubPublicationApiError,\n isSafeGitRef,\n readCommittedGitChange,\n runSandboxGit,\n type CommittedGitChange,\n type CreatedGitHubPublicationPullRequest,\n type GitHubPublicationClient,\n type GitHubPublicationClientOptions,\n type GitHubPublicationPullRequest,\n type SandboxGit,\n} from \"../github-publication\";\nimport type { Change } from \"../schema/change\";\nimport type { TaskId } from \"../schema/id\";\nimport type { Repository, RepositorySlug } from \"../schema/repository\";\nimport type { AgentSessionId } from \"../schema/session\";\nimport type { FactoryStores } from \"../store/engine\";\nimport type {\n OpenPullRequestInput,\n PublishedPullRequest,\n PullRequestPublicationGateInput,\n PullRequestPublicationGateResult,\n PullRequestPublicationOwner,\n PushCheckpointInput,\n TaskPullRequest,\n} from \"./contracts\";\n\n/** Repository credential and client factories required by software publication. */\nexport interface GitHubPullRequestPublisherOptions {\n tokenForRepository(repositorySlug: RepositorySlug): Promise<string>;\n fetch?: typeof globalThis.fetch;\n createClient?: (options: GitHubPublicationClientOptions) => GitHubPublicationClient;\n /** Publishes the initial commit, branch, and pull request through an application credential boundary. */\n publishPullRequest?: (input: {\n repository: RepositorySlug;\n baseCommit: string;\n tree: CommittedGitChange[\"tree\"];\n commitMessage: string;\n branch: string;\n title: string;\n body: string;\n baseBranch: string;\n draft: boolean;\n }) => Promise<CreatedGitHubPublicationPullRequest & { commitSha: string }>;\n}\n\n/** Task- and session-aware operations for idempotent GitHub pull-request publication. */\nexport interface GitHubPullRequestPublisher {\n requireTaskPullRequest(input: RequireTaskPullRequestInput): Promise<TaskPullRequest>;\n openPullRequest(input: PublishGitHubPullRequestInput): Promise<PublishedPullRequest>;\n pushCheckpoint(input: PushGitHubCheckpointInput): Promise<PublishedPullRequest>;\n}\n\n/** Repository and Task whose owned pull request must already exist. */\nexport interface RequireTaskPullRequestInput {\n repository: Repository;\n taskId: TaskId;\n}\n\n/** Sandbox checkout and publication request used to open a GitHub pull request. */\nexport interface PublishGitHubPullRequestInput {\n sandbox: SandboxGit;\n repository: Repository;\n owner: PullRequestPublicationOwner;\n pullRequest: OpenPullRequestInput;\n}\n\n/** Sandbox checkout and optional linked Change used to publish a checkpoint. */\nexport interface PushGitHubCheckpointInput {\n sandbox: SandboxGit;\n repository: Repository;\n owner: PullRequestPublicationOwner;\n checkpoint: PushCheckpointInput;\n linkedChange?: Pick<Change, \"prNumber\" | \"prUrl\">;\n}\n\nasync function clientForRepository(\n options: GitHubPullRequestPublisherOptions,\n repository: Repository,\n): Promise<GitHubPublicationClient> {\n const token = await options.tokenForRepository(repository.slug);\n return (options.createClient ?? createGitHubPublicationClient)({\n repository: repository.slug,\n token,\n fetch: options.fetch,\n });\n}\n\nfunction repositoryOwner(repository: Repository): string {\n const owner = repository.slug.split(\"/\")[0];\n if (owner === undefined || owner === \"\") {\n throw new Error(`invalid repository slug: ${repository.slug}`);\n }\n return owner;\n}\n\nasync function findOpenPullRequest(\n client: GitHubPublicationClient,\n repository: Repository,\n taskId: TaskId,\n): Promise<GitHubPublicationPullRequest & { branch: string }> {\n const branch = factoryTaskBranch(taskId);\n const open = await client.pullRequests({\n state: \"open\",\n head: `${repositoryOwner(repository)}:${branch}`,\n });\n const pull = open.find((candidate) => candidate.head.repository === repository.slug);\n if (pull === undefined) {\n throw new Error(`no open pull request on ${branch}; call open_pull_request first`);\n }\n return { ...pull, branch };\n}\n\nasync function findLinkedPullRequest(\n client: GitHubPublicationClient,\n repository: Repository,\n change: Pick<Change, \"prNumber\" | \"prUrl\">,\n): Promise<GitHubPublicationPullRequest & { branch: string }> {\n const pull = await client.pullRequest({ pullRequestNumber: change.prNumber });\n const branch = pull.head.branch;\n if (\n pull.state !== \"open\" ||\n pull.pullRequestUrl !== change.prUrl ||\n pull.head.repository !== repository.slug ||\n !isSafeGitRef(branch)\n ) {\n throw new Error(\n `Change pull request #${change.prNumber} is not an open same-repository branch`,\n );\n }\n return { ...pull, branch };\n}\n\nasync function createCommit(\n client: GitHubPublicationClient,\n change: CommittedGitChange,\n message: string,\n parent = change.base,\n): Promise<string> {\n const baseCommit = await client.commit({ sha: change.base });\n const tree = await client.createTree({ baseTreeSha: baseCommit.treeSha, entries: change.tree });\n return client.createCommit({ message, treeSha: tree, parentShas: [parent] });\n}\n\nasync function sessionPullRequest(\n client: GitHubPublicationClient,\n repository: Repository,\n branch: string,\n): Promise<GitHubPublicationPullRequest | undefined> {\n const pulls = await client.pullRequests({\n state: \"all\",\n head: `${repositoryOwner(repository)}:${branch}`,\n });\n const pull = pulls.find(\n (candidate) =>\n candidate.head.branch === branch && candidate.head.repository === repository.slug,\n );\n if (pull !== undefined && pull.state !== \"open\") {\n throw new Error(\n \"This session's pull request is merged or closed. Start a new session for a new pull request.\",\n );\n }\n return pull;\n}\n\nasync function sessionHead(sandbox: SandboxGit): Promise<string> {\n const result = await sandbox.run({ command: \"git -C repo config --get factory.publishedHead\" });\n if (result.exitCode === 1) return \"\";\n if (result.exitCode !== undefined && result.exitCode !== 0) {\n throw new Error(\"Could not read the session's published head.\");\n }\n return result.stdout.trim();\n}\n\nasync function rememberSessionHead(sandbox: SandboxGit, sha: string): Promise<void> {\n if (!/^[0-9a-f]{40}$/u.test(sha)) throw new Error(\"GitHub returned an invalid commit SHA.\");\n await runSandboxGit({ sandbox, args: [\"config\", \"factory.publishedHead\", sha] });\n}\n\nasync function assertSessionCheckout(sandbox: SandboxGit, repository: Repository): Promise<void> {\n if (\n (await runSandboxGit({ sandbox, args: [\"remote\", \"get-url\", \"origin\"] })).trim() !==\n `https://github.com/${repository.slug}.git`\n ) {\n throw new Error(`sandbox checkout does not match session repository ${repository.slug}`);\n }\n if ((await runSandboxGit({ sandbox, args: [\"status\", \"--porcelain\"] })).trim() !== \"\") {\n throw new Error(\"Commit your changes before publishing the pull request.\");\n }\n}\n\nasync function acceptSessionHead(\n sandbox: SandboxGit,\n client: GitHubPublicationClient,\n sha: string,\n): Promise<boolean> {\n const expected = await sessionHead(sandbox);\n const commit = await client.commit({ sha });\n const unchanged =\n commit.treeSha ===\n (await runSandboxGit({ sandbox, args: [\"rev-parse\", \"HEAD^{tree}\"] })).trim();\n const recovered = unchanged && (expected === \"\" || commit.parentShas.includes(expected));\n if (expected !== sha && !recovered) {\n throw new Error(\n \"The session PR changed since checkout or publication. Refusing to overwrite newer commits; reload its checkout before continuing.\",\n );\n }\n await rememberSessionHead(sandbox, sha);\n return unchanged;\n}\n\nfunction sessionPublication(\n pull: Pick<GitHubPublicationPullRequest, \"pullRequestNumber\" | \"pullRequestUrl\" | \"draft\">,\n branch: string,\n changedFiles = 0,\n): PublishedPullRequest {\n return {\n prNumber: pull.pullRequestNumber,\n prUrl: pull.pullRequestUrl,\n branch,\n changedFiles,\n draft: pull.draft,\n };\n}\n\n/** Supplied software workflow for safe Task- and session-owned GitHub publication. */\nexport function createGitHubPullRequestPublisher(\n options: GitHubPullRequestPublisherOptions,\n): GitHubPullRequestPublisher {\n async function requireTaskPullRequest(\n input: RequireTaskPullRequestInput,\n ): Promise<TaskPullRequest> {\n const client = await clientForRepository(options, input.repository);\n const pull = await findOpenPullRequest(client, input.repository, input.taskId);\n return {\n prNumber: pull.pullRequestNumber,\n prUrl: pull.pullRequestUrl,\n branch: pull.branch,\n };\n }\n\n async function openSessionPullRequest(\n sandbox: SandboxGit,\n repository: Repository,\n sessionId: AgentSessionId,\n input: OpenPullRequestInput,\n ): Promise<PublishedPullRequest> {\n const branch = factorySessionBranch(sessionId);\n await assertSessionCheckout(sandbox, repository);\n if (options.publishPullRequest !== undefined) {\n const change = await readCommittedGitChange({ sandbox, repositorySlug: repository.slug });\n const published = await options.publishPullRequest({\n repository: repository.slug,\n baseCommit: change.base,\n tree: change.tree,\n commitMessage: change.commitMessage,\n branch,\n title: input.title,\n body: input.body,\n baseBranch: repository.defaultBranch,\n draft: true,\n });\n await rememberSessionHead(sandbox, published.commitSha);\n return {\n prNumber: published.pullRequestNumber,\n prUrl: published.pullRequestUrl,\n branch,\n changedFiles: change.changedFiles,\n draft: published.draft,\n };\n }\n const client = await clientForRepository(options, repository);\n const existing = await sessionPullRequest(client, repository, branch);\n if (existing !== undefined) {\n await acceptSessionHead(sandbox, client, existing.head.sha);\n return sessionPublication(existing, branch);\n }\n\n let sha = await client.branchHead({ branch });\n let changedFiles = 0;\n if (sha === null) {\n const change = await readCommittedGitChange({ sandbox, repositorySlug: repository.slug });\n changedFiles = change.changedFiles;\n sha = await createCommit(client, change, `${input.title}\\n\\n${input.body}`);\n try {\n await client.createBranch({ branch, sha });\n } catch (error) {\n if ((await client.branchHead({ branch })) !== sha) throw error;\n }\n await rememberSessionHead(sandbox, sha);\n } else {\n await acceptSessionHead(sandbox, client, sha);\n }\n try {\n const pull = await client.createPullRequest({\n title: input.title,\n body: input.body,\n head: branch,\n base: repository.defaultBranch,\n draft: true,\n });\n return {\n prNumber: pull.pullRequestNumber,\n prUrl: pull.pullRequestUrl,\n branch,\n changedFiles,\n draft: pull.draft,\n };\n } catch (error) {\n const created = await sessionPullRequest(client, repository, branch);\n if (created === undefined) throw error;\n return sessionPublication(created, branch, changedFiles);\n }\n }\n\n async function openPullRequest(\n input: PublishGitHubPullRequestInput,\n ): Promise<PublishedPullRequest> {\n if (typeof input.owner !== \"string\") {\n return openSessionPullRequest(\n input.sandbox,\n input.repository,\n input.owner.sessionId,\n input.pullRequest,\n );\n }\n const change = await readCommittedGitChange({\n sandbox: input.sandbox,\n repositorySlug: input.repository.slug,\n });\n if (options.publishPullRequest !== undefined) {\n const branch = factoryTaskBranch(input.owner);\n const published = await options.publishPullRequest({\n repository: input.repository.slug,\n baseCommit: change.base,\n tree: change.tree,\n commitMessage: change.commitMessage,\n branch,\n title: input.pullRequest.title,\n body: input.pullRequest.body,\n baseBranch: input.repository.defaultBranch,\n draft: true,\n });\n return {\n prNumber: published.pullRequestNumber,\n prUrl: published.pullRequestUrl,\n branch,\n changedFiles: change.changedFiles,\n draft: published.draft,\n };\n }\n const client = await clientForRepository(options, input.repository);\n const branch = factoryTaskBranch(input.owner);\n const existing = (\n await client.pullRequests({\n state: \"all\",\n head: `${repositoryOwner(input.repository)}:${branch}`,\n })\n ).find((pull) => pull.head.branch === branch && pull.head.repository === input.repository.slug);\n if (existing !== undefined) {\n if (existing.state !== \"open\")\n throw new Error(\n \"This Task's pull request is merged or closed. Start new work for a new pull request.\",\n );\n return {\n prNumber: existing.pullRequestNumber,\n prUrl: existing.pullRequestUrl,\n branch,\n changedFiles: 0,\n draft: existing.draft,\n };\n }\n const sha = await createCommit(\n client,\n change,\n `${input.pullRequest.title}\\n\\n${input.pullRequest.body}`,\n );\n await client.createBranch({ branch, sha });\n const pull = await client.createPullRequest({\n title: input.pullRequest.title,\n body: input.pullRequest.body,\n head: branch,\n base: input.repository.defaultBranch,\n draft: true,\n });\n return {\n prNumber: pull.pullRequestNumber,\n prUrl: pull.pullRequestUrl,\n branch,\n changedFiles: change.changedFiles,\n draft: pull.draft,\n };\n }\n\n async function pushSessionCheckpoint(\n sandbox: SandboxGit,\n repository: Repository,\n sessionId: AgentSessionId,\n input: PushCheckpointInput,\n ): Promise<PublishedPullRequest> {\n const branch = factorySessionBranch(sessionId);\n await assertSessionCheckout(sandbox, repository);\n const client = await clientForRepository(options, repository);\n const pull = await sessionPullRequest(client, repository, branch);\n if (pull === undefined) {\n throw new Error(`no open pull request on ${branch}; call open_pull_request first`);\n }\n const unchanged = await acceptSessionHead(sandbox, client, pull.head.sha);\n let changedFiles = 0;\n if (!unchanged) {\n const change = await readCommittedGitChange({\n sandbox,\n repositorySlug: repository.slug,\n allowEmpty: true,\n });\n changedFiles = change.changedFiles;\n const sha = await createCommit(\n client,\n change,\n `${pull.title}\\n\\n${pull.body ?? \"\"}`,\n pull.head.sha,\n );\n await client.updateBranch({ branch, sha, force: false });\n await rememberSessionHead(sandbox, sha);\n }\n const published = sessionPublication(pull, branch, changedFiles);\n if (input.ready && published.draft) {\n await client.markReady({ nodeId: pull.nodeId });\n published.draft = false;\n }\n return published;\n }\n\n async function pushCheckpoint(input: PushGitHubCheckpointInput): Promise<PublishedPullRequest> {\n if (typeof input.owner !== \"string\") {\n return pushSessionCheckpoint(\n input.sandbox,\n input.repository,\n input.owner.sessionId,\n input.checkpoint,\n );\n }\n const client = await clientForRepository(options, input.repository);\n const pull =\n input.linkedChange === undefined\n ? await findOpenPullRequest(client, input.repository, input.owner)\n : await findLinkedPullRequest(client, input.repository, input.linkedChange);\n const change = await readCommittedGitChange({\n sandbox: input.sandbox,\n repositorySlug: input.repository.slug,\n baseRef:\n input.linkedChange === undefined\n ? \"origin/HEAD\"\n : `refs/remotes/origin/pr-${input.linkedChange.prNumber}`,\n });\n if (input.linkedChange !== undefined && change.base !== pull.head.sha) {\n throw new Error(\n `pull request #${input.linkedChange.prNumber} changed since it was fetched; fetch it again`,\n );\n }\n const sha = await createCommit(client, change, `${pull.title}\\n\\n${pull.body ?? \"\"}`);\n await client.updateBranch({\n branch: pull.branch,\n sha,\n force: input.linkedChange === undefined,\n });\n let draft = pull.draft;\n if (input.checkpoint.ready && draft) {\n await client.markReady({ nodeId: pull.nodeId });\n draft = false;\n }\n return {\n prNumber: pull.pullRequestNumber,\n prUrl: pull.pullRequestUrl,\n branch: pull.branch,\n changedFiles: change.changedFiles,\n draft,\n };\n }\n\n return Object.freeze({ requireTaskPullRequest, openPullRequest, pushCheckpoint });\n}\n\n/** Store and repository lookup dependencies for the pull-request publication gate. */\nexport interface GitHubPullRequestPublicationGateOptions extends GitHubPullRequestPublisherOptions {\n stores: Pick<FactoryStores, \"tasks\" | \"changes\">;\n repositoryForTask(taskId: TaskId): Promise<Repository>;\n}\n\n/** Validates that one pull request belongs to its exact GitHub Task and Change context. */\nexport type GitHubPullRequestPublicationGate = (\n input: PullRequestPublicationGateInput,\n) => Promise<PullRequestPublicationGateResult>;\n\n/** Fail-closed gate for the pull request a supplied code-change workflow records. */\nexport function createGitHubPullRequestPublicationGate(\n options: GitHubPullRequestPublicationGateOptions,\n): GitHubPullRequestPublicationGate {\n return async (\n input: PullRequestPublicationGateInput,\n ): Promise<PullRequestPublicationGateResult> => {\n let repository: Repository;\n let linkedChange: Awaited<ReturnType<FactoryStores[\"changes\"][\"get\"]>>;\n try {\n repository = await options.repositoryForTask(input.taskId);\n if (repository.id !== input.repositoryId) {\n return {\n ok: false,\n code: \"repository_mismatch\",\n reason: \"repositoryId does not match the task repository\",\n };\n }\n const task = await options.stores.tasks.get(input.taskId);\n if (task === null) {\n return {\n ok: false,\n code: \"task_not_found\",\n reason: `task ${input.taskId} does not exist`,\n };\n }\n linkedChange =\n task.changeId === undefined ? null : await options.stores.changes.get(task.changeId);\n if (task.changeId !== undefined && linkedChange === null) {\n return {\n ok: false,\n code: \"change_not_found\",\n reason: `change ${task.changeId} does not exist`,\n };\n }\n if (\n linkedChange !== null &&\n (linkedChange.repositoryId !== repository.id ||\n linkedChange.prNumber !== input.prNumber ||\n linkedChange.prUrl !== input.prUrl)\n ) {\n return {\n ok: false,\n code: \"linked_change_mismatch\",\n reason: \"pull request does not match the Change linked to this task\",\n };\n }\n } catch (error) {\n return {\n ok: false,\n code: \"repository_lookup_failed\",\n reason: redactedErrorMessage(error),\n };\n }\n\n let client: GitHubPublicationClient;\n try {\n client = await clientForRepository(options, repository);\n } catch (error) {\n return {\n ok: false,\n code: \"authentication_failed\",\n reason: `could not authenticate to GitHub: ${redactedErrorMessage(error)}`,\n };\n }\n\n let pull: GitHubPublicationPullRequest;\n try {\n pull = await client.pullRequest({ pullRequestNumber: input.prNumber });\n } catch (error) {\n return {\n ok: false,\n code:\n error instanceof GitHubPublicationApiError && error.status === 404\n ? \"pull_request_not_found\"\n : \"pull_request_lookup_failed\",\n reason:\n error instanceof GitHubPublicationApiError && error.status === 404\n ? `pull request #${input.prNumber} does not exist on ${repository.slug}`\n : `could not verify pull request #${input.prNumber} on ${repository.slug}`,\n };\n }\n if (pull.pullRequestUrl !== input.prUrl) {\n return {\n ok: false,\n code: \"pull_request_url_mismatch\",\n reason: `prUrl does not match pull request #${input.prNumber} on ${repository.slug}`,\n };\n }\n if (pull.state !== \"open\") {\n return {\n ok: false,\n code: \"pull_request_closed\",\n reason: `pull request #${input.prNumber} is not open`,\n };\n }\n const branch = factoryTaskBranch(input.taskId);\n if (\n pull.head.repository !== repository.slug ||\n (linkedChange === null && pull.head.branch !== branch)\n ) {\n return {\n ok: false,\n code: \"pull_request_branch_mismatch\",\n reason:\n linkedChange === null\n ? `pull request #${input.prNumber} is not on this task's branch ${branch}`\n : `pull request #${input.prNumber} is not a same-repository branch`,\n };\n }\n if (pull.draft) {\n return {\n ok: false,\n code: \"pull_request_draft\",\n reason: `pull request #${input.prNumber} is still a draft; call push_checkpoint with ready: true first`,\n };\n }\n return { ok: true };\n };\n}\n"],"mappings":";;;AAgFA,eAAe,oBACb,SACA,YACkC;CAClC,MAAM,QAAQ,MAAM,QAAQ,mBAAmB,WAAW,IAAI;CAC9D,QAAQ,QAAQ,gBAAgB,8BAAA,CAA+B;EAC7D,YAAY,WAAW;EACvB;EACA,OAAO,QAAQ;CACjB,CAAC;AACH;AAEA,SAAS,gBAAgB,YAAgC;CACvD,MAAM,QAAQ,WAAW,KAAK,MAAM,GAAG,CAAC,CAAC;CACzC,IAAI,UAAU,KAAA,KAAa,UAAU,IACnC,MAAM,IAAI,MAAM,4BAA4B,WAAW,MAAM;CAE/D,OAAO;AACT;AAEA,eAAe,oBACb,QACA,YACA,QAC4D;CAC5D,MAAM,SAAS,kBAAkB,MAAM;CAKvC,MAAM,QAAO,MAJM,OAAO,aAAa;EACrC,OAAO;EACP,MAAM,GAAG,gBAAgB,UAAU,EAAE,GAAG;CAC1C,CAAC,EAAA,CACiB,MAAM,cAAc,UAAU,KAAK,eAAe,WAAW,IAAI;CACnF,IAAI,SAAS,KAAA,GACX,MAAM,IAAI,MAAM,2BAA2B,OAAO,+BAA+B;CAEnF,OAAO;EAAE,GAAG;EAAM;CAAO;AAC3B;AAEA,eAAe,sBACb,QACA,YACA,QAC4D;CAC5D,MAAM,OAAO,MAAM,OAAO,YAAY,EAAE,mBAAmB,OAAO,SAAS,CAAC;CAC5E,MAAM,SAAS,KAAK,KAAK;CACzB,IACE,KAAK,UAAU,UACf,KAAK,mBAAmB,OAAO,SAC/B,KAAK,KAAK,eAAe,WAAW,QACpC,CAAC,aAAa,MAAM,GAEpB,MAAM,IAAI,MACR,wBAAwB,OAAO,SAAS,uCAC1C;CAEF,OAAO;EAAE,GAAG;EAAM;CAAO;AAC3B;AAEA,eAAe,aACb,QACA,QACA,SACA,SAAS,OAAO,MACC;CACjB,MAAM,aAAa,MAAM,OAAO,OAAO,EAAE,KAAK,OAAO,KAAK,CAAC;CAC3D,MAAM,OAAO,MAAM,OAAO,WAAW;EAAE,aAAa,WAAW;EAAS,SAAS,OAAO;CAAK,CAAC;CAC9F,OAAO,OAAO,aAAa;EAAE;EAAS,SAAS;EAAM,YAAY,CAAC,MAAM;CAAE,CAAC;AAC7E;AAEA,eAAe,mBACb,QACA,YACA,QACmD;CAKnD,MAAM,QAAO,MAJO,OAAO,aAAa;EACtC,OAAO;EACP,MAAM,GAAG,gBAAgB,UAAU,EAAE,GAAG;CAC1C,CAAC,EAAA,CACkB,MAChB,cACC,UAAU,KAAK,WAAW,UAAU,UAAU,KAAK,eAAe,WAAW,IACjF;CACA,IAAI,SAAS,KAAA,KAAa,KAAK,UAAU,QACvC,MAAM,IAAI,MACR,8FACF;CAEF,OAAO;AACT;AAEA,eAAe,YAAY,SAAsC;CAC/D,MAAM,SAAS,MAAM,QAAQ,IAAI,EAAE,SAAS,iDAAiD,CAAC;CAC9F,IAAI,OAAO,aAAa,GAAG,OAAO;CAClC,IAAI,OAAO,aAAa,KAAA,KAAa,OAAO,aAAa,GACvD,MAAM,IAAI,MAAM,8CAA8C;CAEhE,OAAO,OAAO,OAAO,KAAK;AAC5B;AAEA,eAAe,oBAAoB,SAAqB,KAA4B;CAClF,IAAI,CAAC,kBAAkB,KAAK,GAAG,GAAG,MAAM,IAAI,MAAM,wCAAwC;CAC1F,MAAM,cAAc;EAAE;EAAS,MAAM;GAAC;GAAU;GAAyB;EAAG;CAAE,CAAC;AACjF;AAEA,eAAe,sBAAsB,SAAqB,YAAuC;CAC/F,KACG,MAAM,cAAc;EAAE;EAAS,MAAM;GAAC;GAAU;GAAW;EAAQ;CAAE,CAAC,EAAA,CAAG,KAAK,MAC/E,sBAAsB,WAAW,KAAK,OAEtC,MAAM,IAAI,MAAM,sDAAsD,WAAW,MAAM;CAEzF,KAAK,MAAM,cAAc;EAAE;EAAS,MAAM,CAAC,UAAU,aAAa;CAAE,CAAC,EAAA,CAAG,KAAK,MAAM,IACjF,MAAM,IAAI,MAAM,yDAAyD;AAE7E;AAEA,eAAe,kBACb,SACA,QACA,KACkB;CAClB,MAAM,WAAW,MAAM,YAAY,OAAO;CAC1C,MAAM,SAAS,MAAM,OAAO,OAAO,EAAE,IAAI,CAAC;CAC1C,MAAM,YACJ,OAAO,aACN,MAAM,cAAc;EAAE;EAAS,MAAM,CAAC,aAAa,aAAa;CAAE,CAAC,EAAA,CAAG,KAAK;CAC9E,MAAM,YAAY,cAAc,aAAa,MAAM,OAAO,WAAW,SAAS,QAAQ;CACtF,IAAI,aAAa,OAAO,CAAC,WACvB,MAAM,IAAI,MACR,mIACF;CAEF,MAAM,oBAAoB,SAAS,GAAG;CACtC,OAAO;AACT;AAEA,SAAS,mBACP,MACA,QACA,eAAe,GACO;CACtB,OAAO;EACL,UAAU,KAAK;EACf,OAAO,KAAK;EACZ;EACA;EACA,OAAO,KAAK;CACd;AACF;;AAGA,SAAgB,iCACd,SAC4B;CAC5B,eAAe,uBACb,OAC0B;EAE1B,MAAM,OAAO,MAAM,oBAAoB,MADlB,oBAAoB,SAAS,MAAM,UAAU,GACnB,MAAM,YAAY,MAAM,MAAM;EAC7E,OAAO;GACL,UAAU,KAAK;GACf,OAAO,KAAK;GACZ,QAAQ,KAAK;EACf;CACF;CAEA,eAAe,uBACb,SACA,YACA,WACA,OAC+B;EAC/B,MAAM,SAAS,qBAAqB,SAAS;EAC7C,MAAM,sBAAsB,SAAS,UAAU;EAC/C,IAAI,QAAQ,uBAAuB,KAAA,GAAW;GAC5C,MAAM,SAAS,MAAM,uBAAuB;IAAE;IAAS,gBAAgB,WAAW;GAAK,CAAC;GACxF,MAAM,YAAY,MAAM,QAAQ,mBAAmB;IACjD,YAAY,WAAW;IACvB,YAAY,OAAO;IACnB,MAAM,OAAO;IACb,eAAe,OAAO;IACtB;IACA,OAAO,MAAM;IACb,MAAM,MAAM;IACZ,YAAY,WAAW;IACvB,OAAO;GACT,CAAC;GACD,MAAM,oBAAoB,SAAS,UAAU,SAAS;GACtD,OAAO;IACL,UAAU,UAAU;IACpB,OAAO,UAAU;IACjB;IACA,cAAc,OAAO;IACrB,OAAO,UAAU;GACnB;EACF;EACA,MAAM,SAAS,MAAM,oBAAoB,SAAS,UAAU;EAC5D,MAAM,WAAW,MAAM,mBAAmB,QAAQ,YAAY,MAAM;EACpE,IAAI,aAAa,KAAA,GAAW;GAC1B,MAAM,kBAAkB,SAAS,QAAQ,SAAS,KAAK,GAAG;GAC1D,OAAO,mBAAmB,UAAU,MAAM;EAC5C;EAEA,IAAI,MAAM,MAAM,OAAO,WAAW,EAAE,OAAO,CAAC;EAC5C,IAAI,eAAe;EACnB,IAAI,QAAQ,MAAM;GAChB,MAAM,SAAS,MAAM,uBAAuB;IAAE;IAAS,gBAAgB,WAAW;GAAK,CAAC;GACxF,eAAe,OAAO;GACtB,MAAM,MAAM,aAAa,QAAQ,QAAQ,GAAG,MAAM,MAAM,MAAM,MAAM,MAAM;GAC1E,IAAI;IACF,MAAM,OAAO,aAAa;KAAE;KAAQ;IAAI,CAAC;GAC3C,SAAS,OAAO;IACd,IAAK,MAAM,OAAO,WAAW,EAAE,OAAO,CAAC,MAAO,KAAK,MAAM;GAC3D;GACA,MAAM,oBAAoB,SAAS,GAAG;EACxC,OACE,MAAM,kBAAkB,SAAS,QAAQ,GAAG;EAE9C,IAAI;GACF,MAAM,OAAO,MAAM,OAAO,kBAAkB;IAC1C,OAAO,MAAM;IACb,MAAM,MAAM;IACZ,MAAM;IACN,MAAM,WAAW;IACjB,OAAO;GACT,CAAC;GACD,OAAO;IACL,UAAU,KAAK;IACf,OAAO,KAAK;IACZ;IACA;IACA,OAAO,KAAK;GACd;EACF,SAAS,OAAO;GACd,MAAM,UAAU,MAAM,mBAAmB,QAAQ,YAAY,MAAM;GACnE,IAAI,YAAY,KAAA,GAAW,MAAM;GACjC,OAAO,mBAAmB,SAAS,QAAQ,YAAY;EACzD;CACF;CAEA,eAAe,gBACb,OAC+B;EAC/B,IAAI,OAAO,MAAM,UAAU,UACzB,OAAO,uBACL,MAAM,SACN,MAAM,YACN,MAAM,MAAM,WACZ,MAAM,WACR;EAEF,MAAM,SAAS,MAAM,uBAAuB;GAC1C,SAAS,MAAM;GACf,gBAAgB,MAAM,WAAW;EACnC,CAAC;EACD,IAAI,QAAQ,uBAAuB,KAAA,GAAW;GAC5C,MAAM,SAAS,kBAAkB,MAAM,KAAK;GAC5C,MAAM,YAAY,MAAM,QAAQ,mBAAmB;IACjD,YAAY,MAAM,WAAW;IAC7B,YAAY,OAAO;IACnB,MAAM,OAAO;IACb,eAAe,OAAO;IACtB;IACA,OAAO,MAAM,YAAY;IACzB,MAAM,MAAM,YAAY;IACxB,YAAY,MAAM,WAAW;IAC7B,OAAO;GACT,CAAC;GACD,OAAO;IACL,UAAU,UAAU;IACpB,OAAO,UAAU;IACjB;IACA,cAAc,OAAO;IACrB,OAAO,UAAU;GACnB;EACF;EACA,MAAM,SAAS,MAAM,oBAAoB,SAAS,MAAM,UAAU;EAClE,MAAM,SAAS,kBAAkB,MAAM,KAAK;EAC5C,MAAM,YACJ,MAAM,OAAO,aAAa;GACxB,OAAO;GACP,MAAM,GAAG,gBAAgB,MAAM,UAAU,EAAE,GAAG;EAChD,CAAC,EAAA,CACD,MAAM,SAAS,KAAK,KAAK,WAAW,UAAU,KAAK,KAAK,eAAe,MAAM,WAAW,IAAI;EAC9F,IAAI,aAAa,KAAA,GAAW;GAC1B,IAAI,SAAS,UAAU,QACrB,MAAM,IAAI,MACR,sFACF;GACF,OAAO;IACL,UAAU,SAAS;IACnB,OAAO,SAAS;IAChB;IACA,cAAc;IACd,OAAO,SAAS;GAClB;EACF;EACA,MAAM,MAAM,MAAM,aAChB,QACA,QACA,GAAG,MAAM,YAAY,MAAM,MAAM,MAAM,YAAY,MACrD;EACA,MAAM,OAAO,aAAa;GAAE;GAAQ;EAAI,CAAC;EACzC,MAAM,OAAO,MAAM,OAAO,kBAAkB;GAC1C,OAAO,MAAM,YAAY;GACzB,MAAM,MAAM,YAAY;GACxB,MAAM;GACN,MAAM,MAAM,WAAW;GACvB,OAAO;EACT,CAAC;EACD,OAAO;GACL,UAAU,KAAK;GACf,OAAO,KAAK;GACZ;GACA,cAAc,OAAO;GACrB,OAAO,KAAK;EACd;CACF;CAEA,eAAe,sBACb,SACA,YACA,WACA,OAC+B;EAC/B,MAAM,SAAS,qBAAqB,SAAS;EAC7C,MAAM,sBAAsB,SAAS,UAAU;EAC/C,MAAM,SAAS,MAAM,oBAAoB,SAAS,UAAU;EAC5D,MAAM,OAAO,MAAM,mBAAmB,QAAQ,YAAY,MAAM;EAChE,IAAI,SAAS,KAAA,GACX,MAAM,IAAI,MAAM,2BAA2B,OAAO,+BAA+B;EAEnF,MAAM,YAAY,MAAM,kBAAkB,SAAS,QAAQ,KAAK,KAAK,GAAG;EACxE,IAAI,eAAe;EACnB,IAAI,CAAC,WAAW;GACd,MAAM,SAAS,MAAM,uBAAuB;IAC1C;IACA,gBAAgB,WAAW;IAC3B,YAAY;GACd,CAAC;GACD,eAAe,OAAO;GACtB,MAAM,MAAM,MAAM,aAChB,QACA,QACA,GAAG,KAAK,MAAM,MAAM,KAAK,QAAQ,MACjC,KAAK,KAAK,GACZ;GACA,MAAM,OAAO,aAAa;IAAE;IAAQ;IAAK,OAAO;GAAM,CAAC;GACvD,MAAM,oBAAoB,SAAS,GAAG;EACxC;EACA,MAAM,YAAY,mBAAmB,MAAM,QAAQ,YAAY;EAC/D,IAAI,MAAM,SAAS,UAAU,OAAO;GAClC,MAAM,OAAO,UAAU,EAAE,QAAQ,KAAK,OAAO,CAAC;GAC9C,UAAU,QAAQ;EACpB;EACA,OAAO;CACT;CAEA,eAAe,eAAe,OAAiE;EAC7F,IAAI,OAAO,MAAM,UAAU,UACzB,OAAO,sBACL,MAAM,SACN,MAAM,YACN,MAAM,MAAM,WACZ,MAAM,UACR;EAEF,MAAM,SAAS,MAAM,oBAAoB,SAAS,MAAM,UAAU;EAClE,MAAM,OACJ,MAAM,iBAAiB,KAAA,IACnB,MAAM,oBAAoB,QAAQ,MAAM,YAAY,MAAM,KAAK,IAC/D,MAAM,sBAAsB,QAAQ,MAAM,YAAY,MAAM,YAAY;EAC9E,MAAM,SAAS,MAAM,uBAAuB;GAC1C,SAAS,MAAM;GACf,gBAAgB,MAAM,WAAW;GACjC,SACE,MAAM,iBAAiB,KAAA,IACnB,gBACA,0BAA0B,MAAM,aAAa;EACrD,CAAC;EACD,IAAI,MAAM,iBAAiB,KAAA,KAAa,OAAO,SAAS,KAAK,KAAK,KAChE,MAAM,IAAI,MACR,iBAAiB,MAAM,aAAa,SAAS,8CAC/C;EAEF,MAAM,MAAM,MAAM,aAAa,QAAQ,QAAQ,GAAG,KAAK,MAAM,MAAM,KAAK,QAAQ,IAAI;EACpF,MAAM,OAAO,aAAa;GACxB,QAAQ,KAAK;GACb;GACA,OAAO,MAAM,iBAAiB,KAAA;EAChC,CAAC;EACD,IAAI,QAAQ,KAAK;EACjB,IAAI,MAAM,WAAW,SAAS,OAAO;GACnC,MAAM,OAAO,UAAU,EAAE,QAAQ,KAAK,OAAO,CAAC;GAC9C,QAAQ;EACV;EACA,OAAO;GACL,UAAU,KAAK;GACf,OAAO,KAAK;GACZ,QAAQ,KAAK;GACb,cAAc,OAAO;GACrB;EACF;CACF;CAEA,OAAO,OAAO,OAAO;EAAE;EAAwB;EAAiB;CAAe,CAAC;AAClF;;AAcA,SAAgB,uCACd,SACkC;CAClC,OAAO,OACL,UAC8C;EAC9C,IAAI;EACJ,IAAI;EACJ,IAAI;GACF,aAAa,MAAM,QAAQ,kBAAkB,MAAM,MAAM;GACzD,IAAI,WAAW,OAAO,MAAM,cAC1B,OAAO;IACL,IAAI;IACJ,MAAM;IACN,QAAQ;GACV;GAEF,MAAM,OAAO,MAAM,QAAQ,OAAO,MAAM,IAAI,MAAM,MAAM;GACxD,IAAI,SAAS,MACX,OAAO;IACL,IAAI;IACJ,MAAM;IACN,QAAQ,QAAQ,MAAM,OAAO;GAC/B;GAEF,eACE,KAAK,aAAa,KAAA,IAAY,OAAO,MAAM,QAAQ,OAAO,QAAQ,IAAI,KAAK,QAAQ;GACrF,IAAI,KAAK,aAAa,KAAA,KAAa,iBAAiB,MAClD,OAAO;IACL,IAAI;IACJ,MAAM;IACN,QAAQ,UAAU,KAAK,SAAS;GAClC;GAEF,IACE,iBAAiB,SAChB,aAAa,iBAAiB,WAAW,MACxC,aAAa,aAAa,MAAM,YAChC,aAAa,UAAU,MAAM,QAE/B,OAAO;IACL,IAAI;IACJ,MAAM;IACN,QAAQ;GACV;EAEJ,SAAS,OAAO;GACd,OAAO;IACL,IAAI;IACJ,MAAM;IACN,QAAQ,qBAAqB,KAAK;GACpC;EACF;EAEA,IAAI;EACJ,IAAI;GACF,SAAS,MAAM,oBAAoB,SAAS,UAAU;EACxD,SAAS,OAAO;GACd,OAAO;IACL,IAAI;IACJ,MAAM;IACN,QAAQ,qCAAqC,qBAAqB,KAAK;GACzE;EACF;EAEA,IAAI;EACJ,IAAI;GACF,OAAO,MAAM,OAAO,YAAY,EAAE,mBAAmB,MAAM,SAAS,CAAC;EACvE,SAAS,OAAO;GACd,OAAO;IACL,IAAI;IACJ,MACE,iBAAiB,6BAA6B,MAAM,WAAW,MAC3D,2BACA;IACN,QACE,iBAAiB,6BAA6B,MAAM,WAAW,MAC3D,iBAAiB,MAAM,SAAS,qBAAqB,WAAW,SAChE,kCAAkC,MAAM,SAAS,MAAM,WAAW;GAC1E;EACF;EACA,IAAI,KAAK,mBAAmB,MAAM,OAChC,OAAO;GACL,IAAI;GACJ,MAAM;GACN,QAAQ,sCAAsC,MAAM,SAAS,MAAM,WAAW;EAChF;EAEF,IAAI,KAAK,UAAU,QACjB,OAAO;GACL,IAAI;GACJ,MAAM;GACN,QAAQ,iBAAiB,MAAM,SAAS;EAC1C;EAEF,MAAM,SAAS,kBAAkB,MAAM,MAAM;EAC7C,IACE,KAAK,KAAK,eAAe,WAAW,QACnC,iBAAiB,QAAQ,KAAK,KAAK,WAAW,QAE/C,OAAO;GACL,IAAI;GACJ,MAAM;GACN,QACE,iBAAiB,OACb,iBAAiB,MAAM,SAAS,gCAAgC,WAChE,iBAAiB,MAAM,SAAS;EACxC;EAEF,IAAI,KAAK,OACP,OAAO;GACL,IAAI;GACJ,MAAM;GACN,QAAQ,iBAAiB,MAAM,SAAS;EAC1C;EAEF,OAAO,EAAE,IAAI,KAAK;CACpB;AACF"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { OpenPullRequest, OpenPullRequestInput, PublishedPullRequest, PullRequestLabelAction, PullRequestLabelResult, PullRequestPublicationGateFailure, PullRequestPublicationGateFailureCode, PullRequestPublicationGateInput, PullRequestPublicationGateResult, PullRequestPublicationGateSuccess, PullRequestPublicationOwner, PushCheckpointInput, TaskPullRequest } from "./pull-requests/contracts.mjs";
|
|
3
|
+
import { GitHubFetchPullRequestFailure, GitHubFetchPullRequestFailureCode, GitHubFetchPullRequestInput, GitHubFetchPullRequestResult, GitHubFetchPullRequestSuccess, GitHubFetchPullRequestTool, GitHubFetchPullRequestToolOptions, GitHubFetchPullRequestToolStores, createGitHubFetchPullRequestTool, gitHubFetchPullRequestInputSchema } from "./pull-requests/eve-fetch.mjs";
|
|
4
|
+
import { MergeConflictPayload, mergeConflictPayloadSchema } from "./merge-resolution/contracts.mjs";
|
|
5
|
+
import { GitHubFetchMergeConflictInput, GitHubFetchMergeConflictResult, GitHubMergeConflictTools, GitHubMergeConflictToolsOptions, GitHubMergeConflictToolsStores, GitHubPublishMergeResolutionInput, GitHubPublishMergeResolutionResult, createGitHubMergeConflictTools } from "./merge-resolution/eve-tools.mjs";
|
|
6
|
+
export { type GitHubFetchMergeConflictInput, type GitHubFetchMergeConflictResult, type GitHubFetchPullRequestFailure, type GitHubFetchPullRequestFailureCode, type GitHubFetchPullRequestInput, type GitHubFetchPullRequestResult, type GitHubFetchPullRequestSuccess, type GitHubFetchPullRequestTool, type GitHubFetchPullRequestToolOptions, type GitHubFetchPullRequestToolStores, type GitHubMergeConflictTools, type GitHubMergeConflictToolsOptions, type GitHubMergeConflictToolsStores, type GitHubPublishMergeResolutionInput, type GitHubPublishMergeResolutionResult, type MergeConflictPayload, type OpenPullRequest, type OpenPullRequestInput, type PublishedPullRequest, type PullRequestLabelAction, type PullRequestLabelResult, type PullRequestPublicationGateFailure, type PullRequestPublicationGateFailureCode, type PullRequestPublicationGateInput, type PullRequestPublicationGateResult, type PullRequestPublicationGateSuccess, type PullRequestPublicationOwner, type PushCheckpointInput, type TaskPullRequest, createGitHubFetchPullRequestTool, createGitHubMergeConflictTools, gitHubFetchPullRequestInputSchema, mergeConflictPayloadSchema };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { createGitHubFetchPullRequestTool, gitHubFetchPullRequestInputSchema } from "./pull-requests/eve-fetch.mjs";
|
|
2
|
+
import { mergeConflictPayloadSchema } from "./merge-resolution/contracts.mjs";
|
|
3
|
+
import { createGitHubMergeConflictTools } from "./merge-resolution/eve-tools.mjs";
|
|
4
|
+
export { createGitHubFetchPullRequestTool, createGitHubMergeConflictTools, gitHubFetchPullRequestInputSchema, mergeConflictPayloadSchema };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { ReceiptId, receiptIdSchema } from "./schema/id.mjs";
|
|
2
|
+
import { Cost, Receipt, ReceiptDelivery, ReceiptKind, ReceiptPhase, ReceiptState, StandardReceiptKind, StandardReceiptPhase, StandardReceiptState, costSchema, receiptDeliverySchema, receiptKindSchema, receiptPhaseSchema, receiptSchema, receiptStateSchema, standardReceiptKinds, standardReceiptPhases, standardReceiptStates } from "./schema/receipt.mjs";
|
|
3
|
+
import { AppendReceiptInput } from "./store/engine.mjs";
|
|
4
|
+
export { type AppendReceiptInput, type Cost, type Receipt, type ReceiptDelivery, type ReceiptId, type ReceiptKind, type ReceiptPhase, type ReceiptState, type StandardReceiptKind, type StandardReceiptPhase, type StandardReceiptState, costSchema, receiptDeliverySchema, receiptIdSchema, receiptKindSchema, receiptPhaseSchema, receiptSchema, receiptStateSchema, standardReceiptKinds, standardReceiptPhases, standardReceiptStates };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { receiptIdSchema } from "./schema/id.mjs";
|
|
2
|
+
import { costSchema, receiptDeliverySchema, receiptKindSchema, receiptPhaseSchema, receiptSchema, receiptStateSchema, standardReceiptKinds, standardReceiptPhases, standardReceiptStates } from "./schema/receipt.mjs";
|
|
3
|
+
export { costSchema, receiptDeliverySchema, receiptIdSchema, receiptKindSchema, receiptPhaseSchema, receiptSchema, receiptStateSchema, standardReceiptKinds, standardReceiptPhases, standardReceiptStates };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { RepositoryId } from "./schema/id.mjs";
|
|
2
|
+
import { Repository, RepositorySlug } from "./schema/repository.mjs";
|
|
3
|
+
import { FactoryStores } from "./store/engine.mjs";
|
|
4
|
+
//#region src/repositories.d.ts
|
|
5
|
+
/** Derives a stable repository ID from a validated canonical repository slug. */
|
|
6
|
+
declare function repositoryIdForSlug(slug: RepositorySlug): RepositoryId;
|
|
7
|
+
/** Repository metadata and configured allowlist used to admit or refresh one repository. */
|
|
8
|
+
interface EnsureConfiguredRepositoryInput {
|
|
9
|
+
readonly slug: RepositorySlug;
|
|
10
|
+
readonly configuredSlugs: readonly RepositorySlug[];
|
|
11
|
+
readonly defaultBranch: string;
|
|
12
|
+
readonly dependsOn: readonly RepositorySlug[];
|
|
13
|
+
}
|
|
14
|
+
/** Admits or refreshes a repository only when its slug is explicitly configured. */
|
|
15
|
+
declare function ensureConfiguredRepository(stores: Pick<FactoryStores, "repositories">, input: EnsureConfiguredRepositoryInput): Promise<Repository>;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { EnsureConfiguredRepositoryInput, ensureConfiguredRepository, repositoryIdForSlug };
|
|
18
|
+
//# sourceMappingURL=repositories.d.mts.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import "./schema/common.mjs";
|
|
2
|
+
import { repositorySlugSchema } from "./schema/repository.mjs";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
//#region src/repositories.ts
|
|
5
|
+
/** Derives a stable repository ID from a validated canonical repository slug. */
|
|
6
|
+
function repositoryIdForSlug(slug) {
|
|
7
|
+
const canonical = repositorySlugSchema.parse(slug.toLowerCase());
|
|
8
|
+
return `repo_${createHash("sha256").update(canonical).digest("hex").slice(0, 32)}`;
|
|
9
|
+
}
|
|
10
|
+
/** Admits or refreshes a repository only when its slug is explicitly configured. */
|
|
11
|
+
async function ensureConfiguredRepository(stores, input) {
|
|
12
|
+
const slug = repositorySlugSchema.parse(input.slug.toLowerCase());
|
|
13
|
+
if (!input.configuredSlugs.map((configured) => repositorySlugSchema.parse(configured.toLowerCase())).includes(slug)) throw new Error(`Repository ${slug} is not configured for this factory.`);
|
|
14
|
+
const id = repositoryIdForSlug(slug);
|
|
15
|
+
const dependsOn = input.dependsOn.map((dependency) => repositorySlugSchema.parse(dependency.toLowerCase()));
|
|
16
|
+
const existing = await stores.repositories.get(id);
|
|
17
|
+
if (existing !== null && existing.defaultBranch === input.defaultBranch && existing.dependsOn.length === dependsOn.length && existing.dependsOn.every((dependency, index) => dependency === dependsOn[index])) return existing;
|
|
18
|
+
return stores.repositories.put({
|
|
19
|
+
...existing ?? {
|
|
20
|
+
schemaVersion: 1,
|
|
21
|
+
id,
|
|
22
|
+
slug,
|
|
23
|
+
enabled: true,
|
|
24
|
+
connectedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
25
|
+
},
|
|
26
|
+
defaultBranch: input.defaultBranch,
|
|
27
|
+
dependsOn
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
export { ensureConfiguredRepository, repositoryIdForSlug };
|
|
32
|
+
|
|
33
|
+
//# sourceMappingURL=repositories.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repositories.mjs","names":[],"sources":["../src/repositories.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { SCHEMA_VERSION } from \"./schema/common\";\nimport { repositorySlugSchema, type Repository, type RepositorySlug } from \"./schema/repository\";\nimport type { RepositoryId } from \"./schema/id\";\nimport type { FactoryStores } from \"./store/engine\";\n\n/** Derives a stable repository ID from a validated canonical repository slug. */\nexport function repositoryIdForSlug(slug: RepositorySlug): RepositoryId {\n const canonical = repositorySlugSchema.parse(slug.toLowerCase());\n return `repo_${createHash(\"sha256\").update(canonical).digest(\"hex\").slice(0, 32)}`;\n}\n\n/** Repository metadata and configured allowlist used to admit or refresh one repository. */\nexport interface EnsureConfiguredRepositoryInput {\n readonly slug: RepositorySlug;\n readonly configuredSlugs: readonly RepositorySlug[];\n readonly defaultBranch: string;\n readonly dependsOn: readonly RepositorySlug[];\n}\n\n/** Admits or refreshes a repository only when its slug is explicitly configured. */\nexport async function ensureConfiguredRepository(\n stores: Pick<FactoryStores, \"repositories\">,\n input: EnsureConfiguredRepositoryInput,\n): Promise<Repository> {\n const slug = repositorySlugSchema.parse(input.slug.toLowerCase());\n const configuredSlugs = input.configuredSlugs.map((configured) =>\n repositorySlugSchema.parse(configured.toLowerCase()),\n );\n if (!configuredSlugs.includes(slug)) {\n throw new Error(`Repository ${slug} is not configured for this factory.`);\n }\n const id = repositoryIdForSlug(slug);\n const dependsOn = input.dependsOn.map((dependency) =>\n repositorySlugSchema.parse(dependency.toLowerCase()),\n );\n const existing = await stores.repositories.get(id);\n if (\n existing !== null &&\n existing.defaultBranch === input.defaultBranch &&\n existing.dependsOn.length === dependsOn.length &&\n existing.dependsOn.every((dependency, index) => dependency === dependsOn[index])\n ) {\n return existing;\n }\n return stores.repositories.put({\n ...(existing ?? {\n schemaVersion: SCHEMA_VERSION,\n id,\n slug,\n enabled: true,\n connectedAt: new Date().toISOString(),\n }),\n defaultBranch: input.defaultBranch,\n dependsOn,\n });\n}\n"],"mappings":";;;;;AAOA,SAAgB,oBAAoB,MAAoC;CACtE,MAAM,YAAY,qBAAqB,MAAM,KAAK,YAAY,CAAC;CAC/D,OAAO,QAAQ,WAAW,QAAQ,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,GAAG,EAAE;AACjF;;AAWA,eAAsB,2BACpB,QACA,OACqB;CACrB,MAAM,OAAO,qBAAqB,MAAM,MAAM,KAAK,YAAY,CAAC;CAIhE,IAAI,CAHoB,MAAM,gBAAgB,KAAK,eACjD,qBAAqB,MAAM,WAAW,YAAY,CAAC,CAElC,CAAC,CAAC,SAAS,IAAI,GAChC,MAAM,IAAI,MAAM,cAAc,KAAK,qCAAqC;CAE1E,MAAM,KAAK,oBAAoB,IAAI;CACnC,MAAM,YAAY,MAAM,UAAU,KAAK,eACrC,qBAAqB,MAAM,WAAW,YAAY,CAAC,CACrD;CACA,MAAM,WAAW,MAAM,OAAO,aAAa,IAAI,EAAE;CACjD,IACE,aAAa,QACb,SAAS,kBAAkB,MAAM,iBACjC,SAAS,UAAU,WAAW,UAAU,UACxC,SAAS,UAAU,OAAO,YAAY,UAAU,eAAe,UAAU,MAAM,GAE/E,OAAO;CAET,OAAO,OAAO,aAAa,IAAI;EAC7B,GAAI,YAAY;GACd,eAAA;GACA;GACA;GACA,SAAS;GACT,8BAAa,IAAI,KAAK,EAAA,CAAE,YAAY;EACtC;EACA,eAAe,MAAM;EACrB;CACF,CAAC;AACH"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region src/sandbox/command.d.ts
|
|
2
|
+
/** Shell command accepted by the minimal sandbox command boundary. */
|
|
3
|
+
interface CommandSandboxRunInput {
|
|
4
|
+
command: string;
|
|
5
|
+
}
|
|
6
|
+
/** Captured output and optional exit status returned by a sandbox command. */
|
|
7
|
+
interface CommandSandboxRunResult {
|
|
8
|
+
stdout: string;
|
|
9
|
+
stderr?: string;
|
|
10
|
+
exitCode?: number;
|
|
11
|
+
}
|
|
12
|
+
/** Minimal sandbox contract for running a command and reading its result. */
|
|
13
|
+
interface CommandSandbox {
|
|
14
|
+
run(options: CommandSandboxRunInput): PromiseLike<CommandSandboxRunResult>;
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { CommandSandbox, CommandSandboxRunInput, CommandSandboxRunResult };
|
|
18
|
+
//# sourceMappingURL=command.d.mts.map
|