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
@@ -5,19 +5,27 @@
5
5
  * wizard / config / `models.json` / `--export-config` / `--fake` / secret
6
6
  * orchestration; THIS adapter only supplies the GitHub-specific I/O (repo
7
7
  * detection, `gh secret set`, the optional `delete_branch_on_merge` repo
8
- * setting). Because the seam is the boundary, a second CI provider could be added
8
+ * setting, branch protection, and the Actions workflow permissions that let
9
+ * GitHub Actions open pull requests). Because the seam is the boundary, a second CI provider could be added
9
10
  * WITHOUT touching the core (US #7/#10).
10
11
  *
11
12
  * `install-ci` uses the SEAMS, never `gh` directly in the core: this adapter is
12
13
  * the ONLY place that shells out to `gh`, and it does so behind the seam so tests
13
14
  * stub it entirely (no network, no real `gh`, no real GitHub repo detection). The
14
15
  * adapter NEVER `--force`s and degrades gracefully when `gh` is missing.
16
+ *
17
+ * WRITE-SEAM EXEMPT (task `ci-split-route-direct-writes-through-seams`): the
18
+ * `gh secret set` / `gh api` writes here (secrets, rulesets, branch protection,
19
+ * repo settings, Actions workflow permissions) are only reached from the human-run `install-ci` wizard, never
20
+ * from a CI job, so they stay on this adapter's own `runGh` wrapper instead of a
21
+ * dorfl write seam.
15
22
  */
16
23
 
17
24
  import {run, type RunResult} from './git.js';
18
25
  import {DEFAULT_GH_BIN} from './github.js';
19
26
  import {
20
27
  parseRepoVisibility,
28
+ type ActionsWorkflowPermissions,
21
29
  type CIProviderContext,
22
30
  type RepoVisibility,
23
31
  } from './install-ci-core.js';
@@ -366,6 +374,72 @@ export class GitHubCIContext implements CIProviderContext {
366
374
  }
367
375
  }
368
376
 
377
+ /**
378
+ * Read the repo's Actions workflow permissions via
379
+ * `gh api repos/<repo>/actions/permissions/workflow`. Returns `undefined`
380
+ * when `gh` is unavailable / the repo is unknown / the call fails (it needs
381
+ * repo-admin read on some token kinds) / the answer is not the expected shape.
382
+ */
383
+ async getActionsWorkflowPermissions(): Promise<
384
+ ActionsWorkflowPermissions | undefined
385
+ > {
386
+ if (!this.repo) {
387
+ return undefined;
388
+ }
389
+ const result = this.runGh([
390
+ 'api',
391
+ `repos/${this.repo}/actions/permissions/workflow`,
392
+ ]);
393
+ if (result === undefined || result.status !== 0) {
394
+ return undefined;
395
+ }
396
+ return parseActionsWorkflowPermissions(result.stdout);
397
+ }
398
+
399
+ /**
400
+ * Set the repo's Actions workflow permissions via
401
+ * `gh api -X PUT repos/<repo>/actions/permissions/workflow`, sending ONLY the
402
+ * fields given (an omitted field keeps its GitHub value). `-F` sends the
403
+ * boolean typed, `-f` the string. Throws on failure.
404
+ */
405
+ async setActionsWorkflowPermissions(
406
+ permissions: Partial<ActionsWorkflowPermissions>,
407
+ ): Promise<void> {
408
+ if (!this.repo) {
409
+ throw new Error('cannot set actions workflow permissions: repo unknown');
410
+ }
411
+ const args = [
412
+ 'api',
413
+ '-X',
414
+ 'PUT',
415
+ `repos/${this.repo}/actions/permissions/workflow`,
416
+ ];
417
+ if (permissions.canApprovePullRequestReviews !== undefined) {
418
+ args.push(
419
+ '-F',
420
+ `can_approve_pull_request_reviews=${permissions.canApprovePullRequestReviews}`,
421
+ );
422
+ }
423
+ if (permissions.defaultWorkflowPermissions !== undefined) {
424
+ args.push(
425
+ '-f',
426
+ `default_workflow_permissions=${permissions.defaultWorkflowPermissions}`,
427
+ );
428
+ }
429
+ const result = this.runGh(args);
430
+ if (result === undefined) {
431
+ throw new Error(
432
+ 'gh not available; cannot set actions workflow permissions',
433
+ );
434
+ }
435
+ if (result.status !== 0) {
436
+ throw new Error(
437
+ `gh api PUT repos/${this.repo}/actions/permissions/workflow failed: ` +
438
+ (result.stderr.trim() || 'unknown error'),
439
+ );
440
+ }
441
+ }
442
+
369
443
  /**
370
444
  * Render the GitHub project-setup payload to the steps fragment the
371
445
  * composite setup action splices in FIRST. Free-function delegate so the
@@ -394,6 +468,37 @@ export class GitHubCIContext implements CIProviderContext {
394
468
  }
395
469
  }
396
470
 
471
+ /**
472
+ * Parse the JSON body of `GET repos/<r>/actions/permissions/workflow` into
473
+ * {@link ActionsWorkflowPermissions}, or `undefined` when it is not that shape
474
+ * (unparseable, or either field missing / mistyped). Pure, no I/O.
475
+ */
476
+ export function parseActionsWorkflowPermissions(
477
+ body: string,
478
+ ): ActionsWorkflowPermissions | undefined {
479
+ let parsed: unknown;
480
+ try {
481
+ parsed = JSON.parse(body);
482
+ } catch {
483
+ return undefined;
484
+ }
485
+ if (typeof parsed !== 'object' || parsed === null) {
486
+ return undefined;
487
+ }
488
+ const {default_workflow_permissions, can_approve_pull_request_reviews} =
489
+ parsed as Record<string, unknown>;
490
+ if (
491
+ typeof default_workflow_permissions !== 'string' ||
492
+ typeof can_approve_pull_request_reviews !== 'boolean'
493
+ ) {
494
+ return undefined;
495
+ }
496
+ return {
497
+ defaultWorkflowPermissions: default_workflow_permissions,
498
+ canApprovePullRequestReviews: can_approve_pull_request_reviews,
499
+ };
500
+ }
501
+
397
502
  /**
398
503
  * An in-memory STUB provider context for tests + `--fake` mode: `setSecret`
399
504
  * records to memory (NO real secrets store touched), `ghAvailable` is fixed
@@ -414,6 +519,16 @@ export class MemoryCIProviderContext implements CIProviderContext {
414
519
  readonly branchProtections = new Map<string, unknown>();
415
520
  /** Deadlock-guard rulesets recorded in memory (append-only). */
416
521
  readonly rulesets: unknown[] = [];
522
+ /**
523
+ * The Actions workflow permissions: seeded from the fixture, updated by
524
+ * `setActionsWorkflowPermissions`. `undefined` ⇒ the read "fails".
525
+ */
526
+ actionsWorkflowPermissions: ActionsWorkflowPermissions | undefined;
527
+ /** Every `setActionsWorkflowPermissions` body, in call order (append-only). */
528
+ readonly actionsWorkflowPermissionsSets: Partial<ActionsWorkflowPermissions>[] =
529
+ [];
530
+ /** Whether `setActionsWorkflowPermissions` should throw (tests configure). */
531
+ private readonly actionsWorkflowPermissionsError: string | undefined;
417
532
  /** What `getRepoAdminScope()` should return (tests configure). */
418
533
  private readonly adminScope: boolean | undefined;
419
534
  /** What `getDefaultBranch()` should return (tests configure). */
@@ -442,6 +557,13 @@ export class MemoryCIProviderContext implements CIProviderContext {
442
557
  branchProtectionError?: string;
443
558
  /** When set, `setBranchRuleset` throws with this message (failure path). */
444
559
  branchRulesetError?: string;
560
+ /**
561
+ * Fixture Actions workflow permissions; `undefined` ⇒ the read fails
562
+ * (models a `gh` that could not read the setting).
563
+ */
564
+ actionsWorkflowPermissions?: ActionsWorkflowPermissions;
565
+ /** When set, `setActionsWorkflowPermissions` throws with this message. */
566
+ actionsWorkflowPermissionsError?: string;
445
567
  /**
446
568
  * The provider id this stub claims (default `github`). Tests of the
447
569
  * project-setup seam may override to assert the orchestrator's
@@ -458,6 +580,9 @@ export class MemoryCIProviderContext implements CIProviderContext {
458
580
  this.visibility = options.visibility;
459
581
  this.branchProtectionError = options.branchProtectionError;
460
582
  this.branchRulesetError = options.branchRulesetError;
583
+ this.actionsWorkflowPermissions = options.actionsWorkflowPermissions;
584
+ this.actionsWorkflowPermissionsError =
585
+ options.actionsWorkflowPermissionsError;
461
586
  this.providerId = options.providerId ?? GITHUB_PROVIDER_ID;
462
587
  }
463
588
 
@@ -498,4 +623,27 @@ export class MemoryCIProviderContext implements CIProviderContext {
498
623
  }
499
624
  this.rulesets.push(ruleset);
500
625
  }
626
+
627
+ async getActionsWorkflowPermissions(): Promise<
628
+ ActionsWorkflowPermissions | undefined
629
+ > {
630
+ return this.actionsWorkflowPermissions === undefined
631
+ ? undefined
632
+ : {...this.actionsWorkflowPermissions};
633
+ }
634
+
635
+ async setActionsWorkflowPermissions(
636
+ permissions: Partial<ActionsWorkflowPermissions>,
637
+ ): Promise<void> {
638
+ if (this.actionsWorkflowPermissionsError !== undefined) {
639
+ throw new Error(this.actionsWorkflowPermissionsError);
640
+ }
641
+ this.actionsWorkflowPermissionsSets.push({...permissions});
642
+ if (this.actionsWorkflowPermissions !== undefined) {
643
+ this.actionsWorkflowPermissions = {
644
+ ...this.actionsWorkflowPermissions,
645
+ ...permissions,
646
+ };
647
+ }
648
+ }
501
649
  }
package/src/install-ci.ts CHANGED
@@ -29,6 +29,7 @@ import {
29
29
  type CapabilityEmitter,
30
30
  type SecretSetResult,
31
31
  DEFAULT_HARNESS,
32
+ PR_IDENTITY_SECRET_NAME,
32
33
  loadCIConfigFile,
33
34
  resolveCIConfig,
34
35
  exportCIConfig,
@@ -41,6 +42,10 @@ import {
41
42
  installCIBranchProtectionStep,
42
43
  type BranchProtectionStepResult,
43
44
  } from './install-ci-branch-protection.js';
45
+ import {
46
+ installCIActionsPrCreationStep,
47
+ type ActionsPrCreationStepResult,
48
+ } from './install-ci-actions-pr-creation.js';
44
49
 
45
50
  /**
46
51
  * The interactive prompt SEAM the wizard drives. Production wires readline; tests
@@ -105,6 +110,11 @@ export interface InstallCIResult {
105
110
  secrets: SecretSetResult[];
106
111
  /** The Tier-1 branch-protection outcome (undefined on `exported`). */
107
112
  branchProtection?: BranchProtectionStepResult;
113
+ /**
114
+ * The "Allow GitHub Actions to create and approve pull requests" outcome
115
+ * (undefined on `exported`).
116
+ */
117
+ actionsPrCreation?: ActionsPrCreationStepResult;
108
118
  }
109
119
 
110
120
  /**
@@ -311,6 +321,21 @@ export async function installCI(
311
321
  fake,
312
322
  log,
313
323
  });
324
+
325
+ // 5c. "Allow GitHub Actions to create and approve pull requests" (task
326
+ // install-ci-enables-actions-pr-creation). Off on a new repo, and with it off
327
+ // GitHub refuses every propose-mode PR the workflows open with GITHUB_TOKEN.
328
+ // Same posture as branch protection: set when off and admin-scoped (keeping
329
+ // default_workflow_permissions), print the exact command otherwise, report
330
+ // only under --fake.
331
+ const actionsPrCreation = await installCIActionsPrCreationStep({
332
+ ctx: options.ctx,
333
+ fake,
334
+ log,
335
+ });
336
+ for (const line of prApprovalReminderLines(secrets)) {
337
+ log(line);
338
+ }
314
339
  // CI-autonomy posture (task `install-ci-emits-no-gate-env-let-config-decide`):
315
340
  // the emitted advance workflow carries NO DORFL_AUTO_BUILD /
316
341
  // DORFL_AUTO_TASK / DORFL_OBSERVATION_TRIAGE /
@@ -361,7 +386,49 @@ export async function installCI(
361
386
  log(
362
387
  'without that hook the conflicting case is unsupported. install-ci does NOT detect likely conflicts — this is a documented boundary.',
363
388
  );
364
- return {outcome: 'generated', config, written, secrets, branchProtection};
389
+ return {
390
+ outcome: 'generated',
391
+ config,
392
+ written,
393
+ secrets,
394
+ branchProtection,
395
+ actionsPrCreation,
396
+ };
397
+ }
398
+
399
+ /**
400
+ * The closing-summary note (task `document-that-bot-opened-prs-need-approval`)
401
+ * about GitHub holding the `verify` run of a PR opened with `GITHUB_TOKEN` in
402
+ * `action_required` until someone approves it. When this run did NOT set the
403
+ * PR-identity token (skipped, failed, or `--fake`, where no secret is touched)
404
+ * the advance PRs fall back to `GITHUB_TOKEN`, so the full note is printed. When
405
+ * it was set, only the intake line remains true: `intake.yml` never passes
406
+ * {@link PR_IDENTITY_SECRET_NAME} (`ci-split-generate-workflows` Decisions), so
407
+ * intake PRs always need the approval. See `docs/ci/README.md`.
408
+ */
409
+ export function prApprovalReminderLines(secrets: SecretSetResult[]): string[] {
410
+ const name = PR_IDENTITY_SECRET_NAME;
411
+ const tokenSet = secrets.some((r) => r.name === name && r.status === 'set');
412
+ const intakeLine = ` - intake PRs always need it: intake.yml keeps the built-in GITHUB_TOKEN and never passes ${name}.`;
413
+ const approveLine =
414
+ ' To approve: open the PR, Files changed, "Awaiting approval", "Approve workflows to run" (see docs/ci/README.md).';
415
+ if (tokenSet) {
416
+ return [
417
+ '',
418
+ `PR approval: ${name} is set, so advance PRs trigger verify on their own.`,
419
+ intakeLine,
420
+ approveLine,
421
+ ];
422
+ }
423
+ return [
424
+ '',
425
+ `PR approval: no ${name} was set in this run. Unless that secret already exists on the repository,`,
426
+ ' the workflows open PRs with GITHUB_TOKEN, and GitHub holds their verify run in "action_required"',
427
+ ' until someone with write access approves it:',
428
+ ` - advance PRs (build, tasking): set ${name} (a PAT or App token) and they trigger verify on their own;`,
429
+ intakeLine,
430
+ approveLine,
431
+ ];
365
432
  }
366
433
 
367
434
  /**
@@ -400,54 +467,33 @@ async function gatherSecretsForExport(
400
467
  // ─── The interactive wizard ──────────────────────────────────────────────────
401
468
 
402
469
  /**
403
- * The interactive wizard: gather the auth mode, providers/models (models-json) or
404
- * the default provider/model (auth-json), and the harness, into a
405
- * {@link CIConfigFile}. Drives the {@link WizardPrompts} seam, so it runs
406
- * deterministically in tests and the gathered shape exactly equals a config-file
407
- * input — the equivalence the snapshot test pins. Mirrors whitesmith's prompt
408
- * flow (provider type → key env var → models → defaults).
470
+ * The interactive wizard: gather the providers/models and the harness into a
471
+ * {@link CIConfigFile}. There is no auth-mode prompt: `models-json` is the only
472
+ * mode (the former `auth-json` mode was removed, see {@link AuthMode}); OAuth or
473
+ * other rotating credentials go behind a proxy set as a provider's `baseUrl`.
474
+ * Drives the {@link WizardPrompts} seam, so it runs deterministically in tests
475
+ * and the gathered shape exactly equals a config-file input, the equivalence the
476
+ * snapshot test pins. Mirrors whitesmith's prompt flow (provider type → key env
477
+ * var → models → defaults).
409
478
  */
410
479
  export async function runWizard(prompts: WizardPrompts): Promise<CIConfigFile> {
411
- const authMode = await prompts.select<AuthMode>('Auth mode:', [
412
- {
413
- name: 'models.json (default — one GitHub secret per provider key)',
414
- value: 'models-json',
415
- },
416
- {
417
- name: 'auth.json (single PI_AUTH_JSON + GH_PAT + OAuth refresh — the sharp edge)',
418
- value: 'auth-json',
419
- },
420
- ]);
421
-
422
480
  const harness = await prompts.select<HarnessAdapter>('Agent harness:', [
423
481
  {name: 'pi (the pi coding agent)', value: 'pi'},
424
482
  {name: 'null (shell out to a configured agentCmd)', value: 'null'},
425
483
  ]);
426
484
 
427
- if (authMode === 'auth-json') {
428
- // auth.json mode: no per-provider keys, but the harness still needs a
429
- // default provider/model for its invocations.
430
- const defaultProvider = await prompts.input('Default AI provider:', {
431
- default: 'anthropic',
432
- });
433
- const defaultModel = await prompts.input('Default AI model:', {
434
- default: 'claude-sonnet-4-20250514',
435
- });
436
- return {
437
- authMode,
438
- providers: [],
439
- defaultProvider,
440
- defaultModel,
441
- harness,
442
- };
443
- }
444
-
445
485
  const providers = await promptProviders(prompts);
446
486
  const {defaultProvider, defaultModel} = await promptDefaults(
447
487
  prompts,
448
488
  providers,
449
489
  );
450
- return {authMode, providers, defaultProvider, defaultModel, harness};
490
+ return {
491
+ authMode: 'models-json',
492
+ providers,
493
+ defaultProvider,
494
+ defaultModel,
495
+ harness,
496
+ };
451
497
  }
452
498
 
453
499
  /** Prompt for one or more providers (the models-json path). */
@@ -45,7 +45,12 @@ export type IntakeMarkerKind = 'ask' | 'bounced' | 'created';
45
45
  export interface IntakeMarker {
46
46
  /** What intake did (a neutral fact; the TRIAGE owns terminal-ness, not this). */
47
47
  kind: IntakeMarkerKind;
48
- /** The HUMAN comment ids intake READ this run (the per-run delta; may be empty). */
48
+ /**
49
+ * The HUMAN comment ids intake READ this run (the per-run delta; may be
50
+ * empty). A CI run (task `ci-split-intake`) records EVERY comment id its lock
51
+ * job read (intake's own and already-seen ones included): the apply job has
52
+ * only the ids, and a superset of read ids is harmless to the triage.
53
+ */
49
54
  seen: string[];
50
55
  /** The created task/spec slug \u2014 present only on `kind=created`. */
51
56
  slug?: string;
@@ -89,8 +89,12 @@ export function triageIntake(comments: IssueComment[]): IntakeTriageDecision {
89
89
  const humanComments = comments.filter(
90
90
  (c) => parseIntakeMarker(c.body) === undefined,
91
91
  );
92
- const currentHumanIds = new Set(
93
- humanComments
92
+ // EVERY comment id still in the thread (not only the human ones): a CI run's
93
+ // `seen=` lists every comment id its lock job read, intake's own included
94
+ // (task `ci-split-intake`), and an intake comment that is still there was
95
+ // not deleted.
96
+ const currentIds = new Set(
97
+ comments
94
98
  .map((c) => c.id)
95
99
  .filter((id): id is string => id !== undefined && id !== ''),
96
100
  );
@@ -105,7 +109,7 @@ export function triageIntake(comments: IssueComment[]): IntakeTriageDecision {
105
109
  // previously-seen human id no longer present in the thread was deleted.
106
110
  let deletedSeenCount = 0;
107
111
  for (const id of seenSet) {
108
- if (!currentHumanIds.has(id)) {
112
+ if (!currentIds.has(id)) {
109
113
  deletedSeenCount += 1;
110
114
  }
111
115
  }