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
|
@@ -0,0 +1,552 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `install-ci` orchestrator (prd `runner-in-ci`, task
|
|
3
|
+
* `install-ci-core-and-github-adapter`): ties the provider-agnostic core
|
|
4
|
+
* (`install-ci-core.ts`) to a CI-provider adapter (the first being GitHub,
|
|
5
|
+
* `install-ci-github.ts`) through the {@link CIProviderContext} seam. It drives
|
|
6
|
+
* three paths from ONE config shape so they cannot diverge:
|
|
7
|
+
*
|
|
8
|
+
* - the interactive WIZARD (prompts via the injectable {@link WizardPrompts}
|
|
9
|
+
* seam — production wires readline; tests inject a deterministic stub);
|
|
10
|
+
* - the non-interactive `--config <file>` path (loads the same shape, no prompts);
|
|
11
|
+
* - `--export-config` (+ `--include-secrets`) which round-trips the gathered
|
|
12
|
+
* config back to JSON.
|
|
13
|
+
*
|
|
14
|
+
* The artifacts (composite setup action + auth) are assembled by the core and
|
|
15
|
+
* written under `.fake/` in `--fake` snapshot mode (NEVER `.github/`, NO real
|
|
16
|
+
* secret), so the SAME inputs produce byte-identical output whether gathered
|
|
17
|
+
* interactively or from a config file (the equivalence the task pins).
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import {writeFileSync, readFileSync, existsSync} from 'node:fs';
|
|
21
|
+
import {join} from 'node:path';
|
|
22
|
+
import {
|
|
23
|
+
type AuthMode,
|
|
24
|
+
type ProviderEntry,
|
|
25
|
+
type CIConfigFile,
|
|
26
|
+
type ResolvedCIConfig,
|
|
27
|
+
type InstallSource,
|
|
28
|
+
type CIProviderContext,
|
|
29
|
+
type CapabilityEmitter,
|
|
30
|
+
type SecretSetResult,
|
|
31
|
+
DEFAULT_HARNESS,
|
|
32
|
+
loadCIConfigFile,
|
|
33
|
+
resolveCIConfig,
|
|
34
|
+
exportCIConfig,
|
|
35
|
+
orchestrateSecrets,
|
|
36
|
+
buildSetupArtifacts,
|
|
37
|
+
writeArtifacts,
|
|
38
|
+
} from './install-ci-core.js';
|
|
39
|
+
import type {HarnessAdapter} from './config.js';
|
|
40
|
+
import {
|
|
41
|
+
installCIBranchProtectionStep,
|
|
42
|
+
type BranchProtectionStepResult,
|
|
43
|
+
} from './install-ci-branch-protection.js';
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* The interactive prompt SEAM the wizard drives. Production wires readline; tests
|
|
47
|
+
* inject a deterministic stub so the wizard runs with NO TTY, NO network, and the
|
|
48
|
+
* gathered config exactly equals a config-file input (proving the equivalence).
|
|
49
|
+
*/
|
|
50
|
+
export interface WizardPrompts {
|
|
51
|
+
/** A free-text answer (with an optional default). */
|
|
52
|
+
input(message: string, opts?: {default?: string}): Promise<string>;
|
|
53
|
+
/** A masked secret answer (never echoed). */
|
|
54
|
+
password(message: string): Promise<string>;
|
|
55
|
+
/** A yes/no answer (with a default). */
|
|
56
|
+
confirm(message: string, opts: {default: boolean}): Promise<boolean>;
|
|
57
|
+
/** Pick one of `choices` (each `{name, value}`). */
|
|
58
|
+
select<T extends string>(
|
|
59
|
+
message: string,
|
|
60
|
+
choices: {name: string; value: T}[],
|
|
61
|
+
): Promise<T>;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Options for {@link installCI}. */
|
|
65
|
+
export interface InstallCIOptions {
|
|
66
|
+
/** The CI-provider seam (GitHub adapter in production; a stub in tests). */
|
|
67
|
+
ctx: CIProviderContext;
|
|
68
|
+
/** Snapshot mode: write to `.fake/` (never `.github/`), set NO real secret. */
|
|
69
|
+
fake?: boolean;
|
|
70
|
+
/** Non-interactive: load the config from this JSON file (skips the wizard). */
|
|
71
|
+
configFile?: string;
|
|
72
|
+
/** Write the gathered config as JSON to this path instead of generating. */
|
|
73
|
+
exportConfig?: string;
|
|
74
|
+
/** With `--export-config`: also gather + include the secret values. */
|
|
75
|
+
includeSecrets?: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Force the CLI install source (`registry` / `workspace`), overriding the
|
|
78
|
+
* package.json auto-detection in BOTH directions. When omitted, the source
|
|
79
|
+
* comes from the config file (if it set it) else the auto-detection below.
|
|
80
|
+
*/
|
|
81
|
+
installSource?: InstallSource;
|
|
82
|
+
/**
|
|
83
|
+
* Force the advance-lifecycle matrix concurrency cap (`--max-parallel`),
|
|
84
|
+
* overriding the config file's value. When omitted, it comes from the config
|
|
85
|
+
* file (if set) else {@link DEFAULT_MAX_PARALLEL}. Must be a positive integer.
|
|
86
|
+
*/
|
|
87
|
+
maxParallel?: number;
|
|
88
|
+
/** The interactive prompt seam (required unless `configFile` is given). */
|
|
89
|
+
prompts?: WizardPrompts;
|
|
90
|
+
/** The capability emitters to emit workflows for (none in this core task). */
|
|
91
|
+
capabilities?: CapabilityEmitter[];
|
|
92
|
+
/** Sink for human-facing progress lines (default: console.log). */
|
|
93
|
+
log?: (line: string) => void;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** The result of an {@link installCI} run. */
|
|
97
|
+
export interface InstallCIResult {
|
|
98
|
+
/** What the run did. */
|
|
99
|
+
outcome: 'exported' | 'generated';
|
|
100
|
+
/** The resolved config that was used. */
|
|
101
|
+
config: ResolvedCIConfig;
|
|
102
|
+
/** Repo-relative paths written (the artifacts), empty on `exported`. */
|
|
103
|
+
written: string[];
|
|
104
|
+
/** The secret-orchestration outcomes (empty on `--fake` / `exported`). */
|
|
105
|
+
secrets: SecretSetResult[];
|
|
106
|
+
/** The Tier-1 branch-protection outcome (undefined on `exported`). */
|
|
107
|
+
branchProtection?: BranchProtectionStepResult;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Run `install-ci`. Resolves the config (config-file path or the wizard), then
|
|
112
|
+
* either exports it (`--export-config`) or generates the artifacts. In `--fake`
|
|
113
|
+
* mode it writes to `.fake/` and sets NO real secret; otherwise it orchestrates
|
|
114
|
+
* the required secrets through the provider seam. Returns a structured result.
|
|
115
|
+
*/
|
|
116
|
+
export async function installCI(
|
|
117
|
+
options: InstallCIOptions,
|
|
118
|
+
): Promise<InstallCIResult> {
|
|
119
|
+
const log = options.log ?? ((line: string) => console.log(line));
|
|
120
|
+
const fake = options.fake ?? false;
|
|
121
|
+
|
|
122
|
+
// 1. Resolve the config: the config-file path (no prompts) or the wizard.
|
|
123
|
+
let file: CIConfigFile;
|
|
124
|
+
let knownSecrets: Record<string, string> | undefined;
|
|
125
|
+
if (options.configFile) {
|
|
126
|
+
file = loadCIConfigFile(options.configFile);
|
|
127
|
+
knownSecrets = file.secrets;
|
|
128
|
+
} else {
|
|
129
|
+
if (!options.prompts) {
|
|
130
|
+
throw new Error(
|
|
131
|
+
'install-ci: an interactive run needs a prompt seam (or pass --config)',
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
file = await runWizard(options.prompts);
|
|
135
|
+
}
|
|
136
|
+
const config = resolveCIConfig(file);
|
|
137
|
+
|
|
138
|
+
// An EXPLICIT --install-source flag wins over the config file's value and is
|
|
139
|
+
// folded in BEFORE the export so it round-trips through --export-config. The
|
|
140
|
+
// package.json AUTO-DETECTION (below) is applied AFTER the export early-return
|
|
141
|
+
// instead, so it is NOT baked into an exported config (a consumer re-running
|
|
142
|
+
// from that export must not silently inherit the monorepo's workspace mode).
|
|
143
|
+
const explicitInstallSource =
|
|
144
|
+
options.installSource ?? file.installSource ?? undefined;
|
|
145
|
+
if (options.installSource) {
|
|
146
|
+
config.installSource = options.installSource;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// An EXPLICIT --max-parallel flag wins over the config file's value and is
|
|
150
|
+
// folded in BEFORE the export so it round-trips through --export-config.
|
|
151
|
+
if (options.maxParallel !== undefined) {
|
|
152
|
+
config.maxParallel = options.maxParallel;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// 2. --export-config: round-trip the gathered config back to JSON and exit.
|
|
156
|
+
if (options.exportConfig) {
|
|
157
|
+
let secrets: Record<string, string> | undefined;
|
|
158
|
+
if (options.includeSecrets) {
|
|
159
|
+
secrets = await gatherSecretsForExport(file, options.prompts);
|
|
160
|
+
}
|
|
161
|
+
writeFileSync(
|
|
162
|
+
options.exportConfig,
|
|
163
|
+
exportCIConfig(config, secrets),
|
|
164
|
+
'utf8',
|
|
165
|
+
);
|
|
166
|
+
log(`Config written to ${options.exportConfig}`);
|
|
167
|
+
return {outcome: 'exported', config, written: [], secrets: []};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// 2b. Auto-detect the WORKSPACE install source: when no explicit flag/config
|
|
171
|
+
// value was given AND <workDir>/package.json is the dorfl monorepo,
|
|
172
|
+
// build the CLI from source instead of pulling the (unpublished) registry
|
|
173
|
+
// package. A single exact-name check (NOT a fuzzy "dorfl" match, or
|
|
174
|
+
// it would wrongly trip in a consumer repo named similarly). A missing or
|
|
175
|
+
// unparseable package.json stays `registry` (the error is swallowed). This
|
|
176
|
+
// runs AFTER the export early-return so it is never baked into an export.
|
|
177
|
+
if (!explicitInstallSource) {
|
|
178
|
+
try {
|
|
179
|
+
const pkgPath = join(options.ctx.workDir, 'package.json');
|
|
180
|
+
if (existsSync(pkgPath)) {
|
|
181
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as {
|
|
182
|
+
name?: string;
|
|
183
|
+
};
|
|
184
|
+
if (pkg.name === 'dorfl-monorepo') {
|
|
185
|
+
config.installSource = 'workspace';
|
|
186
|
+
log(
|
|
187
|
+
'📦 Detected dorfl monorepo — using workspace install mode (build from source)',
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
} catch {
|
|
192
|
+
// Ignore — not the dorfl monorepo (missing/unparseable pkg).
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// 3. Orchestrate secrets — SKIPPED in --fake mode (no real secret touched).
|
|
197
|
+
let secrets: SecretSetResult[] = [];
|
|
198
|
+
if (fake) {
|
|
199
|
+
log('--fake: skipping secret setup (no real secret is set)');
|
|
200
|
+
} else {
|
|
201
|
+
secrets = await orchestrateSecrets({
|
|
202
|
+
ctx: options.ctx,
|
|
203
|
+
config,
|
|
204
|
+
knownSecrets,
|
|
205
|
+
prompt: options.prompts
|
|
206
|
+
? (name) =>
|
|
207
|
+
options.prompts!.password(`Enter the value for secret ${name}:`)
|
|
208
|
+
: undefined,
|
|
209
|
+
// The PR-identity token is OPTIONAL: phrase it as such, and Enter-to-skip
|
|
210
|
+
// leaves the legs on the built-in GITHUB_TOKEN fallback (zero-config).
|
|
211
|
+
optionalPrompt: options.prompts
|
|
212
|
+
? (name) =>
|
|
213
|
+
options.prompts!.password(
|
|
214
|
+
`Optional: GitHub token for the CI legs to open PRs under your ` +
|
|
215
|
+
`identity (stored as secret ${name}; a PAT or App token). ` +
|
|
216
|
+
`Leave blank to use the built-in GITHUB_TOKEN:`,
|
|
217
|
+
)
|
|
218
|
+
: undefined,
|
|
219
|
+
});
|
|
220
|
+
for (const r of secrets) {
|
|
221
|
+
if (r.status === 'set') log(` secret ${r.name}: set`);
|
|
222
|
+
else if (r.status === 'skipped')
|
|
223
|
+
log(` secret ${r.name}: skipped (empty)`);
|
|
224
|
+
else log(` secret ${r.name}: FAILED (${r.error})`);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// 4. Optionally offer the GitHub delete_branch_on_merge repo-setting (the
|
|
229
|
+
// capability-F residue): ONLY when offered + confirmed, NEVER silent.
|
|
230
|
+
if (
|
|
231
|
+
!fake &&
|
|
232
|
+
options.prompts &&
|
|
233
|
+
options.ctx.setRepoSetting &&
|
|
234
|
+
options.ctx.repo
|
|
235
|
+
) {
|
|
236
|
+
const wanted = await options.prompts.confirm(
|
|
237
|
+
"Enable GitHub's 'Automatically delete head branches' (delete_branch_on_merge)?",
|
|
238
|
+
{default: false},
|
|
239
|
+
);
|
|
240
|
+
if (wanted) {
|
|
241
|
+
try {
|
|
242
|
+
await options.ctx.setRepoSetting('delete_branch_on_merge', true);
|
|
243
|
+
log(' repo setting delete_branch_on_merge: enabled');
|
|
244
|
+
} catch (err) {
|
|
245
|
+
log(
|
|
246
|
+
` repo setting delete_branch_on_merge: FAILED (${
|
|
247
|
+
err instanceof Error ? err.message : String(err)
|
|
248
|
+
})`,
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// 5. Assemble + write the artifacts (composite setup action + auth). The
|
|
255
|
+
// project-setup escape hatch (prd `install-ci-project-provisioning`) lives
|
|
256
|
+
// on `config.projectSetup` as a PROVIDER-NAMESPACED, OPAQUE map; we look up
|
|
257
|
+
// THIS provider's payload via the seam (`ctx.providerId`) and ask the
|
|
258
|
+
// adapter to render it to the FIRST-steps fragment (`ctx.renderProjectSetup`).
|
|
259
|
+
// Absent payload / missing seam method ⇒ no fragment ⇒ byte-identical to the
|
|
260
|
+
// no-hook baseline (the load-bearing contract this hook preserves).
|
|
261
|
+
let projectSetupSteps: string | undefined;
|
|
262
|
+
const providerId = options.ctx.providerId;
|
|
263
|
+
const payload =
|
|
264
|
+
providerId && config.projectSetup
|
|
265
|
+
? config.projectSetup[providerId]
|
|
266
|
+
: undefined;
|
|
267
|
+
if (payload !== undefined && options.ctx.renderProjectSetup) {
|
|
268
|
+
projectSetupSteps = options.ctx.renderProjectSetup(payload);
|
|
269
|
+
}
|
|
270
|
+
const files = buildSetupArtifacts(config, options.capabilities ?? [], {
|
|
271
|
+
projectSetupSteps,
|
|
272
|
+
});
|
|
273
|
+
const written = writeArtifacts({workDir: options.ctx.workDir, fake, files});
|
|
274
|
+
for (const path of written) {
|
|
275
|
+
log(` wrote ${path}`);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// 5b. Tier-1 GitHub branch protection (prd land-time-reverify-and-parallel-
|
|
279
|
+
// merge-ceiling, Story 11). Auto-configures when the credential is admin-
|
|
280
|
+
// scoped (one `gh api` PUT on the protection endpoint, required check
|
|
281
|
+
// `verify` + strict: true); prints the exact ready-to-run `gh api` command
|
|
282
|
+
// + manual UI fallback when not. Skipped in --fake (no real API touched);
|
|
283
|
+
// skipped on a non-GitHub provider (the seam method is absent there).
|
|
284
|
+
const branchProtection = await installCIBranchProtectionStep({
|
|
285
|
+
ctx: options.ctx,
|
|
286
|
+
fake,
|
|
287
|
+
log,
|
|
288
|
+
});
|
|
289
|
+
// CI-autonomy posture (task `install-ci-emits-no-gate-env-let-config-decide`):
|
|
290
|
+
// the emitted advance workflow carries NO DORFL_AUTO_BUILD /
|
|
291
|
+
// DORFL_AUTO_TASK / DORFL_OBSERVATION_TRIAGE /
|
|
292
|
+
// DORFL_SURFACE_BLOCKERS env line. Gate policy is resolved through the
|
|
293
|
+
// same `flag > env > per-repo > global > default` chain the engine uses
|
|
294
|
+
// everywhere, so CI is treated like any other config consumer. A config-less
|
|
295
|
+
// repo therefore lands on the strict built-in defaults (autoBuild: false,
|
|
296
|
+
// autoTask: false, observationTriage: 'off', surfaceBlockers: false) and CI
|
|
297
|
+
// claims nothing until you opt in. Tell the user that loudly so a now-quiet CI
|
|
298
|
+
// is not a surprise, and how to enable it.
|
|
299
|
+
log('');
|
|
300
|
+
log("CI autonomy is OFF by default (the engine's strict default).");
|
|
301
|
+
log(
|
|
302
|
+
'The emitted advance workflow sets NO DORFL_* gate env, so your\n' +
|
|
303
|
+
' committed .dorfl.json wins (precedence: flag > env > per-repo > global > default).',
|
|
304
|
+
);
|
|
305
|
+
log('To enable CI autonomy, EITHER:');
|
|
306
|
+
log(
|
|
307
|
+
' - set the gate(s) in `.dorfl.json` (applies everywhere), e.g.\n' +
|
|
308
|
+
' { "autoBuild": true, "autoTask": true }',
|
|
309
|
+
);
|
|
310
|
+
log(
|
|
311
|
+
" - OR add the env var(s) to the workflow's `env:` block yourself (CI-only override), e.g.\n" +
|
|
312
|
+
" DORFL_AUTO_BUILD: 'true'\n" +
|
|
313
|
+
" DORFL_AUTO_TASK: 'true'",
|
|
314
|
+
);
|
|
315
|
+
// Project-toolchain boundary (task install-ci-document-toolchain-boundary,
|
|
316
|
+
// PRD install-ci-project-provisioning axis (A)). dorfl declares
|
|
317
|
+
// engines.node '>=18' and the generated composite action pins Node 22 only
|
|
318
|
+
// for dorfl's own runtime — it does NOT provision the project's toolchain.
|
|
319
|
+
// State that boundary explicitly so a maintainer whose project pins a
|
|
320
|
+
// different Node/pnpm version (or uses rust / system packages) is never
|
|
321
|
+
// silently broken: the project-setup hook (sibling task
|
|
322
|
+
// install-ci-project-setup-hook) is the SUPPORTED escape hatch; without
|
|
323
|
+
// it the conflicting case is unsupported. install-ci does NOT sniff
|
|
324
|
+
// .nvmrc / packageManager / rust-toolchain.toml — the boundary is
|
|
325
|
+
// documentation, not detection.
|
|
326
|
+
log('');
|
|
327
|
+
log(
|
|
328
|
+
"Project toolchain: the generated composite action provisions ONLY dorfl's own runtime (Node 22 for engines.node '>=18').",
|
|
329
|
+
);
|
|
330
|
+
log(
|
|
331
|
+
'It does NOT provision your project toolchain (a project-pinned pnpm/Node, rust, system packages, `pnpm install` of your deps).',
|
|
332
|
+
);
|
|
333
|
+
log(
|
|
334
|
+
'A custom or conflicting project toolchain is supported ONLY via the project-setup hook (task install-ci-project-setup-hook);',
|
|
335
|
+
);
|
|
336
|
+
log(
|
|
337
|
+
'without that hook the conflicting case is unsupported. install-ci does NOT detect likely conflicts — this is a documented boundary.',
|
|
338
|
+
);
|
|
339
|
+
return {outcome: 'generated', config, written, secrets, branchProtection};
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Gather the secret values for `--include-secrets` (the export path): take known
|
|
344
|
+
* values from the loaded file, else prompt. Returns the deduped name→value map.
|
|
345
|
+
*/
|
|
346
|
+
async function gatherSecretsForExport(
|
|
347
|
+
file: CIConfigFile,
|
|
348
|
+
prompts: WizardPrompts | undefined,
|
|
349
|
+
): Promise<Record<string, string>> {
|
|
350
|
+
const config = resolveCIConfig(file);
|
|
351
|
+
const secrets: Record<string, string> = {...(file.secrets ?? {})};
|
|
352
|
+
if (!prompts) {
|
|
353
|
+
return secrets;
|
|
354
|
+
}
|
|
355
|
+
const {requiredSecretNames, optionalSecretNames} =
|
|
356
|
+
await import('./install-ci-core.js');
|
|
357
|
+
for (const name of requiredSecretNames(config)) {
|
|
358
|
+
if (secrets[name] !== undefined) continue;
|
|
359
|
+
const value = await prompts.password(`Enter the value for secret ${name}:`);
|
|
360
|
+
if (value) secrets[name] = value;
|
|
361
|
+
}
|
|
362
|
+
// The OPTIONAL PR-identity token: offered (blank ⇒ omitted, never an empty
|
|
363
|
+
// value), so an exported config can carry it without it ever being required.
|
|
364
|
+
for (const name of optionalSecretNames(config)) {
|
|
365
|
+
if (secrets[name] !== undefined) continue;
|
|
366
|
+
const value = await prompts.password(
|
|
367
|
+
`Optional: GitHub token for CI to open PRs under your identity ` +
|
|
368
|
+
`(secret ${name}; a PAT or App token). Leave blank to use GITHUB_TOKEN:`,
|
|
369
|
+
);
|
|
370
|
+
if (value) secrets[name] = value;
|
|
371
|
+
}
|
|
372
|
+
return secrets;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// ─── The interactive wizard ──────────────────────────────────────────────────
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* The interactive wizard: gather the auth mode, providers/models (models-json) or
|
|
379
|
+
* the default provider/model (auth-json), and the harness, into a
|
|
380
|
+
* {@link CIConfigFile}. Drives the {@link WizardPrompts} seam, so it runs
|
|
381
|
+
* deterministically in tests and the gathered shape exactly equals a config-file
|
|
382
|
+
* input — the equivalence the snapshot test pins. Mirrors whitesmith's prompt
|
|
383
|
+
* flow (provider type → key env var → models → defaults).
|
|
384
|
+
*/
|
|
385
|
+
export async function runWizard(prompts: WizardPrompts): Promise<CIConfigFile> {
|
|
386
|
+
const authMode = await prompts.select<AuthMode>('Auth mode:', [
|
|
387
|
+
{
|
|
388
|
+
name: 'models.json (default — one GitHub secret per provider key)',
|
|
389
|
+
value: 'models-json',
|
|
390
|
+
},
|
|
391
|
+
{
|
|
392
|
+
name: 'auth.json (single PI_AUTH_JSON + GH_PAT + OAuth refresh — the sharp edge)',
|
|
393
|
+
value: 'auth-json',
|
|
394
|
+
},
|
|
395
|
+
]);
|
|
396
|
+
|
|
397
|
+
const harness = await prompts.select<HarnessAdapter>('Agent harness:', [
|
|
398
|
+
{name: 'pi (the pi coding agent)', value: 'pi'},
|
|
399
|
+
{name: 'null (shell out to a configured agentCmd)', value: 'null'},
|
|
400
|
+
]);
|
|
401
|
+
|
|
402
|
+
if (authMode === 'auth-json') {
|
|
403
|
+
// auth.json mode: no per-provider keys, but the harness still needs a
|
|
404
|
+
// default provider/model for its invocations.
|
|
405
|
+
const defaultProvider = await prompts.input('Default AI provider:', {
|
|
406
|
+
default: 'anthropic',
|
|
407
|
+
});
|
|
408
|
+
const defaultModel = await prompts.input('Default AI model:', {
|
|
409
|
+
default: 'claude-sonnet-4-20250514',
|
|
410
|
+
});
|
|
411
|
+
return {
|
|
412
|
+
authMode,
|
|
413
|
+
providers: [],
|
|
414
|
+
defaultProvider,
|
|
415
|
+
defaultModel,
|
|
416
|
+
harness,
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
const providers = await promptProviders(prompts);
|
|
421
|
+
const {defaultProvider, defaultModel} = await promptDefaults(
|
|
422
|
+
prompts,
|
|
423
|
+
providers,
|
|
424
|
+
);
|
|
425
|
+
return {authMode, providers, defaultProvider, defaultModel, harness};
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/** Prompt for one or more providers (the models-json path). */
|
|
429
|
+
async function promptProviders(
|
|
430
|
+
prompts: WizardPrompts,
|
|
431
|
+
): Promise<ProviderEntry[]> {
|
|
432
|
+
const providers: ProviderEntry[] = [];
|
|
433
|
+
let addMore = true;
|
|
434
|
+
while (addMore) {
|
|
435
|
+
const type = await prompts.select(
|
|
436
|
+
providers.length === 0 ? 'Add a provider:' : 'Add another provider:',
|
|
437
|
+
[
|
|
438
|
+
{name: 'Anthropic (built-in, needs API key)', value: 'anthropic'},
|
|
439
|
+
{name: 'OpenAI (built-in, needs API key)', value: 'openai'},
|
|
440
|
+
{name: 'Custom provider', value: 'custom'},
|
|
441
|
+
],
|
|
442
|
+
);
|
|
443
|
+
providers.push(
|
|
444
|
+
type === 'custom'
|
|
445
|
+
? await promptCustomProvider(prompts)
|
|
446
|
+
: await promptBuiltinProvider(prompts, type as 'anthropic' | 'openai'),
|
|
447
|
+
);
|
|
448
|
+
addMore = await prompts.confirm('Add another provider?', {default: false});
|
|
449
|
+
}
|
|
450
|
+
return providers;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/** Prompt for a built-in provider (`anthropic` / `openai`). */
|
|
454
|
+
async function promptBuiltinProvider(
|
|
455
|
+
prompts: WizardPrompts,
|
|
456
|
+
type: 'anthropic' | 'openai',
|
|
457
|
+
): Promise<ProviderEntry> {
|
|
458
|
+
const defaultEnvVar =
|
|
459
|
+
type === 'anthropic' ? 'ANTHROPIC_API_KEY' : 'OPENAI_API_KEY';
|
|
460
|
+
const defaultModel =
|
|
461
|
+
type === 'anthropic' ? 'claude-sonnet-4-20250514' : 'gpt-4o';
|
|
462
|
+
const apiKeyEnvVar = await prompts.input(
|
|
463
|
+
'GitHub secret name for the API key:',
|
|
464
|
+
{
|
|
465
|
+
default: defaultEnvVar,
|
|
466
|
+
},
|
|
467
|
+
);
|
|
468
|
+
const baseUrl = await prompts.input('Custom base URL (blank for default):');
|
|
469
|
+
const models = await promptModels(prompts, defaultModel);
|
|
470
|
+
return {
|
|
471
|
+
name: type,
|
|
472
|
+
baseUrl: baseUrl || undefined,
|
|
473
|
+
apiKeyEnvVar,
|
|
474
|
+
models,
|
|
475
|
+
builtin: true,
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/** Prompt for a custom provider. */
|
|
480
|
+
async function promptCustomProvider(
|
|
481
|
+
prompts: WizardPrompts,
|
|
482
|
+
): Promise<ProviderEntry> {
|
|
483
|
+
const name = await prompts.input('Provider name:');
|
|
484
|
+
const baseUrl = await prompts.input('Base URL:');
|
|
485
|
+
const api = await prompts.select('API type:', [
|
|
486
|
+
{name: 'Anthropic Messages API', value: 'anthropic-messages'},
|
|
487
|
+
{name: 'OpenAI Completions API', value: 'openai-completions'},
|
|
488
|
+
]);
|
|
489
|
+
const apiKeyEnvVar = await prompts.input(
|
|
490
|
+
'GitHub secret name for the API key:',
|
|
491
|
+
);
|
|
492
|
+
let compat: Record<string, boolean> | undefined;
|
|
493
|
+
if (api === 'openai-completions') {
|
|
494
|
+
const supportsDeveloperRole = await prompts.confirm(
|
|
495
|
+
'Does this provider support the developer role?',
|
|
496
|
+
{default: true},
|
|
497
|
+
);
|
|
498
|
+
const supportsReasoningEffort = await prompts.confirm(
|
|
499
|
+
'Does this provider support reasoning effort?',
|
|
500
|
+
{default: true},
|
|
501
|
+
);
|
|
502
|
+
if (!supportsDeveloperRole || !supportsReasoningEffort) {
|
|
503
|
+
compat = {supportsDeveloperRole, supportsReasoningEffort};
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
const models = await promptModels(prompts);
|
|
507
|
+
return {name, baseUrl, api, apiKeyEnvVar, models, builtin: false, compat};
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/** Prompt for one or more model ids. */
|
|
511
|
+
async function promptModels(
|
|
512
|
+
prompts: WizardPrompts,
|
|
513
|
+
firstDefault?: string,
|
|
514
|
+
): Promise<{id: string}[]> {
|
|
515
|
+
const models: {id: string}[] = [];
|
|
516
|
+
let addModel = true;
|
|
517
|
+
while (addModel) {
|
|
518
|
+
const id = await prompts.input(
|
|
519
|
+
models.length === 0 ? 'Model ID:' : 'Another model ID:',
|
|
520
|
+
models.length === 0 && firstDefault ? {default: firstDefault} : undefined,
|
|
521
|
+
);
|
|
522
|
+
models.push({id});
|
|
523
|
+
addModel = await prompts.confirm('Add another model?', {default: false});
|
|
524
|
+
}
|
|
525
|
+
return models;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/** Prompt for the default provider + model (skips the prompt when only one). */
|
|
529
|
+
async function promptDefaults(
|
|
530
|
+
prompts: WizardPrompts,
|
|
531
|
+
providers: ProviderEntry[],
|
|
532
|
+
): Promise<{defaultProvider: string; defaultModel: string}> {
|
|
533
|
+
const defaultProvider =
|
|
534
|
+
providers.length === 1
|
|
535
|
+
? providers[0].name
|
|
536
|
+
: await prompts.select(
|
|
537
|
+
'Default provider:',
|
|
538
|
+
providers.map((p) => ({name: p.name, value: p.name})),
|
|
539
|
+
);
|
|
540
|
+
const selected = providers.find((p) => p.name === defaultProvider)!;
|
|
541
|
+
const defaultModel =
|
|
542
|
+
selected.models.length === 1
|
|
543
|
+
? selected.models[0].id
|
|
544
|
+
: await prompts.select(
|
|
545
|
+
'Default model:',
|
|
546
|
+
selected.models.map((m) => ({name: m.id, value: m.id})),
|
|
547
|
+
);
|
|
548
|
+
return {defaultProvider, defaultModel};
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/** Re-export the default harness for callers building a config programmatically. */
|
|
552
|
+
export {DEFAULT_HARNESS};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **`intake`'s PURE event-classification** (task `intake-event-classification`, prd
|
|
3
|
+
* `issue-intake` US #2 — the resume-on-thread-change behaviour).
|
|
4
|
+
*
|
|
5
|
+
* `intake` is a CONVERSATION on an issue thread: a run may ASK a clarifying question
|
|
6
|
+
* and STOP, expecting a LATER run to resume from the updated thread (prd "Loop
|
|
7
|
+
* closure" / the decision table's ASK row). This module is the PURE CONTROL-PATH
|
|
8
|
+
* classifier the re-run depends on: given an issue EVENT, it decides whether `intake`
|
|
9
|
+
* should RE-EVALUATE the whole thread or IGNORE the event.
|
|
10
|
+
*
|
|
11
|
+
* THE CANONICAL RULE (from prd `issue-intake`, "The engine shape"): *"The loop
|
|
12
|
+
* re-runs on a new comment OR an issue-body edit (re-evaluate the whole thread); a
|
|
13
|
+
* buried prior-comment edit is IGNORED."*
|
|
14
|
+
*
|
|
15
|
+
* - a **new comment** → RE-EVALUATE (a genuine new turn on the thread);
|
|
16
|
+
* - an **issue-body edit** → RE-EVALUATE (the spec the prompt reads changed; re-read
|
|
17
|
+
* body + full thread);
|
|
18
|
+
* - editing a **buried PRIOR comment** → IGNORE (it is NOT a new turn —
|
|
19
|
+
* re-triggering on old-comment edits invites loops).
|
|
20
|
+
*
|
|
21
|
+
* Edit-vs-reply changes only the comment's FRAMING, not the control path: a NEW
|
|
22
|
+
* comment re-evaluates whether it is phrased as an edit-of-the-ask or a reply. The
|
|
23
|
+
* distinction the rule turns on is "a NEW turn vs an edit of a BURIED prior turn",
|
|
24
|
+
* NOT "edit vs reply".
|
|
25
|
+
*
|
|
26
|
+
* SCOPE FENCE (prd "Scope: the engine only"): this is ONLY the pure classifier. It is
|
|
27
|
+
* NOT CI's TRIGGER POLICY (command/every-issue, maintainer/anyone) — that is
|
|
28
|
+
* `runner-in-ci`'s. CI's trigger LATER CONSULTS this classifier, but the policy of
|
|
29
|
+
* WHO/WHAT may trigger lives in CI, not here. This module touches no seam, no git, no
|
|
30
|
+
* `gh` — it is pure logic over a stubbed event shape (the same discipline
|
|
31
|
+
* `failure-cause.ts` keeps).
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The KIND of issue event the classifier decides over. The shapes are STUBBED in
|
|
36
|
+
* tests (no webhook, no `gh`); a real CI trigger maps its provider event onto one of
|
|
37
|
+
* these kinds before consulting {@link classifyIntakeEvent}.
|
|
38
|
+
*
|
|
39
|
+
* - `issue-comment-created` — a NEW comment was added to the thread (a new turn).
|
|
40
|
+
* - `issue-body-edited` — the ISSUE BODY itself was edited (the spec changed).
|
|
41
|
+
* - `issue-comment-edited` — an EXISTING comment was edited (see {@link IntakeEvent}
|
|
42
|
+
* for the buried-vs-latest distinction the rule turns on).
|
|
43
|
+
*/
|
|
44
|
+
export type IntakeEventKind =
|
|
45
|
+
| 'issue-comment-created'
|
|
46
|
+
| 'issue-body-edited'
|
|
47
|
+
| 'issue-comment-edited';
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The CONTROL-PATH decision the classifier returns:
|
|
51
|
+
*
|
|
52
|
+
* - `re-evaluate` — `intake` should RE-READ the issue body + full thread and re-run
|
|
53
|
+
* its decision (a new comment or a body edit changed the material the prompt
|
|
54
|
+
* judges).
|
|
55
|
+
* - `ignore` — the event is NOT a new turn; `intake` does nothing (re-triggering on a
|
|
56
|
+
* buried old-comment edit would invite loops).
|
|
57
|
+
*/
|
|
58
|
+
export type IntakeEventDecision = 're-evaluate' | 'ignore';
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* A STUBBED issue event the classifier decides over. Deliberately MINIMAL — it
|
|
62
|
+
* carries only what the CONTROL-PATH rule turns on, nothing else (no author, no CI
|
|
63
|
+
* trigger policy — that is `runner-in-ci`'s).
|
|
64
|
+
*/
|
|
65
|
+
export interface IntakeEvent {
|
|
66
|
+
/** Which kind of thread change occurred. */
|
|
67
|
+
kind: IntakeEventKind;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Classify an issue EVENT into the CONTROL-PATH decision: RE-EVALUATE the whole
|
|
72
|
+
* thread, or IGNORE the event. The PURE realisation of the prd's canonical rule
|
|
73
|
+
* (no seam, no git, no `gh`).
|
|
74
|
+
*
|
|
75
|
+
* The table (prd `issue-intake` US #2):
|
|
76
|
+
*
|
|
77
|
+
* | event kind | decision | why |
|
|
78
|
+
* | ----------------------- | ------------- | -------------------------------------------- |
|
|
79
|
+
* | `issue-comment-created` | `re-evaluate` | a new comment is a new turn on the thread |
|
|
80
|
+
* | `issue-body-edited` | `re-evaluate` | the issue body (the spec) changed |
|
|
81
|
+
* | `issue-comment-edited` | `ignore` | editing a buried prior comment is NOT a turn |
|
|
82
|
+
*
|
|
83
|
+
* `issue-comment-edited` is IGNORED unconditionally: editing a prior comment is not a
|
|
84
|
+
* new turn (and re-triggering on old-comment edits invites loops). The "buried" in
|
|
85
|
+
* the rule is descriptive — the rule does not single out which prior comment was
|
|
86
|
+
* edited; ANY comment edit is an edit of an already-seen turn, not a new one. (Adding
|
|
87
|
+
* NEW content is `issue-comment-created`, which DOES re-evaluate.)
|
|
88
|
+
*
|
|
89
|
+
* Edit-vs-reply does NOT change this: a new comment is `issue-comment-created`
|
|
90
|
+
* REGARDLESS of whether it is phrased as an edit-of-the-ask or a reply — both
|
|
91
|
+
* re-evaluate, because editing-vs-replying changes only the comment's FRAMING, not
|
|
92
|
+
* whether it is a new turn.
|
|
93
|
+
*/
|
|
94
|
+
export function classifyIntakeEvent(event: IntakeEvent): IntakeEventDecision {
|
|
95
|
+
switch (event.kind) {
|
|
96
|
+
case 'issue-comment-created':
|
|
97
|
+
case 'issue-body-edited':
|
|
98
|
+
return 're-evaluate';
|
|
99
|
+
case 'issue-comment-edited':
|
|
100
|
+
return 'ignore';
|
|
101
|
+
}
|
|
102
|
+
}
|