dorfl 0.1.2 → 0.2.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 (364) hide show
  1. package/dist/advance-drivers.d.ts +1 -1
  2. package/dist/advance-drivers.d.ts.map +1 -1
  3. package/dist/advance-drivers.js +15 -3
  4. package/dist/advance-drivers.js.map +1 -1
  5. package/dist/advance-lifecycle-template.d.ts.map +1 -1
  6. package/dist/advance-lifecycle-template.js +76 -4
  7. package/dist/advance-lifecycle-template.js.map +1 -1
  8. package/dist/advance-treeless-publish.d.ts +23 -0
  9. package/dist/advance-treeless-publish.d.ts.map +1 -1
  10. package/dist/advance-treeless-publish.js +41 -0
  11. package/dist/advance-treeless-publish.js.map +1 -1
  12. package/dist/advance.d.ts +59 -7
  13. package/dist/advance.d.ts.map +1 -1
  14. package/dist/advance.js +389 -82
  15. package/dist/advance.js.map +1 -1
  16. package/dist/advancing-lock.d.ts +30 -2
  17. package/dist/advancing-lock.d.ts.map +1 -1
  18. package/dist/advancing-lock.js +50 -0
  19. package/dist/advancing-lock.js.map +1 -1
  20. package/dist/agent-launch.d.ts +12 -0
  21. package/dist/agent-launch.d.ts.map +1 -1
  22. package/dist/agent-launch.js +22 -12
  23. package/dist/agent-launch.js.map +1 -1
  24. package/dist/agent-stop.d.ts +40 -2
  25. package/dist/agent-stop.d.ts.map +1 -1
  26. package/dist/agent-stop.js +30 -2
  27. package/dist/agent-stop.js.map +1 -1
  28. package/dist/apply-decide.d.ts +17 -3
  29. package/dist/apply-decide.d.ts.map +1 -1
  30. package/dist/apply-decide.js +36 -7
  31. package/dist/apply-decide.js.map +1 -1
  32. package/dist/apply-merge-action.d.ts +17 -5
  33. package/dist/apply-merge-action.d.ts.map +1 -1
  34. package/dist/apply-merge-action.js +43 -8
  35. package/dist/apply-merge-action.js.map +1 -1
  36. package/dist/apply-persist.d.ts +57 -26
  37. package/dist/apply-persist.d.ts.map +1 -1
  38. package/dist/apply-persist.js +166 -37
  39. package/dist/apply-persist.js.map +1 -1
  40. package/dist/apply-stuck-action.d.ts +151 -0
  41. package/dist/apply-stuck-action.d.ts.map +1 -0
  42. package/dist/apply-stuck-action.js +125 -0
  43. package/dist/apply-stuck-action.js.map +1 -0
  44. package/dist/brand.d.ts +12 -1
  45. package/dist/brand.d.ts.map +1 -1
  46. package/dist/brand.js +2 -1
  47. package/dist/brand.js.map +1 -1
  48. package/dist/cli-spinner.d.ts +1 -1
  49. package/dist/cli-spinner.js +1 -1
  50. package/dist/cli.d.ts +10 -0
  51. package/dist/cli.d.ts.map +1 -1
  52. package/dist/cli.js +320 -63
  53. package/dist/cli.js.map +1 -1
  54. package/dist/close-job-template.js +1 -1
  55. package/dist/complete.d.ts +6 -3
  56. package/dist/complete.d.ts.map +1 -1
  57. package/dist/complete.js +91 -37
  58. package/dist/complete.js.map +1 -1
  59. package/dist/config.d.ts +55 -9
  60. package/dist/config.d.ts.map +1 -1
  61. package/dist/config.js +56 -4
  62. package/dist/config.js.map +1 -1
  63. package/dist/continue-branch.d.ts.map +1 -1
  64. package/dist/continue-branch.js +22 -0
  65. package/dist/continue-branch.js.map +1 -1
  66. package/dist/decision-engine.d.ts +38 -10
  67. package/dist/decision-engine.d.ts.map +1 -1
  68. package/dist/decision-engine.js +10 -6
  69. package/dist/decision-engine.js.map +1 -1
  70. package/dist/do-autopick.d.ts.map +1 -1
  71. package/dist/do-autopick.js +11 -1
  72. package/dist/do-autopick.js.map +1 -1
  73. package/dist/do-config.d.ts +1 -1
  74. package/dist/do.d.ts +49 -56
  75. package/dist/do.d.ts.map +1 -1
  76. package/dist/do.js +419 -30
  77. package/dist/do.js.map +1 -1
  78. package/dist/env-config.d.ts.map +1 -1
  79. package/dist/env-config.js +12 -4
  80. package/dist/env-config.js.map +1 -1
  81. package/dist/failure-cause.d.ts +3 -2
  82. package/dist/failure-cause.d.ts.map +1 -1
  83. package/dist/failure-cause.js +28 -1
  84. package/dist/failure-cause.js.map +1 -1
  85. package/dist/format.d.ts +6 -6
  86. package/dist/format.d.ts.map +1 -1
  87. package/dist/format.js +10 -27
  88. package/dist/format.js.map +1 -1
  89. package/dist/frontmatter.d.ts +16 -4
  90. package/dist/frontmatter.d.ts.map +1 -1
  91. package/dist/frontmatter.js +27 -1
  92. package/dist/frontmatter.js.map +1 -1
  93. package/dist/gc.d.ts +65 -6
  94. package/dist/gc.d.ts.map +1 -1
  95. package/dist/gc.js +126 -9
  96. package/dist/gc.js.map +1 -1
  97. package/dist/github.d.ts +14 -0
  98. package/dist/github.d.ts.map +1 -1
  99. package/dist/github.js +73 -0
  100. package/dist/github.js.map +1 -1
  101. package/dist/harness.d.ts +25 -0
  102. package/dist/harness.d.ts.map +1 -1
  103. package/dist/harness.js.map +1 -1
  104. package/dist/index.d.ts +4 -1
  105. package/dist/index.d.ts.map +1 -1
  106. package/dist/index.js +2 -1
  107. package/dist/index.js.map +1 -1
  108. package/dist/install-ci-branch-protection.d.ts +132 -38
  109. package/dist/install-ci-branch-protection.d.ts.map +1 -1
  110. package/dist/install-ci-branch-protection.js +190 -48
  111. package/dist/install-ci-branch-protection.js.map +1 -1
  112. package/dist/install-ci-core.d.ts +21 -1
  113. package/dist/install-ci-core.d.ts.map +1 -1
  114. package/dist/install-ci-core.js +10 -3
  115. package/dist/install-ci-core.js.map +1 -1
  116. package/dist/install-ci-github.d.ts +32 -0
  117. package/dist/install-ci-github.d.ts.map +1 -1
  118. package/dist/install-ci-github.js +73 -0
  119. package/dist/install-ci-github.js.map +1 -1
  120. package/dist/install-skills.d.ts +123 -0
  121. package/dist/install-skills.d.ts.map +1 -0
  122. package/dist/install-skills.js +100 -0
  123. package/dist/install-skills.js.map +1 -0
  124. package/dist/intake-trigger-template.js +1 -1
  125. package/dist/intake.d.ts +17 -4
  126. package/dist/intake.d.ts.map +1 -1
  127. package/dist/intake.js +23 -7
  128. package/dist/intake.js.map +1 -1
  129. package/dist/integration-core.d.ts +10 -7
  130. package/dist/integration-core.d.ts.map +1 -1
  131. package/dist/integration-core.js +174 -60
  132. package/dist/integration-core.js.map +1 -1
  133. package/dist/integrator.d.ts +1 -1
  134. package/dist/integrator.d.ts.map +1 -1
  135. package/dist/integrator.js +19 -3
  136. package/dist/integrator.js.map +1 -1
  137. package/dist/isolation.d.ts +2 -2
  138. package/dist/isolation.d.ts.map +1 -1
  139. package/dist/isolation.js +9 -0
  140. package/dist/isolation.js.map +1 -1
  141. package/dist/item-lock.d.ts +196 -129
  142. package/dist/item-lock.d.ts.map +1 -1
  143. package/dist/item-lock.js +329 -254
  144. package/dist/item-lock.js.map +1 -1
  145. package/dist/ledger-write.d.ts +31 -26
  146. package/dist/ledger-write.d.ts.map +1 -1
  147. package/dist/ledger-write.js +100 -122
  148. package/dist/ledger-write.js.map +1 -1
  149. package/dist/lifecycle-gather.d.ts +17 -0
  150. package/dist/lifecycle-gather.d.ts.map +1 -1
  151. package/dist/lifecycle-gather.js +7 -1
  152. package/dist/lifecycle-gather.js.map +1 -1
  153. package/dist/lifecycle-pools.d.ts +40 -3
  154. package/dist/lifecycle-pools.d.ts.map +1 -1
  155. package/dist/lifecycle-pools.js +26 -6
  156. package/dist/lifecycle-pools.js.map +1 -1
  157. package/dist/merge-question-surfacer.d.ts +15 -1
  158. package/dist/merge-question-surfacer.d.ts.map +1 -1
  159. package/dist/merge-question-surfacer.js +18 -3
  160. package/dist/merge-question-surfacer.js.map +1 -1
  161. package/dist/migrate-stuck-locks.d.ts +129 -0
  162. package/dist/migrate-stuck-locks.d.ts.map +1 -0
  163. package/dist/migrate-stuck-locks.js +355 -0
  164. package/dist/migrate-stuck-locks.js.map +1 -0
  165. package/dist/needs-attention.d.ts +293 -16
  166. package/dist/needs-attention.d.ts.map +1 -1
  167. package/dist/needs-attention.js +532 -57
  168. package/dist/needs-attention.js.map +1 -1
  169. package/dist/orphan-sidecar.d.ts +8 -4
  170. package/dist/orphan-sidecar.d.ts.map +1 -1
  171. package/dist/orphan-sidecar.js +35 -2
  172. package/dist/orphan-sidecar.js.map +1 -1
  173. package/dist/pi-harness.d.ts +16 -0
  174. package/dist/pi-harness.d.ts.map +1 -1
  175. package/dist/pi-harness.js +82 -2
  176. package/dist/pi-harness.js.map +1 -1
  177. package/dist/placement.d.ts +3 -3
  178. package/dist/placement.js +1 -1
  179. package/dist/prd-to-spec.d.ts.map +1 -1
  180. package/dist/prd-to-spec.js +9 -5
  181. package/dist/prd-to-spec.js.map +1 -1
  182. package/dist/protocol/CLAIM-PROTOCOL.md +17 -10
  183. package/dist/protocol/REVIEW-PROTOCOL.md +4 -1
  184. package/dist/protocol/SURFACE-PROTOCOL.md +16 -2
  185. package/dist/protocol/TASKING-PROTOCOL.md +3 -1
  186. package/dist/protocol/WORK-CONTRACT.md +22 -18
  187. package/dist/protocol/task-template.md +1 -1
  188. package/dist/reap-branches.d.ts +12 -9
  189. package/dist/reap-branches.d.ts.map +1 -1
  190. package/dist/reap-branches.js +25 -7
  191. package/dist/reap-branches.js.map +1 -1
  192. package/dist/recover-isolated.d.ts +12 -0
  193. package/dist/recover-isolated.d.ts.map +1 -1
  194. package/dist/recover-isolated.js +5 -0
  195. package/dist/recover-isolated.js.map +1 -1
  196. package/dist/repo-config.d.ts +23 -2
  197. package/dist/repo-config.d.ts.map +1 -1
  198. package/dist/repo-config.js +53 -7
  199. package/dist/repo-config.js.map +1 -1
  200. package/dist/repo-mirror.d.ts.map +1 -1
  201. package/dist/repo-mirror.js +18 -2
  202. package/dist/repo-mirror.js.map +1 -1
  203. package/dist/review-verdict.js +1 -1
  204. package/dist/review-verdict.js.map +1 -1
  205. package/dist/run.d.ts +1 -1
  206. package/dist/run.d.ts.map +1 -1
  207. package/dist/run.js +54 -19
  208. package/dist/run.js.map +1 -1
  209. package/dist/scan.d.ts +17 -8
  210. package/dist/scan.d.ts.map +1 -1
  211. package/dist/scan.js +22 -8
  212. package/dist/scan.js.map +1 -1
  213. package/dist/select-priority.d.ts +2 -2
  214. package/dist/select-priority.js +1 -1
  215. package/dist/select-priority.js.map +1 -1
  216. package/dist/sidecar-apply.js +1 -1
  217. package/dist/sidecar-apply.js.map +1 -1
  218. package/dist/sidecar.d.ts +45 -10
  219. package/dist/sidecar.d.ts.map +1 -1
  220. package/dist/sidecar.js +82 -2
  221. package/dist/sidecar.js.map +1 -1
  222. package/dist/skills/answer-questions/SKILL.md +89 -0
  223. package/dist/skills/capture-signal/SKILL.md +52 -0
  224. package/dist/skills/convert-from-prd-to-spec/SKILL.md +90 -0
  225. package/dist/skills/drive-tasks/SKILL.md +218 -0
  226. package/dist/skills/from-idea/SKILL.md +83 -0
  227. package/dist/skills/merge-prs/SKILL.md +70 -0
  228. package/dist/skills/orchestrate/SKILL.md +101 -0
  229. package/dist/skills/promote/SKILL.md +35 -0
  230. package/dist/skills/review/SKILL.md +16 -0
  231. package/dist/skills/setup/SKILL.md +258 -0
  232. package/dist/skills/setup/protocol/ADR-FORMAT.md +47 -0
  233. package/dist/skills/setup/protocol/CLAIM-PROTOCOL.md +224 -0
  234. package/dist/skills/setup/protocol/REVIEW-PROTOCOL.md +122 -0
  235. package/dist/skills/setup/protocol/SURFACE-PROTOCOL.md +135 -0
  236. package/dist/skills/setup/protocol/TASKING-PROTOCOL.md +124 -0
  237. package/dist/skills/setup/protocol/WORK-CONTRACT.md +280 -0
  238. package/dist/skills/setup/protocol/spec-template.md +71 -0
  239. package/dist/skills/setup/protocol/task-template.md +65 -0
  240. package/dist/skills/surface-questions/SKILL.md +16 -0
  241. package/dist/skills/to-spec/SKILL.md +34 -0
  242. package/dist/skills/to-task/SKILL.md +19 -0
  243. package/dist/skills/triage-observations/SKILL.md +78 -0
  244. package/dist/skills/work/SKILL.md +51 -0
  245. package/dist/slug-namespace.d.ts +5 -5
  246. package/dist/slug-namespace.js +5 -5
  247. package/dist/slug-namespace.js.map +1 -1
  248. package/dist/spec-complete.d.ts.map +1 -1
  249. package/dist/spec-complete.js +2 -3
  250. package/dist/spec-complete.js.map +1 -1
  251. package/dist/start.d.ts.map +1 -1
  252. package/dist/start.js +51 -57
  253. package/dist/start.js.map +1 -1
  254. package/dist/surface-gate.d.ts.map +1 -1
  255. package/dist/surface-gate.js +10 -3
  256. package/dist/surface-gate.js.map +1 -1
  257. package/dist/surface-persist.js +1 -1
  258. package/dist/surface-persist.js.map +1 -1
  259. package/dist/tasker-review-loop.d.ts +4 -3
  260. package/dist/tasker-review-loop.d.ts.map +1 -1
  261. package/dist/tasker-review-loop.js.map +1 -1
  262. package/dist/tasking-lock.d.ts +2 -2
  263. package/dist/tasking-lock.d.ts.map +1 -1
  264. package/dist/tasking-lock.js +53 -32
  265. package/dist/tasking-lock.js.map +1 -1
  266. package/dist/tasking.d.ts +40 -6
  267. package/dist/tasking.d.ts.map +1 -1
  268. package/dist/tasking.js +224 -12
  269. package/dist/tasking.js.map +1 -1
  270. package/dist/triage-persist.d.ts +10 -6
  271. package/dist/triage-persist.d.ts.map +1 -1
  272. package/dist/triage-persist.js +34 -4
  273. package/dist/triage-persist.js.map +1 -1
  274. package/dist/vendor/incur/agents.d.ts +58 -0
  275. package/dist/vendor/incur/agents.d.ts.map +1 -0
  276. package/dist/vendor/incur/agents.js +343 -0
  277. package/dist/vendor/incur/agents.js.map +1 -0
  278. package/dist/verify-workflow-template.js +1 -1
  279. package/dist/watch-session.d.ts +11 -3
  280. package/dist/watch-session.d.ts.map +1 -1
  281. package/dist/watch-session.js +94 -7
  282. package/dist/watch-session.js.map +1 -1
  283. package/dist/work-layout.d.ts +7 -3
  284. package/dist/work-layout.d.ts.map +1 -1
  285. package/dist/work-layout.js +6 -3
  286. package/dist/work-layout.js.map +1 -1
  287. package/dist/workspace.d.ts +1 -1
  288. package/package.json +2 -2
  289. package/src/advance-drivers.ts +16 -3
  290. package/src/advance-lifecycle-template.ts +89 -4
  291. package/src/advance-treeless-publish.ts +45 -0
  292. package/src/advance.ts +467 -87
  293. package/src/advancing-lock.ts +96 -1
  294. package/src/agent-launch.ts +37 -12
  295. package/src/agent-stop.ts +60 -2
  296. package/src/apply-decide.ts +36 -7
  297. package/src/apply-merge-action.ts +45 -7
  298. package/src/apply-persist.ts +228 -54
  299. package/src/apply-stuck-action.ts +260 -0
  300. package/src/brand.ts +14 -2
  301. package/src/cli-spinner.ts +1 -1
  302. package/src/cli.ts +401 -70
  303. package/src/close-job-template.ts +1 -1
  304. package/src/complete.ts +110 -52
  305. package/src/config.ts +107 -13
  306. package/src/continue-branch.ts +22 -0
  307. package/src/decision-engine.ts +55 -17
  308. package/src/do-autopick.ts +12 -1
  309. package/src/do-config.ts +1 -1
  310. package/src/do.ts +511 -38
  311. package/src/env-config.ts +12 -4
  312. package/src/failure-cause.ts +30 -1
  313. package/src/format.ts +10 -30
  314. package/src/frontmatter.ts +35 -5
  315. package/src/gc.ts +172 -9
  316. package/src/github.ts +78 -0
  317. package/src/harness.ts +25 -0
  318. package/src/index.ts +10 -0
  319. package/src/install-ci-branch-protection.ts +282 -57
  320. package/src/install-ci-core.ts +30 -3
  321. package/src/install-ci-github.ts +86 -0
  322. package/src/install-skills.ts +166 -0
  323. package/src/intake-trigger-template.ts +1 -1
  324. package/src/intake.ts +46 -11
  325. package/src/integration-core.ts +199 -65
  326. package/src/integrator.ts +22 -9
  327. package/src/isolation.ts +11 -2
  328. package/src/item-lock.ts +485 -341
  329. package/src/ledger-write.ts +135 -150
  330. package/src/lifecycle-gather.ts +29 -6
  331. package/src/lifecycle-pools.ts +67 -9
  332. package/src/merge-question-surfacer.ts +28 -4
  333. package/src/migrate-stuck-locks.ts +451 -0
  334. package/src/needs-attention.ts +857 -84
  335. package/src/orphan-sidecar.ts +47 -6
  336. package/src/pi-harness.ts +82 -2
  337. package/src/placement.ts +3 -3
  338. package/src/prd-to-spec.ts +13 -5
  339. package/src/reap-branches.ts +38 -14
  340. package/src/recover-isolated.ts +17 -0
  341. package/src/repo-config.ts +55 -6
  342. package/src/repo-mirror.ts +23 -1
  343. package/src/review-verdict.ts +1 -1
  344. package/src/run.ts +64 -18
  345. package/src/scan.ts +22 -8
  346. package/src/select-priority.ts +3 -3
  347. package/src/sidecar-apply.ts +1 -1
  348. package/src/sidecar.ts +138 -11
  349. package/src/slug-namespace.ts +7 -7
  350. package/src/spec-complete.ts +2 -3
  351. package/src/start.ts +53 -59
  352. package/src/surface-gate.ts +10 -3
  353. package/src/surface-persist.ts +1 -1
  354. package/src/tasker-review-loop.ts +4 -3
  355. package/src/tasking-lock.ts +52 -36
  356. package/src/tasking.ts +261 -17
  357. package/src/triage-persist.ts +56 -12
  358. package/src/vendor/incur/LICENSE +21 -0
  359. package/src/vendor/incur/README.md +19 -0
  360. package/src/vendor/incur/agents.ts +392 -0
  361. package/src/verify-workflow-template.ts +1 -1
  362. package/src/watch-session.ts +102 -7
  363. package/src/work-layout.ts +6 -3
  364. package/src/workspace.ts +1 -1
@@ -0,0 +1,166 @@
1
+ /**
2
+ * The dorfl-side wrapper around the VENDORED `incur/agents.ts` (MIT — see
3
+ * `./vendor/incur/`, and the ADR `docs/adr/skill-install-vendors-incur-agents-map.md`).
4
+ * The vendored file provides the ~22-harness destination map, `detect()`, and
5
+ * `install(sourceDir, options)` that copies each skill into the canonical
6
+ * `~/.agents/skills/` and symlinks non-universal harnesses. This module is the
7
+ * dorfl-authored code AROUND it: it resolves the packaged-skills SOURCE dir
8
+ * and drives the vendored `install()` — nothing more. Keep the vendored file
9
+ * untouched (byte-close to upstream) so future incur updates stay a mechanical
10
+ * re-copy.
11
+ *
12
+ * ## Decisions (in-scope, non-obvious)
13
+ *
14
+ * - **Sibling script over merged.** The build-time packaging lives in
15
+ * `scripts/vendor-skills.mjs`, a SIBLING of the existing `vendor-protocol.mjs`
16
+ * rather than an appended block on it. The two scripts copy DIFFERENT concept
17
+ * sets (contract docs vs. hand-authored skills) into different dest subtrees;
18
+ * each has its own set that evolves independently. See the header of
19
+ * `vendor-skills.mjs` for the rationale (mirrors the wording here).
20
+ * - **Vendored file location.** `src/vendor/incur/agents.ts` (co-located with
21
+ * its MIT `LICENSE` + a `README.md` provenance note). Under `src/` so `tsc`
22
+ * compiles it into `dist/vendor/incur/agents.js`; under `vendor/incur/` so
23
+ * the upstream origin is CLEAR from the path, and a future re-copy is a
24
+ * drop-in overwrite. All dorfl wrapper code lives OUTSIDE that directory.
25
+ * - **Resolver home.** {@link resolveSkillsSourceDir} lives IN this module
26
+ * (not in `prompt.ts` next to `resolveProtocolDoc`) because "the packaged
27
+ * skills source" is a concept OWNED by skill-install; `resolveProtocolDoc`
28
+ * is owned by the runner's prompt-assembly. Same SHAPE, different concept —
29
+ * duplicating the small resolver body keeps the ownership boundary clean.
30
+ */
31
+
32
+ import {existsSync} from 'node:fs';
33
+ import {dirname, resolve} from 'node:path';
34
+ import {fileURLToPath} from 'node:url';
35
+ import {install, type Agent} from './vendor/incur/agents.js';
36
+
37
+ /**
38
+ * Locate the SOURCE directory of the vendored skills the installer copies
39
+ * from. Resolution order, highest authority first:
40
+ *
41
+ * 1. `override` — explicit, for tests / unusual layouts (short-circuits).
42
+ * 2. `dist/skills/` — a copy VENDORED inside this package (by the
43
+ * `vendor-skills` build step). The published-CLI primary: an installed
44
+ * CLI has no sibling monorepo-root `skills/` tree.
45
+ * 3. the legacy monorepo-relative `skills/` walk — DEV-only, kept LAST (it
46
+ * only resolves inside this dev monorepo; an installed CLI's walks escape
47
+ * into the consumer's filesystem \u2192 nothing there, which is why it cannot
48
+ * be the primary source).
49
+ *
50
+ * Mirrors the shape of {@link import('./prompt.js').resolveProtocolDoc} — the
51
+ * prefer-`dist/`-then-dev-walk order. Returns the first existing candidate;
52
+ * when nothing exists, returns the first candidate (the caller then hits a
53
+ * clean ENOENT rather than a silent no-op).
54
+ */
55
+ export function resolveSkillsSourceDir(override?: string): string {
56
+ if (override) {
57
+ return override;
58
+ }
59
+ const here = dirname(fileURLToPath(import.meta.url));
60
+ // here = .../packages/dorfl/{src,dist}.
61
+ const candidates: string[] = [
62
+ // 2. Package-vendored copy (published-CLI primary). From `src/` (tsx)
63
+ // `dist/` is a sibling; from `dist/` it is the dir itself.
64
+ resolve(here, '..', 'dist', 'skills'),
65
+ resolve(here, 'skills'),
66
+ // 3. Legacy monorepo-root walk \u2014 DEV-only, LAST.
67
+ resolve(here, '..', '..', '..', 'skills'),
68
+ resolve(here, '..', '..', '..', '..', 'skills'),
69
+ ];
70
+ for (const candidate of candidates) {
71
+ if (existsSync(candidate)) {
72
+ return candidate;
73
+ }
74
+ }
75
+ return candidates[0];
76
+ }
77
+
78
+ /**
79
+ * Options threaded through {@link installSkills} to the vendored `install()`.
80
+ * The shape mirrors incur's `install.Options` verbatim, plus a `sourceDir`
81
+ * override for the resolver seam. Everything is optional; a bare call
82
+ * `installSkills()` performs the "install every packaged skill, globally,
83
+ * into every detected harness" default.
84
+ */
85
+ export interface InstallSkillsOptions {
86
+ /**
87
+ * Override the resolved packaged-skills source dir. Tests pin this to a
88
+ * scratch dir with fake skill folders; production callers omit it and take
89
+ * whatever {@link resolveSkillsSourceDir} returns.
90
+ */
91
+ sourceDir?: string;
92
+ /**
93
+ * `false` \u21d2 project-local placement (canonical base is `<cwd>/.agents/skills/`,
94
+ * and non-universal harnesses use their PROJECT-relative dirs). Default
95
+ * `true` (or omitted) \u21d2 global placement under `~/.agents/skills/`.
96
+ */
97
+ global?: boolean;
98
+ /**
99
+ * Working directory for project-local installs. Ignored when `global` is not
100
+ * `false`. Defaults (in the vendored file) to `process.cwd()`.
101
+ */
102
+ cwd?: string;
103
+ /**
104
+ * Override the detected harnesses. Tests use this to force a deterministic
105
+ * set; production callers omit it and let the vendored `detect()` pick.
106
+ */
107
+ agents?: Agent[];
108
+ }
109
+
110
+ /**
111
+ * The per-harness install detail returned by the vendored `install()` (for
112
+ * NON-UNIVERSAL harnesses only \u2014 universal harnesses read from the canonical
113
+ * `.agents/skills/` directly and need no per-harness entry).
114
+ */
115
+ export interface InstalledAgent {
116
+ /** Harness display name (e.g. `'Claude Code'`, `'Windsurf'`). */
117
+ agent: string;
118
+ /** Absolute path the skill was placed at for this harness. */
119
+ path: string;
120
+ /** How the placement was materialised. Symlink is the norm; copy is the
121
+ * Windows/no-permission fallback. */
122
+ mode: 'symlink' | 'copy';
123
+ }
124
+
125
+ /** The report {@link installSkills} returns to its CLI caller. */
126
+ export interface InstallSkillsResult {
127
+ /**
128
+ * The SOURCE directory the vendored `install()` was driven from (the value
129
+ * {@link resolveSkillsSourceDir} chose). Included so `dorfl skills add`
130
+ * can print WHERE the skills were read from, and tests can assert the
131
+ * resolver picked what they expected.
132
+ */
133
+ sourceDir: string;
134
+ /** Canonical install paths (one per skill directory copied). */
135
+ paths: string[];
136
+ /** Per-harness placements for non-universal harnesses. */
137
+ agents: InstalledAgent[];
138
+ }
139
+
140
+ /**
141
+ * Resolve the packaged-skills source, drive the vendored `install()`, return
142
+ * the source + canonical paths + per-harness report. Global by default; pass
143
+ * `global: false` for project-local placement. Tests pin `sourceDir`/`agents`
144
+ * to keep the run hermetic; production callers pass nothing.
145
+ *
146
+ * The vendored `install()` reads `os.homedir()` (etc.) at MODULE LOAD, so
147
+ * shared-write isolation for `global: true` (the default) has to happen BEFORE
148
+ * this module is loaded (e.g. by pointing `HOME` at a scratch dir). Tests use
149
+ * `global: false` + a scratch `cwd` for the common path (no env dance needed);
150
+ * see `test/install-skills.test.ts`.
151
+ */
152
+ export function installSkills(
153
+ options: InstallSkillsOptions = {},
154
+ ): InstallSkillsResult {
155
+ const sourceDir = resolveSkillsSourceDir(options.sourceDir);
156
+ const result = install(sourceDir, {
157
+ global: options.global,
158
+ cwd: options.cwd,
159
+ agents: options.agents,
160
+ });
161
+ return {
162
+ sourceDir,
163
+ paths: result.paths,
164
+ agents: result.agents,
165
+ };
166
+ }
@@ -317,7 +317,7 @@ jobs:
317
317
  if: \${{ github.event.issue.number && !github.event.issue.pull_request }}
318
318
  runs-on: ubuntu-latest
319
319
  steps:
320
- - uses: actions/checkout@v4
320
+ - uses: actions/checkout@v5
321
321
  with:
322
322
  fetch-depth: 0
323
323
  - uses: ./.github/actions/dorfl-setup${setupWith}
package/src/intake.ts CHANGED
@@ -95,7 +95,7 @@ import {renderTaskBody, renderSpecBody} from './buildable-body.js';
95
95
  * table). EXPAND step (spec
96
96
  * `prd-to-spec-vocabulary-cutover-and-migration-command`): the `spec` outcome
97
97
  * names the "clear + coherent but >1 task" classification (a parent SPEC). HARD
98
- * CUTOVER (contract step): the legacy `prd` outcome token is GONE — the prompt
98
+ * CUTOVER (contract step): the legacy ''prd'' outcome token is GONE — the prompt
99
99
  * emits `spec` and the parser rejects any other token.
100
100
  */
101
101
  export type IntakeOutcome = 'ask' | 'task' | 'spec' | 'bounce';
@@ -256,7 +256,7 @@ export interface PerformIntakeOptions {
256
256
  * The PER-OUTCOME integration modes (spec `issue-intake` US #9) the emitted artifact integrates
257
257
  * THROUGH the shared core with. Because `intake` decides the artifact TYPE at
258
258
  * RUNTIME, the mode is keyed per type: an emitted task integrates with
259
- * `integration.task`, an emitted spec with `integration.prd` (`propose` =
259
+ * `integration.task`, an emitted spec with `integration.spec` (`propose` =
260
260
  * push the `work/<slug>` branch + open a PR, NO `main` touch; `merge` = land on
261
261
  * `main`). The CLI resolves this from the granular + aggregate flags via
262
262
  * {@link resolveIntakeIntegrationModes}; ask/bounce emit nothing, so the modes
@@ -267,7 +267,7 @@ export interface PerformIntakeOptions {
267
267
  * **The ORIGIN-TRUST verdict, passed IN** (task
268
268
  * `untrusted-origin-forces-build-propose`; the `--origin-trust <trusted|untrusted>`
269
269
  * CLI flag). `intake` STAMPS `origin: issue` + this `originTrust` onto every spec/
270
- * task it emits, so the author-trust signal SURVIVES the prd/task merge
270
+ * task it emits, so the author-trust signal SURVIVES the spec/task merge
271
271
  * boundary (a landed-on-main artifact otherwise erases how it was born, the
272
272
  * laundering gap). `intake` does NOT resolve trust itself: the verdict is CI's
273
273
  * POLICY, computed in the `intake.yml` shell from the SAME `author_association`
@@ -325,6 +325,19 @@ export interface PerformIntakeOptions {
325
325
  * must not act as the bot. Absent ⇒ ambient (today's behaviour).
326
326
  */
327
327
  identity?: Identity;
328
+ /**
329
+ * **The cross-job merge-serialiser CAS-retry cap** (config `mergeRetries`, spec
330
+ * `land-time-reverify-and-parallel-merge-ceiling` Story 5 / Applied Answer q1
331
+ * (a)). Threaded VERBATIM into the shared integrate core so a wide-matrix CI's
332
+ * raised cap reaches intake's task/spec emit land tail too (task
333
+ * `thread-merge-retries-cross-task-and-ratify-default`). Resolved ONCE at the
334
+ * entry point (the CLI) through the env + per-repo layers of the gate-family
335
+ * precedence chain — the `intake` command has NO `--merge-retries` flag today
336
+ * (the flag layer legitimately does not apply here; intake is
337
+ * unattended-CI-first, env + per-repo cover the need). Unset ⇒ the engine's
338
+ * `DEFAULT_MERGE_RETRIES = 1000` (byte-for-byte unchanged).
339
+ */
340
+ mergeRetries?: number;
328
341
  /** Environment for child git/agent processes (the AGENT-launch ambient env). */
329
342
  env?: NodeJS.ProcessEnv;
330
343
  /** Sink for human-readable progress notes. */
@@ -377,14 +390,14 @@ function specLandingToSide(
377
390
 
378
391
  /**
379
392
  * The emitted artifact TYPE `intake` decides at RUNTIME — a `task` verdict emits
380
- * `work/backlog/<slug>.md`, a `prd` verdict emits the spec file (`work/specs/ready/<slug>.md`). The two
393
+ * `work/backlog/<slug>.md`, a `spec` verdict emits the spec file (`work/specs/ready/<slug>.md`). The two
381
394
  * granular flag axes (`--merge-task`/`--propose-task` vs `--merge-spec`/
382
395
  * `--propose-spec`) are keyed on this. (ask/bounce emit NOTHING, so the modes are
383
396
  * no-ops for them.)
384
397
  */
385
398
  export type IntakeArtifactType = 'task' | 'spec';
386
- // `prd` → `spec` HARD CUTOVER: `'spec'` is the ONLY spec artifact type value; the
387
- // legacy `'prd'` alias is GONE (the contract task removed it).
399
+ // ''prd'' → `spec` HARD CUTOVER: `'spec'` is the ONLY spec artifact type value; the
400
+ // legacy ''prd'' alias is GONE (the contract task removed it).
388
401
 
389
402
  /**
390
403
  * The PER-OUTCOME integration mode FLAG SET (spec `issue-intake` US #9). Because
@@ -837,6 +850,9 @@ async function decideAndDispatch(
837
850
  cwd,
838
851
  arbiter,
839
852
  integration: modes.task,
853
+ // The resolved cross-job CAS-retry cap (config `mergeRetries`) — threaded so
854
+ // intake's lone-task emit lands under the same per-repo cap the build path uses.
855
+ mergeRetries: options.mergeRetries,
840
856
  // The origin-trust STAMP, passed IN (not resolved here): the emitted task
841
857
  // carries `origin: issue` + this verdict so the becomes-code checkpoint is
842
858
  // not laundered. Unset ⇒ unstamped (a local intake ⇒ human/trusted).
@@ -855,7 +871,7 @@ async function decideAndDispatch(
855
871
  note,
856
872
  });
857
873
  // The `spec` outcome is the parent-spec verdict; it dispatches through
858
- // `modes.spec`. HARD CUTOVER: the legacy `prd` outcome case is GONE.
874
+ // `modes.spec`. HARD CUTOVER: the legacy ''prd'' outcome case is GONE.
859
875
  case 'spec':
860
876
  return dispatchSpec({
861
877
  verdict,
@@ -863,6 +879,9 @@ async function decideAndDispatch(
863
879
  cwd,
864
880
  arbiter,
865
881
  integration: modes.spec,
882
+ // The resolved cross-job CAS-retry cap (config `mergeRetries`) — threaded so
883
+ // intake's spec emit lands under the same per-repo cap the build path uses.
884
+ mergeRetries: options.mergeRetries,
866
885
  // Same origin-trust stamp on the spec outcome (propagated onto its tasks
867
886
  // later by the tasker). Passed IN; not resolved here.
868
887
  originTrust: options.originTrust,
@@ -1041,6 +1060,8 @@ async function dispatchTask(params: {
1041
1060
  cwd: string;
1042
1061
  arbiter: string;
1043
1062
  integration: IntegrationMode;
1063
+ /** The resolved cross-job CAS-retry cap (undefined ⇒ engine default). */
1064
+ mergeRetries: number | undefined;
1044
1065
  /** The origin-trust stamp passed IN (unset ⇒ emit unstamped ⇒ human/trusted). */
1045
1066
  originTrust: OriginTrust | undefined;
1046
1067
  noPR: boolean | undefined;
@@ -1063,6 +1084,7 @@ async function dispatchTask(params: {
1063
1084
  cwd,
1064
1085
  arbiter,
1065
1086
  integration,
1087
+ mergeRetries,
1066
1088
  originTrust,
1067
1089
  noPR,
1068
1090
  providerInstance,
@@ -1185,6 +1207,12 @@ async function dispatchTask(params: {
1185
1207
  // EXPLICITLY-chosen mode proceeds as-is: a future `--merge-task` lands on main
1186
1208
  // (`merge` IS the auto-land mode, never downgraded).
1187
1209
  mode: integration,
1210
+ // The cross-job merge-serialiser CAS-retry cap (config `mergeRetries`) — the
1211
+ // git-alone floor of the cross-job land queue, resolved through the gate-
1212
+ // family precedence chain in the CLI and threaded here so intake's lone-task
1213
+ // emit lands under the same per-repo cap the build path uses. Unset ⇒ the
1214
+ // engine default (byte-for-byte unchanged).
1215
+ mergeRetries,
1188
1216
  noPR,
1189
1217
  providerInstance,
1190
1218
  type: 'feat',
@@ -1217,8 +1245,8 @@ async function dispatchTask(params: {
1217
1245
  }
1218
1246
 
1219
1247
  /**
1220
- * DISPATCH the `spec` outcome (canonical; the legacy `prd` outcome routes here too
1221
- * through the cutover): derive a content-derived slug, write the spec file
1248
+ * DISPATCH the `spec` outcome (the SOLE parent-spec outcome after the HARD CUTOVER;
1249
+ * the legacy ''prd'' outcome token is GONE): derive a content-derived slug, write the spec file
1222
1250
  * (`work/specs/ready/<slug>.md`) carrying `issue: N` (the loop-closure linkage the
1223
1251
  * close JOB reaches via `task.spec: → spec issue:`; on a fanned spec the number
1224
1252
  * lives ONLY on the spec — a fanned task uses `spec:`, NOT its own `issue:`, which
@@ -1234,6 +1262,8 @@ async function dispatchSpec(params: {
1234
1262
  cwd: string;
1235
1263
  arbiter: string;
1236
1264
  integration: IntegrationMode;
1265
+ /** The resolved cross-job CAS-retry cap (undefined ⇒ engine default). */
1266
+ mergeRetries: number | undefined;
1237
1267
  /** The origin-trust stamp passed IN (unset ⇒ emit unstamped ⇒ human/trusted). */
1238
1268
  originTrust: OriginTrust | undefined;
1239
1269
  noPR: boolean | undefined;
@@ -1255,6 +1285,7 @@ async function dispatchSpec(params: {
1255
1285
  cwd,
1256
1286
  arbiter,
1257
1287
  integration,
1288
+ mergeRetries,
1258
1289
  originTrust,
1259
1290
  noPR,
1260
1291
  specsLandIn,
@@ -1321,6 +1352,10 @@ async function dispatchSpec(params: {
1321
1352
  // not a build), exactly as the task branch + the tasking transition skip it.
1322
1353
  skipVerify: true,
1323
1354
  mode: integration,
1355
+ // The cross-job merge-serialiser CAS-retry cap (config `mergeRetries`) — same
1356
+ // rationale as the lone-task emit above; threaded so intake's spec emit lands
1357
+ // under the same per-repo cap. Unset ⇒ the engine default (byte-for-byte).
1358
+ mergeRetries,
1324
1359
  noPR,
1325
1360
  providerInstance,
1326
1361
  type: 'feat',
@@ -1737,7 +1772,7 @@ async function stageIntakeContent(params: {
1737
1772
  * `intake-` PRODUCER prefix keeps this short-lived "create the item" branch
1738
1773
  * DISTINCT from the later build branch (`work/task-<slug>`) for the same slug
1739
1774
  * — the firing `intake` × `do task:` collision the observation traced. The
1740
- * task-emit path passes `'task'`, the spec-emit path `'prd'`. A pre-existing
1775
+ * task-emit path passes `'task'`, the spec-emit path `'spec'`. A pre-existing
1741
1776
  * local branch (a re-run) is force-recreated off fresh main.
1742
1777
  */
1743
1778
  async function switchToWorkBranch(
@@ -1860,7 +1895,7 @@ export function parseIntakeVerdict(output: string): IntakeVerdict {
1860
1895
  outcome !== 'bounce'
1861
1896
  ) {
1862
1897
  // The prompt teaches the LLM to emit `spec`, so the accepted outcome set is
1863
- // `ask|task|spec|bounce`. HARD CUTOVER: the legacy `prd` outcome token is
1898
+ // `ask|task|spec|bounce`. HARD CUTOVER: the legacy ''prd'' outcome token is
1864
1899
  // fully gone (rejected here + removed from the `IntakeOutcome` type + the
1865
1900
  // dispatch `case`).
1866
1901
  throw new Error(