@joshuafolkken/kit 1.1229.0 → 1.1370.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 (939) hide show
  1. package/.claude/agents/investigator.md +1 -0
  2. package/.claude/settings.json +4 -0
  3. package/.claude/skills/dependency-update/SKILL.md +5 -3
  4. package/.claude/skills/epic-commands/SKILL.md +82 -113
  5. package/.claude/skills/epic-commands/epic-bundle.md +38 -63
  6. package/.claude/skills/epic-commands/execution-waves.md +30 -51
  7. package/.claude/skills/verify-ui/SKILL.md +13 -20
  8. package/.claude/skills/workflow-commands/SKILL.md +10 -10
  9. package/.claude/skills/workflow-commands/background-commands.md +4 -4
  10. package/.claude/skills/workflow-commands/backlogrun-child.md +30 -105
  11. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +29 -0
  12. package/.claude/skills/workflow-commands/backlogrun-lanes.md +45 -131
  13. package/.claude/skills/workflow-commands/backlogrun-park.md +36 -53
  14. package/.claude/skills/workflow-commands/backlogrun-progress.md +81 -331
  15. package/.claude/skills/workflow-commands/backlogrun-recovery.md +29 -83
  16. package/.claude/skills/workflow-commands/backlogrun-steps.md +105 -424
  17. package/.claude/skills/workflow-commands/backlogrun.md +50 -61
  18. package/.claude/skills/workflow-commands/chain-rule.md +36 -40
  19. package/.claude/skills/workflow-commands/entry-sequence.md +6 -6
  20. package/.claude/skills/workflow-commands/followup.md +24 -20
  21. package/.claude/skills/workflow-commands/fullrun-steps.md +23 -27
  22. package/.claude/skills/workflow-commands/fullrun.md +10 -10
  23. package/.claude/skills/workflow-commands/halfrun.md +9 -8
  24. package/.claude/skills/workflow-commands/into-target.md +12 -18
  25. package/.claude/skills/workflow-commands/issue-comments.md +11 -26
  26. package/.claude/skills/workflow-commands/kickoff.md +27 -16
  27. package/.claude/skills/workflow-commands/latest-gate.md +18 -29
  28. package/.claude/skills/workflow-commands/needs-human-review.md +13 -24
  29. package/.claude/skills/workflow-commands/observation-filing.md +37 -28
  30. package/.claude/skills/workflow-commands/observation-ledger.md +48 -38
  31. package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -9
  32. package/.claude/skills/workflow-commands/prerequisite.md +23 -15
  33. package/.claude/skills/workflow-commands/progress-watcher.md +17 -11
  34. package/.claude/skills/workflow-commands/prrun.md +3 -3
  35. package/.claude/skills/workflow-commands/retrospective.md +13 -18
  36. package/.claude/skills/workflow-commands/split-assessment.md +6 -4
  37. package/.claude/skills/workflow-commands/target-repository.md +25 -28
  38. package/.claude/skills/workflow-commands/working-tree-hold.md +11 -17
  39. package/.gitattributes +2 -1
  40. package/.github/workflows/ci.yml +14 -0
  41. package/.github/workflows/publish.yml +2 -0
  42. package/.vscode/tasks.json +14 -0
  43. package/CLAUDE.md +10 -61
  44. package/README.md +38 -57
  45. package/SECURITY.md +1 -1
  46. package/dist/CLAUDE.md +10 -61
  47. package/dist/commands/document-section-cli.js +42 -10
  48. package/dist/config-merge/index.js +11 -2
  49. package/dist/hooks/audit-provision.js +2 -2
  50. package/dist/hooks/batch-guard.js +7 -7
  51. package/dist/hooks/{chunk-FIVDHQGT.js → chunk-43G45XJF.js} +18 -20
  52. package/dist/hooks/{chunk-JUDKDCDP.js → chunk-4TW4MQUL.js} +284 -362
  53. package/dist/hooks/{chunk-5VMKCCC4.js → chunk-76RK6E3H.js} +13 -11
  54. package/dist/hooks/{chunk-RNWHN5BP.js → chunk-DZWZ3DKY.js} +4 -4
  55. package/dist/hooks/{chunk-5VNDSNG3.js → chunk-FZ6FUSBM.js} +1 -1
  56. package/dist/hooks/{chunk-VC3PZPZO.js → chunk-GG72ANKI.js} +1 -1
  57. package/dist/hooks/{chunk-6HJJXRBX.js → chunk-KPM4YIIX.js} +8 -44
  58. package/dist/hooks/chunk-MXVQMLDP.js +3705 -0
  59. package/dist/hooks/{chunk-ELCN5LCH.js → chunk-NEC4AT4Z.js} +34 -12
  60. package/dist/hooks/{chunk-TQNPDZNH.js → chunk-NZBHG6FW.js} +7 -5
  61. package/dist/hooks/chunk-NZN2UFI6.js +2409 -0
  62. package/dist/hooks/{chunk-F56MFS4B.js → chunk-R6CRQEAL.js} +4 -4
  63. package/dist/hooks/chunk-SYSRHRWU.js +1589 -0
  64. package/dist/hooks/{chunk-55HHG5PX.js → chunk-TLJYAGZK.js} +799 -903
  65. package/dist/hooks/chunk-Z5TMJIPW.js +45 -0
  66. package/dist/hooks/codex-hook-adapter.js +26 -21
  67. package/dist/hooks/duplicate-read-guard.js +8 -8
  68. package/dist/hooks/format-edited.js +4 -4
  69. package/dist/hooks/inputs.json +213 -197
  70. package/dist/hooks/investigation-guard.js +8 -8
  71. package/dist/hooks/pretool-guard.js +15 -15
  72. package/dist/hooks/session-lang.js +406 -8
  73. package/dist/hooks/stop-guard.js +122 -201
  74. package/dist/josh.js +540 -137
  75. package/dist/version/index.js +15 -13
  76. package/eslint/base.js +43 -5
  77. package/eslint/rules/english-only-prose.js +3 -3
  78. package/eslint/rules/import.js +12 -0
  79. package/eslint/rules/namespace-object-export.js +2 -2
  80. package/package.json +16 -10
  81. package/pnpm-workspace.yaml +2 -4
  82. package/prompts/coding-standards.md +14 -48
  83. package/prompts/collaboration-workflow/file-edits.md +1 -1
  84. package/prompts/collaboration-workflow/issue-citation.md +1 -1
  85. package/prompts/collaboration-workflow/issue-template.md +4 -10
  86. package/prompts/collaboration-workflow/operating-rules.md +7 -8
  87. package/prompts/collaboration-workflow/output-bounds.md +1 -1
  88. package/prompts/collaboration-workflow/overview.md +1 -1
  89. package/prompts/collaboration-workflow/plan-comment.md +2 -1
  90. package/prompts/collaboration-workflow/principles.md +21 -3
  91. package/prompts/collaboration-workflow/report-format.md +16 -29
  92. package/prompts/collaboration-workflow/residency.md +1 -1
  93. package/prompts/collaboration-workflow/rule-delivery.md +7 -95
  94. package/prompts/collaboration-workflow/shell-body.md +3 -23
  95. package/prompts/collaboration-workflow/turn-batching.md +4 -13
  96. package/prompts/collaboration-workflow/wip-cap.md +5 -11
  97. package/prompts/refactoring.md +1 -1
  98. package/prompts/review-rubric.md +3 -22
  99. package/prompts/review.md +15 -38
  100. package/prompts/testing-guide.md +2 -4
  101. package/scripts/adopt/adopt-logic.ts +5 -5
  102. package/scripts/adopt/adopt-toolkits.ts +4 -5
  103. package/scripts/adopt/adopt.ts +2 -3
  104. package/scripts/agent/agent-argv.ts +7 -7
  105. package/scripts/agent/agent-diagnostics.ts +2 -2
  106. package/scripts/agent/agent-exit-record.ts +1 -1
  107. package/scripts/agent/agent-headless.ts +1 -1
  108. package/scripts/agent/agent-launch-environment.ts +6 -1
  109. package/scripts/agent/agent-role-profile.ts +49 -22
  110. package/scripts/agent/agent-session-role.ts +32 -0
  111. package/scripts/agent/api-outage.ts +1 -1
  112. package/scripts/agent/claude-agent-argv.ts +4 -4
  113. package/scripts/agent/claude-result-event.ts +4 -4
  114. package/scripts/agent/codex-hooks.ts +2 -2
  115. package/scripts/agent/interactive-ask.ts +3 -6
  116. package/scripts/auto-ok/auto-ok-cli.ts +46 -60
  117. package/scripts/backlog/backlog-arrival-added.ts +34 -0
  118. package/scripts/backlog/backlog-arrival.ts +54 -17
  119. package/scripts/backlog/backlog-budget-cli.ts +34 -6
  120. package/scripts/backlog/backlog-budget.ts +17 -24
  121. package/scripts/backlog/backlog-defect-priority.ts +1 -1
  122. package/scripts/backlog/backlog-drive-args.ts +5 -4
  123. package/scripts/backlog/backlog-drive-cli.ts +14 -10
  124. package/scripts/backlog/backlog-drive-epic.ts +85 -0
  125. package/scripts/backlog/backlog-drive-launch.ts +1 -1
  126. package/scripts/backlog/backlog-drive-named-offer.ts +60 -9
  127. package/scripts/backlog/backlog-drive-named.ts +39 -9
  128. package/scripts/backlog/backlog-drive-offer-argv.ts +1 -1
  129. package/scripts/backlog/backlog-drive-restore.ts +1 -1
  130. package/scripts/backlog/backlog-drive-retrospective.ts +2 -2
  131. package/scripts/backlog/backlog-drive.ts +43 -28
  132. package/scripts/backlog/backlog-idle.ts +88 -0
  133. package/scripts/backlog/backlog-named.ts +11 -15
  134. package/scripts/backlog/backlog-next.ts +26 -30
  135. package/scripts/backlog/backlog-offer-cli.ts +28 -23
  136. package/scripts/backlog/backlog-offer.ts +7 -7
  137. package/scripts/backlog/backlog-overlap.ts +178 -0
  138. package/scripts/backlog/backlog-plan-cli.ts +14 -90
  139. package/scripts/backlog/backlog-plan-read.ts +111 -0
  140. package/scripts/backlog/backlog-plan.ts +11 -10
  141. package/scripts/backlog/backlog-pool.ts +13 -14
  142. package/scripts/backlog/backlog-rank.ts +11 -11
  143. package/scripts/backlog/backlog-ready.ts +15 -10
  144. package/scripts/backlog/backlog-scope.ts +14 -15
  145. package/scripts/backlog/backlog-stalled-cli.ts +2 -2
  146. package/scripts/backlog/backlog-stalled-detect.ts +4 -4
  147. package/scripts/backlog/backlog-stalled.ts +5 -6
  148. package/scripts/backlog/backlog-waves.ts +4 -4
  149. package/scripts/backlog/backlogrun-args.ts +74 -0
  150. package/scripts/backlog/backlogrun-cli.ts +113 -0
  151. package/scripts/backlog/backlogrun-launch.ts +178 -0
  152. package/scripts/behavior/behavior-assertion.ts +6 -8
  153. package/scripts/behavior/behavior-cli.ts +1 -1
  154. package/scripts/behavior/behavior-rules.ts +3 -3
  155. package/scripts/build/build-claude-md.ts +4 -4
  156. package/scripts/build/build-codex-hooks.ts +2 -2
  157. package/scripts/build/build-commands.ts +1 -1
  158. package/scripts/build/build-hooks.ts +5 -5
  159. package/scripts/build/build.ts +1 -1
  160. package/scripts/build/hook-bundle-stamp.ts +109 -7
  161. package/scripts/build/local-bin.ts +2 -2
  162. package/scripts/cases/cases-cli.ts +1 -1
  163. package/scripts/cases/cases-logic.ts +2 -2
  164. package/scripts/ci/composite-actions.ts +1 -2
  165. package/scripts/ci/pr-classification.ts +2 -2
  166. package/scripts/claude/workflow-destination.ts +1 -1
  167. package/scripts/clone/clone-aggregate.ts +1 -1
  168. package/scripts/clone/clone-fingerprint.ts +1 -1
  169. package/scripts/clone/clone-scan-cli.ts +1 -1
  170. package/scripts/clone/clone-scan.ts +1 -1
  171. package/scripts/config-merge/index.ts +1 -1
  172. package/scripts/config-merge/json-format.ts +1 -3
  173. package/scripts/config-merge/patch-json-array.ts +90 -0
  174. package/scripts/config-merge/patch-json-key.ts +6 -3
  175. package/scripts/config-merge/patch-json-list.ts +1 -1
  176. package/scripts/cost-runtime/codex-usage.ts +1 -1
  177. package/scripts/cost-runtime/context-cut-payback.ts +4 -5
  178. package/scripts/cost-runtime/context-cut-threshold.ts +4 -6
  179. package/scripts/cost-runtime/cost-attribute.ts +3 -3
  180. package/scripts/cost-runtime/cost-blocks.ts +3 -4
  181. package/scripts/cost-runtime/cost-cli.ts +14 -11
  182. package/scripts/cost-runtime/cost-corpus.ts +11 -11
  183. package/scripts/cost-runtime/cost-pricing.ts +4 -4
  184. package/scripts/cost-runtime/cost-tokens.ts +1 -2
  185. package/scripts/cost-runtime/cost-transcript.ts +29 -29
  186. package/scripts/cost-runtime/cost-usage.ts +6 -7
  187. package/scripts/cost-runtime/cost-verdict.ts +10 -11
  188. package/scripts/cost-runtime/own-session.ts +1 -1
  189. package/scripts/cost-runtime/transcript-cwd.ts +2 -2
  190. package/scripts/delegation/delegation-cli.ts +4 -4
  191. package/scripts/delegation/delegation-policy.ts +13 -15
  192. package/scripts/delegation/duplicate-read-guard.ts +9 -10
  193. package/scripts/delegation/fanout-cli.ts +1 -1
  194. package/scripts/delegation/fanout.ts +1 -1
  195. package/scripts/delegation/investigation-guard.ts +18 -22
  196. package/scripts/delegation/investigation-reads.ts +48 -238
  197. package/scripts/discovery/repo-discovery.ts +1 -1
  198. package/scripts/discovery/repo-map-logic.ts +1 -2
  199. package/scripts/discovery/repo-origin.ts +3 -3
  200. package/scripts/discovery/repo-party-cli.ts +2 -2
  201. package/scripts/discovery/repo-party.ts +2 -2
  202. package/scripts/doctor/doctor-consumer.ts +1 -1
  203. package/scripts/doctor/doctor-io.ts +6 -7
  204. package/scripts/doctor/doctor-logic.ts +1 -1
  205. package/scripts/doctor/doctor-ports.ts +1 -1
  206. package/scripts/doctor/doctor.ts +8 -9
  207. package/scripts/document/backlogrun-parent-read-set.ts +5 -6
  208. package/scripts/document/bash-output-cap.ts +5 -7
  209. package/scripts/document/capped-print-part.ts +1 -1
  210. package/scripts/document/capped-print.ts +1 -1
  211. package/scripts/document/document-byte-budget.ts +33 -64
  212. package/scripts/document/document-byte-check.ts +4 -4
  213. package/scripts/document/document-reachability.ts +7 -8
  214. package/scripts/document/document-read-cli.ts +2 -2
  215. package/scripts/document/document-scan.ts +26 -2
  216. package/scripts/document/document-section-cli.ts +6 -8
  217. package/scripts/document/document-section.ts +8 -12
  218. package/scripts/document/edit-files-cli.ts +3 -4
  219. package/scripts/document/entry-read-budget.ts +8 -70
  220. package/scripts/document/entry-read-set.ts +51 -34
  221. package/scripts/document/lane-child-read-set.ts +9 -9
  222. package/scripts/document/read-files-cli.ts +1 -2
  223. package/scripts/document/read-set-cli.ts +16 -19
  224. package/scripts/document/read-set-cost.ts +4 -4
  225. package/scripts/document/read-set-point-of-use.ts +28 -38
  226. package/scripts/document/read-set-pricing.ts +1 -1
  227. package/scripts/document/read-set-trim.ts +3 -3
  228. package/scripts/document/resident-budget.ts +8 -10
  229. package/scripts/epic/epic-add-body.ts +15 -18
  230. package/scripts/epic/epic-add-plan.ts +26 -28
  231. package/scripts/epic/epic-add.ts +32 -25
  232. package/scripts/epic/epic-audit-checks.ts +27 -37
  233. package/scripts/epic/epic-audit-cli.ts +21 -22
  234. package/scripts/epic/epic-audit-orphans.ts +16 -17
  235. package/scripts/epic/epic-audit-rationale.ts +10 -15
  236. package/scripts/epic/epic-audit-report.ts +2 -5
  237. package/scripts/epic/epic-audit.ts +18 -14
  238. package/scripts/epic/epic-body.ts +10 -10
  239. package/scripts/epic/epic-bundle-cli.ts +36 -34
  240. package/scripts/epic/epic-bundle-evidence.ts +5 -5
  241. package/scripts/epic/epic-bundle-gaps.ts +6 -9
  242. package/scripts/epic/epic-bundle-poll.ts +1 -1
  243. package/scripts/epic/epic-bundle-referenced.ts +11 -14
  244. package/scripts/epic/epic-bundle.ts +19 -20
  245. package/scripts/epic/epic-busy.ts +44 -21
  246. package/scripts/epic/epic-candidate-confirm.ts +15 -18
  247. package/scripts/epic/epic-chains.ts +18 -23
  248. package/scripts/epic/epic-classify.ts +11 -12
  249. package/scripts/epic/epic-cli-argv.ts +5 -6
  250. package/scripts/epic/epic-cli-remove.ts +9 -4
  251. package/scripts/epic/epic-cli.ts +38 -26
  252. package/scripts/epic/epic-close-comment.ts +14 -15
  253. package/scripts/epic/epic-close.ts +25 -29
  254. package/scripts/epic/epic-cross-repo.ts +18 -21
  255. package/scripts/epic/epic-decision.ts +14 -18
  256. package/scripts/epic/epic-fetch.ts +25 -31
  257. package/scripts/epic/epic-graph.ts +15 -17
  258. package/scripts/epic/epic-index.ts +14 -16
  259. package/scripts/epic/epic-issue.ts +9 -11
  260. package/scripts/epic/epic-label-age.ts +74 -0
  261. package/scripts/epic/epic-lane-offer.ts +35 -24
  262. package/scripts/epic/epic-nested.ts +1 -1
  263. package/scripts/epic/epic-next-read.ts +8 -8
  264. package/scripts/epic/epic-next-views.ts +12 -12
  265. package/scripts/epic/epic-next.ts +29 -33
  266. package/scripts/epic/epic-outside-blocker.ts +11 -10
  267. package/scripts/epic/epic-parse.ts +22 -24
  268. package/scripts/epic/epic-promote.ts +3 -2
  269. package/scripts/epic/epic-rank.ts +1 -1
  270. package/scripts/epic/epic-read.ts +10 -8
  271. package/scripts/epic/epic-reconcile.ts +8 -6
  272. package/scripts/epic/epic-reference.ts +5 -4
  273. package/scripts/epic/epic-relation-recheck.ts +10 -11
  274. package/scripts/epic/epic-relations.ts +9 -8
  275. package/scripts/epic/epic-remove-plan.ts +4 -5
  276. package/scripts/epic/epic-remove.ts +7 -5
  277. package/scripts/epic/epic-report.ts +18 -20
  278. package/scripts/epic/epic-run.ts +6 -5
  279. package/scripts/epic/epic-sections.ts +2 -2
  280. package/scripts/epic/epic-shape.ts +3 -3
  281. package/scripts/epic/epic-solo-stale.ts +3 -2
  282. package/scripts/epic/epic-solo.ts +8 -8
  283. package/scripts/epic/epic-triage.ts +5 -4
  284. package/scripts/epic/epic-validate.ts +8 -7
  285. package/scripts/epic/epic.ts +5 -5
  286. package/scripts/exports/unused-members-cli.ts +1 -1
  287. package/scripts/followup/followup-issue-number.ts +1 -2
  288. package/scripts/followup/git-followup-cleanup.ts +6 -7
  289. package/scripts/followup/git-followup-finish.ts +11 -13
  290. package/scripts/followup/git-followup-flush.ts +11 -7
  291. package/scripts/followup/git-followup-issue-close.ts +16 -13
  292. package/scripts/followup/git-followup-label.ts +9 -6
  293. package/scripts/followup/git-followup-merged.ts +1 -1
  294. package/scripts/followup/git-followup-pending.ts +7 -9
  295. package/scripts/followup/git-followup-stages.ts +28 -17
  296. package/scripts/followup/git-followup-workflow.ts +19 -21
  297. package/scripts/followup/git-pr-followup-checks.ts +13 -20
  298. package/scripts/followup/git-pr-followup-wrapup.ts +7 -7
  299. package/scripts/followup/git-pr-followup.ts +18 -17
  300. package/scripts/gate/core-admission.ts +162 -0
  301. package/scripts/gate/core-budget.ts +134 -91
  302. package/scripts/gate/gate-ledger.ts +114 -0
  303. package/scripts/gate/gate-log.ts +7 -9
  304. package/scripts/gate/gate-plan.ts +103 -35
  305. package/scripts/gate/gate-report.ts +39 -21
  306. package/scripts/gate/gate-skip.ts +11 -13
  307. package/scripts/gate/gate-steps.ts +5 -1
  308. package/scripts/gate/gate-tree.ts +3 -4
  309. package/scripts/gate/hook-gate-reuse.ts +9 -9
  310. package/scripts/gate/machine-capacity.ts +313 -0
  311. package/scripts/gate/pre-commit-type-check.ts +4 -4
  312. package/scripts/gate/project-checks.ts +12 -4
  313. package/scripts/gate/scoped-green.ts +11 -18
  314. package/scripts/gate/type-check-command.ts +2 -2
  315. package/scripts/gate/type-check-step.ts +4 -4
  316. package/scripts/gate/verification-gate.ts +60 -53
  317. package/scripts/gh/gh-spawn.ts +2 -2
  318. package/scripts/gh/git-ai-review-scan.ts +3 -2
  319. package/scripts/gh/git-gh-api-path.ts +10 -11
  320. package/scripts/gh/git-gh-exec.ts +43 -48
  321. package/scripts/gh/git-gh-failure.ts +6 -9
  322. package/scripts/gh/git-gh-helpers.ts +1 -1
  323. package/scripts/gh/git-gh-issue-list.ts +15 -19
  324. package/scripts/gh/git-gh-issue-read.ts +43 -60
  325. package/scripts/gh/git-gh-issue-rest.ts +14 -15
  326. package/scripts/gh/git-gh-issue-write.ts +52 -40
  327. package/scripts/gh/git-gh-issue.ts +23 -24
  328. package/scripts/gh/git-gh-pr-auto-merge.ts +3 -3
  329. package/scripts/gh/git-gh-pr-read.ts +46 -50
  330. package/scripts/gh/git-gh-pr-rest.ts +23 -26
  331. package/scripts/gh/git-gh-pr-review.ts +2 -2
  332. package/scripts/gh/git-gh-pr-rollup.ts +4 -4
  333. package/scripts/gh/git-gh-pr-snapshot.ts +8 -10
  334. package/scripts/gh/git-gh-pr.ts +16 -16
  335. package/scripts/gh/git-gh-reachability.ts +11 -12
  336. package/scripts/gh/git-gh-repo.ts +2 -3
  337. package/scripts/gh/git-gh-rest-state.ts +1 -1
  338. package/scripts/gh/git-pr-ai-review.ts +6 -5
  339. package/scripts/gh/git-pr-checks-eval.ts +28 -30
  340. package/scripts/gh/git-pr-checks-parse.ts +14 -16
  341. package/scripts/gh/git-pr-checks-watch.ts +17 -17
  342. package/scripts/gh/git-pr-checks.ts +20 -23
  343. package/scripts/gh/git-pr-coderabbit.ts +8 -6
  344. package/scripts/gh/git-pr-confirmation.ts +5 -5
  345. package/scripts/gh/git-pr-managed-config.ts +7 -9
  346. package/scripts/gh/git-pr-messages.ts +1 -1
  347. package/scripts/gh/git-pr.ts +15 -16
  348. package/scripts/gh/github-issue-url.ts +8 -9
  349. package/scripts/git/base-tree.ts +66 -0
  350. package/scripts/git/change-base.ts +42 -2
  351. package/scripts/git/changed-file-scope.ts +5 -5
  352. package/scripts/git/changed-paths.ts +1 -2
  353. package/scripts/git/constants.ts +2 -2
  354. package/scripts/git/git-branch.ts +1 -1
  355. package/scripts/git/git-closes-keyword.ts +3 -3
  356. package/scripts/git/git-command.ts +53 -41
  357. package/scripts/git/git-common-directory.ts +3 -3
  358. package/scripts/git/git-diff-reads.ts +14 -15
  359. package/scripts/git/git-error.ts +1 -1
  360. package/scripts/git/git-execa-error.ts +1 -2
  361. package/scripts/git/git-issue.ts +10 -8
  362. package/scripts/git/git-location-environment.ts +3 -4
  363. package/scripts/git/git-ls-remote.ts +6 -8
  364. package/scripts/git/git-pre-push-hook.ts +11 -10
  365. package/scripts/git/git-preflight.ts +5 -5
  366. package/scripts/git/git-push-transport.ts +2 -2
  367. package/scripts/git/git-remote-branch.ts +1 -2
  368. package/scripts/git/git-schemas.ts +16 -23
  369. package/scripts/git/git-spawn-sync.ts +1 -1
  370. package/scripts/git/git-spawn.ts +37 -14
  371. package/scripts/git/git-ssh-keepalive.ts +12 -5
  372. package/scripts/git/git-staging.ts +7 -8
  373. package/scripts/git/git-workflow.ts +1 -1
  374. package/scripts/git/git-worktree.ts +35 -27
  375. package/scripts/git/gone-branch.ts +2 -2
  376. package/scripts/git/listing-cutoff.ts +1 -2
  377. package/scripts/git/lockfile-sync.ts +65 -0
  378. package/scripts/git/main-merge-guard.ts +1 -2
  379. package/scripts/git/main-merge.ts +7 -7
  380. package/scripts/git/main-sync.ts +23 -8
  381. package/scripts/git/parse-json-array.ts +18 -23
  382. package/scripts/git/repository-lock.ts +34 -2
  383. package/scripts/git/stash/git-stash.ts +4 -5
  384. package/scripts/git/stash/stash-orphans.ts +5 -3
  385. package/scripts/git/stash/stash-pop-args.ts +1 -1
  386. package/scripts/git/stash/stash-pop-cli.ts +3 -3
  387. package/scripts/git/stash/stash-sweep-lock.ts +2 -2
  388. package/scripts/hooks/batch-guard.ts +11 -13
  389. package/scripts/hooks/check-commit-message.ts +12 -9
  390. package/scripts/hooks/codex-hook-adapter.ts +16 -10
  391. package/scripts/hooks/edited-cspell.ts +3 -4
  392. package/scripts/hooks/format-edited-cli.ts +1 -1
  393. package/scripts/hooks/format-edited-file.ts +11 -17
  394. package/scripts/hooks/format-rewrite-notice.ts +19 -17
  395. package/scripts/hooks/pre-push-unit.ts +10 -14
  396. package/scripts/hooks/pretool-guard-cli.ts +4 -4
  397. package/scripts/hooks/pretool-guard.ts +93 -18
  398. package/scripts/hooks/reserved-run.ts +2 -2
  399. package/scripts/hooks/step-zero-notice.ts +1 -1
  400. package/scripts/hooks/stop-guard.ts +21 -10
  401. package/scripts/init/basic-path-migration.ts +2 -2
  402. package/scripts/init/claude-kit-only-settings.ts +2 -2
  403. package/scripts/init/claude-plugin-config.ts +2 -2
  404. package/scripts/init/distributed-paths.ts +4 -4
  405. package/scripts/init/hook-command-rewrite.ts +3 -3
  406. package/scripts/init/hook-launch.ts +5 -5
  407. package/scripts/init/init-actions.ts +13 -0
  408. package/scripts/init/init-ai-copy.ts +11 -11
  409. package/scripts/init/init-bootstrap.ts +3 -3
  410. package/scripts/init/init-copy-content.ts +4 -4
  411. package/scripts/init/init-logic-json-merge.ts +7 -9
  412. package/scripts/init/init-logic-migrate.ts +1 -1
  413. package/scripts/init/init-logic-templates.ts +1 -1
  414. package/scripts/init/init-logic-workspace.ts +4 -4
  415. package/scripts/init/init-logic-yaml-merge.ts +2 -2
  416. package/scripts/init/init-logic.ts +19 -22
  417. package/scripts/init/init.ts +12 -8
  418. package/scripts/init/kit-base-preset.ts +1 -1
  419. package/scripts/init/kit-setup-state.ts +1 -1
  420. package/scripts/init/kit-written-paths.ts +1 -2
  421. package/scripts/init/package-manager-pin.ts +35 -0
  422. package/scripts/init/project-profile-cli.ts +1 -1
  423. package/scripts/init/project-profile.ts +3 -3
  424. package/scripts/init/session-language-environment.ts +1 -1
  425. package/scripts/init/start-exec.ts +3 -4
  426. package/scripts/init/start-plan.ts +2 -2
  427. package/scripts/init/start-setup-pr.ts +3 -2
  428. package/scripts/init/start-steps.ts +2 -2
  429. package/scripts/init/tsconfig-preset-migration.ts +1 -1
  430. package/scripts/init/vscode-tasks.ts +62 -0
  431. package/scripts/issue/baseline-measure.ts +2 -2
  432. package/scripts/issue/behavior-change-lint.ts +2 -2
  433. package/scripts/issue/defect-rate-cli.ts +6 -7
  434. package/scripts/issue/defect-rate.ts +37 -27
  435. package/scripts/issue/git-next-issues.ts +9 -8
  436. package/scripts/issue/issue-auto-ok.ts +49 -11
  437. package/scripts/issue/issue-backlinks-cli.ts +5 -5
  438. package/scripts/issue/issue-backlinks.ts +6 -6
  439. package/scripts/issue/issue-cite-cli.ts +20 -18
  440. package/scripts/issue/issue-cite.ts +18 -8
  441. package/scripts/issue/issue-closing-pr.ts +4 -4
  442. package/scripts/issue/issue-comment-cli.ts +6 -4
  443. package/scripts/issue/issue-file-cli.ts +75 -15
  444. package/scripts/issue/issue-file-fold.ts +155 -0
  445. package/scripts/issue/issue-file.ts +14 -6
  446. package/scripts/issue/issue-fold-cli.ts +14 -9
  447. package/scripts/issue/issue-fold.ts +23 -8
  448. package/scripts/issue/issue-labels.ts +46 -37
  449. package/scripts/issue/issue-lint-cli.ts +2 -2
  450. package/scripts/issue/issue-lint.ts +1 -1
  451. package/scripts/issue/issue-merged.ts +10 -4
  452. package/scripts/issue/issue-number-shape.ts +27 -0
  453. package/scripts/issue/issue-rank.ts +1 -1
  454. package/scripts/issue/issue-read-cli.ts +4 -5
  455. package/scripts/issue/issue-read.ts +4 -5
  456. package/scripts/issue/issue-reference.ts +5 -5
  457. package/scripts/issue/issue-release-cli.ts +165 -0
  458. package/scripts/issue/issue-release.ts +58 -0
  459. package/scripts/issue/issue-report-failures.ts +7 -4
  460. package/scripts/issue/issue-scout-cli.ts +11 -11
  461. package/scripts/issue/issue-scout-closed.ts +4 -4
  462. package/scripts/issue/issue-scout.ts +4 -5
  463. package/scripts/issue/issue-state-cli.ts +17 -10
  464. package/scripts/issue/issue-state.ts +12 -13
  465. package/scripts/issue/issue-wip.ts +7 -7
  466. package/scripts/issue/markdown-section.ts +3 -3
  467. package/scripts/issue/measure-rerun-cli.ts +10 -9
  468. package/scripts/issue/reproduction-measure.ts +3 -3
  469. package/scripts/issue/session-cite.ts +56 -0
  470. package/scripts/josh/agent-session-environment.ts +10 -8
  471. package/scripts/josh/cli-body.ts +2 -2
  472. package/scripts/josh/command-suggest.ts +1 -1
  473. package/scripts/josh/file-map-stamp.ts +20 -23
  474. package/scripts/josh/hook-decision.ts +24 -28
  475. package/scripts/josh/josh-command-map.ts +4 -1
  476. package/scripts/josh/josh-command-types.ts +32 -34
  477. package/scripts/josh/josh-commands-ai.ts +6 -6
  478. package/scripts/josh/josh-commands-backlog.ts +15 -3
  479. package/scripts/josh/josh-commands-clone.ts +1 -1
  480. package/scripts/josh/josh-commands-development.ts +33 -4
  481. package/scripts/josh/josh-commands-document.ts +3 -3
  482. package/scripts/josh/josh-commands-guard.ts +3 -3
  483. package/scripts/josh/josh-commands-issue.ts +11 -5
  484. package/scripts/josh/josh-commands-lane.ts +16 -5
  485. package/scripts/josh/josh-commands-lint.ts +1 -1
  486. package/scripts/josh/josh-commands-maintenance.ts +2 -2
  487. package/scripts/josh/josh-commands-run.ts +20 -6
  488. package/scripts/josh/josh-commands-split.ts +1 -2
  489. package/scripts/josh/josh-commands-versioning.ts +5 -5
  490. package/scripts/josh/josh-commands-workflow.ts +30 -22
  491. package/scripts/josh/josh-environment-file.ts +1 -1
  492. package/scripts/josh/josh-in-process.ts +3 -3
  493. package/scripts/josh/josh-logic.ts +10 -10
  494. package/scripts/josh/josh-run.ts +3 -3
  495. package/scripts/josh/josh-verdict.ts +9 -12
  496. package/scripts/josh/josh.ts +3 -3
  497. package/scripts/josh/kit-only.ts +2 -2
  498. package/scripts/josh/path-decision.ts +3 -3
  499. package/scripts/josh/platform-temporary.ts +7 -5
  500. package/scripts/josh/process-identity.ts +24 -6
  501. package/scripts/josh/process-owner.ts +4 -4
  502. package/scripts/josh/session-language-cli.ts +53 -11
  503. package/scripts/josh/session-language.ts +1 -1
  504. package/scripts/josh/stamp-file.ts +48 -29
  505. package/scripts/josh/stamp-record.ts +57 -0
  506. package/scripts/lane/lane-await.ts +35 -11
  507. package/scripts/lane/lane-cache.ts +6 -6
  508. package/scripts/lane/lane-capacity.ts +32 -17
  509. package/scripts/lane/lane-child-invocation.ts +17 -15
  510. package/scripts/lane/lane-child-marker.ts +12 -12
  511. package/scripts/lane/lane-cli.ts +20 -13
  512. package/scripts/lane/lane-close.ts +6 -6
  513. package/scripts/lane/lane-dispatch.ts +61 -72
  514. package/scripts/lane/lane-environment.ts +5 -5
  515. package/scripts/lane/lane-guard-policy.ts +7 -21
  516. package/scripts/lane/lane-handoff.ts +2 -2
  517. package/scripts/lane/lane-install.ts +9 -10
  518. package/scripts/lane/lane-launch-cli.ts +13 -8
  519. package/scripts/lane/lane-ledger.ts +73 -11
  520. package/scripts/lane/lane-leftover.ts +44 -30
  521. package/scripts/lane/lane-limit-cli.ts +160 -0
  522. package/scripts/lane/lane-limit-override.ts +74 -0
  523. package/scripts/lane/lane-load.ts +19 -68
  524. package/scripts/lane/lane-measure-cli.ts +15 -25
  525. package/scripts/lane/lane-occupancy.ts +6 -4
  526. package/scripts/lane/lane-open.ts +25 -24
  527. package/scripts/lane/lane-output.ts +4 -3
  528. package/scripts/lane/lane-paths.ts +22 -8
  529. package/scripts/lane/lane-phase.ts +33 -0
  530. package/scripts/lane/lane-reap.ts +2 -2
  531. package/scripts/lane/lane-registry.ts +27 -15
  532. package/scripts/lane/lane-relaunch.ts +9 -9
  533. package/scripts/lane/lane-report.ts +5 -4
  534. package/scripts/lane/lane-resume.ts +2 -2
  535. package/scripts/lane/lane-sampler.ts +55 -0
  536. package/scripts/lane/lane-seed.ts +7 -7
  537. package/scripts/lane/lane-stage-stats.ts +135 -0
  538. package/scripts/lane/lane-start-point.ts +8 -11
  539. package/scripts/lane/lane-stats.ts +60 -15
  540. package/scripts/lane/lane-stray.ts +140 -0
  541. package/scripts/lane/lane-vacant.ts +1 -1
  542. package/scripts/lane/openai-lane-supervisor-decision.ts +3 -7
  543. package/scripts/lane/openai-lane-supervisor-owner.ts +3 -9
  544. package/scripts/lane/openai-review-broker.ts +2 -4
  545. package/scripts/lib/ancestor-directories.ts +1 -1
  546. package/scripts/lib/bounded-pool.ts +2 -2
  547. package/scripts/lib/buffered-process.ts +4 -6
  548. package/scripts/lib/caddy-logs.sh +0 -0
  549. package/scripts/lib/cli-flags.ts +39 -6
  550. package/scripts/lib/error-message.ts +1 -1
  551. package/scripts/lib/json-value.ts +17 -3
  552. package/scripts/lib/poll.ts +1 -1
  553. package/scripts/lib/status-icons.ts +3 -3
  554. package/scripts/lib/timed-fetch.ts +1 -1
  555. package/scripts/lib/timeouts.ts +1 -1
  556. package/scripts/lines/bytes-command.ts +3 -4
  557. package/scripts/lines/effective-limit.ts +25 -12
  558. package/scripts/lines/line-budget.ts +47 -55
  559. package/scripts/lines/line-targets.ts +6 -2
  560. package/scripts/lines/lines-command.ts +3 -3
  561. package/scripts/lint/cspell-cached.ts +1 -1
  562. package/scripts/lint/cycle-recheck.ts +122 -0
  563. package/scripts/lint/format.ts +1 -2
  564. package/scripts/lint/lint-parallel.ts +34 -19
  565. package/scripts/lint/lint-related-scope.ts +25 -15
  566. package/scripts/lint/lint-related.ts +6 -7
  567. package/scripts/managed-marker/index.ts +1 -1
  568. package/scripts/managed-marker/managed-marker-logic.ts +1 -2
  569. package/scripts/notify/git-notify.ts +9 -7
  570. package/scripts/notify/telegram-notify.ts +53 -37
  571. package/scripts/notify/telegram-test-logic.ts +3 -3
  572. package/scripts/notify/telegram-test.ts +45 -30
  573. package/scripts/observations/observation-ledger-home.ts +14 -8
  574. package/scripts/observations/observation-ledger-line.ts +3 -2
  575. package/scripts/observations/observation-ledger-migrate.ts +3 -4
  576. package/scripts/observations/observation-ledger-prepare.ts +4 -4
  577. package/scripts/observations/observation-ledger.ts +14 -15
  578. package/scripts/observations/observation-record-cli.ts +83 -0
  579. package/scripts/observations/observation-record.ts +91 -0
  580. package/scripts/observations/observations-flush-cli.ts +1 -1
  581. package/scripts/observations/observations-flush-landing.ts +7 -6
  582. package/scripts/observations/observations-flush.ts +26 -27
  583. package/scripts/overrides/overrides-check.ts +18 -8
  584. package/scripts/package/package-scout-cli.ts +1 -1
  585. package/scripts/package/package-scout-format.ts +2 -2
  586. package/scripts/package/package-scout.ts +1 -1
  587. package/scripts/propagate/propagate-git-failure.ts +1 -1
  588. package/scripts/propagate/propagate-git.ts +7 -7
  589. package/scripts/propagate/propagate-plan.ts +2 -2
  590. package/scripts/propagate/propagate-publish.ts +2 -3
  591. package/scripts/propagate/propagate-run.ts +5 -7
  592. package/scripts/propagate/propagate-select.ts +1 -1
  593. package/scripts/propagate/propagate-steps.ts +19 -20
  594. package/scripts/propagate/propagate-targets.ts +6 -10
  595. package/scripts/propagate/propagate.ts +5 -5
  596. package/scripts/refactor/import-graph.ts +1 -1
  597. package/scripts/refactor/refactor-lint.ts +4 -10
  598. package/scripts/refactor/refactor-scan-cli.ts +1 -1
  599. package/scripts/refactor/refactor-scan.ts +2 -2
  600. package/scripts/refactor/refactor-targets.ts +1 -1
  601. package/scripts/release/github-release-cli.ts +25 -3
  602. package/scripts/release/github-release-environment.ts +1 -0
  603. package/scripts/release/github-release-runs.ts +115 -0
  604. package/scripts/release/github-release.ts +13 -67
  605. package/scripts/release/release-cli.ts +21 -4
  606. package/scripts/release/release-history.ts +6 -10
  607. package/scripts/release/release-plan.ts +3 -3
  608. package/scripts/release/release-progress.ts +3 -4
  609. package/scripts/release/release-publish.ts +8 -9
  610. package/scripts/release/release-scope-cli.ts +8 -10
  611. package/scripts/release/release-tag.ts +6 -8
  612. package/scripts/release/release-worktree.ts +5 -5
  613. package/scripts/repo/auto-merge-setting-logic.ts +7 -9
  614. package/scripts/repo/auto-merge-setting.ts +1 -1
  615. package/scripts/repo/repo-setting.ts +4 -4
  616. package/scripts/repo/repository-labels.ts +1 -1
  617. package/scripts/repo/required-checks-logic.ts +3 -3
  618. package/scripts/repo/required-checks-report.ts +1 -1
  619. package/scripts/repo/ruleset-check-cli.ts +1 -1
  620. package/scripts/repo/ruleset-check.ts +1 -1
  621. package/scripts/report/report-format-reference.ts +26 -0
  622. package/scripts/report/report-lint-cli.ts +2 -2
  623. package/scripts/report/report-lint.ts +16 -2
  624. package/scripts/review/disposition-cli.ts +2 -2
  625. package/scripts/review/disposition-logic.ts +1 -1
  626. package/scripts/review/live-evidence.ts +9 -6
  627. package/scripts/review/review-attest-cli.ts +1 -2
  628. package/scripts/review/review-attest.ts +3 -3
  629. package/scripts/review/review-brief-cli.ts +19 -20
  630. package/scripts/review/review-brief.ts +29 -32
  631. package/scripts/review/review-checkout.ts +2 -2
  632. package/scripts/review/review-diff-parts.ts +3 -5
  633. package/scripts/review/review-diff-write.ts +1 -1
  634. package/scripts/review/review-finding-ledger.ts +7 -4
  635. package/scripts/review/review-findings-cli.ts +2 -2
  636. package/scripts/review/review-level.ts +4 -7
  637. package/scripts/review/review-record-cli.ts +73 -16
  638. package/scripts/review/review-record.ts +5 -4
  639. package/scripts/review/review-round2-cli.ts +2 -3
  640. package/scripts/review/review-round2.ts +13 -21
  641. package/scripts/review/review-stamps.ts +9 -71
  642. package/scripts/review/review-tree.ts +4 -5
  643. package/scripts/rules/bash-triggers.ts +4 -4
  644. package/scripts/rules/decision-oracle-batch.ts +5 -6
  645. package/scripts/rules/decision-oracle-stage.ts +1 -1
  646. package/scripts/rules/decision-oracle-tokens.ts +1 -2
  647. package/scripts/rules/decision-oracle.ts +2 -2
  648. package/scripts/rules/delivered-rules.ts +61 -406
  649. package/scripts/rules/destructive-command.ts +2 -2
  650. package/scripts/rules/direct-filing.ts +4 -4
  651. package/scripts/rules/direct-pr-create.ts +2 -2
  652. package/scripts/rules/early-heartbeat.ts +15 -19
  653. package/scripts/rules/file-body.ts +5 -6
  654. package/scripts/rules/filing-cap.ts +6 -7
  655. package/scripts/rules/filing-offer.ts +1 -1
  656. package/scripts/rules/firing-point.ts +6 -6
  657. package/scripts/rules/gh-api.ts +2 -2
  658. package/scripts/rules/git-argv.ts +3 -3
  659. package/scripts/rules/git-force.ts +2 -2
  660. package/scripts/rules/hook-context-line.ts +31 -0
  661. package/scripts/rules/implementation-cut-verdict.ts +5 -8
  662. package/scripts/rules/implementation-cut.ts +35 -32
  663. package/scripts/rules/index-guard.ts +2 -2
  664. package/scripts/rules/issue-citation.ts +7 -7
  665. package/scripts/rules/issue-comments.ts +21 -13
  666. package/scripts/rules/josh-git-bare.ts +2 -2
  667. package/scripts/rules/lane-background.ts +14 -16
  668. package/scripts/rules/lane-carry-conflict.ts +41 -5
  669. package/scripts/rules/lane-interactive-ask.ts +6 -9
  670. package/scripts/rules/lane-park.ts +12 -16
  671. package/scripts/rules/lane-split-park.ts +1 -2
  672. package/scripts/rules/lane-switch-main.ts +10 -13
  673. package/scripts/rules/last-prompt.ts +1 -1
  674. package/scripts/rules/oracle-consulted.ts +5 -5
  675. package/scripts/rules/oracle-firing.ts +6 -9
  676. package/scripts/rules/oracle-list-cli.ts +2 -2
  677. package/scripts/rules/permission-guards.ts +2 -2
  678. package/scripts/rules/piped-verification.ts +79 -9
  679. package/scripts/rules/poll-loop.ts +9 -11
  680. package/scripts/rules/pre-gate-cut.ts +33 -30
  681. package/scripts/rules/prior-comment-read.ts +3 -3
  682. package/scripts/rules/protected-files.ts +25 -13
  683. package/scripts/rules/raw-field-body.ts +3 -4
  684. package/scripts/rules/reply-language.ts +1 -1
  685. package/scripts/rules/rule-body-guard.ts +10 -12
  686. package/scripts/rules/rule-guard.ts +1 -1
  687. package/scripts/rules/rule-list.ts +51 -0
  688. package/scripts/rules/rule-registry-rows.ts +282 -0
  689. package/scripts/rules/rule-registry.ts +109 -0
  690. package/scripts/rules/rule-value-cache.ts +2 -2
  691. package/scripts/rules/rule-value-cli.ts +6 -4
  692. package/scripts/rules/rule-value.ts +61 -22
  693. package/scripts/rules/run-tail-rule.ts +11 -15
  694. package/scripts/rules/shell-body-trigger.ts +7 -7
  695. package/scripts/rules/shell-segments.ts +2 -4
  696. package/scripts/rules/stop-rules.ts +54 -41
  697. package/scripts/rules/tail-commands.ts +1 -1
  698. package/scripts/rules/test-declared-commit.ts +2 -2
  699. package/scripts/rules/third-party-write.ts +3 -3
  700. package/scripts/rules/worktree-guard.ts +12 -5
  701. package/scripts/run/add/run-add-cli.ts +165 -0
  702. package/scripts/run/add/run-add.ts +124 -0
  703. package/scripts/run/board/run-board-cli.ts +207 -0
  704. package/scripts/run/board/run-board-closed.ts +95 -0
  705. package/scripts/run/board/run-board-every.ts +60 -0
  706. package/scripts/run/board/run-board-fetch.ts +38 -0
  707. package/scripts/run/board/run-board-fit.ts +219 -0
  708. package/scripts/run/board/run-board-github.ts +162 -0
  709. package/scripts/run/board/run-board-header.ts +275 -0
  710. package/scripts/run/board/run-board-kind.ts +35 -0
  711. package/scripts/run/board/run-board-labels.ts +299 -0
  712. package/scripts/run/board/run-board-layout.ts +222 -0
  713. package/scripts/run/board/run-board-link.ts +31 -0
  714. package/scripts/run/board/run-board-machine.ts +198 -0
  715. package/scripts/run/board/run-board-notes.ts +103 -0
  716. package/scripts/run/board/run-board-phase.ts +136 -0
  717. package/scripts/run/board/run-board-plan.ts +129 -0
  718. package/scripts/run/board/run-board-read.ts +62 -0
  719. package/scripts/run/board/run-board-render-legend.ts +82 -0
  720. package/scripts/run/board/run-board-render-notes.ts +77 -0
  721. package/scripts/run/board/run-board-render-slot.ts +50 -0
  722. package/scripts/run/board/run-board-render.ts +407 -0
  723. package/scripts/run/board/run-board-scope.ts +17 -0
  724. package/scripts/run/board/run-board-screen.ts +43 -0
  725. package/scripts/run/board/run-board-span.ts +66 -0
  726. package/scripts/run/board/run-board-spin.ts +115 -0
  727. package/scripts/run/board/run-board-state.ts +113 -0
  728. package/scripts/run/board/run-board-status.ts +279 -0
  729. package/scripts/run/board/run-board-tick.ts +210 -0
  730. package/scripts/run/board/run-board-track.ts +22 -0
  731. package/scripts/run/board/run-board-usage-read.ts +255 -0
  732. package/scripts/run/board/run-board-usage-rusage.ts +124 -0
  733. package/scripts/run/board/run-board-usage-text.ts +80 -0
  734. package/scripts/run/board/run-board-usage.ts +165 -0
  735. package/scripts/run/carry/run-carry-added.ts +62 -0
  736. package/scripts/run/carry/run-carry-args.ts +25 -22
  737. package/scripts/run/carry/run-carry-change.ts +1 -1
  738. package/scripts/run/carry/run-carry-cli.ts +71 -48
  739. package/scripts/run/carry/run-carry-conversation.ts +6 -7
  740. package/scripts/run/carry/run-carry-ended.ts +85 -0
  741. package/scripts/run/carry/run-carry-reclaim.ts +1 -1
  742. package/scripts/run/carry/run-carry-stash.ts +3 -2
  743. package/scripts/run/carry/run-carry-streak.ts +8 -10
  744. package/scripts/run/carry/run-carry.ts +85 -89
  745. package/scripts/run/cut/run-cut-args.ts +7 -7
  746. package/scripts/run/cut/run-cut-cli.ts +68 -37
  747. package/scripts/run/cut/run-cut-handoff.ts +15 -15
  748. package/scripts/run/cut/run-cut-report.ts +37 -16
  749. package/scripts/run/cut/run-cut.ts +63 -77
  750. package/scripts/run/detached-launch.ts +35 -50
  751. package/scripts/run/entry/run-entry-cli.ts +48 -27
  752. package/scripts/run/entry/run-entry-stop.ts +7 -9
  753. package/scripts/run/entry/run-entry.ts +5 -6
  754. package/scripts/run/event/run-event-cli.ts +5 -6
  755. package/scripts/run/event/run-event-filed.ts +69 -0
  756. package/scripts/run/event/run-event-follow.ts +3 -3
  757. package/scripts/run/event/run-event-plan.ts +38 -0
  758. package/scripts/run/event/run-event-render.ts +10 -4
  759. package/scripts/run/event/run-event-scope.ts +47 -18
  760. package/scripts/run/event/run-event-stream-emit.ts +64 -11
  761. package/scripts/run/event/run-event-stream.ts +172 -43
  762. package/scripts/run/event/run-event-watch.ts +4 -6
  763. package/scripts/run/hold/run-hold-cli.ts +65 -62
  764. package/scripts/run/hold/run-hold.ts +88 -46
  765. package/scripts/run/merge/run-merge-cli.ts +116 -77
  766. package/scripts/run/merge/run-merge-collect.ts +107 -0
  767. package/scripts/run/merge/run-merge-steps.ts +112 -65
  768. package/scripts/run/merge/run-merge-token.ts +30 -0
  769. package/scripts/run/merge/run-merge.ts +31 -22
  770. package/scripts/run/progress/run-progress-args.ts +4 -4
  771. package/scripts/run/progress/run-progress-cli.ts +39 -50
  772. package/scripts/run/progress/run-progress-clock.ts +25 -32
  773. package/scripts/run/progress/run-progress-config.ts +6 -9
  774. package/scripts/run/progress/run-progress-read.ts +9 -10
  775. package/scripts/run/progress/run-progress.ts +48 -53
  776. package/scripts/run/review/run-review-cli.ts +6 -6
  777. package/scripts/run/review/run-review-steps.ts +6 -6
  778. package/scripts/run/review/run-review.ts +9 -11
  779. package/scripts/run/run-cli-fault.ts +29 -0
  780. package/scripts/run/run-ending-cli.ts +3 -3
  781. package/scripts/run/run-ending.ts +10 -14
  782. package/scripts/run/run-halfrun-resume.ts +6 -8
  783. package/scripts/run/run-headless.ts +25 -12
  784. package/scripts/run/run-invocation.ts +17 -22
  785. package/scripts/run/run-label.ts +7 -5
  786. package/scripts/run/run-liveness-cli.ts +19 -6
  787. package/scripts/run/run-liveness.ts +27 -38
  788. package/scripts/run/run-next-cli.ts +5 -9
  789. package/scripts/run/run-next.ts +4 -5
  790. package/scripts/run/run-parent-cut-hook.ts +10 -12
  791. package/scripts/run/run-preflight.ts +25 -29
  792. package/scripts/run/run-prep-cli.ts +17 -13
  793. package/scripts/run/run-prep-locate.ts +4 -5
  794. package/scripts/run/run-prep.ts +7 -10
  795. package/scripts/run/run-prrun-resume.ts +2 -2
  796. package/scripts/run/run-report-cli.ts +4 -4
  797. package/scripts/run/run-report.ts +9 -14
  798. package/scripts/run/run-retrospective.ts +3 -3
  799. package/scripts/run/run-section.ts +42 -0
  800. package/scripts/run/run-stage-read.ts +2 -2
  801. package/scripts/run/run-stage.ts +6 -4
  802. package/scripts/run/run-status-cli.ts +7 -5
  803. package/scripts/run/run-status.ts +6 -7
  804. package/scripts/run/run-step-cli.ts +13 -15
  805. package/scripts/run/run-step.ts +62 -48
  806. package/scripts/run/run-stop-notify.ts +7 -8
  807. package/scripts/run/run-stranded-cli.ts +1 -1
  808. package/scripts/run/run-stranded-detect.ts +4 -4
  809. package/scripts/run/run-stranded.ts +11 -13
  810. package/scripts/run/run-tail-cli.ts +15 -16
  811. package/scripts/run/run-tail.ts +14 -33
  812. package/scripts/run/run-watcher-guard-cli.ts +3 -4
  813. package/scripts/run/run-watcher-guard.ts +11 -12
  814. package/scripts/run/run-watcher-hook.ts +6 -12
  815. package/scripts/run/ship/run-ship-cli.ts +67 -33
  816. package/scripts/run/ship/run-ship-detach.ts +15 -13
  817. package/scripts/run/ship/run-ship-lock.ts +1 -1
  818. package/scripts/run/ship/run-ship-next.ts +7 -8
  819. package/scripts/run/ship/run-ship-pre-detach.ts +27 -11
  820. package/scripts/run/ship/run-ship-preflight.ts +10 -11
  821. package/scripts/run/ship/run-ship-probe.ts +4 -4
  822. package/scripts/run/ship/run-ship-return.ts +1 -1
  823. package/scripts/run/ship/run-ship-review-steps.ts +43 -24
  824. package/scripts/run/ship/run-ship-review.ts +12 -14
  825. package/scripts/run/ship/run-ship-scoped.ts +15 -6
  826. package/scripts/run/ship/run-ship-stage.ts +80 -26
  827. package/scripts/run/ship/run-ship-steps.ts +26 -16
  828. package/scripts/run/ship/run-ship-stop-text.ts +4 -2
  829. package/scripts/run/ship/run-ship-sync.ts +9 -8
  830. package/scripts/run/ship/run-ship.ts +17 -32
  831. package/scripts/run/tidy/run-tidy-cli.ts +9 -5
  832. package/scripts/run/tidy/run-tidy-lanes.ts +18 -7
  833. package/scripts/run/tidy/run-tidy-stashes.ts +8 -8
  834. package/scripts/run/tidy/run-tidy.ts +4 -3
  835. package/scripts/run/wake/run-wake-cli.ts +27 -33
  836. package/scripts/run/wake/run-wake-describe.ts +76 -29
  837. package/scripts/run/wake/run-wake-driver.ts +14 -14
  838. package/scripts/run/wake/run-wake-handoff.ts +6 -6
  839. package/scripts/run/wake/run-wake-loop.ts +13 -21
  840. package/scripts/run/wake/run-wake-restart.ts +4 -5
  841. package/scripts/run/wake/run-wake-session.ts +23 -27
  842. package/scripts/run/wake/run-wake.ts +57 -328
  843. package/scripts/safe-chain/ci-installer-pin.ts +3 -3
  844. package/scripts/safe-chain/pack-hook.ts +2 -2
  845. package/scripts/safe-chain/preinstall-command.ts +2 -2
  846. package/scripts/security/security-audit-logic.ts +1 -1
  847. package/scripts/security/security-audit-provision-logic.ts +1 -1
  848. package/scripts/security/security-audit-provision.ts +2 -2
  849. package/scripts/security/security-audit.ts +5 -5
  850. package/scripts/security/security-updates-logic.ts +2 -3
  851. package/scripts/security/security-updates.ts +2 -4
  852. package/scripts/self-sync-guard/index.ts +1 -1
  853. package/scripts/self-sync-guard/self-sync-guard-logic.ts +2 -2
  854. package/scripts/self-sync-guard/self-sync-refusal.ts +1 -1
  855. package/scripts/sonar/sonar-hotspots-cli.ts +1 -1
  856. package/scripts/sonar/sonar-hotspots.ts +1 -1
  857. package/scripts/sonar/sonar-new-code-cli.ts +1 -1
  858. package/scripts/sonar/sonar-new-code.ts +1 -1
  859. package/scripts/sonar/sonar-project.ts +1 -1
  860. package/scripts/split/split-assess-cli.ts +1 -1
  861. package/scripts/split/split-assess.ts +3 -3
  862. package/scripts/sync/directory-copy-guard.ts +2 -3
  863. package/scripts/sync/managed-config-scope-cli.ts +1 -2
  864. package/scripts/sync/managed-config-scope.ts +4 -4
  865. package/scripts/sync/plugin-skill-directories.ts +2 -2
  866. package/scripts/sync/reconcile-templates.ts +17 -8
  867. package/scripts/sync/removed-skill-manifest.ts +2 -3
  868. package/scripts/sync/sync-ai-files.ts +7 -7
  869. package/scripts/sync/sync-configs.ts +30 -3
  870. package/scripts/sync/sync-hook-safety.ts +2 -2
  871. package/scripts/sync/sync.ts +23 -10
  872. package/scripts/sync/synced-paths.ts +2 -1
  873. package/scripts/sync/workflow-pin-logic.ts +1 -1
  874. package/scripts/test/test-declared-changed.ts +4 -4
  875. package/scripts/test/test-declared-logic.ts +2 -3
  876. package/scripts/test/test-declared-match.ts +25 -4
  877. package/scripts/test/test-declared.ts +26 -9
  878. package/scripts/test/test-red-commit.ts +3 -2
  879. package/scripts/test/test-red-logic.ts +7 -14
  880. package/scripts/test/test-red.ts +12 -47
  881. package/scripts/test/test-related-scope.ts +2 -3
  882. package/scripts/test/test-related.ts +3 -3
  883. package/scripts/test/test-type-logic.ts +1 -2
  884. package/scripts/test/test-unit-guard.ts +13 -17
  885. package/scripts/test/unit-worker-share.ts +7 -8
  886. package/scripts/time-runtime/time-agent-bundles.ts +2 -4
  887. package/scripts/time-runtime/time-background.ts +17 -21
  888. package/scripts/time-runtime/time-batch-guard.ts +67 -342
  889. package/scripts/time-runtime/time-bundle-call.ts +26 -28
  890. package/scripts/time-runtime/time-bundles.ts +11 -12
  891. package/scripts/time-runtime/time-call-identity.ts +1 -1
  892. package/scripts/time-runtime/time-command-key.ts +2 -2
  893. package/scripts/time-runtime/time-density-hook.ts +8 -11
  894. package/scripts/time-runtime/time-density.ts +5 -5
  895. package/scripts/time-runtime/time-followup-stage.ts +7 -7
  896. package/scripts/time-runtime/time-format.ts +5 -5
  897. package/scripts/time-runtime/time-hook-transcript.ts +3 -3
  898. package/scripts/time-runtime/time-instant.ts +1 -1
  899. package/scripts/time-runtime/time-markers.ts +15 -19
  900. package/scripts/time-runtime/time-phase-names.ts +3 -3
  901. package/scripts/time-runtime/time-reported-failure.ts +15 -19
  902. package/scripts/time-runtime/time-round-trips.ts +20 -23
  903. package/scripts/time-runtime/time-shell.ts +8 -8
  904. package/scripts/time-runtime/time-single-check.ts +1 -2
  905. package/scripts/time-runtime/time-spans.ts +35 -40
  906. package/scripts/time-runtime/time-tool-call.ts +15 -16
  907. package/scripts/time-runtime/time-transcript-line.ts +53 -34
  908. package/scripts/time-runtime/time-writes.ts +5 -5
  909. package/scripts/ui/ui-routes-cli.ts +1 -2
  910. package/scripts/ui/ui-routes.ts +1 -2
  911. package/scripts/version/bump-version.ts +1 -1
  912. package/scripts/version/fresh-metadata-cache.ts +2 -2
  913. package/scripts/version/latest-corepack.ts +129 -98
  914. package/scripts/version/latest-lane-guard.ts +1 -1
  915. package/scripts/version/latest-scope-cli.ts +2 -2
  916. package/scripts/version/latest-stamp.ts +1 -2
  917. package/scripts/version/latest-update.ts +2 -2
  918. package/scripts/version/npm-registry.ts +2 -2
  919. package/scripts/version/package-manager-version.ts +18 -0
  920. package/scripts/version/publishable-range-check.ts +2 -1
  921. package/scripts/version/publishable-range.ts +1 -1
  922. package/scripts/version/release-age.ts +11 -11
  923. package/scripts/version/release-hold.ts +2 -2
  924. package/scripts/version/safe-chain-version-update.ts +3 -3
  925. package/scripts/version/version-check-logic.ts +2 -3
  926. package/scripts/version/version-check.ts +1 -2
  927. package/scripts/version/version-command-config.ts +2 -2
  928. package/scripts/version/version-commands.ts +3 -3
  929. package/scripts/version/version-remote.ts +4 -4
  930. package/scripts/version/version-targets.ts +2 -2
  931. package/templates/gitignore +7 -0
  932. package/templates/workflows/github-release.yml +4 -0
  933. package/dist/hooks/chunk-NV2JRZZO.js +0 -6385
  934. package/dist/hooks/chunk-RKUAD3I6.js +0 -90
  935. package/dist/hooks/chunk-WPALEIRX.js +0 -18
  936. package/scripts/backlog/backlog-restructure.ts +0 -152
  937. package/scripts/rules/issue-fold-rule.ts +0 -72
  938. package/scripts/rules/wip-cap.ts +0 -63
  939. package/scripts/run/run-issue-number.ts +0 -19
@@ -1,23 +1,24 @@
1
+ import { session_cite } from '#scripts/issue/session-cite'
1
2
  import { error_text } from '#scripts/lib/error-message'
2
3
  import { git_gh_api_path } from './git-gh-api-path'
3
4
  import { git_gh_exec, type GhApiRequest } from './git-gh-exec'
5
+ import { gh_failure } from './git-gh-failure'
4
6
 
5
7
  // Writing issues and labels through REST, in the return-value contracts the `gh <noun> <verb>`
6
8
  // wrappers had.
7
9
  //
8
10
  // `gh issue edit` / `comment` / `create` / `close` and `gh label create` all go through GraphQL,
9
- // which a cloud session is answered 403 for while the REST endpoints are served normally
10
- // (joshuafolkken/kit#1022). Split out of `git-gh-issue.ts` rather than added to it: that file was
11
+ // which a cloud session is answered 403 for while the REST endpoints are served normally.
12
+ // Split out of `git-gh-issue.ts` rather than added to it: that file was
11
13
  // already at 215 of the 300 lines a file may hold, and the reads had been split out for the same
12
- // reason (joshuafolkken/kit#957, joshuafolkken/kit#1026).
14
+ // reason.
13
15
  //
14
- // **Every path here was measured against the live API before it was written.**
15
- // joshuafolkken/kit#1022 deliberately measured only the reads, because a write has side effects, and
16
- // left the write side as candidates to confirm one at a time. They were confirmed on a pair of
17
- // throwaway issues, and one of them did not behave as its name suggests — see `read_issue_id`.
16
+ // **Every path here is measured against the live API.** A write has side effects, so each one is
17
+ // confirmed on throwaway issues, and one of them does not behave as its name suggests — see
18
+ // `read_issue_id`.
18
19
  //
19
- // The bodies still travel over stdin: `exec_gh_api` hands `body` to gh as `--input -`, so multi-line
20
- // markdown depends on no shell quoting, exactly as `--body-file -` did before.
20
+ // The bodies travel over stdin: `exec_gh_api` hands `body` to gh as `--input -`, so multi-line
21
+ // markdown depends on no shell quoting.
21
22
 
22
23
  // `gh api` promotes a request carrying `--input` to POST, so a creation names no method; the two
23
24
  // verbs that are not implied by a body do.
@@ -35,6 +36,8 @@ const LABELS_SEGMENT = '/labels'
35
36
  const COMMENTS_SEGMENT = '/comments'
36
37
  const CLOSED_STATE = 'closed'
37
38
  const COLOR_HASH = '#'
39
+ const UNPROCESSABLE_STATUS = 422
40
+ const ALREADY_EXISTS_CODE = 'already_exists'
38
41
 
39
42
  // The four writers below answered `boolean` under `gh`, and their callers read it: `epic-run.ts`
40
43
  // only reports the epic label when it was applied, `epic-relations.ts` counts the relations it
@@ -72,7 +75,7 @@ async function issue_comment(issue_number: string, body: string): Promise<string
72
75
  // The same comment, counted rather than thrown. `josh epic --add --decision-file` posts one per child
73
76
  // **after** the epic body already carries the record, so a refused comment costs that child's copy and
74
77
  // nothing else — an exception there would leave the caller unable to tell a landed insertion from one
75
- // that wrote nothing (joshuafolkken/kit#1350).
78
+ // that wrote nothing.
76
79
  async function issue_try_comment(issue_number: string, body: string): Promise<boolean> {
77
80
  return await did_write_succeed(async () => await issue_comment(issue_number, body))
78
81
  }
@@ -85,7 +88,7 @@ async function issue_try_comment(issue_number: string, body: string): Promise<bo
85
88
  //
86
89
  // **`comment: undefined` closes without commenting**, and it is what the ordering above costs: a run
87
90
  // whose comment landed and whose close was refused leaves the issue open carrying the comment, so
88
- // the next run must close it without posting a second copy (joshuafolkken/kit#1039). The return
91
+ // the next run must close it without posting a second copy. The return
89
92
  // value keeps meaning what it meant — with no comment to post, the state change is not merely the
90
93
  // last thing attempted but the only one.
91
94
  //
@@ -103,23 +106,30 @@ async function issue_close(issue_number: string, comment: string | undefined): P
103
106
  })
104
107
  }
105
108
 
106
- // `gh label create` accepted `#5319e7` and stripped the `#` itself; REST answers 422
107
- // `{"resource":"Label","code":"invalid","field":"color"}` for the same value. The one caller passes
108
- // the hash form (`EPIC_LABEL_COLOR`), so dropping it here is what keeps that call site unchanged.
109
+ // REST answers 422 `{"resource":"Label","code":"invalid","field":"color"}` for a color carrying a
110
+ // leading `#`. The one caller passes the hash form (`EPIC_LABEL_COLOR`), so dropping it here is what
111
+ // keeps that call site unchanged.
109
112
  function to_label_color(color: string): string {
110
113
  return color.startsWith(COLOR_HASH) ? color.slice(COLOR_HASH.length) : color
111
114
  }
112
115
 
113
- // `|| true` semantics, unchanged: an existing label answers 422 `already_exists`, which is not an
114
- // error here.
116
+ // The one failure that means the label is there: 422 with `"code":"already_exists"` in the error
117
+ // document. The status comes from the failed request itself (`git-gh-failure.ts`) and the code from
118
+ // the body `to_gh_error` appends, so a 422 for another reason — an invalid color — is not read as it.
119
+ function is_label_already_exists(error: unknown): boolean {
120
+ if (gh_failure.failure_of(error)?.status !== UNPROCESSABLE_STATUS) return false
121
+
122
+ return error_text.message_of(error).includes(ALREADY_EXISTS_CODE)
123
+ }
124
+
125
+ // `|| true` semantics: an existing label answers 422 `already_exists`, which is not an error here.
115
126
  //
116
- // **What swallowing it costs did change, and in the safe direction.** Under `gh`, a label this call
117
- // failed to create surfaced later — `gh issue create --label epic` could not resolve it and failed
118
- // there. REST does not fail: `POST /issues` with `labels: [...]`, and `POST /issues/{N}/labels`,
119
- // both **create** a label the repository does not have, with a generated color and no description
120
- // (measured on joshuafolkken/kit#1026). So a swallowed failure here costs the label's color and
127
+ // **Every other failure is warned about, and still not thrown.** `POST /issues` with
128
+ // `labels: [...]`, and `POST /issues/{N}/labels`, both **create** a label the repository does not
129
+ // have, with a generated color and no description. So a failure here costs the label's color and
121
130
  // description, never the label itself — `epic:next` and the auto-close filter on the name, and the
122
- // name is applied either way.
131
+ // name is applied either way. A 401 / 403, a rate limit or a request that never arrived is named
132
+ // rather than read as "the label already exists".
123
133
  async function label_ensure(input: {
124
134
  name: string
125
135
  color: string
@@ -134,17 +144,20 @@ async function label_ensure(input: {
134
144
  description: input.description,
135
145
  }),
136
146
  })
137
- } catch {
138
- /* the label already exists */
147
+ } catch (error) {
148
+ if (is_label_already_exists(error)) return
149
+ const [gist = ''] = error_text.message_of(error).split('\n', 1)
150
+
151
+ console.warn(`⚠ could not create the \`${input.name}\` label — ${gist}`)
139
152
  }
140
153
  }
141
154
 
142
155
  // What creating an issue over REST means, as one value both execution paths build from: the
143
- // collection to post to, the JSON body, and the `.html_url` unwrap that answers the browser URL
144
- // `gh issue create` used to print.
156
+ // collection to post to, the JSON body, and the `.html_url` unwrap that answers the issue's browser
157
+ // URL.
145
158
  //
146
159
  // It exists as a request rather than only as the writer below because `josh propagate` opens its
147
- // consumer's issue **synchronously** and cannot await (joshuafolkken/kit#1042). Spelling the same
160
+ // consumer's issue **synchronously** and cannot await. Spelling the same
148
161
  // three decisions out again at that call site would be a second definition of the same write
149
162
  // (`CLAUDE.md` → "No clones"), so the request is shared and only the spawn differs.
150
163
  //
@@ -184,7 +197,7 @@ async function issue_create_with_label(input: {
184
197
  }
185
198
 
186
199
  // The outcome of applying one label, with the swallowed failure's gist kept for a caller that has to
187
- // say why it refused (joshuafolkken/kit#3312).
200
+ // say why it refused.
188
201
  type LabelWrite = { is_applied: true } | { is_applied: false; reason: string }
189
202
 
190
203
  // The issue's label names, read back after a failed write. A read that itself fails answers
@@ -207,7 +220,7 @@ async function read_label_names(issue_number: string): Promise<Array<string> | u
207
220
 
208
221
  // **A failed answer is not a failed write.** The POST is idempotent, and a timeout, a non-zero exit
209
222
  // after the write or a secondary rate limit can each throw after the label landed — which refused a
210
- // lane dispatch whose label was in fact applied (joshuafolkken/kit#3312). So a throw is confirmed by
223
+ // lane dispatch whose label was in fact applied. So a throw is confirmed by
211
224
  // reading the labels back, and only a label that is really absent answers `is_applied: false`.
212
225
  async function issue_apply_label(issue_number: string, label: string): Promise<LabelWrite> {
213
226
  const labels_path = `${git_gh_api_path.issue_api_path(issue_number)}${LABELS_SEGMENT}`
@@ -232,15 +245,15 @@ async function issue_apply_label(issue_number: string, label: string): Promise<L
232
245
 
233
246
  // Applied after the body edit so a failure leaves an issue with the epic sections and no label,
234
247
  // which `epic:check` reports — rather than a labelled issue with nothing to track. The caller checks
235
- // the return: the label is what the auto-close filters on (joshuafolkken/kit#865).
248
+ // the return: the label is what the auto-close filters on.
236
249
  async function issue_add_label(issue_number: string, label: string): Promise<boolean> {
237
250
  const write = await issue_apply_label(issue_number, label)
238
251
 
239
252
  return write.is_applied
240
253
  }
241
254
 
242
- // The counterpart to the addition above, for a run taking its own marker back off
243
- // (joshuafolkken/kit#1794). **The name travels in the path, so it is encoded**: a label is free to
255
+ // The counterpart to the addition above, for a run taking its own marker back off.
256
+ // **The name travels in the path, so it is encoded**: a label is free to
244
257
  // contain a `/` or a `#`, and an unencoded one would address a path that is not this label's.
245
258
  //
246
259
  // **It throws rather than answering `boolean`**, which is the one place it departs from
@@ -263,8 +276,8 @@ async function issue_remove_label(issue_number: string, label: string): Promise<
263
276
  // The endpoint takes `{"issue_id": <n>}` and does not check that `<n>` is an issue in this
264
277
  // repository, or that it is the number the caller meant. Posting `{"issue_id":1036}` to a scratch
265
278
  // issue in this repository recorded an issue in a completely unrelated repository — the one whose
266
- // database id happens to be 1036 — as a blocker, with a 200 and no warning (measured on
267
- // joshuafolkken/kit#1026, which names it). Every caller here names a blocker by its issue number, so
279
+ // database id happens to be 1036 — as a blocker, with a 200 and no warning. Every caller here names
280
+ // a blocker by its issue number, so
268
281
  // sending that number would silently record an arbitrary issue from anywhere on GitHub.
269
282
  //
270
283
  // A resolution that does not produce a usable id throws rather than returning something to send:
@@ -278,16 +291,15 @@ async function read_issue_id(issue_number: string): Promise<number> {
278
291
  const issue_id = Number(raw.trim())
279
292
 
280
293
  if (!Number.isSafeInteger(issue_id) || issue_id <= 0) {
281
- throw new Error(`gh api answered no database id for issue #${issue_number}`)
294
+ throw new Error(`gh api answered no database id for issue ${session_cite.issue(issue_number)}`)
282
295
  }
283
296
 
284
297
  return issue_id
285
298
  }
286
299
 
287
300
  // Applied after creation, never as part of it: the relation is a nicety and the Issue is not, so a
288
- // failure here costs only the relation. It no longer depends on the gh CLI's version — the
289
- // dependencies endpoint is REST, and `gh api` has proxied REST since long before `--add-blocked-by`
290
- // existed (joshuafolkken/kit#1026).
301
+ // failure here costs only the relation. It does not depend on the gh CLI's version — the
302
+ // dependencies endpoint is REST, which `gh api` proxies.
291
303
  async function issue_add_blocked_by(issue_number: string, blocker: string): Promise<boolean> {
292
304
  return await did_write_succeed(async () => {
293
305
  const issue_id = await read_issue_id(blocker)
@@ -300,8 +312,8 @@ async function issue_add_blocked_by(issue_number: string, blocker: string): Prom
300
312
  }
301
313
 
302
314
  // The counterpart, for an insertion that re-points an existing chain: inserting `#N` between `#B`
303
- // and `#M` has to drop `#B -> #M`, or the epic would declare one order and record two
304
- // (joshuafolkken/kit#890). The id goes in the path here rather than in a body, and the endpoint is
315
+ // and `#M` has to drop `#B -> #M`, or the epic would declare one order and record two.
316
+ // The id goes in the path here rather than in a body, and the endpoint is
305
317
  // idempotent — deleting a relation that is not there answers 200.
306
318
  async function issue_remove_blocked_by(issue_number: string, blocker: string): Promise<boolean> {
307
319
  return await did_write_succeed(async () => {
@@ -5,17 +5,17 @@ import { git_gh_issue_write } from './git-gh-issue-write'
5
5
 
6
6
  const NUMBER_AND_BODY_FIELDS = 'number,body'
7
7
  // The backlog scan's fields. The title rides along because the pre-filing scan compares titles
8
- // (joshuafolkken/kit#1252) and it costs nothing: the same listing request already carries it, so the
8
+ // and it costs nothing: the same listing request already carries it, so the
9
9
  // two consumers share one read rather than each making their own.
10
10
  //
11
11
  // `blocked_by_count` rides along for the same reason and is the one field here that `gh --json`
12
12
  // never had: it is read out of the `issue_dependencies_summary` the listing response already
13
- // carries, so it costs no request at all (joshuafolkken/kit#1736). It is what lets `epic:bundle`
13
+ // carries, so it costs no request at all. It is what lets `epic:bundle`
14
14
  // tell a row with no blockers from one with some **before** deciding whether that row is worth a
15
- // per-issue read — the read it used to make for every open issue in the repository. Absent on a row
16
- // whose summary is missing, which must not be read as zero; `git-gh-issue-rest.ts` states why.
15
+ // per-issue read, which would otherwise be made for every open issue in the repository. Absent on a
16
+ // row whose summary is missing, which must not be read as zero; `git-gh-issue-rest.ts` states why.
17
17
  const BACKLOG_SCAN_FIELDS = `number,title,body,${BLOCKED_BY_COUNT_FIELD}`
18
- // The recently-closed scan's fields (joshuafolkken/kit#1679). It compares titles like the scan above
18
+ // The recently-closed scan's fields. It compares titles like the scan above
19
19
  // and never reads a body, and it needs the labels to tell an epic from a deliverable — the open half
20
20
  // gets that from the epic listing, which by construction holds no closed epic.
21
21
  const NUMBER_TITLE_AND_LABELS_FIELDS = 'number,title,labels'
@@ -26,16 +26,16 @@ const SUMMARY_FIELDS = 'number,title,labels,createdAt'
26
26
  // `SUMMARY_FIELDS` on purpose: a listing carries no `blockedBy`, so the field is answered from each
27
27
  // row's own dependencies endpoint, and asking for it on the shared list would put that request
28
28
  // behind the next-issues display too — where a refused one becomes a failure with no message at all,
29
- // since the listing swallows the error (joshuafolkken/kit#996, joshuafolkken/kit#1025). `body` costs
29
+ // since the listing swallows the error. `body` costs
30
30
  // no request — the REST listing row already carries it — and is what the backlog offer reads for
31
- // the restructures each issue declares (joshuafolkken/kit#3221).
31
+ // the paths each issue declares.
32
32
  const PICKUP_FIELDS = `${SUMMARY_FIELDS},blockedBy,body`
33
33
 
34
34
  // Every listing below goes through the one REST invocation in `git-gh-issue-list.ts`. It kept the
35
35
  // `json_fields` / `limit` contract it had as a `gh issue list` wrapper, so these callers changed
36
- // only where a `gh` flag became a query parameter (joshuafolkken/kit#1025).
36
+ // only where a `gh` flag became a query parameter.
37
37
  //
38
- // **They all answer `IssueListOutcome`, not the JSON alone** (joshuafolkken/kit#1067). The page
38
+ // **They all answer `IssueListOutcome`, not the JSON alone**. The page
39
39
  // ceiling now bounds every one of them, and a bound whose caller cannot see it was reached is a
40
40
  // silently shortened answer — so the flag rides out to the caller and the caller decides. The
41
41
  // disposition each one settled on, and why:
@@ -44,18 +44,18 @@ const PICKUP_FIELDS = `${SUMMARY_FIELDS},blockedBy,body`
44
44
  // | --- | --- | --- |
45
45
  // | `issue_list_recent` | **ignorable** | The display shows the five newest of the twenty it asks for, and the paging is newest-first — so a truncated read is a *prefix* of the untruncated one and the five rows are the same five. Nothing is hidden that this display would have shown. |
46
46
  // | `issue_list_open_bodies` | **warning** | `epic:bundle` scanned what it scanned; a related issue past the cut is missed, which is what its existing `⚠ … cap` line already says. The scan ran, so it is something to read rather than a check that did not happen. |
47
- // | `issue_search_body` | **warning** | Unchanged from joshuafolkken/kit#1033 — the orphan search ran over the newest issues, and an orphan is normally an issue filed minutes ago. |
47
+ // | `issue_search_body` | **warning** | The orphan search runs over the newest issues, and an orphan is normally an issue filed minutes ago. |
48
48
  // | `issue_list_by_label` | **warning** | Both consumers report it: `epic:bundle`'s epic listing, where an epic past the cut has its child recommended a second epic, and the auto-close, where an epic past the cut is never checked for completion. Neither may fail — the auto-close runs after the merge — so both print and continue. |
49
49
  // | `issue_list_by_label_summary` | **warning** | The `auto-ok` pickup already says the cap dropped the *oldest* opted-in issues; the ceiling drops the same ones. The answer it gives is still opted in, just possibly not the highest-priority one. |
50
50
  // | `issue_list_recently_closed` | **warning** | `issue:scout` widens its duplicate scan over what closed recently; a closed issue past the cut is one candidate the reader is not shown, exactly as on the open half. The scan ran, so it is reported beside the open one rather than failing the command. |
51
- // | `issue_list_by_label_in_repo` | **error** | `epic:busy` asks whether a repository already has work running in it, and it is the only one whose answer *authorizes an action*. A truncated listing with no visible holder is not "nothing is running", and reading it as one starts a second run in the same checkout — the direction joshuafolkken/kit#925 closed. It lands with the unreadable listing, on `wait`. It is also the only caller that reports the page ceiling **without** the `limit` cap beside it; `epic-busy.ts` records why a full page of parked issues must not latch the guard. |
51
+ // | `issue_list_by_label_in_repo` | **error** | `epic:busy` asks whether a repository already has work running in it, and it is the only one whose answer *authorizes an action*. A truncated listing with no visible holder is not "nothing is running", and reading it as one starts a second run in the same checkout. It lands with the unreadable listing, on `wait`. It is also the only caller that reports the page ceiling **without** the `limit` cap beside it; `epic-busy.ts` records why a full page of parked issues must not latch the guard. |
52
52
  //
53
- // The split is joshuafolkken/kit#1033's, applied caller by caller rather than copied: truncation is
53
+ // The split is applied caller by caller rather than copied: truncation is
54
54
  // a warning where the scan *ran* and an error where the answer it produced would authorize an
55
55
  // action. Only `epic:busy` authorizes one.
56
56
  const { issue_list } = git_gh_issue_list
57
57
 
58
- // The newest open issues, for the next-issues display at workflow completion (#821). `createdAt`
58
+ // The newest open issues, for the next-issues display at workflow completion. `createdAt`
59
59
  // rides along because the caller re-sorts explicitly rather than inheriting the listing's order.
60
60
  async function issue_list_recent(limit: number): Promise<IssueListOutcome> {
61
61
  return await issue_list({ json_fields: SUMMARY_FIELDS, limit })
@@ -63,15 +63,14 @@ async function issue_list_recent(limit: number): Promise<IssueListOutcome> {
63
63
 
64
64
  // Every open issue with its title and body. Used by `epic:bundle` to scan the backlog and by
65
65
  // `issue:scout` to compare titles before one is filed; a search with an empty term is not a listing,
66
- // and asking `gh` for one produced a partial and arbitrary answer (joshuafolkken/kit#873).
66
+ // and asking `gh` for one produced a partial and arbitrary answer.
67
67
  async function issue_list_open_bodies(limit: number): Promise<IssueListOutcome> {
68
68
  return await issue_list({ json_fields: BACKLOG_SCAN_FIELDS, limit })
69
69
  }
70
70
 
71
- // The issues that closed most recently, for the duplicate half of `issue:scout`
72
- // (joshuafolkken/kit#1679). **The work most likely to be filed twice is the work that just
73
- // finished** — joshuafolkken/kit#1656 was filed about five hours after joshuafolkken/kit#1623 closed
74
- // having already done it — and a scan that reads only open issues cannot see any of it.
71
+ // The issues that closed most recently, for the duplicate half of `issue:scout`.
72
+ // **The work most likely to be filed twice is the work that just
73
+ // finished**, and a scan that reads only open issues cannot see any of it.
75
74
  //
76
75
  // `sort=updated` rather than `created`: the question is what closed recently, and a listing ordered
77
76
  // by filing date puts a five-year-old issue closed this morning behind whatever was filed yesterday.
@@ -95,11 +94,11 @@ async function issue_list_recently_closed(limit: number): Promise<IssueListOutco
95
94
  }
96
95
 
97
96
  // Open issues whose body mentions `term`. Used by `epic:audit` to find an issue that names an epic
98
- // as its parent while the epic's task list does not track it (joshuafolkken/kit#870).
97
+ // as its parent while the epic's task list does not track it.
99
98
  //
100
99
  // The one listing here whose filter runs client-side, and so the one that reaches the page ceiling
101
100
  // on an ordinary repository: its matches are normally zero, so "stop once `limit` rows are selected"
102
- // never fires for it (joshuafolkken/kit#1033).
101
+ // never fires for it.
103
102
  async function issue_search_body(term: string, limit: number): Promise<IssueListOutcome> {
104
103
  return await issue_list({
105
104
  json_fields: NUMBER_AND_BODY_FIELDS,
@@ -112,13 +111,13 @@ async function issue_list_by_label(label: string, limit: number): Promise<IssueL
112
111
  return await issue_list({ json_fields: NUMBER_AND_BODY_FIELDS, limit, label })
113
112
  }
114
113
 
115
- // The same filter with the fields the `auto-ok` pickup needs (joshuafolkken/kit#906): it orders by
116
- // `createdAt`, re-checks `labels` client-side and reads each body for its declared restructures. A
114
+ // The same filter with the fields the `auto-ok` pickup needs: it orders by
115
+ // `createdAt`, re-checks `labels` client-side and reads each body for its declared paths. A
117
116
  // label that does not exist in the repository is not an error — the listing comes back empty, which
118
117
  // is exactly "nobody has opted anything in".
119
118
  // `json_fields` overrides the pickup's list. Its only caller is the probe that runs *after* a failed
120
119
  // read, asking the same question without `blockedBy` so a refused dependencies endpoint is told
121
- // apart from an access failure (joshuafolkken/kit#1005).
120
+ // apart from an access failure.
122
121
  async function issue_list_by_label_summary(
123
122
  label: string,
124
123
  limit: number,
@@ -132,7 +131,7 @@ async function issue_list_by_label_summary(
132
131
  }
133
132
 
134
133
  // Open issues carrying `label` in one named repository — the read `epic:next` makes before it
135
- // offers a child, to see whether that repository already has one running (joshuafolkken/kit#925).
134
+ // offers a child, to see whether that repository already has one running.
136
135
  //
137
136
  // `SUMMARY_FIELDS` rather than `PICKUP_FIELDS`: the answer is only "which issues hold this
138
137
  // repository", and asking for `blockedBy` would put a dependencies request behind the guard — where
@@ -4,14 +4,14 @@ import { git_gh_exec } from './git-gh-exec'
4
4
  import { read_pull, require_pr_number } from './git-gh-pr-read'
5
5
  import { git_gh_pr_rest, type RestPull } from './git-gh-pr-rest'
6
6
 
7
- // Auto-merge for a pull request a josh command opens and would otherwise have to stay alive to land
8
- // (joshuafolkken/kit#2497). `pnpm josh observations:flush` used to merge its pull request only from
7
+ // Auto-merge for a pull request a josh command opens and would otherwise have to stay alive to land.
8
+ // `pnpm josh observations:flush` used to merge its pull request only from
9
9
  // inside its own wait, so a wait that ended early — a session cut, a killed process — left a green
10
10
  // pull request open with nobody to merge it.
11
11
  //
12
12
  // **This is the one GraphQL request in the pull-request layer, because REST has no equivalent.**
13
13
  // Enabling auto-merge is `enablePullRequestAutoMerge` and nothing else. A cloud session can be
14
- // answered 403 for GraphQL (joshuafolkken/kit#1022), so the caller treats a failure here as a lost
14
+ // answered 403 for GraphQL, so the caller treats a failure here as a lost
15
15
  // safety net rather than a failed command — the in-process wait still merges as it always did.
16
16
 
17
17
  const GRAPHQL_PATH = 'graphql'
@@ -4,17 +4,16 @@ import { git_gh_helpers } from './git-gh-helpers'
4
4
  import { git_gh_pr_rest, type RestPull } from './git-gh-pr-rest'
5
5
  import { to_gh_state } from './git-gh-rest-state'
6
6
 
7
- // Reading pull requests through REST, in the answers `gh pr view` used to give.
7
+ // Reading pull requests through REST, in the answers `gh pr view` gives.
8
8
  //
9
- // `gh pr view` goes through GraphQL, which a cloud session is answered 403 for (joshuafolkken/kit#1022).
9
+ // `gh pr view` goes through GraphQL, which a cloud session is answered 403 for.
10
10
  // The reads move to `gh api`, and every caller downstream keeps the contract it already reads — the
11
11
  // empty string from `pr_view`, `undefined` from the two comment readers. `pr_exists` is the one
12
12
  // exception, and it is deliberate: it gates a **write**, so a lookup that failed cannot answer
13
- // `false` there (joshuafolkken/kit#1043).
13
+ // `false` there.
14
14
  //
15
15
  // One thing has no counterpart in REST: `gh pr view` accepted a **branch name** and every REST
16
- // endpoint is keyed by **number**. The resolution below is the single place that bridges the two
17
- // (joshuafolkken/kit#1027).
16
+ // endpoint is keyed by **number**. The resolution below is the single place that bridges the two.
18
17
 
19
18
  // The branch → number resolution, remembered for the life of the process.
20
19
  //
@@ -35,22 +34,21 @@ const pr_number_by_branch = new Map<string, number>()
35
34
  // most recent one" while this ordering holds.
36
35
  const LOOKUP_QUERY = 'state=all&sort=created&direction=desc&per_page=100'
37
36
  // The comment listings are paged: REST answers 30 rows by default, while `gh pr view --json comments`
38
- // answered the whole conversation. Truncating them is the kit#973 failure again in another form — the
39
- // newest Claude Review blocker falls off a listing that is ordered oldest first, and the merge gate
40
- // finds nothing to stop on. `gh api --paginate` merges the pages of an array endpoint into one array,
41
- // so the answer stays the flat listing every caller parses. The page size itself is
42
- // `FULL_PAGE_QUERY`, shared with the merge-gate listings (joshuafolkken/kit#1028).
37
+ // answers the whole conversation. Truncating them lets the merge gate pass on a listing it never
38
+ // fully read — the newest Claude Review blocker falls off a listing that is ordered oldest first,
39
+ // and the merge gate finds nothing to stop on. `gh api --paginate` merges the pages of an array
40
+ // endpoint into one array, so the answer stays the flat listing every caller parses. The page size
41
+ // itself is `FULL_PAGE_QUERY`, shared with the merge-gate listings.
43
42
  const COMMENTS_QUERY = FULL_PAGE_QUERY
44
43
  // Written as a constant rather than inline: `{owner}` inside a template literal reads as a broken
45
44
  // interpolation.
46
45
  const OWNER_PLACEHOLDER = '{owner}'
47
46
  // What a branch-keyed caller that cannot fold an absence into its own answer throws. Lives here
48
47
  // rather than beside either caller: the merge-gate snapshot and the two branch-keyed writes all need
49
- // it, and three copies of one message is the clone `CLAUDE.md` prohibits (joshuafolkken/kit#1029).
48
+ // it, and three copies of one message is the clone `CLAUDE.md` prohibits.
50
49
  const NO_PULL_REQUEST_MESSAGE = 'gh api found no pull request for branch'
51
50
  // And what it throws when the lookup never answered at all. Separate from the message above because
52
- // the two are different diagnoses: one says the branch has nothing, the other says nobody looked
53
- // (joshuafolkken/kit#1048).
51
+ // the two are different diagnoses: one says the branch has nothing, the other says nobody looked.
54
52
  const UNREADABLE_PULL_REQUEST_MESSAGE = 'gh api could not read the pull requests for branch'
55
53
 
56
54
  // `head` names the owner of the head repository, which for every branch this tooling opens is the
@@ -74,15 +72,15 @@ async function fetch_pr_number(branch_name: string): Promise<number | undefined>
74
72
  // auth, a dropped connection, a 200 carrying something other than a listing.
75
73
  //
76
74
  // The vocabulary is `IssueRead`'s in `git-gh-issue-read.ts`, which tells the same two apart for an
77
- // issue number (joshuafolkken/kit#957); reusing it rather than inventing a second spelling for one
75
+ // issue number; reusing it rather than inventing a second spelling for one
78
76
  // distinction is the point. The *classification* is cheaper here and needs no status probe: a branch
79
77
  // with no pull request is a 200 with an empty listing rather than a 404, so the lookup's own outcome
80
- // already separates them (joshuafolkken/kit#1048).
78
+ // already separates them.
81
79
  interface PullMergeState {
82
80
  is_merged: boolean
83
81
  merged_at: string | undefined
84
82
  head_sha: string | undefined
85
- // `josh ship` reads `DIRTY` here to re-merge a conflicting pull request (joshuafolkken/kit#3221).
83
+ // `josh ship` reads `DIRTY` here to re-merge a conflicting pull request.
86
84
  merge_state_status: string | undefined
87
85
  }
88
86
 
@@ -90,15 +88,15 @@ type PullNumberRead =
90
88
  { kind: 'read'; pr_number: number } | { kind: 'missing' } | { kind: 'unreadable'; cause: unknown }
91
89
 
92
90
  // The branch-keyed detail read, in the same three answers. `missing` and `unreadable` are the
93
- // resolution's own; `unreadable` also covers a resolved number whose detail read failed, which every
94
- // branch-keyed reader used to fold into "no pull request" (joshuafolkken/kit#3263).
91
+ // resolution's own; `unreadable` also covers a resolved number whose detail read failed, so no
92
+ // branch-keyed reader folds it into "no pull request".
95
93
  type PullRead = Exclude<PullNumberRead, { kind: 'read' }> | { kind: 'read'; pull: RestPull }
96
94
 
97
95
  // The lookups still in flight, keyed the same way the resolved numbers are.
98
96
  const pending_pr_number_by_branch = new Map<string, Promise<PullNumberRead>>()
99
97
 
100
- // The detail reads, keyed by number and remembered for the life of the command
101
- // (joshuafolkken/kit#3263). `josh followup` asks `pr_get_body` and `pr_get_url` in one tick — the
98
+ // The detail reads, keyed by number and remembered for the life of the command.
99
+ // `josh followup` asks `pr_get_body` and `pr_get_url` in one tick — the
102
100
  // same `GET /pulls/{N}` each time. The promise is stored, so readers in one tick share the request as
103
101
  // well as its answer; a read that fails is dropped and re-tried, the rule the number memo holds.
104
102
  // **Every write to a pull request clears it** through `forget_pr_numbers`, and the two state readers
@@ -119,7 +117,7 @@ async function fetch_pr_number_read(branch_name: string): Promise<PullNumberRead
119
117
  }
120
118
  }
121
119
 
122
- // **The lookup in flight is shared, not only the number it resolves to** (joshuafolkken/kit#1446).
120
+ // **The lookup in flight is shared, not only the number it resolves to**.
123
121
  // The memo above answers a caller arriving *after* the first lookup returned, which was every caller
124
122
  // while the branch-keyed reads were issued one at a time. `josh followup` now asks `pr_get_body` and
125
123
  // `pr_get_url` about the same branch in the same tick, and two callers that both miss an empty map
@@ -170,22 +168,21 @@ async function resolve_pr_number(branch_name: string): Promise<number | undefine
170
168
  }
171
169
 
172
170
  // One definition, because both callers that refuse to fold an unreadable lookup raise it —
173
- // `require_pr_number` and `pr_exists` (joshuafolkken/kit#1043).
171
+ // `require_pr_number` and `pr_exists`.
174
172
  function to_unreadable_error(branch_name: string, cause: unknown): Error {
175
173
  return new Error(`${UNREADABLE_PULL_REQUEST_MESSAGE}: ${branch_name}`, { cause })
176
174
  }
177
175
 
178
176
  // The number for a caller that has nothing to fold an absence into. The reads above answer their own
179
177
  // empty value for a branch with no pull request; a write cannot — `gh pr comment <branch>` and
180
- // `gh pr merge <branch>` both failed there, and the merge-gate snapshot already threw for the same
181
- // reason. One throw shared by all three (joshuafolkken/kit#1029).
178
+ // `gh pr merge <branch>` both fail there, and the merge-gate snapshot throws for the same reason.
179
+ // One throw shared by all three.
182
180
  //
183
- // **This is the caller the distinction was written for.** Folding both into
184
- // `NO_PULL_REQUEST_MESSAGE` reported a rate-limited lookup as "there is no pull request for this
185
- // branch" — safe, in that the run stops without merging, but wrong about why, which is the
186
- // joshuafolkken/kit#973 misread costing diagnosis time instead of correctness. The failure travels as
187
- // the `cause`, so `git_error.handle` prints gh's own reason under 💡 Details
188
- // (joshuafolkken/kit#1048).
181
+ // **This is the caller the distinction matters most for.** Folding both into
182
+ // `NO_PULL_REQUEST_MESSAGE` would report a rate-limited lookup as "there is no pull request for this
183
+ // branch" — safe, in that the run stops without merging, but wrong about why, which costs diagnosis
184
+ // time instead of correctness. The failure travels as
185
+ // the `cause`, so `git_error.handle` prints gh's own reason under 💡 Details.
189
186
  async function require_pr_number(branch_name: string): Promise<number> {
190
187
  const read = await read_pr_number(branch_name)
191
188
  if (read.kind === 'read') return read.pr_number
@@ -239,13 +236,13 @@ async function read_pull_or_undefined(branch_name: string): Promise<RestPull | u
239
236
  return read.kind === 'read' ? read.pull : undefined
240
237
  }
241
238
 
242
- // **`false` means the branch has no pull request, and nothing else.** This is the second half of
243
- // joshuafolkken/kit#1048's distinction, on the caller that needs it most: `pr_exists` is not read for
244
- // display, it decides whether `git-pr.ts` **opens** a pull request. Folding an unreadable lookup into
245
- // `false` therefore made a rate-limited run try to create a second pull request on a branch that
246
- // already had one — surviving only because `pr_create`'s 422 → `PR_ALREADY_EXISTS` recovery caught it
247
- // (joshuafolkken/kit#1029), which is an accident rather than a design. The throw is the one
248
- // `require_pr_number` raises, so gh's own reason travels as the `cause` (joshuafolkken/kit#1043).
239
+ // **`false` means the branch has no pull request, and nothing else.** This is the same
240
+ // missing-versus-unreadable distinction, on the caller that needs it most: `pr_exists` is not read
241
+ // for display, it decides whether `git-pr.ts` **opens** a pull request. Folding an unreadable lookup
242
+ // into `false` would make a rate-limited run try to create a second pull request on a branch that
243
+ // already has one — surviving only if `pr_create`'s 422 → `PR_ALREADY_EXISTS` recovery caught it,
244
+ // which is an accident rather than a design. The throw is the one
245
+ // `require_pr_number` raises, so gh's own reason travels as the `cause`.
249
246
  async function pr_exists(branch_name: string): Promise<boolean> {
250
247
  const read = await read_pr_number(branch_name)
251
248
  if (read.kind === 'unreadable') throw to_unreadable_error(branch_name, read.cause)
@@ -264,12 +261,12 @@ async function pr_get_url(branch_name: string): Promise<string | undefined> {
264
261
  return git_gh_helpers.parse_pr_state_string(pull.html_url)
265
262
  }
266
263
 
267
- // **Where the branch's pull request stands** — a merge a person made by hand included
268
- // (joshuafolkken/kit#3023): whether it merged and when, and the commit its head is on, which a push
264
+ // **Where the branch's pull request stands** — a merge a person made by hand included:
265
+ // whether it merged and when, and the commit its head is on, which a push
269
266
  // made on GitHub moves without touching the local branch. `undefined` covers both "no pull request"
270
267
  // and "nothing could be read": `followup` then takes its ordinary path, whose merge step settles a
271
268
  // pull request that did merge after all (`pr_merge`), so an unread answer costs a wait, not a wrong tail.
272
- // Read past the detail memo: `josh ship` asks it again after each merge it pushes (joshuafolkken/kit#3263).
269
+ // Read past the detail memo: `josh ship` asks it again after each merge it pushes.
273
270
  async function pr_get_merge_state(branch_name: string): Promise<PullMergeState | undefined> {
274
271
  const read = await read_pull_of_branch(branch_name, read_pull)
275
272
  if (read.kind !== 'read') return undefined
@@ -283,8 +280,8 @@ async function pr_get_merge_state(branch_name: string): Promise<PullMergeState |
283
280
  }
284
281
  }
285
282
 
286
- // REST answers JSON null for a pull request with no body where `gh --json body` answered an empty
287
- // string, and both used to arrive here as the empty answer this folds to `undefined`.
283
+ // REST answers JSON null for a pull request with no body where `gh --json body` answers an empty
284
+ // string; both are the empty answer this folds to `undefined`.
288
285
  async function pr_get_body(branch_name: string): Promise<string | undefined> {
289
286
  const pull = await read_pull_or_undefined(branch_name)
290
287
  const body = pull?.body
@@ -295,7 +292,7 @@ async function pr_get_body(branch_name: string): Promise<string | undefined> {
295
292
  // The empty string means "this branch has no pull request", and nothing else. A read that failed
296
293
  // throws, carrying gh's reason as the `cause`: `git-pr.ts` decides from this state whether the
297
294
  // branch's pull request merged, and a rate limit answered as "no state" sent a merged pull request
298
- // down the open one's path (joshuafolkken/kit#3263). Read past the detail memo, like the merge state.
295
+ // down the open one's path. Read past the detail memo, like the merge state.
299
296
  async function pr_view(branch_name: string): Promise<string> {
300
297
  const read = await read_pull_of_branch(branch_name, read_pull)
301
298
  if (read.kind === 'unreadable') throw to_unreadable_error(branch_name, read.cause)
@@ -305,11 +302,11 @@ async function pr_view(branch_name: string): Promise<string> {
305
302
  }
306
303
 
307
304
  // `undefined` when the listing could not be read — a failed request, or a PR whose number could not
308
- // be resolved. Not `'[]'`, which every failure used to become.
305
+ // be resolved. Not `'[]'`.
309
306
  //
310
- // The two are the same string to a caller, and the callers are the merge gate: a rate limit arrived
311
- // as "no reviewer left a finding" and the PR merged with the gate never actually read
312
- // (joshuafolkken/kit#973). The direction is what makes it worse than the epic auto-close's version of
307
+ // The two are the same string to a caller, and the callers are the merge gate: a rate limit would
308
+ // arrive as "no reviewer left a finding" and the PR merge with the gate never actually read.
309
+ // The direction is what makes it worse than the epic auto-close's version of
313
310
  // the same misread — that one only failed to close something.
314
311
  async function read_comments(
315
312
  branch_name: string,
@@ -332,7 +329,7 @@ function to_comments_json(raw: string): string {
332
329
  }
333
330
 
334
331
  // `git-pr-coderabbit.ts` parses `html_url` and `user.login` itself, so the review thread is handed on
335
- // as REST serves it (joshuafolkken/kit#1023).
332
+ // as REST serves it.
336
333
  function as_served(raw: string): string {
337
334
  return raw
338
335
  }
@@ -360,8 +357,7 @@ const git_gh_pr_read = {
360
357
 
361
358
  // The merge-gate snapshot needs the same branch → number resolution and the same detail read, and it
362
359
  // needs them separately: the reviews endpoint is keyed by number while the rollup is keyed by the
363
- // head commit the detail carries. Exported rather than re-derived so the memo above stays one memo
364
- // (joshuafolkken/kit#1028).
360
+ // head commit the detail carries. Exported rather than re-derived so the memo above stays one memo.
365
361
  export type { PullMergeState }
366
362
  export {
367
363
  git_gh_pr_read,