@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,363 @@
|
|
|
1
|
+
import { repositorySlugSchema } from "./schema/repository.mjs";
|
|
2
|
+
import { isSafeGitRef } from "./github-publication.mjs";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
//#region src/vercel-github-api.ts
|
|
5
|
+
/** GitHub API failure returned through the managed credential Sandbox. */
|
|
6
|
+
var VercelManagedGitHubApiError = class extends Error {
|
|
7
|
+
status;
|
|
8
|
+
constructor(status, message) {
|
|
9
|
+
super(`GitHub API request failed (${status}): ${message}`);
|
|
10
|
+
this.status = status;
|
|
11
|
+
this.name = "VercelManagedGitHubApiError";
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
const sandboxResponseSchema = z.object({
|
|
15
|
+
status: z.number().int().min(100).max(599),
|
|
16
|
+
body: z.unknown()
|
|
17
|
+
});
|
|
18
|
+
const issueSchema = z.object({
|
|
19
|
+
title: z.string(),
|
|
20
|
+
body: z.string().nullable(),
|
|
21
|
+
html_url: z.url(),
|
|
22
|
+
pull_request: z.unknown().optional()
|
|
23
|
+
});
|
|
24
|
+
const pullRequestSchema = z.object({
|
|
25
|
+
number: z.number().int().positive(),
|
|
26
|
+
html_url: z.url(),
|
|
27
|
+
draft: z.boolean()
|
|
28
|
+
});
|
|
29
|
+
const shaSchema = z.string().regex(/^[a-f0-9]{40}$/u);
|
|
30
|
+
const commitSchema = z.object({
|
|
31
|
+
sha: shaSchema,
|
|
32
|
+
tree: z.object({ sha: shaSchema }),
|
|
33
|
+
parents: z.array(z.object({ sha: shaSchema }))
|
|
34
|
+
});
|
|
35
|
+
const treeSchema = z.object({ sha: shaSchema });
|
|
36
|
+
const refSchema = z.object({ object: z.object({ sha: shaSchema }) });
|
|
37
|
+
const publicationPullSchema = pullRequestSchema.extend({
|
|
38
|
+
state: z.enum(["open", "closed"]),
|
|
39
|
+
head: z.object({
|
|
40
|
+
ref: z.string(),
|
|
41
|
+
sha: shaSchema
|
|
42
|
+
})
|
|
43
|
+
});
|
|
44
|
+
const publicationPathSchema = z.string().min(1).max(1024).refine((path) => Buffer.byteLength(path, "utf8") <= 1024, { message: "Managed publication path exceeds byte limit" }).refine((path) => /^[A-Za-z0-9.][A-Za-z0-9._/-]*$/u.test(path) && !path.includes("..") && !path.includes("//") && !path.endsWith("/") && !path.split("/").some((part) => part === "."), { message: "Invalid managed publication path" });
|
|
45
|
+
const publicationBranchSchema = z.string().min(1).max(256).refine((branch) => isSafeGitRef(branch) && branch.split("/").every((component) => component.length > 0 && !component.startsWith(".") && !component.endsWith(".") && !component.endsWith(".lock")), { message: "Invalid managed publication branch" });
|
|
46
|
+
const publicationTextSchema = (maximum, field) => z.string().max(maximum).refine((value) => Buffer.byteLength(value, "utf8") <= maximum, { message: `Managed publication ${field} exceeds byte limit` });
|
|
47
|
+
const publicationCommitMessageSchema = publicationTextSchema(65536, "commit message").min(1);
|
|
48
|
+
const publicationTitleSchema = publicationTextSchema(256, "title").min(1);
|
|
49
|
+
const publicationBodySchema = publicationTextSchema(65536, "body");
|
|
50
|
+
const publicationBaseBranchSchema = z.string().min(1).max(256).refine((branch) => isSafeGitRef(branch), { message: "Invalid managed publication base branch" });
|
|
51
|
+
const publicationContentSchema = z.string().max(2e5).refine((content) => Buffer.byteLength(content, "utf8") <= 2e5, { message: "Managed publication content exceeds byte limit" });
|
|
52
|
+
const publicationTreeSchema = z.array(z.union([z.strictObject({
|
|
53
|
+
path: publicationPathSchema,
|
|
54
|
+
mode: z.enum(["100644", "100755"]),
|
|
55
|
+
type: z.literal("blob"),
|
|
56
|
+
content: publicationContentSchema
|
|
57
|
+
}), z.strictObject({
|
|
58
|
+
path: publicationPathSchema,
|
|
59
|
+
mode: z.enum(["100644", "100755"]),
|
|
60
|
+
type: z.literal("blob"),
|
|
61
|
+
sha: z.null()
|
|
62
|
+
})])).min(1).max(25).refine((entries) => new TextEncoder().encode(JSON.stringify({ tree: entries })).byteLength <= 1e6, "Managed publication tree exceeds transfer limit");
|
|
63
|
+
const githubRequestScript = `
|
|
64
|
+
const request = JSON.parse(process.argv[1]);
|
|
65
|
+
const response = await fetch(request.url, {
|
|
66
|
+
method: request.method,
|
|
67
|
+
headers: {
|
|
68
|
+
accept: "application/vnd.github+json",
|
|
69
|
+
"content-type": "application/json",
|
|
70
|
+
"x-github-api-version": "2022-11-28",
|
|
71
|
+
},
|
|
72
|
+
body: request.body === undefined ? undefined : JSON.stringify(request.body),
|
|
73
|
+
redirect: "error",
|
|
74
|
+
});
|
|
75
|
+
const reader = response.body?.getReader();
|
|
76
|
+
const chunks = [];
|
|
77
|
+
let byteLength = 0;
|
|
78
|
+
if (reader) {
|
|
79
|
+
for (;;) {
|
|
80
|
+
const { done, value } = await reader.read();
|
|
81
|
+
if (done) break;
|
|
82
|
+
byteLength += value.byteLength;
|
|
83
|
+
if (byteLength > 1_000_000) {
|
|
84
|
+
await reader.cancel();
|
|
85
|
+
throw new Error("GitHub API response exceeds transfer limit");
|
|
86
|
+
}
|
|
87
|
+
chunks.push(value);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const bytes = new Uint8Array(byteLength);
|
|
91
|
+
let offset = 0;
|
|
92
|
+
for (const chunk of chunks) { bytes.set(chunk, offset); offset += chunk.byteLength; }
|
|
93
|
+
const text = new TextDecoder().decode(bytes);
|
|
94
|
+
let body = null;
|
|
95
|
+
try { body = text === "" ? null : JSON.parse(text); } catch { body = { message: text }; }
|
|
96
|
+
process.stdout.write(JSON.stringify({ status: response.status, body }));
|
|
97
|
+
`;
|
|
98
|
+
async function createManagedSandbox(input) {
|
|
99
|
+
const { Sandbox } = await import("@vercel/sandbox");
|
|
100
|
+
return Sandbox.create({ ...input });
|
|
101
|
+
}
|
|
102
|
+
function createInput(repository, action) {
|
|
103
|
+
return {
|
|
104
|
+
__credentials: { github: [{
|
|
105
|
+
repositories: [repository],
|
|
106
|
+
actions: [action]
|
|
107
|
+
}] },
|
|
108
|
+
networkPolicy: { allow: ["api.github.com"] },
|
|
109
|
+
persistent: false,
|
|
110
|
+
resources: { vcpus: 6 },
|
|
111
|
+
runtime: "node24",
|
|
112
|
+
timeout: 6e4
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function createPublicationInput(repository, commitIdentity) {
|
|
116
|
+
return {
|
|
117
|
+
source: {
|
|
118
|
+
type: "git",
|
|
119
|
+
url: `https://github.com/${repository}.git`
|
|
120
|
+
},
|
|
121
|
+
__source_credentials: true,
|
|
122
|
+
__commitAs: commitIdentity,
|
|
123
|
+
__credentials: { github: [{
|
|
124
|
+
repositories: [repository],
|
|
125
|
+
actions: ["github:pull-request:create"]
|
|
126
|
+
}] },
|
|
127
|
+
networkPolicy: { allow: ["github.com", "api.github.com"] },
|
|
128
|
+
persistent: false,
|
|
129
|
+
resources: { vcpus: 6 },
|
|
130
|
+
runtime: "node24",
|
|
131
|
+
timeout: 18e4
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
async function request(createSandbox, input) {
|
|
135
|
+
const sandbox = await createSandbox(createInput(input.repository, input.action));
|
|
136
|
+
try {
|
|
137
|
+
await input.authorize();
|
|
138
|
+
const result = await sandbox.runCommand({
|
|
139
|
+
cmd: "node",
|
|
140
|
+
args: [
|
|
141
|
+
"--input-type=module",
|
|
142
|
+
"--eval",
|
|
143
|
+
githubRequestScript,
|
|
144
|
+
JSON.stringify({
|
|
145
|
+
method: input.method,
|
|
146
|
+
url: `https://api.github.com/repos/${input.repository}${input.path}`,
|
|
147
|
+
...input.body === void 0 ? {} : { body: input.body }
|
|
148
|
+
})
|
|
149
|
+
],
|
|
150
|
+
timeoutMs: 3e4
|
|
151
|
+
});
|
|
152
|
+
const stderr = (await result.stderr()).trim();
|
|
153
|
+
if (result.exitCode !== 0) throw new Error(`Managed GitHub API operation failed (${result.exitCode}): ${stderr}`);
|
|
154
|
+
const response = sandboxResponseSchema.parse(JSON.parse((await result.stdout()).trim()));
|
|
155
|
+
if (response.status < 200 || response.status >= 300) {
|
|
156
|
+
const message = z.object({ message: z.string() }).safeParse(response.body);
|
|
157
|
+
throw new VercelManagedGitHubApiError(response.status, message.success ? message.data.message : "Unexpected response");
|
|
158
|
+
}
|
|
159
|
+
return response.body;
|
|
160
|
+
} finally {
|
|
161
|
+
await sandbox.stop();
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
async function sandboxRequest(sandbox, input) {
|
|
165
|
+
const result = await sandbox.runCommand({
|
|
166
|
+
cmd: "node",
|
|
167
|
+
args: [
|
|
168
|
+
"--input-type=module",
|
|
169
|
+
"--eval",
|
|
170
|
+
githubRequestScript,
|
|
171
|
+
JSON.stringify({
|
|
172
|
+
method: input.method,
|
|
173
|
+
url: `https://api.github.com/repos/${input.repository}${input.path}`,
|
|
174
|
+
...input.body === void 0 ? {} : { body: input.body }
|
|
175
|
+
})
|
|
176
|
+
],
|
|
177
|
+
timeoutMs: 3e4
|
|
178
|
+
});
|
|
179
|
+
const stderr = (await result.stderr()).trim();
|
|
180
|
+
if (result.exitCode !== 0) throw new Error(`Managed GitHub API operation failed (${result.exitCode}): ${stderr}`);
|
|
181
|
+
const response = sandboxResponseSchema.parse(JSON.parse((await result.stdout()).trim()));
|
|
182
|
+
if (response.status < 200 || response.status >= 300) {
|
|
183
|
+
const message = z.object({ message: z.string() }).safeParse(response.body);
|
|
184
|
+
throw new VercelManagedGitHubApiError(response.status, message.success ? message.data.message : "Unexpected response");
|
|
185
|
+
}
|
|
186
|
+
return response.body;
|
|
187
|
+
}
|
|
188
|
+
/** Create repository-scoped GitHub API operations backed by managed Sandbox credentials. */
|
|
189
|
+
function createVercelManagedGitHubApi(options = {}) {
|
|
190
|
+
const createSandbox = options.createSandbox ?? createManagedSandbox;
|
|
191
|
+
return {
|
|
192
|
+
async readIssue(input) {
|
|
193
|
+
const repository = repositorySlugSchema.parse(input.repository.toLowerCase());
|
|
194
|
+
if (!Number.isSafeInteger(input.issueNumber) || input.issueNumber < 1) throw new Error("Invalid GitHub issue number");
|
|
195
|
+
const issue = issueSchema.parse(await request(createSandbox, {
|
|
196
|
+
repository,
|
|
197
|
+
action: "github:issues:read",
|
|
198
|
+
method: "GET",
|
|
199
|
+
path: `/issues/${input.issueNumber}`,
|
|
200
|
+
authorize: input.authorize
|
|
201
|
+
}));
|
|
202
|
+
return {
|
|
203
|
+
title: issue.title,
|
|
204
|
+
body: issue.body,
|
|
205
|
+
url: issue.html_url,
|
|
206
|
+
pullRequest: issue.pull_request !== void 0
|
|
207
|
+
};
|
|
208
|
+
},
|
|
209
|
+
async createPullRequest(input) {
|
|
210
|
+
const repository = repositorySlugSchema.parse(input.repository.toLowerCase());
|
|
211
|
+
const head = publicationBranchSchema.parse(input.head);
|
|
212
|
+
const base = publicationBaseBranchSchema.parse(input.base);
|
|
213
|
+
const title = publicationTitleSchema.parse(input.title);
|
|
214
|
+
const body = publicationBodySchema.parse(input.body);
|
|
215
|
+
const pull = pullRequestSchema.parse(await request(createSandbox, {
|
|
216
|
+
repository,
|
|
217
|
+
action: "github:pull-request:create",
|
|
218
|
+
method: "POST",
|
|
219
|
+
path: "/pulls",
|
|
220
|
+
body: {
|
|
221
|
+
title,
|
|
222
|
+
body,
|
|
223
|
+
head,
|
|
224
|
+
base,
|
|
225
|
+
draft: input.draft
|
|
226
|
+
},
|
|
227
|
+
authorize: input.authorize
|
|
228
|
+
}));
|
|
229
|
+
return {
|
|
230
|
+
pullRequestNumber: pull.number,
|
|
231
|
+
pullRequestUrl: pull.html_url,
|
|
232
|
+
draft: pull.draft
|
|
233
|
+
};
|
|
234
|
+
},
|
|
235
|
+
async publishPullRequest(input) {
|
|
236
|
+
const repository = repositorySlugSchema.parse(input.repository.toLowerCase());
|
|
237
|
+
if (!options.commitIdentity) throw new Error("Managed publication requires commit identity");
|
|
238
|
+
if (!/^[a-f0-9]{40}$/u.test(input.baseCommit) || input.commitMessage.trim() === "") throw new Error("Invalid managed GitHub publication");
|
|
239
|
+
const publicationTree = publicationTreeSchema.parse(input.tree);
|
|
240
|
+
const branch = publicationBranchSchema.parse(input.branch);
|
|
241
|
+
const baseBranch = publicationBaseBranchSchema.parse(input.baseBranch);
|
|
242
|
+
const title = publicationTitleSchema.parse(input.title);
|
|
243
|
+
const body = publicationBodySchema.parse(input.body);
|
|
244
|
+
const commitMessage = publicationCommitMessageSchema.parse(`${input.commitMessage}\n\nCo-authored-by: ${options.commitIdentity.name} <${options.commitIdentity.email}>`);
|
|
245
|
+
const sandbox = await createSandbox(createPublicationInput(repository, options.commitIdentity));
|
|
246
|
+
try {
|
|
247
|
+
const authorizedRequest = async (request) => {
|
|
248
|
+
await input.authorize();
|
|
249
|
+
return sandboxRequest(sandbox, {
|
|
250
|
+
repository,
|
|
251
|
+
...request
|
|
252
|
+
});
|
|
253
|
+
};
|
|
254
|
+
const base = commitSchema.parse(await authorizedRequest({
|
|
255
|
+
method: "GET",
|
|
256
|
+
path: `/git/commits/${input.baseCommit}`
|
|
257
|
+
}));
|
|
258
|
+
const tree = treeSchema.parse(await authorizedRequest({
|
|
259
|
+
method: "POST",
|
|
260
|
+
path: "/git/trees",
|
|
261
|
+
body: {
|
|
262
|
+
base_tree: base.tree.sha,
|
|
263
|
+
tree: publicationTree
|
|
264
|
+
}
|
|
265
|
+
}));
|
|
266
|
+
const pullPath = `/pulls?${new URLSearchParams({
|
|
267
|
+
state: "all",
|
|
268
|
+
head: `${repository.split("/")[0]}:${branch}`,
|
|
269
|
+
per_page: "100"
|
|
270
|
+
})}`;
|
|
271
|
+
const pulls = async () => z.array(publicationPullSchema).parse(await authorizedRequest({
|
|
272
|
+
method: "GET",
|
|
273
|
+
path: pullPath
|
|
274
|
+
}));
|
|
275
|
+
const result = (pull, commitSha) => ({
|
|
276
|
+
commitSha,
|
|
277
|
+
pullRequestNumber: pull.number,
|
|
278
|
+
pullRequestUrl: pull.html_url,
|
|
279
|
+
draft: pull.draft
|
|
280
|
+
});
|
|
281
|
+
const refPath = `/git/ref/heads/${branch.split("/").map(encodeURIComponent).join("/")}`;
|
|
282
|
+
let existingRef;
|
|
283
|
+
try {
|
|
284
|
+
existingRef = refSchema.parse(await authorizedRequest({
|
|
285
|
+
method: "GET",
|
|
286
|
+
path: refPath
|
|
287
|
+
}));
|
|
288
|
+
} catch (error) {
|
|
289
|
+
if (!(error instanceof VercelManagedGitHubApiError) || error.status !== 404) throw error;
|
|
290
|
+
existingRef = null;
|
|
291
|
+
}
|
|
292
|
+
let commitSha = existingRef?.object.sha;
|
|
293
|
+
if (commitSha) {
|
|
294
|
+
const existingPull = (await pulls()).find((pull) => pull.head.ref === branch);
|
|
295
|
+
if (existingPull) {
|
|
296
|
+
if (existingPull.state !== "open") throw new Error("Managed publication pull request is closed");
|
|
297
|
+
const existingCommit = commitSchema.parse(await authorizedRequest({
|
|
298
|
+
method: "GET",
|
|
299
|
+
path: `/git/commits/${existingPull.head.sha}`
|
|
300
|
+
}));
|
|
301
|
+
if (existingCommit.tree.sha !== tree.sha || existingCommit.parents.length !== 1 || existingCommit.parents[0]?.sha !== input.baseCommit) throw new Error("Managed publication pull request contains different changes");
|
|
302
|
+
return result(existingPull, existingPull.head.sha);
|
|
303
|
+
}
|
|
304
|
+
const existingCommit = commitSchema.parse(await authorizedRequest({
|
|
305
|
+
method: "GET",
|
|
306
|
+
path: `/git/commits/${commitSha}`
|
|
307
|
+
}));
|
|
308
|
+
if (existingCommit.tree.sha !== tree.sha || existingCommit.parents.length !== 1 || existingCommit.parents[0]?.sha !== input.baseCommit) throw new Error("Managed publication branch contains different changes");
|
|
309
|
+
} else {
|
|
310
|
+
commitSha = commitSchema.parse(await authorizedRequest({
|
|
311
|
+
method: "POST",
|
|
312
|
+
path: "/git/commits",
|
|
313
|
+
body: {
|
|
314
|
+
message: commitMessage,
|
|
315
|
+
tree: tree.sha,
|
|
316
|
+
parents: [input.baseCommit]
|
|
317
|
+
}
|
|
318
|
+
})).sha;
|
|
319
|
+
try {
|
|
320
|
+
await authorizedRequest({
|
|
321
|
+
method: "POST",
|
|
322
|
+
path: "/git/refs",
|
|
323
|
+
body: {
|
|
324
|
+
ref: `refs/heads/${branch}`,
|
|
325
|
+
sha: commitSha
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
} catch (error) {
|
|
329
|
+
if (refSchema.parse(await authorizedRequest({
|
|
330
|
+
method: "GET",
|
|
331
|
+
path: refPath
|
|
332
|
+
})).object.sha !== commitSha) throw error;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
let pull;
|
|
336
|
+
try {
|
|
337
|
+
pull = pullRequestSchema.parse(await authorizedRequest({
|
|
338
|
+
method: "POST",
|
|
339
|
+
path: "/pulls",
|
|
340
|
+
body: {
|
|
341
|
+
title,
|
|
342
|
+
body,
|
|
343
|
+
head: branch,
|
|
344
|
+
base: baseBranch,
|
|
345
|
+
draft: input.draft
|
|
346
|
+
}
|
|
347
|
+
}));
|
|
348
|
+
} catch (error) {
|
|
349
|
+
const reconciled = (await pulls()).find((candidate) => candidate.head.ref === branch);
|
|
350
|
+
if (!reconciled || reconciled.state !== "open" || reconciled.head.sha !== commitSha) throw error;
|
|
351
|
+
pull = reconciled;
|
|
352
|
+
}
|
|
353
|
+
return result(pull, commitSha);
|
|
354
|
+
} finally {
|
|
355
|
+
await sandbox.stop();
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
//#endregion
|
|
361
|
+
export { VercelManagedGitHubApiError, createVercelManagedGitHubApi };
|
|
362
|
+
|
|
363
|
+
//# sourceMappingURL=vercel-github-api.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vercel-github-api.mjs","names":[],"sources":["../src/vercel-github-api.ts"],"sourcesContent":["import type { Sandbox, NetworkPolicy } from \"@vercel/sandbox\";\nimport { z } from \"zod\";\nimport { isSafeGitRef, type GitHubTreeEntry } from \"./github-publication\";\nimport { repositorySlugSchema, type RepositorySlug } from \"./schema/repository\";\n\ntype TrustedGitHubApiSandbox = Pick<Sandbox, \"runCommand\" | \"stop\">;\n\n/** GitHub API actions supported by Vercel-managed Sandbox credentials. */\nexport type VercelManagedGitHubApiAction = \"github:issues:read\" | \"github:pull-request:create\";\n\n/** Exact creation request for one Vercel-managed GitHub API operation. */\nexport interface VercelManagedGitHubApiSandboxCreateInput {\n source?: {\n type: \"git\";\n url: string;\n };\n __source_credentials?: true;\n __commitAs?: {\n name: string;\n email: string;\n };\n __credentials: {\n github: [\n {\n repositories: [RepositorySlug];\n actions: [VercelManagedGitHubApiAction];\n },\n ];\n };\n networkPolicy: NetworkPolicy;\n persistent: false;\n resources: { vcpus: 6 };\n runtime: \"node24\";\n timeout: 60_000 | 180_000;\n}\n\n/** Configures fresh trusted Sandboxes for brokered GitHub API requests. */\nexport interface VercelManagedGitHubApiOptions {\n /** Attribution metadata supplied when managed publication creates a signed commit. */\n commitIdentity?: { name: string; email: string };\n createSandbox?: (\n input: VercelManagedGitHubApiSandboxCreateInput,\n ) => Promise<TrustedGitHubApiSandbox>;\n}\n\n/** Authorized request to read one exact GitHub issue. */\nexport interface VercelManagedGitHubIssueInput {\n repository: RepositorySlug;\n issueNumber: number;\n authorize(): Promise<void>;\n}\n\n/** Issue fields returned by a Vercel-managed GitHub API request. */\nexport interface VercelManagedGitHubIssue {\n title: string;\n body: string | null;\n url: string;\n pullRequest: boolean;\n}\n\n/** Authorized request to create one draft or ready GitHub pull request. */\nexport interface VercelManagedGitHubPullRequestInput {\n repository: RepositorySlug;\n title: string;\n body: string;\n head: string;\n base: string;\n draft: boolean;\n authorize(): Promise<void>;\n}\n\n/** Pull-request identity returned by a Vercel-managed GitHub API request. */\nexport interface VercelManagedGitHubPullRequest {\n pullRequestNumber: number;\n pullRequestUrl: string;\n draft: boolean;\n}\n\n/** Git Data and pull-request inputs for one idempotent managed publication. */\nexport interface VercelManagedGitHubPublicationInput {\n repository: RepositorySlug;\n baseCommit: string;\n tree: readonly GitHubTreeEntry[];\n commitMessage: string;\n branch: string;\n title: string;\n body: string;\n baseBranch: string;\n draft: boolean;\n authorize(): Promise<void>;\n}\n\n/** Commit and pull-request identities returned after managed publication. */\nexport interface VercelManagedGitHubPublication extends VercelManagedGitHubPullRequest {\n commitSha: string;\n}\n\n/** Repository-scoped brokered GitHub API operations supplied by Vercel Sandbox. */\nexport interface VercelManagedGitHubApi {\n readIssue(input: VercelManagedGitHubIssueInput): Promise<VercelManagedGitHubIssue>;\n createPullRequest(\n input: VercelManagedGitHubPullRequestInput,\n ): Promise<VercelManagedGitHubPullRequest>;\n publishPullRequest(\n input: VercelManagedGitHubPublicationInput,\n ): Promise<VercelManagedGitHubPublication>;\n}\n\n/** GitHub API failure returned through the managed credential Sandbox. */\nexport class VercelManagedGitHubApiError extends Error {\n constructor(\n readonly status: number,\n message: string,\n ) {\n super(`GitHub API request failed (${status}): ${message}`);\n this.name = \"VercelManagedGitHubApiError\";\n }\n}\n\nconst sandboxResponseSchema = z.object({\n status: z.number().int().min(100).max(599),\n body: z.unknown(),\n});\nconst issueSchema = z.object({\n title: z.string(),\n body: z.string().nullable(),\n html_url: z.url(),\n pull_request: z.unknown().optional(),\n});\nconst pullRequestSchema = z.object({\n number: z.number().int().positive(),\n html_url: z.url(),\n draft: z.boolean(),\n});\nconst shaSchema = z.string().regex(/^[a-f0-9]{40}$/u);\nconst commitSchema = z.object({\n sha: shaSchema,\n tree: z.object({ sha: shaSchema }),\n parents: z.array(z.object({ sha: shaSchema })),\n});\nconst treeSchema = z.object({ sha: shaSchema });\nconst refSchema = z.object({ object: z.object({ sha: shaSchema }) });\nconst publicationPullSchema = pullRequestSchema.extend({\n state: z.enum([\"open\", \"closed\"]),\n head: z.object({ ref: z.string(), sha: shaSchema }),\n});\nconst publicationPathSchema = z\n .string()\n .min(1)\n .max(1_024)\n .refine((path) => Buffer.byteLength(path, \"utf8\") <= 1_024, {\n message: \"Managed publication path exceeds byte limit\",\n })\n .refine(\n (path) =>\n /^[A-Za-z0-9.][A-Za-z0-9._/-]*$/u.test(path) &&\n !path.includes(\"..\") &&\n !path.includes(\"//\") &&\n !path.endsWith(\"/\") &&\n !path.split(\"/\").some((part) => part === \".\"),\n { message: \"Invalid managed publication path\" },\n );\nconst publicationBranchSchema = z\n .string()\n .min(1)\n .max(256)\n .refine(\n (branch) =>\n isSafeGitRef(branch) &&\n branch\n .split(\"/\")\n .every(\n (component) =>\n component.length > 0 &&\n !component.startsWith(\".\") &&\n !component.endsWith(\".\") &&\n !component.endsWith(\".lock\"),\n ),\n { message: \"Invalid managed publication branch\" },\n );\nconst publicationTextSchema = (maximum: number, field: string) =>\n z\n .string()\n .max(maximum)\n .refine((value) => Buffer.byteLength(value, \"utf8\") <= maximum, {\n message: `Managed publication ${field} exceeds byte limit`,\n });\nconst publicationCommitMessageSchema = publicationTextSchema(65_536, \"commit message\").min(1);\nconst publicationTitleSchema = publicationTextSchema(256, \"title\").min(1);\nconst publicationBodySchema = publicationTextSchema(65_536, \"body\");\nconst publicationBaseBranchSchema = z\n .string()\n .min(1)\n .max(256)\n .refine((branch) => isSafeGitRef(branch), {\n message: \"Invalid managed publication base branch\",\n });\nconst publicationContentSchema = z\n .string()\n .max(200_000)\n .refine((content) => Buffer.byteLength(content, \"utf8\") <= 200_000, {\n message: \"Managed publication content exceeds byte limit\",\n });\nconst publicationTreeSchema = z\n .array(\n z.union([\n z.strictObject({\n path: publicationPathSchema,\n mode: z.enum([\"100644\", \"100755\"]),\n type: z.literal(\"blob\"),\n content: publicationContentSchema,\n }),\n z.strictObject({\n path: publicationPathSchema,\n mode: z.enum([\"100644\", \"100755\"]),\n type: z.literal(\"blob\"),\n sha: z.null(),\n }),\n ]),\n )\n .min(1)\n .max(25)\n .refine(\n (entries) =>\n new TextEncoder().encode(JSON.stringify({ tree: entries })).byteLength <= 1_000_000,\n \"Managed publication tree exceeds transfer limit\",\n );\nconst githubRequestScript = `\nconst request = JSON.parse(process.argv[1]);\nconst response = await fetch(request.url, {\n method: request.method,\n headers: {\n accept: \"application/vnd.github+json\",\n \"content-type\": \"application/json\",\n \"x-github-api-version\": \"2022-11-28\",\n },\n body: request.body === undefined ? undefined : JSON.stringify(request.body),\n redirect: \"error\",\n});\nconst reader = response.body?.getReader();\nconst chunks = [];\nlet byteLength = 0;\nif (reader) {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n byteLength += value.byteLength;\n if (byteLength > 1_000_000) {\n await reader.cancel();\n throw new Error(\"GitHub API response exceeds transfer limit\");\n }\n chunks.push(value);\n }\n}\nconst bytes = new Uint8Array(byteLength);\nlet offset = 0;\nfor (const chunk of chunks) { bytes.set(chunk, offset); offset += chunk.byteLength; }\nconst text = new TextDecoder().decode(bytes);\nlet body = null;\ntry { body = text === \"\" ? null : JSON.parse(text); } catch { body = { message: text }; }\nprocess.stdout.write(JSON.stringify({ status: response.status, body }));\n`;\n\nasync function createManagedSandbox(\n input: VercelManagedGitHubApiSandboxCreateInput,\n): Promise<TrustedGitHubApiSandbox> {\n const { Sandbox } = await import(\"@vercel/sandbox\");\n return Sandbox.create({ ...input });\n}\n\nfunction createInput(\n repository: RepositorySlug,\n action: VercelManagedGitHubApiAction,\n): VercelManagedGitHubApiSandboxCreateInput {\n return {\n __credentials: { github: [{ repositories: [repository], actions: [action] }] },\n networkPolicy: { allow: [\"api.github.com\"] },\n persistent: false,\n resources: { vcpus: 6 },\n runtime: \"node24\",\n timeout: 60_000,\n };\n}\n\nfunction createPublicationInput(\n repository: RepositorySlug,\n commitIdentity: { name: string; email: string },\n): VercelManagedGitHubApiSandboxCreateInput {\n return {\n source: { type: \"git\", url: `https://github.com/${repository}.git` },\n __source_credentials: true,\n __commitAs: commitIdentity,\n __credentials: {\n github: [\n {\n repositories: [repository],\n actions: [\"github:pull-request:create\"],\n },\n ],\n },\n networkPolicy: { allow: [\"github.com\", \"api.github.com\"] },\n persistent: false,\n resources: { vcpus: 6 },\n runtime: \"node24\",\n timeout: 180_000,\n };\n}\n\nasync function request(\n createSandbox: (\n input: VercelManagedGitHubApiSandboxCreateInput,\n ) => Promise<TrustedGitHubApiSandbox>,\n input: {\n repository: RepositorySlug;\n action: VercelManagedGitHubApiAction;\n method: \"GET\" | \"POST\";\n path: string;\n body?: unknown;\n authorize(): Promise<void>;\n },\n): Promise<unknown> {\n const sandbox = await createSandbox(createInput(input.repository, input.action));\n try {\n await input.authorize();\n const result = await sandbox.runCommand({\n cmd: \"node\",\n args: [\n \"--input-type=module\",\n \"--eval\",\n githubRequestScript,\n JSON.stringify({\n method: input.method,\n url: `https://api.github.com/repos/${input.repository}${input.path}`,\n ...(input.body === undefined ? {} : { body: input.body }),\n }),\n ],\n timeoutMs: 30_000,\n });\n const stderr = (await result.stderr()).trim();\n if (result.exitCode !== 0) {\n throw new Error(`Managed GitHub API operation failed (${result.exitCode}): ${stderr}`);\n }\n const response = sandboxResponseSchema.parse(JSON.parse((await result.stdout()).trim()));\n if (response.status < 200 || response.status >= 300) {\n const message = z.object({ message: z.string() }).safeParse(response.body);\n throw new VercelManagedGitHubApiError(\n response.status,\n message.success ? message.data.message : \"Unexpected response\",\n );\n }\n return response.body;\n } finally {\n await sandbox.stop();\n }\n}\n\nasync function sandboxRequest(\n sandbox: TrustedGitHubApiSandbox,\n input: {\n repository: RepositorySlug;\n method: \"GET\" | \"POST\";\n path: string;\n body?: unknown;\n },\n): Promise<unknown> {\n const result = await sandbox.runCommand({\n cmd: \"node\",\n args: [\n \"--input-type=module\",\n \"--eval\",\n githubRequestScript,\n JSON.stringify({\n method: input.method,\n url: `https://api.github.com/repos/${input.repository}${input.path}`,\n ...(input.body === undefined ? {} : { body: input.body }),\n }),\n ],\n timeoutMs: 30_000,\n });\n const stderr = (await result.stderr()).trim();\n if (result.exitCode !== 0) {\n throw new Error(`Managed GitHub API operation failed (${result.exitCode}): ${stderr}`);\n }\n const response = sandboxResponseSchema.parse(JSON.parse((await result.stdout()).trim()));\n if (response.status < 200 || response.status >= 300) {\n const message = z.object({ message: z.string() }).safeParse(response.body);\n throw new VercelManagedGitHubApiError(\n response.status,\n message.success ? message.data.message : \"Unexpected response\",\n );\n }\n return response.body;\n}\n\n/** Create repository-scoped GitHub API operations backed by managed Sandbox credentials. */\nexport function createVercelManagedGitHubApi(\n options: VercelManagedGitHubApiOptions = {},\n): VercelManagedGitHubApi {\n const createSandbox = options.createSandbox ?? createManagedSandbox;\n return {\n async readIssue(input) {\n const repository = repositorySlugSchema.parse(input.repository.toLowerCase());\n if (!Number.isSafeInteger(input.issueNumber) || input.issueNumber < 1) {\n throw new Error(\"Invalid GitHub issue number\");\n }\n const issue = issueSchema.parse(\n await request(createSandbox, {\n repository,\n action: \"github:issues:read\",\n method: \"GET\",\n path: `/issues/${input.issueNumber}`,\n authorize: input.authorize,\n }),\n );\n return {\n title: issue.title,\n body: issue.body,\n url: issue.html_url,\n pullRequest: issue.pull_request !== undefined,\n };\n },\n async createPullRequest(input) {\n const repository = repositorySlugSchema.parse(input.repository.toLowerCase());\n const head = publicationBranchSchema.parse(input.head);\n const base = publicationBaseBranchSchema.parse(input.base);\n const title = publicationTitleSchema.parse(input.title);\n const body = publicationBodySchema.parse(input.body);\n const pull = pullRequestSchema.parse(\n await request(createSandbox, {\n repository,\n action: \"github:pull-request:create\",\n method: \"POST\",\n path: \"/pulls\",\n body: {\n title,\n body,\n head,\n base,\n draft: input.draft,\n },\n authorize: input.authorize,\n }),\n );\n return {\n pullRequestNumber: pull.number,\n pullRequestUrl: pull.html_url,\n draft: pull.draft,\n };\n },\n async publishPullRequest(input) {\n const repository = repositorySlugSchema.parse(input.repository.toLowerCase());\n if (!options.commitIdentity) throw new Error(\"Managed publication requires commit identity\");\n if (!/^[a-f0-9]{40}$/u.test(input.baseCommit) || input.commitMessage.trim() === \"\") {\n throw new Error(\"Invalid managed GitHub publication\");\n }\n const publicationTree = publicationTreeSchema.parse(input.tree);\n const branch = publicationBranchSchema.parse(input.branch);\n const baseBranch = publicationBaseBranchSchema.parse(input.baseBranch);\n const title = publicationTitleSchema.parse(input.title);\n const body = publicationBodySchema.parse(input.body);\n const commitMessage = publicationCommitMessageSchema.parse(\n `${input.commitMessage}\\n\\nCo-authored-by: ${options.commitIdentity.name} <${options.commitIdentity.email}>`,\n );\n const sandbox = await createSandbox(\n createPublicationInput(repository, options.commitIdentity),\n );\n try {\n const authorizedRequest = async (\n request: Omit<Parameters<typeof sandboxRequest>[1], \"repository\">,\n ) => {\n await input.authorize();\n return sandboxRequest(sandbox, { repository, ...request });\n };\n const base = commitSchema.parse(\n await authorizedRequest({\n method: \"GET\",\n path: `/git/commits/${input.baseCommit}`,\n }),\n );\n const tree = treeSchema.parse(\n await authorizedRequest({\n method: \"POST\",\n path: \"/git/trees\",\n body: { base_tree: base.tree.sha, tree: publicationTree },\n }),\n );\n const pullPath = `/pulls?${new URLSearchParams({\n state: \"all\",\n head: `${repository.split(\"/\")[0]}:${branch}`,\n per_page: \"100\",\n })}`;\n const pulls = async () =>\n z\n .array(publicationPullSchema)\n .parse(await authorizedRequest({ method: \"GET\", path: pullPath }));\n const result = (pull: z.infer<typeof pullRequestSchema>, commitSha: string) => ({\n commitSha,\n pullRequestNumber: pull.number,\n pullRequestUrl: pull.html_url,\n draft: pull.draft,\n });\n const refPath = `/git/ref/heads/${branch.split(\"/\").map(encodeURIComponent).join(\"/\")}`;\n let existingRef: z.infer<typeof refSchema> | null;\n try {\n existingRef = refSchema.parse(await authorizedRequest({ method: \"GET\", path: refPath }));\n } catch (error) {\n if (!(error instanceof VercelManagedGitHubApiError) || error.status !== 404) throw error;\n existingRef = null;\n }\n let commitSha = existingRef?.object.sha;\n if (commitSha) {\n const existingPull = (await pulls()).find((pull) => pull.head.ref === branch);\n if (existingPull) {\n if (existingPull.state !== \"open\") {\n throw new Error(\"Managed publication pull request is closed\");\n }\n const existingCommit = commitSchema.parse(\n await authorizedRequest({\n method: \"GET\",\n path: `/git/commits/${existingPull.head.sha}`,\n }),\n );\n if (\n existingCommit.tree.sha !== tree.sha ||\n existingCommit.parents.length !== 1 ||\n existingCommit.parents[0]?.sha !== input.baseCommit\n ) {\n throw new Error(\"Managed publication pull request contains different changes\");\n }\n return result(existingPull, existingPull.head.sha);\n }\n const existingCommit = commitSchema.parse(\n await authorizedRequest({\n method: \"GET\",\n path: `/git/commits/${commitSha}`,\n }),\n );\n if (\n existingCommit.tree.sha !== tree.sha ||\n existingCommit.parents.length !== 1 ||\n existingCommit.parents[0]?.sha !== input.baseCommit\n ) {\n throw new Error(\"Managed publication branch contains different changes\");\n }\n } else {\n const commit = commitSchema.parse(\n await authorizedRequest({\n method: \"POST\",\n path: \"/git/commits\",\n body: {\n message: commitMessage,\n tree: tree.sha,\n parents: [input.baseCommit],\n },\n }),\n );\n commitSha = commit.sha;\n try {\n await authorizedRequest({\n method: \"POST\",\n path: \"/git/refs\",\n body: { ref: `refs/heads/${branch}`, sha: commitSha },\n });\n } catch (error) {\n const reconciled = refSchema.parse(\n await authorizedRequest({ method: \"GET\", path: refPath }),\n );\n if (reconciled.object.sha !== commitSha) throw error;\n }\n }\n let pull: z.infer<typeof pullRequestSchema>;\n try {\n pull = pullRequestSchema.parse(\n await authorizedRequest({\n method: \"POST\",\n path: \"/pulls\",\n body: {\n title,\n body,\n head: branch,\n base: baseBranch,\n draft: input.draft,\n },\n }),\n );\n } catch (error) {\n const reconciled = (await pulls()).find((candidate) => candidate.head.ref === branch);\n if (!reconciled || reconciled.state !== \"open\" || reconciled.head.sha !== commitSha) {\n throw error;\n }\n pull = reconciled;\n }\n return result(pull, commitSha);\n } finally {\n await sandbox.stop();\n }\n },\n };\n}\n"],"mappings":"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"}
|
package/dist/vercel.d.mts
CHANGED
|
@@ -1,4 +1,33 @@
|
|
|
1
|
+
import { RepositorySlug } from "./schema/repository.mjs";
|
|
2
|
+
import { WorkNotification, WorkNotifications } from "./store/work-notifications.mjs";
|
|
3
|
+
import { VercelManagedGitHubApi, VercelManagedGitHubApiAction, VercelManagedGitHubApiError, VercelManagedGitHubApiOptions, VercelManagedGitHubApiSandboxCreateInput, VercelManagedGitHubIssue, VercelManagedGitHubIssueInput, VercelManagedGitHubPublication, VercelManagedGitHubPublicationInput, VercelManagedGitHubPullRequest, VercelManagedGitHubPullRequestInput, createVercelManagedGitHubApi } from "./vercel-github-api.mjs";
|
|
4
|
+
import { VercelGitHubGitTransportOptions, VercelGitHubTokenInput, VercelManagedGitHubGitTransportOptions, VercelManagedGitHubSandboxCreateInput, createVercelGitHubGitTransport, createVercelManagedGitHubGitTransport } from "./vercel-git.mjs";
|
|
1
5
|
//#region src/vercel.d.ts
|
|
6
|
+
/** Provider delivery settings applied to one Vercel Queue message. */
|
|
7
|
+
interface VercelQueueSendOptions {
|
|
8
|
+
region: string;
|
|
9
|
+
retentionSeconds: number;
|
|
10
|
+
idempotencyKey: string;
|
|
11
|
+
delaySeconds: number;
|
|
12
|
+
}
|
|
13
|
+
/** Injectable Vercel Queue send operation for one validated Factory work notification. */
|
|
14
|
+
type VercelQueueSend = (topic: string, message: WorkNotification, options: VercelQueueSendOptions) => Promise<unknown>;
|
|
15
|
+
/** Configures Vercel Queue transport, failure reporting, retention, and runtime guards. */
|
|
16
|
+
interface VercelWorkQueueOptions {
|
|
17
|
+
send: VercelQueueSend;
|
|
18
|
+
onError(error: unknown, event: WorkNotification): void;
|
|
19
|
+
topic?: string;
|
|
20
|
+
region?: string;
|
|
21
|
+
retentionSeconds?: number;
|
|
22
|
+
environment?: Readonly<Record<string, string | undefined>>;
|
|
23
|
+
}
|
|
24
|
+
/** Publishes graph wakeups and exposes the hosted-runtime notification adapter. */
|
|
25
|
+
interface VercelWorkQueue {
|
|
26
|
+
publish(event: WorkNotification, delaySeconds?: number): Promise<void>;
|
|
27
|
+
hostedNotifications(): WorkNotifications | undefined;
|
|
28
|
+
}
|
|
29
|
+
/** Configure graph wakeups over Vercel Queues without granting queue messages execution authority. */
|
|
30
|
+
declare function createVercelWorkQueue(options: VercelWorkQueueOptions): VercelWorkQueue;
|
|
2
31
|
/**
|
|
3
32
|
* Verify a Vercel webhook signature (the x-vercel-signature header): an
|
|
4
33
|
* HMAC-SHA1 hex digest of the raw request body. Returns false for missing or
|
|
@@ -9,6 +38,7 @@ declare function verifyVercelSignature(options: {
|
|
|
9
38
|
payload: string;
|
|
10
39
|
signature: string | null;
|
|
11
40
|
}): boolean;
|
|
41
|
+
/** A normalized production deployment observation with optional Git commit identity. */
|
|
12
42
|
interface VercelProductionDeployment {
|
|
13
43
|
source: "vercel_production_deployment";
|
|
14
44
|
deliveryId: string;
|
|
@@ -17,7 +47,7 @@ interface VercelProductionDeployment {
|
|
|
17
47
|
deploymentUrl: string;
|
|
18
48
|
projectId: string;
|
|
19
49
|
/** owner/name from the deployment's git metadata; null for non-git deployments. */
|
|
20
|
-
repositorySlug:
|
|
50
|
+
repositorySlug: RepositorySlug | null;
|
|
21
51
|
/** Commit the deployment was built from; null for non-git deployments. */
|
|
22
52
|
commitSha: string | null;
|
|
23
53
|
}
|
|
@@ -27,6 +57,8 @@ interface VercelProductionDeployment {
|
|
|
27
57
|
* production. Returns null for other events and non-production targets.
|
|
28
58
|
*/
|
|
29
59
|
declare function normalizeVercelProductionDeployment(payload: unknown): VercelProductionDeployment | null;
|
|
60
|
+
/** Verify a personal Vercel API token against Vercel; never infer a person from workload OIDC. */
|
|
61
|
+
declare function authenticateVercelUserToken(request: Request, fetcher?: typeof fetch): Promise<string | null>;
|
|
30
62
|
//#endregion
|
|
31
|
-
export { VercelProductionDeployment, normalizeVercelProductionDeployment, verifyVercelSignature };
|
|
63
|
+
export { type VercelGitHubGitTransportOptions, type VercelGitHubTokenInput, type VercelManagedGitHubApi, type VercelManagedGitHubApiAction, VercelManagedGitHubApiError, type VercelManagedGitHubApiOptions, type VercelManagedGitHubApiSandboxCreateInput, type VercelManagedGitHubGitTransportOptions, type VercelManagedGitHubIssue, type VercelManagedGitHubIssueInput, type VercelManagedGitHubPublication, type VercelManagedGitHubPublicationInput, type VercelManagedGitHubPullRequest, type VercelManagedGitHubPullRequestInput, type VercelManagedGitHubSandboxCreateInput, VercelProductionDeployment, VercelQueueSend, VercelQueueSendOptions, VercelWorkQueue, VercelWorkQueueOptions, authenticateVercelUserToken, createVercelGitHubGitTransport, createVercelManagedGitHubApi, createVercelManagedGitHubGitTransport, createVercelWorkQueue, normalizeVercelProductionDeployment, verifyVercelSignature };
|
|
32
64
|
//# sourceMappingURL=vercel.d.mts.map
|
package/dist/vercel.mjs
CHANGED
|
@@ -1,6 +1,36 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { repositorySlugSchema } from "./schema/repository.mjs";
|
|
2
|
+
import { workNotificationSchema } from "./store/work-notifications.mjs";
|
|
3
|
+
import { VercelManagedGitHubApiError, createVercelManagedGitHubApi } from "./vercel-github-api.mjs";
|
|
4
|
+
import { createVercelGitHubGitTransport, createVercelManagedGitHubGitTransport } from "./vercel-git.mjs";
|
|
2
5
|
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
6
|
+
import { z } from "zod";
|
|
3
7
|
//#region src/vercel.ts
|
|
8
|
+
/** Configure graph wakeups over Vercel Queues without granting queue messages execution authority. */
|
|
9
|
+
function createVercelWorkQueue(options) {
|
|
10
|
+
const environment = options.environment ?? process.env;
|
|
11
|
+
const topic = options.topic ?? "factory-work";
|
|
12
|
+
const region = options.region ?? "iad1";
|
|
13
|
+
const retentionSeconds = options.retentionSeconds ?? 604800;
|
|
14
|
+
const hosted = () => environment.VERCEL === "1" && environment.FACTORY_LOCAL_TEST !== "1";
|
|
15
|
+
const publish = async (event, delaySeconds = 0) => {
|
|
16
|
+
if (!hosted()) throw new Error("Vercel work queues require a hosted, non-fixture runtime");
|
|
17
|
+
const message = workNotificationSchema.parse(event);
|
|
18
|
+
await options.send(topic, message, {
|
|
19
|
+
region,
|
|
20
|
+
retentionSeconds,
|
|
21
|
+
idempotencyKey: message.key,
|
|
22
|
+
delaySeconds
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
const notifications = {
|
|
26
|
+
publish,
|
|
27
|
+
onError: options.onError
|
|
28
|
+
};
|
|
29
|
+
return Object.freeze({
|
|
30
|
+
publish,
|
|
31
|
+
hostedNotifications: () => hosted() ? notifications : void 0
|
|
32
|
+
});
|
|
33
|
+
}
|
|
4
34
|
/**
|
|
5
35
|
* Verify a Vercel webhook signature (the x-vercel-signature header): an
|
|
6
36
|
* HMAC-SHA1 hex digest of the raw request body. Returns false for missing or
|
|
@@ -45,6 +75,7 @@ function normalizeVercelProductionDeployment(payload) {
|
|
|
45
75
|
const meta = event.deployment.meta;
|
|
46
76
|
const org = meta?.githubCommitOrg ?? meta?.githubOrg;
|
|
47
77
|
const repo = meta?.githubCommitRepo ?? meta?.githubRepo;
|
|
78
|
+
const repositorySlug = org === void 0 || repo === void 0 ? null : repositorySlugSchema.safeParse(`${org}/${repo}`.toLowerCase()).data ?? null;
|
|
48
79
|
return {
|
|
49
80
|
source: "vercel_production_deployment",
|
|
50
81
|
deliveryId: parsed.data.id,
|
|
@@ -52,11 +83,26 @@ function normalizeVercelProductionDeployment(payload) {
|
|
|
52
83
|
deploymentId: event.deployment.id,
|
|
53
84
|
deploymentUrl: event.deployment.url,
|
|
54
85
|
projectId: event.project.id,
|
|
55
|
-
repositorySlug
|
|
86
|
+
repositorySlug,
|
|
56
87
|
commitSha: meta?.githubCommitSha ?? null
|
|
57
88
|
};
|
|
58
89
|
}
|
|
90
|
+
/** Verify a personal Vercel API token against Vercel; never infer a person from workload OIDC. */
|
|
91
|
+
async function authenticateVercelUserToken(request, fetcher = fetch) {
|
|
92
|
+
const authorization = request.headers.get("authorization");
|
|
93
|
+
if (!authorization?.match(/^Bearer \S+$/u)) return null;
|
|
94
|
+
const response = await fetcher("https://api.vercel.com/v2/user", {
|
|
95
|
+
headers: { authorization },
|
|
96
|
+
cache: "no-store",
|
|
97
|
+
redirect: "error",
|
|
98
|
+
signal: AbortSignal.timeout(1e4)
|
|
99
|
+
});
|
|
100
|
+
if (response.status === 401 || response.status === 403) return null;
|
|
101
|
+
if (!response.ok) throw new Error(`Vercel identity lookup failed (${response.status})`);
|
|
102
|
+
const result = z.object({ user: z.object({ id: z.string().min(1) }) }).safeParse(await response.json());
|
|
103
|
+
return result.success ? `vercel:${result.data.user.id}` : null;
|
|
104
|
+
}
|
|
59
105
|
//#endregion
|
|
60
|
-
export { normalizeVercelProductionDeployment, verifyVercelSignature };
|
|
106
|
+
export { VercelManagedGitHubApiError, authenticateVercelUserToken, createVercelGitHubGitTransport, createVercelManagedGitHubApi, createVercelManagedGitHubGitTransport, createVercelWorkQueue, normalizeVercelProductionDeployment, verifyVercelSignature };
|
|
61
107
|
|
|
62
108
|
//# sourceMappingURL=vercel.mjs.map
|
package/dist/vercel.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vercel.mjs","names":[],"sources":["../src/vercel.ts"],"sourcesContent":["import { createHmac, timingSafeEqual } from \"node:crypto\";\nimport { z } from \"zod\";\n\n/**\n * Verify a Vercel webhook signature (the x-vercel-signature header): an\n * HMAC-SHA1 hex digest of the raw request body. Returns false for missing or\n * malformed signatures instead of throwing.\n */\nexport function verifyVercelSignature(options: {\n secret: string;\n payload: string;\n signature: string | null;\n}): boolean {\n const { secret, payload, signature } = options;\n if (signature === null || !/^[0-9a-f]{40}$/.test(signature)) {\n return false;\n }\n const expected = createHmac(\"sha1\", secret).update(payload).digest(\"hex\");\n return timingSafeEqual(Buffer.from(signature, \"hex\"), Buffer.from(expected, \"hex\"));\n}\n\nconst observedDeploymentEvents = new Set([\"deployment.succeeded\", \"deployment.promoted\"]);\n\nconst deploymentEventSchema = z.looseObject({\n id: z.string().min(1),\n type: z.string(),\n payload: z.looseObject({\n target: z.string().nullable().optional(),\n project: z.looseObject({ id: z.string().min(1) }),\n deployment: z.looseObject({\n id: z.string().min(1),\n url: z.string().min(1),\n meta: z\n .looseObject({\n githubCommitSha: z.string().optional(),\n githubCommitOrg: z.string().optional(),\n githubCommitRepo: z.string().optional(),\n githubOrg: z.string().optional(),\n githubRepo: z.string().optional(),\n })\n .optional(),\n }),\n }),\n});\n\nexport interface VercelProductionDeployment {\n source: \"vercel_production_deployment\";\n deliveryId: string;\n eventType: string;\n deploymentId: string;\n deploymentUrl: string;\n projectId: string;\n /** owner/name from the deployment's git metadata; null for non-git deployments. */\n repositorySlug: string | null;\n /** Commit the deployment was built from; null for non-git deployments. */\n commitSha: string | null;\n}\n\n/**\n * Normalize a deployment.succeeded or deployment.promoted webhook for a\n * production deployment so the factory can observe a merge reaching\n * production. Returns null for other events and non-production targets.\n */\nexport function normalizeVercelProductionDeployment(\n payload: unknown,\n): VercelProductionDeployment | null {\n const parsed = deploymentEventSchema.safeParse(payload);\n if (!parsed.success || !observedDeploymentEvents.has(parsed.data.type)) {\n return null;\n }\n const event = parsed.data.payload;\n if (event.target !== \"production\") {\n return null;\n }\n const meta = event.deployment.meta;\n const org = meta?.githubCommitOrg ?? meta?.githubOrg;\n const repo = meta?.githubCommitRepo ?? meta?.githubRepo;\n return {\n source: \"vercel_production_deployment\",\n deliveryId: parsed.data.id,\n eventType: parsed.data.type,\n deploymentId: event.deployment.id,\n deploymentUrl: event.deployment.url,\n projectId: event.project.id,\n repositorySlug:\n org !== undefined && repo !== undefined ? `${org}/${repo}`.toLowerCase() : null,\n commitSha: meta?.githubCommitSha ?? null,\n };\n}\n"],"mappings":";;;;;;;;AAQA,SAAgB,sBAAsB,SAI1B;CACV,MAAM,EAAE,QAAQ,SAAS,cAAc;CACvC,IAAI,cAAc,QAAQ,CAAC,iBAAiB,KAAK,SAAS,GACxD,OAAO;CAET,MAAM,WAAW,WAAW,QAAQ,MAAM,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,OAAO,KAAK;CACxE,OAAO,gBAAgB,OAAO,KAAK,WAAW,KAAK,GAAG,OAAO,KAAK,UAAU,KAAK,CAAC;AACpF;AAEA,MAAM,2CAA2B,IAAI,IAAI,CAAC,wBAAwB,qBAAqB,CAAC;AAExF,MAAM,wBAAwB,EAAE,YAAY;CAC1C,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CACpB,MAAM,EAAE,OAAO;CACf,SAAS,EAAE,YAAY;EACrB,QAAQ,EAAE,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS;EACvC,SAAS,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;EAChD,YAAY,EAAE,YAAY;GACxB,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;GACpB,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;GACrB,MAAM,EACH,YAAY;IACX,iBAAiB,EAAE,OAAO,CAAC,CAAC,SAAS;IACrC,iBAAiB,EAAE,OAAO,CAAC,CAAC,SAAS;IACrC,kBAAkB,EAAE,OAAO,CAAC,CAAC,SAAS;IACtC,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;IAC/B,YAAY,EAAE,OAAO,CAAC,CAAC,SAAS;GAClC,CAAC,CAAC,CACD,SAAS;EACd,CAAC;CACH,CAAC;AACH,CAAC;;;;;;AAoBD,SAAgB,oCACd,SACmC;CACnC,MAAM,SAAS,sBAAsB,UAAU,OAAO;CACtD,IAAI,CAAC,OAAO,WAAW,CAAC,yBAAyB,IAAI,OAAO,KAAK,IAAI,GACnE,OAAO;CAET,MAAM,QAAQ,OAAO,KAAK;CAC1B,IAAI,MAAM,WAAW,cACnB,OAAO;CAET,MAAM,OAAO,MAAM,WAAW;CAC9B,MAAM,MAAM,MAAM,mBAAmB,MAAM;CAC3C,MAAM,OAAO,MAAM,oBAAoB,MAAM;CAC7C,OAAO;EACL,QAAQ;EACR,YAAY,OAAO,KAAK;EACxB,WAAW,OAAO,KAAK;EACvB,cAAc,MAAM,WAAW;EAC/B,eAAe,MAAM,WAAW;EAChC,WAAW,MAAM,QAAQ;EACzB,gBACE,QAAQ,KAAA,KAAa,SAAS,KAAA,IAAY,GAAG,IAAI,GAAG,OAAO,YAAY,IAAI;EAC7E,WAAW,MAAM,mBAAmB;CACtC;AACF"}
|
|
1
|
+
{"version":3,"file":"vercel.mjs","names":[],"sources":["../src/vercel.ts"],"sourcesContent":["import { createHmac, timingSafeEqual } from \"node:crypto\";\nimport { z } from \"zod\";\nimport { repositorySlugSchema, type RepositorySlug } from \"./schema/repository\";\nimport {\n workNotificationSchema,\n type WorkNotification,\n type WorkNotifications,\n} from \"./store/work-notifications\";\n\n/** Provider delivery settings applied to one Vercel Queue message. */\nexport interface VercelQueueSendOptions {\n region: string;\n retentionSeconds: number;\n idempotencyKey: string;\n delaySeconds: number;\n}\n\n/** Injectable Vercel Queue send operation for one validated Factory work notification. */\nexport type VercelQueueSend = (\n topic: string,\n message: WorkNotification,\n options: VercelQueueSendOptions,\n) => Promise<unknown>;\n\n/** Configures Vercel Queue transport, failure reporting, retention, and runtime guards. */\nexport interface VercelWorkQueueOptions {\n send: VercelQueueSend;\n onError(error: unknown, event: WorkNotification): void;\n topic?: string;\n region?: string;\n retentionSeconds?: number;\n environment?: Readonly<Record<string, string | undefined>>;\n}\n\n/** Publishes graph wakeups and exposes the hosted-runtime notification adapter. */\nexport interface VercelWorkQueue {\n publish(event: WorkNotification, delaySeconds?: number): Promise<void>;\n hostedNotifications(): WorkNotifications | undefined;\n}\n\nexport {\n createVercelManagedGitHubApi,\n VercelManagedGitHubApiError,\n type VercelManagedGitHubApi,\n type VercelManagedGitHubApiAction,\n type VercelManagedGitHubApiOptions,\n type VercelManagedGitHubApiSandboxCreateInput,\n type VercelManagedGitHubIssue,\n type VercelManagedGitHubIssueInput,\n type VercelManagedGitHubPullRequest,\n type VercelManagedGitHubPullRequestInput,\n type VercelManagedGitHubPublication,\n type VercelManagedGitHubPublicationInput,\n} from \"./vercel-github-api\";\n\nexport {\n createVercelGitHubGitTransport,\n createVercelManagedGitHubGitTransport,\n type VercelGitHubGitTransportOptions,\n type VercelGitHubTokenInput,\n type VercelManagedGitHubGitTransportOptions,\n type VercelManagedGitHubSandboxCreateInput,\n} from \"./vercel-git\";\n\n/** Configure graph wakeups over Vercel Queues without granting queue messages execution authority. */\nexport function createVercelWorkQueue(options: VercelWorkQueueOptions): VercelWorkQueue {\n const environment = options.environment ?? process.env;\n const topic = options.topic ?? \"factory-work\";\n const region = options.region ?? \"iad1\";\n const retentionSeconds = options.retentionSeconds ?? 604_800;\n const hosted = () => environment.VERCEL === \"1\" && environment.FACTORY_LOCAL_TEST !== \"1\";\n const publish = async (event: WorkNotification, delaySeconds = 0): Promise<void> => {\n if (!hosted()) throw new Error(\"Vercel work queues require a hosted, non-fixture runtime\");\n const message = workNotificationSchema.parse(event);\n await options.send(topic, message, {\n region,\n retentionSeconds,\n idempotencyKey: message.key,\n delaySeconds,\n });\n };\n const notifications: WorkNotifications = { publish, onError: options.onError };\n return Object.freeze({\n publish,\n hostedNotifications: () => (hosted() ? notifications : undefined),\n });\n}\n\n/**\n * Verify a Vercel webhook signature (the x-vercel-signature header): an\n * HMAC-SHA1 hex digest of the raw request body. Returns false for missing or\n * malformed signatures instead of throwing.\n */\nexport function verifyVercelSignature(options: {\n secret: string;\n payload: string;\n signature: string | null;\n}): boolean {\n const { secret, payload, signature } = options;\n if (signature === null || !/^[0-9a-f]{40}$/.test(signature)) {\n return false;\n }\n const expected = createHmac(\"sha1\", secret).update(payload).digest(\"hex\");\n return timingSafeEqual(Buffer.from(signature, \"hex\"), Buffer.from(expected, \"hex\"));\n}\n\nconst observedDeploymentEvents = new Set([\"deployment.succeeded\", \"deployment.promoted\"]);\n\nconst deploymentEventSchema = z.looseObject({\n id: z.string().min(1),\n type: z.string(),\n payload: z.looseObject({\n target: z.string().nullable().optional(),\n project: z.looseObject({ id: z.string().min(1) }),\n deployment: z.looseObject({\n id: z.string().min(1),\n url: z.string().min(1),\n meta: z\n .looseObject({\n githubCommitSha: z.string().optional(),\n githubCommitOrg: z.string().optional(),\n githubCommitRepo: z.string().optional(),\n githubOrg: z.string().optional(),\n githubRepo: z.string().optional(),\n })\n .optional(),\n }),\n }),\n});\n\n/** A normalized production deployment observation with optional Git commit identity. */\nexport interface VercelProductionDeployment {\n source: \"vercel_production_deployment\";\n deliveryId: string;\n eventType: string;\n deploymentId: string;\n deploymentUrl: string;\n projectId: string;\n /** owner/name from the deployment's git metadata; null for non-git deployments. */\n repositorySlug: RepositorySlug | null;\n /** Commit the deployment was built from; null for non-git deployments. */\n commitSha: string | null;\n}\n\n/**\n * Normalize a deployment.succeeded or deployment.promoted webhook for a\n * production deployment so the factory can observe a merge reaching\n * production. Returns null for other events and non-production targets.\n */\nexport function normalizeVercelProductionDeployment(\n payload: unknown,\n): VercelProductionDeployment | null {\n const parsed = deploymentEventSchema.safeParse(payload);\n if (!parsed.success || !observedDeploymentEvents.has(parsed.data.type)) {\n return null;\n }\n const event = parsed.data.payload;\n if (event.target !== \"production\") {\n return null;\n }\n const meta = event.deployment.meta;\n const org = meta?.githubCommitOrg ?? meta?.githubOrg;\n const repo = meta?.githubCommitRepo ?? meta?.githubRepo;\n const repositorySlug =\n org === undefined || repo === undefined\n ? null\n : (repositorySlugSchema.safeParse(`${org}/${repo}`.toLowerCase()).data ?? null);\n return {\n source: \"vercel_production_deployment\",\n deliveryId: parsed.data.id,\n eventType: parsed.data.type,\n deploymentId: event.deployment.id,\n deploymentUrl: event.deployment.url,\n projectId: event.project.id,\n repositorySlug,\n commitSha: meta?.githubCommitSha ?? null,\n };\n}\n\n/** Verify a personal Vercel API token against Vercel; never infer a person from workload OIDC. */\nexport async function authenticateVercelUserToken(\n request: Request,\n fetcher: typeof fetch = fetch,\n): Promise<string | null> {\n const authorization = request.headers.get(\"authorization\");\n if (!authorization?.match(/^Bearer \\S+$/u)) return null;\n const response = await fetcher(\"https://api.vercel.com/v2/user\", {\n headers: { authorization },\n cache: \"no-store\",\n redirect: \"error\",\n signal: AbortSignal.timeout(10_000),\n });\n if (response.status === 401 || response.status === 403) return null;\n if (!response.ok) throw new Error(`Vercel identity lookup failed (${response.status})`);\n const result = z\n .object({ user: z.object({ id: z.string().min(1) }) })\n .safeParse(await response.json());\n return result.success ? `vercel:${result.data.user.id}` : null;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { RepositoryId } from "../schema/id.mjs";
|
|
2
|
+
import { FactoryStores } from "../store/engine.mjs";
|
|
3
|
+
import { ExistingWorkLookupOptions, ExistingWorkLookupResult } from "./find-existing-work.mjs";
|
|
4
|
+
import { ToolContext, ToolDefinition } from "eve/tools";
|
|
5
|
+
//#region src/work-triage/eve-tool.d.ts
|
|
6
|
+
/** Change, repository, and Task capabilities required by the existing-work tool. */
|
|
7
|
+
type FindExistingWorkToolStores = Pick<FactoryStores, "changes" | "repositories" | "tasks">;
|
|
8
|
+
/** Stores and provider lookup used to construct the existing-work tool. */
|
|
9
|
+
interface FindExistingWorkToolOptions extends ExistingWorkLookupOptions {
|
|
10
|
+
stores: FindExistingWorkToolStores;
|
|
11
|
+
}
|
|
12
|
+
/** Repository selected for a read-only existing-work lookup. */
|
|
13
|
+
interface FindExistingWorkToolInput {
|
|
14
|
+
repositoryId: RepositoryId;
|
|
15
|
+
}
|
|
16
|
+
/** Eve tool that checks a repository for overlapping open work. */
|
|
17
|
+
interface FindExistingWorkTool extends ToolDefinition<FindExistingWorkToolInput, ExistingWorkLookupResult> {
|
|
18
|
+
execute(input: FindExistingWorkToolInput, ctx: ToolContext): Promise<ExistingWorkLookupResult>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Read-only triage helper: before delegating new work or accepting a signal,
|
|
22
|
+
* check whether an open pull request, a recorded Change, or an in-flight
|
|
23
|
+
* Task already covers the same repository, so Foreman does not duplicate
|
|
24
|
+
* work that is already underway.
|
|
25
|
+
*/
|
|
26
|
+
declare function createFindExistingWorkTool(input: FindExistingWorkToolOptions): FindExistingWorkTool;
|
|
27
|
+
//#endregion
|
|
28
|
+
export { FindExistingWorkTool, FindExistingWorkToolInput, FindExistingWorkToolOptions, FindExistingWorkToolStores, createFindExistingWorkTool };
|
|
29
|
+
//# sourceMappingURL=eve-tool.d.mts.map
|