dorfl 0.0.0 → 0.1.1
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 +3100 -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 +208 -0
- package/dist/frontmatter.d.ts.map +1 -0
- package/dist/frontmatter.js +344 -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 +329 -0
- package/dist/prd-to-spec.d.ts.map +1 -0
- package/dist/prd-to-spec.js +706 -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 +363 -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 +951 -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 +4379 -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 +477 -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 +1059 -0
- package/src/prepare.ts +230 -0
- package/src/prompt.ts +763 -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 +1437 -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/src/workspace.ts
ADDED
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
import {existsSync, readFileSync, rmSync, writeFileSync} from 'node:fs';
|
|
2
|
+
import {basename, dirname, join} from 'node:path';
|
|
3
|
+
import {git} from './git.js';
|
|
4
|
+
import {
|
|
5
|
+
encodeRepoKey,
|
|
6
|
+
ensureMirror,
|
|
7
|
+
type EnsureMirrorResult,
|
|
8
|
+
} from './repo-mirror.js';
|
|
9
|
+
import {
|
|
10
|
+
branchAheadOfArbiter,
|
|
11
|
+
rebaseContinuedBranchOntoMain,
|
|
12
|
+
pushContinuedBranchWithStaleLeaseRetry,
|
|
13
|
+
} from './continue-branch.js';
|
|
14
|
+
import {type HarnessRecord} from './harness.js';
|
|
15
|
+
import {brand} from './brand.js';
|
|
16
|
+
import {workBranchRef, type SlugNamespace} from './slug-namespace.js';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The workspace manager (ADR §2): one git worktree per **job** (a claimed work
|
|
20
|
+
* item being processed), checked out OUTSIDE the bare hub mirror at
|
|
21
|
+
* `<workspacesDir>/work/<work-id>/`, on branch `work/<slug>`, branched off the
|
|
22
|
+
* hub's freshly-fetched `main`.
|
|
23
|
+
*
|
|
24
|
+
* This is the single isolation primitive (ADR §1: jobs-not-agents) — both the
|
|
25
|
+
* autonomous `run-once` runner and (later) the human `work-on` build on it. It
|
|
26
|
+
* consumes the **`repo-mirror`** hub primitive (it does NOT reimplement mirror
|
|
27
|
+
* management or the repo→key encoding) and leaves a per-job state record (a
|
|
28
|
+
* `<work-id>.json` SIBLING of the worktree, OUTSIDE the checked-out tree —
|
|
29
|
+
* {@link jobRecordPath}) + the worktree on disk for `gc`/`status` to read (those
|
|
30
|
+
* are SEPARATE tasks — this task only provides the state they evaluate).
|
|
31
|
+
*
|
|
32
|
+
* `<workspacesDir>` is STATE, not cache (ADR §3): it lives under a single
|
|
33
|
+
* visible `~/.dorfl/`, never `~/.cache`.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
/** The on-disk JSON record `gc`/`status` read to evaluate a job. */
|
|
37
|
+
export interface JobRecord {
|
|
38
|
+
/** The work slug being processed. */
|
|
39
|
+
slug: string;
|
|
40
|
+
/** The encoded repo key (the hub mirror key for the arbiter URL). */
|
|
41
|
+
repoKey: string;
|
|
42
|
+
/** The work branch checked out in the worktree (`work/<slug>`). */
|
|
43
|
+
branch: string;
|
|
44
|
+
/** ISO timestamp the job worktree was created. */
|
|
45
|
+
startedAt: string;
|
|
46
|
+
/** Lifecycle state; `gc`/`status` read this alongside the worktree's existence. */
|
|
47
|
+
state: JobState;
|
|
48
|
+
/**
|
|
49
|
+
* Why the job is stuck, when `state` is `needs-attention` (ADR §12). The
|
|
50
|
+
* runner records the reason it routed the job to needs-attention (a red gate,
|
|
51
|
+
* a rebase conflict, …) so `status` can surface it without re-deriving it.
|
|
52
|
+
* Absent for `running`/`done` jobs.
|
|
53
|
+
*/
|
|
54
|
+
reason?: string;
|
|
55
|
+
/**
|
|
56
|
+
* The URL of the review request opened for this job (e.g. a GitHub PR), when
|
|
57
|
+
* `propose` mode + a real provider (ADR §6) opened one. Recorded so `status`
|
|
58
|
+
* can surface it. Absent for merge mode, the push-only `none`/degraded path,
|
|
59
|
+
* and jobs that have not integrated yet.
|
|
60
|
+
*/
|
|
61
|
+
prUrl?: string;
|
|
62
|
+
/** The harness block: how this job is launched + its liveness pointer. */
|
|
63
|
+
harness: HarnessRecord;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* A job's lifecycle state, persisted in its record. The reaper (`gc`) and
|
|
68
|
+
* `status` read it together with the worktree's existence (ADR §4); this task
|
|
69
|
+
* only ever sets `running` (and lets the harness/integration update it later).
|
|
70
|
+
*/
|
|
71
|
+
export type JobState =
|
|
72
|
+
| 'running' // the worktree exists and the job is in flight
|
|
73
|
+
| 'done' // work landed/pushed (integration succeeded)
|
|
74
|
+
| 'needs-attention'; // stuck — a human must look (gate red, rebase conflict, …)
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Encode a flat, deterministic, unique-per-claim **work-id** from the arbiter
|
|
78
|
+
* URL + slug: the hierarchical repo key with its `/` separators flattened to
|
|
79
|
+
* `__`, then `__<slug>` appended (ADR §2). Flat (not hierarchical) so listing /
|
|
80
|
+
* counting / GC of jobs is a flat `ls`. Reuses the `repo-mirror` repo→key
|
|
81
|
+
* encoding (dot→dash per segment) — it does NOT duplicate it.
|
|
82
|
+
*
|
|
83
|
+
* E.g. `git@github.com:wighawag/dorfl.git` + `feat`
|
|
84
|
+
* → `github-com__wighawag__dorfl__feat`.
|
|
85
|
+
*/
|
|
86
|
+
export function encodeWorkId(url: string, slug: string): string {
|
|
87
|
+
const key = encodeRepoKey(url).split('/').join('__');
|
|
88
|
+
return `${key}__${slug}`;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* The on-disk location of a job's worktree: `<workspacesDir>/work/<work-id>/`.
|
|
93
|
+
* Flat, OUTSIDE the hub (`<workspacesDir>/repos/...`), under `workspacesDir`
|
|
94
|
+
* (default `~/.dorfl`), never `~/.cache` (ADR §3).
|
|
95
|
+
*/
|
|
96
|
+
export function jobWorktreePath(
|
|
97
|
+
workspacesDir: string,
|
|
98
|
+
url: string,
|
|
99
|
+
slug: string,
|
|
100
|
+
): string {
|
|
101
|
+
return join(workspacesDir, 'work', encodeWorkId(url, slug));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** Filename of the per-job record. Derived from the single brand identity
|
|
105
|
+
* (`.{base}-job.json`) so a rename flips it in lockstep.
|
|
106
|
+
*
|
|
107
|
+
* HISTORICAL: this used to be the name of a file written INSIDE the job worktree
|
|
108
|
+
* (`<work-id>/.dorfl-job.json`). That in-tree location was the mistake —
|
|
109
|
+
* a runtime control file inside the checked-out worktree got swept onto the work
|
|
110
|
+
* branch by the runner's broad `git add -A` commits (and once WEDGED a
|
|
111
|
+
* continue-rebase `git switch`). The record now lives at a SIBLING path OUTSIDE
|
|
112
|
+
* the worktree ({@link jobRecordPath}); this constant survives only as the
|
|
113
|
+
* legacy in-tree read-fallback name + as the no-op-build / clean-worktree
|
|
114
|
+
* classification token in `agent-stop.ts`/`gc.ts` (now inert — the record can no
|
|
115
|
+
* longer appear in `git status`). */
|
|
116
|
+
export const JOB_RECORD_FILENAME = brand.jobRecordFilename;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* The on-disk location of a job's state record: a SIBLING of its worktree dir,
|
|
120
|
+
* `<workspacesDir>/work/<work-id>.json` (NEXT TO `<workspacesDir>/work/<work-id>/`,
|
|
121
|
+
* NOT inside it).
|
|
122
|
+
*
|
|
123
|
+
* This is the structural fix for the in-tree leak: the record is still under the
|
|
124
|
+
* same `workspacesDir/work/` control area (so `discoverJobs`'s single-directory
|
|
125
|
+
* walk still finds it), but it is PHYSICALLY OUTSIDE the checked-out git
|
|
126
|
+
* worktree, so the runner's broad `git add -A` commits can NEVER stage it — in
|
|
127
|
+
* ANY repo, with no `.gitignore` entry needed. A `<work-id>.json` file name can
|
|
128
|
+
* never collide with the `<work-id>/` worktree DIR (one carries a `.json`
|
|
129
|
+
* extension, the other does not).
|
|
130
|
+
*
|
|
131
|
+
* Derived purely from the worktree `dir` (sibling = `<dir>.json`) so every
|
|
132
|
+
* existing caller that holds a worktree dir keeps the same `(dir, …)` signature.
|
|
133
|
+
*/
|
|
134
|
+
export function jobRecordPath(dir: string): string {
|
|
135
|
+
return join(dirname(dir), `${basename(dir)}.json`);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** The LEGACY in-tree record path (`<dir>/.dorfl-job.json`) for the
|
|
139
|
+
* read-fallback below — a job worktree materialised by an OLD binary still has
|
|
140
|
+
* its record here. */
|
|
141
|
+
function legacyJobRecordPath(dir: string): string {
|
|
142
|
+
return join(dir, JOB_RECORD_FILENAME);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export interface CreateJobOptions {
|
|
146
|
+
/**
|
|
147
|
+
* The arbiter remote URL to mirror + branch from. Either `url` OR
|
|
148
|
+
* (`fromRepo` + `arbiter`) must be given; if both, `url` wins.
|
|
149
|
+
*/
|
|
150
|
+
url?: string;
|
|
151
|
+
/** A working repo to resolve the arbiter URL from (with `arbiter`). */
|
|
152
|
+
fromRepo?: string;
|
|
153
|
+
/** Remote name in `fromRepo` whose URL to mirror (default `origin`). */
|
|
154
|
+
arbiter?: string;
|
|
155
|
+
/** The work slug being processed (→ branch `work/<type>-<slug>` + work-id). */
|
|
156
|
+
slug: string;
|
|
157
|
+
/**
|
|
158
|
+
* The item TYPE — `'task'` (build) or `'prd'` (tasking) — namespacing the
|
|
159
|
+
* work branch via {@link workBranchRef} so a same-slug task and prd never
|
|
160
|
+
* collide. Defaults to `'task'`.
|
|
161
|
+
*/
|
|
162
|
+
type?: SlugNamespace;
|
|
163
|
+
/** The execution working area (config `workspacesDir`, default `~/.dorfl`). */
|
|
164
|
+
workspacesDir: string;
|
|
165
|
+
/** The initial harness block to persist in the record (default: null adapter). */
|
|
166
|
+
harness?: HarnessRecord;
|
|
167
|
+
env?: NodeJS.ProcessEnv;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export interface Job {
|
|
171
|
+
/** Working directory the agent + tests run in (the worktree). */
|
|
172
|
+
dir: string;
|
|
173
|
+
/** The work branch checked out there (`work/<slug>`). */
|
|
174
|
+
branch: string;
|
|
175
|
+
/** The slug being processed. */
|
|
176
|
+
slug: string;
|
|
177
|
+
/**
|
|
178
|
+
* The git remote name VALID INSIDE the worktree that tracks the arbiter. A
|
|
179
|
+
* job worktree is cut from the bare hub mirror, whose clone remote is
|
|
180
|
+
* `origin` (pointing at the arbiter URL). So rebase/integrate inside the
|
|
181
|
+
* worktree always target `origin`, regardless of what the source working repo
|
|
182
|
+
* calls its arbiter remote.
|
|
183
|
+
*/
|
|
184
|
+
arbiterRemote: string;
|
|
185
|
+
/** Absolute path to the per-job record. */
|
|
186
|
+
recordPath: string;
|
|
187
|
+
/** The persisted record. */
|
|
188
|
+
record: JobRecord;
|
|
189
|
+
/** The hub-mirror result this job was cut from. */
|
|
190
|
+
mirror: EnsureMirrorResult;
|
|
191
|
+
/**
|
|
192
|
+
* True iff this job CONTINUED a kept arbiter `work/<slug>` branch (a requeue)
|
|
193
|
+
* rather than cutting fresh off main — the worktree was cut from that branch
|
|
194
|
+
* and rebased onto the freshly-fetched main at onboard-time (ADR §10).
|
|
195
|
+
*/
|
|
196
|
+
continued: boolean;
|
|
197
|
+
/**
|
|
198
|
+
* True iff a CONTINUE rebase onto fresh main CONFLICTED (aborted, never
|
|
199
|
+
* auto-resolved). The caller (`run`'s pipeline / `do --remote`) routes the
|
|
200
|
+
* item to needs-attention via the §10 path; the worktree is left on the
|
|
201
|
+
* un-rebased kept branch as the never-lose-work signal.
|
|
202
|
+
*/
|
|
203
|
+
continueRebaseConflict: boolean;
|
|
204
|
+
/**
|
|
205
|
+
* Set iff the CONTINUE reconcile push to the arbiter FAILED TERMINALLY (the
|
|
206
|
+
* stale-lease retry cap was exhausted, or a non-stale-lease rejection such as
|
|
207
|
+
* a protected ref / an unreachable arbiter) — the helper THROWS, and we catch
|
|
208
|
+
* it here so the run does NOT crash leaving the task silently in-progress on
|
|
209
|
+
* the arbiter (the stale-lease-strand bug). The caller routes the item to
|
|
210
|
+
* needs-attention, the kept work left committed + recoverable on the branch.
|
|
211
|
+
* Absent on a fresh cut, a clean continue that pushed, and a rebase conflict
|
|
212
|
+
* (which sets {@link continueRebaseConflict} instead).
|
|
213
|
+
*/
|
|
214
|
+
continuePushFailure?: string;
|
|
215
|
+
/**
|
|
216
|
+
* Remove the job's worktree + work branch from the hub (`git worktree remove`
|
|
217
|
+
* + prune; never a bare `rm -rf`, ADR §4). NOTE: the SAFE-to-delete predicate
|
|
218
|
+
* (ADR §4) is owned by the `gc` task — this is only the mechanical teardown
|
|
219
|
+
* the runner uses after a job is provably saved.
|
|
220
|
+
*/
|
|
221
|
+
dispose(): void;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const DEFAULT_HARNESS: HarnessRecord = {adapter: 'null'};
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Create (or recreate) a job: ensure the hub mirror via `repo-mirror`, then
|
|
228
|
+
* `git worktree add` a per-job worktree OUTSIDE the hub at
|
|
229
|
+
* `<workspacesDir>/work/<work-id>/` on `work/<slug>`, branched off the
|
|
230
|
+
* freshly-fetched `<hub>/main`. Writes the per-job record at a SIBLING of the
|
|
231
|
+
* worktree (`<work-id>.json`, OUTSIDE the tree — {@link jobRecordPath}).
|
|
232
|
+
*
|
|
233
|
+
* Distinct slugs ⇒ distinct `work/<slug>` branches, so git's one-branch-per-
|
|
234
|
+
* worktree constraint is naturally avoided (ADR §2). If a stale worktree/branch
|
|
235
|
+
* for this work-id already exists it is cleared first (idempotent re-create).
|
|
236
|
+
*/
|
|
237
|
+
export function createJob(options: CreateJobOptions): Job {
|
|
238
|
+
const env = options.env;
|
|
239
|
+
const mirror = ensureMirror({
|
|
240
|
+
url: options.url,
|
|
241
|
+
fromRepo: options.fromRepo,
|
|
242
|
+
arbiter: options.arbiter,
|
|
243
|
+
workspacesDir: options.workspacesDir,
|
|
244
|
+
env,
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
const slug = options.slug;
|
|
248
|
+
const branch = workBranchRef(options.type ?? 'task', slug);
|
|
249
|
+
const dir = jobWorktreePath(options.workspacesDir, mirror.url, slug);
|
|
250
|
+
|
|
251
|
+
// CONTINUE-detection (shared with the in-place path, ADR §14 keystone): after
|
|
252
|
+
// `ensureMirror`'s mirror-style fetch (`+refs/heads/*:refs/heads/*`), a kept
|
|
253
|
+
// arbiter `work/<slug>` lands as a LOCAL head `work/<slug>` in the bare mirror.
|
|
254
|
+
// If it is AHEAD of `main` (a requeue kept it), CONTINUE from it; otherwise cut
|
|
255
|
+
// FRESH off main (the common case — a first attempt, or `requeue --reset` deleted
|
|
256
|
+
// it).
|
|
257
|
+
// ARBITER-AUTHORITATIVE continue-detection: `ls-remote` the arbiter (the
|
|
258
|
+
// mirror's `origin`) so an orphaned local head/tracking-ref in the bare hub
|
|
259
|
+
// mirror — e.g. a `refs/remotes/origin/work/<slug>` in the namespace no
|
|
260
|
+
// `remote.origin.fetch` refspec prunes, or a `refs/heads/work/<slug>` that
|
|
261
|
+
// `ensureMirror`'s `--prune` could not reach — cannot resurrect a branch the
|
|
262
|
+
// arbiter no longer has (e.g. a cross-machine `gc --remote-branches` delete).
|
|
263
|
+
const continueFromKept = branchAheadOfArbiter({
|
|
264
|
+
cwd: mirror.path,
|
|
265
|
+
arbiterRemote: 'origin',
|
|
266
|
+
branch,
|
|
267
|
+
branchRef: branch,
|
|
268
|
+
mainRef: 'main',
|
|
269
|
+
env,
|
|
270
|
+
});
|
|
271
|
+
let continued = false;
|
|
272
|
+
let continueRebaseConflict = false;
|
|
273
|
+
let continuePushFailure: string | undefined;
|
|
274
|
+
|
|
275
|
+
if (continueFromKept) {
|
|
276
|
+
// The arbiter `work/<slug>` tip the mirror fetched, READ BEFORE the onboard
|
|
277
|
+
// rebase rewrites the local branch — the value the --force-with-lease push
|
|
278
|
+
// expects the arbiter to still hold. A requeue-continue can CHURN this ref
|
|
279
|
+
// after the mirror fetch, making the lease stale; the retry below re-leases
|
|
280
|
+
// against the freshly-fetched tip (the WORK branch is unshared, so re-observing
|
|
281
|
+
// + replaying is correct).
|
|
282
|
+
const expectedRemoteTip = git(['rev-parse', branch], mirror.path, {
|
|
283
|
+
env,
|
|
284
|
+
}).trim();
|
|
285
|
+
|
|
286
|
+
// Clear ONLY a stale worktree DIR (never the branch we are continuing), then
|
|
287
|
+
// cut the worktree FROM the kept branch (not fresh off main).
|
|
288
|
+
clearStaleWorktreeOnly(mirror.path, dir, env);
|
|
289
|
+
git(['worktree', 'add', dir, branch], mirror.path, {env});
|
|
290
|
+
continued = true;
|
|
291
|
+
|
|
292
|
+
// REBASE the continued branch onto the freshly-fetched mirror main at
|
|
293
|
+
// onboard-time (ADR §10: rebase, not merge) so the agent builds on a CURRENT
|
|
294
|
+
// base. A CLEAN rebase → update the already-pushed arbiter tip with
|
|
295
|
+
// --force-with-lease on the WORK branch ONLY (a requeued item is unshared) —
|
|
296
|
+
// NEVER --force, NEVER to main (§11). A CONFLICT → aborted (never
|
|
297
|
+
// auto-resolved) + flagged so the caller routes to needs-attention.
|
|
298
|
+
const rebase = rebaseContinuedBranchOntoMain(dir, 'main', env);
|
|
299
|
+
if (rebase.kind === 'conflict') {
|
|
300
|
+
continueRebaseConflict = true;
|
|
301
|
+
} else {
|
|
302
|
+
// Push the rebased tip with --force-with-lease, SURVIVING a stale-lease
|
|
303
|
+
// ("stale info") rejection: re-fetch the arbiter `work/<slug>` + main,
|
|
304
|
+
// re-rebase onto current main, and retry (bounded) instead of stranding the
|
|
305
|
+
// committed green work in the worktree. A rebase CONFLICT on a retry is the
|
|
306
|
+
// SAME abort → needs-attention path (never auto-resolved).
|
|
307
|
+
//
|
|
308
|
+
// The helper THROWS on a terminal failure (the stale-lease retry cap, or a
|
|
309
|
+
// non-stale-lease rejection / unreachable arbiter). BEFORE this task that
|
|
310
|
+
// throw ESCAPED `createJob` uncaught, crashing the run and leaving the
|
|
311
|
+
// already-committed kept work silently in `work/in-progress/` on the arbiter
|
|
312
|
+
// (the stale-lease-strand incident). We now CATCH it and flag
|
|
313
|
+
// `continuePushFailure` so the caller (`runRemotePipeline`) routes the item
|
|
314
|
+
// to needs-attention — the kept work stays committed + recoverable on the
|
|
315
|
+
// branch — instead of stranding it.
|
|
316
|
+
try {
|
|
317
|
+
const pushed = pushContinuedBranchWithStaleLeaseRetry({
|
|
318
|
+
cwd: dir,
|
|
319
|
+
branch,
|
|
320
|
+
arbiter: 'origin',
|
|
321
|
+
mainRef: 'main',
|
|
322
|
+
expectedRemoteTip,
|
|
323
|
+
env,
|
|
324
|
+
});
|
|
325
|
+
if (pushed.kind === 'conflict') {
|
|
326
|
+
continueRebaseConflict = true;
|
|
327
|
+
}
|
|
328
|
+
} catch (err) {
|
|
329
|
+
continuePushFailure = err instanceof Error ? err.message : String(err);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
} else {
|
|
333
|
+
// Clear any stale registration for this work-id (idempotent re-create): a
|
|
334
|
+
// leftover worktree dir or branch from a prior crashed run would block the
|
|
335
|
+
// `worktree add`. We use git's own removal, never a bare rm -rf (ADR §4).
|
|
336
|
+
clearStale(mirror.path, dir, branch, env);
|
|
337
|
+
|
|
338
|
+
// Cut the worktree OUTSIDE the hub, on a fresh per-slug branch off the
|
|
339
|
+
// freshly-fetched mirror main. `--force` is not used: the branch is unique.
|
|
340
|
+
git(['worktree', 'add', '-b', branch, dir, 'main'], mirror.path, {env});
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const record: JobRecord = {
|
|
344
|
+
slug,
|
|
345
|
+
repoKey: encodeRepoKey(mirror.url),
|
|
346
|
+
branch,
|
|
347
|
+
startedAt: new Date().toISOString(),
|
|
348
|
+
state: 'running',
|
|
349
|
+
harness: options.harness ?? DEFAULT_HARNESS,
|
|
350
|
+
};
|
|
351
|
+
const recordPath = jobRecordPath(dir);
|
|
352
|
+
writeJobRecord(dir, record);
|
|
353
|
+
|
|
354
|
+
return {
|
|
355
|
+
dir,
|
|
356
|
+
branch,
|
|
357
|
+
slug,
|
|
358
|
+
arbiterRemote: 'origin',
|
|
359
|
+
recordPath,
|
|
360
|
+
record,
|
|
361
|
+
mirror,
|
|
362
|
+
continued,
|
|
363
|
+
continueRebaseConflict,
|
|
364
|
+
continuePushFailure,
|
|
365
|
+
dispose() {
|
|
366
|
+
git(['worktree', 'remove', '--force', dir], mirror.path, {env});
|
|
367
|
+
removeJobRecord(dir);
|
|
368
|
+
pruneAndDropBranch(mirror.path, branch, env);
|
|
369
|
+
},
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Write (or overwrite) a job's record to its SIBLING path ({@link jobRecordPath},
|
|
375
|
+
* `<work-id>.json` next to the worktree), OUTSIDE the checked-out tree. `dir` is
|
|
376
|
+
* the worktree dir, kept as the parameter so every caller is unchanged.
|
|
377
|
+
*/
|
|
378
|
+
export function writeJobRecord(dir: string, record: JobRecord): void {
|
|
379
|
+
writeFileSync(jobRecordPath(dir), JSON.stringify(record, null, 2) + '\n');
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Read a job's record given its worktree `dir`, or `undefined` if absent/invalid.
|
|
384
|
+
*
|
|
385
|
+
* Reads the NEW sibling location ({@link jobRecordPath}) first, then falls back
|
|
386
|
+
* to the LEGACY in-tree location (`<dir>/.dorfl-job.json`) so a job
|
|
387
|
+
* worktree materialised by an OLD binary (record still inside the tree) stays
|
|
388
|
+
* discoverable/reapable until it is torn down. New jobs only ever write the
|
|
389
|
+
* sibling path, so the fallback is purely for in-flight migration.
|
|
390
|
+
*/
|
|
391
|
+
export function readJobRecord(dir: string): JobRecord | undefined {
|
|
392
|
+
for (const path of [jobRecordPath(dir), legacyJobRecordPath(dir)]) {
|
|
393
|
+
if (!existsSync(path)) {
|
|
394
|
+
continue;
|
|
395
|
+
}
|
|
396
|
+
try {
|
|
397
|
+
return JSON.parse(readFileSync(path, 'utf8')) as JobRecord;
|
|
398
|
+
} catch {
|
|
399
|
+
return undefined;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
return undefined;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Delete a job's record on teardown — BOTH the new sibling path
|
|
407
|
+
* ({@link jobRecordPath}) and the legacy in-tree path (an old-binary worktree).
|
|
408
|
+
* Best-effort + idempotent (a missing file is fine). Called when a worktree is
|
|
409
|
+
* removed (reaped / disposed / cleared) so the relocated record does not outlive
|
|
410
|
+
* its worktree as an orphan `<work-id>.json` (when the record lived INSIDE the
|
|
411
|
+
* worktree it was deleted WITH it by `git worktree remove`; now that it is a
|
|
412
|
+
* sibling, its teardown must be explicit).
|
|
413
|
+
*/
|
|
414
|
+
export function removeJobRecord(dir: string): void {
|
|
415
|
+
for (const path of [jobRecordPath(dir), legacyJobRecordPath(dir)]) {
|
|
416
|
+
try {
|
|
417
|
+
rmSync(path, {force: true});
|
|
418
|
+
} catch {
|
|
419
|
+
// best-effort: an unremovable orphan record is harmless (discovery
|
|
420
|
+
// keys on the worktree DIR, which is gone).
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Update a job's record in place (e.g. flip `state` to `needs-attention` after a
|
|
427
|
+
* rebase conflict), merging the patch over the on-disk record. A no-op if no
|
|
428
|
+
* record exists.
|
|
429
|
+
*/
|
|
430
|
+
export function updateJobRecord(
|
|
431
|
+
dir: string,
|
|
432
|
+
patch: Partial<JobRecord>,
|
|
433
|
+
): JobRecord | undefined {
|
|
434
|
+
const current = readJobRecord(dir);
|
|
435
|
+
if (!current) {
|
|
436
|
+
return undefined;
|
|
437
|
+
}
|
|
438
|
+
const next = {...current, ...patch};
|
|
439
|
+
writeJobRecord(dir, next);
|
|
440
|
+
return next;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
/** Remove a stale worktree dir / branch registration before re-creating. */
|
|
444
|
+
function clearStale(
|
|
445
|
+
mirrorPath: string,
|
|
446
|
+
dir: string,
|
|
447
|
+
branch: string,
|
|
448
|
+
env: NodeJS.ProcessEnv | undefined,
|
|
449
|
+
): void {
|
|
450
|
+
if (existsSync(dir)) {
|
|
451
|
+
// Soft-remove: ignore errors (e.g. the dir is not a registered worktree).
|
|
452
|
+
try {
|
|
453
|
+
git(['worktree', 'remove', '--force', dir], mirrorPath, {env});
|
|
454
|
+
} catch {
|
|
455
|
+
// fall through to prune below
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
pruneAndDropBranch(mirrorPath, branch, env);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Clear ONLY a stale worktree DIR (and prune dangling registrations) — WITHOUT
|
|
463
|
+
* dropping the branch. Used on the CONTINUE path so the kept `work/<slug>`
|
|
464
|
+
* branch (the durable requeue artifact) is NEVER nuked while a leftover worktree
|
|
465
|
+
* dir from a prior crashed attempt is still cleared so `worktree add` succeeds.
|
|
466
|
+
*/
|
|
467
|
+
function clearStaleWorktreeOnly(
|
|
468
|
+
mirrorPath: string,
|
|
469
|
+
dir: string,
|
|
470
|
+
env: NodeJS.ProcessEnv | undefined,
|
|
471
|
+
): void {
|
|
472
|
+
if (existsSync(dir)) {
|
|
473
|
+
try {
|
|
474
|
+
git(['worktree', 'remove', '--force', dir], mirrorPath, {env});
|
|
475
|
+
} catch {
|
|
476
|
+
// fall through to prune below
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
try {
|
|
480
|
+
git(['worktree', 'prune'], mirrorPath, {env});
|
|
481
|
+
} catch {
|
|
482
|
+
// best-effort
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/** Prune dangling worktree registrations + delete the work branch if present. */
|
|
487
|
+
function pruneAndDropBranch(
|
|
488
|
+
mirrorPath: string,
|
|
489
|
+
branch: string,
|
|
490
|
+
env: NodeJS.ProcessEnv | undefined,
|
|
491
|
+
): void {
|
|
492
|
+
try {
|
|
493
|
+
git(['worktree', 'prune'], mirrorPath, {env});
|
|
494
|
+
} catch {
|
|
495
|
+
// best-effort
|
|
496
|
+
}
|
|
497
|
+
try {
|
|
498
|
+
git(['branch', '-D', branch], mirrorPath, {env});
|
|
499
|
+
} catch {
|
|
500
|
+
// branch may not exist
|
|
501
|
+
}
|
|
502
|
+
}
|