dorfl 0.14.2 → 0.15.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 (418) hide show
  1. package/dist/advance-ci-template.d.ts +17 -16
  2. package/dist/advance-ci-template.d.ts.map +1 -1
  3. package/dist/advance-ci-template.js +42 -53
  4. package/dist/advance-ci-template.js.map +1 -1
  5. package/dist/advance-drivers.d.ts +8 -0
  6. package/dist/advance-drivers.d.ts.map +1 -1
  7. package/dist/advance-drivers.js +28 -4
  8. package/dist/advance-drivers.js.map +1 -1
  9. package/dist/advance-isolated.d.ts.map +1 -1
  10. package/dist/advance-isolated.js +3 -2
  11. package/dist/advance-isolated.js.map +1 -1
  12. package/dist/advance-lifecycle-template.d.ts +41 -40
  13. package/dist/advance-lifecycle-template.d.ts.map +1 -1
  14. package/dist/advance-lifecycle-template.js +309 -489
  15. package/dist/advance-lifecycle-template.js.map +1 -1
  16. package/dist/advance-loop-driver.d.ts.map +1 -1
  17. package/dist/advance-loop-driver.js +3 -2
  18. package/dist/advance-loop-driver.js.map +1 -1
  19. package/dist/advance-treeless-publish.d.ts +31 -0
  20. package/dist/advance-treeless-publish.d.ts.map +1 -1
  21. package/dist/advance-treeless-publish.js +40 -0
  22. package/dist/advance-treeless-publish.js.map +1 -1
  23. package/dist/advance.d.ts +63 -3
  24. package/dist/advance.d.ts.map +1 -1
  25. package/dist/advance.js +80 -12
  26. package/dist/advance.js.map +1 -1
  27. package/dist/advancing-lock.d.ts +9 -0
  28. package/dist/advancing-lock.d.ts.map +1 -1
  29. package/dist/advancing-lock.js +21 -1
  30. package/dist/advancing-lock.js.map +1 -1
  31. package/dist/agent-env.d.ts +61 -0
  32. package/dist/agent-env.d.ts.map +1 -0
  33. package/dist/agent-env.js +144 -0
  34. package/dist/agent-env.js.map +1 -0
  35. package/dist/agent-stop.d.ts +35 -0
  36. package/dist/agent-stop.d.ts.map +1 -1
  37. package/dist/agent-stop.js +62 -0
  38. package/dist/agent-stop.js.map +1 -1
  39. package/dist/apply-merge-action.d.ts +76 -34
  40. package/dist/apply-merge-action.d.ts.map +1 -1
  41. package/dist/apply-merge-action.js +339 -129
  42. package/dist/apply-merge-action.js.map +1 -1
  43. package/dist/apply-stuck-action.js +2 -2
  44. package/dist/apply-stuck-action.js.map +1 -1
  45. package/dist/ci-agent-result.d.ts +151 -0
  46. package/dist/ci-agent-result.d.ts.map +1 -0
  47. package/dist/ci-agent-result.js +314 -0
  48. package/dist/ci-agent-result.js.map +1 -0
  49. package/dist/ci-handoff-apply.d.ts +162 -0
  50. package/dist/ci-handoff-apply.d.ts.map +1 -0
  51. package/dist/ci-handoff-apply.js +497 -0
  52. package/dist/ci-handoff-apply.js.map +1 -0
  53. package/dist/ci-handoff-format.d.ts +369 -0
  54. package/dist/ci-handoff-format.d.ts.map +1 -0
  55. package/dist/ci-handoff-format.js +646 -0
  56. package/dist/ci-handoff-format.js.map +1 -0
  57. package/dist/ci-handoff-lfs.d.ts +146 -0
  58. package/dist/ci-handoff-lfs.d.ts.map +1 -0
  59. package/dist/ci-handoff-lfs.js +397 -0
  60. package/dist/ci-handoff-lfs.js.map +1 -0
  61. package/dist/ci-handoff.d.ts +99 -0
  62. package/dist/ci-handoff.d.ts.map +1 -0
  63. package/dist/ci-handoff.js +277 -0
  64. package/dist/ci-handoff.js.map +1 -0
  65. package/dist/ci-lock-outputs.d.ts +93 -0
  66. package/dist/ci-lock-outputs.d.ts.map +1 -0
  67. package/dist/ci-lock-outputs.js +223 -0
  68. package/dist/ci-lock-outputs.js.map +1 -0
  69. package/dist/ci-phase-build.d.ts +178 -0
  70. package/dist/ci-phase-build.d.ts.map +1 -0
  71. package/dist/ci-phase-build.js +989 -0
  72. package/dist/ci-phase-build.js.map +1 -0
  73. package/dist/ci-phase-driver.d.ts +247 -0
  74. package/dist/ci-phase-driver.d.ts.map +1 -0
  75. package/dist/ci-phase-driver.js +370 -0
  76. package/dist/ci-phase-driver.js.map +1 -0
  77. package/dist/ci-phase-intake.d.ts +172 -0
  78. package/dist/ci-phase-intake.d.ts.map +1 -0
  79. package/dist/ci-phase-intake.js +555 -0
  80. package/dist/ci-phase-intake.js.map +1 -0
  81. package/dist/ci-phase-tasking.d.ts +205 -0
  82. package/dist/ci-phase-tasking.d.ts.map +1 -0
  83. package/dist/ci-phase-tasking.js +906 -0
  84. package/dist/ci-phase-tasking.js.map +1 -0
  85. package/dist/ci-phase-treeless.d.ts +224 -0
  86. package/dist/ci-phase-treeless.d.ts.map +1 -0
  87. package/dist/ci-phase-treeless.js +1482 -0
  88. package/dist/ci-phase-treeless.js.map +1 -0
  89. package/dist/ci-read-token.d.ts +47 -0
  90. package/dist/ci-read-token.d.ts.map +1 -0
  91. package/dist/ci-read-token.js +80 -0
  92. package/dist/ci-read-token.js.map +1 -0
  93. package/dist/cli.d.ts.map +1 -1
  94. package/dist/cli.js +447 -22
  95. package/dist/cli.js.map +1 -1
  96. package/dist/close-job-template.d.ts +10 -1
  97. package/dist/close-job-template.d.ts.map +1 -1
  98. package/dist/close-job-template.js +46 -14
  99. package/dist/close-job-template.js.map +1 -1
  100. package/dist/close-job.d.ts +20 -5
  101. package/dist/close-job.d.ts.map +1 -1
  102. package/dist/close-job.js +65 -12
  103. package/dist/close-job.js.map +1 -1
  104. package/dist/complete.d.ts.map +1 -1
  105. package/dist/complete.js +20 -1
  106. package/dist/complete.js.map +1 -1
  107. package/dist/config.d.ts +41 -44
  108. package/dist/config.d.ts.map +1 -1
  109. package/dist/config.js +2 -4
  110. package/dist/config.js.map +1 -1
  111. package/dist/continue-branch.d.ts +63 -15
  112. package/dist/continue-branch.d.ts.map +1 -1
  113. package/dist/continue-branch.js +75 -8
  114. package/dist/continue-branch.js.map +1 -1
  115. package/dist/crashed-run-save.d.ts +73 -0
  116. package/dist/crashed-run-save.d.ts.map +1 -0
  117. package/dist/crashed-run-save.js +86 -0
  118. package/dist/crashed-run-save.js.map +1 -0
  119. package/dist/cwd-section.d.ts.map +1 -1
  120. package/dist/cwd-section.js +10 -2
  121. package/dist/cwd-section.js.map +1 -1
  122. package/dist/decision-engine.d.ts +10 -0
  123. package/dist/decision-engine.d.ts.map +1 -1
  124. package/dist/decision-engine.js.map +1 -1
  125. package/dist/do-config.d.ts +2 -24
  126. package/dist/do-config.d.ts.map +1 -1
  127. package/dist/do-config.js +1 -33
  128. package/dist/do-config.js.map +1 -1
  129. package/dist/do.d.ts +149 -1
  130. package/dist/do.d.ts.map +1 -1
  131. package/dist/do.js +115 -25
  132. package/dist/do.js.map +1 -1
  133. package/dist/dorfl-item-template.d.ts +98 -0
  134. package/dist/dorfl-item-template.d.ts.map +1 -0
  135. package/dist/dorfl-item-template.js +504 -0
  136. package/dist/dorfl-item-template.js.map +1 -0
  137. package/dist/env-config.d.ts.map +1 -1
  138. package/dist/env-config.js +7 -5
  139. package/dist/env-config.js.map +1 -1
  140. package/dist/frontmatter.d.ts +52 -0
  141. package/dist/frontmatter.d.ts.map +1 -1
  142. package/dist/frontmatter.js +136 -2
  143. package/dist/frontmatter.js.map +1 -1
  144. package/dist/gc.d.ts +13 -0
  145. package/dist/gc.d.ts.map +1 -1
  146. package/dist/gc.js +16 -2
  147. package/dist/gc.js.map +1 -1
  148. package/dist/git.d.ts +18 -1
  149. package/dist/git.d.ts.map +1 -1
  150. package/dist/git.js +70 -5
  151. package/dist/git.js.map +1 -1
  152. package/dist/harness.d.ts +44 -5
  153. package/dist/harness.d.ts.map +1 -1
  154. package/dist/harness.js +24 -1
  155. package/dist/harness.js.map +1 -1
  156. package/dist/index.d.ts +11 -4
  157. package/dist/index.d.ts.map +1 -1
  158. package/dist/index.js +7 -3
  159. package/dist/index.js.map +1 -1
  160. package/dist/install-ci-action-pins.d.ts +123 -0
  161. package/dist/install-ci-action-pins.d.ts.map +1 -0
  162. package/dist/install-ci-action-pins.js +190 -0
  163. package/dist/install-ci-action-pins.js.map +1 -0
  164. package/dist/install-ci-actions-pr-creation.d.ts +70 -0
  165. package/dist/install-ci-actions-pr-creation.d.ts.map +1 -0
  166. package/dist/install-ci-actions-pr-creation.js +106 -0
  167. package/dist/install-ci-actions-pr-creation.js.map +1 -0
  168. package/dist/install-ci-capabilities/dorfl-item.d.ts +12 -0
  169. package/dist/install-ci-capabilities/dorfl-item.d.ts.map +1 -0
  170. package/dist/install-ci-capabilities/dorfl-item.js +26 -0
  171. package/dist/install-ci-capabilities/dorfl-item.js.map +1 -0
  172. package/dist/install-ci-core.d.ts +155 -37
  173. package/dist/install-ci-core.d.ts.map +1 -1
  174. package/dist/install-ci-core.js +304 -200
  175. package/dist/install-ci-core.js.map +1 -1
  176. package/dist/install-ci-github.d.ts +47 -2
  177. package/dist/install-ci-github.d.ts.map +1 -1
  178. package/dist/install-ci-github.js +113 -1
  179. package/dist/install-ci-github.js.map +1 -1
  180. package/dist/install-ci.d.ts +25 -6
  181. package/dist/install-ci.d.ts.map +1 -1
  182. package/dist/install-ci.js +72 -36
  183. package/dist/install-ci.js.map +1 -1
  184. package/dist/intake-marker.d.ts +6 -1
  185. package/dist/intake-marker.d.ts.map +1 -1
  186. package/dist/intake-marker.js.map +1 -1
  187. package/dist/intake-triage.d.ts.map +1 -1
  188. package/dist/intake-triage.js +6 -2
  189. package/dist/intake-triage.js.map +1 -1
  190. package/dist/intake-trigger-template.d.ts +31 -25
  191. package/dist/intake-trigger-template.d.ts.map +1 -1
  192. package/dist/intake-trigger-template.js +107 -292
  193. package/dist/intake-trigger-template.js.map +1 -1
  194. package/dist/intake.d.ts +186 -4
  195. package/dist/intake.d.ts.map +1 -1
  196. package/dist/intake.js +533 -416
  197. package/dist/intake.js.map +1 -1
  198. package/dist/integration-core.d.ts +154 -1
  199. package/dist/integration-core.d.ts.map +1 -1
  200. package/dist/integration-core.js +759 -486
  201. package/dist/integration-core.js.map +1 -1
  202. package/dist/integrator.d.ts +12 -0
  203. package/dist/integrator.d.ts.map +1 -1
  204. package/dist/integrator.js +21 -0
  205. package/dist/integrator.js.map +1 -1
  206. package/dist/isolation.d.ts +12 -2
  207. package/dist/isolation.d.ts.map +1 -1
  208. package/dist/isolation.js +19 -8
  209. package/dist/isolation.js.map +1 -1
  210. package/dist/item-lock.d.ts +93 -11
  211. package/dist/item-lock.d.ts.map +1 -1
  212. package/dist/item-lock.js +233 -65
  213. package/dist/item-lock.js.map +1 -1
  214. package/dist/land-question-residue.d.ts +58 -0
  215. package/dist/land-question-residue.d.ts.map +1 -0
  216. package/dist/land-question-residue.js +95 -0
  217. package/dist/land-question-residue.js.map +1 -0
  218. package/dist/lifecycle-gather.d.ts +16 -0
  219. package/dist/lifecycle-gather.d.ts.map +1 -1
  220. package/dist/lifecycle-gather.js +54 -6
  221. package/dist/lifecycle-gather.js.map +1 -1
  222. package/dist/merge-answer.d.ts +41 -0
  223. package/dist/merge-answer.d.ts.map +1 -0
  224. package/dist/merge-answer.js +60 -0
  225. package/dist/merge-answer.js.map +1 -0
  226. package/dist/merge-question-surfacer.d.ts +105 -30
  227. package/dist/merge-question-surfacer.d.ts.map +1 -1
  228. package/dist/merge-question-surfacer.js +202 -91
  229. package/dist/merge-question-surfacer.js.map +1 -1
  230. package/dist/merge-question-tick.d.ts +64 -0
  231. package/dist/merge-question-tick.d.ts.map +1 -0
  232. package/dist/merge-question-tick.js +96 -0
  233. package/dist/merge-question-tick.js.map +1 -0
  234. package/dist/mint-adr.d.ts.map +1 -1
  235. package/dist/mint-adr.js +20 -2
  236. package/dist/mint-adr.js.map +1 -1
  237. package/dist/needs-attention.d.ts +72 -2
  238. package/dist/needs-attention.d.ts.map +1 -1
  239. package/dist/needs-attention.js +275 -38
  240. package/dist/needs-attention.js.map +1 -1
  241. package/dist/phase-recorder.d.ts +168 -0
  242. package/dist/phase-recorder.d.ts.map +1 -0
  243. package/dist/phase-recorder.js +218 -0
  244. package/dist/phase-recorder.js.map +1 -0
  245. package/dist/phase.d.ts +94 -0
  246. package/dist/phase.d.ts.map +1 -0
  247. package/dist/phase.js +148 -0
  248. package/dist/phase.js.map +1 -0
  249. package/dist/pi-harness.d.ts.map +1 -1
  250. package/dist/pi-harness.js +19 -6
  251. package/dist/pi-harness.js.map +1 -1
  252. package/dist/prepare.d.ts.map +1 -1
  253. package/dist/prepare.js +4 -0
  254. package/dist/prepare.js.map +1 -1
  255. package/dist/prompt.d.ts +4 -0
  256. package/dist/prompt.d.ts.map +1 -1
  257. package/dist/prompt.js +48 -1
  258. package/dist/prompt.js.map +1 -1
  259. package/dist/protocol/CLAIM-PROTOCOL.md +3 -1
  260. package/dist/protocol/WORK-CONTRACT.md +1 -1
  261. package/dist/reap-branches.d.ts +48 -0
  262. package/dist/reap-branches.d.ts.map +1 -1
  263. package/dist/reap-branches.js +64 -0
  264. package/dist/reap-branches.js.map +1 -1
  265. package/dist/ref-write.d.ts +198 -0
  266. package/dist/ref-write.d.ts.map +1 -0
  267. package/dist/ref-write.js +79 -0
  268. package/dist/ref-write.js.map +1 -0
  269. package/dist/repo-config.js +8 -8
  270. package/dist/repo-config.js.map +1 -1
  271. package/dist/repo-mirror.d.ts +36 -0
  272. package/dist/repo-mirror.d.ts.map +1 -1
  273. package/dist/repo-mirror.js +91 -1
  274. package/dist/repo-mirror.js.map +1 -1
  275. package/dist/review-verdict.d.ts +1 -1
  276. package/dist/review-verdict.js +1 -1
  277. package/dist/run.d.ts +7 -1
  278. package/dist/run.d.ts.map +1 -1
  279. package/dist/run.js +28 -4
  280. package/dist/run.js.map +1 -1
  281. package/dist/scan.d.ts +19 -1
  282. package/dist/scan.d.ts.map +1 -1
  283. package/dist/scan.js +21 -8
  284. package/dist/scan.js.map +1 -1
  285. package/dist/sidecar.d.ts +14 -0
  286. package/dist/sidecar.d.ts.map +1 -1
  287. package/dist/sidecar.js +21 -0
  288. package/dist/sidecar.js.map +1 -1
  289. package/dist/single-job-warning.d.ts +63 -0
  290. package/dist/single-job-warning.d.ts.map +1 -0
  291. package/dist/single-job-warning.js +110 -0
  292. package/dist/single-job-warning.js.map +1 -0
  293. package/dist/skills/setup/protocol/CLAIM-PROTOCOL.md +3 -1
  294. package/dist/skills/setup/protocol/WORK-CONTRACT.md +1 -1
  295. package/dist/spec-complete.d.ts +13 -6
  296. package/dist/spec-complete.d.ts.map +1 -1
  297. package/dist/spec-complete.js +23 -11
  298. package/dist/spec-complete.js.map +1 -1
  299. package/dist/start.d.ts.map +1 -1
  300. package/dist/start.js +47 -14
  301. package/dist/start.js.map +1 -1
  302. package/dist/status.d.ts +12 -0
  303. package/dist/status.d.ts.map +1 -1
  304. package/dist/status.js +11 -3
  305. package/dist/status.js.map +1 -1
  306. package/dist/tasking.d.ts +246 -1
  307. package/dist/tasking.d.ts.map +1 -1
  308. package/dist/tasking.js +452 -358
  309. package/dist/tasking.js.map +1 -1
  310. package/dist/triage-persist.d.ts.map +1 -1
  311. package/dist/triage-persist.js +21 -2
  312. package/dist/triage-persist.js.map +1 -1
  313. package/dist/verify-workflow-template.d.ts.map +1 -1
  314. package/dist/verify-workflow-template.js +8 -4
  315. package/dist/verify-workflow-template.js.map +1 -1
  316. package/dist/verify.d.ts.map +1 -1
  317. package/dist/verify.js +4 -0
  318. package/dist/verify.js.map +1 -1
  319. package/dist/watch-session.d.ts +42 -13
  320. package/dist/watch-session.d.ts.map +1 -1
  321. package/dist/watch-session.js +52 -23
  322. package/dist/watch-session.js.map +1 -1
  323. package/dist/work-layout.d.ts +10 -4
  324. package/dist/work-layout.d.ts.map +1 -1
  325. package/dist/work-layout.js +11 -3
  326. package/dist/work-layout.js.map +1 -1
  327. package/dist/workspace.d.ts +65 -4
  328. package/dist/workspace.d.ts.map +1 -1
  329. package/dist/workspace.js +159 -11
  330. package/dist/workspace.js.map +1 -1
  331. package/package.json +1 -1
  332. package/src/advance-ci-template.ts +80 -81
  333. package/src/advance-drivers.ts +45 -6
  334. package/src/advance-isolated.ts +3 -5
  335. package/src/advance-lifecycle-template.ts +375 -538
  336. package/src/advance-loop-driver.ts +3 -5
  337. package/src/advance-treeless-publish.ts +61 -0
  338. package/src/advance.ts +145 -15
  339. package/src/advancing-lock.ts +36 -1
  340. package/src/agent-env.ts +174 -0
  341. package/src/agent-stop.ts +81 -0
  342. package/src/apply-merge-action.ts +401 -154
  343. package/src/apply-stuck-action.ts +2 -2
  344. package/src/ci-agent-result.ts +421 -0
  345. package/src/ci-handoff-apply.ts +737 -0
  346. package/src/ci-handoff-format.ts +926 -0
  347. package/src/ci-handoff-lfs.ts +519 -0
  348. package/src/ci-handoff.ts +392 -0
  349. package/src/ci-lock-outputs.ts +273 -0
  350. package/src/ci-phase-build.ts +1328 -0
  351. package/src/ci-phase-driver.ts +548 -0
  352. package/src/ci-phase-intake.ts +861 -0
  353. package/src/ci-phase-tasking.ts +1255 -0
  354. package/src/ci-phase-treeless.ts +2028 -0
  355. package/src/ci-read-token.ts +90 -0
  356. package/src/cli.ts +591 -29
  357. package/src/close-job-template.ts +52 -15
  358. package/src/close-job.ts +77 -12
  359. package/src/complete.ts +19 -1
  360. package/src/config.ts +43 -48
  361. package/src/continue-branch.ts +121 -16
  362. package/src/crashed-run-save.ts +162 -0
  363. package/src/cwd-section.ts +10 -0
  364. package/src/decision-engine.ts +10 -0
  365. package/src/do-config.ts +2 -57
  366. package/src/do.ts +170 -28
  367. package/src/dorfl-item-template.ts +556 -0
  368. package/src/env-config.ts +7 -5
  369. package/src/frontmatter.ts +155 -2
  370. package/src/gc.ts +27 -2
  371. package/src/git.ts +83 -5
  372. package/src/harness.ts +58 -6
  373. package/src/index.ts +50 -1
  374. package/src/install-ci-action-pins.ts +209 -0
  375. package/src/install-ci-actions-pr-creation.ts +186 -0
  376. package/src/install-ci-capabilities/dorfl-item.ts +33 -0
  377. package/src/install-ci-core.ts +388 -233
  378. package/src/install-ci-github.ts +149 -1
  379. package/src/install-ci.ts +83 -37
  380. package/src/intake-marker.ts +6 -1
  381. package/src/intake-triage.ts +7 -3
  382. package/src/intake-trigger-template.ts +126 -327
  383. package/src/intake.ts +725 -544
  384. package/src/integration-core.ts +975 -523
  385. package/src/integrator.ts +28 -0
  386. package/src/isolation.ts +29 -10
  387. package/src/item-lock.ts +308 -92
  388. package/src/land-question-residue.ts +122 -0
  389. package/src/lifecycle-gather.ts +82 -10
  390. package/src/merge-answer.ts +82 -0
  391. package/src/merge-question-surfacer.ts +320 -112
  392. package/src/merge-question-tick.ts +182 -0
  393. package/src/mint-adr.ts +28 -2
  394. package/src/needs-attention.ts +350 -42
  395. package/src/phase-recorder.ts +350 -0
  396. package/src/phase.ts +177 -0
  397. package/src/pi-harness.ts +25 -5
  398. package/src/prepare.ts +4 -0
  399. package/src/prompt.ts +68 -1
  400. package/src/reap-branches.ts +107 -0
  401. package/src/ref-write.ts +324 -0
  402. package/src/repo-config.ts +8 -8
  403. package/src/repo-mirror.ts +107 -1
  404. package/src/review-verdict.ts +1 -1
  405. package/src/run.ts +47 -6
  406. package/src/scan.ts +37 -7
  407. package/src/sidecar.ts +36 -0
  408. package/src/single-job-warning.ts +135 -0
  409. package/src/spec-complete.ts +36 -14
  410. package/src/start.ts +55 -16
  411. package/src/status.ts +29 -3
  412. package/src/tasking.ts +593 -378
  413. package/src/triage-persist.ts +24 -2
  414. package/src/verify-workflow-template.ts +8 -4
  415. package/src/verify.ts +4 -0
  416. package/src/watch-session.ts +86 -28
  417. package/src/work-layout.ts +11 -3
  418. package/src/workspace.ts +210 -14
@@ -0,0 +1,209 @@
1
+ /**
2
+ * The ONE table of third-party GitHub Actions that `dorfl install-ci` emits,
3
+ * each pinned to a full 40-character commit SHA, plus the regeneration rule that
4
+ * keeps a consumer repository's own pins.
5
+ *
6
+ * WHY SHAS. A tag such as `@v5` can be moved by whoever controls the action's
7
+ * repository, so a compromised or careless release reaches every job that uses
8
+ * it, including dorfl's jobs that hold `contents: write` and a provider API key.
9
+ * A commit SHA cannot move. This is GitHub's own hardening guidance ("Using
10
+ * third-party actions", Security hardening for GitHub Actions).
11
+ *
12
+ * THE FORMAT. Every reference is emitted as `owner/repo@<40-hex-sha> # vX.Y.Z`,
13
+ * the exact shape Dependabot writes and rewrites, so a consumer that enables
14
+ * Dependabot's `github-actions` ecosystem (with `/.github/actions/*` in
15
+ * `directories` for the composite action) gets reviewable bump PRs.
16
+ *
17
+ * HOW EACH SHA WAS RESOLVED (2026-09-26). For each tag:
18
+ * 1. `git ls-remote --tags https://github.com/<owner>/<repo>.git`, reading the
19
+ * peeled `refs/tags/<tag>^{}` line when the tag is annotated (that line is
20
+ * the COMMIT; the unpeeled line is the tag OBJECT and must never be used),
21
+ * else the tag line itself for a lightweight tag;
22
+ * 2. cross-checked with `gh api repos/<owner>/<repo>/git/ref/tags/<tag>`
23
+ * (object type) and `gh api repos/<owner>/<repo>/commits/<sha>` (the SHA is
24
+ * a commit that exists in the repository).
25
+ *
26
+ * actions/checkout v7.0.1: lightweight tag, `git/ref` type `commit`,
27
+ * 3d3c42e5aac5ba805825da76410c181273ba90b1 ("prep v7.0.1 release (#2531)").
28
+ * The floating `v7` tag points at the same commit. v7 is the current major
29
+ * and adds the fork-PR checkout block for `pull_request_target` /
30
+ * `workflow_run` that v5 lacks; the inputs dorfl passes (`fetch-depth`,
31
+ * `persist-credentials`) are unchanged.
32
+ * actions/setup-node v7.0.0: lightweight tag, `git/ref` type `commit`,
33
+ * 820762786026740c76f36085b0efc47a31fe5020 ("Migrate to ESM and upgrade
34
+ * dependencies (#1574)"). The floating `v7` tag points at the same commit.
35
+ * `node-version` and `package-manager-cache` are still inputs (see the
36
+ * comment on the setup-node step in `generateSetupAction`).
37
+ * pnpm/action-setup v6.1.0: ANNOTATED tag. `git/ref` type `tag` with object
38
+ * d9184bf108216479bc5a137cc391f4d7b14c870b (the tag object, NOT usable);
39
+ * peeled `^{}` and `gh api .../git/tags/d9184bf...` both give the commit
40
+ * ea17c68df8912ef543352723c149a84f56e3d413 ("feat: support pnpm v12
41
+ * (#288)"). With no `version` input it still reads `packageManager` from
42
+ * package.json, which is how dorfl's workspace mode uses it.
43
+ *
44
+ * Resolved 2026-09-28 (task `ci-split-generate-workflows`, the split CI item
45
+ * workflow's handoff artifact; the spec requires at least v4.1.3 of both):
46
+ * actions/upload-artifact v7.0.1: lightweight tag (`ls-remote` lists no
47
+ * peeled `^{}` line for it), `git/ref` type `commit`,
48
+ * 043fb46d1a93c77aae656e7c1c64a875d1fc6a0a ("Merge pull request #797 from
49
+ * actions/yacaovsnc/update-dependency"). The floating `v7` tag points at
50
+ * the same commit. The inputs dorfl passes (`name`, `path`,
51
+ * `retention-days`, `if-no-files-found`) are unchanged since v4.
52
+ * actions/download-artifact v8.0.1: lightweight tag, `git/ref` type
53
+ * `commit`, 3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c ("Add regression tests
54
+ * for CJK characters (#471)"). The floating `v8` tag points at the same
55
+ * commit. v8 fails on a digest mismatch by default (`digest-mismatch:
56
+ * error`), which is what the apply job wants; dorfl passes `name` and
57
+ * `path` and never `run-id` (the apply job reads its OWN run's artifact).
58
+ *
59
+ * To bump a pin: resolve the new tag the same way, update the entry, and record
60
+ * the resolution above. `install-ci-actions-pinned.test.ts` fails on any
61
+ * emitted `uses:` that is not a full SHA.
62
+ */
63
+
64
+ /** One pinned third-party action. */
65
+ export interface ActionPin {
66
+ /** `owner/repo`, or `owner/repo/path` for an action in a subdirectory. */
67
+ readonly action: string;
68
+ /** The full 40-character lowercase commit SHA (never a tag object). */
69
+ readonly sha: string;
70
+ /** The release tag the SHA was resolved from, for the trailing comment. */
71
+ readonly version: string;
72
+ }
73
+
74
+ /** Every third-party action dorfl's generators emit. */
75
+ export const ACTION_PINS = {
76
+ checkout: {
77
+ action: 'actions/checkout',
78
+ sha: '3d3c42e5aac5ba805825da76410c181273ba90b1',
79
+ version: 'v7.0.1',
80
+ },
81
+ setupNode: {
82
+ action: 'actions/setup-node',
83
+ sha: '820762786026740c76f36085b0efc47a31fe5020',
84
+ version: 'v7.0.0',
85
+ },
86
+ pnpmSetup: {
87
+ action: 'pnpm/action-setup',
88
+ sha: 'ea17c68df8912ef543352723c149a84f56e3d413',
89
+ version: 'v6.1.0',
90
+ },
91
+ uploadArtifact: {
92
+ action: 'actions/upload-artifact',
93
+ sha: '043fb46d1a93c77aae656e7c1c64a875d1fc6a0a',
94
+ version: 'v7.0.1',
95
+ },
96
+ downloadArtifact: {
97
+ action: 'actions/download-artifact',
98
+ sha: '3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c',
99
+ version: 'v8.0.1',
100
+ },
101
+ } as const satisfies Record<string, ActionPin>;
102
+
103
+ /**
104
+ * The value to put after `uses: ` for a pinned action:
105
+ * `owner/repo@<sha> # vX.Y.Z` (the Dependabot format).
106
+ */
107
+ export function pinnedUses(pin: ActionPin): string {
108
+ return `${pin.action}@${pin.sha} # ${pin.version}`;
109
+ }
110
+
111
+ // ─── preserving the consumer's pins on regeneration ─────────────────────────
112
+
113
+ /**
114
+ * A `uses:` step line: the prefix (indentation, an optional `- ` list marker,
115
+ * `uses:` and its spacing), then the VALUE (an optionally quoted
116
+ * `action@ref`), then an optional trailing comment. Matched per line, which is
117
+ * how both dorfl's templates and Dependabot write these lines. A flow-style or
118
+ * multi-line `uses:` value is not recognised (and so not preserved).
119
+ */
120
+ const USES_LINE =
121
+ /^(\s*(?:-\s+)?uses:[ \t]+)((['"]?)([^\s'"@#]+)@([^\s'"#]+)\3(?:[ \t]+#.*)?)[ \t]*$/;
122
+
123
+ /**
124
+ * A full commit SHA (what counts as "pinned"). Case-insensitive here, so a
125
+ * consumer's uppercase pin is still kept; dorfl itself emits lowercase.
126
+ */
127
+ const FULL_SHA = /^[0-9a-f]{40}$/i;
128
+
129
+ /** The lookup key for an action: GitHub treats `owner/repo` case-insensitively. */
130
+ function actionKey(action: string): string {
131
+ return action.toLowerCase();
132
+ }
133
+
134
+ /** A remote action key (`owner/repo[/path]`), i.e. not `./local` nor `docker://`. */
135
+ function isRemoteAction(action: string): boolean {
136
+ return !action.startsWith('.') && /^[^/\s]+\/[^/\s]+/.test(action);
137
+ }
138
+
139
+ /** Parse the version out of a trailing `# v1.2.3` comment, for ranking. */
140
+ function versionOf(tail: string): number[] | undefined {
141
+ const m = /#\s*v?(\d+(?:\.\d+)*)/.exec(tail);
142
+ return m ? m[1].split('.').map(Number) : undefined;
143
+ }
144
+
145
+ /** Compare two parsed versions; a missing version ranks lowest. */
146
+ function compareVersions(a?: number[], b?: number[]): number {
147
+ if (!a || !b) return (a ? 1 : 0) - (b ? 1 : 0);
148
+ for (let i = 0; i < Math.max(a.length, b.length); i++) {
149
+ const d = (a[i] ?? 0) - (b[i] ?? 0);
150
+ if (d !== 0) return d;
151
+ }
152
+ return 0;
153
+ }
154
+
155
+ /**
156
+ * Collect the SHA pins an existing file already carries, keyed by action
157
+ * (`owner/repo[/path]`). The value is the whole `uses:` value with its trailing
158
+ * comment, exactly as written. When the file pins the same action to several
159
+ * different SHAs, the one whose `# vX.Y.Z` comment is highest wins (ties: the
160
+ * first in the file), so a partial manual bump is never undone.
161
+ */
162
+ export function existingPins(existing: string): Map<string, string> {
163
+ const pins = new Map<string, string>();
164
+ // `\r?\n`: a CRLF checkout (Windows, `core.autocrlf`) must not hide its pins,
165
+ // or dorfl's default would silently replace them.
166
+ for (const line of existing.split(/\r?\n/)) {
167
+ const m = USES_LINE.exec(line);
168
+ if (!m) continue;
169
+ const [, , value, , action, ref] = m;
170
+ if (!isRemoteAction(action) || !FULL_SHA.test(ref)) continue;
171
+ const key = actionKey(action);
172
+ const current = pins.get(key);
173
+ if (
174
+ current === undefined ||
175
+ compareVersions(versionOf(value), versionOf(current)) > 0
176
+ ) {
177
+ pins.set(key, value);
178
+ }
179
+ }
180
+ return pins;
181
+ }
182
+
183
+ /**
184
+ * Rewrite a freshly generated workflow / composite action so every `uses:` of an
185
+ * action that `existing` already pins to a full SHA keeps the consumer's
186
+ * reference and trailing comment. Matching is by action (`owner/repo`, plus the
187
+ * path for an action in a subdirectory), never by position. An existing TAG is
188
+ * not a pin: the generated reference (dorfl's SHA) stays. So the result never
189
+ * swaps a SHA for a tag. Only the value after `uses: ` changes; indentation and
190
+ * every other line are the generated ones.
191
+ */
192
+ export function preserveExistingPins(
193
+ generated: string,
194
+ existing: string | undefined,
195
+ ): string {
196
+ if (existing === undefined) return generated;
197
+ const pins = existingPins(existing);
198
+ if (pins.size === 0) return generated;
199
+ return generated
200
+ .split('\n')
201
+ .map((line) => {
202
+ const m = USES_LINE.exec(line);
203
+ if (!m) return line;
204
+ const [, prefix, , , action] = m;
205
+ const kept = pins.get(actionKey(action));
206
+ return kept === undefined ? line : `${prefix}${kept}`;
207
+ })
208
+ .join('\n');
209
+ }
@@ -0,0 +1,186 @@
1
+ /**
2
+ * The "Allow GitHub Actions to create and approve pull requests" STEP for
3
+ * `install-ci` (task `install-ci-enables-actions-pr-creation`). A new GitHub
4
+ * repository has this setting OFF (`GET repos/<r>/actions/permissions/workflow`
5
+ * answers `can_approve_pull_request_reviews: false`), and with it off GitHub
6
+ * refuses every pull request the generated workflows try to open with the
7
+ * ambient `GITHUB_TOKEN`, so propose mode silently opens no PR. dorfl's own
8
+ * repository has it on, which is why this was only found in a fresh sandbox.
9
+ *
10
+ * BEHAVIOUR (mirrors the Tier-1 branch-protection step,
11
+ * `install-ci-branch-protection.ts`: auto-when-admin, instruct-otherwise):
12
+ *
13
+ * - READ the setting ({@link CIProviderContext.getActionsWorkflowPermissions}).
14
+ * Already on: leave it alone and say so.
15
+ * - Off (or unreadable) and the credential is repo-admin-scoped: SET it
16
+ * ({@link CIProviderContext.setActionsWorkflowPermissions}) with
17
+ * `can_approve_pull_request_reviews: true`, carrying the
18
+ * `default_workflow_permissions` value that was read so the GITHUB_TOKEN's
19
+ * default scope is preserved, never widened or narrowed.
20
+ * - Not admin (or unknown): never call the API; print the exact `gh api`
21
+ * command and the settings page instead. A rejected PUT is `failed` and
22
+ * prints the same command to retry by hand.
23
+ * - `--fake`: report what would be checked, call nothing.
24
+ *
25
+ * Never throws: a failure is reported in the result and the log, so install-ci's
26
+ * later steps still run.
27
+ */
28
+
29
+ import type {
30
+ ActionsWorkflowPermissions,
31
+ CIProviderContext,
32
+ } from './install-ci-core.js';
33
+
34
+ export type {ActionsWorkflowPermissions};
35
+
36
+ /**
37
+ * The exact `gh api` command a user runs to turn the setting on by hand. When
38
+ * the current `default_workflow_permissions` is known it is passed back
39
+ * unchanged; when it is not, the field is omitted, which leaves it as it is on
40
+ * GitHub (both PUT fields are optional). Pure string, no I/O.
41
+ */
42
+ export function formatManualActionsPrCreationCommand(
43
+ repo: string,
44
+ defaultWorkflowPermissions?: string,
45
+ ): string {
46
+ const keep =
47
+ defaultWorkflowPermissions !== undefined
48
+ ? ` -f default_workflow_permissions=${defaultWorkflowPermissions}`
49
+ : '';
50
+ return (
51
+ `gh api -X PUT repos/${repo}/actions/permissions/workflow ` +
52
+ `-F can_approve_pull_request_reviews=true${keep}`
53
+ );
54
+ }
55
+
56
+ /** Options for {@link installCIActionsPrCreationStep}. */
57
+ export interface ActionsPrCreationStepOptions {
58
+ /** The CI-provider seam (GitHub adapter in production; stub in tests). */
59
+ ctx: CIProviderContext;
60
+ /** Snapshot mode: never call the live API. */
61
+ fake?: boolean;
62
+ /** Sink for human-facing progress lines. */
63
+ log: (line: string) => void;
64
+ }
65
+
66
+ /** The outcome of one actions-PR-creation step run. */
67
+ export interface ActionsPrCreationStepResult {
68
+ /**
69
+ * - `already-enabled`: the setting was on; nothing was changed;
70
+ * - `set`: it was off (or unreadable), admin scope, the PUT succeeded;
71
+ * - `failed`: admin scope, the PUT was rejected (detail in `error`);
72
+ * - `instructed`: not admin (or unknown), the manual command was printed;
73
+ * - `skipped-no-repo`: the provider context has no `repo` known;
74
+ * - `skipped-no-seam`: the provider does not implement the seam;
75
+ * - `skipped-fake`: `--fake` snapshot mode (no real API touched).
76
+ */
77
+ status:
78
+ | 'already-enabled'
79
+ | 'set'
80
+ | 'failed'
81
+ | 'instructed'
82
+ | 'skipped-no-repo'
83
+ | 'skipped-no-seam'
84
+ | 'skipped-fake';
85
+ /** The permissions read before any change (`undefined` when unreadable). */
86
+ before?: ActionsWorkflowPermissions;
87
+ /** The detected admin-scope verdict (`true`/`false`/`undefined`=unknown). */
88
+ adminScope?: boolean;
89
+ /** The failure detail when `status === 'failed'`. */
90
+ error?: string;
91
+ }
92
+
93
+ const LABEL = 'actions PR creation';
94
+
95
+ /**
96
+ * Check, and when off and permitted, enable the repository setting that lets
97
+ * GitHub Actions create pull requests (see the module header).
98
+ */
99
+ export async function installCIActionsPrCreationStep(
100
+ options: ActionsPrCreationStepOptions,
101
+ ): Promise<ActionsPrCreationStepResult> {
102
+ const {ctx, log, fake} = options;
103
+
104
+ if (fake) {
105
+ log(
106
+ `${LABEL}: skipped (--fake; would check that "Allow GitHub Actions to create and approve pull requests" is on, and enable it if not)`,
107
+ );
108
+ return {status: 'skipped-fake'};
109
+ }
110
+ if (
111
+ !ctx.getActionsWorkflowPermissions ||
112
+ !ctx.setActionsWorkflowPermissions
113
+ ) {
114
+ log(
115
+ `${LABEL}: skipped (provider does not implement the seam, non-GitHub host).`,
116
+ );
117
+ return {status: 'skipped-no-seam'};
118
+ }
119
+ if (!ctx.repo) {
120
+ log(`${LABEL}: skipped (repo unknown, pass --repo to enable).`);
121
+ return {status: 'skipped-no-repo'};
122
+ }
123
+ const repo = ctx.repo;
124
+
125
+ const before = await ctx
126
+ .getActionsWorkflowPermissions()
127
+ .catch(() => undefined);
128
+ if (before?.canApprovePullRequestReviews === true) {
129
+ log(
130
+ `${LABEL}: "Allow GitHub Actions to create and approve pull requests" is already on for ${repo}.`,
131
+ );
132
+ return {status: 'already-enabled', before};
133
+ }
134
+
135
+ const keep = before?.defaultWorkflowPermissions;
136
+ const adminScope = ctx.getRepoAdminScope
137
+ ? await ctx.getRepoAdminScope().catch(() => undefined)
138
+ : undefined;
139
+
140
+ if (adminScope !== true) {
141
+ log(
142
+ before === undefined
143
+ ? `${LABEL}: could not read "Allow GitHub Actions to create and approve pull requests" for ${repo}, and no admin-scoped credential was detected.`
144
+ : `${LABEL}: "Allow GitHub Actions to create and approve pull requests" is OFF for ${repo}, and no admin-scoped credential was detected.`,
145
+ );
146
+ log(
147
+ ' With it off, propose mode opens no pull request (GitHub refuses PRs created with GITHUB_TOKEN).',
148
+ );
149
+ log(
150
+ ' install-ci will NOT call the GitHub API. Run this yourself (admin token required):',
151
+ );
152
+ log(` ${formatManualActionsPrCreationCommand(repo, keep)}`);
153
+ log(
154
+ ` Manual UI fallback: https://github.com/${repo}/settings/actions ` +
155
+ '→ "Workflow permissions" → tick "Allow GitHub Actions to create and approve pull requests" → Save.',
156
+ );
157
+ return {status: 'instructed', before, adminScope};
158
+ }
159
+
160
+ try {
161
+ // Carry the default scope through unchanged; when it could not be read,
162
+ // omit it so GitHub keeps whatever it is.
163
+ await ctx.setActionsWorkflowPermissions({
164
+ canApprovePullRequestReviews: true,
165
+ ...(keep !== undefined ? {defaultWorkflowPermissions: keep} : {}),
166
+ });
167
+ } catch (err) {
168
+ const error = err instanceof Error ? err.message : String(err);
169
+ log(`${LABEL}: FAILED (${error})`);
170
+ log(
171
+ ' With it off, propose mode opens no pull request (GitHub refuses PRs created with GITHUB_TOKEN).',
172
+ );
173
+ log(
174
+ ` Retry by hand (admin token required):\n` +
175
+ ` ${formatManualActionsPrCreationCommand(repo, keep)}`,
176
+ );
177
+ return {status: 'failed', before, adminScope, error};
178
+ }
179
+ log(
180
+ `${LABEL}: enabled "Allow GitHub Actions to create and approve pull requests" on ${repo}` +
181
+ (keep !== undefined
182
+ ? ` (default_workflow_permissions kept as ${keep}).`
183
+ : '.'),
184
+ );
185
+ return {status: 'set', before, adminScope};
186
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * The SPLIT CI ITEM capability emitter (spec `ci-agent-job-without-write-token`,
3
+ * task `ci-split-generate-workflows`). A SELF-REGISTERING module (see
4
+ * `example-noop.ts`): it emits `dorfl-item.yml` (the lock, agent and apply jobs
5
+ * of ONE item) and `dorfl-item-dispatch.yml` (the per-item dispatch wrapper the
6
+ * advance tick starts), which the advance-lifecycle and intake workflows call.
7
+ *
8
+ * The workflow text lives in `dorfl-item-template.ts`; this file is the thin
9
+ * registry-wiring shim.
10
+ */
11
+
12
+ import {registerCapability} from '../install-ci-core.js';
13
+ import {
14
+ ITEM_DISPATCH_WORKFLOW_PATH,
15
+ ITEM_WORKFLOW_PATH,
16
+ generateItemDispatchWorkflow,
17
+ generateItemWorkflow,
18
+ } from '../dorfl-item-template.js';
19
+
20
+ registerCapability({
21
+ id: 'dorfl-item',
22
+ label:
23
+ 'Run each CI item as lock, agent and apply jobs (the per-item workflow the advance tick and intake call)',
24
+ emit(config) {
25
+ return [
26
+ {path: ITEM_WORKFLOW_PATH, content: generateItemWorkflow(config)},
27
+ {
28
+ path: ITEM_DISPATCH_WORKFLOW_PATH,
29
+ content: generateItemDispatchWorkflow(config),
30
+ },
31
+ ];
32
+ },
33
+ });