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,496 @@
1
+ import {existsSync, readFileSync} from 'node:fs';
2
+ import {join} from 'node:path';
3
+ import {run, type RunResult} from './git.js';
4
+ import {isGitHubArbiterUrl, DEFAULT_GH_BIN} from './github.js';
5
+ import {
6
+ parseSidecar,
7
+ sidecarPathFor,
8
+ isEntryAnswered,
9
+ type NewQuestion,
10
+ } from './sidecar.js';
11
+ import {
12
+ persistSurfacedQuestions,
13
+ type SurfacePersistOptions,
14
+ type SurfacePersistResult,
15
+ } from './surface-persist.js';
16
+ import {workItemRel, type WorkFolderKey} from './work-layout.js';
17
+
18
+ /**
19
+ * The **MERGE-QUESTION SURFACER** (prd `land-time-reverify-and-parallel-merge-ceiling`,
20
+ * task `merge-question-surfacer`, US #14) — the SECOND, STATE-sourced surfacer
21
+ * in the advance loop. It is a clean SIBLING to the existing
22
+ * `surface-questions` JUDGEMENT surfacer (`surface-gate.ts` +
23
+ * `surface-persist.ts`) — that one spawns a fresh-context agent to JUDGE an
24
+ * item's open content questions; this one enumerates RUNNER STATE (unmerged
25
+ * `work/*` branches) and surfaces one MERGE-QUESTION per branch into the SAME
26
+ * binary sidecar shape. The judgement skill is UNTOUCHED.
27
+ *
28
+ * The shape is `surface → answer → apply` over the BINARY sidecar (the keystone
29
+ * `agentic-question-resolution-retire-disposition-vocabulary`): a sidecar entry
30
+ * is `no-answer | answered`; there is no `disposition=` token. The dispatch
31
+ * signal the (separate) apply rung reads is the typed `kind` field
32
+ * (`sidecar-kind-field`) — this surfacer STAMPS `kind: merge` on every entry it
33
+ * emits. The `merge | hold | drop` menu rides the entry's `default` as a
34
+ * human-readable HINT only; the apply layer must NEVER recognise a
35
+ * merge-question by the shape of `default` (that string-sniff workaround is
36
+ * exactly what a first build of this task was BLOCKED at review for).
37
+ *
38
+ * Layered like the spec asks: the FLOOR (git-alone reachability) is the
39
+ * authoritative enumerator — it works against a bare `--bare` arbiter with
40
+ * `NoneProvider`. The CEILING (`gh pr list` PR metadata) is pure ENRICHMENT
41
+ * layered on top when a GitHub host is configured; the surfacer functions
42
+ * identically without it.
43
+ *
44
+ * OUT OF SCOPE for this task (covered by sibling tasks of the same prd):
45
+ *
46
+ * - The APPLY rung dispatch that lands an answered `kind: merge` through the
47
+ * land primitive (rebase → re-verify → advance). Task
48
+ * `apply-rung-merge-disposition`.
49
+ * - The GATE axis that decides whether this surfacer runs at all on a given
50
+ * advance tick. Task `merge-questions-gate-axis`.
51
+ *
52
+ * Tests inject the two seams ({@link listUnmergedWorkBranches},
53
+ * {@link listOpenPullRequests}) so they NEVER hit real GitHub — the floor uses
54
+ * `git for-each-ref` against a throwaway repo, the ceiling is the injected
55
+ * `gh pr list` stub.
56
+ */
57
+
58
+ /** A `work/<slug>` branch whose tip is not reachable from `<base>`. */
59
+ export interface UnmergedWorkBranch {
60
+ /** The full short ref, e.g. `work/foo`. */
61
+ ref: string;
62
+ /** The bare slug (`work/` prefix stripped), e.g. `foo`. */
63
+ slug: string;
64
+ /** Branch tip SHA (advisory). */
65
+ sha?: string;
66
+ }
67
+
68
+ /** Minimal PR metadata the ceiling renders into the question context. */
69
+ export interface MergeQuestionPullRequest {
70
+ number: number;
71
+ url?: string;
72
+ title?: string;
73
+ state?: string;
74
+ }
75
+
76
+ /** Inputs to the listings seams (and the surfacer). */
77
+ export interface ListUnmergedInput {
78
+ cwd: string;
79
+ base: string;
80
+ env?: NodeJS.ProcessEnv;
81
+ }
82
+
83
+ export interface ListPullRequestsInput {
84
+ cwd: string;
85
+ ghBin: string;
86
+ base: string;
87
+ env?: NodeJS.ProcessEnv;
88
+ }
89
+
90
+ /** Options the surfacer takes (almost all seams are injectable for tests). */
91
+ export interface SurfaceMergeQuestionsOptions {
92
+ /** Working clone the surfacer reads git refs + writes sidecars from. */
93
+ cwd: string;
94
+ /**
95
+ * The arbiter remote URL — when GitHub-shaped (per
96
+ * {@link isGitHubArbiterUrl}) the CEILING (`gh pr list`) runs. Absent /
97
+ * non-GitHub ⇒ the floor only (a bare arbiter with `NoneProvider`).
98
+ */
99
+ arbiterUrl?: string;
100
+ /** The base branch reachability is checked against. Default `main`. */
101
+ base?: string;
102
+ /** The `gh` CLI binary to invoke for the ceiling. Default `gh` on PATH. */
103
+ ghBin?: string;
104
+ /** Environment for spawned git/gh processes. */
105
+ env?: NodeJS.ProcessEnv;
106
+ /** Sink for human-readable progress notes. */
107
+ note?: (message: string) => void;
108
+ /**
109
+ * Seam: enumerate unmerged `work/*` branches (the FLOOR). Production uses
110
+ * `git for-each-ref` + `git merge-base --is-ancestor`. Tests inject a canned
111
+ * list so the surfacer is exercised over deterministic inputs.
112
+ */
113
+ listUnmergedWorkBranches?: (input: ListUnmergedInput) => UnmergedWorkBranch[];
114
+ /**
115
+ * Seam: list open PRs by branch (the CEILING). Production shells
116
+ * `gh pr list --json …`. Tests inject a stub map so they NEVER touch real
117
+ * GitHub. Skipped entirely when the arbiter is not GitHub-shaped.
118
+ */
119
+ listOpenPullRequests?: (
120
+ input: ListPullRequestsInput,
121
+ ) => Map<string, MergeQuestionPullRequest>;
122
+ /** Seam: persist a single merge-question. Defaults to {@link persistSurfacedQuestions}. */
123
+ persist?: (options: SurfacePersistOptions) => SurfacePersistResult;
124
+ }
125
+
126
+ /** One surfaced merge-question (a row in the result). */
127
+ export interface MergeQuestionSurfaced {
128
+ /** The namespaced item identity (`task:<slug>`). */
129
+ item: string;
130
+ /** The bare slug. */
131
+ slug: string;
132
+ /** The `work/<slug>` ref the question is about. */
133
+ ref: string;
134
+ /** The sidecar path the persist touched (repo-relative). */
135
+ sidecarPath: string;
136
+ /** The persist commit (`undefined` if the persist was a no-op). */
137
+ commit?: string;
138
+ /** PR url when a GitHub ceiling matched the branch (advisory). */
139
+ prUrl?: string;
140
+ }
141
+
142
+ /** One branch the surfacer considered but did not surface (with the reason). */
143
+ export interface MergeQuestionSkipped {
144
+ ref: string;
145
+ slug: string;
146
+ reason: 'no-item-body' | 'already-pending-merge-question' | 'persist-nothing';
147
+ }
148
+
149
+ /** Aggregate result of one surfacer pass. */
150
+ export interface SurfaceMergeQuestionsResult {
151
+ /** How many `work/*` branches were unreachable from `<base>` (the floor). */
152
+ considered: number;
153
+ /** The branches a merge-question was emitted for. */
154
+ surfaced: MergeQuestionSurfaced[];
155
+ /** The branches that were considered but skipped, with the reason. */
156
+ skipped: MergeQuestionSkipped[];
157
+ }
158
+
159
+ /** Raised for fatal usage errors (a missing repo, etc.). */
160
+ export class MergeQuestionSurfacerError extends Error {
161
+ constructor(message: string) {
162
+ super(message);
163
+ this.name = 'MergeQuestionSurfacerError';
164
+ }
165
+ }
166
+
167
+ /** The lifecycle folders a task body may rest in (the FOLDERS the persist
168
+ * needs to find the item file to set `needsAnswers:true` on). Matches
169
+ * `advance.ts`'s `findItemPath` task-folder set. */
170
+ const TASK_FOLDERS: readonly WorkFolderKey[] = [
171
+ 'tasks-ready',
172
+ 'tasks-backlog',
173
+ 'done',
174
+ 'cancelled',
175
+ ] as const;
176
+
177
+ /**
178
+ * Surface merge-questions for every unmerged `work/*` branch in `cwd`.
179
+ *
180
+ * The FLOOR (git reachability) is authoritative; the CEILING (`gh pr list`)
181
+ * runs only when {@link isGitHubArbiterUrl} accepts the arbiter URL, and is
182
+ * pure enrichment (a missing/failed `gh` degrades silently — the floor still
183
+ * surfaces the question).
184
+ *
185
+ * Idempotency: a branch whose sidecar ALREADY carries a PENDING `kind: merge`
186
+ * entry is SKIPPED (with `already-pending-merge-question`). A branch with no
187
+ * item body on `main` is SKIPPED (with `no-item-body`) — the cross-cutting
188
+ * branch-keyed sidecar identity (PRD sidecar Q5-i) is OOS for this task; an
189
+ * unmerged-branch-with-no-body lands on the same skip path until that
190
+ * generalisation arrives.
191
+ */
192
+ export function surfaceMergeQuestions(
193
+ options: SurfaceMergeQuestionsOptions,
194
+ ): SurfaceMergeQuestionsResult {
195
+ const {cwd} = options;
196
+ const base = options.base ?? 'main';
197
+ const env = options.env;
198
+ const note = options.note ?? (() => {});
199
+ const persist = options.persist ?? persistSurfacedQuestions;
200
+
201
+ const listBranches =
202
+ options.listUnmergedWorkBranches ?? listUnmergedWorkBranchesViaGit;
203
+ const branches = listBranches({cwd, base, env});
204
+
205
+ // CEILING: only consult `gh pr list` when the arbiter is GitHub-shaped. A
206
+ // bare / non-GitHub arbiter never spawns `gh` (the floor is sufficient).
207
+ let prs: Map<string, MergeQuestionPullRequest> = new Map();
208
+ const ghEnabled =
209
+ options.arbiterUrl !== undefined && isGitHubArbiterUrl(options.arbiterUrl);
210
+ if (ghEnabled && branches.length > 0) {
211
+ const listPRs = options.listOpenPullRequests ?? listOpenPullRequestsViaGh;
212
+ try {
213
+ prs = listPRs({
214
+ cwd,
215
+ ghBin: options.ghBin ?? DEFAULT_GH_BIN,
216
+ base,
217
+ env,
218
+ });
219
+ } catch (err) {
220
+ // `gh` is the ENRICHMENT layer — a failure must NEVER suppress the
221
+ // floor's surfacing. Note it and proceed with an empty PR map.
222
+ const detail = err instanceof Error ? err.message : String(err);
223
+ note(
224
+ `merge-question surfacer: gh pr list failed (${detail}) — continuing with the git-only floor.`,
225
+ );
226
+ prs = new Map();
227
+ }
228
+ }
229
+
230
+ const surfaced: MergeQuestionSurfaced[] = [];
231
+ const skipped: MergeQuestionSkipped[] = [];
232
+
233
+ for (const branch of branches) {
234
+ const item = `task:${branch.slug}`;
235
+
236
+ // Idempotency: if the sidecar already carries a PENDING `kind: merge`
237
+ // entry, this surfacer must not append a duplicate. (An ANSWERED merge
238
+ // entry is fine — apply will dispatch it; appending a new entry would
239
+ // re-pause the sidecar unnecessarily.)
240
+ if (alreadyHasPendingMergeQuestion(cwd, item)) {
241
+ skipped.push({
242
+ ref: branch.ref,
243
+ slug: branch.slug,
244
+ reason: 'already-pending-merge-question',
245
+ });
246
+ continue;
247
+ }
248
+
249
+ const itemPath = findTaskItemPath(cwd, branch.slug);
250
+ if (itemPath === undefined) {
251
+ // The `branch:`/`ref:`-keyed sidecar identity (PRD sidecar Q5-i, the
252
+ // cross-cutting open question SHARED with the stuck-lock surfacer) is
253
+ // OUT OF SCOPE for this task — without a body to flip `needsAnswers`
254
+ // on, persist would tear the invariant. Skip with the reason so the
255
+ // case is visible to the caller.
256
+ skipped.push({
257
+ ref: branch.ref,
258
+ slug: branch.slug,
259
+ reason: 'no-item-body',
260
+ });
261
+ continue;
262
+ }
263
+
264
+ const pr = prs.get(branch.ref);
265
+ const question = buildMergeQuestion(branch, pr);
266
+
267
+ const result = persist({
268
+ cwd,
269
+ item,
270
+ itemPath,
271
+ questions: [question],
272
+ env,
273
+ note,
274
+ });
275
+ if (result.outcome === 'nothing') {
276
+ skipped.push({
277
+ ref: branch.ref,
278
+ slug: branch.slug,
279
+ reason: 'persist-nothing',
280
+ });
281
+ continue;
282
+ }
283
+
284
+ surfaced.push({
285
+ item,
286
+ slug: branch.slug,
287
+ ref: branch.ref,
288
+ sidecarPath: result.sidecarPath,
289
+ commit: result.commit,
290
+ prUrl: pr?.url,
291
+ });
292
+ }
293
+
294
+ return {considered: branches.length, surfaced, skipped};
295
+ }
296
+
297
+ /**
298
+ * Build the merge-question for ONE unmerged branch.
299
+ *
300
+ * - The QUESTION is a plain English "should this branch land?" prompt.
301
+ * - The CONTEXT carries the floor evidence (the unmerged branch ref) and, if
302
+ * a host PR matched, the ceiling enrichment (PR number, url, title).
303
+ * - The DEFAULT carries `merge | hold | drop` as a HUMAN-READABLE HINT only.
304
+ * The MACHINE dispatch signal is `kind: merge`, NEVER the shape of
305
+ * `default` (the workaround the first build was blocked for).
306
+ * - The KIND is the typed dispatch axis from `sidecar-kind-field` —
307
+ * `kind: merge` is what the apply rung reads to route the answer to the
308
+ * deterministic land primitive.
309
+ */
310
+ function buildMergeQuestion(
311
+ branch: UnmergedWorkBranch,
312
+ pr: MergeQuestionPullRequest | undefined,
313
+ ): NewQuestion {
314
+ const contextLines: string[] = [
315
+ `The branch \`${branch.ref}\` is not reachable from \`main\` — it carries pushed work that has not yet landed.`,
316
+ ];
317
+ if (pr !== undefined) {
318
+ const titleSuffix = pr.title ? `: ${pr.title}` : '';
319
+ const urlSuffix = pr.url ? ` (${pr.url})` : '';
320
+ const stateSuffix = pr.state ? ` [${pr.state}]` : '';
321
+ contextLines.push(
322
+ `Open PR #${pr.number}${stateSuffix}${titleSuffix}${urlSuffix}.`,
323
+ );
324
+ } else {
325
+ contextLines.push(
326
+ `No host PR metadata available (git-alone floor — the branch is the source of truth).`,
327
+ );
328
+ }
329
+ return {
330
+ question: `Land \`${branch.ref}\`? An unmerged \`work/*\` branch is awaiting an integration decision.`,
331
+ context: contextLines.join('\n'),
332
+ // HUMAN HINT only — the apply layer MUST NOT string-sniff this.
333
+ default: 'merge | hold | drop',
334
+ // MACHINE dispatch signal — the apply layer routes on this, not on `default`.
335
+ kind: 'merge',
336
+ };
337
+ }
338
+
339
+ /** Probe the sidecar for an existing pending `kind: merge` entry. */
340
+ function alreadyHasPendingMergeQuestion(cwd: string, item: string): boolean {
341
+ const rel = sidecarPathFor(item);
342
+ const abs = join(cwd, rel);
343
+ if (!existsSync(abs)) {
344
+ return false;
345
+ }
346
+ try {
347
+ const model = parseSidecar(readFileSync(abs, 'utf8'));
348
+ return model.entries.some((e) => e.kind === 'merge' && !isEntryAnswered(e));
349
+ } catch {
350
+ // A malformed sidecar is not THIS surfacer's problem — pretend there is
351
+ // no pending merge-question and let the persist write surface the issue.
352
+ return false;
353
+ }
354
+ }
355
+
356
+ /** Locate the task body `work/<folder>/<slug>.md` across lifecycle folders. */
357
+ function findTaskItemPath(cwd: string, slug: string): string | undefined {
358
+ for (const folder of TASK_FOLDERS) {
359
+ const rel = workItemRel(folder, `${slug}.md`);
360
+ if (existsSync(join(cwd, rel))) {
361
+ return rel;
362
+ }
363
+ }
364
+ return undefined;
365
+ }
366
+
367
+ // --- Production seams ----------------------------------------------------
368
+
369
+ function gitSoft(
370
+ args: string[],
371
+ cwd: string,
372
+ env: NodeJS.ProcessEnv | undefined,
373
+ ): RunResult {
374
+ return run('git', args, cwd, {env});
375
+ }
376
+
377
+ /**
378
+ * Production FLOOR: enumerate every `refs/heads/work/*` whose tip is NOT
379
+ * reachable from `<base>`. A repo with no `<base>` (e.g. a fresh init before
380
+ * the first commit) yields the empty list — the surfacer is a no-op until
381
+ * `main` exists.
382
+ */
383
+ export function listUnmergedWorkBranchesViaGit(
384
+ input: ListUnmergedInput,
385
+ ): UnmergedWorkBranch[] {
386
+ const {cwd, base, env} = input;
387
+ // Bail if `<base>` does not resolve — without a base, "unmerged" is
388
+ // meaningless and we'd over-surface every branch as unmerged.
389
+ const haveBase = gitSoft(
390
+ ['rev-parse', '--verify', '--quiet', base],
391
+ cwd,
392
+ env,
393
+ );
394
+ if (haveBase.status !== 0) {
395
+ return [];
396
+ }
397
+ const refs = gitSoft(
398
+ [
399
+ 'for-each-ref',
400
+ '--format=%(refname:short) %(objectname)',
401
+ 'refs/heads/work/',
402
+ ],
403
+ cwd,
404
+ env,
405
+ );
406
+ if (refs.status !== 0) {
407
+ return [];
408
+ }
409
+ const lines = refs.stdout
410
+ .split('\n')
411
+ .map((l) => l.trim())
412
+ .filter((l) => l !== '');
413
+ const unmerged: UnmergedWorkBranch[] = [];
414
+ for (const line of lines) {
415
+ const space = line.indexOf(' ');
416
+ if (space === -1) {
417
+ continue;
418
+ }
419
+ const ref = line.slice(0, space);
420
+ const sha = line.slice(space + 1).trim();
421
+ if (!ref.startsWith('work/')) {
422
+ continue;
423
+ }
424
+ const slug = ref.slice('work/'.length);
425
+ if (slug === '') {
426
+ continue;
427
+ }
428
+ // `git merge-base --is-ancestor <sha> <base>` — exit 0 ⇒ reachable
429
+ // (merged), exit 1 ⇒ unmerged.
430
+ const reach = gitSoft(['merge-base', '--is-ancestor', sha, base], cwd, env);
431
+ if (reach.status !== 0) {
432
+ unmerged.push({ref, slug, sha});
433
+ }
434
+ }
435
+ return unmerged;
436
+ }
437
+
438
+ /**
439
+ * Production CEILING: shell `gh pr list --state open --json …` and index the
440
+ * results by their `headRefName` so the surfacer can enrich the matching
441
+ * branch's question. A non-zero / missing `gh` is treated as "no host
442
+ * metadata available" — the floor still surfaces every unmerged branch.
443
+ */
444
+ export function listOpenPullRequestsViaGh(
445
+ input: ListPullRequestsInput,
446
+ ): Map<string, MergeQuestionPullRequest> {
447
+ const {cwd, ghBin, base, env} = input;
448
+ const result = run(
449
+ ghBin,
450
+ [
451
+ 'pr',
452
+ 'list',
453
+ '--state',
454
+ 'open',
455
+ '--base',
456
+ base,
457
+ '--limit',
458
+ '200',
459
+ '--json',
460
+ 'number,url,title,headRefName,state',
461
+ ],
462
+ cwd,
463
+ {env},
464
+ );
465
+ if (result.status !== 0) {
466
+ return new Map();
467
+ }
468
+ let parsed: unknown;
469
+ try {
470
+ parsed = JSON.parse(result.stdout);
471
+ } catch {
472
+ return new Map();
473
+ }
474
+ if (!Array.isArray(parsed)) {
475
+ return new Map();
476
+ }
477
+ const out = new Map<string, MergeQuestionPullRequest>();
478
+ for (const raw of parsed) {
479
+ if (typeof raw !== 'object' || raw === null) {
480
+ continue;
481
+ }
482
+ const r = raw as Record<string, unknown>;
483
+ const headRefName = typeof r.headRefName === 'string' ? r.headRefName : '';
484
+ const number = typeof r.number === 'number' ? r.number : undefined;
485
+ if (headRefName === '' || number === undefined) {
486
+ continue;
487
+ }
488
+ out.set(headRefName, {
489
+ number,
490
+ url: typeof r.url === 'string' ? r.url : undefined,
491
+ title: typeof r.title === 'string' ? r.title : undefined,
492
+ state: typeof r.state === 'string' ? r.state : undefined,
493
+ });
494
+ }
495
+ return out;
496
+ }