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/github.js
ADDED
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { run } from './git.js';
|
|
2
|
+
import { ghFailureDetail } from './gh-failure.js';
|
|
3
|
+
import { realSleep, retryWithBackoff } from './retry-backoff.js';
|
|
4
|
+
import { NoneProvider, manualRequestText, } from './integrator.js';
|
|
5
|
+
/** The default `gh` CLI binary name (resolved on `PATH`). */
|
|
6
|
+
export const DEFAULT_GH_BIN = 'gh';
|
|
7
|
+
/**
|
|
8
|
+
* True iff `url` is a GitHub arbiter remote, recognised across the URL shapes
|
|
9
|
+
* the arbiter can take (scp-like ssh `git@github.com:o/r.git`, `ssh://`,
|
|
10
|
+
* `https://`/`http://`). We match on the HOST being exactly `github.com` (or a
|
|
11
|
+
* `github.com` subdomain — GitHub Enterprise installs are out of scope and read
|
|
12
|
+
* as not-GitHub, the safe `none` default). A mere substring match is rejected so
|
|
13
|
+
* a lookalike host (`notgithub.com.evil`) never selects the GitHub provider.
|
|
14
|
+
*/
|
|
15
|
+
export function isGitHubArbiterUrl(url) {
|
|
16
|
+
const host = arbiterHost(url);
|
|
17
|
+
if (host === undefined) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
return host === 'github.com' || host.endsWith('.github.com');
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Extract the bare host from an arbiter remote URL, or `undefined` for a local
|
|
24
|
+
* filesystem path (`file://...` / `/abs/path`) which has no host. Mirrors the
|
|
25
|
+
* `repo-mirror` URL handling (the four shapes the arbiter can take) but only
|
|
26
|
+
* needs the host for provider detection.
|
|
27
|
+
*/
|
|
28
|
+
function arbiterHost(url) {
|
|
29
|
+
const trimmed = url.trim();
|
|
30
|
+
if (!trimmed.includes('://')) {
|
|
31
|
+
// scp-like ssh: [user@]host:path (no `://`, a `:` before the path, NOT a
|
|
32
|
+
// plain absolute local path).
|
|
33
|
+
const scp = /^(?:[^@/]+@)?([^/:]+):(.+)$/;
|
|
34
|
+
const m = scp.exec(trimmed);
|
|
35
|
+
if (m && !trimmed.startsWith('/')) {
|
|
36
|
+
return m[1].toLowerCase();
|
|
37
|
+
}
|
|
38
|
+
return undefined; // a plain local path has no host
|
|
39
|
+
}
|
|
40
|
+
const rest = trimmed.slice(trimmed.indexOf('://') + 3);
|
|
41
|
+
const slash = rest.indexOf('/');
|
|
42
|
+
const authority = slash === -1 ? rest : rest.slice(0, slash);
|
|
43
|
+
const host = stripUserAndPort(authority).toLowerCase();
|
|
44
|
+
// `file://` yields an empty authority (file:///abs/path) → no host.
|
|
45
|
+
return host === '' ? undefined : host;
|
|
46
|
+
}
|
|
47
|
+
/** Drop `user@` and `:port` from an authority, leaving the bare host. */
|
|
48
|
+
function stripUserAndPort(authority) {
|
|
49
|
+
const afterUser = authority.includes('@')
|
|
50
|
+
? authority.slice(authority.lastIndexOf('@') + 1)
|
|
51
|
+
: authority;
|
|
52
|
+
const colon = afterUser.indexOf(':');
|
|
53
|
+
return colon === -1 ? afterUser : afterUser.slice(0, colon);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Resolve the review-request provider for an integration (ADR §6), PURELY from
|
|
57
|
+
* the arbiter URL — there is NO override axis:
|
|
58
|
+
*
|
|
59
|
+
* - a `github.com` arbiter URL ⇒ the GitHub provider, else
|
|
60
|
+
* - the `none` provider (the safe default for unknown / local `--bare`
|
|
61
|
+
* arbiters, which have no review concept).
|
|
62
|
+
*
|
|
63
|
+
* The GitHub provider degrades to `none` behaviour at RUNTIME when `gh` is
|
|
64
|
+
* absent/unauthenticated (so it is safe to select it on URL alone — the work is
|
|
65
|
+
* already pushed by the seam, ADR §6); this keeps SELECTION a pure, testable
|
|
66
|
+
* function of the arbiter URL. The orthogonal "do not open a PR" INTENT is the
|
|
67
|
+
* `noPR` config axis (handled by the caller, layered on top — it does NOT pick a
|
|
68
|
+
* provider here), and whether `gh` is authed to actually open the PR is the
|
|
69
|
+
* identity's `providers.github` / ambient `gh` auth.
|
|
70
|
+
*/
|
|
71
|
+
export function selectProvider(options) {
|
|
72
|
+
if (options.arbiterUrl && isGitHubArbiterUrl(options.arbiterUrl)) {
|
|
73
|
+
return new GitHubProvider({ ghBin: options.ghBin });
|
|
74
|
+
}
|
|
75
|
+
return new NoneProvider();
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* The GitHub provider: opens a PR for an already-pushed `work/<slug>` branch via
|
|
79
|
+
* `gh pr create`. It NEVER hard-fails — a missing/unauthenticated `gh` degrades
|
|
80
|
+
* to the `none` behaviour (the branch is already pushed; print manual-PR
|
|
81
|
+
* instructions) — and NEVER `--force`s anything. The created PR URL is parsed
|
|
82
|
+
* from `gh`'s stdout and returned so the caller can record it.
|
|
83
|
+
*/
|
|
84
|
+
export class GitHubProvider {
|
|
85
|
+
name = 'github';
|
|
86
|
+
ghBin;
|
|
87
|
+
base;
|
|
88
|
+
constructor(options = {}) {
|
|
89
|
+
this.ghBin = options.ghBin ?? DEFAULT_GH_BIN;
|
|
90
|
+
this.base = options.base ?? 'main';
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Open a PR for `input.branch` via `gh pr create --base main --head <branch>`,
|
|
94
|
+
* passing an explicit `--title`/`--body` when the caller supplied them (the
|
|
95
|
+
* synthesised single-line title + the agent's summary body) and falling back to
|
|
96
|
+
* `--fill` ONLY when BOTH are absent (today's behaviour — no regression). A
|
|
97
|
+
* partial set (one present) still drops `--fill`: `--fill` and an explicit
|
|
98
|
+
* `--title`/`--body` are mutually exclusive to `gh`, so once we override either
|
|
99
|
+
* field we must supply both explicitly (the other defaults to the slug-derived
|
|
100
|
+
* title / an empty body rather than re-deriving a run-on subject). The branch
|
|
101
|
+
* is GUARANTEED to be on the arbiter already (the push is the seam's safety-
|
|
102
|
+
* bearing step), so any `gh` failure is non-fatal: we fall back to the same
|
|
103
|
+
* manual-instructions result the `none` provider returns. On success we parse
|
|
104
|
+
* the PR URL `gh` prints and surface it (recorded by the caller into the job
|
|
105
|
+
* record / `status`).
|
|
106
|
+
*/
|
|
107
|
+
async openRequest(input) {
|
|
108
|
+
const args = [
|
|
109
|
+
'pr',
|
|
110
|
+
'create',
|
|
111
|
+
'--base',
|
|
112
|
+
this.base,
|
|
113
|
+
'--head',
|
|
114
|
+
input.branch,
|
|
115
|
+
...prCreateContentArgs(input),
|
|
116
|
+
];
|
|
117
|
+
// First attempt. A non-zero / missing `gh` can mean two VERY different things:
|
|
118
|
+
// - DETERMINISTIC: `gh` is missing or unauthenticated — retrying is pointless
|
|
119
|
+
// (every attempt fails identically); degrade IMMEDIATELY (today's
|
|
120
|
+
// behaviour, no wasted backoff).
|
|
121
|
+
// - TRANSIENT (OUTAGE): `gh` is present + authed but the network/API is down
|
|
122
|
+
// — RETRY with bounded backoff (the same shared helper the push uses)
|
|
123
|
+
// before degrading. This is a LOW-severity mode: the branch is already
|
|
124
|
+
// pushed (the seam's safety step), so the work is safe — only the review
|
|
125
|
+
// surface is missing. We do NOT gate requeue on it.
|
|
126
|
+
const first = this.runGh(args, input.cwd, input.env);
|
|
127
|
+
if (first !== undefined && first.status === 0) {
|
|
128
|
+
return this.parseOpened(input, first);
|
|
129
|
+
}
|
|
130
|
+
// Failed once — distinguish DETERMINISTIC (missing/unauth) from a TRANSIENT
|
|
131
|
+
// outage by an availability probe. Missing/unauth ⇒ degrade now (no retry).
|
|
132
|
+
// Thread the FAILED first attempt so the degrade surfaces the REAL `gh` cause
|
|
133
|
+
// (its stderr / the missing-binary detail), not a hard-coded auth guess.
|
|
134
|
+
//
|
|
135
|
+
// NOTE (degrade NARROWED): for a propose-with-PR-intent run (`noPR` unset) the
|
|
136
|
+
// start-of-run "`gh` unavailable/unauthed" case is now caught UP FRONT by the
|
|
137
|
+
// pre-flight `gh` auth probe (see `do.ts`'s pre-flight guard / `selectProvider`
|
|
138
|
+
// docs), so it never reaches this point as a silent degrade. The legitimate
|
|
139
|
+
// callers that still land here are: `noPR: true` (intended push-only — the
|
|
140
|
+
// caller does not even pass a GitHub provider, so this is moot), and a `gh`
|
|
141
|
+
// that went away AFTER a passing up-front probe (a transient mid-run loss).
|
|
142
|
+
if (!this.available(input.cwd, input.env)) {
|
|
143
|
+
return this.degrade(input, 'unavailable', first);
|
|
144
|
+
}
|
|
145
|
+
// `gh` IS available but the create failed — a transient outage. Retry the
|
|
146
|
+
// create with bounded backoff before a clean give-up into the OUTAGE degrade.
|
|
147
|
+
const attempt = await retryWithBackoff(async () => {
|
|
148
|
+
const r = this.runGh(args, input.cwd, input.env);
|
|
149
|
+
if (r !== undefined && r.status === 0) {
|
|
150
|
+
return { ok: true, value: r };
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
ok: false,
|
|
154
|
+
error: r?.stderr.trim() || 'gh pr create failed',
|
|
155
|
+
};
|
|
156
|
+
}, { sleep: input.sleep ?? realSleep, ...input.backoff });
|
|
157
|
+
if (!attempt.ok) {
|
|
158
|
+
return this.degrade(input, 'outage');
|
|
159
|
+
}
|
|
160
|
+
return this.parseOpened(input, attempt.value);
|
|
161
|
+
}
|
|
162
|
+
/** Map a successful `gh pr create` RunResult to an OpenRequestResult. */
|
|
163
|
+
parseOpened(input, result) {
|
|
164
|
+
const url = parsePrUrl(result.stdout);
|
|
165
|
+
if (url === undefined) {
|
|
166
|
+
// gh succeeded but we could not parse a URL — still treat the PR as
|
|
167
|
+
// opened (gh exited 0) but fall back to a generic confirmation.
|
|
168
|
+
return {
|
|
169
|
+
opened: true,
|
|
170
|
+
instruction: `Opened a GitHub PR for ${input.branch}.`,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
opened: true,
|
|
175
|
+
url,
|
|
176
|
+
instruction: `Opened a GitHub PR for ${input.branch}: ${url}`,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Post a follow-up COMMENT on an already-opened PR via
|
|
181
|
+
* `gh pr comment <url> --body <text>` (task `review-gate-pr-comment`),
|
|
182
|
+
* threading the PR by the `url` {@link openRequest} returned. The PR already
|
|
183
|
+
* exists (this runs AFTER the propose integrate), so any `gh` failure is
|
|
184
|
+
* non-fatal: a missing/unauthenticated `gh` DEGRADES to the same surface-the-
|
|
185
|
+
* text result the `none` provider returns — NEVER throws (ADR §6). The comment
|
|
186
|
+
* is ADVISORY: it changes no gate/verdict/merge logic. NEVER `--force`s.
|
|
187
|
+
*/
|
|
188
|
+
postPRComment(input) {
|
|
189
|
+
const result = this.runGh(['pr', 'comment', input.url, '--body', input.body], input.cwd, input.env);
|
|
190
|
+
// gh missing (spawn failed) OR non-zero exit (e.g. unauthenticated): the PR
|
|
191
|
+
// already exists and the review is in the run output, so degrade gracefully
|
|
192
|
+
// — NEVER throw (the comment is advisory; a failure must not lose work).
|
|
193
|
+
if (result === undefined || result.status !== 0) {
|
|
194
|
+
// Surface the REAL `gh` cause (its stderr, with the missing-binary special
|
|
195
|
+
// case) — NOT a hard-coded "unavailable or unauthenticated" guess that sends
|
|
196
|
+
// the operator chasing a phantom auth problem (mirrors `issue-provider.ts`).
|
|
197
|
+
const reason = ghFailureDetail(result);
|
|
198
|
+
return {
|
|
199
|
+
posted: false,
|
|
200
|
+
instruction: `${reason} The review was not posted as a comment on ` +
|
|
201
|
+
`${input.url}. The review:\n${input.body}`,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
posted: true,
|
|
206
|
+
instruction: `Posted the review as a comment on ${input.url}.`,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Post the review comment by RESOLVING the PR from the pushed `work/<slug>`
|
|
211
|
+
* BRANCH (task `review-comment-fallback-on-unparsed-pr-url`), the FALLBACK for
|
|
212
|
+
* when `gh pr create` opened a PR (exit 0) but its stdout url was unparseable so
|
|
213
|
+
* {@link openRequest} returned `{opened: true}` with NO `url`. We first RESOLVE
|
|
214
|
+
* the open PR's url from the branch (`gh pr view <branch> --json url --jq .url`):
|
|
215
|
+
*
|
|
216
|
+
* - a url comes back ⇒ a PR genuinely exists — post the comment on it via the
|
|
217
|
+
* url-keyed {@link postPRComment} (the audit trail is preserved);
|
|
218
|
+
* - nothing resolvable (no PR for the branch, or `gh` missing/unauthenticated)
|
|
219
|
+
* ⇒ an HONEST clean no-op (`posted: false`) — but only AFTER trying. The
|
|
220
|
+
* "no PR ⇒ no comment" rule holds; what changes is we no longer drop the
|
|
221
|
+
* comment when a PR DID open.
|
|
222
|
+
*
|
|
223
|
+
* Resolving the url first (rather than commenting on the branch directly) keeps
|
|
224
|
+
* the no-PR case a deterministic no-op and reuses the exact same comment
|
|
225
|
+
* mechanics as the url path. NEVER throws, NEVER `--force`s (ADR §6).
|
|
226
|
+
*/
|
|
227
|
+
postPRCommentOnBranch(input) {
|
|
228
|
+
const url = this.resolvePrUrlForBranch(input.branch, input.cwd, input.env);
|
|
229
|
+
if (url === undefined) {
|
|
230
|
+
// No PR resolvable from the branch (truly none, or `gh` unavailable): an
|
|
231
|
+
// honest no-op — but only after trying. Surface the review text so it is
|
|
232
|
+
// never lost; nothing was posted.
|
|
233
|
+
return {
|
|
234
|
+
posted: false,
|
|
235
|
+
instruction: `No open PR could be resolved for ${input.branch}, so the review ` +
|
|
236
|
+
`was not posted as a comment. The review:\n${input.body}`,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
// A PR genuinely exists for the branch — comment on it via the url path.
|
|
240
|
+
return this.postPRComment({
|
|
241
|
+
cwd: input.cwd,
|
|
242
|
+
url,
|
|
243
|
+
body: input.body,
|
|
244
|
+
env: input.env,
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Resolve the open PR's url for `branch` via `gh pr view <branch> --json url
|
|
249
|
+
* --jq .url`, or `undefined` when no PR is found / `gh` is missing or
|
|
250
|
+
* unauthenticated (a non-zero exit or a spawn failure). Read-only; mutates
|
|
251
|
+
* nothing. The result is parsed for a PR url (any surrounding chatter ignored)
|
|
252
|
+
* so a stray warning line never defeats the resolution.
|
|
253
|
+
*/
|
|
254
|
+
resolvePrUrlForBranch(branch, cwd, env) {
|
|
255
|
+
const result = this.runGh(['pr', 'view', branch, '--json', 'url', '--jq', '.url'], cwd, env);
|
|
256
|
+
if (result === undefined || result.status !== 0) {
|
|
257
|
+
return undefined; // no PR for the branch, or gh missing/unauthenticated
|
|
258
|
+
}
|
|
259
|
+
return parsePrUrl(result.stdout);
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Is `gh` available AND authenticated (so a PR can actually be opened)?
|
|
263
|
+
* `gh auth status` exits 0 when authenticated. A missing `gh` (spawn failure)
|
|
264
|
+
* or a non-zero exit both read as unavailable. Read-only; mutates nothing.
|
|
265
|
+
*/
|
|
266
|
+
available(cwd, env) {
|
|
267
|
+
const result = this.runGh(['auth', 'status'], cwd, env);
|
|
268
|
+
return result !== undefined && result.status === 0;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Run `gh <args>` in `cwd`, returning the result, or `undefined` when `gh`
|
|
272
|
+
* cannot even be spawned (binary missing). `run` throws on a spawn error; we
|
|
273
|
+
* catch it here so a missing `gh` degrades rather than crashing the runner.
|
|
274
|
+
*/
|
|
275
|
+
runGh(args, cwd, env) {
|
|
276
|
+
try {
|
|
277
|
+
return run(this.ghBin, args, cwd, { env });
|
|
278
|
+
}
|
|
279
|
+
catch {
|
|
280
|
+
return undefined; // gh binary not found / not executable
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* The graceful-degradation result (identical SHAPE to the `none` provider's):
|
|
285
|
+
* the branch is already pushed (safe), only the PR is missing. The `reason`
|
|
286
|
+
* distinguishes the two LOW-severity degrade causes so the operator knows what
|
|
287
|
+
* to do: `unavailable` (`gh` missing/unauth — fix `gh`/auth) vs `outage`
|
|
288
|
+
* (transient network/API failure that survived the bounded retry — just re-run
|
|
289
|
+
* / open it manually). Both print the SAME manual `gh pr create` suggestion.
|
|
290
|
+
*/
|
|
291
|
+
degrade(input, reason,
|
|
292
|
+
/**
|
|
293
|
+
* The FAILED `gh pr create` result that triggered the `unavailable` degrade
|
|
294
|
+
* (`undefined` = `gh` binary missing). Threaded in so the `unavailable` arm
|
|
295
|
+
* surfaces the REAL cause rather than a hard-coded auth guess. The `outage`
|
|
296
|
+
* arm does not need it (its wording is already honest about the retried
|
|
297
|
+
* transient failure).
|
|
298
|
+
*/
|
|
299
|
+
result) {
|
|
300
|
+
// Echo the explicit title/body in the suggested manual command when present,
|
|
301
|
+
// so a human opening the PR by hand reuses the same content the autonomous
|
|
302
|
+
// path would have set (else fall back to the bare `--fill` suggestion).
|
|
303
|
+
const contentArgs = prCreateContentArgs(input);
|
|
304
|
+
const suggestion = `gh pr create --base ${this.base} --head ${input.branch} ${contentArgs.join(' ')}`.trim();
|
|
305
|
+
const cause = reason === 'outage'
|
|
306
|
+
? '`gh pr create` failed after retries (a transient outage), so no PR ' +
|
|
307
|
+
'was opened — the branch is pushed and the work is SAFE; re-run or ' +
|
|
308
|
+
'open one manually, e.g. '
|
|
309
|
+
: // Surface the REAL `gh` cause (its stderr, with the missing-binary
|
|
310
|
+
// special case) — NOT a hard-coded "unavailable or unauthenticated"
|
|
311
|
+
// guess (mirrors `issue-provider.ts`).
|
|
312
|
+
`${ghFailureDetail(result)} No PR was opened — open one manually, e.g. `;
|
|
313
|
+
return {
|
|
314
|
+
opened: false,
|
|
315
|
+
instruction: `Pushed ${input.branch} to ${input.arbiter}. ${cause}` +
|
|
316
|
+
`\`${suggestion}\`.` +
|
|
317
|
+
manualRequestText(input),
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* The CONTENT args for `gh pr create`: an explicit `--title`/`--body` when the
|
|
323
|
+
* caller supplied either (a partial set is completed so `--fill` is never mixed
|
|
324
|
+
* with an explicit field — `gh` forbids that), else the lone `--fill` (today's
|
|
325
|
+
* behaviour, no regression). Returned as a flat arg array so both the live
|
|
326
|
+
* invocation and the degraded suggestion build from one source of truth.
|
|
327
|
+
*/
|
|
328
|
+
export function prCreateContentArgs(input) {
|
|
329
|
+
if (input.title === undefined && input.body === undefined) {
|
|
330
|
+
return ['--fill'];
|
|
331
|
+
}
|
|
332
|
+
return ['--title', input.title ?? '', '--body', input.body ?? ''];
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Parse the PR URL `gh pr create` prints to stdout. `gh` prints the PR URL as a
|
|
336
|
+
* line (often the only/last line); we pick the first GitHub PR URL we find. Any
|
|
337
|
+
* surrounding chatter is ignored. Returns `undefined` when no URL is present.
|
|
338
|
+
*/
|
|
339
|
+
function parsePrUrl(stdout) {
|
|
340
|
+
const match = stdout.match(/https?:\/\/\S+\/pull\/\d+/);
|
|
341
|
+
return match ? match[0] : undefined;
|
|
342
|
+
}
|
|
343
|
+
//# sourceMappingURL=github.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The **harness seam** (ADR §5): how a job's command is launched and how its
|
|
3
|
+
* liveness is observed is pluggable behind an adapter; the core never hard-codes
|
|
4
|
+
* a specific tool.
|
|
5
|
+
*
|
|
6
|
+
* Crucially, **liveness is reported by the harness, NOT inferred from filesystem
|
|
7
|
+
* mtime**: a live agent can think for minutes without writing any files, so
|
|
8
|
+
* mtime would mistake a thinking agent for a dead one. Adapters answer liveness
|
|
9
|
+
* from the real signal (the PID, a session handle, …) — never mtime.
|
|
10
|
+
*
|
|
11
|
+
* This task ships the **null adapter** (records a PID, runs a configured
|
|
12
|
+
* command) so the substrate is testable standalone. The first real target (the
|
|
13
|
+
* `pi` adapter: liveness via PID + a pointer to the pi session dir/log,
|
|
14
|
+
* invocation via the pi CLI) is its own task.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* The persisted harness block in a job's `.dorfl-job.json` record. It
|
|
18
|
+
* captures which adapter launched the job + the liveness pointer the adapter
|
|
19
|
+
* needs to answer `isAlive` later (so `gc`/`status` can re-derive liveness from
|
|
20
|
+
* a fresh process without re-launching). Adapter-specific fields are optional.
|
|
21
|
+
*/
|
|
22
|
+
export interface HarnessRecord {
|
|
23
|
+
/** Which harness adapter owns this job (`null`, later `pi`, …). */
|
|
24
|
+
adapter: string;
|
|
25
|
+
/** OS process id of the launched command (the liveness anchor). */
|
|
26
|
+
pid?: number;
|
|
27
|
+
/** The command the adapter ran (for audit / re-launch). */
|
|
28
|
+
command?: string;
|
|
29
|
+
/** Adapter-specific session pointer (e.g. the pi session dir/log path). */
|
|
30
|
+
session?: string;
|
|
31
|
+
}
|
|
32
|
+
/** What a harness needs to launch one job's command. */
|
|
33
|
+
export interface LaunchInput {
|
|
34
|
+
/** The job's working directory (the worktree) — the command runs here. */
|
|
35
|
+
dir: string;
|
|
36
|
+
/** The slug being processed (for adapters that name/log per slug). */
|
|
37
|
+
slug: string;
|
|
38
|
+
/** The command to run (e.g. the configured `agentCmd`). */
|
|
39
|
+
command: string;
|
|
40
|
+
/** Optional prompt fed on the command's stdin. */
|
|
41
|
+
prompt?: string;
|
|
42
|
+
/**
|
|
43
|
+
* The model the agent should run on (the harness-agnostic routing intent, ADR
|
|
44
|
+
* §13). `undefined` ⇒ dorfl forces no model. The ADAPTER decides HOW
|
|
45
|
+
* this reaches its tool: the pi adapter passes `--model <model>` natively; the
|
|
46
|
+
* null/shell adapter substitutes a `{model}` placeholder in `command` (see
|
|
47
|
+
* {@link substituteModel}). auth/keys are NEVER carried here — they stay the
|
|
48
|
+
* harness's job.
|
|
49
|
+
*/
|
|
50
|
+
model?: string;
|
|
51
|
+
/**
|
|
52
|
+
* The full pi session-FILE path the adapter passes as `--session <path>` (the
|
|
53
|
+
* caller generates it ONCE — before launch, so the `do --watch` tailer can tail
|
|
54
|
+
* the KNOWN path — via {@link generateSessionPath} from the resolved
|
|
55
|
+
* `sessionsDir` + cwd). Adapter-agnostic: the pi adapter uses it verbatim and
|
|
56
|
+
* records it in `PiHarnessRecord.session`; the null/shell adapter ignores it.
|
|
57
|
+
* `undefined` ⇒ the pi adapter falls back to a generated default for its cwd.
|
|
58
|
+
*/
|
|
59
|
+
session?: string;
|
|
60
|
+
env?: NodeJS.ProcessEnv;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* What a harness needs to launch one item's harness INTERACTIVELY (task
|
|
64
|
+
* `agent-interactive-launch`): a FOREGROUND human session in `dir`, inherited
|
|
65
|
+
* stdio, NO prepared prompt. This is the OPPOSITE shape to {@link LaunchInput}
|
|
66
|
+
* (which feeds a prompt on stdin and captures output for the autonomous path):
|
|
67
|
+
* here the human drives the agent, so there is nothing to feed and nothing to
|
|
68
|
+
* capture. A NEW seam intent, NOT a flag on {@link Harness.launch} (decision #1):
|
|
69
|
+
* `launch` is fundamentally spawnSync + prompt-on-stdin + capture-output, and a
|
|
70
|
+
* boolean would make its `LaunchResult` lie.
|
|
71
|
+
*/
|
|
72
|
+
export interface InteractiveLaunchInput {
|
|
73
|
+
/** The onboarded working tree to start the session in (the command runs here). */
|
|
74
|
+
dir: string;
|
|
75
|
+
/** The slug being worked on (for adapters that name/log per slug). */
|
|
76
|
+
slug: string;
|
|
77
|
+
/**
|
|
78
|
+
* The resolved model the human starts pinned to (ADR §13 routing: flag > env
|
|
79
|
+
* > per-repo > global). `undefined` ⇒ no model forced. The pi adapter passes
|
|
80
|
+
* `--model <model>`; the human may still switch models inside the session.
|
|
81
|
+
*/
|
|
82
|
+
model?: string;
|
|
83
|
+
/**
|
|
84
|
+
* The full pi session-FILE path passed as `--session <path>` so the human
|
|
85
|
+
* session is still recorded/visible (audit trail + the pi dashboard, decision
|
|
86
|
+
* #2). `undefined` ⇒ the pi adapter generates a default for `dir`.
|
|
87
|
+
*/
|
|
88
|
+
session?: string;
|
|
89
|
+
env?: NodeJS.ProcessEnv;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* The result of an interactive launch — there is NOTHING to capture (the human
|
|
93
|
+
* drove a foreground session; no prepared prompt, no piped output, no PID record
|
|
94
|
+
* to persist; it is NOT a tracked job, decision #3). The only useful signal is
|
|
95
|
+
* the harness's exit code, returned here. Callers may ignore it.
|
|
96
|
+
*/
|
|
97
|
+
export interface InteractiveLaunchResult {
|
|
98
|
+
/** The harness process's exit code (0 = clean exit). */
|
|
99
|
+
exitCode: number;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* What the human-face verbs (`start`/`work-on`) hand a launcher: just the
|
|
103
|
+
* onboarded WORKING TREE + the slug + env. The model + the pi `--session` path
|
|
104
|
+
* are resolved at the CLI boundary (where config lives) and BOUND INTO the
|
|
105
|
+
* injected closure, so the git-logic modules stay decoupled from `createHarness`
|
|
106
|
+
* / config resolution. The CLI's closure calls
|
|
107
|
+
* {@link Harness.launchInteractive} with the resolved model/session.
|
|
108
|
+
*/
|
|
109
|
+
export interface InteractiveLaunchSite {
|
|
110
|
+
/** The slug being worked on. */
|
|
111
|
+
slug: string;
|
|
112
|
+
/** The onboarded working tree to start the foreground session in. */
|
|
113
|
+
dir: string;
|
|
114
|
+
/** Environment for the launched harness process. */
|
|
115
|
+
env?: NodeJS.ProcessEnv;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* The injectable interactive launcher the human-face verbs call AFTER
|
|
119
|
+
* onboarding. The CLI binds the resolved harness + model + sessions-dir into it;
|
|
120
|
+
* tests inject a spy. A thin seam so `start.ts`/`work-on.ts` never import
|
|
121
|
+
* `createHarness` or resolve config.
|
|
122
|
+
*/
|
|
123
|
+
export type InteractiveLauncher = (site: InteractiveLaunchSite) => void;
|
|
124
|
+
/** The `{model}` placeholder the null/shell adapter substitutes in `agentCmd`. */
|
|
125
|
+
export declare const MODEL_PLACEHOLDER = "{model}";
|
|
126
|
+
/**
|
|
127
|
+
* Inject the model ROUTING intent (ADR §13) into a shell `command` for the
|
|
128
|
+
* null/shell adapter, with three degradation rules so model routing is OFFERED,
|
|
129
|
+
* never FORCED:
|
|
130
|
+
*
|
|
131
|
+
* 1. `{model}` present + `model` set ⇒ substitute every occurrence.
|
|
132
|
+
* 2. `{model}` present + `model` unset ⇒ a clear config error (we never emit a
|
|
133
|
+
* literal `{model}` to the shell — that would silently misroute).
|
|
134
|
+
* 3. `{model}` absent ⇒ return `command` as-is (a user who bakes the model into
|
|
135
|
+
* `agentCmd`, or relies on the harness's own default, is untouched).
|
|
136
|
+
*
|
|
137
|
+
* dorfl only moves the model INTENT; auth/keys stay the harness's job.
|
|
138
|
+
*/
|
|
139
|
+
export declare function substituteModel(command: string, model: string | undefined): string;
|
|
140
|
+
export interface LaunchResult {
|
|
141
|
+
/** True iff the launched command completed successfully. */
|
|
142
|
+
ok: boolean;
|
|
143
|
+
/** The harness block to persist in the job record (PID, command, …). */
|
|
144
|
+
record: HarnessRecord;
|
|
145
|
+
/** Failure detail when `ok` is false (the stderr/failure channel). */
|
|
146
|
+
detail?: string;
|
|
147
|
+
/**
|
|
148
|
+
* The agent's final ANSWER (task `harness-agent-output`): the concatenated
|
|
149
|
+
* `text` of the LAST assistant turn the invocation produced. This is the
|
|
150
|
+
* channel for the agent's OUTPUT on success — DISTINCT from {@link detail},
|
|
151
|
+
* which is the failure/`stderr` channel. `undefined` when the invocation
|
|
152
|
+
* produced no parseable assistant text.
|
|
153
|
+
*
|
|
154
|
+
* Per-adapter EXTRACTION from each tool's native channel (Option C, decided
|
|
155
|
+
* 2026-06-06): pi reads the last assistant message from the session `.jsonl`
|
|
156
|
+
* it wrote (via `watch-session.ts`'s shared reader); the null/shell adapter
|
|
157
|
+
* returns its captured (synchronous) command stdout. The forward-contract for
|
|
158
|
+
* an opencode adapter (not built yet) is to take the last assistant `text`
|
|
159
|
+
* part from its `--format json` stream — the SAME `output` field.
|
|
160
|
+
*/
|
|
161
|
+
output?: string;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* The harness seam. `launch` starts the job's command + returns the record (with
|
|
165
|
+
* the liveness anchor); `isAlive` answers liveness FROM THE HARNESS (PID/session
|
|
166
|
+
* — never mtime, ADR §5).
|
|
167
|
+
*/
|
|
168
|
+
export interface Harness {
|
|
169
|
+
/** A stable adapter name (`null`, `pi`, …) stamped into the record. */
|
|
170
|
+
readonly adapter: string;
|
|
171
|
+
/** Launch the job's command; record the PID + liveness pointer. */
|
|
172
|
+
launch(input: LaunchInput): LaunchResult;
|
|
173
|
+
/**
|
|
174
|
+
* Launch the harness INTERACTIVELY (task `agent-interactive-launch`): a
|
|
175
|
+
* FOREGROUND human session in `input.dir` with INHERITED stdio and NO prepared
|
|
176
|
+
* prompt — the human drives it, and control returns when they exit. This is
|
|
177
|
+
* the human-facing counterpart to the autonomous {@link launch}; it is NOT a
|
|
178
|
+
* tracked job (no `.dorfl-job.json`, no PID/liveness record, no gate,
|
|
179
|
+
* decision #3), so it returns only an exit code. pi-only: the null adapter
|
|
180
|
+
* throws a clear pi-only error (decision #2).
|
|
181
|
+
*/
|
|
182
|
+
launchInteractive(input: InteractiveLaunchInput): InteractiveLaunchResult;
|
|
183
|
+
/** Is the job still alive? Answered from the record's anchor, NOT mtime. */
|
|
184
|
+
isAlive(record: HarnessRecord): boolean;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Is this `spawnSync.error` a BENIGN failure of the prompt write, safe to
|
|
188
|
+
* ignore? The null/shell adapter feeds `input.prompt` to the child on stdin
|
|
189
|
+
* (`spawnSync('bash', …, {input})`). When the prompt is EMPTY — the autonomous
|
|
190
|
+
* review/arbiter launches that just shell out and capture stdout — a child that
|
|
191
|
+
* closes its stdin before the parent's (zero-byte) write surfaces as `EPIPE`
|
|
192
|
+
* under concurrent test load. That write failing is harmless: there was nothing
|
|
193
|
+
* to deliver, and the child's stdout/exit status are still captured normally.
|
|
194
|
+
* So we treat ONLY `EPIPE` as benign and let every OTHER spawn error (`ENOENT`,
|
|
195
|
+
* `EACCES`, buffer overflow, …) throw — those are real launch failures.
|
|
196
|
+
*/
|
|
197
|
+
export declare function isBenignPromptWriteError(error: Error): boolean;
|
|
198
|
+
/**
|
|
199
|
+
* The **null adapter**: runs the configured command synchronously to completion
|
|
200
|
+
* in the job dir, recording the PID. Liveness is `process.kill(pid, 0)` against
|
|
201
|
+
* the recorded PID (the OS process table) — explicitly NOT a file mtime. Because
|
|
202
|
+
* it runs synchronously, the process has already exited by the time `launch`
|
|
203
|
+
* returns, so a finished job reads as not-alive (which is correct).
|
|
204
|
+
*/
|
|
205
|
+
export declare class NullHarness implements Harness {
|
|
206
|
+
readonly adapter = "null";
|
|
207
|
+
launch(input: LaunchInput): LaunchResult;
|
|
208
|
+
/**
|
|
209
|
+
* Interactive launch is NOT supported by the null/shell adapter (decision #2):
|
|
210
|
+
* its `agentCmd` is shaped for the captured, prompt-fed AUTONOMOUS path, so
|
|
211
|
+
* "interactive" has no clean meaning here. Throw a CLEAR pi-only error
|
|
212
|
+
* (mirroring `do --watch`'s fail-on-null decision) rather than silently
|
|
213
|
+
* shelling out the wrong way.
|
|
214
|
+
*/
|
|
215
|
+
launchInteractive(_input: InteractiveLaunchInput): InteractiveLaunchResult;
|
|
216
|
+
isAlive(record: HarnessRecord): boolean;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Resolve the harness adapter that OWNS a given job record, keyed off the
|
|
220
|
+
* record's `adapter` field. The core (`status`, `watch`, `gc`) reads liveness
|
|
221
|
+
* for a heterogeneous set of jobs (some null, some pi) from their persisted
|
|
222
|
+
* records, so it must ask the RIGHT adapter per job — a pi job's liveness is the
|
|
223
|
+
* pi adapter's responsibility (PID + session pointer), not the null adapter's.
|
|
224
|
+
*
|
|
225
|
+
* Adapters register here lazily via {@link registerHarness}; an unknown adapter
|
|
226
|
+
* falls back to the null adapter (PID-only liveness — never mtime), which is a
|
|
227
|
+
* safe superset for any PID-anchored record.
|
|
228
|
+
*/
|
|
229
|
+
export declare function resolveHarness(record: HarnessRecord): Harness;
|
|
230
|
+
/**
|
|
231
|
+
* Register a harness adapter under its `adapter` name so {@link resolveHarness}
|
|
232
|
+
* can dispatch liveness to it. Idempotent (last registration wins). The pi
|
|
233
|
+
* adapter registers itself on import; tests may register stubs.
|
|
234
|
+
*/
|
|
235
|
+
export declare function registerHarness(harness: Harness): void;
|
|
236
|
+
/**
|
|
237
|
+
* Is `pid` a live process? Uses signal 0 (`process.kill(pid, 0)`), which checks
|
|
238
|
+
* for existence/permission WITHOUT delivering a signal — the OS process table,
|
|
239
|
+
* never a filesystem mtime. Unknown/undefined PID ⇒ not alive.
|
|
240
|
+
*/
|
|
241
|
+
export declare function pidAlive(pid: number | undefined): boolean;
|
|
242
|
+
//# sourceMappingURL=harness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness.d.ts","sourceRoot":"","sources":["../src/harness.ts"],"names":[],"mappings":"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"}
|