dorfl 0.0.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/advance-ci-template.d.ts +73 -0
- package/dist/advance-ci-template.d.ts.map +1 -0
- package/dist/advance-ci-template.js +104 -0
- package/dist/advance-ci-template.js.map +1 -0
- package/dist/advance-classify.d.ts +132 -0
- package/dist/advance-classify.d.ts.map +1 -0
- package/dist/advance-classify.js +120 -0
- package/dist/advance-classify.js.map +1 -0
- package/dist/advance-drivers.d.ts +182 -0
- package/dist/advance-drivers.d.ts.map +1 -0
- package/dist/advance-drivers.js +231 -0
- package/dist/advance-drivers.js.map +1 -0
- package/dist/advance-isolated.d.ts +156 -0
- package/dist/advance-isolated.d.ts.map +1 -0
- package/dist/advance-isolated.js +256 -0
- package/dist/advance-isolated.js.map +1 -0
- package/dist/advance-lifecycle-template.d.ts +107 -0
- package/dist/advance-lifecycle-template.d.ts.map +1 -0
- package/dist/advance-lifecycle-template.js +668 -0
- package/dist/advance-lifecycle-template.js.map +1 -0
- package/dist/advance-loop-driver.d.ts +325 -0
- package/dist/advance-loop-driver.d.ts.map +1 -0
- package/dist/advance-loop-driver.js +437 -0
- package/dist/advance-loop-driver.js.map +1 -0
- package/dist/advance-treeless-publish.d.ts +108 -0
- package/dist/advance-treeless-publish.d.ts.map +1 -0
- package/dist/advance-treeless-publish.js +71 -0
- package/dist/advance-treeless-publish.js.map +1 -0
- package/dist/advance.d.ts +340 -0
- package/dist/advance.d.ts.map +1 -0
- package/dist/advance.js +1122 -0
- package/dist/advance.js.map +1 -0
- package/dist/advancing-lock.d.ts +294 -0
- package/dist/advancing-lock.d.ts.map +1 -0
- package/dist/advancing-lock.js +594 -0
- package/dist/advancing-lock.js.map +1 -0
- package/dist/agent-launch.d.ts +79 -0
- package/dist/agent-launch.d.ts.map +1 -0
- package/dist/agent-launch.js +61 -0
- package/dist/agent-launch.js.map +1 -0
- package/dist/agent-stop.d.ts +149 -0
- package/dist/agent-stop.d.ts.map +1 -0
- package/dist/agent-stop.js +307 -0
- package/dist/agent-stop.js.map +1 -0
- package/dist/apply-decide.d.ts +127 -0
- package/dist/apply-decide.d.ts.map +1 -0
- package/dist/apply-decide.js +176 -0
- package/dist/apply-decide.js.map +1 -0
- package/dist/apply-merge-action.d.ts +206 -0
- package/dist/apply-merge-action.d.ts.map +1 -0
- package/dist/apply-merge-action.js +307 -0
- package/dist/apply-merge-action.js.map +1 -0
- package/dist/apply-persist.d.ts +174 -0
- package/dist/apply-persist.d.ts.map +1 -0
- package/dist/apply-persist.js +359 -0
- package/dist/apply-persist.js.map +1 -0
- package/dist/arbiter.d.ts +120 -0
- package/dist/arbiter.d.ts.map +1 -0
- package/dist/arbiter.js +255 -0
- package/dist/arbiter.js.map +1 -0
- package/dist/brand.d.ts +70 -0
- package/dist/brand.d.ts.map +1 -0
- package/dist/brand.js +84 -0
- package/dist/brand.js.map +1 -0
- package/dist/buildable-body.d.ts +132 -0
- package/dist/buildable-body.d.ts.map +1 -0
- package/dist/buildable-body.js +131 -0
- package/dist/buildable-body.js.map +1 -0
- package/dist/categorise.d.ts +66 -0
- package/dist/categorise.d.ts.map +1 -0
- package/dist/categorise.js +106 -0
- package/dist/categorise.js.map +1 -0
- package/dist/claim-cas.d.ts +117 -0
- package/dist/claim-cas.d.ts.map +1 -0
- package/dist/claim-cas.js +312 -0
- package/dist/claim-cas.js.map +1 -0
- package/dist/cli-spinner.d.ts +112 -0
- package/dist/cli-spinner.d.ts.map +1 -0
- package/dist/cli-spinner.js +157 -0
- package/dist/cli-spinner.js.map +1 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +3094 -0
- package/dist/cli.js.map +1 -0
- package/dist/close-job-template.d.ts +70 -0
- package/dist/close-job-template.d.ts.map +1 -0
- package/dist/close-job-template.js +180 -0
- package/dist/close-job-template.js.map +1 -0
- package/dist/close-job.d.ts +95 -0
- package/dist/close-job.d.ts.map +1 -0
- package/dist/close-job.js +226 -0
- package/dist/close-job.js.map +1 -0
- package/dist/complete.d.ts +361 -0
- package/dist/complete.d.ts.map +1 -0
- package/dist/complete.js +885 -0
- package/dist/complete.js.map +1 -0
- package/dist/concurrency.d.ts +68 -0
- package/dist/concurrency.d.ts.map +1 -0
- package/dist/concurrency.js +112 -0
- package/dist/concurrency.js.map +1 -0
- package/dist/config-override.d.ts +76 -0
- package/dist/config-override.d.ts.map +1 -0
- package/dist/config-override.js +50 -0
- package/dist/config-override.js.map +1 -0
- package/dist/config.d.ts +668 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +241 -0
- package/dist/config.js.map +1 -0
- package/dist/continue-branch.d.ts +249 -0
- package/dist/continue-branch.d.ts.map +1 -0
- package/dist/continue-branch.js +389 -0
- package/dist/continue-branch.js.map +1 -0
- package/dist/cwd-section.d.ts +186 -0
- package/dist/cwd-section.d.ts.map +1 -0
- package/dist/cwd-section.js +209 -0
- package/dist/cwd-section.js.map +1 -0
- package/dist/decision-engine.d.ts +170 -0
- package/dist/decision-engine.d.ts.map +1 -0
- package/dist/decision-engine.js +136 -0
- package/dist/decision-engine.js.map +1 -0
- package/dist/detect.d.ts +17 -0
- package/dist/detect.d.ts.map +1 -0
- package/dist/detect.js +118 -0
- package/dist/detect.js.map +1 -0
- package/dist/do-autopick.d.ts +85 -0
- package/dist/do-autopick.d.ts.map +1 -0
- package/dist/do-autopick.js +112 -0
- package/dist/do-autopick.js.map +1 -0
- package/dist/do-config.d.ts +312 -0
- package/dist/do-config.d.ts.map +1 -0
- package/dist/do-config.js +358 -0
- package/dist/do-config.js.map +1 -0
- package/dist/do-remote-auto.d.ts +75 -0
- package/dist/do-remote-auto.d.ts.map +1 -0
- package/dist/do-remote-auto.js +111 -0
- package/dist/do-remote-auto.js.map +1 -0
- package/dist/do.d.ts +621 -0
- package/dist/do.d.ts.map +1 -0
- package/dist/do.js +1882 -0
- package/dist/do.js.map +1 -0
- package/dist/drop-source.d.ts +96 -0
- package/dist/drop-source.d.ts.map +1 -0
- package/dist/drop-source.js +91 -0
- package/dist/drop-source.js.map +1 -0
- package/dist/eligibility.d.ts +46 -0
- package/dist/eligibility.d.ts.map +1 -0
- package/dist/eligibility.js +34 -0
- package/dist/eligibility.js.map +1 -0
- package/dist/env-config.d.ts +51 -0
- package/dist/env-config.d.ts.map +1 -0
- package/dist/env-config.js +272 -0
- package/dist/env-config.js.map +1 -0
- package/dist/failure-cause.d.ts +70 -0
- package/dist/failure-cause.d.ts.map +1 -0
- package/dist/failure-cause.js +126 -0
- package/dist/failure-cause.js.map +1 -0
- package/dist/format.d.ts +43 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +256 -0
- package/dist/format.js.map +1 -0
- package/dist/frontmatter.d.ts +215 -0
- package/dist/frontmatter.d.ts.map +1 -0
- package/dist/frontmatter.js +345 -0
- package/dist/frontmatter.js.map +1 -0
- package/dist/gate-readiness.d.ts +84 -0
- package/dist/gate-readiness.d.ts.map +1 -0
- package/dist/gate-readiness.js +103 -0
- package/dist/gate-readiness.js.map +1 -0
- package/dist/gc.d.ts +165 -0
- package/dist/gc.d.ts.map +1 -0
- package/dist/gc.js +313 -0
- package/dist/gc.js.map +1 -0
- package/dist/gh-failure.d.ts +42 -0
- package/dist/gh-failure.d.ts.map +1 -0
- package/dist/gh-failure.js +49 -0
- package/dist/gh-failure.js.map +1 -0
- package/dist/git.d.ts +75 -0
- package/dist/git.d.ts.map +1 -0
- package/dist/git.js +130 -0
- package/dist/git.js.map +1 -0
- package/dist/github.d.ts +187 -0
- package/dist/github.d.ts.map +1 -0
- package/dist/github.js +343 -0
- package/dist/github.js.map +1 -0
- package/dist/harness.d.ts +242 -0
- package/dist/harness.d.ts.map +1 -0
- package/dist/harness.js +157 -0
- package/dist/harness.js.map +1 -0
- package/dist/identity.d.ts +167 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +231 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +147 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +76 -0
- package/dist/index.js.map +1 -0
- package/dist/install-ci-branch-protection.d.ts +147 -0
- package/dist/install-ci-branch-protection.d.ts.map +1 -0
- package/dist/install-ci-branch-protection.js +166 -0
- package/dist/install-ci-branch-protection.js.map +1 -0
- package/dist/install-ci-capabilities/advance-lifecycle.d.ts +15 -0
- package/dist/install-ci-capabilities/advance-lifecycle.d.ts.map +1 -0
- package/dist/install-ci-capabilities/advance-lifecycle.js +28 -0
- package/dist/install-ci-capabilities/advance-lifecycle.js.map +1 -0
- package/dist/install-ci-capabilities/close-job.d.ts +13 -0
- package/dist/install-ci-capabilities/close-job.d.ts.map +1 -0
- package/dist/install-ci-capabilities/close-job.js +26 -0
- package/dist/install-ci-capabilities/close-job.js.map +1 -0
- package/dist/install-ci-capabilities/example-noop.d.ts +16 -0
- package/dist/install-ci-capabilities/example-noop.d.ts.map +1 -0
- package/dist/install-ci-capabilities/example-noop.js +23 -0
- package/dist/install-ci-capabilities/example-noop.js.map +1 -0
- package/dist/install-ci-capabilities/intake.d.ts +15 -0
- package/dist/install-ci-capabilities/intake.d.ts.map +1 -0
- package/dist/install-ci-capabilities/intake.js +28 -0
- package/dist/install-ci-capabilities/intake.js.map +1 -0
- package/dist/install-ci-capabilities/verify.d.ts +14 -0
- package/dist/install-ci-capabilities/verify.d.ts.map +1 -0
- package/dist/install-ci-capabilities/verify.js +27 -0
- package/dist/install-ci-capabilities/verify.js.map +1 -0
- package/dist/install-ci-core.d.ts +446 -0
- package/dist/install-ci-core.d.ts.map +1 -0
- package/dist/install-ci-core.js +760 -0
- package/dist/install-ci-core.js.map +1 -0
- package/dist/install-ci-github.d.ts +167 -0
- package/dist/install-ci-github.d.ts.map +1 -0
- package/dist/install-ci-github.js +315 -0
- package/dist/install-ci-github.js.map +1 -0
- package/dist/install-ci.d.ts +105 -0
- package/dist/install-ci.d.ts.map +1 -0
- package/dist/install-ci.js +363 -0
- package/dist/install-ci.js.map +1 -0
- package/dist/intake-event.d.ts +88 -0
- package/dist/intake-event.d.ts.map +1 -0
- package/dist/intake-event.js +66 -0
- package/dist/intake-event.js.map +1 -0
- package/dist/intake-marker.d.ts +95 -0
- package/dist/intake-marker.d.ts.map +1 -0
- package/dist/intake-marker.js +127 -0
- package/dist/intake-marker.js.map +1 -0
- package/dist/intake-triage.d.ts +48 -0
- package/dist/intake-triage.d.ts.map +1 -0
- package/dist/intake-triage.js +95 -0
- package/dist/intake-triage.js.map +1 -0
- package/dist/intake-trigger-template.d.ts +185 -0
- package/dist/intake-trigger-template.d.ts.map +1 -0
- package/dist/intake-trigger-template.js +449 -0
- package/dist/intake-trigger-template.js.map +1 -0
- package/dist/intake.d.ts +569 -0
- package/dist/intake.d.ts.map +1 -0
- package/dist/intake.js +1628 -0
- package/dist/intake.js.map +1 -0
- package/dist/integration-core.d.ts +539 -0
- package/dist/integration-core.d.ts.map +1 -0
- package/dist/integration-core.js +2195 -0
- package/dist/integration-core.js.map +1 -0
- package/dist/integrator.d.ts +343 -0
- package/dist/integrator.d.ts.map +1 -0
- package/dist/integrator.js +400 -0
- package/dist/integrator.js.map +1 -0
- package/dist/isolation.d.ts +219 -0
- package/dist/isolation.d.ts.map +1 -0
- package/dist/isolation.js +261 -0
- package/dist/isolation.js.map +1 -0
- package/dist/issue-provider.d.ts +349 -0
- package/dist/issue-provider.d.ts.map +1 -0
- package/dist/issue-provider.js +360 -0
- package/dist/issue-provider.js.map +1 -0
- package/dist/item-lock.d.ts +626 -0
- package/dist/item-lock.d.ts.map +1 -0
- package/dist/item-lock.js +1381 -0
- package/dist/item-lock.js.map +1 -0
- package/dist/item-path.d.ts +49 -0
- package/dist/item-path.d.ts.map +1 -0
- package/dist/item-path.js +66 -0
- package/dist/item-path.js.map +1 -0
- package/dist/ledger-lint.d.ts +129 -0
- package/dist/ledger-lint.d.ts.map +1 -0
- package/dist/ledger-lint.js +249 -0
- package/dist/ledger-lint.js.map +1 -0
- package/dist/ledger-read.d.ts +357 -0
- package/dist/ledger-read.d.ts.map +1 -0
- package/dist/ledger-read.js +442 -0
- package/dist/ledger-read.js.map +1 -0
- package/dist/ledger-write.d.ts +330 -0
- package/dist/ledger-write.d.ts.map +1 -0
- package/dist/ledger-write.js +411 -0
- package/dist/ledger-write.js.map +1 -0
- package/dist/lifecycle-gather.d.ts +30 -0
- package/dist/lifecycle-gather.d.ts.map +1 -0
- package/dist/lifecycle-gather.js +205 -0
- package/dist/lifecycle-gather.js.map +1 -0
- package/dist/lifecycle-pools.d.ts +180 -0
- package/dist/lifecycle-pools.d.ts.map +1 -0
- package/dist/lifecycle-pools.js +78 -0
- package/dist/lifecycle-pools.js.map +1 -0
- package/dist/merge-question-surfacer.d.ts +166 -0
- package/dist/merge-question-surfacer.d.ts.map +1 -0
- package/dist/merge-question-surfacer.js +297 -0
- package/dist/merge-question-surfacer.js.map +1 -0
- package/dist/mint-adr.d.ts +126 -0
- package/dist/mint-adr.d.ts.map +1 -0
- package/dist/mint-adr.js +257 -0
- package/dist/mint-adr.js.map +1 -0
- package/dist/mirror-pool-scan.d.ts +125 -0
- package/dist/mirror-pool-scan.d.ts.map +1 -0
- package/dist/mirror-pool-scan.js +104 -0
- package/dist/mirror-pool-scan.js.map +1 -0
- package/dist/needs-attention.d.ts +341 -0
- package/dist/needs-attention.d.ts.map +1 -0
- package/dist/needs-attention.js +900 -0
- package/dist/needs-attention.js.map +1 -0
- package/dist/orphan-sidecar.d.ts +79 -0
- package/dist/orphan-sidecar.d.ts.map +1 -0
- package/dist/orphan-sidecar.js +71 -0
- package/dist/orphan-sidecar.js.map +1 -0
- package/dist/output.d.ts +48 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +66 -0
- package/dist/output.js.map +1 -0
- package/dist/pi-harness.d.ts +179 -0
- package/dist/pi-harness.d.ts.map +1 -0
- package/dist/pi-harness.js +342 -0
- package/dist/pi-harness.js.map +1 -0
- package/dist/placement.d.ts +99 -0
- package/dist/placement.d.ts.map +1 -0
- package/dist/placement.js +67 -0
- package/dist/placement.js.map +1 -0
- package/dist/prd-to-spec.d.ts +315 -0
- package/dist/prd-to-spec.d.ts.map +1 -0
- package/dist/prd-to-spec.js +684 -0
- package/dist/prd-to-spec.js.map +1 -0
- package/dist/prepare.d.ts +121 -0
- package/dist/prepare.d.ts.map +1 -0
- package/dist/prepare.js +140 -0
- package/dist/prepare.js.map +1 -0
- package/dist/prompt.d.ts +360 -0
- package/dist/prompt.d.ts.map +1 -0
- package/dist/prompt.js +499 -0
- package/dist/prompt.js.map +1 -0
- package/dist/protocol/ADR-FORMAT.md +47 -0
- package/dist/protocol/CLAIM-PROTOCOL.md +217 -0
- package/dist/protocol/REVIEW-PROTOCOL.md +119 -0
- package/dist/protocol/SURFACE-PROTOCOL.md +121 -0
- package/dist/protocol/TASKING-PROTOCOL.md +122 -0
- package/dist/protocol/WORK-CONTRACT.md +276 -0
- package/dist/protocol/spec-template.md +71 -0
- package/dist/protocol/task-template.md +65 -0
- package/dist/readiness.d.ts +66 -0
- package/dist/readiness.d.ts.map +1 -0
- package/dist/readiness.js +36 -0
- package/dist/readiness.js.map +1 -0
- package/dist/reap-branches.d.ts +102 -0
- package/dist/reap-branches.d.ts.map +1 -0
- package/dist/reap-branches.js +149 -0
- package/dist/reap-branches.js.map +1 -0
- package/dist/recover-isolated.d.ts +72 -0
- package/dist/recover-isolated.d.ts.map +1 -0
- package/dist/recover-isolated.js +188 -0
- package/dist/recover-isolated.js.map +1 -0
- package/dist/registry.d.ts +172 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +296 -0
- package/dist/registry.js.map +1 -0
- package/dist/repo-config.d.ts +201 -0
- package/dist/repo-config.d.ts.map +1 -0
- package/dist/repo-config.js +414 -0
- package/dist/repo-config.js.map +1 -0
- package/dist/repo-key.d.ts +20 -0
- package/dist/repo-key.d.ts.map +1 -0
- package/dist/repo-key.js +68 -0
- package/dist/repo-key.js.map +1 -0
- package/dist/repo-mirror.d.ts +177 -0
- package/dist/repo-mirror.d.ts.map +1 -0
- package/dist/repo-mirror.js +271 -0
- package/dist/repo-mirror.js.map +1 -0
- package/dist/retry-backoff.d.ts +90 -0
- package/dist/retry-backoff.d.ts.map +1 -0
- package/dist/retry-backoff.js +98 -0
- package/dist/retry-backoff.js.map +1 -0
- package/dist/review-gate.d.ts +173 -0
- package/dist/review-gate.d.ts.map +1 -0
- package/dist/review-gate.js +261 -0
- package/dist/review-gate.js.map +1 -0
- package/dist/review-verdict.d.ts +149 -0
- package/dist/review-verdict.d.ts.map +1 -0
- package/dist/review-verdict.js +332 -0
- package/dist/review-verdict.js.map +1 -0
- package/dist/run.d.ts +221 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +963 -0
- package/dist/run.js.map +1 -0
- package/dist/scan.d.ts +308 -0
- package/dist/scan.d.ts.map +1 -0
- package/dist/scan.js +374 -0
- package/dist/scan.js.map +1 -0
- package/dist/select-order.d.ts +75 -0
- package/dist/select-order.d.ts.map +1 -0
- package/dist/select-order.js +108 -0
- package/dist/select-order.js.map +1 -0
- package/dist/select-priority.d.ts +188 -0
- package/dist/select-priority.d.ts.map +1 -0
- package/dist/select-priority.js +80 -0
- package/dist/select-priority.js.map +1 -0
- package/dist/select.d.ts +25 -0
- package/dist/select.d.ts.map +1 -0
- package/dist/select.js +43 -0
- package/dist/select.js.map +1 -0
- package/dist/session-path.d.ts +36 -0
- package/dist/session-path.d.ts.map +1 -0
- package/dist/session-path.js +129 -0
- package/dist/session-path.js.map +1 -0
- package/dist/sidecar-apply.d.ts +83 -0
- package/dist/sidecar-apply.d.ts.map +1 -0
- package/dist/sidecar-apply.js +111 -0
- package/dist/sidecar-apply.js.map +1 -0
- package/dist/sidecar.d.ts +245 -0
- package/dist/sidecar.d.ts.map +1 -0
- package/dist/sidecar.js +481 -0
- package/dist/sidecar.js.map +1 -0
- package/dist/slug-namespace.d.ts +204 -0
- package/dist/slug-namespace.d.ts.map +1 -0
- package/dist/slug-namespace.js +229 -0
- package/dist/slug-namespace.js.map +1 -0
- package/dist/spec-complete.d.ts +44 -0
- package/dist/spec-complete.d.ts.map +1 -0
- package/dist/spec-complete.js +69 -0
- package/dist/spec-complete.js.map +1 -0
- package/dist/start.d.ts +97 -0
- package/dist/start.d.ts.map +1 -0
- package/dist/start.js +633 -0
- package/dist/start.js.map +1 -0
- package/dist/status.d.ts +199 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +228 -0
- package/dist/status.js.map +1 -0
- package/dist/surface-gate.d.ts +162 -0
- package/dist/surface-gate.d.ts.map +1 -0
- package/dist/surface-gate.js +206 -0
- package/dist/surface-gate.js.map +1 -0
- package/dist/surface-persist.d.ts +86 -0
- package/dist/surface-persist.d.ts.map +1 -0
- package/dist/surface-persist.js +129 -0
- package/dist/surface-persist.js.map +1 -0
- package/dist/tasker-review-loop.d.ts +249 -0
- package/dist/tasker-review-loop.d.ts.map +1 -0
- package/dist/tasker-review-loop.js +369 -0
- package/dist/tasker-review-loop.js.map +1 -0
- package/dist/tasking-eligibility.d.ts +74 -0
- package/dist/tasking-eligibility.d.ts.map +1 -0
- package/dist/tasking-eligibility.js +52 -0
- package/dist/tasking-eligibility.js.map +1 -0
- package/dist/tasking-lock.d.ts +111 -0
- package/dist/tasking-lock.d.ts.map +1 -0
- package/dist/tasking-lock.js +256 -0
- package/dist/tasking-lock.js.map +1 -0
- package/dist/tasking.d.ts +275 -0
- package/dist/tasking.d.ts.map +1 -0
- package/dist/tasking.js +952 -0
- package/dist/tasking.js.map +1 -0
- package/dist/triage-gate.d.ts +127 -0
- package/dist/triage-gate.d.ts.map +1 -0
- package/dist/triage-gate.js +139 -0
- package/dist/triage-gate.js.map +1 -0
- package/dist/triage-persist.d.ts +163 -0
- package/dist/triage-persist.d.ts.map +1 -0
- package/dist/triage-persist.js +387 -0
- package/dist/triage-persist.js.map +1 -0
- package/dist/verdict-json.d.ts +32 -0
- package/dist/verdict-json.d.ts.map +1 -0
- package/dist/verdict-json.js +74 -0
- package/dist/verdict-json.js.map +1 -0
- package/dist/verify-workflow-template.d.ts +60 -0
- package/dist/verify-workflow-template.d.ts.map +1 -0
- package/dist/verify-workflow-template.js +126 -0
- package/dist/verify-workflow-template.js.map +1 -0
- package/dist/verify.d.ts +60 -0
- package/dist/verify.d.ts.map +1 -0
- package/dist/verify.js +62 -0
- package/dist/verify.js.map +1 -0
- package/dist/watch-session.d.ts +112 -0
- package/dist/watch-session.d.ts.map +1 -0
- package/dist/watch-session.js +347 -0
- package/dist/watch-session.js.map +1 -0
- package/dist/work-layout.d.ts +198 -0
- package/dist/work-layout.d.ts.map +1 -0
- package/dist/work-layout.js +217 -0
- package/dist/work-layout.js.map +1 -0
- package/dist/work-on.d.ts +154 -0
- package/dist/work-on.d.ts.map +1 -0
- package/dist/work-on.js +387 -0
- package/dist/work-on.js.map +1 -0
- package/dist/workspace.d.ts +224 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +325 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +46 -2
- package/src/advance-ci-template.ts +203 -0
- package/src/advance-classify.ts +197 -0
- package/src/advance-drivers.ts +414 -0
- package/src/advance-isolated.ts +432 -0
- package/src/advance-lifecycle-template.ts +791 -0
- package/src/advance-loop-driver.ts +745 -0
- package/src/advance-treeless-publish.ts +177 -0
- package/src/advance.ts +1564 -0
- package/src/advancing-lock.ts +988 -0
- package/src/agent-launch.ts +137 -0
- package/src/agent-stop.ts +361 -0
- package/src/apply-decide.ts +242 -0
- package/src/apply-merge-action.ts +502 -0
- package/src/apply-persist.ts +518 -0
- package/src/arbiter.ts +372 -0
- package/src/brand.ts +111 -0
- package/src/buildable-body.ts +196 -0
- package/src/categorise.ts +158 -0
- package/src/claim-cas.ts +513 -0
- package/src/cli-spinner.ts +225 -0
- package/src/cli.ts +4369 -0
- package/src/close-job-template.ts +236 -0
- package/src/close-job.ts +319 -0
- package/src/complete.ts +1379 -0
- package/src/concurrency.ts +151 -0
- package/src/config-override.ts +116 -0
- package/src/config.ts +883 -0
- package/src/continue-branch.ts +542 -0
- package/src/cwd-section.ts +392 -0
- package/src/decision-engine.ts +272 -0
- package/src/detect.ts +124 -0
- package/src/do-autopick.ts +223 -0
- package/src/do-config.ts +589 -0
- package/src/do-remote-auto.ts +197 -0
- package/src/do.ts +2623 -0
- package/src/drop-source.ts +194 -0
- package/src/eligibility.ts +79 -0
- package/src/env-config.ts +305 -0
- package/src/failure-cause.ts +142 -0
- package/src/format.ts +313 -0
- package/src/frontmatter.ts +485 -0
- package/src/gate-readiness.ts +147 -0
- package/src/gc.ts +510 -0
- package/src/gh-failure.ts +53 -0
- package/src/git.ts +186 -0
- package/src/github.ts +468 -0
- package/src/harness.ts +355 -0
- package/src/identity.ts +322 -0
- package/src/index.ts +785 -0
- package/src/install-ci-branch-protection.ts +255 -0
- package/src/install-ci-capabilities/advance-lifecycle.ts +34 -0
- package/src/install-ci-capabilities/close-job.ts +32 -0
- package/src/install-ci-capabilities/example-noop.ts +24 -0
- package/src/install-ci-capabilities/intake.ts +34 -0
- package/src/install-ci-capabilities/verify.ts +33 -0
- package/src/install-ci-core.ts +1088 -0
- package/src/install-ci-github.ts +376 -0
- package/src/install-ci.ts +552 -0
- package/src/intake-event.ts +102 -0
- package/src/intake-marker.ts +195 -0
- package/src/intake-triage.ts +138 -0
- package/src/intake-trigger-template.ts +591 -0
- package/src/intake.ts +2445 -0
- package/src/integration-core.ts +3065 -0
- package/src/integrator.ts +771 -0
- package/src/isolation.ts +484 -0
- package/src/issue-provider.ts +733 -0
- package/src/item-lock.ts +1858 -0
- package/src/item-path.ts +75 -0
- package/src/ledger-lint.ts +332 -0
- package/src/ledger-read.ts +924 -0
- package/src/ledger-write.ts +865 -0
- package/src/lifecycle-gather.ts +298 -0
- package/src/lifecycle-pools.ts +250 -0
- package/src/merge-question-surfacer.ts +496 -0
- package/src/mint-adr.ts +362 -0
- package/src/mirror-pool-scan.ts +240 -0
- package/src/needs-attention.ts +1506 -0
- package/src/orphan-sidecar.ts +150 -0
- package/src/output.ts +89 -0
- package/src/pi-harness.ts +403 -0
- package/src/placement.ts +131 -0
- package/src/prd-to-spec.ts +1023 -0
- package/src/prepare.ts +230 -0
- package/src/prompt.ts +760 -0
- package/src/readiness.ts +98 -0
- package/src/reap-branches.ts +278 -0
- package/src/recover-isolated.ts +276 -0
- package/src/registry.ts +475 -0
- package/src/repo-config.ts +550 -0
- package/src/repo-key.ts +74 -0
- package/src/repo-mirror.ts +367 -0
- package/src/retry-backoff.ts +130 -0
- package/src/review-gate.ts +389 -0
- package/src/review-verdict.ts +422 -0
- package/src/run.ts +1430 -0
- package/src/scan.ts +611 -0
- package/src/select-order.ts +143 -0
- package/src/select-priority.ts +266 -0
- package/src/select.ts +62 -0
- package/src/session-path.ts +153 -0
- package/src/sidecar-apply.ts +216 -0
- package/src/sidecar.ts +700 -0
- package/src/slug-namespace.ts +367 -0
- package/src/spec-complete.ts +118 -0
- package/src/start.ts +974 -0
- package/src/status.ts +441 -0
- package/src/surface-gate.ts +337 -0
- package/src/surface-persist.ts +241 -0
- package/src/tasker-review-loop.ts +671 -0
- package/src/tasking-eligibility.ts +114 -0
- package/src/tasking-lock.ts +416 -0
- package/src/tasking.ts +1438 -0
- package/src/triage-gate.ts +248 -0
- package/src/triage-persist.ts +570 -0
- package/src/verdict-json.ts +73 -0
- package/src/verify-workflow-template.ts +159 -0
- package/src/verify.ts +123 -0
- package/src/watch-session.ts +397 -0
- package/src/work-layout.ts +262 -0
- package/src/work-on.ts +660 -0
- package/src/workspace.ts +502 -0
package/dist/harness.js
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
/** The `{model}` placeholder the null/shell adapter substitutes in `agentCmd`. */
|
|
3
|
+
export const MODEL_PLACEHOLDER = '{model}';
|
|
4
|
+
/**
|
|
5
|
+
* Inject the model ROUTING intent (ADR §13) into a shell `command` for the
|
|
6
|
+
* null/shell adapter, with three degradation rules so model routing is OFFERED,
|
|
7
|
+
* never FORCED:
|
|
8
|
+
*
|
|
9
|
+
* 1. `{model}` present + `model` set ⇒ substitute every occurrence.
|
|
10
|
+
* 2. `{model}` present + `model` unset ⇒ a clear config error (we never emit a
|
|
11
|
+
* literal `{model}` to the shell — that would silently misroute).
|
|
12
|
+
* 3. `{model}` absent ⇒ return `command` as-is (a user who bakes the model into
|
|
13
|
+
* `agentCmd`, or relies on the harness's own default, is untouched).
|
|
14
|
+
*
|
|
15
|
+
* dorfl only moves the model INTENT; auth/keys stay the harness's job.
|
|
16
|
+
*/
|
|
17
|
+
export function substituteModel(command, model) {
|
|
18
|
+
if (!command.includes(MODEL_PLACEHOLDER)) {
|
|
19
|
+
return command; // rule 3: no placeholder ⇒ run as-is.
|
|
20
|
+
}
|
|
21
|
+
if (model === undefined || model === '') {
|
|
22
|
+
throw new Error(`agentCmd contains a ${MODEL_PLACEHOLDER} placeholder but no model is ` +
|
|
23
|
+
`configured. Set a model (--model, DORFL_MODEL, per-repo, or ` +
|
|
24
|
+
`global config) or remove ${MODEL_PLACEHOLDER} from agentCmd.`);
|
|
25
|
+
}
|
|
26
|
+
return command.split(MODEL_PLACEHOLDER).join(model); // rule 1: substitute.
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Is this `spawnSync.error` a BENIGN failure of the prompt write, safe to
|
|
30
|
+
* ignore? The null/shell adapter feeds `input.prompt` to the child on stdin
|
|
31
|
+
* (`spawnSync('bash', …, {input})`). When the prompt is EMPTY — the autonomous
|
|
32
|
+
* review/arbiter launches that just shell out and capture stdout — a child that
|
|
33
|
+
* closes its stdin before the parent's (zero-byte) write surfaces as `EPIPE`
|
|
34
|
+
* under concurrent test load. That write failing is harmless: there was nothing
|
|
35
|
+
* to deliver, and the child's stdout/exit status are still captured normally.
|
|
36
|
+
* So we treat ONLY `EPIPE` as benign and let every OTHER spawn error (`ENOENT`,
|
|
37
|
+
* `EACCES`, buffer overflow, …) throw — those are real launch failures.
|
|
38
|
+
*/
|
|
39
|
+
export function isBenignPromptWriteError(error) {
|
|
40
|
+
return error.code === 'EPIPE';
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The **null adapter**: runs the configured command synchronously to completion
|
|
44
|
+
* in the job dir, recording the PID. Liveness is `process.kill(pid, 0)` against
|
|
45
|
+
* the recorded PID (the OS process table) — explicitly NOT a file mtime. Because
|
|
46
|
+
* it runs synchronously, the process has already exited by the time `launch`
|
|
47
|
+
* returns, so a finished job reads as not-alive (which is correct).
|
|
48
|
+
*/
|
|
49
|
+
export class NullHarness {
|
|
50
|
+
adapter = 'null';
|
|
51
|
+
launch(input) {
|
|
52
|
+
// BACKSTOP (config error, NOT a spawn failure): an empty/whitespace command
|
|
53
|
+
// resolves the null adapter to `bash -c ''`, which exits 0 with no output — a
|
|
54
|
+
// "successful" build that ran NOTHING. The `do`/`run`/`--remote` CLI sites
|
|
55
|
+
// already refuse this up-front (doNeedsAgentCmd), but THIS seam can be reached
|
|
56
|
+
// by other callers (tests, embeddings, future paths), so it must refuse too.
|
|
57
|
+
// Distinct from the `result.error` spawn-failure throw below: this names the
|
|
58
|
+
// config cause + the fix, in the voice of `launchInteractive`/`substituteModel`.
|
|
59
|
+
if (input.command.trim() === '') {
|
|
60
|
+
throw new Error('no command to run: the null/shell adapter was launched with an empty ' +
|
|
61
|
+
'agentCmd — nothing would run. Set `agentCmd` (--agent-cmd, per-repo, or ' +
|
|
62
|
+
'global config) or configure `harness: pi`.');
|
|
63
|
+
}
|
|
64
|
+
// Inject the model routing intent into the shell command via the `{model}`
|
|
65
|
+
// placeholder (ADR §13) — offered, never forced (see substituteModel).
|
|
66
|
+
const command = substituteModel(input.command, input.model);
|
|
67
|
+
const result = spawnSync('bash', ['-c', command], {
|
|
68
|
+
cwd: input.dir,
|
|
69
|
+
encoding: 'utf8',
|
|
70
|
+
input: input.prompt,
|
|
71
|
+
env: input.env ?? process.env,
|
|
72
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
73
|
+
});
|
|
74
|
+
if (result.error && !isBenignPromptWriteError(result.error)) {
|
|
75
|
+
throw new Error(`failed to spawn harness command: ${result.error.message}`);
|
|
76
|
+
}
|
|
77
|
+
// Record the CHILD's PID (the liveness anchor) — not the runner's. The null
|
|
78
|
+
// adapter runs synchronously, so by the time we return the child has
|
|
79
|
+
// exited, and `isAlive` correctly reads it as not-alive (from the PID
|
|
80
|
+
// table, NOT a file mtime).
|
|
81
|
+
const record = {
|
|
82
|
+
adapter: this.adapter,
|
|
83
|
+
pid: result.pid,
|
|
84
|
+
command,
|
|
85
|
+
};
|
|
86
|
+
const status = result.status ?? -1;
|
|
87
|
+
// The null/shell adapter's OUTPUT is its captured stdout (trimmed): a
|
|
88
|
+
// synchronous spawn, so there is no stream-fragility caveat — the command's
|
|
89
|
+
// stdout IS its answer. `undefined` when empty (no answer to surface).
|
|
90
|
+
const stdout = (result.stdout ?? '').trim();
|
|
91
|
+
return {
|
|
92
|
+
ok: status === 0,
|
|
93
|
+
record,
|
|
94
|
+
detail: status === 0 ? undefined : (result.stderr ?? '').trim(),
|
|
95
|
+
output: stdout === '' ? undefined : stdout,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Interactive launch is NOT supported by the null/shell adapter (decision #2):
|
|
100
|
+
* its `agentCmd` is shaped for the captured, prompt-fed AUTONOMOUS path, so
|
|
101
|
+
* "interactive" has no clean meaning here. Throw a CLEAR pi-only error
|
|
102
|
+
* (mirroring `do --watch`'s fail-on-null decision) rather than silently
|
|
103
|
+
* shelling out the wrong way.
|
|
104
|
+
*/
|
|
105
|
+
launchInteractive(_input) {
|
|
106
|
+
throw new Error('interactive launch requires the pi harness; configure `harness: pi` ' +
|
|
107
|
+
'(the null/shell adapter only supports the captured autonomous launch).');
|
|
108
|
+
}
|
|
109
|
+
isAlive(record) {
|
|
110
|
+
return pidAlive(record.pid);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Resolve the harness adapter that OWNS a given job record, keyed off the
|
|
115
|
+
* record's `adapter` field. The core (`status`, `watch`, `gc`) reads liveness
|
|
116
|
+
* for a heterogeneous set of jobs (some null, some pi) from their persisted
|
|
117
|
+
* records, so it must ask the RIGHT adapter per job — a pi job's liveness is the
|
|
118
|
+
* pi adapter's responsibility (PID + session pointer), not the null adapter's.
|
|
119
|
+
*
|
|
120
|
+
* Adapters register here lazily via {@link registerHarness}; an unknown adapter
|
|
121
|
+
* falls back to the null adapter (PID-only liveness — never mtime), which is a
|
|
122
|
+
* safe superset for any PID-anchored record.
|
|
123
|
+
*/
|
|
124
|
+
export function resolveHarness(record) {
|
|
125
|
+
return HARNESS_REGISTRY.get(record.adapter) ?? FALLBACK_HARNESS;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Register a harness adapter under its `adapter` name so {@link resolveHarness}
|
|
129
|
+
* can dispatch liveness to it. Idempotent (last registration wins). The pi
|
|
130
|
+
* adapter registers itself on import; tests may register stubs.
|
|
131
|
+
*/
|
|
132
|
+
export function registerHarness(harness) {
|
|
133
|
+
HARNESS_REGISTRY.set(harness.adapter, harness);
|
|
134
|
+
}
|
|
135
|
+
const FALLBACK_HARNESS = new NullHarness();
|
|
136
|
+
const HARNESS_REGISTRY = new Map([
|
|
137
|
+
[FALLBACK_HARNESS.adapter, FALLBACK_HARNESS],
|
|
138
|
+
]);
|
|
139
|
+
/**
|
|
140
|
+
* Is `pid` a live process? Uses signal 0 (`process.kill(pid, 0)`), which checks
|
|
141
|
+
* for existence/permission WITHOUT delivering a signal — the OS process table,
|
|
142
|
+
* never a filesystem mtime. Unknown/undefined PID ⇒ not alive.
|
|
143
|
+
*/
|
|
144
|
+
export function pidAlive(pid) {
|
|
145
|
+
if (pid === undefined || pid <= 0) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
try {
|
|
149
|
+
process.kill(pid, 0);
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
catch (err) {
|
|
153
|
+
// EPERM means the process exists but we may not signal it ⇒ still alive.
|
|
154
|
+
return err.code === 'EPERM';
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=harness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness.js","sourceRoot":"","sources":["../src/harness.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The **identity** feature: run the runner's git + provider operations as a
|
|
3
|
+
* configured entity (a bot), without mutating the user's global git/`gh` config.
|
|
4
|
+
*
|
|
5
|
+
* The mechanism is process-scoped environment overrides on the child processes
|
|
6
|
+
* the runner spawns (`git`, `gh`) — never a global mutation. So if the runner
|
|
7
|
+
* crashes mid-run the user's machine is untouched, and an absent identity is
|
|
8
|
+
* byte-for-byte today's ambient behaviour.
|
|
9
|
+
*
|
|
10
|
+
* # The three axes (keep these distinct — they are different concerns)
|
|
11
|
+
*
|
|
12
|
+
* 1. **commit label** (`name` / `email`) — the git author/committer strings
|
|
13
|
+
* stamped into the commit object. These are NOT authenticated: git never
|
|
14
|
+
* checks them against anything. Driven by `GIT_CONFIG_PARAMETERS`.
|
|
15
|
+
* 2. **git transport auth** (`auth`) — WHO pushes. Per-transport policy: an
|
|
16
|
+
* SSH key (or ambient ssh) drives `GIT_SSH_COMMAND`; HTTPS uses the ambient
|
|
17
|
+
* credential. This is the substrate concern — meaningful with NO provider.
|
|
18
|
+
* 3. **provider API auth** (`providers.github`) — WHO opens the PR / posts the
|
|
19
|
+
* comment, via `GH_TOKEN`. NEVER used as a git credential (git is SSH-first;
|
|
20
|
+
* GitHub is an additive layer). Optional: absent ⇒ `gh` degrades.
|
|
21
|
+
*
|
|
22
|
+
* The three axes SHOULD point at the same entity for a coherent bot (the token's
|
|
23
|
+
* GitHub account should be the account the SSH key is registered to), but nothing
|
|
24
|
+
* can verify that automatically — it is a documented coherence note, not a check.
|
|
25
|
+
*
|
|
26
|
+
* # Why `auth` is mandatory-explicit (no silent omission)
|
|
27
|
+
*
|
|
28
|
+
* `auth.ssh` and `auth.https` are BOTH required, each an explicit small union, so
|
|
29
|
+
* the dangerous "I set a bot provider token but left git auth ambient — and my
|
|
30
|
+
* remote is HTTPS, so I silently push as the human" misconfig is UNSPELLABLE by
|
|
31
|
+
* accident: pushing over ambient HTTPS requires literally writing
|
|
32
|
+
* `https: "ambient"`. A bot setup naturally writes `https: "never"`, which makes
|
|
33
|
+
* the leak a hard push-time failure instead of a silent wrong-account push.
|
|
34
|
+
*/
|
|
35
|
+
/** The conventional `agents.alt` TLD never resolves to a real account (deliberate). */
|
|
36
|
+
export declare const DEFAULT_IDENTITY_NAME = "dorfl";
|
|
37
|
+
export declare const DEFAULT_IDENTITY_EMAIL = "dorfl@agents.alt";
|
|
38
|
+
/**
|
|
39
|
+
* Per-transport git-auth policy for SSH. A filesystem path PINS that key
|
|
40
|
+
* (`GIT_SSH_COMMAND -i <path>`); `"ambient"` lets ssh-agent / `~/.ssh/config`
|
|
41
|
+
* resolve the key; `"never"` FORBIDS the SSH transport (a hard push-time failure
|
|
42
|
+
* if the arbiter is an SSH remote). A `union of more` later (e.g. host options).
|
|
43
|
+
*/
|
|
44
|
+
export type SshAuth = string | 'ambient' | 'never';
|
|
45
|
+
/**
|
|
46
|
+
* Per-transport git-auth policy for HTTPS. `"ambient"` uses whatever HTTPS
|
|
47
|
+
* credential the environment supplies (credential helper / cached PAT — e.g. the
|
|
48
|
+
* CI `actions/checkout` token); `"never"` FORBIDS the HTTPS transport (a hard
|
|
49
|
+
* push-time failure if the arbiter is an HTTPS remote). A token-pin member (the
|
|
50
|
+
* explicit HTTPS-push credential, distinct from the provider token) is a planned
|
|
51
|
+
* future addition — keep this a union so it grows without churn.
|
|
52
|
+
*/
|
|
53
|
+
export type HttpsAuth = 'ambient' | 'never';
|
|
54
|
+
/** Git TRANSPORT auth — both transports stated, no silent-omission state. */
|
|
55
|
+
export interface GitAuth {
|
|
56
|
+
/** Policy for SSH pushes: a key path, `"ambient"`, or `"never"`. */
|
|
57
|
+
ssh: SshAuth;
|
|
58
|
+
/** Policy for HTTPS pushes: `"ambient"` or `"never"`. */
|
|
59
|
+
https: HttpsAuth;
|
|
60
|
+
}
|
|
61
|
+
/** Provider API auth — the `gh` token, by literal value OR an env-var name. */
|
|
62
|
+
export type GitHubProviderAuth = {
|
|
63
|
+
token: string;
|
|
64
|
+
} | {
|
|
65
|
+
tokenEnv: string;
|
|
66
|
+
};
|
|
67
|
+
/** The optional, pluggable review-request providers (matches `ProviderName`). */
|
|
68
|
+
export interface IdentityProviders {
|
|
69
|
+
/** GitHub provider API auth (`gh`). Absent ⇒ `gh` runs unauthenticated. */
|
|
70
|
+
github?: GitHubProviderAuth;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* A configured runner identity (a bot). The WHOLE block is optional — absent ⇒
|
|
74
|
+
* fully ambient (today's behaviour, byte-for-byte). When present, `auth` is
|
|
75
|
+
* MANDATORY (both transports stated); `name`/`email` default in; `providers` is
|
|
76
|
+
* optional. HOST-ONLY: rejected in a per-repo `.dorfl.json` (it carries
|
|
77
|
+
* secrets and is per-machine), so it lives only in the global config.
|
|
78
|
+
*/
|
|
79
|
+
export interface Identity {
|
|
80
|
+
/** Commit author/committer LABEL. Default {@link DEFAULT_IDENTITY_NAME}. */
|
|
81
|
+
name?: string;
|
|
82
|
+
/** Commit author/committer LABEL. Default {@link DEFAULT_IDENTITY_EMAIL}. */
|
|
83
|
+
email?: string;
|
|
84
|
+
/** Git transport auth (mandatory when identity present). */
|
|
85
|
+
auth: GitAuth;
|
|
86
|
+
/** Optional pluggable providers (GitHub today). */
|
|
87
|
+
providers?: IdentityProviders;
|
|
88
|
+
}
|
|
89
|
+
/** Which transport an arbiter remote URL pushes over. */
|
|
90
|
+
export type ArbiterTransport = 'ssh' | 'https' | 'local';
|
|
91
|
+
/**
|
|
92
|
+
* Classify the git transport an arbiter remote URL uses — the fact that selects
|
|
93
|
+
* WHICH `auth` policy (`ssh` vs `https`) applies at push time. Mirrors the four
|
|
94
|
+
* URL shapes `repo-mirror`/`github` already handle:
|
|
95
|
+
*
|
|
96
|
+
* - scp-like ssh (`git@host:org/repo.git`) and `ssh://` ⇒ `ssh`
|
|
97
|
+
* - `https://` / `http://` ⇒ `https`
|
|
98
|
+
* - `file://` / a plain local path ⇒ `local` (no transport auth applies)
|
|
99
|
+
*/
|
|
100
|
+
export declare function arbiterTransport(url: string): ArbiterTransport;
|
|
101
|
+
/** A validation failure naming the offending field (load-time config error). */
|
|
102
|
+
export declare class IdentityConfigError extends Error {
|
|
103
|
+
}
|
|
104
|
+
/** A push-time transport-coherence failure (forbidden transport for the arbiter). */
|
|
105
|
+
export declare class IdentityTransportError extends Error {
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Validate a present `identity` block at config-LOAD time (dumb — does NOT
|
|
109
|
+
* resolve any arbiter URL; the transport-coherence check is push-time). Throws
|
|
110
|
+
* an {@link IdentityConfigError} naming the offending field. The structural
|
|
111
|
+
* "auth mandatory / ssh+https stated" guarantee mostly rides on the type, but a
|
|
112
|
+
* JSON file is untyped, so we re-check it here for a human-facing message.
|
|
113
|
+
*/
|
|
114
|
+
export declare function validateIdentity(identity: Identity): void;
|
|
115
|
+
/**
|
|
116
|
+
* Resolve the `gh` token for the GitHub provider from the identity, or
|
|
117
|
+
* `undefined` when no GitHub provider auth is configured. A `tokenEnv` is read
|
|
118
|
+
* from `env` at USE-time (so a missing env var surfaces here with a clear
|
|
119
|
+
* message), `token` is the literal value. `env` defaults to `process.env`.
|
|
120
|
+
*/
|
|
121
|
+
export declare function resolveGitHubToken(identity: Identity | undefined, env?: NodeJS.ProcessEnv): string | undefined;
|
|
122
|
+
/**
|
|
123
|
+
* Build the process-scoped environment overrides for `identity`, merged over
|
|
124
|
+
* `base` (default `process.env`). Returns `base` UNCHANGED (same reference) when
|
|
125
|
+
* `identity` is `undefined` — the absent-identity path is byte-for-byte today's
|
|
126
|
+
* behaviour, so callers can pass the result straight through.
|
|
127
|
+
*
|
|
128
|
+
* When present it sets, on a COPY of `base`:
|
|
129
|
+
* - `GIT_CONFIG_PARAMETERS` — quoted `'user.name=…' 'user.email=…'` (defaults
|
|
130
|
+
* applied). Properly single-quoted (with `'\''` escaping) so a name/email
|
|
131
|
+
* containing a space or quote cannot break the parse.
|
|
132
|
+
* - `GIT_AUTHOR_NAME`/`GIT_AUTHOR_EMAIL`/`GIT_COMMITTER_NAME`/
|
|
133
|
+
* `GIT_COMMITTER_EMAIL` — set to the SAME bot name/email. This is
|
|
134
|
+
* LOAD-BEARING: the per-commit `GIT_AUTHOR_*`/`GIT_COMMITTER_*` env vars take
|
|
135
|
+
* PRECEDENCE over `user.name`/`user.email` (and thus over
|
|
136
|
+
* `GIT_CONFIG_PARAMETERS`). If the AMBIENT env already has them (some CI /
|
|
137
|
+
* tooling sets them), `GIT_CONFIG_PARAMETERS` alone would be SILENTLY ignored
|
|
138
|
+
* and the commit would be authored by the ambient identity — exactly the
|
|
139
|
+
* silent-fallback this feature exists to prevent. So we pin all four to the
|
|
140
|
+
* identity, making it win UNCONDITIONALLY over any ambient git identity.
|
|
141
|
+
* - `GIT_SSH_COMMAND` — `ssh -i <path> -o IdentitiesOnly=yes -o
|
|
142
|
+
* IdentityAgent=none` ONLY when `auth.ssh` is a key path. `"ambient"`/`"never"`
|
|
143
|
+
* set nothing (ambient ssh resolution; `"never"` is enforced by the push-time
|
|
144
|
+
* transport guard).
|
|
145
|
+
*
|
|
146
|
+
* `IdentityAgent=none` is LOAD-BEARING, NOT decoration: `IdentitiesOnly=yes`
|
|
147
|
+
* ALONE does NOT stop a running ssh-agent from offering its OWN keys — it only
|
|
148
|
+
* restricts which keys are tried to those whose public file is named, and an
|
|
149
|
+
* agent key matching a discoverable `~/.ssh/*.pub` is still offered FIRST. So
|
|
150
|
+
* with a personal key in the agent, the push could silently authenticate as
|
|
151
|
+
* the HUMAN (the wrong account) despite `-i <bot key>` — the exact silent-
|
|
152
|
+
* wrong-account failure mode this feature exists to prevent (the SSH-axis twin
|
|
153
|
+
* of the `GIT_AUTHOR_*` pinning below). `IdentityAgent=none` detaches the
|
|
154
|
+
* agent entirely, so ONLY the pinned key is offered — it wins unconditionally.
|
|
155
|
+
* - `GH_TOKEN` — ONLY when a GitHub provider token is configured (resolved at
|
|
156
|
+
* use-time). NEVER fed to git (the token is provider-API only).
|
|
157
|
+
*/
|
|
158
|
+
export declare function identityEnv(identity: Identity | undefined, base?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
|
|
159
|
+
/**
|
|
160
|
+
* Enforce the push-time transport-coherence rule: the `auth` policy for the
|
|
161
|
+
* arbiter's actual transport must not be `"never"`. Throws an
|
|
162
|
+
* {@link IdentityTransportError} with an actionable message (use a matching
|
|
163
|
+
* remote, or unset `identity`) when the transport is forbidden. A `local`
|
|
164
|
+
* arbiter (or an absent identity) has nothing to enforce.
|
|
165
|
+
*/
|
|
166
|
+
export declare function assertTransportAllowed(identity: Identity | undefined, arbiterUrl: string): void;
|
|
167
|
+
//# sourceMappingURL=identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,uFAAuF;AACvF,eAAO,MAAM,qBAAqB,UAAU,CAAC;AAC7C,eAAO,MAAM,sBAAsB,qBAAqB,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;AAEnD;;;;;;;GAOG;AACH,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAE5C,6EAA6E;AAC7E,MAAM,WAAW,OAAO;IACvB,oEAAoE;IACpE,GAAG,EAAE,OAAO,CAAC;IACb,yDAAyD;IACzD,KAAK,EAAE,SAAS,CAAC;CACjB;AAED,+EAA+E;AAC/E,MAAM,MAAM,kBAAkB,GAAG;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,GAAG;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAC,CAAC;AAEtE,iFAAiF;AACjF,MAAM,WAAW,iBAAiB;IACjC,2EAA2E;IAC3E,MAAM,CAAC,EAAE,kBAAkB,CAAC;CAC5B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,QAAQ;IACxB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,IAAI,EAAE,OAAO,CAAC;IACd,mDAAmD;IACnD,SAAS,CAAC,EAAE,iBAAiB,CAAC;CAC9B;AAED,yDAAyD;AACzD,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,OAAO,GAAG,OAAO,CAAC;AAEzD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAkB9D;AAED,gFAAgF;AAChF,qBAAa,mBAAoB,SAAQ,KAAK;CAAG;AAEjD,qFAAqF;AACrF,qBAAa,sBAAuB,SAAQ,KAAK;CAAG;AAEpD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAkCzD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CACjC,QAAQ,EAAE,QAAQ,GAAG,SAAS,EAC9B,GAAG,GAAE,MAAM,CAAC,UAAwB,GAClC,MAAM,GAAG,SAAS,CAmBpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,WAAW,CAC1B,QAAQ,EAAE,QAAQ,GAAG,SAAS,EAC9B,IAAI,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,CAAC,UAAU,CAuCnB;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACrC,QAAQ,EAAE,QAAQ,GAAG,SAAS,EAC9B,UAAU,EAAE,MAAM,GAChB,IAAI,CAmBN"}
|
package/dist/identity.js
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The **identity** feature: run the runner's git + provider operations as a
|
|
3
|
+
* configured entity (a bot), without mutating the user's global git/`gh` config.
|
|
4
|
+
*
|
|
5
|
+
* The mechanism is process-scoped environment overrides on the child processes
|
|
6
|
+
* the runner spawns (`git`, `gh`) — never a global mutation. So if the runner
|
|
7
|
+
* crashes mid-run the user's machine is untouched, and an absent identity is
|
|
8
|
+
* byte-for-byte today's ambient behaviour.
|
|
9
|
+
*
|
|
10
|
+
* # The three axes (keep these distinct — they are different concerns)
|
|
11
|
+
*
|
|
12
|
+
* 1. **commit label** (`name` / `email`) — the git author/committer strings
|
|
13
|
+
* stamped into the commit object. These are NOT authenticated: git never
|
|
14
|
+
* checks them against anything. Driven by `GIT_CONFIG_PARAMETERS`.
|
|
15
|
+
* 2. **git transport auth** (`auth`) — WHO pushes. Per-transport policy: an
|
|
16
|
+
* SSH key (or ambient ssh) drives `GIT_SSH_COMMAND`; HTTPS uses the ambient
|
|
17
|
+
* credential. This is the substrate concern — meaningful with NO provider.
|
|
18
|
+
* 3. **provider API auth** (`providers.github`) — WHO opens the PR / posts the
|
|
19
|
+
* comment, via `GH_TOKEN`. NEVER used as a git credential (git is SSH-first;
|
|
20
|
+
* GitHub is an additive layer). Optional: absent ⇒ `gh` degrades.
|
|
21
|
+
*
|
|
22
|
+
* The three axes SHOULD point at the same entity for a coherent bot (the token's
|
|
23
|
+
* GitHub account should be the account the SSH key is registered to), but nothing
|
|
24
|
+
* can verify that automatically — it is a documented coherence note, not a check.
|
|
25
|
+
*
|
|
26
|
+
* # Why `auth` is mandatory-explicit (no silent omission)
|
|
27
|
+
*
|
|
28
|
+
* `auth.ssh` and `auth.https` are BOTH required, each an explicit small union, so
|
|
29
|
+
* the dangerous "I set a bot provider token but left git auth ambient — and my
|
|
30
|
+
* remote is HTTPS, so I silently push as the human" misconfig is UNSPELLABLE by
|
|
31
|
+
* accident: pushing over ambient HTTPS requires literally writing
|
|
32
|
+
* `https: "ambient"`. A bot setup naturally writes `https: "never"`, which makes
|
|
33
|
+
* the leak a hard push-time failure instead of a silent wrong-account push.
|
|
34
|
+
*/
|
|
35
|
+
/** The conventional `agents.alt` TLD never resolves to a real account (deliberate). */
|
|
36
|
+
export const DEFAULT_IDENTITY_NAME = 'dorfl';
|
|
37
|
+
export const DEFAULT_IDENTITY_EMAIL = 'dorfl@agents.alt';
|
|
38
|
+
/**
|
|
39
|
+
* Classify the git transport an arbiter remote URL uses — the fact that selects
|
|
40
|
+
* WHICH `auth` policy (`ssh` vs `https`) applies at push time. Mirrors the four
|
|
41
|
+
* URL shapes `repo-mirror`/`github` already handle:
|
|
42
|
+
*
|
|
43
|
+
* - scp-like ssh (`git@host:org/repo.git`) and `ssh://` ⇒ `ssh`
|
|
44
|
+
* - `https://` / `http://` ⇒ `https`
|
|
45
|
+
* - `file://` / a plain local path ⇒ `local` (no transport auth applies)
|
|
46
|
+
*/
|
|
47
|
+
export function arbiterTransport(url) {
|
|
48
|
+
const trimmed = url.trim();
|
|
49
|
+
if (!trimmed.includes('://')) {
|
|
50
|
+
// scp-like ssh: [user@]host:path (a `:` before the path, NOT a local path).
|
|
51
|
+
const scp = /^(?:[^@/]+@)?([^/:]+):(.+)$/;
|
|
52
|
+
if (scp.test(trimmed) && !trimmed.startsWith('/')) {
|
|
53
|
+
return 'ssh';
|
|
54
|
+
}
|
|
55
|
+
return 'local'; // a plain absolute path has no transport
|
|
56
|
+
}
|
|
57
|
+
const scheme = trimmed.slice(0, trimmed.indexOf('://')).toLowerCase();
|
|
58
|
+
if (scheme === 'ssh') {
|
|
59
|
+
return 'ssh';
|
|
60
|
+
}
|
|
61
|
+
if (scheme === 'https' || scheme === 'http') {
|
|
62
|
+
return 'https';
|
|
63
|
+
}
|
|
64
|
+
return 'local'; // file:// (or anything else) — no transport auth
|
|
65
|
+
}
|
|
66
|
+
/** A validation failure naming the offending field (load-time config error). */
|
|
67
|
+
export class IdentityConfigError extends Error {
|
|
68
|
+
}
|
|
69
|
+
/** A push-time transport-coherence failure (forbidden transport for the arbiter). */
|
|
70
|
+
export class IdentityTransportError extends Error {
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Validate a present `identity` block at config-LOAD time (dumb — does NOT
|
|
74
|
+
* resolve any arbiter URL; the transport-coherence check is push-time). Throws
|
|
75
|
+
* an {@link IdentityConfigError} naming the offending field. The structural
|
|
76
|
+
* "auth mandatory / ssh+https stated" guarantee mostly rides on the type, but a
|
|
77
|
+
* JSON file is untyped, so we re-check it here for a human-facing message.
|
|
78
|
+
*/
|
|
79
|
+
export function validateIdentity(identity) {
|
|
80
|
+
if (identity.auth === undefined || identity.auth === null) {
|
|
81
|
+
throw new IdentityConfigError('identity.auth is required when an identity is configured ' +
|
|
82
|
+
'(state both `ssh` and `https`).');
|
|
83
|
+
}
|
|
84
|
+
const { ssh, https } = identity.auth;
|
|
85
|
+
if (ssh === undefined || ssh === null || ssh === '') {
|
|
86
|
+
throw new IdentityConfigError('identity.auth.ssh is required (a key path, "ambient", or "never").');
|
|
87
|
+
}
|
|
88
|
+
if (https !== 'ambient' && https !== 'never') {
|
|
89
|
+
throw new IdentityConfigError('identity.auth.https must be "ambient" or "never".');
|
|
90
|
+
}
|
|
91
|
+
const github = identity.providers?.github;
|
|
92
|
+
if (github !== undefined) {
|
|
93
|
+
const hasToken = 'token' in github && github.token !== undefined;
|
|
94
|
+
const hasEnv = 'tokenEnv' in github && github.tokenEnv !== undefined;
|
|
95
|
+
if (hasToken && hasEnv) {
|
|
96
|
+
throw new IdentityConfigError('identity.providers.github must set exactly one of `token` or ' +
|
|
97
|
+
'`tokenEnv`, not both.');
|
|
98
|
+
}
|
|
99
|
+
if (!hasToken && !hasEnv) {
|
|
100
|
+
throw new IdentityConfigError('identity.providers.github must set `token` or `tokenEnv`.');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Resolve the `gh` token for the GitHub provider from the identity, or
|
|
106
|
+
* `undefined` when no GitHub provider auth is configured. A `tokenEnv` is read
|
|
107
|
+
* from `env` at USE-time (so a missing env var surfaces here with a clear
|
|
108
|
+
* message), `token` is the literal value. `env` defaults to `process.env`.
|
|
109
|
+
*/
|
|
110
|
+
export function resolveGitHubToken(identity, env = process.env) {
|
|
111
|
+
const github = identity?.providers?.github;
|
|
112
|
+
if (github === undefined) {
|
|
113
|
+
return undefined;
|
|
114
|
+
}
|
|
115
|
+
if ('token' in github && github.token !== undefined) {
|
|
116
|
+
return github.token;
|
|
117
|
+
}
|
|
118
|
+
if ('tokenEnv' in github && github.tokenEnv !== undefined) {
|
|
119
|
+
const value = env[github.tokenEnv];
|
|
120
|
+
if (value === undefined || value === '') {
|
|
121
|
+
throw new IdentityConfigError(`identity.providers.github.tokenEnv names env var ` +
|
|
122
|
+
`"${github.tokenEnv}", which is unset or empty.`);
|
|
123
|
+
}
|
|
124
|
+
return value;
|
|
125
|
+
}
|
|
126
|
+
return undefined;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Build the process-scoped environment overrides for `identity`, merged over
|
|
130
|
+
* `base` (default `process.env`). Returns `base` UNCHANGED (same reference) when
|
|
131
|
+
* `identity` is `undefined` — the absent-identity path is byte-for-byte today's
|
|
132
|
+
* behaviour, so callers can pass the result straight through.
|
|
133
|
+
*
|
|
134
|
+
* When present it sets, on a COPY of `base`:
|
|
135
|
+
* - `GIT_CONFIG_PARAMETERS` — quoted `'user.name=…' 'user.email=…'` (defaults
|
|
136
|
+
* applied). Properly single-quoted (with `'\''` escaping) so a name/email
|
|
137
|
+
* containing a space or quote cannot break the parse.
|
|
138
|
+
* - `GIT_AUTHOR_NAME`/`GIT_AUTHOR_EMAIL`/`GIT_COMMITTER_NAME`/
|
|
139
|
+
* `GIT_COMMITTER_EMAIL` — set to the SAME bot name/email. This is
|
|
140
|
+
* LOAD-BEARING: the per-commit `GIT_AUTHOR_*`/`GIT_COMMITTER_*` env vars take
|
|
141
|
+
* PRECEDENCE over `user.name`/`user.email` (and thus over
|
|
142
|
+
* `GIT_CONFIG_PARAMETERS`). If the AMBIENT env already has them (some CI /
|
|
143
|
+
* tooling sets them), `GIT_CONFIG_PARAMETERS` alone would be SILENTLY ignored
|
|
144
|
+
* and the commit would be authored by the ambient identity — exactly the
|
|
145
|
+
* silent-fallback this feature exists to prevent. So we pin all four to the
|
|
146
|
+
* identity, making it win UNCONDITIONALLY over any ambient git identity.
|
|
147
|
+
* - `GIT_SSH_COMMAND` — `ssh -i <path> -o IdentitiesOnly=yes -o
|
|
148
|
+
* IdentityAgent=none` ONLY when `auth.ssh` is a key path. `"ambient"`/`"never"`
|
|
149
|
+
* set nothing (ambient ssh resolution; `"never"` is enforced by the push-time
|
|
150
|
+
* transport guard).
|
|
151
|
+
*
|
|
152
|
+
* `IdentityAgent=none` is LOAD-BEARING, NOT decoration: `IdentitiesOnly=yes`
|
|
153
|
+
* ALONE does NOT stop a running ssh-agent from offering its OWN keys — it only
|
|
154
|
+
* restricts which keys are tried to those whose public file is named, and an
|
|
155
|
+
* agent key matching a discoverable `~/.ssh/*.pub` is still offered FIRST. So
|
|
156
|
+
* with a personal key in the agent, the push could silently authenticate as
|
|
157
|
+
* the HUMAN (the wrong account) despite `-i <bot key>` — the exact silent-
|
|
158
|
+
* wrong-account failure mode this feature exists to prevent (the SSH-axis twin
|
|
159
|
+
* of the `GIT_AUTHOR_*` pinning below). `IdentityAgent=none` detaches the
|
|
160
|
+
* agent entirely, so ONLY the pinned key is offered — it wins unconditionally.
|
|
161
|
+
* - `GH_TOKEN` — ONLY when a GitHub provider token is configured (resolved at
|
|
162
|
+
* use-time). NEVER fed to git (the token is provider-API only).
|
|
163
|
+
*/
|
|
164
|
+
export function identityEnv(identity, base = process.env) {
|
|
165
|
+
if (identity === undefined) {
|
|
166
|
+
return base;
|
|
167
|
+
}
|
|
168
|
+
const name = identity.name ?? DEFAULT_IDENTITY_NAME;
|
|
169
|
+
const email = identity.email ?? DEFAULT_IDENTITY_EMAIL;
|
|
170
|
+
const env = { ...base };
|
|
171
|
+
// Commit LABEL (always set when an identity is present). GIT_CONFIG_PARAMETERS
|
|
172
|
+
// is a space-separated list of shell-quoted `key=value` pairs.
|
|
173
|
+
env.GIT_CONFIG_PARAMETERS = [
|
|
174
|
+
shellQuote(`user.name=${name}`),
|
|
175
|
+
shellQuote(`user.email=${email}`),
|
|
176
|
+
].join(' ');
|
|
177
|
+
// Pin the per-commit author/committer env too — these OUTRANK `user.name`/
|
|
178
|
+
// `user.email`, so without them an ambient `GIT_AUTHOR_*`/`GIT_COMMITTER_*`
|
|
179
|
+
// would silently beat the identity (the silent-fallback failure mode). Setting
|
|
180
|
+
// them makes the identity win unconditionally.
|
|
181
|
+
env.GIT_AUTHOR_NAME = name;
|
|
182
|
+
env.GIT_AUTHOR_EMAIL = email;
|
|
183
|
+
env.GIT_COMMITTER_NAME = name;
|
|
184
|
+
env.GIT_COMMITTER_EMAIL = email;
|
|
185
|
+
// Git TRANSPORT auth — only a PINNED ssh key sets GIT_SSH_COMMAND.
|
|
186
|
+
// `IdentityAgent=none` is REQUIRED for the pin to actually hold: without it a
|
|
187
|
+
// running ssh-agent (e.g. with the human's personal key) can offer its own keys
|
|
188
|
+
// FIRST and silently push as the wrong account, despite `-i <bot key>`.
|
|
189
|
+
const ssh = identity.auth.ssh;
|
|
190
|
+
if (ssh !== 'ambient' && ssh !== 'never') {
|
|
191
|
+
env.GIT_SSH_COMMAND = `ssh -i ${shellQuote(ssh)} -o IdentitiesOnly=yes -o IdentityAgent=none`;
|
|
192
|
+
}
|
|
193
|
+
// Provider API auth — the gh token, NEVER a git credential.
|
|
194
|
+
const token = resolveGitHubToken(identity, base);
|
|
195
|
+
if (token !== undefined) {
|
|
196
|
+
env.GH_TOKEN = token;
|
|
197
|
+
}
|
|
198
|
+
return env;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Enforce the push-time transport-coherence rule: the `auth` policy for the
|
|
202
|
+
* arbiter's actual transport must not be `"never"`. Throws an
|
|
203
|
+
* {@link IdentityTransportError} with an actionable message (use a matching
|
|
204
|
+
* remote, or unset `identity`) when the transport is forbidden. A `local`
|
|
205
|
+
* arbiter (or an absent identity) has nothing to enforce.
|
|
206
|
+
*/
|
|
207
|
+
export function assertTransportAllowed(identity, arbiterUrl) {
|
|
208
|
+
if (identity === undefined) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
const transport = arbiterTransport(arbiterUrl);
|
|
212
|
+
if (transport === 'ssh' && identity.auth.ssh === 'never') {
|
|
213
|
+
throw new IdentityTransportError(`identity forbids SSH (auth.ssh: "never") but arbiter ` +
|
|
214
|
+
`"${arbiterUrl}" is an SSH remote. Use an HTTPS remote, set ` +
|
|
215
|
+
`auth.ssh to a key path or "ambient", or unset identity.`);
|
|
216
|
+
}
|
|
217
|
+
if (transport === 'https' && identity.auth.https === 'never') {
|
|
218
|
+
throw new IdentityTransportError(`identity forbids HTTPS (auth.https: "never") but arbiter ` +
|
|
219
|
+
`"${arbiterUrl}" is an HTTPS remote. Use an SSH remote, set ` +
|
|
220
|
+
`auth.https to "ambient", or unset identity.`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Single-quote a string for safe inclusion in a `GIT_CONFIG_PARAMETERS` /
|
|
225
|
+
* `GIT_SSH_COMMAND` value: wrap in single quotes and escape any embedded single
|
|
226
|
+
* quote as `'\''` (close-quote, escaped-quote, re-open-quote — the POSIX idiom).
|
|
227
|
+
*/
|
|
228
|
+
function shellQuote(value) {
|
|
229
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"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"}
|