dorfl 0.0.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (619) hide show
  1. package/dist/advance-ci-template.d.ts +73 -0
  2. package/dist/advance-ci-template.d.ts.map +1 -0
  3. package/dist/advance-ci-template.js +104 -0
  4. package/dist/advance-ci-template.js.map +1 -0
  5. package/dist/advance-classify.d.ts +132 -0
  6. package/dist/advance-classify.d.ts.map +1 -0
  7. package/dist/advance-classify.js +120 -0
  8. package/dist/advance-classify.js.map +1 -0
  9. package/dist/advance-drivers.d.ts +182 -0
  10. package/dist/advance-drivers.d.ts.map +1 -0
  11. package/dist/advance-drivers.js +231 -0
  12. package/dist/advance-drivers.js.map +1 -0
  13. package/dist/advance-isolated.d.ts +156 -0
  14. package/dist/advance-isolated.d.ts.map +1 -0
  15. package/dist/advance-isolated.js +256 -0
  16. package/dist/advance-isolated.js.map +1 -0
  17. package/dist/advance-lifecycle-template.d.ts +107 -0
  18. package/dist/advance-lifecycle-template.d.ts.map +1 -0
  19. package/dist/advance-lifecycle-template.js +668 -0
  20. package/dist/advance-lifecycle-template.js.map +1 -0
  21. package/dist/advance-loop-driver.d.ts +325 -0
  22. package/dist/advance-loop-driver.d.ts.map +1 -0
  23. package/dist/advance-loop-driver.js +437 -0
  24. package/dist/advance-loop-driver.js.map +1 -0
  25. package/dist/advance-treeless-publish.d.ts +108 -0
  26. package/dist/advance-treeless-publish.d.ts.map +1 -0
  27. package/dist/advance-treeless-publish.js +71 -0
  28. package/dist/advance-treeless-publish.js.map +1 -0
  29. package/dist/advance.d.ts +340 -0
  30. package/dist/advance.d.ts.map +1 -0
  31. package/dist/advance.js +1122 -0
  32. package/dist/advance.js.map +1 -0
  33. package/dist/advancing-lock.d.ts +294 -0
  34. package/dist/advancing-lock.d.ts.map +1 -0
  35. package/dist/advancing-lock.js +594 -0
  36. package/dist/advancing-lock.js.map +1 -0
  37. package/dist/agent-launch.d.ts +79 -0
  38. package/dist/agent-launch.d.ts.map +1 -0
  39. package/dist/agent-launch.js +61 -0
  40. package/dist/agent-launch.js.map +1 -0
  41. package/dist/agent-stop.d.ts +149 -0
  42. package/dist/agent-stop.d.ts.map +1 -0
  43. package/dist/agent-stop.js +307 -0
  44. package/dist/agent-stop.js.map +1 -0
  45. package/dist/apply-decide.d.ts +127 -0
  46. package/dist/apply-decide.d.ts.map +1 -0
  47. package/dist/apply-decide.js +176 -0
  48. package/dist/apply-decide.js.map +1 -0
  49. package/dist/apply-merge-action.d.ts +206 -0
  50. package/dist/apply-merge-action.d.ts.map +1 -0
  51. package/dist/apply-merge-action.js +307 -0
  52. package/dist/apply-merge-action.js.map +1 -0
  53. package/dist/apply-persist.d.ts +174 -0
  54. package/dist/apply-persist.d.ts.map +1 -0
  55. package/dist/apply-persist.js +359 -0
  56. package/dist/apply-persist.js.map +1 -0
  57. package/dist/arbiter.d.ts +120 -0
  58. package/dist/arbiter.d.ts.map +1 -0
  59. package/dist/arbiter.js +255 -0
  60. package/dist/arbiter.js.map +1 -0
  61. package/dist/brand.d.ts +70 -0
  62. package/dist/brand.d.ts.map +1 -0
  63. package/dist/brand.js +84 -0
  64. package/dist/brand.js.map +1 -0
  65. package/dist/buildable-body.d.ts +132 -0
  66. package/dist/buildable-body.d.ts.map +1 -0
  67. package/dist/buildable-body.js +131 -0
  68. package/dist/buildable-body.js.map +1 -0
  69. package/dist/categorise.d.ts +66 -0
  70. package/dist/categorise.d.ts.map +1 -0
  71. package/dist/categorise.js +106 -0
  72. package/dist/categorise.js.map +1 -0
  73. package/dist/claim-cas.d.ts +117 -0
  74. package/dist/claim-cas.d.ts.map +1 -0
  75. package/dist/claim-cas.js +312 -0
  76. package/dist/claim-cas.js.map +1 -0
  77. package/dist/cli-spinner.d.ts +112 -0
  78. package/dist/cli-spinner.d.ts.map +1 -0
  79. package/dist/cli-spinner.js +157 -0
  80. package/dist/cli-spinner.js.map +1 -0
  81. package/dist/cli.d.ts +11 -0
  82. package/dist/cli.d.ts.map +1 -0
  83. package/dist/cli.js +3094 -0
  84. package/dist/cli.js.map +1 -0
  85. package/dist/close-job-template.d.ts +70 -0
  86. package/dist/close-job-template.d.ts.map +1 -0
  87. package/dist/close-job-template.js +180 -0
  88. package/dist/close-job-template.js.map +1 -0
  89. package/dist/close-job.d.ts +95 -0
  90. package/dist/close-job.d.ts.map +1 -0
  91. package/dist/close-job.js +226 -0
  92. package/dist/close-job.js.map +1 -0
  93. package/dist/complete.d.ts +361 -0
  94. package/dist/complete.d.ts.map +1 -0
  95. package/dist/complete.js +885 -0
  96. package/dist/complete.js.map +1 -0
  97. package/dist/concurrency.d.ts +68 -0
  98. package/dist/concurrency.d.ts.map +1 -0
  99. package/dist/concurrency.js +112 -0
  100. package/dist/concurrency.js.map +1 -0
  101. package/dist/config-override.d.ts +76 -0
  102. package/dist/config-override.d.ts.map +1 -0
  103. package/dist/config-override.js +50 -0
  104. package/dist/config-override.js.map +1 -0
  105. package/dist/config.d.ts +668 -0
  106. package/dist/config.d.ts.map +1 -0
  107. package/dist/config.js +241 -0
  108. package/dist/config.js.map +1 -0
  109. package/dist/continue-branch.d.ts +249 -0
  110. package/dist/continue-branch.d.ts.map +1 -0
  111. package/dist/continue-branch.js +389 -0
  112. package/dist/continue-branch.js.map +1 -0
  113. package/dist/cwd-section.d.ts +186 -0
  114. package/dist/cwd-section.d.ts.map +1 -0
  115. package/dist/cwd-section.js +209 -0
  116. package/dist/cwd-section.js.map +1 -0
  117. package/dist/decision-engine.d.ts +170 -0
  118. package/dist/decision-engine.d.ts.map +1 -0
  119. package/dist/decision-engine.js +136 -0
  120. package/dist/decision-engine.js.map +1 -0
  121. package/dist/detect.d.ts +17 -0
  122. package/dist/detect.d.ts.map +1 -0
  123. package/dist/detect.js +118 -0
  124. package/dist/detect.js.map +1 -0
  125. package/dist/do-autopick.d.ts +85 -0
  126. package/dist/do-autopick.d.ts.map +1 -0
  127. package/dist/do-autopick.js +112 -0
  128. package/dist/do-autopick.js.map +1 -0
  129. package/dist/do-config.d.ts +312 -0
  130. package/dist/do-config.d.ts.map +1 -0
  131. package/dist/do-config.js +358 -0
  132. package/dist/do-config.js.map +1 -0
  133. package/dist/do-remote-auto.d.ts +75 -0
  134. package/dist/do-remote-auto.d.ts.map +1 -0
  135. package/dist/do-remote-auto.js +111 -0
  136. package/dist/do-remote-auto.js.map +1 -0
  137. package/dist/do.d.ts +621 -0
  138. package/dist/do.d.ts.map +1 -0
  139. package/dist/do.js +1882 -0
  140. package/dist/do.js.map +1 -0
  141. package/dist/drop-source.d.ts +96 -0
  142. package/dist/drop-source.d.ts.map +1 -0
  143. package/dist/drop-source.js +91 -0
  144. package/dist/drop-source.js.map +1 -0
  145. package/dist/eligibility.d.ts +46 -0
  146. package/dist/eligibility.d.ts.map +1 -0
  147. package/dist/eligibility.js +34 -0
  148. package/dist/eligibility.js.map +1 -0
  149. package/dist/env-config.d.ts +51 -0
  150. package/dist/env-config.d.ts.map +1 -0
  151. package/dist/env-config.js +272 -0
  152. package/dist/env-config.js.map +1 -0
  153. package/dist/failure-cause.d.ts +70 -0
  154. package/dist/failure-cause.d.ts.map +1 -0
  155. package/dist/failure-cause.js +126 -0
  156. package/dist/failure-cause.js.map +1 -0
  157. package/dist/format.d.ts +43 -0
  158. package/dist/format.d.ts.map +1 -0
  159. package/dist/format.js +256 -0
  160. package/dist/format.js.map +1 -0
  161. package/dist/frontmatter.d.ts +215 -0
  162. package/dist/frontmatter.d.ts.map +1 -0
  163. package/dist/frontmatter.js +345 -0
  164. package/dist/frontmatter.js.map +1 -0
  165. package/dist/gate-readiness.d.ts +84 -0
  166. package/dist/gate-readiness.d.ts.map +1 -0
  167. package/dist/gate-readiness.js +103 -0
  168. package/dist/gate-readiness.js.map +1 -0
  169. package/dist/gc.d.ts +165 -0
  170. package/dist/gc.d.ts.map +1 -0
  171. package/dist/gc.js +313 -0
  172. package/dist/gc.js.map +1 -0
  173. package/dist/gh-failure.d.ts +42 -0
  174. package/dist/gh-failure.d.ts.map +1 -0
  175. package/dist/gh-failure.js +49 -0
  176. package/dist/gh-failure.js.map +1 -0
  177. package/dist/git.d.ts +75 -0
  178. package/dist/git.d.ts.map +1 -0
  179. package/dist/git.js +130 -0
  180. package/dist/git.js.map +1 -0
  181. package/dist/github.d.ts +187 -0
  182. package/dist/github.d.ts.map +1 -0
  183. package/dist/github.js +343 -0
  184. package/dist/github.js.map +1 -0
  185. package/dist/harness.d.ts +242 -0
  186. package/dist/harness.d.ts.map +1 -0
  187. package/dist/harness.js +157 -0
  188. package/dist/harness.js.map +1 -0
  189. package/dist/identity.d.ts +167 -0
  190. package/dist/identity.d.ts.map +1 -0
  191. package/dist/identity.js +231 -0
  192. package/dist/identity.js.map +1 -0
  193. package/dist/index.d.ts +147 -0
  194. package/dist/index.d.ts.map +1 -0
  195. package/dist/index.js +76 -0
  196. package/dist/index.js.map +1 -0
  197. package/dist/install-ci-branch-protection.d.ts +147 -0
  198. package/dist/install-ci-branch-protection.d.ts.map +1 -0
  199. package/dist/install-ci-branch-protection.js +166 -0
  200. package/dist/install-ci-branch-protection.js.map +1 -0
  201. package/dist/install-ci-capabilities/advance-lifecycle.d.ts +15 -0
  202. package/dist/install-ci-capabilities/advance-lifecycle.d.ts.map +1 -0
  203. package/dist/install-ci-capabilities/advance-lifecycle.js +28 -0
  204. package/dist/install-ci-capabilities/advance-lifecycle.js.map +1 -0
  205. package/dist/install-ci-capabilities/close-job.d.ts +13 -0
  206. package/dist/install-ci-capabilities/close-job.d.ts.map +1 -0
  207. package/dist/install-ci-capabilities/close-job.js +26 -0
  208. package/dist/install-ci-capabilities/close-job.js.map +1 -0
  209. package/dist/install-ci-capabilities/example-noop.d.ts +16 -0
  210. package/dist/install-ci-capabilities/example-noop.d.ts.map +1 -0
  211. package/dist/install-ci-capabilities/example-noop.js +23 -0
  212. package/dist/install-ci-capabilities/example-noop.js.map +1 -0
  213. package/dist/install-ci-capabilities/intake.d.ts +15 -0
  214. package/dist/install-ci-capabilities/intake.d.ts.map +1 -0
  215. package/dist/install-ci-capabilities/intake.js +28 -0
  216. package/dist/install-ci-capabilities/intake.js.map +1 -0
  217. package/dist/install-ci-capabilities/verify.d.ts +14 -0
  218. package/dist/install-ci-capabilities/verify.d.ts.map +1 -0
  219. package/dist/install-ci-capabilities/verify.js +27 -0
  220. package/dist/install-ci-capabilities/verify.js.map +1 -0
  221. package/dist/install-ci-core.d.ts +446 -0
  222. package/dist/install-ci-core.d.ts.map +1 -0
  223. package/dist/install-ci-core.js +760 -0
  224. package/dist/install-ci-core.js.map +1 -0
  225. package/dist/install-ci-github.d.ts +167 -0
  226. package/dist/install-ci-github.d.ts.map +1 -0
  227. package/dist/install-ci-github.js +315 -0
  228. package/dist/install-ci-github.js.map +1 -0
  229. package/dist/install-ci.d.ts +105 -0
  230. package/dist/install-ci.d.ts.map +1 -0
  231. package/dist/install-ci.js +363 -0
  232. package/dist/install-ci.js.map +1 -0
  233. package/dist/intake-event.d.ts +88 -0
  234. package/dist/intake-event.d.ts.map +1 -0
  235. package/dist/intake-event.js +66 -0
  236. package/dist/intake-event.js.map +1 -0
  237. package/dist/intake-marker.d.ts +95 -0
  238. package/dist/intake-marker.d.ts.map +1 -0
  239. package/dist/intake-marker.js +127 -0
  240. package/dist/intake-marker.js.map +1 -0
  241. package/dist/intake-triage.d.ts +48 -0
  242. package/dist/intake-triage.d.ts.map +1 -0
  243. package/dist/intake-triage.js +95 -0
  244. package/dist/intake-triage.js.map +1 -0
  245. package/dist/intake-trigger-template.d.ts +185 -0
  246. package/dist/intake-trigger-template.d.ts.map +1 -0
  247. package/dist/intake-trigger-template.js +449 -0
  248. package/dist/intake-trigger-template.js.map +1 -0
  249. package/dist/intake.d.ts +569 -0
  250. package/dist/intake.d.ts.map +1 -0
  251. package/dist/intake.js +1628 -0
  252. package/dist/intake.js.map +1 -0
  253. package/dist/integration-core.d.ts +539 -0
  254. package/dist/integration-core.d.ts.map +1 -0
  255. package/dist/integration-core.js +2195 -0
  256. package/dist/integration-core.js.map +1 -0
  257. package/dist/integrator.d.ts +343 -0
  258. package/dist/integrator.d.ts.map +1 -0
  259. package/dist/integrator.js +400 -0
  260. package/dist/integrator.js.map +1 -0
  261. package/dist/isolation.d.ts +219 -0
  262. package/dist/isolation.d.ts.map +1 -0
  263. package/dist/isolation.js +261 -0
  264. package/dist/isolation.js.map +1 -0
  265. package/dist/issue-provider.d.ts +349 -0
  266. package/dist/issue-provider.d.ts.map +1 -0
  267. package/dist/issue-provider.js +360 -0
  268. package/dist/issue-provider.js.map +1 -0
  269. package/dist/item-lock.d.ts +626 -0
  270. package/dist/item-lock.d.ts.map +1 -0
  271. package/dist/item-lock.js +1381 -0
  272. package/dist/item-lock.js.map +1 -0
  273. package/dist/item-path.d.ts +49 -0
  274. package/dist/item-path.d.ts.map +1 -0
  275. package/dist/item-path.js +66 -0
  276. package/dist/item-path.js.map +1 -0
  277. package/dist/ledger-lint.d.ts +129 -0
  278. package/dist/ledger-lint.d.ts.map +1 -0
  279. package/dist/ledger-lint.js +249 -0
  280. package/dist/ledger-lint.js.map +1 -0
  281. package/dist/ledger-read.d.ts +357 -0
  282. package/dist/ledger-read.d.ts.map +1 -0
  283. package/dist/ledger-read.js +442 -0
  284. package/dist/ledger-read.js.map +1 -0
  285. package/dist/ledger-write.d.ts +330 -0
  286. package/dist/ledger-write.d.ts.map +1 -0
  287. package/dist/ledger-write.js +411 -0
  288. package/dist/ledger-write.js.map +1 -0
  289. package/dist/lifecycle-gather.d.ts +30 -0
  290. package/dist/lifecycle-gather.d.ts.map +1 -0
  291. package/dist/lifecycle-gather.js +205 -0
  292. package/dist/lifecycle-gather.js.map +1 -0
  293. package/dist/lifecycle-pools.d.ts +180 -0
  294. package/dist/lifecycle-pools.d.ts.map +1 -0
  295. package/dist/lifecycle-pools.js +78 -0
  296. package/dist/lifecycle-pools.js.map +1 -0
  297. package/dist/merge-question-surfacer.d.ts +166 -0
  298. package/dist/merge-question-surfacer.d.ts.map +1 -0
  299. package/dist/merge-question-surfacer.js +297 -0
  300. package/dist/merge-question-surfacer.js.map +1 -0
  301. package/dist/mint-adr.d.ts +126 -0
  302. package/dist/mint-adr.d.ts.map +1 -0
  303. package/dist/mint-adr.js +257 -0
  304. package/dist/mint-adr.js.map +1 -0
  305. package/dist/mirror-pool-scan.d.ts +125 -0
  306. package/dist/mirror-pool-scan.d.ts.map +1 -0
  307. package/dist/mirror-pool-scan.js +104 -0
  308. package/dist/mirror-pool-scan.js.map +1 -0
  309. package/dist/needs-attention.d.ts +341 -0
  310. package/dist/needs-attention.d.ts.map +1 -0
  311. package/dist/needs-attention.js +900 -0
  312. package/dist/needs-attention.js.map +1 -0
  313. package/dist/orphan-sidecar.d.ts +79 -0
  314. package/dist/orphan-sidecar.d.ts.map +1 -0
  315. package/dist/orphan-sidecar.js +71 -0
  316. package/dist/orphan-sidecar.js.map +1 -0
  317. package/dist/output.d.ts +48 -0
  318. package/dist/output.d.ts.map +1 -0
  319. package/dist/output.js +66 -0
  320. package/dist/output.js.map +1 -0
  321. package/dist/pi-harness.d.ts +179 -0
  322. package/dist/pi-harness.d.ts.map +1 -0
  323. package/dist/pi-harness.js +342 -0
  324. package/dist/pi-harness.js.map +1 -0
  325. package/dist/placement.d.ts +99 -0
  326. package/dist/placement.d.ts.map +1 -0
  327. package/dist/placement.js +67 -0
  328. package/dist/placement.js.map +1 -0
  329. package/dist/prd-to-spec.d.ts +315 -0
  330. package/dist/prd-to-spec.d.ts.map +1 -0
  331. package/dist/prd-to-spec.js +684 -0
  332. package/dist/prd-to-spec.js.map +1 -0
  333. package/dist/prepare.d.ts +121 -0
  334. package/dist/prepare.d.ts.map +1 -0
  335. package/dist/prepare.js +140 -0
  336. package/dist/prepare.js.map +1 -0
  337. package/dist/prompt.d.ts +360 -0
  338. package/dist/prompt.d.ts.map +1 -0
  339. package/dist/prompt.js +499 -0
  340. package/dist/prompt.js.map +1 -0
  341. package/dist/protocol/ADR-FORMAT.md +47 -0
  342. package/dist/protocol/CLAIM-PROTOCOL.md +217 -0
  343. package/dist/protocol/REVIEW-PROTOCOL.md +119 -0
  344. package/dist/protocol/SURFACE-PROTOCOL.md +121 -0
  345. package/dist/protocol/TASKING-PROTOCOL.md +122 -0
  346. package/dist/protocol/WORK-CONTRACT.md +276 -0
  347. package/dist/protocol/spec-template.md +71 -0
  348. package/dist/protocol/task-template.md +65 -0
  349. package/dist/readiness.d.ts +66 -0
  350. package/dist/readiness.d.ts.map +1 -0
  351. package/dist/readiness.js +36 -0
  352. package/dist/readiness.js.map +1 -0
  353. package/dist/reap-branches.d.ts +102 -0
  354. package/dist/reap-branches.d.ts.map +1 -0
  355. package/dist/reap-branches.js +149 -0
  356. package/dist/reap-branches.js.map +1 -0
  357. package/dist/recover-isolated.d.ts +72 -0
  358. package/dist/recover-isolated.d.ts.map +1 -0
  359. package/dist/recover-isolated.js +188 -0
  360. package/dist/recover-isolated.js.map +1 -0
  361. package/dist/registry.d.ts +172 -0
  362. package/dist/registry.d.ts.map +1 -0
  363. package/dist/registry.js +296 -0
  364. package/dist/registry.js.map +1 -0
  365. package/dist/repo-config.d.ts +201 -0
  366. package/dist/repo-config.d.ts.map +1 -0
  367. package/dist/repo-config.js +414 -0
  368. package/dist/repo-config.js.map +1 -0
  369. package/dist/repo-key.d.ts +20 -0
  370. package/dist/repo-key.d.ts.map +1 -0
  371. package/dist/repo-key.js +68 -0
  372. package/dist/repo-key.js.map +1 -0
  373. package/dist/repo-mirror.d.ts +177 -0
  374. package/dist/repo-mirror.d.ts.map +1 -0
  375. package/dist/repo-mirror.js +271 -0
  376. package/dist/repo-mirror.js.map +1 -0
  377. package/dist/retry-backoff.d.ts +90 -0
  378. package/dist/retry-backoff.d.ts.map +1 -0
  379. package/dist/retry-backoff.js +98 -0
  380. package/dist/retry-backoff.js.map +1 -0
  381. package/dist/review-gate.d.ts +173 -0
  382. package/dist/review-gate.d.ts.map +1 -0
  383. package/dist/review-gate.js +261 -0
  384. package/dist/review-gate.js.map +1 -0
  385. package/dist/review-verdict.d.ts +149 -0
  386. package/dist/review-verdict.d.ts.map +1 -0
  387. package/dist/review-verdict.js +332 -0
  388. package/dist/review-verdict.js.map +1 -0
  389. package/dist/run.d.ts +221 -0
  390. package/dist/run.d.ts.map +1 -0
  391. package/dist/run.js +963 -0
  392. package/dist/run.js.map +1 -0
  393. package/dist/scan.d.ts +308 -0
  394. package/dist/scan.d.ts.map +1 -0
  395. package/dist/scan.js +374 -0
  396. package/dist/scan.js.map +1 -0
  397. package/dist/select-order.d.ts +75 -0
  398. package/dist/select-order.d.ts.map +1 -0
  399. package/dist/select-order.js +108 -0
  400. package/dist/select-order.js.map +1 -0
  401. package/dist/select-priority.d.ts +188 -0
  402. package/dist/select-priority.d.ts.map +1 -0
  403. package/dist/select-priority.js +80 -0
  404. package/dist/select-priority.js.map +1 -0
  405. package/dist/select.d.ts +25 -0
  406. package/dist/select.d.ts.map +1 -0
  407. package/dist/select.js +43 -0
  408. package/dist/select.js.map +1 -0
  409. package/dist/session-path.d.ts +36 -0
  410. package/dist/session-path.d.ts.map +1 -0
  411. package/dist/session-path.js +129 -0
  412. package/dist/session-path.js.map +1 -0
  413. package/dist/sidecar-apply.d.ts +83 -0
  414. package/dist/sidecar-apply.d.ts.map +1 -0
  415. package/dist/sidecar-apply.js +111 -0
  416. package/dist/sidecar-apply.js.map +1 -0
  417. package/dist/sidecar.d.ts +245 -0
  418. package/dist/sidecar.d.ts.map +1 -0
  419. package/dist/sidecar.js +481 -0
  420. package/dist/sidecar.js.map +1 -0
  421. package/dist/slug-namespace.d.ts +204 -0
  422. package/dist/slug-namespace.d.ts.map +1 -0
  423. package/dist/slug-namespace.js +229 -0
  424. package/dist/slug-namespace.js.map +1 -0
  425. package/dist/spec-complete.d.ts +44 -0
  426. package/dist/spec-complete.d.ts.map +1 -0
  427. package/dist/spec-complete.js +69 -0
  428. package/dist/spec-complete.js.map +1 -0
  429. package/dist/start.d.ts +97 -0
  430. package/dist/start.d.ts.map +1 -0
  431. package/dist/start.js +633 -0
  432. package/dist/start.js.map +1 -0
  433. package/dist/status.d.ts +199 -0
  434. package/dist/status.d.ts.map +1 -0
  435. package/dist/status.js +228 -0
  436. package/dist/status.js.map +1 -0
  437. package/dist/surface-gate.d.ts +162 -0
  438. package/dist/surface-gate.d.ts.map +1 -0
  439. package/dist/surface-gate.js +206 -0
  440. package/dist/surface-gate.js.map +1 -0
  441. package/dist/surface-persist.d.ts +86 -0
  442. package/dist/surface-persist.d.ts.map +1 -0
  443. package/dist/surface-persist.js +129 -0
  444. package/dist/surface-persist.js.map +1 -0
  445. package/dist/tasker-review-loop.d.ts +249 -0
  446. package/dist/tasker-review-loop.d.ts.map +1 -0
  447. package/dist/tasker-review-loop.js +369 -0
  448. package/dist/tasker-review-loop.js.map +1 -0
  449. package/dist/tasking-eligibility.d.ts +74 -0
  450. package/dist/tasking-eligibility.d.ts.map +1 -0
  451. package/dist/tasking-eligibility.js +52 -0
  452. package/dist/tasking-eligibility.js.map +1 -0
  453. package/dist/tasking-lock.d.ts +111 -0
  454. package/dist/tasking-lock.d.ts.map +1 -0
  455. package/dist/tasking-lock.js +256 -0
  456. package/dist/tasking-lock.js.map +1 -0
  457. package/dist/tasking.d.ts +275 -0
  458. package/dist/tasking.d.ts.map +1 -0
  459. package/dist/tasking.js +952 -0
  460. package/dist/tasking.js.map +1 -0
  461. package/dist/triage-gate.d.ts +127 -0
  462. package/dist/triage-gate.d.ts.map +1 -0
  463. package/dist/triage-gate.js +139 -0
  464. package/dist/triage-gate.js.map +1 -0
  465. package/dist/triage-persist.d.ts +163 -0
  466. package/dist/triage-persist.d.ts.map +1 -0
  467. package/dist/triage-persist.js +387 -0
  468. package/dist/triage-persist.js.map +1 -0
  469. package/dist/verdict-json.d.ts +32 -0
  470. package/dist/verdict-json.d.ts.map +1 -0
  471. package/dist/verdict-json.js +74 -0
  472. package/dist/verdict-json.js.map +1 -0
  473. package/dist/verify-workflow-template.d.ts +60 -0
  474. package/dist/verify-workflow-template.d.ts.map +1 -0
  475. package/dist/verify-workflow-template.js +126 -0
  476. package/dist/verify-workflow-template.js.map +1 -0
  477. package/dist/verify.d.ts +60 -0
  478. package/dist/verify.d.ts.map +1 -0
  479. package/dist/verify.js +62 -0
  480. package/dist/verify.js.map +1 -0
  481. package/dist/watch-session.d.ts +112 -0
  482. package/dist/watch-session.d.ts.map +1 -0
  483. package/dist/watch-session.js +347 -0
  484. package/dist/watch-session.js.map +1 -0
  485. package/dist/work-layout.d.ts +198 -0
  486. package/dist/work-layout.d.ts.map +1 -0
  487. package/dist/work-layout.js +217 -0
  488. package/dist/work-layout.js.map +1 -0
  489. package/dist/work-on.d.ts +154 -0
  490. package/dist/work-on.d.ts.map +1 -0
  491. package/dist/work-on.js +387 -0
  492. package/dist/work-on.js.map +1 -0
  493. package/dist/workspace.d.ts +224 -0
  494. package/dist/workspace.d.ts.map +1 -0
  495. package/dist/workspace.js +325 -0
  496. package/dist/workspace.js.map +1 -0
  497. package/package.json +46 -2
  498. package/src/advance-ci-template.ts +203 -0
  499. package/src/advance-classify.ts +197 -0
  500. package/src/advance-drivers.ts +414 -0
  501. package/src/advance-isolated.ts +432 -0
  502. package/src/advance-lifecycle-template.ts +791 -0
  503. package/src/advance-loop-driver.ts +745 -0
  504. package/src/advance-treeless-publish.ts +177 -0
  505. package/src/advance.ts +1564 -0
  506. package/src/advancing-lock.ts +988 -0
  507. package/src/agent-launch.ts +137 -0
  508. package/src/agent-stop.ts +361 -0
  509. package/src/apply-decide.ts +242 -0
  510. package/src/apply-merge-action.ts +502 -0
  511. package/src/apply-persist.ts +518 -0
  512. package/src/arbiter.ts +372 -0
  513. package/src/brand.ts +111 -0
  514. package/src/buildable-body.ts +196 -0
  515. package/src/categorise.ts +158 -0
  516. package/src/claim-cas.ts +513 -0
  517. package/src/cli-spinner.ts +225 -0
  518. package/src/cli.ts +4369 -0
  519. package/src/close-job-template.ts +236 -0
  520. package/src/close-job.ts +319 -0
  521. package/src/complete.ts +1379 -0
  522. package/src/concurrency.ts +151 -0
  523. package/src/config-override.ts +116 -0
  524. package/src/config.ts +883 -0
  525. package/src/continue-branch.ts +542 -0
  526. package/src/cwd-section.ts +392 -0
  527. package/src/decision-engine.ts +272 -0
  528. package/src/detect.ts +124 -0
  529. package/src/do-autopick.ts +223 -0
  530. package/src/do-config.ts +589 -0
  531. package/src/do-remote-auto.ts +197 -0
  532. package/src/do.ts +2623 -0
  533. package/src/drop-source.ts +194 -0
  534. package/src/eligibility.ts +79 -0
  535. package/src/env-config.ts +305 -0
  536. package/src/failure-cause.ts +142 -0
  537. package/src/format.ts +313 -0
  538. package/src/frontmatter.ts +485 -0
  539. package/src/gate-readiness.ts +147 -0
  540. package/src/gc.ts +510 -0
  541. package/src/gh-failure.ts +53 -0
  542. package/src/git.ts +186 -0
  543. package/src/github.ts +468 -0
  544. package/src/harness.ts +355 -0
  545. package/src/identity.ts +322 -0
  546. package/src/index.ts +785 -0
  547. package/src/install-ci-branch-protection.ts +255 -0
  548. package/src/install-ci-capabilities/advance-lifecycle.ts +34 -0
  549. package/src/install-ci-capabilities/close-job.ts +32 -0
  550. package/src/install-ci-capabilities/example-noop.ts +24 -0
  551. package/src/install-ci-capabilities/intake.ts +34 -0
  552. package/src/install-ci-capabilities/verify.ts +33 -0
  553. package/src/install-ci-core.ts +1088 -0
  554. package/src/install-ci-github.ts +376 -0
  555. package/src/install-ci.ts +552 -0
  556. package/src/intake-event.ts +102 -0
  557. package/src/intake-marker.ts +195 -0
  558. package/src/intake-triage.ts +138 -0
  559. package/src/intake-trigger-template.ts +591 -0
  560. package/src/intake.ts +2445 -0
  561. package/src/integration-core.ts +3065 -0
  562. package/src/integrator.ts +771 -0
  563. package/src/isolation.ts +484 -0
  564. package/src/issue-provider.ts +733 -0
  565. package/src/item-lock.ts +1858 -0
  566. package/src/item-path.ts +75 -0
  567. package/src/ledger-lint.ts +332 -0
  568. package/src/ledger-read.ts +924 -0
  569. package/src/ledger-write.ts +865 -0
  570. package/src/lifecycle-gather.ts +298 -0
  571. package/src/lifecycle-pools.ts +250 -0
  572. package/src/merge-question-surfacer.ts +496 -0
  573. package/src/mint-adr.ts +362 -0
  574. package/src/mirror-pool-scan.ts +240 -0
  575. package/src/needs-attention.ts +1506 -0
  576. package/src/orphan-sidecar.ts +150 -0
  577. package/src/output.ts +89 -0
  578. package/src/pi-harness.ts +403 -0
  579. package/src/placement.ts +131 -0
  580. package/src/prd-to-spec.ts +1023 -0
  581. package/src/prepare.ts +230 -0
  582. package/src/prompt.ts +760 -0
  583. package/src/readiness.ts +98 -0
  584. package/src/reap-branches.ts +278 -0
  585. package/src/recover-isolated.ts +276 -0
  586. package/src/registry.ts +475 -0
  587. package/src/repo-config.ts +550 -0
  588. package/src/repo-key.ts +74 -0
  589. package/src/repo-mirror.ts +367 -0
  590. package/src/retry-backoff.ts +130 -0
  591. package/src/review-gate.ts +389 -0
  592. package/src/review-verdict.ts +422 -0
  593. package/src/run.ts +1430 -0
  594. package/src/scan.ts +611 -0
  595. package/src/select-order.ts +143 -0
  596. package/src/select-priority.ts +266 -0
  597. package/src/select.ts +62 -0
  598. package/src/session-path.ts +153 -0
  599. package/src/sidecar-apply.ts +216 -0
  600. package/src/sidecar.ts +700 -0
  601. package/src/slug-namespace.ts +367 -0
  602. package/src/spec-complete.ts +118 -0
  603. package/src/start.ts +974 -0
  604. package/src/status.ts +441 -0
  605. package/src/surface-gate.ts +337 -0
  606. package/src/surface-persist.ts +241 -0
  607. package/src/tasker-review-loop.ts +671 -0
  608. package/src/tasking-eligibility.ts +114 -0
  609. package/src/tasking-lock.ts +416 -0
  610. package/src/tasking.ts +1438 -0
  611. package/src/triage-gate.ts +248 -0
  612. package/src/triage-persist.ts +570 -0
  613. package/src/verdict-json.ts +73 -0
  614. package/src/verify-workflow-template.ts +159 -0
  615. package/src/verify.ts +123 -0
  616. package/src/watch-session.ts +397 -0
  617. package/src/work-layout.ts +262 -0
  618. package/src/work-on.ts +660 -0
  619. package/src/workspace.ts +502 -0
@@ -0,0 +1,733 @@
1
+ import {run, type RunResult} from './git.js';
2
+ import {DEFAULT_GH_BIN} from './github.js';
3
+ import {
4
+ GH_BINARY_MISSING,
5
+ ghFailureDetail,
6
+ ghFailureReason,
7
+ } from './gh-failure.js';
8
+ import {brand} from './brand.js';
9
+
10
+ /**
11
+ * The single provider-native PROCESSING LOCK label (task `intake-processing-lock`,
12
+ * prd `issue-intake` US #10): a TRANSIENT concurrency mutex — added on start (the
13
+ * winner only), removed on finish — that serialises two concurrent `intake` runs on
14
+ * the SAME issue. It is namespaced under the brand (`dorfl:processing`) so it
15
+ * cannot collide with a user's own labels. It carries NO `work/` state — it is NOT a
16
+ * label STATE-MACHINE (ADR §12) and NOT a `work/`-file CAS; it is ONE transient lock
17
+ * label and nothing more.
18
+ */
19
+ export const PROCESSING_LOCK_LABEL = `${brand.base}:processing`;
20
+
21
+ /**
22
+ * The **issue seam** (prd `issue-intake`, task `intake-tracer-slice-outcome`):
23
+ * the provider-pluggable surface `intake <N>` reads an issue + its comment thread
24
+ * through, and posts a clarifying comment back onto. It is the SIBLING of the
25
+ * review-request `ReviewProvider` (`integrator.ts` / `github.ts`): both name a
26
+ * GitHub-backed surface behind a seam, and both keep the CORE free of any `gh`
27
+ * import — ONLY the adapter shells out (the same discipline `github.ts` documents).
28
+ *
29
+ * The READ methods (`getIssue`, `listComments`) + the issue comment
30
+ * (`postIssueComment`) landed with the keystone task; the LABEL ops
31
+ * (`addLabel`/`removeLabel`/`getLabels` — the transient `processing` LOCK, task
32
+ * `intake-processing-lock`) extend it. `closeIssue` (task
33
+ * `intake-closes-issue-on-bounce`) is the ATOMIC close used on a BOUNCE — a
34
+ * terminal outcome, so intake closes the issue directly (comment + `not planned`
35
+ * + close in ONE call). It is ALSO the method CI's future close-job uses for the
36
+ * task/prd path; only the BOUNCE close is intake's.
37
+ *
38
+ * The label ops are a TRANSIENT CONCURRENCY MUTEX carrying NO `work/` state — ONE
39
+ * lock label, added-on-start / removed-on-finish. They are NOT a label
40
+ * STATE-MACHINE (ADR §12 forbids modelling `work/` lifecycle in labels) and NOT a
41
+ * `work/`-file CAS (the contended thing is the ISSUE; the output slug is unknown
42
+ * pre-run). A provider with no label concept DEGRADES to best-effort (it reports
43
+ * `supported: false` / `applied: false` and the run proceeds WITHOUT the lock).
44
+ *
45
+ * Why `postIssueComment` is a DISTINCT method from `ReviewProvider.postPRComment`
46
+ * (renamed from `postComment` in this same task): the PR-comment surface is keyed
47
+ * by the PR **url**; the issue-comment surface is keyed by the issue **number**. In
48
+ * GitHub the two comment id spaces happen to coincide, but another provider may not
49
+ * share them — so they are nominally distinct seams with distinct input types
50
+ * ({@link PostIssueCommentInput} carries `issueNumber`, NOT a `url`).
51
+ *
52
+ * Tests STUB `gh` via the injectable `ghBin` (the SAME mechanism the PR-provider
53
+ * tests use) — no network, no real GitHub.
54
+ */
55
+
56
+ /** A GitHub issue's durable fields the decision prompt reads. */
57
+ export interface Issue {
58
+ /** The issue number (`#N`). */
59
+ number: number;
60
+ /** The issue title. */
61
+ title: string;
62
+ /** The issue body (markdown), possibly empty. */
63
+ body: string;
64
+ /** The issue author's login (e.g. `octocat`), when the provider reports one. */
65
+ author?: string;
66
+ /** `open` / `closed` — the provider's state string, lower-cased. */
67
+ state?: string;
68
+ }
69
+
70
+ /** One comment on the issue thread (oldest-first, as `listComments` returns them). */
71
+ export interface IssueComment {
72
+ /**
73
+ * The provider's comment id (`gh issue view --json comments` reports it). Surfaced
74
+ * for the intake TRIAGE GATE (task `intake-self-awareness-resumption-tracking`):
75
+ * the triage is id-set membership + list position only — it records which comment
76
+ * ids intake READ (the marker's `seen=<id>,…`) and detects raced-in / deleted
77
+ * comments by id arithmetic. ADDITIVE (no existing reader breaks); NO `createdAt`
78
+ * is added — nothing reads a timestamp (ordering is `listComments`' oldest-first).
79
+ */
80
+ id?: string;
81
+ /** The comment author's login, when reported. */
82
+ author?: string;
83
+ /** The comment body (markdown). */
84
+ body: string;
85
+ }
86
+
87
+ export interface GetIssueInput {
88
+ cwd: string;
89
+ /** The issue number to read (`intake <N>`). */
90
+ issueNumber: number;
91
+ env?: NodeJS.ProcessEnv;
92
+ }
93
+
94
+ export interface ListCommentsInput {
95
+ cwd: string;
96
+ issueNumber: number;
97
+ env?: NodeJS.ProcessEnv;
98
+ }
99
+
100
+ export interface PostIssueCommentInput {
101
+ cwd: string;
102
+ /**
103
+ * The issue number to comment ON — the issue-comment surface's KEY. This is the
104
+ * whole reason {@link IssueProvider.postIssueComment} is a sibling of (not a
105
+ * reuse of) `ReviewProvider.postPRComment`, which is keyed by the PR `url`.
106
+ */
107
+ issueNumber: number;
108
+ /** The comment body (markdown). */
109
+ body: string;
110
+ env?: NodeJS.ProcessEnv;
111
+ }
112
+
113
+ export interface PostIssueCommentResult {
114
+ /** True iff a comment was actually posted (a real, authenticated provider). */
115
+ posted: boolean;
116
+ /** Human-readable confirmation / fallback (the text on degrade). */
117
+ instruction: string;
118
+ }
119
+
120
+ /**
121
+ * The close-reason GitHub renders distinct from a "completed" close. `gh issue
122
+ * close --reason` accepts `completed | not planned | duplicate`; a BOUNCE is
123
+ * precisely `not planned` (the asks are unrelated and must be re-filed). The
124
+ * INTERFACE carries it provider-neutrally — a non-GitHub adapter maps or ignores
125
+ * it (the seam stays provider-pluggable; `reason` is a GitHub-ism on the wire).
126
+ */
127
+ export type IssueCloseReason = 'completed' | 'not planned' | 'duplicate';
128
+
129
+ export interface CloseIssueInput {
130
+ cwd: string;
131
+ /** The issue number to close (`gh issue close <N>`). */
132
+ issueNumber: number;
133
+ /**
134
+ * An OPTIONAL closing comment posted IN THE SAME atomic operation as the close
135
+ * (`gh issue close --comment <body>`). Carrying it on the close call (not a
136
+ * separate `postIssueComment` then close) removes the comment-posted-but-close-
137
+ * failed window — the whole point of the atomic close.
138
+ */
139
+ comment?: string;
140
+ /** An OPTIONAL close reason (`gh issue close --reason "not planned"`). */
141
+ reason?: IssueCloseReason;
142
+ env?: NodeJS.ProcessEnv;
143
+ }
144
+
145
+ export interface CloseIssueResult {
146
+ /** True iff the issue was actually closed (a real, authenticated provider). */
147
+ closed: boolean;
148
+ /**
149
+ * The REAL underlying failure detail when `closed` is false — the actual `gh`
150
+ * stderr via {@link ghFailureReason}, NOT a hard-coded "unavailable or
151
+ * unauthenticated" guess (that misattribution bug was fixed in `mutateLabel`;
152
+ * do not propagate it). Absent on success.
153
+ */
154
+ reason?: string;
155
+ /** Human-readable confirmation / fallback (the text on degrade). */
156
+ instruction: string;
157
+ }
158
+
159
+ export interface LabelInput {
160
+ cwd: string;
161
+ /** The issue number to label / read labels FROM. */
162
+ issueNumber: number;
163
+ env?: NodeJS.ProcessEnv;
164
+ }
165
+
166
+ export interface AddLabelInput extends LabelInput {
167
+ /** The single label to add (e.g. the `processing` lock). */
168
+ label: string;
169
+ }
170
+
171
+ export interface RemoveLabelInput extends LabelInput {
172
+ /** The single label to remove (e.g. the `processing` lock). */
173
+ label: string;
174
+ }
175
+
176
+ /**
177
+ * The OUTCOME of a label MUTATION (`addLabel` / `removeLabel`). The lock ops are a
178
+ * CONCURRENCY mutex, so the caller must distinguish THREE genuinely-different
179
+ * results — collapsing them (the original bug) sent a maintainer hunting an auth
180
+ * problem that did not exist, and made a real lock-failure proceed lock-less:
181
+ *
182
+ * - **`applied`** — the provider made the change on the real surface (the winner
183
+ * acquired / released the lock label).
184
+ * - **`unsupported`** — the provider has NO label concept at all (a non-GitHub
185
+ * provider without labels). The lock LEGITIMATELY degrades to best-effort here
186
+ * (the spec's provider-pluggability): there is simply nothing to lock on.
187
+ * - **`failed`** — the provider DOES support labels but the op failed for a REAL
188
+ * reason (a missing/unauthenticated `gh`, a permissions error, an unexpected
189
+ * `gh` failure). This is NOT a legitimate degrade: the lock is meaningful but
190
+ * could not be taken, so the caller must FAIL / back off rather than silently
191
+ * proceed lock-less (maintainer decision — see {@link LabelResult.reason}).
192
+ *
193
+ * NEVER throws — the seam reports the outcome (the caller decides fail-vs-degrade),
194
+ * the same never-crash discipline the comment poster / PR provider keep (ADR §6).
195
+ */
196
+ export type LabelOutcome = 'applied' | 'unsupported' | 'failed';
197
+
198
+ export interface LabelResult {
199
+ /** Which of the three outcomes occurred (the caller routes fail-vs-degrade on this). */
200
+ outcome: LabelOutcome;
201
+ /**
202
+ * True iff the label change was actually applied on the provider surface
203
+ * (`outcome === 'applied'`). Retained as a convenience for the acquire/release
204
+ * sites; the THREE-way `outcome` is the load-bearing discriminator.
205
+ */
206
+ applied: boolean;
207
+ /**
208
+ * The REAL underlying failure detail when `outcome === 'failed'` — the actual
209
+ * `gh` stderr (e.g. `'dorfl:processing' not found`), NOT a hard-coded
210
+ * "unavailable or unauthenticated" guess. Surfaced so the cause is diagnosable.
211
+ * Absent for `applied` / `unsupported`.
212
+ */
213
+ reason?: string;
214
+ /** Human-readable confirmation / degrade-or-failure reason. */
215
+ instruction: string;
216
+ }
217
+
218
+ /**
219
+ * The result of READING an issue's labels — the lock READ that decides acquire vs
220
+ * back-off. Like {@link LabelResult} it distinguishes the SAME three outcomes so
221
+ * the caller never confuses a genuinely-unsupported provider (legitimate degrade)
222
+ * with a real read FAILURE on a label-supporting provider (must NOT silently
223
+ * proceed lock-less):
224
+ *
225
+ * - **`ok`** — the labels were read (`labels` carries them; possibly empty).
226
+ * - **`unsupported`** — the provider has NO label concept (legitimate degrade).
227
+ * - **`failed`** — a label-supporting provider could not be read (e.g. `gh`
228
+ * missing/unauthenticated): the lock STATE is unknown, so the caller must FAIL
229
+ * rather than guess "no lock held".
230
+ */
231
+ export type GetLabelsOutcome = 'ok' | 'unsupported' | 'failed';
232
+
233
+ export interface GetLabelsResult {
234
+ /** Which of the three outcomes occurred (the caller routes fail-vs-degrade on this). */
235
+ outcome: GetLabelsOutcome;
236
+ /**
237
+ * False iff the provider has no label surface at all (`outcome === 'unsupported'`)
238
+ * — retained for back-compat; the three-way `outcome` is load-bearing. A `failed`
239
+ * read is ALSO `supported: false` historically, but `outcome` separates them.
240
+ */
241
+ supported: boolean;
242
+ /** The labels currently on the issue (empty when none / unsupported / failed). */
243
+ labels: string[];
244
+ /**
245
+ * The REAL underlying failure detail when `outcome === 'failed'` — the actual
246
+ * `gh` stderr, NOT a hard-coded "unavailable or unauthenticated" guess.
247
+ */
248
+ reason?: string;
249
+ /** Human-readable confirmation / degrade-or-failure reason. */
250
+ instruction: string;
251
+ }
252
+
253
+ /**
254
+ * The issue seam (provider-pluggable; GitHub via `gh` first). The CORE depends on
255
+ * THIS interface only; the concrete `gh` shelling-out lives entirely in
256
+ * {@link GitHubIssueProvider}. A non-GitHub provider can follow the same shape.
257
+ */
258
+ export interface IssueProvider {
259
+ /** Stable provider name stamped into diagnostics (`github`, …). */
260
+ readonly name: string;
261
+ /** Read the issue (number/title/body/author/state). */
262
+ getIssue(input: GetIssueInput): Promise<Issue>;
263
+ /** Read the issue's comment thread, oldest-first. */
264
+ listComments(input: ListCommentsInput): Promise<IssueComment[]>;
265
+ /** Post a clarifying comment on the issue (keyed by the issue NUMBER). */
266
+ postIssueComment(
267
+ input: PostIssueCommentInput,
268
+ ): Promise<PostIssueCommentResult>;
269
+ /**
270
+ * Read the issue's current labels — the lock READ that decides acquire vs
271
+ * back-off. NEVER throws; returns a three-way {@link GetLabelsResult}: `ok`
272
+ * (labels read), `unsupported` (no label concept → legitimate degrade), or
273
+ * `failed` (a label-supporting provider could not be read → the caller FAILS
274
+ * rather than guessing the lock is free).
275
+ */
276
+ getLabels(input: LabelInput): Promise<GetLabelsResult>;
277
+ /**
278
+ * ADD a single label (acquire the `processing` lock — the winner only). The
279
+ * RUNNER calls this; the agent stays label-free. NEVER throws — it returns a
280
+ * three-way {@link LabelResult} (`applied` / `unsupported` / `failed`) so the
281
+ * caller can FAIL on a real lock-acquire failure (e.g. `gh` unauthenticated)
282
+ * rather than silently proceed lock-less. On a label-supporting provider where
283
+ * the lock label does not exist yet (a fresh repo), it CREATES the label first
284
+ * so the lock works from the first run, then adds it.
285
+ */
286
+ addLabel(input: AddLabelInput): Promise<LabelResult>;
287
+ /**
288
+ * REMOVE a single label (release the `processing` lock on finish — success OR
289
+ * handled failure). The RUNNER calls this; the agent stays label-free. NEVER
290
+ * throws; returns the three-way {@link LabelResult} like {@link addLabel}.
291
+ */
292
+ removeLabel(input: RemoveLabelInput): Promise<LabelResult>;
293
+ /**
294
+ * CLOSE an issue, OPTIONALLY posting a closing comment and setting a close
295
+ * reason IN THE SAME atomic operation (`gh issue close <N> [--comment <body>]
296
+ * [--reason "not planned"]`). Used on a BOUNCE (terminal: comment + `not
297
+ * planned` + close in ONE call — no post-then-close partial-failure window) and,
298
+ * later, by CI's task/prd close-job. The RUNNER calls this; the agent stays
299
+ * seam-free. NEVER throws — a missing/unauthenticated `gh` DEGRADES, surfacing
300
+ * the REAL `gh` stderr via {@link CloseIssueResult.reason} (NOT a hard-coded
301
+ * guess), so the terminal outcome is unchanged and the cause stays diagnosable.
302
+ */
303
+ closeIssue(input: CloseIssueInput): Promise<CloseIssueResult>;
304
+ }
305
+
306
+ export interface GitHubIssueProviderOptions {
307
+ /**
308
+ * The `gh` CLI binary (default `gh` on `PATH`). Tests inject a stub script so
309
+ * the seam is exercised without a real model / network / GitHub — the SAME test
310
+ * seam the {@link GitHubProvider} (review-request) uses.
311
+ */
312
+ ghBin?: string;
313
+ }
314
+
315
+ /**
316
+ * The GitHub issue provider: reads an issue + thread, posts a comment, and (on a
317
+ * BOUNCE) atomically closes the issue by shelling out to the `gh` CLI (`gh issue
318
+ * view` / `gh issue comment` / `gh issue close --comment --reason` / `gh issue
319
+ * edit` for labels). It is the ONLY place in the issue-seam stack that invokes
320
+ * `gh` — the core never
321
+ * imports it (the same boundary `github.ts` keeps for the review-request seam).
322
+ *
323
+ * The READ methods THROW on a `gh` failure (a missing/unauthenticated `gh`, or an
324
+ * unknown issue): `intake` cannot decide without the issue, so a read failure is a
325
+ * hard, surfaced error (unlike the review-request `openRequest`, whose work is
326
+ * already safely pushed and so degrades). `postIssueComment` is advisory and
327
+ * DEGRADES (never throws), like the PR-comment poster.
328
+ */
329
+ export class GitHubIssueProvider implements IssueProvider {
330
+ readonly name = 'github';
331
+ private readonly ghBin: string;
332
+
333
+ constructor(options: GitHubIssueProviderOptions = {}) {
334
+ this.ghBin = options.ghBin ?? DEFAULT_GH_BIN;
335
+ }
336
+
337
+ async getIssue(input: GetIssueInput): Promise<Issue> {
338
+ const result = this.runGh(
339
+ [
340
+ 'issue',
341
+ 'view',
342
+ String(input.issueNumber),
343
+ '--json',
344
+ 'number,title,body,author,state',
345
+ ],
346
+ input.cwd,
347
+ input.env,
348
+ );
349
+ const parsed = this.parseJson(result, `read issue #${input.issueNumber}`);
350
+ return normaliseIssue(input.issueNumber, parsed);
351
+ }
352
+
353
+ async listComments(input: ListCommentsInput): Promise<IssueComment[]> {
354
+ const result = this.runGh(
355
+ ['issue', 'view', String(input.issueNumber), '--json', 'comments'],
356
+ input.cwd,
357
+ input.env,
358
+ );
359
+ const parsed = this.parseJson(
360
+ result,
361
+ `read comments on issue #${input.issueNumber}`,
362
+ );
363
+ return normaliseComments(parsed);
364
+ }
365
+
366
+ async postIssueComment(
367
+ input: PostIssueCommentInput,
368
+ ): Promise<PostIssueCommentResult> {
369
+ const result = this.runGh(
370
+ ['issue', 'comment', String(input.issueNumber), '--body', input.body],
371
+ input.cwd,
372
+ input.env,
373
+ );
374
+ // Advisory: a failed `gh` DEGRADES (surface the text), never throws — mirroring
375
+ // the PR-comment poster (ADR §6). Surface the REAL `gh` cause via
376
+ // `ghFailureReason` (or the missing-binary detail) — NOT a hard-coded
377
+ // "unavailable or unauthenticated" guess (the misattribution already removed
378
+ // from `mutateLabel`/`closeIssue`; this was the last contagion source).
379
+ if (result === undefined || result.status !== 0) {
380
+ const reason = ghFailureDetail(result);
381
+ return {
382
+ posted: false,
383
+ instruction:
384
+ `could not post the comment on issue #${input.issueNumber}: ` +
385
+ `${reason}. The comment:\n${input.body}`,
386
+ };
387
+ }
388
+ return {
389
+ posted: true,
390
+ instruction: `Posted a comment on issue #${input.issueNumber}.`,
391
+ };
392
+ }
393
+
394
+ async closeIssue(input: CloseIssueInput): Promise<CloseIssueResult> {
395
+ // ATOMIC: post the closing comment AND set the reason AND close in ONE
396
+ // `gh issue close` call — NOT a separate post-then-close (which has a
397
+ // comment-posted-but-close-failed window: the dishonest open-with-bounce-comment
398
+ // state this task closes TO AVOID).
399
+ const args = ['issue', 'close', String(input.issueNumber)];
400
+ if (input.comment !== undefined && input.comment !== '') {
401
+ args.push('--comment', input.comment);
402
+ }
403
+ if (input.reason !== undefined) {
404
+ args.push('--reason', input.reason);
405
+ }
406
+ const result = this.runGh(args, input.cwd, input.env);
407
+ // DEGRADE (never throw) on a missing/unauthenticated `gh`. Surface the REAL
408
+ // `gh` stderr via `ghFailureReason` — NOT a hard-coded "unavailable or
409
+ // unauthenticated" guess (the misattribution bug already fixed in `mutateLabel`).
410
+ if (result === undefined) {
411
+ const reason = GH_BINARY_MISSING;
412
+ return {
413
+ closed: false,
414
+ reason,
415
+ instruction:
416
+ `could not close issue #${input.issueNumber}: ${reason}` +
417
+ (input.comment ? `\nThe comment:\n${input.comment}` : ''),
418
+ };
419
+ }
420
+ if (result.status !== 0) {
421
+ const reason = ghFailureReason(result);
422
+ return {
423
+ closed: false,
424
+ reason,
425
+ instruction:
426
+ `could not close issue #${input.issueNumber}: ${reason}` +
427
+ (input.comment ? `\nThe comment:\n${input.comment}` : ''),
428
+ };
429
+ }
430
+ return {
431
+ closed: true,
432
+ instruction: `Closed issue #${input.issueNumber}.`,
433
+ };
434
+ }
435
+
436
+ async getLabels(input: LabelInput): Promise<GetLabelsResult> {
437
+ const result = this.runGh(
438
+ ['issue', 'view', String(input.issueNumber), '--json', 'labels'],
439
+ input.cwd,
440
+ input.env,
441
+ );
442
+ // GitHub HAS labels: a failed read is `failed`, NOT `unsupported`. Surfacing
443
+ // the REAL `gh` stderr (not a hard-coded "unauthenticated" guess) keeps the
444
+ // cause diagnosable; the caller FAILS rather than guessing the lock is free.
445
+ if (result === undefined) {
446
+ return {
447
+ outcome: 'failed',
448
+ supported: false,
449
+ labels: [],
450
+ reason: GH_BINARY_MISSING,
451
+ instruction:
452
+ `could not read the labels on issue #${input.issueNumber}: ` +
453
+ GH_BINARY_MISSING,
454
+ };
455
+ }
456
+ if (result.status !== 0) {
457
+ const reason = ghFailureReason(result);
458
+ return {
459
+ outcome: 'failed',
460
+ supported: false,
461
+ labels: [],
462
+ reason,
463
+ instruction: `could not read the labels on issue #${input.issueNumber}: ${reason}`,
464
+ };
465
+ }
466
+ let labels: string[];
467
+ try {
468
+ labels = normaliseLabels(JSON.parse(result.stdout) as unknown);
469
+ } catch {
470
+ return {
471
+ outcome: 'failed',
472
+ supported: false,
473
+ labels: [],
474
+ reason: 'could not parse the `gh` labels JSON.',
475
+ instruction: `could not parse the labels JSON for issue #${input.issueNumber}.`,
476
+ };
477
+ }
478
+ return {
479
+ outcome: 'ok',
480
+ supported: true,
481
+ labels,
482
+ instruction: `Read ${labels.length} label(s) on issue #${input.issueNumber}.`,
483
+ };
484
+ }
485
+
486
+ async addLabel(input: AddLabelInput): Promise<LabelResult> {
487
+ return this.mutateLabel('--add-label', input);
488
+ }
489
+
490
+ async removeLabel(input: RemoveLabelInput): Promise<LabelResult> {
491
+ return this.mutateLabel('--remove-label', input);
492
+ }
493
+
494
+ /**
495
+ * Shared `gh issue edit <N> --add-label|--remove-label <label>` runner for the
496
+ * label MUTATIONS (the lock acquire/release). NEVER throws — it reports a
497
+ * three-way {@link LabelResult} so the CALLER decides fail-vs-degrade (the lock
498
+ * acquire-site FAILS on `failed`; only a genuinely-unsupported provider degrades).
499
+ *
500
+ * On `--add-label` against a fresh repo where the lock label does NOT exist yet,
501
+ * `gh` exits non-zero with `'<label>' not found`. We CREATE the label (`gh label
502
+ * create`) and RETRY the add, so the lock works from the very first `intake` run
503
+ * (a fresh repo is lockable without a manual `gh label create`). Label creation
504
+ * is idempotent-enough for our purpose: a concurrent create loses harmlessly
505
+ * (the retry add then succeeds against the now-existing label).
506
+ */
507
+ private mutateLabel(
508
+ flag: '--add-label' | '--remove-label',
509
+ input: AddLabelInput | RemoveLabelInput,
510
+ ): LabelResult {
511
+ const verb = flag === '--add-label' ? 'add' : 'remove';
512
+ let result = this.runGh(
513
+ ['issue', 'edit', String(input.issueNumber), flag, input.label],
514
+ input.cwd,
515
+ input.env,
516
+ );
517
+
518
+ // Fresh-repo case: the label has never been created, so the add fails with
519
+ // `'<label>' not found`. Create it (settled decision: create-on-first-use), then
520
+ // retry — so the lock is usable from the first run rather than a hard failure.
521
+ if (
522
+ flag === '--add-label' &&
523
+ result !== undefined &&
524
+ result.status !== 0 &&
525
+ isLabelNotFound(result, input.label)
526
+ ) {
527
+ const created = this.createLabel(input.label, input.cwd, input.env);
528
+ if (created.ok) {
529
+ result = this.runGh(
530
+ ['issue', 'edit', String(input.issueNumber), flag, input.label],
531
+ input.cwd,
532
+ input.env,
533
+ );
534
+ } else if (created.reason !== undefined) {
535
+ // The CREATE failed for a real reason (e.g. a token without label-create
536
+ // permission). Surface the CREATE's REAL cause — NOT the original
537
+ // `'<label>' not found` add failure, which is merely the fresh-repo SYMPTOM
538
+ // (the misattribution this fix removes). A missing-`gh` create degrades to
539
+ // the original `result` (handled below) like the rest of the seam.
540
+ return {
541
+ outcome: 'failed',
542
+ applied: false,
543
+ reason: created.reason,
544
+ instruction:
545
+ `could not ${verb} the \`${input.label}\` label on issue ` +
546
+ `#${input.issueNumber}: ${created.reason}`,
547
+ };
548
+ }
549
+ }
550
+
551
+ if (result === undefined) {
552
+ return {
553
+ outcome: 'failed',
554
+ applied: false,
555
+ reason: GH_BINARY_MISSING,
556
+ instruction:
557
+ `could not ${verb} the \`${input.label}\` label on issue ` +
558
+ `#${input.issueNumber}: ${GH_BINARY_MISSING}`,
559
+ };
560
+ }
561
+ if (result.status !== 0) {
562
+ const reason = ghFailureReason(result);
563
+ return {
564
+ outcome: 'failed',
565
+ applied: false,
566
+ reason,
567
+ // Surface the REAL `gh` stderr (e.g. `'dorfl:processing' not found`),
568
+ // never a hard-coded "unavailable or unauthenticated" guess — the cause must
569
+ // be diagnosable.
570
+ instruction:
571
+ `could not ${verb} the \`${input.label}\` label on issue ` +
572
+ `#${input.issueNumber}: ${reason}`,
573
+ };
574
+ }
575
+ return {
576
+ outcome: 'applied',
577
+ applied: true,
578
+ instruction: `${verb === 'add' ? 'Added' : 'Removed'} the \`${input.label}\` label on issue #${input.issueNumber}.`,
579
+ };
580
+ }
581
+
582
+ /**
583
+ * Create the lock label (`gh label create <label>`) so a fresh repo is lockable
584
+ * from the first run. Returns a three-way result rather than a bare boolean so the
585
+ * caller can surface the CREATE's REAL cause (the original bug threw the stderr
586
+ * away, leaving `mutateLabel` to report the fresh-repo SYMPTOM `'<label>' not
587
+ * found` even on a permission-denied create):
588
+ *
589
+ * - **`{ok: true}`** — the label now exists (created here, or it already existed —
590
+ * `gh` reports `already exists`, which we treat as success).
591
+ * - **`{ok: false}`** (no `reason`) — `gh` is MISSING (binary absent): degrade to
592
+ * the caller's existing missing-`gh` handling (the never-hard-fail posture).
593
+ * - **`{ok: false, reason}`** — the create FAILED for a real reason (e.g. no
594
+ * permission): the caller surfaces `reason` (the create's REAL `gh` stderr).
595
+ *
596
+ * NEVER throws.
597
+ */
598
+ private createLabel(
599
+ label: string,
600
+ cwd: string,
601
+ env: NodeJS.ProcessEnv | undefined,
602
+ ): {ok: boolean; reason?: string} {
603
+ const result = this.runGh(
604
+ [
605
+ 'label',
606
+ 'create',
607
+ label,
608
+ '--description',
609
+ 'dorfl intake processing lock (transient concurrency mutex)',
610
+ ],
611
+ cwd,
612
+ env,
613
+ );
614
+ // Missing `gh`: no reason to surface — degrade to the caller's missing-`gh`
615
+ // handling (keeps the never-hard-fail posture unchanged).
616
+ if (result === undefined) {
617
+ return {ok: false};
618
+ }
619
+ if (result.status === 0) {
620
+ return {ok: true};
621
+ }
622
+ // A concurrent run created it first — `gh` reports "already exists"; that is a
623
+ // success for our purpose (the label is present for the retry).
624
+ if (/already exists/i.test(result.stderr)) {
625
+ return {ok: true};
626
+ }
627
+ // A genuine create failure (e.g. no permission): surface its REAL `gh` stderr so
628
+ // `mutateLabel` reports the create's TRUE cause, not the fresh-repo `not found`.
629
+ return {ok: false, reason: ghFailureReason(result)};
630
+ }
631
+
632
+ /**
633
+ * Run `gh <args>` in `cwd`, returning the result, or `undefined` when `gh`
634
+ * cannot even be spawned (binary missing). Mirrors {@link GitHubProvider}'s
635
+ * `runGh` (the spawn-error catch keeps a missing `gh` a clean failure).
636
+ */
637
+ private runGh(
638
+ args: string[],
639
+ cwd: string,
640
+ env: NodeJS.ProcessEnv | undefined,
641
+ ): RunResult | undefined {
642
+ try {
643
+ return run(this.ghBin, args, cwd, {env});
644
+ } catch {
645
+ return undefined; // gh binary not found / not executable
646
+ }
647
+ }
648
+
649
+ /** Parse a `gh --json` read, THROWING a clear error on any failure. */
650
+ private parseJson(result: RunResult | undefined, action: string): unknown {
651
+ if (result === undefined) {
652
+ throw new Error(`failed to ${action}: ${GH_BINARY_MISSING}`);
653
+ }
654
+ if (result.status !== 0) {
655
+ throw new Error(
656
+ `failed to ${action}: \`gh\` exited ${result.status}` +
657
+ (result.stderr.trim() ? ` — ${result.stderr.trim()}` : '') +
658
+ ' (is `gh` authenticated?).',
659
+ );
660
+ }
661
+ try {
662
+ return JSON.parse(result.stdout) as unknown;
663
+ } catch {
664
+ throw new Error(
665
+ `failed to ${action}: could not parse \`gh\` JSON output.`,
666
+ );
667
+ }
668
+ }
669
+ }
670
+
671
+ /**
672
+ * True iff a failed `gh issue edit --add-label` failed because the label does not
673
+ * exist in the repo yet (`gh` prints `'<label>' not found`). On a fresh repo the
674
+ * lock label has never been created, so this is the create-on-first-use trigger —
675
+ * distinct from a real auth/permission failure (which must NOT be papered over).
676
+ */
677
+ function isLabelNotFound(result: RunResult, label: string): boolean {
678
+ const stderr = result.stderr.toLowerCase();
679
+ return stderr.includes('not found') && stderr.includes(label.toLowerCase());
680
+ }
681
+
682
+ /** Map a `gh issue view --json …` object onto the {@link Issue} shape. */
683
+ function normaliseIssue(issueNumber: number, parsed: unknown): Issue {
684
+ const obj = (parsed ?? {}) as Record<string, unknown>;
685
+ const author = obj.author as {login?: string} | undefined;
686
+ return {
687
+ number:
688
+ typeof obj.number === 'number' ? (obj.number as number) : issueNumber,
689
+ title: typeof obj.title === 'string' ? obj.title : '',
690
+ body: typeof obj.body === 'string' ? obj.body : '',
691
+ author: author?.login,
692
+ state:
693
+ typeof obj.state === 'string'
694
+ ? (obj.state as string).toLowerCase()
695
+ : undefined,
696
+ };
697
+ }
698
+
699
+ /** Map a `gh issue view --json labels` object onto the bare label-name list. */
700
+ function normaliseLabels(parsed: unknown): string[] {
701
+ const obj = (parsed ?? {}) as Record<string, unknown>;
702
+ const labels = Array.isArray(obj.labels) ? obj.labels : [];
703
+ return labels
704
+ .map((raw) => {
705
+ const l = (raw ?? {}) as Record<string, unknown>;
706
+ return typeof l.name === 'string' ? l.name : '';
707
+ })
708
+ .filter((name) => name !== '');
709
+ }
710
+
711
+ /** Map a `gh issue view --json comments` object onto the comment list. */
712
+ function normaliseComments(parsed: unknown): IssueComment[] {
713
+ const obj = (parsed ?? {}) as Record<string, unknown>;
714
+ const comments = Array.isArray(obj.comments) ? obj.comments : [];
715
+ return comments.map((raw) => {
716
+ const c = (raw ?? {}) as Record<string, unknown>;
717
+ const author = c.author as {login?: string} | undefined;
718
+ // `gh` reports the comment id as a number or a string depending on the field;
719
+ // normalise to a string (the triage compares ids as opaque tokens, never as
720
+ // numbers). ADDITIVE — absent on a provider that does not report one.
721
+ const id =
722
+ typeof c.id === 'string'
723
+ ? c.id
724
+ : typeof c.id === 'number'
725
+ ? String(c.id)
726
+ : undefined;
727
+ return {
728
+ ...(id !== undefined ? {id} : {}),
729
+ author: author?.login,
730
+ body: typeof c.body === 'string' ? c.body : '',
731
+ };
732
+ });
733
+ }