@vercel/factory 0.0.14 → 0.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +306 -0
- package/dist/agent-routes.d.mts +69 -0
- package/dist/agent-routes.mjs +64 -0
- package/dist/agent-routes.mjs.map +1 -0
- package/dist/api-contracts.d.mts +1749 -0
- package/dist/api-contracts.mjs +118 -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 +68 -216
- package/dist/api.mjs +872 -97
- 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 +692 -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 +41 -6
- package/dist/blob/index.mjs +158 -40
- package/dist/blob/index.mjs.map +1 -1
- package/dist/budget.d.mts +108 -0
- package/dist/budget.mjs +141 -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 +6 -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 +24 -0
- package/dist/change-verification/dispatch.mjs +45 -0
- package/dist/change-verification/dispatch.mjs.map +1 -0
- package/dist/change-verification/eve-tool.d.mts +60 -0
- package/dist/change-verification/eve-tool.mjs +101 -0
- package/dist/change-verification/eve-tool.mjs.map +1 -0
- package/dist/changes/eve-record-change.d.mts +56 -0
- package/dist/changes/eve-record-change.mjs +97 -0
- package/dist/changes/eve-record-change.mjs.map +1 -0
- package/dist/changes/presentation.d.mts +14 -0
- package/dist/changes.d.mts +23 -0
- package/dist/changes.mjs +29 -0
- package/dist/changes.mjs.map +1 -0
- package/dist/client-events.d.mts +18 -0
- package/dist/client-events.mjs +41 -0
- package/dist/client-events.mjs.map +1 -0
- package/dist/client-stream.d.mts +28 -0
- package/dist/client-stream.mjs +204 -0
- package/dist/client-stream.mjs.map +1 -0
- package/dist/client-transcript.d.mts +41 -0
- package/dist/client-transcript.mjs +229 -0
- package/dist/client-transcript.mjs.map +1 -0
- package/dist/client.d.mts +234 -0
- package/dist/client.mjs +258 -0
- package/dist/client.mjs.map +1 -0
- package/dist/code-review/contracts.d.mts +26 -0
- package/dist/code-review/eve-post-review.d.mts +70 -0
- package/dist/code-review/eve-post-review.mjs +183 -0
- package/dist/code-review/eve-post-review.mjs.map +1 -0
- package/dist/code-review/eve-review-comments.d.mts +64 -0
- package/dist/code-review/eve-review-comments.mjs +159 -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 +44 -0
- package/dist/code-review/github-reporter.mjs +260 -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 +6 -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 +164 -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 +81 -0
- package/dist/dispatch.mjs +140 -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 +143 -1271
- package/dist/eve/index.mjs +233 -1065
- package/dist/eve/index.mjs.map +1 -1
- package/dist/eve/invoke.d.mts +144 -0
- package/dist/eve/invoke.mjs +241 -0
- package/dist/eve/invoke.mjs.map +1 -0
- package/dist/eve/session-client.d.mts +68 -0
- package/dist/eve/session-client.mjs +131 -0
- package/dist/eve/session-client.mjs.map +1 -0
- package/dist/eve/task-execution.mjs +18 -0
- package/dist/eve/task-execution.mjs.map +1 -0
- package/dist/eve/task-session.d.mts +87 -0
- package/dist/eve/task-session.mjs +203 -0
- package/dist/eve/task-session.mjs.map +1 -0
- package/dist/eve/transcript.d.mts +37 -0
- package/dist/eve/transcript.mjs +65 -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 +75 -0
- package/dist/execution.mjs +153 -0
- package/dist/execution.mjs.map +1 -0
- package/dist/finding-remediation/admission.d.mts +51 -0
- package/dist/finding-remediation/admission.mjs +87 -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 +6 -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 +198 -0
- package/dist/github-publication.mjs +429 -0
- package/dist/github-publication.mjs.map +1 -0
- package/dist/github-transfer.d.mts +72 -0
- package/dist/github-transfer.mjs +125 -0
- package/dist/github-transfer.mjs.map +1 -0
- package/dist/github.d.mts +406 -2
- package/dist/github.mjs +239 -40
- 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/index.d.mts +14 -484
- package/dist/index.mjs +14 -522
- package/dist/intake-contracts.d.mts +56 -0
- package/dist/intake-contracts.mjs +33 -0
- package/dist/intake-contracts.mjs.map +1 -0
- package/dist/integrations/deepsec.d.mts +4 -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 +3 -0
- package/dist/integrations/slack.mjs +3 -0
- package/dist/integrations/vercel.d.mts +3 -0
- package/dist/integrations/vercel.mjs +3 -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 +46 -0
- package/dist/merge-resolution/eve-tools.mjs +117 -0
- package/dist/merge-resolution/eve-tools.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 +273 -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 +7 -1
- package/dist/postgres/index.mjs +7 -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 +53 -0
- package/dist/presets/software-development/dispatch.mjs +66 -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 +23 -0
- package/dist/presets/software-development/task-communication.mjs +120 -0
- package/dist/presets/software-development/task-communication.mjs.map +1 -0
- package/dist/presets/software-development.d.mts +9 -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 +53 -0
- package/dist/pull-requests/github-publisher.mjs +345 -0
- package/dist/pull-requests/github-publisher.mjs.map +1 -0
- package/dist/pull-requests.d.mts +5 -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 +9 -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 +22 -0
- package/dist/schema/agent-route.mjs +15 -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 +95 -0
- package/dist/schema/factory-config.mjs +60 -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 +26 -0
- package/dist/schema/repository.mjs +25 -0
- package/dist/schema/repository.mjs.map +1 -0
- package/dist/schema/session.d.mts +135 -0
- package/dist/schema/session.mjs +53 -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/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 +3134 -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 +272 -0
- package/dist/schema/task.mjs +199 -0
- package/dist/schema/task.mjs.map +1 -0
- package/dist/schema/transcript.d.mts +170 -0
- package/dist/schema/transcript.mjs +86 -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 +101 -0
- package/dist/schema/work.mjs +102 -0
- package/dist/schema/work.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 +19 -0
- package/dist/signals.mjs +19 -0
- package/dist/signals.mjs.map +1 -0
- package/dist/stall.d.mts +38 -0
- package/dist/stall.mjs +79 -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 +485 -0
- package/dist/store/engine.mjs +2175 -0
- package/dist/store/engine.mjs.map +1 -0
- package/dist/store/memory.d.mts +7 -0
- package/dist/store/memory.mjs +52 -0
- package/dist/store/memory.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 +65 -0
- package/dist/store/task-work.mjs +134 -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 +57 -0
- package/dist/sweep.mjs +143 -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 +264 -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 +21 -0
- package/dist/vercel-git.mjs +112 -0
- package/dist/vercel-git.mjs.map +1 -0
- package/dist/vercel.d.mts +33 -2
- package/dist/vercel.mjs +48 -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 +3 -0
- package/dist/work-triage.mjs +3 -0
- package/dist/workflows.d.mts +48 -0
- package/dist/workflows.mjs +86 -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-snapshot.d.mts +26 -0
- package/dist/workspace-snapshot.mjs +80 -0
- package/dist/workspace-snapshot.mjs.map +1 -0
- package/package.json +129 -44
- 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 @@
|
|
|
1
|
+
{"version":3,"file":"github-publication.mjs","names":[],"sources":["../src/github-publication.ts"],"sourcesContent":["import {\n withSandboxGitBundle,\n quoteShellArgument,\n runSandboxCommand,\n type GitHubGitTransport,\n type GitTransferSandbox,\n} from \"./github-transfer\";\nimport type { TaskId } from \"./schema/id\";\nimport { repositorySlugSchema, type RepositorySlug } from \"./schema/repository\";\nimport { agentSessionIdSchema, type AgentSessionId } from \"./schema/session\";\nimport { z } from \"zod\";\n\n/** Minimal sandbox command boundary required by Git checkout and publication helpers. */\nexport interface SandboxGit {\n run(options: SandboxGitCommandInput): PromiseLike<SandboxGitCommandResult>;\n}\n\n/** Shell command submitted through the minimal Git sandbox boundary. */\nexport interface SandboxGitCommandInput {\n command: string;\n}\n\n/** Captured output and optional exit status from a sandbox Git command. */\nexport interface SandboxGitCommandResult {\n stdout: string;\n stderr?: string;\n exitCode?: number;\n}\n\n/** Bounds applied while translating committed workspace changes into GitHub tree entries. */\nexport interface GitHubPublicationLimits {\n maxChangedFiles?: number;\n maxFileBytes?: number;\n}\n\n/** Repository-scoped credentials and transport for the GitHub publication client. */\nexport interface GitHubPublicationClientOptions {\n repository: RepositorySlug;\n token: string;\n fetch?: typeof globalThis.fetch;\n}\n\n/** Pull-request snapshot used to reconcile idempotent publication effects. */\nexport interface GitHubPublicationPullRequest {\n pullRequestNumber: number;\n pullRequestUrl: string;\n nodeId: string;\n title: string;\n body: string | null;\n state: \"open\" | \"closed\";\n draft: boolean;\n head: {\n branch: string;\n sha: string;\n repository: RepositorySlug | null;\n };\n}\n\n/** Git Data and pull-request operations needed by supplied publication workflows. */\nexport interface GitHubPublicationClient {\n commit(input: ReadGitHubCommitInput): Promise<GitHubCommit>;\n branchHead(input: ReadGitHubBranchHeadInput): Promise<string | null>;\n createTree(input: CreateGitHubTreeInput): Promise<string>;\n createCommit(input: CreateGitHubCommitInput): Promise<string>;\n createBranch(input: CreateGitHubBranchInput): Promise<void>;\n updateBranch(input: UpdateGitHubBranchInput): Promise<void>;\n createPullRequest(\n input: CreateGitHubPublicationPullRequestInput,\n ): Promise<CreatedGitHubPublicationPullRequest>;\n pullRequest(input: ReadGitHubPullRequestInput): Promise<GitHubPublicationPullRequest>;\n pullRequests(\n input: ListGitHubPublicationPullRequestsInput,\n ): Promise<readonly GitHubPublicationPullRequest[]>;\n markReady(input: MarkGitHubPullRequestReadyInput): Promise<void>;\n}\n\n/** Exact commit requested from GitHub's Git Data API. */\nexport interface ReadGitHubCommitInput {\n sha: string;\n}\n\n/** Tree and parents recorded for one GitHub commit. */\nexport interface GitHubCommit {\n treeSha: string;\n parentShas: readonly string[];\n}\n\n/** Exact branch whose current GitHub head should be read. */\nexport interface ReadGitHubBranchHeadInput {\n branch: string;\n}\n\n/** Base tree and exclusive file operations used to create a GitHub tree. */\nexport interface CreateGitHubTreeInput {\n baseTreeSha: string;\n entries: readonly GitHubTreeEntry[];\n}\n\n/** Commit content and parent identities used to create a GitHub commit. */\nexport interface CreateGitHubCommitInput {\n message: string;\n treeSha: string;\n parentShas: readonly string[];\n}\n\n/** Branch and commit identity used to create a GitHub branch. */\nexport interface CreateGitHubBranchInput {\n branch: string;\n sha: string;\n}\n\n/** Branch update and force policy used to move a GitHub branch. */\nexport interface UpdateGitHubBranchInput extends CreateGitHubBranchInput {\n force: boolean;\n}\n\n/** Provider-owned pull-request number to read. */\nexport interface ReadGitHubPullRequestInput {\n pullRequestNumber: number;\n}\n\n/** Provider GraphQL node identity of a draft pull request to mark ready. */\nexport interface MarkGitHubPullRequestReadyInput {\n nodeId: string;\n}\n\n/** Pull-request presentation and branch inputs used during GitHub publication. */\nexport interface CreateGitHubPublicationPullRequestInput {\n title: string;\n body: string;\n head: string;\n base: string;\n draft: boolean;\n}\n\n/** Provider identity and draft state returned after creating a pull request. */\nexport interface CreatedGitHubPublicationPullRequest {\n pullRequestNumber: number;\n pullRequestUrl: string;\n draft: boolean;\n}\n\n/** State and optional exact head filter used to list publication pull requests. */\nexport interface ListGitHubPublicationPullRequestsInput {\n state: \"open\" | \"all\";\n head?: string;\n}\n\n/** GitHub publication failure that preserves the provider HTTP status. */\nexport class GitHubPublicationApiError extends Error {\n constructor(\n readonly status: number,\n message: string,\n ) {\n super(`GitHub API request failed (${status}): ${message}`);\n this.name = \"GitHubPublicationApiError\";\n }\n}\n\ninterface GitHubTreeEntryBase {\n path: string;\n mode: \"100644\" | \"100755\";\n type: \"blob\";\n}\n\n/** File content uploaded through GitHub's Git Data API. */\nexport interface GitHubTreeUpsert extends GitHubTreeEntryBase {\n content: string;\n sha?: never;\n}\n\n/** Existing file removed through GitHub's Git Data API. */\nexport interface GitHubTreeDeletion extends GitHubTreeEntryBase {\n sha: null;\n content?: never;\n}\n\n/** Exclusive bounded file upsert or deletion accepted by GitHub's Git Data API. */\nexport type GitHubTreeEntry = GitHubTreeUpsert | GitHubTreeDeletion;\n\n/** Committed workspace delta represented against a specific base commit. */\nexport interface CommittedGitChange {\n base: string;\n tree: readonly GitHubTreeEntry[];\n changedFiles: number;\n}\n\n/** Sandbox, repository, and bounds for reading a committed workspace delta. */\nexport interface ReadCommittedGitChangeInput extends GitHubPublicationLimits {\n sandbox: SandboxGit;\n repositorySlug: RepositorySlug;\n baseRef?: string;\n allowEmpty?: boolean;\n}\n\n/** Common dependencies for an authorized repository checkout. */\ninterface CheckoutGitHubRepositoryBaseInput {\n sandbox: GitTransferSandbox;\n repositorySlug: RepositorySlug;\n transport: GitHubGitTransport;\n}\n\n/** Authorized repository checkout with recovery options that require a branch to resume. */\nexport type CheckoutGitHubRepositoryInput = CheckoutGitHubRepositoryBaseInput &\n (\n | {\n resumeBranch?: never;\n rememberPublishedHead?: never;\n }\n | {\n /** Resume this remote branch when it exists after refreshing the default branch. */\n resumeBranch: string;\n /** Remember the resumed remote head for later publication reconciliation. */\n rememberPublishedHead?: true;\n }\n );\n\n/** Refusal raised when an existing sandbox checkout points at another repository. */\nexport class GitHubCheckoutConflictError extends Error {\n constructor(\n readonly existingOrigin: string,\n readonly expectedOrigin: string,\n ) {\n super(`sandbox checkout ${existingOrigin} does not match ${expectedOrigin}`);\n this.name = \"GitHubCheckoutConflictError\";\n }\n}\n\nconst safePathPattern = /^[A-Za-z0-9.][A-Za-z0-9._/-]*$/u;\nconst safeRefPattern = /^[A-Za-z0-9][A-Za-z0-9._/-]*$/u;\nconst allowedModes = new Set([\"100644\", \"100755\"]);\nconst gitHubApiUrl = \"https://api.github.com\";\n\nconst shaSchema = z.string().min(1);\nconst pullRequestSchema = z.object({\n number: z.number().int().positive(),\n html_url: z.url(),\n node_id: z.string().min(1),\n title: z.string(),\n body: z.string().nullable(),\n state: z.enum([\"open\", \"closed\"]),\n draft: z.boolean(),\n head: z.object({\n ref: z.string().min(1),\n sha: shaSchema,\n repo: z.object({ full_name: z.string().min(1) }).nullable(),\n }),\n});\n\n/** GitHub Git Data and pull-request operations used by publication workflows. */\nexport function createGitHubPublicationClient(\n options: GitHubPublicationClientOptions,\n): GitHubPublicationClient {\n const repository = repositorySlugSchema.parse(options.repository.toLowerCase());\n const request = async (path: string, init: RequestInit = {}): Promise<unknown> => {\n let response: Response;\n try {\n response = await (options.fetch ?? globalThis.fetch)(\n `${gitHubApiUrl}/repos/${repository}${path}`,\n {\n ...init,\n headers: {\n Accept: \"application/vnd.github+json\",\n Authorization: `Bearer ${options.token}`,\n \"Content-Type\": \"application/json\",\n \"X-GitHub-Api-Version\": \"2022-11-28\",\n ...init.headers,\n },\n },\n );\n } catch (error) {\n throw new Error(\"GitHub API request failed\", { cause: error });\n }\n const body: unknown = await response.json().catch(() => null);\n if (!response.ok) {\n const parsed = z.object({ message: z.string() }).safeParse(body);\n throw new GitHubPublicationApiError(\n response.status,\n parsed.success ? parsed.data.message : response.statusText,\n );\n }\n return body;\n };\n const graphql = async (query: string, variables: Record<string, unknown>): Promise<void> => {\n let response: Response;\n try {\n response = await (options.fetch ?? globalThis.fetch)(`${gitHubApiUrl}/graphql`, {\n method: \"POST\",\n headers: {\n Accept: \"application/vnd.github+json\",\n Authorization: `Bearer ${options.token}`,\n \"Content-Type\": \"application/json\",\n \"X-GitHub-Api-Version\": \"2022-11-28\",\n },\n body: JSON.stringify({ query, variables }),\n });\n } catch (error) {\n throw new Error(\"GitHub GraphQL request failed\", { cause: error });\n }\n const body: unknown = await response.json().catch(() => null);\n const parsed = z\n .object({ errors: z.array(z.object({ message: z.string() })).optional() })\n .safeParse(body);\n if (!response.ok || (parsed.success && parsed.data.errors?.length)) {\n throw new GitHubPublicationApiError(\n response.status,\n parsed.success && parsed.data.errors?.[0] !== undefined\n ? parsed.data.errors[0].message\n : response.statusText,\n );\n }\n };\n const parsePullRequest = (value: unknown): GitHubPublicationPullRequest => {\n const pull = pullRequestSchema.parse(value);\n return {\n pullRequestNumber: pull.number,\n pullRequestUrl: pull.html_url,\n nodeId: pull.node_id,\n title: pull.title,\n body: pull.body,\n state: pull.state,\n draft: pull.draft,\n head: {\n branch: pull.head.ref,\n sha: pull.head.sha,\n repository:\n pull.head.repo === null\n ? null\n : repositorySlugSchema.parse(pull.head.repo.full_name.toLowerCase()),\n },\n };\n };\n const branchPath = (branch: string): string => {\n if (!isSafeGitRef(branch)) throw new Error(`refusing to use unsafe branch name: ${branch}`);\n return branch;\n };\n\n return {\n async commit(input) {\n const commit = z\n .object({\n tree: z.object({ sha: shaSchema }),\n parents: z.array(z.object({ sha: shaSchema })),\n })\n .parse(await request(`/git/commits/${encodeURIComponent(input.sha)}`));\n return { treeSha: commit.tree.sha, parentShas: commit.parents.map((parent) => parent.sha) };\n },\n async branchHead(input) {\n try {\n const ref = z\n .object({ object: z.object({ sha: shaSchema }) })\n .parse(await request(`/git/ref/heads/${branchPath(input.branch)}`));\n return ref.object.sha;\n } catch (error) {\n if (error instanceof GitHubPublicationApiError && error.status === 404) return null;\n throw error;\n }\n },\n async createTree(input) {\n return z.object({ sha: shaSchema }).parse(\n await request(\"/git/trees\", {\n method: \"POST\",\n body: JSON.stringify({ base_tree: input.baseTreeSha, tree: input.entries }),\n }),\n ).sha;\n },\n async createCommit(input) {\n return z.object({ sha: shaSchema }).parse(\n await request(\"/git/commits\", {\n method: \"POST\",\n body: JSON.stringify({\n message: input.message,\n tree: input.treeSha,\n parents: input.parentShas,\n }),\n }),\n ).sha;\n },\n async createBranch(input) {\n await request(\"/git/refs\", {\n method: \"POST\",\n body: JSON.stringify({\n ref: `refs/heads/${branchPath(input.branch)}`,\n sha: input.sha,\n }),\n });\n },\n async updateBranch(input) {\n await request(`/git/refs/heads/${branchPath(input.branch)}`, {\n method: \"PATCH\",\n body: JSON.stringify({ sha: input.sha, force: input.force }),\n });\n },\n async createPullRequest(input) {\n const pull = z\n .object({\n number: z.number().int().positive(),\n html_url: z.url(),\n draft: z.boolean(),\n })\n .parse(\n await request(\"/pulls\", {\n method: \"POST\",\n body: JSON.stringify(input),\n }),\n );\n return {\n pullRequestNumber: pull.number,\n pullRequestUrl: pull.html_url,\n draft: pull.draft,\n };\n },\n async pullRequest(input) {\n return parsePullRequest(await request(`/pulls/${input.pullRequestNumber}`));\n },\n async pullRequests(input) {\n const query = new URLSearchParams({ state: input.state, per_page: \"100\" });\n if (input.head !== undefined) query.set(\"head\", input.head);\n return z\n .array(pullRequestSchema)\n .parse(await request(`/pulls?${query.toString()}`))\n .map(parsePullRequest);\n },\n async markReady(input) {\n await graphql(\n \"mutation($id: ID!) { markPullRequestReadyForReview(input: { pullRequestId: $id }) { clientMutationId } }\",\n { id: input.nodeId },\n );\n },\n };\n}\n\n/** Derive the deterministic publication branch owned by a durable Task. */\nexport function factoryTaskBranch(taskId: TaskId): string {\n return `factory/${taskId}`;\n}\n\n/** Derive the deterministic publication branch owned by an operator session. */\nexport function factorySessionBranch(sessionId: AgentSessionId): string {\n return `factory/${agentSessionIdSchema.parse(sessionId)}`;\n}\n\n/** Check whether a Git reference is safe to interpolate into supplied Git commands. */\nexport function isSafeGitRef(ref: string): boolean {\n return safeRefPattern.test(ref) && !ref.includes(\"..\");\n}\n\n/** Clone or refresh one authorized GitHub repository without retaining credentials. */\nexport async function checkoutGitHubRepository(\n input: CheckoutGitHubRepositoryInput,\n): Promise<void> {\n const slug = repositorySlugSchema.parse(input.repositorySlug.toLowerCase());\n const expectedOrigin = `https://github.com/${slug}.git`;\n const checkout = await input.sandbox.run({ command: \"test -d repo/.git\" });\n const existingOrigin =\n checkout.exitCode === undefined || checkout.exitCode === 0\n ? (\n await runSandboxCommand(input.sandbox, [\n \"git\",\n \"-C\",\n \"repo\",\n \"remote\",\n \"get-url\",\n \"origin\",\n ])\n ).trim()\n : \"\";\n if (existingOrigin !== \"\" && existingOrigin.toLowerCase() !== expectedOrigin) {\n throw new GitHubCheckoutConflictError(existingOrigin, expectedOrigin);\n }\n\n const resume = input.resumeBranch;\n if (resume !== undefined && !isSafeGitRef(resume)) {\n throw new Error(`refusing to resume unsafe branch name: ${resume}`);\n }\n const bundle = await input.transport.fetch({ repository: slug, refs: [] });\n await withSandboxGitBundle({\n sandbox: input.sandbox,\n bundle,\n async use(path) {\n if (existingOrigin === \"\") {\n await runSandboxCommand(input.sandbox, [\"git\", \"clone\", path, \"repo\"]);\n await runSandboxCommand(input.sandbox, [\n \"git\",\n \"-C\",\n \"repo\",\n \"remote\",\n \"set-url\",\n \"origin\",\n expectedOrigin,\n ]);\n await runSandboxCommand(input.sandbox, [\n \"git\",\n \"-C\",\n \"repo\",\n \"config\",\n \"user.name\",\n \"factory\",\n ]);\n await runSandboxCommand(input.sandbox, [\n \"git\",\n \"-C\",\n \"repo\",\n \"config\",\n \"user.email\",\n \"factory@localhost\",\n ]);\n } else {\n await runSandboxCommand(input.sandbox, [\n \"git\",\n \"-C\",\n \"repo\",\n \"fetch\",\n path,\n \"+refs/heads/*:refs/remotes/origin/*\",\n ]);\n await runSandboxCommand(input.sandbox, [\n \"git\",\n \"-C\",\n \"repo\",\n \"reset\",\n \"--hard\",\n \"origin/HEAD\",\n ]);\n }\n if (resume === undefined) return;\n const exists = await input.sandbox.run({\n command: [\n \"git\",\n \"-C\",\n \"repo\",\n \"show-ref\",\n \"--verify\",\n \"--quiet\",\n `refs/remotes/origin/${resume}`,\n ]\n .map(quoteShellArgument)\n .join(\" \"),\n });\n if (exists.exitCode !== 0) return;\n await runSandboxCommand(input.sandbox, [\n \"git\",\n \"-C\",\n \"repo\",\n \"checkout\",\n \"-B\",\n resume,\n `refs/remotes/origin/${resume}`,\n ]);\n if (input.rememberPublishedHead === true) {\n const head = (\n await runSandboxCommand(input.sandbox, [\"git\", \"-C\", \"repo\", \"rev-parse\", \"HEAD\"])\n ).trim();\n await runSandboxCommand(input.sandbox, [\n \"git\",\n \"-C\",\n \"repo\",\n \"config\",\n \"factory.publishedHead\",\n head,\n ]);\n }\n },\n });\n}\n\n/** Sandbox and argument vector for one Git command in a repository checkout. */\nexport interface RunSandboxGitInput {\n sandbox: SandboxGit;\n args: readonly string[];\n repositoryPath?: string;\n}\n\n/** Run a Git argument vector in a sandbox repository and reject nonzero exits. */\nexport function runSandboxGit(input: RunSandboxGitInput): Promise<string> {\n return runSandboxCommand(input.sandbox, [\n \"git\",\n \"-C\",\n input.repositoryPath ?? \"repo\",\n ...input.args,\n ]);\n}\n\n/** Read committed sandbox changes as a bounded GitHub Git Data API tree. */\nexport async function readCommittedGitChange(\n input: ReadCommittedGitChangeInput,\n): Promise<CommittedGitChange> {\n const repositorySlug = repositorySlugSchema.parse(input.repositorySlug.toLowerCase());\n const baseRef = input.baseRef ?? \"origin/HEAD\";\n if (!isSafeGitRef(baseRef)) {\n throw new Error(`refusing to read unsafe base ref: ${baseRef}`);\n }\n const maxChangedFiles = input.maxChangedFiles ?? 25;\n const maxFileBytes = input.maxFileBytes ?? 200_000;\n if (!Number.isSafeInteger(maxChangedFiles) || maxChangedFiles < 1) {\n throw new Error(\"maxChangedFiles must be a positive integer\");\n }\n if (!Number.isSafeInteger(maxFileBytes) || maxFileBytes < 1) {\n throw new Error(\"maxFileBytes must be a positive integer\");\n }\n const origin = (\n await runSandboxGit({ sandbox: input.sandbox, args: [\"remote\", \"get-url\", \"origin\"] })\n ).trim();\n if (origin !== `https://github.com/${repositorySlug}.git`) {\n throw new Error(`sandbox checkout does not match task repository ${repositorySlug}`);\n }\n const head = (\n await runSandboxGit({ sandbox: input.sandbox, args: [\"rev-parse\", \"HEAD\"] })\n ).trim();\n const base = (\n await runSandboxGit({ sandbox: input.sandbox, args: [\"rev-parse\", baseRef] })\n ).trim();\n if (head === base && input.allowEmpty !== true) {\n throw new Error(\"no local commits to publish; commit your changes in the repo first\");\n }\n\n const nameStatus = (\n await runSandboxGit({\n sandbox: input.sandbox,\n args: [\"diff\", \"--name-status\", base, head],\n })\n ).trim();\n const upserts: string[] = [];\n const deletions: string[] = [];\n for (const line of nameStatus.split(\"\\n\").filter(Boolean)) {\n const fields = line.split(\"\\t\");\n const status = fields[0] ?? \"\";\n if (status === \"A\" || status === \"M\" || status === \"T\") {\n upserts.push(requireSafePath(fields[1]));\n } else if (status === \"D\") {\n deletions.push(requireSafePath(fields[1]));\n } else if (status.startsWith(\"R\") || status.startsWith(\"C\")) {\n if (status.startsWith(\"R\")) deletions.push(requireSafePath(fields[1]));\n upserts.push(requireSafePath(fields[2]));\n } else {\n throw new Error(`unsupported change status \"${status}\" in ${line}`);\n }\n }\n const changedFiles = upserts.length + deletions.length;\n if (changedFiles === 0 && input.allowEmpty !== true) {\n throw new Error(\"the local commits contain no file changes\");\n }\n if (changedFiles > maxChangedFiles) {\n throw new Error(`too many changed files (${changedFiles} > ${maxChangedFiles})`);\n }\n\n const tree: GitHubTreeEntry[] = [];\n for (const path of upserts) {\n const mode = (\n await runSandboxGit({\n sandbox: input.sandbox,\n args: [\"ls-tree\", head, \"--\", path],\n })\n )\n .trim()\n .split(\" \")[0];\n if (mode === undefined || !allowedModes.has(mode)) {\n throw new Error(`unsupported file mode ${mode || \"(none)\"} for ${path}`);\n }\n const content = await runSandboxGit({\n sandbox: input.sandbox,\n args: [\"show\", `${head}:${path}`],\n });\n if (Buffer.byteLength(content, \"utf8\") > maxFileBytes) {\n throw new Error(`${path} exceeds the ${maxFileBytes} byte publication limit`);\n }\n tree.push({ path, mode: mode as \"100644\" | \"100755\", type: \"blob\", content });\n }\n for (const path of deletions) {\n tree.push({ path, mode: \"100644\", type: \"blob\", sha: null });\n }\n return { base, tree, changedFiles };\n}\n\nfunction requireSafePath(path: string | undefined): string {\n if (path === undefined || path === \"\" || !safePathPattern.test(path) || path.includes(\"..\")) {\n throw new Error(`refusing to publish unsafe path: ${path ?? \"(missing)\"}`);\n }\n return path;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { RepositorySlug } from "./schema/repository.mjs";
|
|
2
|
+
import { CommandSandbox } from "./sandbox/command.mjs";
|
|
3
|
+
//#region src/github-transfer.d.ts
|
|
4
|
+
/** Sandbox path used to read a transferred Git bundle. */
|
|
5
|
+
interface ReadGitTransferFileInput {
|
|
6
|
+
path: string;
|
|
7
|
+
}
|
|
8
|
+
/** Sandbox path and bytes used to stage a transferred Git bundle. */
|
|
9
|
+
interface WriteGitTransferFileInput {
|
|
10
|
+
path: string;
|
|
11
|
+
content: Uint8Array;
|
|
12
|
+
}
|
|
13
|
+
/** Binary file and command access used to exchange Git objects with an agent sandbox. */
|
|
14
|
+
interface GitTransferSandbox extends CommandSandbox {
|
|
15
|
+
readFile(options: ReadGitTransferFileInput): PromiseLike<ReadableStream<Uint8Array> | null>;
|
|
16
|
+
writeBinaryFile(options: WriteGitTransferFileInput): PromiseLike<void>;
|
|
17
|
+
}
|
|
18
|
+
/** Self-contained Git objects and refs transported without repository configuration or hooks. */
|
|
19
|
+
interface GitHubRepositoryBundle {
|
|
20
|
+
base64: string;
|
|
21
|
+
}
|
|
22
|
+
/** Repository and exact additional refs requested from the trusted Git transport. */
|
|
23
|
+
interface FetchGitHubBundleInput {
|
|
24
|
+
repository: RepositorySlug;
|
|
25
|
+
refs: readonly string[];
|
|
26
|
+
}
|
|
27
|
+
/** Exact branch update requested from the trusted Git transport. */
|
|
28
|
+
interface PushGitHubBundleInput {
|
|
29
|
+
repository: RepositorySlug;
|
|
30
|
+
bundle: GitHubRepositoryBundle;
|
|
31
|
+
branch: string;
|
|
32
|
+
expectedHead: string;
|
|
33
|
+
head: string;
|
|
34
|
+
}
|
|
35
|
+
/** Trusted Git transport that never enables credentials in an agent sandbox. */
|
|
36
|
+
interface GitHubGitTransport {
|
|
37
|
+
/** Read the default branch, all branch heads, and any additional exact refs with read-only credentials. */
|
|
38
|
+
fetch(input: FetchGitHubBundleInput): Promise<GitHubRepositoryBundle>;
|
|
39
|
+
/** Publish a bundle to exactly one branch with an expected remote head. */
|
|
40
|
+
push(input: PushGitHubBundleInput): Promise<void>;
|
|
41
|
+
}
|
|
42
|
+
/** Input for temporarily copying a credential-free Git bundle into a sandbox. */
|
|
43
|
+
interface WithSandboxGitBundleInput<T> {
|
|
44
|
+
sandbox: GitTransferSandbox;
|
|
45
|
+
bundle: GitHubRepositoryBundle;
|
|
46
|
+
use(path: string): Promise<T>;
|
|
47
|
+
}
|
|
48
|
+
/** One remote Git ref and its sandbox-local destination. */
|
|
49
|
+
interface GitHubRefMapping {
|
|
50
|
+
remote: string;
|
|
51
|
+
local: string;
|
|
52
|
+
}
|
|
53
|
+
/** Input for importing exact GitHub refs into a credential-free sandbox checkout. */
|
|
54
|
+
interface FetchGitHubRefsInput {
|
|
55
|
+
sandbox: GitTransferSandbox;
|
|
56
|
+
transport: GitHubGitTransport;
|
|
57
|
+
repository: RepositorySlug;
|
|
58
|
+
refs: readonly GitHubRefMapping[];
|
|
59
|
+
repositoryPath?: string;
|
|
60
|
+
}
|
|
61
|
+
/** Input for publishing the current sandbox commit to one exact GitHub branch. */
|
|
62
|
+
interface PushGitHubHeadInput {
|
|
63
|
+
sandbox: GitTransferSandbox;
|
|
64
|
+
transport: GitHubGitTransport;
|
|
65
|
+
repository: RepositorySlug;
|
|
66
|
+
branch: string;
|
|
67
|
+
expectedHead: string;
|
|
68
|
+
repositoryPath?: string;
|
|
69
|
+
}
|
|
70
|
+
//#endregion
|
|
71
|
+
export { FetchGitHubBundleInput, FetchGitHubRefsInput, GitHubGitTransport, GitHubRefMapping, GitHubRepositoryBundle, GitTransferSandbox, PushGitHubBundleInput, PushGitHubHeadInput, ReadGitTransferFileInput, WithSandboxGitBundleInput, WriteGitTransferFileInput };
|
|
72
|
+
//# sourceMappingURL=github-transfer.d.mts.map
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
//#region src/github-transfer.ts
|
|
3
|
+
/** Maximum decoded size accepted for a credential-free Git bundle transfer. */
|
|
4
|
+
const maxGitBundleBytes = 52428800;
|
|
5
|
+
/** Decode and validate a bounded Git bundle before it crosses a trust boundary. */
|
|
6
|
+
function validateGitBundle(bundle) {
|
|
7
|
+
if (bundle.base64.length > Math.ceil(52428800 / 3) * 4 || bundle.base64.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/u.test(bundle.base64)) throw new Error("Invalid or oversized Git bundle");
|
|
8
|
+
const data = Buffer.from(bundle.base64, "base64");
|
|
9
|
+
if (data.length > 52428800) throw new Error("Git bundle exceeds transfer limit");
|
|
10
|
+
if (!data.subarray(0, 32).toString().startsWith("# v2 git bundle\n") && !data.subarray(0, 32).toString().startsWith("# v3 git bundle\n")) throw new Error("Invalid Git bundle header");
|
|
11
|
+
return data;
|
|
12
|
+
}
|
|
13
|
+
/** Quote one argument for the sandbox's POSIX shell command boundary. */
|
|
14
|
+
function quoteShellArgument(value) {
|
|
15
|
+
return "'" + value.replaceAll("'", "'\"'\"'") + "'";
|
|
16
|
+
}
|
|
17
|
+
/** Run an argument vector through the sandbox command boundary without interpolating its values. */
|
|
18
|
+
async function runSandboxCommand(sandbox, command) {
|
|
19
|
+
if (command.length === 0) throw new Error("Sandbox command must contain an executable");
|
|
20
|
+
const rendered = command.map(quoteShellArgument).join(" ");
|
|
21
|
+
const result = await sandbox.run({ command: rendered });
|
|
22
|
+
if (typeof result.exitCode === "number" && result.exitCode !== 0) throw new Error(`Sandbox command failed: ${(result.stderr ?? "").trim()}`);
|
|
23
|
+
return result.stdout;
|
|
24
|
+
}
|
|
25
|
+
/** Copy a validated Git bundle into a sandbox and remove it after use. */
|
|
26
|
+
async function withSandboxGitBundle(input) {
|
|
27
|
+
const data = validateGitBundle(input.bundle);
|
|
28
|
+
const path = `/tmp/factory-${randomUUID()}.bundle`;
|
|
29
|
+
try {
|
|
30
|
+
await input.sandbox.writeBinaryFile({
|
|
31
|
+
path,
|
|
32
|
+
content: data
|
|
33
|
+
});
|
|
34
|
+
return await input.use(path);
|
|
35
|
+
} finally {
|
|
36
|
+
await runSandboxCommand(input.sandbox, [
|
|
37
|
+
"rm",
|
|
38
|
+
"-f",
|
|
39
|
+
path
|
|
40
|
+
]);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/** Import exact GitHub refs into a credential-free sandbox checkout. */
|
|
44
|
+
async function fetchGitHubRefs(input) {
|
|
45
|
+
const bundle = await input.transport.fetch({
|
|
46
|
+
repository: input.repository,
|
|
47
|
+
refs: input.refs.map((ref) => ref.remote)
|
|
48
|
+
});
|
|
49
|
+
await withSandboxGitBundle({
|
|
50
|
+
sandbox: input.sandbox,
|
|
51
|
+
bundle,
|
|
52
|
+
async use(path) {
|
|
53
|
+
await runSandboxCommand(input.sandbox, [
|
|
54
|
+
"git",
|
|
55
|
+
"-C",
|
|
56
|
+
input.repositoryPath ?? "repo",
|
|
57
|
+
"fetch",
|
|
58
|
+
"--no-tags",
|
|
59
|
+
path,
|
|
60
|
+
...input.refs.map((ref) => `+${ref.remote}:${ref.local}`)
|
|
61
|
+
]);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/** Publish the current sandbox commit with an expected-head lease. */
|
|
66
|
+
async function pushGitHubHead(input) {
|
|
67
|
+
const repositoryPath = input.repositoryPath ?? "repo";
|
|
68
|
+
const path = `/tmp/factory-${randomUUID()}.bundle`;
|
|
69
|
+
try {
|
|
70
|
+
const head = (await runSandboxCommand(input.sandbox, [
|
|
71
|
+
"git",
|
|
72
|
+
"-C",
|
|
73
|
+
repositoryPath,
|
|
74
|
+
"rev-parse",
|
|
75
|
+
"HEAD"
|
|
76
|
+
])).trim();
|
|
77
|
+
await runSandboxCommand(input.sandbox, [
|
|
78
|
+
"git",
|
|
79
|
+
"-C",
|
|
80
|
+
repositoryPath,
|
|
81
|
+
"bundle",
|
|
82
|
+
"create",
|
|
83
|
+
path,
|
|
84
|
+
"HEAD"
|
|
85
|
+
]);
|
|
86
|
+
const stream = await input.sandbox.readFile({ path });
|
|
87
|
+
if (stream === null) throw new Error("Git bundle was not created");
|
|
88
|
+
const reader = stream.getReader();
|
|
89
|
+
const chunks = [];
|
|
90
|
+
let size = 0;
|
|
91
|
+
try {
|
|
92
|
+
for (;;) {
|
|
93
|
+
const { done, value } = await reader.read();
|
|
94
|
+
if (done) break;
|
|
95
|
+
size += value.byteLength;
|
|
96
|
+
if (size > 52428800) {
|
|
97
|
+
await reader.cancel();
|
|
98
|
+
throw new Error("Git bundle exceeds transfer limit");
|
|
99
|
+
}
|
|
100
|
+
chunks.push(value);
|
|
101
|
+
}
|
|
102
|
+
} finally {
|
|
103
|
+
reader.releaseLock();
|
|
104
|
+
}
|
|
105
|
+
const bundle = { base64: Buffer.concat(chunks, size).toString("base64") };
|
|
106
|
+
validateGitBundle(bundle);
|
|
107
|
+
await input.transport.push({
|
|
108
|
+
repository: input.repository,
|
|
109
|
+
bundle,
|
|
110
|
+
branch: input.branch,
|
|
111
|
+
expectedHead: input.expectedHead,
|
|
112
|
+
head
|
|
113
|
+
});
|
|
114
|
+
} finally {
|
|
115
|
+
await runSandboxCommand(input.sandbox, [
|
|
116
|
+
"rm",
|
|
117
|
+
"-f",
|
|
118
|
+
path
|
|
119
|
+
]);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
//#endregion
|
|
123
|
+
export { fetchGitHubRefs, maxGitBundleBytes, pushGitHubHead, quoteShellArgument, runSandboxCommand, validateGitBundle, withSandboxGitBundle };
|
|
124
|
+
|
|
125
|
+
//# sourceMappingURL=github-transfer.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-transfer.mjs","names":[],"sources":["../src/github-transfer.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type { CommandSandbox } from \"./sandbox/command\";\nimport type { RepositorySlug } from \"./schema/repository\";\n\n/** Sandbox path used to read a transferred Git bundle. */\nexport interface ReadGitTransferFileInput {\n path: string;\n}\n\n/** Sandbox path and bytes used to stage a transferred Git bundle. */\nexport interface WriteGitTransferFileInput {\n path: string;\n content: Uint8Array;\n}\n\n/** Binary file and command access used to exchange Git objects with an agent sandbox. */\nexport interface GitTransferSandbox extends CommandSandbox {\n readFile(options: ReadGitTransferFileInput): PromiseLike<ReadableStream<Uint8Array> | null>;\n writeBinaryFile(options: WriteGitTransferFileInput): PromiseLike<void>;\n}\n\n/** Self-contained Git objects and refs transported without repository configuration or hooks. */\nexport interface GitHubRepositoryBundle {\n base64: string;\n}\n\n/** Repository and exact additional refs requested from the trusted Git transport. */\nexport interface FetchGitHubBundleInput {\n repository: RepositorySlug;\n refs: readonly string[];\n}\n\n/** Exact branch update requested from the trusted Git transport. */\nexport interface PushGitHubBundleInput {\n repository: RepositorySlug;\n bundle: GitHubRepositoryBundle;\n branch: string;\n expectedHead: string;\n head: string;\n}\n\n/** Trusted Git transport that never enables credentials in an agent sandbox. */\nexport interface GitHubGitTransport {\n /** Read the default branch, all branch heads, and any additional exact refs with read-only credentials. */\n fetch(input: FetchGitHubBundleInput): Promise<GitHubRepositoryBundle>;\n /** Publish a bundle to exactly one branch with an expected remote head. */\n push(input: PushGitHubBundleInput): Promise<void>;\n}\n\n/** Maximum decoded size accepted for a credential-free Git bundle transfer. */\nexport const maxGitBundleBytes = 50 * 1024 * 1024;\n\n/** Decode and validate a bounded Git bundle before it crosses a trust boundary. */\nexport function validateGitBundle(bundle: GitHubRepositoryBundle): Buffer {\n if (\n bundle.base64.length > Math.ceil(maxGitBundleBytes / 3) * 4 ||\n bundle.base64.length % 4 !== 0 ||\n !/^[A-Za-z0-9+/]*={0,2}$/u.test(bundle.base64)\n ) {\n throw new Error(\"Invalid or oversized Git bundle\");\n }\n const data = Buffer.from(bundle.base64, \"base64\");\n if (data.length > maxGitBundleBytes) throw new Error(\"Git bundle exceeds transfer limit\");\n if (\n !data.subarray(0, 32).toString().startsWith(\"# v2 git bundle\\n\") &&\n !data.subarray(0, 32).toString().startsWith(\"# v3 git bundle\\n\")\n ) {\n throw new Error(\"Invalid Git bundle header\");\n }\n return data;\n}\n\n/** Quote one argument for the sandbox's POSIX shell command boundary. */\nexport function quoteShellArgument(value: string): string {\n return \"'\" + value.replaceAll(\"'\", \"'\\\"'\\\"'\") + \"'\";\n}\n\n/** Run an argument vector through the sandbox command boundary without interpolating its values. */\nexport async function runSandboxCommand(\n sandbox: CommandSandbox,\n command: readonly string[],\n): Promise<string> {\n if (command.length === 0) throw new Error(\"Sandbox command must contain an executable\");\n const rendered = command.map(quoteShellArgument).join(\" \");\n const result = await sandbox.run({ command: rendered });\n if (typeof result.exitCode === \"number\" && result.exitCode !== 0) {\n throw new Error(`Sandbox command failed: ${(result.stderr ?? \"\").trim()}`);\n }\n return result.stdout;\n}\n\n/** Input for temporarily copying a credential-free Git bundle into a sandbox. */\nexport interface WithSandboxGitBundleInput<T> {\n sandbox: GitTransferSandbox;\n bundle: GitHubRepositoryBundle;\n use(path: string): Promise<T>;\n}\n\n/** Copy a validated Git bundle into a sandbox and remove it after use. */\nexport async function withSandboxGitBundle<T>(input: WithSandboxGitBundleInput<T>): Promise<T> {\n const data = validateGitBundle(input.bundle);\n const path = `/tmp/factory-${randomUUID()}.bundle`;\n try {\n await input.sandbox.writeBinaryFile({ path, content: data });\n return await input.use(path);\n } finally {\n await runSandboxCommand(input.sandbox, [\"rm\", \"-f\", path]);\n }\n}\n\n/** One remote Git ref and its sandbox-local destination. */\nexport interface GitHubRefMapping {\n remote: string;\n local: string;\n}\n\n/** Input for importing exact GitHub refs into a credential-free sandbox checkout. */\nexport interface FetchGitHubRefsInput {\n sandbox: GitTransferSandbox;\n transport: GitHubGitTransport;\n repository: RepositorySlug;\n refs: readonly GitHubRefMapping[];\n repositoryPath?: string;\n}\n\n/** Import exact GitHub refs into a credential-free sandbox checkout. */\nexport async function fetchGitHubRefs(input: FetchGitHubRefsInput): Promise<void> {\n const bundle = await input.transport.fetch({\n repository: input.repository,\n refs: input.refs.map((ref) => ref.remote),\n });\n await withSandboxGitBundle({\n sandbox: input.sandbox,\n bundle,\n async use(path) {\n await runSandboxCommand(input.sandbox, [\n \"git\",\n \"-C\",\n input.repositoryPath ?? \"repo\",\n \"fetch\",\n \"--no-tags\",\n path,\n ...input.refs.map((ref) => `+${ref.remote}:${ref.local}`),\n ]);\n },\n });\n}\n\n/** Input for publishing the current sandbox commit to one exact GitHub branch. */\nexport interface PushGitHubHeadInput {\n sandbox: GitTransferSandbox;\n transport: GitHubGitTransport;\n repository: RepositorySlug;\n branch: string;\n expectedHead: string;\n repositoryPath?: string;\n}\n\n/** Publish the current sandbox commit with an expected-head lease. */\nexport async function pushGitHubHead(input: PushGitHubHeadInput): Promise<void> {\n const repositoryPath = input.repositoryPath ?? \"repo\";\n const path = `/tmp/factory-${randomUUID()}.bundle`;\n try {\n const head = (\n await runSandboxCommand(input.sandbox, [\"git\", \"-C\", repositoryPath, \"rev-parse\", \"HEAD\"])\n ).trim();\n await runSandboxCommand(input.sandbox, [\n \"git\",\n \"-C\",\n repositoryPath,\n \"bundle\",\n \"create\",\n path,\n \"HEAD\",\n ]);\n const stream = await input.sandbox.readFile({ path });\n if (stream === null) throw new Error(\"Git bundle was not created\");\n const reader = stream.getReader();\n const chunks: Uint8Array[] = [];\n let size = 0;\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n size += value.byteLength;\n if (size > maxGitBundleBytes) {\n await reader.cancel();\n throw new Error(\"Git bundle exceeds transfer limit\");\n }\n chunks.push(value);\n }\n } finally {\n reader.releaseLock();\n }\n const bundle = { base64: Buffer.concat(chunks, size).toString(\"base64\") };\n validateGitBundle(bundle);\n await input.transport.push({\n repository: input.repository,\n bundle,\n branch: input.branch,\n expectedHead: input.expectedHead,\n head,\n });\n } finally {\n await runSandboxCommand(input.sandbox, [\"rm\", \"-f\", path]);\n }\n}\n"],"mappings":"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"}
|