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.
Files changed (619) hide show
  1. package/dist/advance-ci-template.d.ts +73 -0
  2. package/dist/advance-ci-template.d.ts.map +1 -0
  3. package/dist/advance-ci-template.js +104 -0
  4. package/dist/advance-ci-template.js.map +1 -0
  5. package/dist/advance-classify.d.ts +132 -0
  6. package/dist/advance-classify.d.ts.map +1 -0
  7. package/dist/advance-classify.js +120 -0
  8. package/dist/advance-classify.js.map +1 -0
  9. package/dist/advance-drivers.d.ts +182 -0
  10. package/dist/advance-drivers.d.ts.map +1 -0
  11. package/dist/advance-drivers.js +231 -0
  12. package/dist/advance-drivers.js.map +1 -0
  13. package/dist/advance-isolated.d.ts +156 -0
  14. package/dist/advance-isolated.d.ts.map +1 -0
  15. package/dist/advance-isolated.js +256 -0
  16. package/dist/advance-isolated.js.map +1 -0
  17. package/dist/advance-lifecycle-template.d.ts +107 -0
  18. package/dist/advance-lifecycle-template.d.ts.map +1 -0
  19. package/dist/advance-lifecycle-template.js +668 -0
  20. package/dist/advance-lifecycle-template.js.map +1 -0
  21. package/dist/advance-loop-driver.d.ts +325 -0
  22. package/dist/advance-loop-driver.d.ts.map +1 -0
  23. package/dist/advance-loop-driver.js +437 -0
  24. package/dist/advance-loop-driver.js.map +1 -0
  25. package/dist/advance-treeless-publish.d.ts +108 -0
  26. package/dist/advance-treeless-publish.d.ts.map +1 -0
  27. package/dist/advance-treeless-publish.js +71 -0
  28. package/dist/advance-treeless-publish.js.map +1 -0
  29. package/dist/advance.d.ts +340 -0
  30. package/dist/advance.d.ts.map +1 -0
  31. package/dist/advance.js +1122 -0
  32. package/dist/advance.js.map +1 -0
  33. package/dist/advancing-lock.d.ts +294 -0
  34. package/dist/advancing-lock.d.ts.map +1 -0
  35. package/dist/advancing-lock.js +594 -0
  36. package/dist/advancing-lock.js.map +1 -0
  37. package/dist/agent-launch.d.ts +79 -0
  38. package/dist/agent-launch.d.ts.map +1 -0
  39. package/dist/agent-launch.js +61 -0
  40. package/dist/agent-launch.js.map +1 -0
  41. package/dist/agent-stop.d.ts +149 -0
  42. package/dist/agent-stop.d.ts.map +1 -0
  43. package/dist/agent-stop.js +307 -0
  44. package/dist/agent-stop.js.map +1 -0
  45. package/dist/apply-decide.d.ts +127 -0
  46. package/dist/apply-decide.d.ts.map +1 -0
  47. package/dist/apply-decide.js +176 -0
  48. package/dist/apply-decide.js.map +1 -0
  49. package/dist/apply-merge-action.d.ts +206 -0
  50. package/dist/apply-merge-action.d.ts.map +1 -0
  51. package/dist/apply-merge-action.js +307 -0
  52. package/dist/apply-merge-action.js.map +1 -0
  53. package/dist/apply-persist.d.ts +174 -0
  54. package/dist/apply-persist.d.ts.map +1 -0
  55. package/dist/apply-persist.js +359 -0
  56. package/dist/apply-persist.js.map +1 -0
  57. package/dist/arbiter.d.ts +120 -0
  58. package/dist/arbiter.d.ts.map +1 -0
  59. package/dist/arbiter.js +255 -0
  60. package/dist/arbiter.js.map +1 -0
  61. package/dist/brand.d.ts +70 -0
  62. package/dist/brand.d.ts.map +1 -0
  63. package/dist/brand.js +84 -0
  64. package/dist/brand.js.map +1 -0
  65. package/dist/buildable-body.d.ts +132 -0
  66. package/dist/buildable-body.d.ts.map +1 -0
  67. package/dist/buildable-body.js +131 -0
  68. package/dist/buildable-body.js.map +1 -0
  69. package/dist/categorise.d.ts +66 -0
  70. package/dist/categorise.d.ts.map +1 -0
  71. package/dist/categorise.js +106 -0
  72. package/dist/categorise.js.map +1 -0
  73. package/dist/claim-cas.d.ts +117 -0
  74. package/dist/claim-cas.d.ts.map +1 -0
  75. package/dist/claim-cas.js +312 -0
  76. package/dist/claim-cas.js.map +1 -0
  77. package/dist/cli-spinner.d.ts +112 -0
  78. package/dist/cli-spinner.d.ts.map +1 -0
  79. package/dist/cli-spinner.js +157 -0
  80. package/dist/cli-spinner.js.map +1 -0
  81. package/dist/cli.d.ts +11 -0
  82. package/dist/cli.d.ts.map +1 -0
  83. package/dist/cli.js +3094 -0
  84. package/dist/cli.js.map +1 -0
  85. package/dist/close-job-template.d.ts +70 -0
  86. package/dist/close-job-template.d.ts.map +1 -0
  87. package/dist/close-job-template.js +180 -0
  88. package/dist/close-job-template.js.map +1 -0
  89. package/dist/close-job.d.ts +95 -0
  90. package/dist/close-job.d.ts.map +1 -0
  91. package/dist/close-job.js +226 -0
  92. package/dist/close-job.js.map +1 -0
  93. package/dist/complete.d.ts +361 -0
  94. package/dist/complete.d.ts.map +1 -0
  95. package/dist/complete.js +885 -0
  96. package/dist/complete.js.map +1 -0
  97. package/dist/concurrency.d.ts +68 -0
  98. package/dist/concurrency.d.ts.map +1 -0
  99. package/dist/concurrency.js +112 -0
  100. package/dist/concurrency.js.map +1 -0
  101. package/dist/config-override.d.ts +76 -0
  102. package/dist/config-override.d.ts.map +1 -0
  103. package/dist/config-override.js +50 -0
  104. package/dist/config-override.js.map +1 -0
  105. package/dist/config.d.ts +668 -0
  106. package/dist/config.d.ts.map +1 -0
  107. package/dist/config.js +241 -0
  108. package/dist/config.js.map +1 -0
  109. package/dist/continue-branch.d.ts +249 -0
  110. package/dist/continue-branch.d.ts.map +1 -0
  111. package/dist/continue-branch.js +389 -0
  112. package/dist/continue-branch.js.map +1 -0
  113. package/dist/cwd-section.d.ts +186 -0
  114. package/dist/cwd-section.d.ts.map +1 -0
  115. package/dist/cwd-section.js +209 -0
  116. package/dist/cwd-section.js.map +1 -0
  117. package/dist/decision-engine.d.ts +170 -0
  118. package/dist/decision-engine.d.ts.map +1 -0
  119. package/dist/decision-engine.js +136 -0
  120. package/dist/decision-engine.js.map +1 -0
  121. package/dist/detect.d.ts +17 -0
  122. package/dist/detect.d.ts.map +1 -0
  123. package/dist/detect.js +118 -0
  124. package/dist/detect.js.map +1 -0
  125. package/dist/do-autopick.d.ts +85 -0
  126. package/dist/do-autopick.d.ts.map +1 -0
  127. package/dist/do-autopick.js +112 -0
  128. package/dist/do-autopick.js.map +1 -0
  129. package/dist/do-config.d.ts +312 -0
  130. package/dist/do-config.d.ts.map +1 -0
  131. package/dist/do-config.js +358 -0
  132. package/dist/do-config.js.map +1 -0
  133. package/dist/do-remote-auto.d.ts +75 -0
  134. package/dist/do-remote-auto.d.ts.map +1 -0
  135. package/dist/do-remote-auto.js +111 -0
  136. package/dist/do-remote-auto.js.map +1 -0
  137. package/dist/do.d.ts +621 -0
  138. package/dist/do.d.ts.map +1 -0
  139. package/dist/do.js +1882 -0
  140. package/dist/do.js.map +1 -0
  141. package/dist/drop-source.d.ts +96 -0
  142. package/dist/drop-source.d.ts.map +1 -0
  143. package/dist/drop-source.js +91 -0
  144. package/dist/drop-source.js.map +1 -0
  145. package/dist/eligibility.d.ts +46 -0
  146. package/dist/eligibility.d.ts.map +1 -0
  147. package/dist/eligibility.js +34 -0
  148. package/dist/eligibility.js.map +1 -0
  149. package/dist/env-config.d.ts +51 -0
  150. package/dist/env-config.d.ts.map +1 -0
  151. package/dist/env-config.js +272 -0
  152. package/dist/env-config.js.map +1 -0
  153. package/dist/failure-cause.d.ts +70 -0
  154. package/dist/failure-cause.d.ts.map +1 -0
  155. package/dist/failure-cause.js +126 -0
  156. package/dist/failure-cause.js.map +1 -0
  157. package/dist/format.d.ts +43 -0
  158. package/dist/format.d.ts.map +1 -0
  159. package/dist/format.js +256 -0
  160. package/dist/format.js.map +1 -0
  161. package/dist/frontmatter.d.ts +215 -0
  162. package/dist/frontmatter.d.ts.map +1 -0
  163. package/dist/frontmatter.js +345 -0
  164. package/dist/frontmatter.js.map +1 -0
  165. package/dist/gate-readiness.d.ts +84 -0
  166. package/dist/gate-readiness.d.ts.map +1 -0
  167. package/dist/gate-readiness.js +103 -0
  168. package/dist/gate-readiness.js.map +1 -0
  169. package/dist/gc.d.ts +165 -0
  170. package/dist/gc.d.ts.map +1 -0
  171. package/dist/gc.js +313 -0
  172. package/dist/gc.js.map +1 -0
  173. package/dist/gh-failure.d.ts +42 -0
  174. package/dist/gh-failure.d.ts.map +1 -0
  175. package/dist/gh-failure.js +49 -0
  176. package/dist/gh-failure.js.map +1 -0
  177. package/dist/git.d.ts +75 -0
  178. package/dist/git.d.ts.map +1 -0
  179. package/dist/git.js +130 -0
  180. package/dist/git.js.map +1 -0
  181. package/dist/github.d.ts +187 -0
  182. package/dist/github.d.ts.map +1 -0
  183. package/dist/github.js +343 -0
  184. package/dist/github.js.map +1 -0
  185. package/dist/harness.d.ts +242 -0
  186. package/dist/harness.d.ts.map +1 -0
  187. package/dist/harness.js +157 -0
  188. package/dist/harness.js.map +1 -0
  189. package/dist/identity.d.ts +167 -0
  190. package/dist/identity.d.ts.map +1 -0
  191. package/dist/identity.js +231 -0
  192. package/dist/identity.js.map +1 -0
  193. package/dist/index.d.ts +147 -0
  194. package/dist/index.d.ts.map +1 -0
  195. package/dist/index.js +76 -0
  196. package/dist/index.js.map +1 -0
  197. package/dist/install-ci-branch-protection.d.ts +147 -0
  198. package/dist/install-ci-branch-protection.d.ts.map +1 -0
  199. package/dist/install-ci-branch-protection.js +166 -0
  200. package/dist/install-ci-branch-protection.js.map +1 -0
  201. package/dist/install-ci-capabilities/advance-lifecycle.d.ts +15 -0
  202. package/dist/install-ci-capabilities/advance-lifecycle.d.ts.map +1 -0
  203. package/dist/install-ci-capabilities/advance-lifecycle.js +28 -0
  204. package/dist/install-ci-capabilities/advance-lifecycle.js.map +1 -0
  205. package/dist/install-ci-capabilities/close-job.d.ts +13 -0
  206. package/dist/install-ci-capabilities/close-job.d.ts.map +1 -0
  207. package/dist/install-ci-capabilities/close-job.js +26 -0
  208. package/dist/install-ci-capabilities/close-job.js.map +1 -0
  209. package/dist/install-ci-capabilities/example-noop.d.ts +16 -0
  210. package/dist/install-ci-capabilities/example-noop.d.ts.map +1 -0
  211. package/dist/install-ci-capabilities/example-noop.js +23 -0
  212. package/dist/install-ci-capabilities/example-noop.js.map +1 -0
  213. package/dist/install-ci-capabilities/intake.d.ts +15 -0
  214. package/dist/install-ci-capabilities/intake.d.ts.map +1 -0
  215. package/dist/install-ci-capabilities/intake.js +28 -0
  216. package/dist/install-ci-capabilities/intake.js.map +1 -0
  217. package/dist/install-ci-capabilities/verify.d.ts +14 -0
  218. package/dist/install-ci-capabilities/verify.d.ts.map +1 -0
  219. package/dist/install-ci-capabilities/verify.js +27 -0
  220. package/dist/install-ci-capabilities/verify.js.map +1 -0
  221. package/dist/install-ci-core.d.ts +446 -0
  222. package/dist/install-ci-core.d.ts.map +1 -0
  223. package/dist/install-ci-core.js +760 -0
  224. package/dist/install-ci-core.js.map +1 -0
  225. package/dist/install-ci-github.d.ts +167 -0
  226. package/dist/install-ci-github.d.ts.map +1 -0
  227. package/dist/install-ci-github.js +315 -0
  228. package/dist/install-ci-github.js.map +1 -0
  229. package/dist/install-ci.d.ts +105 -0
  230. package/dist/install-ci.d.ts.map +1 -0
  231. package/dist/install-ci.js +363 -0
  232. package/dist/install-ci.js.map +1 -0
  233. package/dist/intake-event.d.ts +88 -0
  234. package/dist/intake-event.d.ts.map +1 -0
  235. package/dist/intake-event.js +66 -0
  236. package/dist/intake-event.js.map +1 -0
  237. package/dist/intake-marker.d.ts +95 -0
  238. package/dist/intake-marker.d.ts.map +1 -0
  239. package/dist/intake-marker.js +127 -0
  240. package/dist/intake-marker.js.map +1 -0
  241. package/dist/intake-triage.d.ts +48 -0
  242. package/dist/intake-triage.d.ts.map +1 -0
  243. package/dist/intake-triage.js +95 -0
  244. package/dist/intake-triage.js.map +1 -0
  245. package/dist/intake-trigger-template.d.ts +185 -0
  246. package/dist/intake-trigger-template.d.ts.map +1 -0
  247. package/dist/intake-trigger-template.js +449 -0
  248. package/dist/intake-trigger-template.js.map +1 -0
  249. package/dist/intake.d.ts +569 -0
  250. package/dist/intake.d.ts.map +1 -0
  251. package/dist/intake.js +1628 -0
  252. package/dist/intake.js.map +1 -0
  253. package/dist/integration-core.d.ts +539 -0
  254. package/dist/integration-core.d.ts.map +1 -0
  255. package/dist/integration-core.js +2195 -0
  256. package/dist/integration-core.js.map +1 -0
  257. package/dist/integrator.d.ts +343 -0
  258. package/dist/integrator.d.ts.map +1 -0
  259. package/dist/integrator.js +400 -0
  260. package/dist/integrator.js.map +1 -0
  261. package/dist/isolation.d.ts +219 -0
  262. package/dist/isolation.d.ts.map +1 -0
  263. package/dist/isolation.js +261 -0
  264. package/dist/isolation.js.map +1 -0
  265. package/dist/issue-provider.d.ts +349 -0
  266. package/dist/issue-provider.d.ts.map +1 -0
  267. package/dist/issue-provider.js +360 -0
  268. package/dist/issue-provider.js.map +1 -0
  269. package/dist/item-lock.d.ts +626 -0
  270. package/dist/item-lock.d.ts.map +1 -0
  271. package/dist/item-lock.js +1381 -0
  272. package/dist/item-lock.js.map +1 -0
  273. package/dist/item-path.d.ts +49 -0
  274. package/dist/item-path.d.ts.map +1 -0
  275. package/dist/item-path.js +66 -0
  276. package/dist/item-path.js.map +1 -0
  277. package/dist/ledger-lint.d.ts +129 -0
  278. package/dist/ledger-lint.d.ts.map +1 -0
  279. package/dist/ledger-lint.js +249 -0
  280. package/dist/ledger-lint.js.map +1 -0
  281. package/dist/ledger-read.d.ts +357 -0
  282. package/dist/ledger-read.d.ts.map +1 -0
  283. package/dist/ledger-read.js +442 -0
  284. package/dist/ledger-read.js.map +1 -0
  285. package/dist/ledger-write.d.ts +330 -0
  286. package/dist/ledger-write.d.ts.map +1 -0
  287. package/dist/ledger-write.js +411 -0
  288. package/dist/ledger-write.js.map +1 -0
  289. package/dist/lifecycle-gather.d.ts +30 -0
  290. package/dist/lifecycle-gather.d.ts.map +1 -0
  291. package/dist/lifecycle-gather.js +205 -0
  292. package/dist/lifecycle-gather.js.map +1 -0
  293. package/dist/lifecycle-pools.d.ts +180 -0
  294. package/dist/lifecycle-pools.d.ts.map +1 -0
  295. package/dist/lifecycle-pools.js +78 -0
  296. package/dist/lifecycle-pools.js.map +1 -0
  297. package/dist/merge-question-surfacer.d.ts +166 -0
  298. package/dist/merge-question-surfacer.d.ts.map +1 -0
  299. package/dist/merge-question-surfacer.js +297 -0
  300. package/dist/merge-question-surfacer.js.map +1 -0
  301. package/dist/mint-adr.d.ts +126 -0
  302. package/dist/mint-adr.d.ts.map +1 -0
  303. package/dist/mint-adr.js +257 -0
  304. package/dist/mint-adr.js.map +1 -0
  305. package/dist/mirror-pool-scan.d.ts +125 -0
  306. package/dist/mirror-pool-scan.d.ts.map +1 -0
  307. package/dist/mirror-pool-scan.js +104 -0
  308. package/dist/mirror-pool-scan.js.map +1 -0
  309. package/dist/needs-attention.d.ts +341 -0
  310. package/dist/needs-attention.d.ts.map +1 -0
  311. package/dist/needs-attention.js +900 -0
  312. package/dist/needs-attention.js.map +1 -0
  313. package/dist/orphan-sidecar.d.ts +79 -0
  314. package/dist/orphan-sidecar.d.ts.map +1 -0
  315. package/dist/orphan-sidecar.js +71 -0
  316. package/dist/orphan-sidecar.js.map +1 -0
  317. package/dist/output.d.ts +48 -0
  318. package/dist/output.d.ts.map +1 -0
  319. package/dist/output.js +66 -0
  320. package/dist/output.js.map +1 -0
  321. package/dist/pi-harness.d.ts +179 -0
  322. package/dist/pi-harness.d.ts.map +1 -0
  323. package/dist/pi-harness.js +342 -0
  324. package/dist/pi-harness.js.map +1 -0
  325. package/dist/placement.d.ts +99 -0
  326. package/dist/placement.d.ts.map +1 -0
  327. package/dist/placement.js +67 -0
  328. package/dist/placement.js.map +1 -0
  329. package/dist/prd-to-spec.d.ts +315 -0
  330. package/dist/prd-to-spec.d.ts.map +1 -0
  331. package/dist/prd-to-spec.js +684 -0
  332. package/dist/prd-to-spec.js.map +1 -0
  333. package/dist/prepare.d.ts +121 -0
  334. package/dist/prepare.d.ts.map +1 -0
  335. package/dist/prepare.js +140 -0
  336. package/dist/prepare.js.map +1 -0
  337. package/dist/prompt.d.ts +360 -0
  338. package/dist/prompt.d.ts.map +1 -0
  339. package/dist/prompt.js +499 -0
  340. package/dist/prompt.js.map +1 -0
  341. package/dist/protocol/ADR-FORMAT.md +47 -0
  342. package/dist/protocol/CLAIM-PROTOCOL.md +217 -0
  343. package/dist/protocol/REVIEW-PROTOCOL.md +119 -0
  344. package/dist/protocol/SURFACE-PROTOCOL.md +121 -0
  345. package/dist/protocol/TASKING-PROTOCOL.md +122 -0
  346. package/dist/protocol/WORK-CONTRACT.md +276 -0
  347. package/dist/protocol/spec-template.md +71 -0
  348. package/dist/protocol/task-template.md +65 -0
  349. package/dist/readiness.d.ts +66 -0
  350. package/dist/readiness.d.ts.map +1 -0
  351. package/dist/readiness.js +36 -0
  352. package/dist/readiness.js.map +1 -0
  353. package/dist/reap-branches.d.ts +102 -0
  354. package/dist/reap-branches.d.ts.map +1 -0
  355. package/dist/reap-branches.js +149 -0
  356. package/dist/reap-branches.js.map +1 -0
  357. package/dist/recover-isolated.d.ts +72 -0
  358. package/dist/recover-isolated.d.ts.map +1 -0
  359. package/dist/recover-isolated.js +188 -0
  360. package/dist/recover-isolated.js.map +1 -0
  361. package/dist/registry.d.ts +172 -0
  362. package/dist/registry.d.ts.map +1 -0
  363. package/dist/registry.js +296 -0
  364. package/dist/registry.js.map +1 -0
  365. package/dist/repo-config.d.ts +201 -0
  366. package/dist/repo-config.d.ts.map +1 -0
  367. package/dist/repo-config.js +414 -0
  368. package/dist/repo-config.js.map +1 -0
  369. package/dist/repo-key.d.ts +20 -0
  370. package/dist/repo-key.d.ts.map +1 -0
  371. package/dist/repo-key.js +68 -0
  372. package/dist/repo-key.js.map +1 -0
  373. package/dist/repo-mirror.d.ts +177 -0
  374. package/dist/repo-mirror.d.ts.map +1 -0
  375. package/dist/repo-mirror.js +271 -0
  376. package/dist/repo-mirror.js.map +1 -0
  377. package/dist/retry-backoff.d.ts +90 -0
  378. package/dist/retry-backoff.d.ts.map +1 -0
  379. package/dist/retry-backoff.js +98 -0
  380. package/dist/retry-backoff.js.map +1 -0
  381. package/dist/review-gate.d.ts +173 -0
  382. package/dist/review-gate.d.ts.map +1 -0
  383. package/dist/review-gate.js +261 -0
  384. package/dist/review-gate.js.map +1 -0
  385. package/dist/review-verdict.d.ts +149 -0
  386. package/dist/review-verdict.d.ts.map +1 -0
  387. package/dist/review-verdict.js +332 -0
  388. package/dist/review-verdict.js.map +1 -0
  389. package/dist/run.d.ts +221 -0
  390. package/dist/run.d.ts.map +1 -0
  391. package/dist/run.js +963 -0
  392. package/dist/run.js.map +1 -0
  393. package/dist/scan.d.ts +308 -0
  394. package/dist/scan.d.ts.map +1 -0
  395. package/dist/scan.js +374 -0
  396. package/dist/scan.js.map +1 -0
  397. package/dist/select-order.d.ts +75 -0
  398. package/dist/select-order.d.ts.map +1 -0
  399. package/dist/select-order.js +108 -0
  400. package/dist/select-order.js.map +1 -0
  401. package/dist/select-priority.d.ts +188 -0
  402. package/dist/select-priority.d.ts.map +1 -0
  403. package/dist/select-priority.js +80 -0
  404. package/dist/select-priority.js.map +1 -0
  405. package/dist/select.d.ts +25 -0
  406. package/dist/select.d.ts.map +1 -0
  407. package/dist/select.js +43 -0
  408. package/dist/select.js.map +1 -0
  409. package/dist/session-path.d.ts +36 -0
  410. package/dist/session-path.d.ts.map +1 -0
  411. package/dist/session-path.js +129 -0
  412. package/dist/session-path.js.map +1 -0
  413. package/dist/sidecar-apply.d.ts +83 -0
  414. package/dist/sidecar-apply.d.ts.map +1 -0
  415. package/dist/sidecar-apply.js +111 -0
  416. package/dist/sidecar-apply.js.map +1 -0
  417. package/dist/sidecar.d.ts +245 -0
  418. package/dist/sidecar.d.ts.map +1 -0
  419. package/dist/sidecar.js +481 -0
  420. package/dist/sidecar.js.map +1 -0
  421. package/dist/slug-namespace.d.ts +204 -0
  422. package/dist/slug-namespace.d.ts.map +1 -0
  423. package/dist/slug-namespace.js +229 -0
  424. package/dist/slug-namespace.js.map +1 -0
  425. package/dist/spec-complete.d.ts +44 -0
  426. package/dist/spec-complete.d.ts.map +1 -0
  427. package/dist/spec-complete.js +69 -0
  428. package/dist/spec-complete.js.map +1 -0
  429. package/dist/start.d.ts +97 -0
  430. package/dist/start.d.ts.map +1 -0
  431. package/dist/start.js +633 -0
  432. package/dist/start.js.map +1 -0
  433. package/dist/status.d.ts +199 -0
  434. package/dist/status.d.ts.map +1 -0
  435. package/dist/status.js +228 -0
  436. package/dist/status.js.map +1 -0
  437. package/dist/surface-gate.d.ts +162 -0
  438. package/dist/surface-gate.d.ts.map +1 -0
  439. package/dist/surface-gate.js +206 -0
  440. package/dist/surface-gate.js.map +1 -0
  441. package/dist/surface-persist.d.ts +86 -0
  442. package/dist/surface-persist.d.ts.map +1 -0
  443. package/dist/surface-persist.js +129 -0
  444. package/dist/surface-persist.js.map +1 -0
  445. package/dist/tasker-review-loop.d.ts +249 -0
  446. package/dist/tasker-review-loop.d.ts.map +1 -0
  447. package/dist/tasker-review-loop.js +369 -0
  448. package/dist/tasker-review-loop.js.map +1 -0
  449. package/dist/tasking-eligibility.d.ts +74 -0
  450. package/dist/tasking-eligibility.d.ts.map +1 -0
  451. package/dist/tasking-eligibility.js +52 -0
  452. package/dist/tasking-eligibility.js.map +1 -0
  453. package/dist/tasking-lock.d.ts +111 -0
  454. package/dist/tasking-lock.d.ts.map +1 -0
  455. package/dist/tasking-lock.js +256 -0
  456. package/dist/tasking-lock.js.map +1 -0
  457. package/dist/tasking.d.ts +275 -0
  458. package/dist/tasking.d.ts.map +1 -0
  459. package/dist/tasking.js +952 -0
  460. package/dist/tasking.js.map +1 -0
  461. package/dist/triage-gate.d.ts +127 -0
  462. package/dist/triage-gate.d.ts.map +1 -0
  463. package/dist/triage-gate.js +139 -0
  464. package/dist/triage-gate.js.map +1 -0
  465. package/dist/triage-persist.d.ts +163 -0
  466. package/dist/triage-persist.d.ts.map +1 -0
  467. package/dist/triage-persist.js +387 -0
  468. package/dist/triage-persist.js.map +1 -0
  469. package/dist/verdict-json.d.ts +32 -0
  470. package/dist/verdict-json.d.ts.map +1 -0
  471. package/dist/verdict-json.js +74 -0
  472. package/dist/verdict-json.js.map +1 -0
  473. package/dist/verify-workflow-template.d.ts +60 -0
  474. package/dist/verify-workflow-template.d.ts.map +1 -0
  475. package/dist/verify-workflow-template.js +126 -0
  476. package/dist/verify-workflow-template.js.map +1 -0
  477. package/dist/verify.d.ts +60 -0
  478. package/dist/verify.d.ts.map +1 -0
  479. package/dist/verify.js +62 -0
  480. package/dist/verify.js.map +1 -0
  481. package/dist/watch-session.d.ts +112 -0
  482. package/dist/watch-session.d.ts.map +1 -0
  483. package/dist/watch-session.js +347 -0
  484. package/dist/watch-session.js.map +1 -0
  485. package/dist/work-layout.d.ts +198 -0
  486. package/dist/work-layout.d.ts.map +1 -0
  487. package/dist/work-layout.js +217 -0
  488. package/dist/work-layout.js.map +1 -0
  489. package/dist/work-on.d.ts +154 -0
  490. package/dist/work-on.d.ts.map +1 -0
  491. package/dist/work-on.js +387 -0
  492. package/dist/work-on.js.map +1 -0
  493. package/dist/workspace.d.ts +224 -0
  494. package/dist/workspace.d.ts.map +1 -0
  495. package/dist/workspace.js +325 -0
  496. package/dist/workspace.js.map +1 -0
  497. package/package.json +46 -2
  498. package/src/advance-ci-template.ts +203 -0
  499. package/src/advance-classify.ts +197 -0
  500. package/src/advance-drivers.ts +414 -0
  501. package/src/advance-isolated.ts +432 -0
  502. package/src/advance-lifecycle-template.ts +791 -0
  503. package/src/advance-loop-driver.ts +745 -0
  504. package/src/advance-treeless-publish.ts +177 -0
  505. package/src/advance.ts +1564 -0
  506. package/src/advancing-lock.ts +988 -0
  507. package/src/agent-launch.ts +137 -0
  508. package/src/agent-stop.ts +361 -0
  509. package/src/apply-decide.ts +242 -0
  510. package/src/apply-merge-action.ts +502 -0
  511. package/src/apply-persist.ts +518 -0
  512. package/src/arbiter.ts +372 -0
  513. package/src/brand.ts +111 -0
  514. package/src/buildable-body.ts +196 -0
  515. package/src/categorise.ts +158 -0
  516. package/src/claim-cas.ts +513 -0
  517. package/src/cli-spinner.ts +225 -0
  518. package/src/cli.ts +4369 -0
  519. package/src/close-job-template.ts +236 -0
  520. package/src/close-job.ts +319 -0
  521. package/src/complete.ts +1379 -0
  522. package/src/concurrency.ts +151 -0
  523. package/src/config-override.ts +116 -0
  524. package/src/config.ts +883 -0
  525. package/src/continue-branch.ts +542 -0
  526. package/src/cwd-section.ts +392 -0
  527. package/src/decision-engine.ts +272 -0
  528. package/src/detect.ts +124 -0
  529. package/src/do-autopick.ts +223 -0
  530. package/src/do-config.ts +589 -0
  531. package/src/do-remote-auto.ts +197 -0
  532. package/src/do.ts +2623 -0
  533. package/src/drop-source.ts +194 -0
  534. package/src/eligibility.ts +79 -0
  535. package/src/env-config.ts +305 -0
  536. package/src/failure-cause.ts +142 -0
  537. package/src/format.ts +313 -0
  538. package/src/frontmatter.ts +485 -0
  539. package/src/gate-readiness.ts +147 -0
  540. package/src/gc.ts +510 -0
  541. package/src/gh-failure.ts +53 -0
  542. package/src/git.ts +186 -0
  543. package/src/github.ts +468 -0
  544. package/src/harness.ts +355 -0
  545. package/src/identity.ts +322 -0
  546. package/src/index.ts +785 -0
  547. package/src/install-ci-branch-protection.ts +255 -0
  548. package/src/install-ci-capabilities/advance-lifecycle.ts +34 -0
  549. package/src/install-ci-capabilities/close-job.ts +32 -0
  550. package/src/install-ci-capabilities/example-noop.ts +24 -0
  551. package/src/install-ci-capabilities/intake.ts +34 -0
  552. package/src/install-ci-capabilities/verify.ts +33 -0
  553. package/src/install-ci-core.ts +1088 -0
  554. package/src/install-ci-github.ts +376 -0
  555. package/src/install-ci.ts +552 -0
  556. package/src/intake-event.ts +102 -0
  557. package/src/intake-marker.ts +195 -0
  558. package/src/intake-triage.ts +138 -0
  559. package/src/intake-trigger-template.ts +591 -0
  560. package/src/intake.ts +2445 -0
  561. package/src/integration-core.ts +3065 -0
  562. package/src/integrator.ts +771 -0
  563. package/src/isolation.ts +484 -0
  564. package/src/issue-provider.ts +733 -0
  565. package/src/item-lock.ts +1858 -0
  566. package/src/item-path.ts +75 -0
  567. package/src/ledger-lint.ts +332 -0
  568. package/src/ledger-read.ts +924 -0
  569. package/src/ledger-write.ts +865 -0
  570. package/src/lifecycle-gather.ts +298 -0
  571. package/src/lifecycle-pools.ts +250 -0
  572. package/src/merge-question-surfacer.ts +496 -0
  573. package/src/mint-adr.ts +362 -0
  574. package/src/mirror-pool-scan.ts +240 -0
  575. package/src/needs-attention.ts +1506 -0
  576. package/src/orphan-sidecar.ts +150 -0
  577. package/src/output.ts +89 -0
  578. package/src/pi-harness.ts +403 -0
  579. package/src/placement.ts +131 -0
  580. package/src/prd-to-spec.ts +1023 -0
  581. package/src/prepare.ts +230 -0
  582. package/src/prompt.ts +760 -0
  583. package/src/readiness.ts +98 -0
  584. package/src/reap-branches.ts +278 -0
  585. package/src/recover-isolated.ts +276 -0
  586. package/src/registry.ts +475 -0
  587. package/src/repo-config.ts +550 -0
  588. package/src/repo-key.ts +74 -0
  589. package/src/repo-mirror.ts +367 -0
  590. package/src/retry-backoff.ts +130 -0
  591. package/src/review-gate.ts +389 -0
  592. package/src/review-verdict.ts +422 -0
  593. package/src/run.ts +1430 -0
  594. package/src/scan.ts +611 -0
  595. package/src/select-order.ts +143 -0
  596. package/src/select-priority.ts +266 -0
  597. package/src/select.ts +62 -0
  598. package/src/session-path.ts +153 -0
  599. package/src/sidecar-apply.ts +216 -0
  600. package/src/sidecar.ts +700 -0
  601. package/src/slug-namespace.ts +367 -0
  602. package/src/spec-complete.ts +118 -0
  603. package/src/start.ts +974 -0
  604. package/src/status.ts +441 -0
  605. package/src/surface-gate.ts +337 -0
  606. package/src/surface-persist.ts +241 -0
  607. package/src/tasker-review-loop.ts +671 -0
  608. package/src/tasking-eligibility.ts +114 -0
  609. package/src/tasking-lock.ts +416 -0
  610. package/src/tasking.ts +1438 -0
  611. package/src/triage-gate.ts +248 -0
  612. package/src/triage-persist.ts +570 -0
  613. package/src/verdict-json.ts +73 -0
  614. package/src/verify-workflow-template.ts +159 -0
  615. package/src/verify.ts +123 -0
  616. package/src/watch-session.ts +397 -0
  617. package/src/work-layout.ts +262 -0
  618. package/src/work-on.ts +660 -0
  619. package/src/workspace.ts +502 -0
package/src/work-on.ts ADDED
@@ -0,0 +1,660 @@
1
+ import {cpSync, existsSync, mkdirSync, rmSync, statSync} from 'node:fs';
2
+ import {homedir} from 'node:os';
3
+ import {dirname, join, resolve} from 'node:path';
4
+ import {git, runAsync, type RunResult} from './git.js';
5
+ import {performClaim} from './claim-cas.js';
6
+ import {
7
+ encodeRepoKey,
8
+ ensureMirror,
9
+ fetchMirrorMain,
10
+ mirrorPath,
11
+ } from './repo-mirror.js';
12
+ import {
13
+ defaultConfigPath,
14
+ loadConfig,
15
+ saveConfig,
16
+ type Config,
17
+ } from './config.js';
18
+ import {brand} from './brand.js';
19
+ import {workBranchRef} from './slug-namespace.js';
20
+ import type {InteractiveLauncher} from './harness.js';
21
+
22
+ /**
23
+ * `dorfl work-on` — the HUMAN command to claim a task and create an
24
+ * isolated **worktree in a human-friendly location**, so a person can open their
25
+ * editor and work several tasks in parallel without juggling branches in one
26
+ * checkout. It is the human counterpart to the runner's job worktrees
27
+ * (`workspace.ts`): it is NEVER used by agents, so it never carries the human's
28
+ * secrets into an agent context (see `--copy`).
29
+ *
30
+ * Two invocation forms — the ONLY intended difference between them is **where the
31
+ * worktree's files live**; the claim, the integration semantics, and the
32
+ * starting commit are IDENTICAL:
33
+ *
34
+ * work-on <slug> in-repo: the arbiter remote/URL is inferred from
35
+ * the current repo; the claim runs in that repo.
36
+ * work-on --remote <r> <slug> remote: ensure a hub mirror for <r> (creating
37
+ * it via repo-mirror if absent, exactly like
38
+ * agents do), then claim against it from a
39
+ * throwaway worktree. The remote target is a FLAG
40
+ * (consistent with `do --remote`), not positional.
41
+ *
42
+ * BOTH forms: claim the slug, then ALWAYS `git fetch` and branch the worktree off
43
+ * the **freshly-fetched `<arbiter>/main`** — never a possibly-stale local ref.
44
+ * THIS GUARANTEE is what makes the two forms equivalent: the same slug yields
45
+ * equivalent work either way (same starting commit).
46
+ *
47
+ * The worktree lives under the configured `humanWorktreesDir`
48
+ * (`<dir>/<key>/<slug>/` on branch `work/<slug>`) — prompted + saved on first use,
49
+ * with a sensible suggestion but no silent default, and NEVER under
50
+ * `~/.dorfl/` (that is the agents' area; `work-on` is human-only).
51
+ *
52
+ * A binary cannot `cd` its parent shell, so on success it prints the worktree path
53
+ * + a `cd` hint; `--print-dir` emits the path ONLY (stdout) so the human can
54
+ * install a shell function that actually cd's them:
55
+ *
56
+ * work-on() { cd "$(dorfl work-on "$@" --print-dir)"; }
57
+ */
58
+
59
+ /** The semantic outcome of a `work-on` invocation. */
60
+ export type WorkOnOutcome =
61
+ | 'created' // claimed and created the worktree
62
+ | 'refused' // a readiness refusal (unmet blockedBy without override)
63
+ | 'lost' // lost the claim race (propagated from claim) — NO worktree
64
+ | 'contended' // claim push kept being rejected — NO worktree
65
+ | 'usage-error'; // usage / environment problem
66
+
67
+ export interface WorkOnOptions {
68
+ /** The slug to work on (`work/backlog/<slug>.md`). Required. */
69
+ slug: string;
70
+ /**
71
+ * Remote mode: the remote spec/URL to mirror via `repo-mirror`. When given,
72
+ * `work-on --remote <r> <slug>` ensures a hub mirror (creating it if absent)
73
+ * and claims against it. When omitted, in-repo mode: the arbiter is inferred
74
+ * from `cwd`.
75
+ */
76
+ remote?: string;
77
+ /** The current working directory (in-repo mode resolves the arbiter from it). */
78
+ cwd: string;
79
+ /**
80
+ * Name of the arbiter git remote in `cwd` (in-repo mode only). Defaults to
81
+ * `origin`. Ignored in remote mode (the mirror's own `origin` is used).
82
+ */
83
+ arbiter?: string;
84
+ /**
85
+ * Override the readiness guard (`--ignore-not-ready`): claim despite
86
+ * an unmet `blockedBy`, and silence the `needsAnswers` warning. Forwarded to
87
+ * the claim CAS's human-path guard.
88
+ */
89
+ override?: boolean;
90
+ /**
91
+ * Comma-separated glob-free filenames (gitignored, untracked files like
92
+ * `.env.local,.env`) to COPY into the new worktree so the project is runnable.
93
+ * Copy, not symlink (tooling-safe). Source = the current repo in-repo mode; in
94
+ * remote mode there is no implicit source, so `--copy` REQUIRES `copyFrom`.
95
+ */
96
+ copy?: string;
97
+ /**
98
+ * The explicit source dir for `--copy` in remote mode (`--copy-from <path>`).
99
+ * Required when `copy` is set in remote mode; ignored otherwise.
100
+ */
101
+ copyFrom?: string;
102
+ /** The execution working area for hub mirrors (config `workspacesDir`). */
103
+ workspacesDir?: string;
104
+ /**
105
+ * The human worktree root (config `humanWorktreesDir`). When already
106
+ * configured this is used directly; when undefined, `promptForRoot` is invoked
107
+ * to obtain + SAVE it (first-use prompt). Tests pass it directly to avoid TTY.
108
+ */
109
+ humanWorktreesDir?: string;
110
+ /**
111
+ * First-use prompt for the human worktree root. Called only when
112
+ * `humanWorktreesDir` is undefined (in config + options). Receives a sensible
113
+ * SUGGESTION; returns the chosen absolute path (or '' to abort). The CLI wires
114
+ * a readline prompt; tests inject a stub.
115
+ */
116
+ promptForRoot?: (suggestion: string) => Promise<string> | string;
117
+ /**
118
+ * Persist a newly-prompted `humanWorktreesDir`. The CLI wires this to
119
+ * `saveConfig` at `configPath`; tests can inject a spy or a no-op.
120
+ */
121
+ saveRoot?: (dir: string) => void;
122
+ /**
123
+ * `--agent` (task `agent-interactive-launch`): after the human worktree is
124
+ * created, launch the configured harness INTERACTIVELY in THAT worktree — a
125
+ * foreground session the human drives (no prepared prompt). Injected as a thin
126
+ * launcher so `work-on.ts` stays decoupled from `createHarness`: the CLI wires
127
+ * it to the resolved harness's `launchInteractive` (model/session resolved
128
+ * there). Omitted ⇒ work-on creates the worktree and prints the cd hint (its
129
+ * historical behaviour). It is NOT a tracked job (decision #3): no job record,
130
+ * no gate — after exit the human drives `complete`/`requeue`.
131
+ */
132
+ launchInteractive?: InteractiveLauncher;
133
+ /** Environment for child git processes (identity etc.). */
134
+ env?: NodeJS.ProcessEnv;
135
+ /** Sink for human-readable progress + the security notice (stderr). */
136
+ note?: (message: string) => void;
137
+ }
138
+
139
+ export interface WorkOnResult {
140
+ exitCode: 0 | 1 | 2 | 3;
141
+ outcome: WorkOnOutcome;
142
+ /** Absolute path to the created worktree (only on success). */
143
+ dir?: string;
144
+ /** The work branch checked out there (`work/<slug>`). */
145
+ branch?: string;
146
+ /** The resolved arbiter URL the worktree branches from. */
147
+ arbiterUrl?: string;
148
+ /** The starting commit (freshly-fetched `<arbiter>/main`) the worktree is cut from. */
149
+ startCommit?: string;
150
+ /** Files copied in via `--copy` (basenames), in order. */
151
+ copied?: string[];
152
+ /** Human-readable summary of the terminal condition. */
153
+ message: string;
154
+ }
155
+
156
+ const DEFAULT_ARBITER = 'origin';
157
+
158
+ /** Raised for usage/environment errors (exit 1, outcome 'usage-error'). */
159
+ class WorkOnUsageError extends Error {}
160
+
161
+ /**
162
+ * Run the `work-on` ritual. Never throws for the expected lost/contended/refused
163
+ * cases — those are returned with the appropriate exit code and NO worktree.
164
+ * Usage/environment problems surface as exit 1.
165
+ */
166
+ export async function performWorkOn(
167
+ options: WorkOnOptions,
168
+ ): Promise<WorkOnResult> {
169
+ const note = options.note ?? (() => {});
170
+ try {
171
+ return await runWorkOn(options, note);
172
+ } catch (err) {
173
+ const message = err instanceof Error ? err.message : String(err);
174
+ return {exitCode: 1, outcome: 'usage-error', message};
175
+ }
176
+ }
177
+
178
+ async function runWorkOn(
179
+ options: WorkOnOptions,
180
+ note: (m: string) => void,
181
+ ): Promise<WorkOnResult> {
182
+ const slug = options.slug;
183
+ if (!slug) {
184
+ throw new WorkOnUsageError(
185
+ 'missing <slug>. usage: dorfl work-on <slug> [--remote <r>]',
186
+ );
187
+ }
188
+ const env = options.env;
189
+ const workspacesDir =
190
+ options.workspacesDir ?? join(homedir(), brand.workdirName);
191
+
192
+ // The human worktree root: configured value wins; otherwise prompt + save on
193
+ // first use (a sensible suggestion, NEVER a silent default; never under
194
+ // ~/.dorfl/).
195
+ const root = await resolveHumanWorktreesRoot(options, note);
196
+
197
+ // Resolve the arbiter URL + a CLAIM CONTEXT (a checkout with the arbiter
198
+ // remote where the CAS runs). The ONLY thing that differs between the two
199
+ // forms is the claim context's location; both fetch + branch off the fresh
200
+ // arbiter main, so the starting commit is identical.
201
+ const ctx = await resolveClaimContext({
202
+ slug,
203
+ remote: options.remote,
204
+ cwd: options.cwd,
205
+ arbiter: options.arbiter ?? DEFAULT_ARBITER,
206
+ workspacesDir,
207
+ env,
208
+ note,
209
+ });
210
+
211
+ try {
212
+ // Claim FIRST. On a lost/contended/refused claim, create NO worktree
213
+ // (clean failure, exactly like `claim`).
214
+ const claim = await performClaim({
215
+ slug,
216
+ cwd: ctx.claimCwd,
217
+ arbiter: ctx.claimArbiter,
218
+ env,
219
+ humanPath: true,
220
+ override: options.override,
221
+ note,
222
+ });
223
+ if (claim.exitCode !== 0) {
224
+ const outcome: WorkOnOutcome =
225
+ claim.outcome === 'not-ready'
226
+ ? 'refused'
227
+ : claim.exitCode === 2
228
+ ? 'lost'
229
+ : claim.exitCode === 3
230
+ ? 'contended'
231
+ : 'usage-error';
232
+ return {exitCode: claim.exitCode, outcome, message: claim.message};
233
+ }
234
+
235
+ // The claim landed. Create the human worktree off the FRESHLY-FETCHED
236
+ // arbiter main (which now includes the claim move). We branch from the hub
237
+ // mirror's main so both forms share one branching primitive.
238
+ const created = createHumanWorktree({
239
+ slug,
240
+ root,
241
+ arbiterUrl: ctx.arbiterUrl,
242
+ workspacesDir,
243
+ env,
244
+ });
245
+
246
+ // Copy named gitignored files (copy, not symlink) so the project is
247
+ // runnable; print a security notice. Source resolved per mode.
248
+ const copied = copyGitignoredFiles({
249
+ copy: options.copy,
250
+ copyFrom: options.copyFrom,
251
+ remoteMode: ctx.remoteMode,
252
+ inRepoSource: options.cwd,
253
+ destDir: created.dir,
254
+ note,
255
+ });
256
+
257
+ const message = `Created worktree for '${slug}' at ${created.dir} (branch ${created.branch}).`;
258
+ note(message);
259
+ note(`To start working: cd ${created.dir}`);
260
+
261
+ // `--agent` (task `agent-interactive-launch`): launch the configured harness
262
+ // INTERACTIVELY in the freshly-created worktree so the human can immediately
263
+ // drive the agent there. It is NOT a tracked job (decision #3): no record, no
264
+ // gate — it blocks in the foreground until the human exits, then control
265
+ // returns and they drive `complete`/`requeue`. The model/session are bound in
266
+ // the CLI's launcher closure (config lives there).
267
+ if (options.launchInteractive) {
268
+ note(`Launching the configured harness interactively in ${created.dir}.`);
269
+ options.launchInteractive({slug, dir: created.dir, env});
270
+ }
271
+
272
+ return {
273
+ exitCode: 0,
274
+ outcome: 'created',
275
+ dir: created.dir,
276
+ branch: created.branch,
277
+ arbiterUrl: ctx.arbiterUrl,
278
+ startCommit: created.startCommit,
279
+ copied,
280
+ message,
281
+ };
282
+ } finally {
283
+ ctx.cleanup();
284
+ }
285
+ }
286
+
287
+ interface ClaimContext {
288
+ /** Resolved arbiter URL (canonical; used for the hub key + worktree). */
289
+ arbiterUrl: string;
290
+ /** The checkout where the claim CAS runs. */
291
+ claimCwd: string;
292
+ /** The arbiter remote NAME valid inside `claimCwd`. */
293
+ claimArbiter: string;
294
+ /** True iff this is remote mode (no implicit `--copy` source). */
295
+ remoteMode: boolean;
296
+ /** Tear down any throwaway claim worktree. */
297
+ cleanup(): void;
298
+ }
299
+
300
+ /**
301
+ * Resolve where + how the claim CAS runs, per mode. The starting commit is
302
+ * guaranteed identical because the claim and the worktree both branch off the
303
+ * freshly-fetched arbiter main; only the claim context's LOCATION differs.
304
+ */
305
+ async function resolveClaimContext(params: {
306
+ slug: string;
307
+ remote: string | undefined;
308
+ cwd: string;
309
+ arbiter: string;
310
+ workspacesDir: string;
311
+ env: NodeJS.ProcessEnv | undefined;
312
+ note: (m: string) => void;
313
+ }): Promise<ClaimContext> {
314
+ const {remote, cwd, arbiter, workspacesDir, env, note} = params;
315
+
316
+ if (remote === undefined || remote.trim() === '') {
317
+ // IN-REPO: infer the arbiter URL from the current repo; claim runs here.
318
+ if ((await gitSoft(['rev-parse', '--git-dir'], cwd, env)).status !== 0) {
319
+ throw new WorkOnUsageError(
320
+ 'not inside a git repository (run inside a clone, or use the remote form: work-on --remote <r> <slug>)',
321
+ );
322
+ }
323
+ const url = await gitSoft(['remote', 'get-url', arbiter], cwd, env);
324
+ if (url.status !== 0) {
325
+ throw new WorkOnUsageError(
326
+ `no git remote named '${arbiter}' (set one, or pass --arbiter)`,
327
+ );
328
+ }
329
+ return {
330
+ arbiterUrl: url.stdout.trim(),
331
+ claimCwd: cwd,
332
+ claimArbiter: arbiter,
333
+ remoteMode: false,
334
+ cleanup: () => {},
335
+ };
336
+ }
337
+
338
+ // REMOTE: ensure a hub mirror for <remote> (create if absent, like agents do)
339
+ // so the worktree can later branch off it. The claim itself needs a normal
340
+ // (non-bare) checkout with an `origin/main` tracking ref + a work tree to
341
+ // commit in, which a bare mirror does not provide — so the claim runs in a
342
+ // THROWAWAY clone of the arbiter URL (removed in cleanup either way).
343
+ //
344
+ // When the mirror already exists we refresh ONLY `main` (non-pruning): a
345
+ // pruning mirror-fetch here would delete the LOCAL-ONLY `work/<slug>` branches
346
+ // of other live human worktrees off this hub.
347
+ const hubPath = mirrorPath(workspacesDir, remote);
348
+ let mirrorUrl: string;
349
+ if (existsSync(hubPath)) {
350
+ mirrorUrl = ensureMirrorUrl(remote);
351
+ fetchMirrorMain(hubPath, env);
352
+ note(`Reusing hub mirror for ${mirrorUrl} at ${hubPath}.`);
353
+ } else {
354
+ const created = ensureMirror({url: remote, workspacesDir, env});
355
+ mirrorUrl = created.url;
356
+ note(`Created hub mirror for ${mirrorUrl} at ${created.path}.`);
357
+ }
358
+
359
+ const claimDir = join(
360
+ workspacesDir,
361
+ 'claim',
362
+ `${encodeRepoKey(mirrorUrl).split('/').join('__')}__${params.slug}`,
363
+ );
364
+ rmSync(claimDir, {recursive: true, force: true});
365
+ mkdirSync(dirname(claimDir), {recursive: true});
366
+ // A lightweight clone whose `origin` IS the arbiter URL — the claim CAS fetches
367
+ // `origin` + branches off `origin/main`, exactly as in the in-repo form.
368
+ git(['clone', '--quiet', mirrorUrl, claimDir], dirname(claimDir), {env});
369
+
370
+ return {
371
+ arbiterUrl: mirrorUrl,
372
+ claimCwd: claimDir,
373
+ claimArbiter: 'origin',
374
+ remoteMode: true,
375
+ cleanup: () => rmSync(claimDir, {recursive: true, force: true}),
376
+ };
377
+ }
378
+
379
+ interface CreatedWorktree {
380
+ dir: string;
381
+ branch: string;
382
+ startCommit: string;
383
+ }
384
+
385
+ /**
386
+ * Create the human worktree at `<root>/<key>/<slug>/` on `work/<slug>`, branched
387
+ * off the freshly-fetched hub-mirror `main`. The mirror is (re-)fetched here too,
388
+ * so even in in-repo mode the worktree is cut from the latest arbiter main — the
389
+ * same-starting-commit guarantee.
390
+ */
391
+ function createHumanWorktree(params: {
392
+ slug: string;
393
+ root: string;
394
+ arbiterUrl: string;
395
+ workspacesDir: string;
396
+ env: NodeJS.ProcessEnv | undefined;
397
+ }): CreatedWorktree {
398
+ const {slug, root, arbiterUrl, workspacesDir, env} = params;
399
+
400
+ // Ensure the hub mirror exists, then refresh ONLY `main` to the latest arbiter
401
+ // tip (which, post-claim, includes the claim move). We do NOT use the pruning
402
+ // mirror-fetch here: this mirror also holds the LOCAL-ONLY `work/<slug>`
403
+ // branches of other live human worktrees, and a pruning fetch would delete
404
+ // (and corrupt) them. fetchMirrorMain refreshes main without touching them.
405
+ const hubPath = mirrorPath(workspacesDir, arbiterUrl);
406
+ let mirrorUrl = arbiterUrl;
407
+ if (existsSync(hubPath)) {
408
+ fetchMirrorMain(hubPath, env);
409
+ } else {
410
+ mirrorUrl = ensureMirror({url: arbiterUrl, workspacesDir, env}).url;
411
+ }
412
+
413
+ const key = encodeRepoKey(mirrorUrl);
414
+ // `work-on` builds a TASK in a worktree — the task-namespaced work branch.
415
+ const branch = workBranchRef('task', slug);
416
+ const dir = join(root, key, slug);
417
+
418
+ // Clear any stale worktree/branch for this slug (idempotent re-run).
419
+ clearWorktree(hubPath, dir, env);
420
+ pruneBranch(hubPath, branch, env);
421
+
422
+ mkdirSync(dirname(dir), {recursive: true});
423
+ git(['worktree', 'add', '--quiet', '-b', branch, dir, 'main'], hubPath, {
424
+ env,
425
+ });
426
+
427
+ const startCommit = git(['rev-parse', 'HEAD'], dir, {env}).trim();
428
+ return {dir, branch, startCommit};
429
+ }
430
+
431
+ /**
432
+ * Copy the named gitignored files into the new worktree (COPY, not symlink). A
433
+ * fresh worktree has NONE of your untracked files, so a project that needs e.g.
434
+ * `.env.local` to run won't run without this. Prints a one-line SECURITY NOTICE
435
+ * naming what was copied and that secrets now live in a second location.
436
+ *
437
+ * Source: the current repo in in-repo mode; in remote mode there is no implicit
438
+ * source, so `--copy` REQUIRES `--copy-from <path>`.
439
+ */
440
+ function copyGitignoredFiles(params: {
441
+ copy: string | undefined;
442
+ copyFrom: string | undefined;
443
+ remoteMode: boolean;
444
+ inRepoSource: string;
445
+ destDir: string;
446
+ note: (m: string) => void;
447
+ }): string[] {
448
+ const {copy, copyFrom, remoteMode, inRepoSource, destDir, note} = params;
449
+ if (!copy || copy.trim() === '') {
450
+ return [];
451
+ }
452
+
453
+ const patterns = copy
454
+ .split(',')
455
+ .map((p) => p.trim())
456
+ .filter((p) => p.length > 0);
457
+ if (patterns.length === 0) {
458
+ return [];
459
+ }
460
+
461
+ const source = resolveCopySource({remoteMode, copyFrom, inRepoSource});
462
+
463
+ const copied: string[] = [];
464
+ const missing: string[] = [];
465
+ for (const name of patterns) {
466
+ const from = join(source, name);
467
+ if (!existsSync(from)) {
468
+ missing.push(name);
469
+ continue;
470
+ }
471
+ const to = join(destDir, name);
472
+ mkdirSync(dirname(to), {recursive: true});
473
+ // Copy (recursively for dirs); explicitly NOT a symlink, so the worktree is
474
+ // tooling-safe and self-contained.
475
+ cpSync(from, to, {recursive: true});
476
+ copied.push(name);
477
+ }
478
+
479
+ if (missing.length > 0) {
480
+ note(`!! --copy: not found in ${source} (skipped): ${missing.join(', ')}.`);
481
+ }
482
+ if (copied.length > 0) {
483
+ note(
484
+ `!! SECURITY NOTICE: copied ${copied.length} gitignored file(s) into the ` +
485
+ `new worktree: ${copied.join(', ')}. These are real copies (not ` +
486
+ `symlinks) — secrets now live in a SECOND location (${destDir}). ` +
487
+ 'Treat that worktree like the source for credential hygiene.',
488
+ );
489
+ }
490
+ return copied;
491
+ }
492
+
493
+ /** Resolve the source dir for `--copy`, enforcing `--copy-from` in remote mode. */
494
+ function resolveCopySource(params: {
495
+ remoteMode: boolean;
496
+ copyFrom: string | undefined;
497
+ inRepoSource: string;
498
+ }): string {
499
+ const {remoteMode, copyFrom, inRepoSource} = params;
500
+ if (remoteMode) {
501
+ if (!copyFrom || copyFrom.trim() === '') {
502
+ throw new WorkOnUsageError(
503
+ '--copy needs an explicit source in remote mode: pass --copy-from <path> ' +
504
+ '(there is no current repo to copy gitignored files from).',
505
+ );
506
+ }
507
+ const src = resolve(copyFrom);
508
+ if (!existsSync(src) || !statSync(src).isDirectory()) {
509
+ throw new WorkOnUsageError(
510
+ `--copy-from path does not exist or is not a directory: ${src}`,
511
+ );
512
+ }
513
+ return src;
514
+ }
515
+ return inRepoSource;
516
+ }
517
+
518
+ /**
519
+ * Resolve the human worktree root: a configured `humanWorktreesDir` wins; else
520
+ * prompt for it (a sensible SUGGESTION, no silent default) and SAVE it, so the
521
+ * human is asked exactly once. NEVER allow a root under `~/.dorfl/` (that
522
+ * is the agents' execution area — work-on is human-only).
523
+ */
524
+ async function resolveHumanWorktreesRoot(
525
+ options: WorkOnOptions,
526
+ note: (m: string) => void,
527
+ ): Promise<string> {
528
+ const configured = options.humanWorktreesDir;
529
+ if (configured && configured.trim() !== '') {
530
+ return assertHumanRoot(resolve(configured));
531
+ }
532
+
533
+ if (!options.promptForRoot) {
534
+ throw new WorkOnUsageError(
535
+ 'humanWorktreesDir is not configured and no prompt is available; set ' +
536
+ '`humanWorktreesDir` in config (a human-only worktree root, NOT under ' +
537
+ '~/.dorfl/).',
538
+ );
539
+ }
540
+
541
+ const suggestion = suggestHumanWorktreesDir();
542
+ const answeredRaw = await options.promptForRoot(suggestion);
543
+ const answered = (answeredRaw ?? '').trim();
544
+ if (answered === '') {
545
+ throw new WorkOnUsageError(
546
+ 'no humanWorktreesDir provided — aborting (work-on needs a worktree root).',
547
+ );
548
+ }
549
+ const chosen = assertHumanRoot(resolve(answered));
550
+ if (options.saveRoot) {
551
+ options.saveRoot(chosen);
552
+ note(`Saved humanWorktreesDir = ${chosen} to config.`);
553
+ }
554
+ return chosen;
555
+ }
556
+
557
+ /**
558
+ * Reject a human worktree root under `~/.dorfl/` (the agents' area, ADR
559
+ * §3): work-on is human-only and must never share that space.
560
+ */
561
+ function assertHumanRoot(dir: string): string {
562
+ const agentArea = join(homedir(), brand.workdirName);
563
+ const normalized = dir.endsWith('/') ? dir.slice(0, -1) : dir;
564
+ if (normalized === agentArea || normalized.startsWith(agentArea + '/')) {
565
+ throw new WorkOnUsageError(
566
+ `humanWorktreesDir must NOT be under ${agentArea} (that is the agents' ` +
567
+ 'execution area; work-on is human-only). Choose a separate human dir.',
568
+ );
569
+ }
570
+ return dir;
571
+ }
572
+
573
+ /**
574
+ * A sensible SUGGESTION for the human worktree root. Deliberately uses a name
575
+ * (`~/worktrees`) that does NOT share a prefix with the usual code dir
576
+ * (`~/dev/...`), so shell tab-completion on the code dir never collides with it.
577
+ * This is only a suggestion — there is no silent default; the human confirms.
578
+ */
579
+ export function suggestHumanWorktreesDir(): string {
580
+ return join(homedir(), 'worktrees');
581
+ }
582
+
583
+ /** Remove a worktree registration from the hub (git's own removal, never rm -rf). */
584
+ function clearWorktree(
585
+ mirrorPath: string,
586
+ dir: string,
587
+ env: NodeJS.ProcessEnv | undefined,
588
+ ): void {
589
+ if (existsSync(dir)) {
590
+ try {
591
+ git(['worktree', 'remove', '--force', dir], mirrorPath, {env});
592
+ } catch {
593
+ // not a registered worktree — fall through to a plain rm + prune
594
+ rmSync(dir, {recursive: true, force: true});
595
+ }
596
+ }
597
+ try {
598
+ git(['worktree', 'prune'], mirrorPath, {env});
599
+ } catch {
600
+ // best-effort
601
+ }
602
+ }
603
+
604
+ /** Drop a branch from the hub if it exists (idempotent re-run safety). */
605
+ function pruneBranch(
606
+ mirrorPath: string,
607
+ branch: string,
608
+ env: NodeJS.ProcessEnv | undefined,
609
+ ): void {
610
+ try {
611
+ git(['branch', '-D', branch], mirrorPath, {env});
612
+ } catch {
613
+ // branch may not exist
614
+ }
615
+ }
616
+
617
+ /**
618
+ * The canonical arbiter URL a mirror tracks for a given `remote` spec. The
619
+ * mirror is cloned from `remote`, so the tracked URL is just the trimmed spec
620
+ * (the same value {@link ensureMirror} would resolve from `url`).
621
+ */
622
+ function ensureMirrorUrl(remote: string): string {
623
+ return remote.trim();
624
+ }
625
+
626
+ /** Run git, returning the raw result (no throw) — for soft checks. */
627
+ function gitSoft(
628
+ args: string[],
629
+ cwd: string,
630
+ env: NodeJS.ProcessEnv | undefined,
631
+ ): Promise<RunResult> {
632
+ return runAsync('git', args, cwd, {env});
633
+ }
634
+
635
+ /**
636
+ * Resolve `humanWorktreesDir` + `configPath` for the CLI: read config from
637
+ * `configPath` and surface its `humanWorktreesDir` (undefined ⇒ first use). The
638
+ * CLI wires the prompt/save around this; kept here so the wiring is testable.
639
+ */
640
+ export function loadHumanWorktreesDir(
641
+ configPath: string = defaultConfigPath(),
642
+ ): {
643
+ dir: string | undefined;
644
+ config: Config;
645
+ } {
646
+ const config = loadConfig(configPath);
647
+ return {dir: config.humanWorktreesDir, config};
648
+ }
649
+
650
+ /** Save a chosen `humanWorktreesDir` back to `configPath`, preserving the rest. */
651
+ export function persistHumanWorktreesDir(
652
+ dir: string,
653
+ configPath: string = defaultConfigPath(),
654
+ ): void {
655
+ const config = loadConfig(configPath);
656
+ saveConfig({...config, humanWorktreesDir: dir}, configPath);
657
+ }
658
+
659
+ // Re-export for callers that want the encoding without importing repo-mirror.
660
+ export {encodeRepoKey};