@joshuafolkken/kit 1.1784.0 → 1.2114.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 (690) hide show
  1. package/.claude/agents/reviewer-verification.md +19 -0
  2. package/.claude/agents/reviewer.md +19 -0
  3. package/.claude/settings.json +5 -6
  4. package/.claude/skills/dependency-update/SKILL.md +9 -10
  5. package/.claude/skills/workflow-commands/SKILL.md +6 -6
  6. package/.claude/skills/workflow-commands/background-commands.md +8 -5
  7. package/.claude/skills/workflow-commands/backlogrun-child.md +3 -1
  8. package/.claude/skills/workflow-commands/backlogrun-lanes.md +1 -1
  9. package/.claude/skills/workflow-commands/backlogrun-park.md +5 -2
  10. package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -3
  11. package/.claude/skills/workflow-commands/backlogrun-recovery.md +1 -1
  12. package/.claude/skills/workflow-commands/backlogrun-steps.md +3 -2
  13. package/.claude/skills/workflow-commands/backlogrun.md +1 -1
  14. package/.claude/skills/workflow-commands/chain-rule.md +41 -32
  15. package/.claude/skills/workflow-commands/delegation.md +6 -6
  16. package/.claude/skills/workflow-commands/entry-sequence.md +2 -2
  17. package/.claude/skills/workflow-commands/followup.md +7 -5
  18. package/.claude/skills/workflow-commands/fullrun-steps.md +6 -6
  19. package/.claude/skills/workflow-commands/fullrun.md +1 -1
  20. package/.claude/skills/workflow-commands/issue-comments.md +9 -4
  21. package/.claude/skills/workflow-commands/issue-fold-existing.md +2 -1
  22. package/.claude/skills/workflow-commands/kickoff.md +2 -2
  23. package/.claude/skills/workflow-commands/observation-filing.md +1 -1
  24. package/.claude/skills/workflow-commands/observation-ledger.md +6 -4
  25. package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -7
  26. package/.claude/skills/workflow-commands/prerequisite.md +3 -2
  27. package/.claude/skills/workflow-commands/retrospective.md +2 -2
  28. package/.claude/skills/workflow-commands/split-assessment.md +7 -5
  29. package/.codex/hooks.json +5 -5
  30. package/.github/actions/setup-pnpm/action.yml +9 -16
  31. package/.github/dependabot.yml +16 -0
  32. package/.github/workflows/auto-tag.yml +45 -0
  33. package/.github/workflows/ci.yml +155 -15
  34. package/.github/workflows/dependabot-auto-merge.yml +63 -4
  35. package/.github/workflows/production.yml +8 -0
  36. package/.github/workflows/publish.yml +59 -45
  37. package/.vscode/settings.json +19 -0
  38. package/CLAUDE.md +5 -12
  39. package/SECURITY.md +2 -2
  40. package/dist/CLAUDE.md +5 -12
  41. package/dist/commands/document-read-cli.js +2 -1
  42. package/dist/commands/document-section-main.js +2 -1
  43. package/dist/commands/read-set-cli.js +194 -134
  44. package/dist/commands/run-prep-main.js +9694 -10173
  45. package/dist/commands/run-step-cli.js +22138 -18285
  46. package/dist/hooks/audit-provision.js +23 -5
  47. package/dist/hooks/chunk-3GKE653K.js +6204 -0
  48. package/dist/hooks/chunk-45CJJOO7.js +1243 -0
  49. package/dist/hooks/{chunk-CWMBGKYW.js → chunk-5PM2JRGV.js} +2153 -856
  50. package/dist/hooks/{chunk-WR2KQAYZ.js → chunk-7SIUNQXK.js} +1207 -1470
  51. package/dist/hooks/{chunk-O2YBIDSI.js → chunk-CQD4LJE6.js} +1682 -1130
  52. package/dist/hooks/{chunk-VWWCFGWK.js → chunk-OPSRGWFU.js} +1 -1
  53. package/dist/hooks/{chunk-XGBNSWEI.js → chunk-UJ3FPMMM.js} +132 -49
  54. package/dist/hooks/chunk-VVNYJWEI.js +30 -0
  55. package/dist/hooks/chunk-Z6DQJKH3.js +2806 -0
  56. package/dist/hooks/codex-hook-adapter.js +8 -8
  57. package/dist/hooks/format-edited.js +4 -5
  58. package/dist/hooks/inputs.json +415 -389
  59. package/dist/hooks/pretool-guard.js +7 -6
  60. package/dist/hooks/session-lang.js +101 -258
  61. package/dist/hooks/stop-guard.js +1744 -2576
  62. package/dist/josh.js +7133 -6368
  63. package/dist/version/index.js +161 -1
  64. package/eslint/rules/comment-why-only.js +108 -0
  65. package/package.json +15 -8
  66. package/prompts/coding-standards.md +1 -1
  67. package/prompts/collaboration-workflow/file-edits.md +14 -11
  68. package/prompts/collaboration-workflow/issue-citation.md +0 -4
  69. package/prompts/collaboration-workflow/issue-template.md +40 -21
  70. package/prompts/collaboration-workflow/lane-instructions.md +3 -1
  71. package/prompts/collaboration-workflow/measurement.md +8 -1
  72. package/prompts/collaboration-workflow/operating-rules.md +11 -2
  73. package/prompts/collaboration-workflow/output-bounds.md +6 -2
  74. package/prompts/collaboration-workflow/plan-comment.md +1 -1
  75. package/prompts/collaboration-workflow/principles.md +9 -0
  76. package/prompts/collaboration-workflow/residency.md +3 -2
  77. package/prompts/collaboration-workflow/rule-delivery.md +13 -1
  78. package/prompts/collaboration-workflow/upstream-interrupt.md +2 -2
  79. package/prompts/collaboration-workflow/wip-cap.md +3 -1
  80. package/prompts/review-rubric.md +8 -0
  81. package/prompts/review.md +31 -22
  82. package/prompts/testing-guide.md +1 -0
  83. package/scripts/agent/agent-argv.ts +14 -16
  84. package/scripts/agent/agent-provider.ts +138 -0
  85. package/scripts/agent/agent-role-profile.ts +108 -156
  86. package/scripts/agent/agent-safe-text.ts +20 -5
  87. package/scripts/agent/api-usage-limit.ts +65 -0
  88. package/scripts/agent/claude-agent-argv.ts +19 -9
  89. package/scripts/agent/codex-agent-argv.ts +118 -22
  90. package/scripts/agent/usage-limit-reset.ts +179 -0
  91. package/scripts/auth/claude-token-output.ts +2 -2
  92. package/scripts/auto-ok/auto-ok-author.ts +53 -0
  93. package/scripts/auto-ok/auto-ok-cli.ts +20 -9
  94. package/scripts/backlog/backlog-defect-priority.ts +1 -1
  95. package/scripts/backlog/backlog-drive-cli.ts +6 -1
  96. package/scripts/backlog/backlog-drive-hold.ts +3 -3
  97. package/scripts/backlog/backlog-drive-idle.ts +10 -0
  98. package/scripts/backlog/backlog-drive-launch-pass.ts +90 -0
  99. package/scripts/backlog/backlog-drive-launch.ts +8 -2
  100. package/scripts/backlog/backlog-drive-named-offer.ts +73 -30
  101. package/scripts/backlog/backlog-drive-named.ts +28 -7
  102. package/scripts/backlog/backlog-drive-paused.ts +5 -4
  103. package/scripts/backlog/backlog-drive-restore.ts +11 -3
  104. package/scripts/backlog/backlog-drive.ts +21 -60
  105. package/scripts/backlog/backlog-gate-scope.ts +61 -0
  106. package/scripts/backlog/backlog-measure-close.ts +112 -0
  107. package/scripts/backlog/backlog-next.ts +39 -49
  108. package/scripts/backlog/backlog-occupied.ts +2 -2
  109. package/scripts/backlog/backlog-overlap.ts +42 -8
  110. package/scripts/backlog/backlog-plan-cli.ts +4 -1
  111. package/scripts/backlog/backlog-plan-comment.ts +81 -0
  112. package/scripts/backlog/backlog-plan-read.ts +19 -6
  113. package/scripts/backlog/backlog-pool.ts +50 -12
  114. package/scripts/backlog/backlog-rank.ts +60 -13
  115. package/scripts/backlog/backlog-stalled-detect.ts +2 -1
  116. package/scripts/backlog/backlog-waves.ts +17 -2
  117. package/scripts/backlog/backlogrun-launch.ts +7 -4
  118. package/scripts/cost-runtime/context-cut-payback.ts +27 -25
  119. package/scripts/cost-runtime/cost-cli.ts +37 -16
  120. package/scripts/cost-runtime/cost-pricing.ts +9 -0
  121. package/scripts/cost-runtime/cost-verdict.ts +4 -1
  122. package/scripts/delegation/delegation-policy.ts +2 -2
  123. package/scripts/delegation/duplicate-read-guard.ts +1 -0
  124. package/scripts/delegation/investigation-guard.ts +14 -2
  125. package/scripts/delegation/investigation-reads.ts +45 -23
  126. package/scripts/dependabot/dependabot-cooldown.ts +3 -2
  127. package/scripts/discovery/repo-party.ts +80 -20
  128. package/scripts/discovery/session-owner-pin.ts +51 -0
  129. package/scripts/document/capped-print.ts +1 -1
  130. package/scripts/document/command-reference-line-budget.ts +42 -0
  131. package/scripts/document/document-byte-budget.ts +17 -7
  132. package/scripts/document/document-checks.ts +20 -0
  133. package/scripts/document/document-ratchet-check.ts +101 -0
  134. package/scripts/document/document-section.ts +1 -0
  135. package/scripts/document/entry-read-budget.ts +7 -3
  136. package/scripts/document/issue-citation-budget.ts +94 -0
  137. package/scripts/epic/epic-cli-argv.ts +2 -2
  138. package/scripts/epic/epic-fetch.ts +4 -2
  139. package/scripts/epic/epic-graph.ts +7 -2
  140. package/scripts/epic/epic-issue.ts +3 -1
  141. package/scripts/epic/epic-rank.ts +5 -0
  142. package/scripts/exports/unused-members-check.ts +62 -0
  143. package/scripts/exports/unused-members-cli.ts +6 -51
  144. package/scripts/followup/followup-ci-path.ts +67 -0
  145. package/scripts/followup/followup-coderabbit-retrigger.ts +261 -0
  146. package/scripts/followup/followup-coderabbit-wait.ts +13 -10
  147. package/scripts/followup/followup-failed-tests.ts +160 -0
  148. package/scripts/followup/followup-job-needs.ts +100 -0
  149. package/scripts/followup/followup-job-rerun.ts +303 -0
  150. package/scripts/followup/followup-main-move.ts +113 -0
  151. package/scripts/followup/git-followup-finish.ts +43 -11
  152. package/scripts/followup/git-followup-pending.ts +3 -3
  153. package/scripts/followup/git-followup-stages.ts +41 -11
  154. package/scripts/followup/git-pr-followup-checks.ts +55 -16
  155. package/scripts/followup/git-pr-followup-wrapup.ts +24 -5
  156. package/scripts/followup/git-pr-followup.ts +62 -27
  157. package/scripts/fresh-machine/fresh-machine-script.ts +5 -9
  158. package/scripts/fresh-machine/specs/kit-test-backlogrun-python.json +2 -2
  159. package/scripts/fresh-machine/specs/kit-test-backlogrun.json +2 -2
  160. package/scripts/gate/busy-average.ts +34 -2
  161. package/scripts/gate/check-related-pinned.ts +43 -0
  162. package/scripts/gate/check-related-reuse.ts +64 -0
  163. package/scripts/gate/check-related-section.ts +57 -0
  164. package/scripts/gate/check-related-unplanned.ts +34 -0
  165. package/scripts/gate/check-related.ts +265 -0
  166. package/scripts/gate/command-memory.ts +1 -1
  167. package/scripts/gate/core-admission.ts +24 -6
  168. package/scripts/gate/core-budget-timing.ts +20 -6
  169. package/scripts/gate/core-budget.ts +40 -11
  170. package/scripts/gate/core-wait-record.ts +3 -2
  171. package/scripts/gate/core-wait.ts +25 -2
  172. package/scripts/gate/core-weights.ts +15 -7
  173. package/scripts/gate/gate-labels.ts +46 -0
  174. package/scripts/gate/gate-ledger.ts +14 -6
  175. package/scripts/gate/gate-plan.ts +103 -58
  176. package/scripts/gate/gate-report.ts +9 -7
  177. package/scripts/gate/gate-run-steps.ts +26 -3
  178. package/scripts/gate/gate-skip.ts +45 -6
  179. package/scripts/gate/gate-static-group.ts +60 -0
  180. package/scripts/gate/gate-steps.ts +2 -1
  181. package/scripts/gate/gate-tree.ts +4 -2
  182. package/scripts/gate/hook-gate-reuse.ts +19 -2
  183. package/scripts/gate/metrics-totals.ts +59 -0
  184. package/scripts/gate/scoped-green.ts +68 -15
  185. package/scripts/gate/since-green.ts +14 -6
  186. package/scripts/gate/structural-checks.ts +96 -0
  187. package/scripts/gate/verification-gate.ts +51 -16
  188. package/scripts/gate/verification-inputs.ts +21 -6
  189. package/scripts/gate/verification-tail.ts +52 -0
  190. package/scripts/gh/gh-author-association.ts +23 -2
  191. package/scripts/gh/git-ai-review-scan.ts +1 -1
  192. package/scripts/gh/git-gh-api-path.ts +12 -3
  193. package/scripts/gh/git-gh-comments-unreadable.ts +36 -0
  194. package/scripts/gh/git-gh-exec.ts +32 -2
  195. package/scripts/gh/git-gh-issue-read.ts +4 -2
  196. package/scripts/gh/git-gh-issue-rest.ts +1 -0
  197. package/scripts/gh/git-gh-issue-write.ts +8 -2
  198. package/scripts/gh/git-gh-issue.ts +12 -5
  199. package/scripts/gh/git-gh-pr-auto-merge.ts +13 -6
  200. package/scripts/gh/git-gh-pr-graphql-state.ts +56 -0
  201. package/scripts/gh/git-gh-pr-read.ts +74 -13
  202. package/scripts/gh/git-gh-pr-rest.ts +3 -1
  203. package/scripts/gh/git-gh-pr-snapshot.ts +22 -7
  204. package/scripts/gh/git-gh-pr-too-large.ts +20 -0
  205. package/scripts/gh/git-gh-pr.ts +21 -7
  206. package/scripts/gh/git-gh-retry.ts +141 -0
  207. package/scripts/gh/git-pr-ai-review.ts +15 -6
  208. package/scripts/gh/git-pr-checks-eval.ts +3 -0
  209. package/scripts/gh/git-pr-checks.ts +5 -5
  210. package/scripts/git/base-tree.ts +30 -0
  211. package/scripts/git/change-base.ts +4 -10
  212. package/scripts/git/changed-paths-sync.ts +63 -0
  213. package/scripts/git/changed-paths.ts +16 -1
  214. package/scripts/git/git-common-directory.ts +11 -1
  215. package/scripts/git/git-diff-reads.ts +66 -20
  216. package/scripts/git/git-error.ts +9 -2
  217. package/scripts/git/git-schemas.ts +13 -0
  218. package/scripts/git/git-worktree.ts +13 -0
  219. package/scripts/git/gone-branch.ts +4 -1
  220. package/scripts/git/main-merge-budget-conflict.ts +89 -0
  221. package/scripts/git/main-merge-guard.ts +55 -18
  222. package/scripts/git/main-merge-regenerate.ts +59 -25
  223. package/scripts/git/main-merge.ts +53 -5
  224. package/scripts/git/no-base-checkout.ts +127 -0
  225. package/scripts/git/stash/git-stash.ts +11 -2
  226. package/scripts/git/stash/stash-push-cli.ts +10 -0
  227. package/scripts/hooks/batch-guard.ts +40 -21
  228. package/scripts/hooks/edited-cspell.ts +37 -11
  229. package/scripts/hooks/format-edited-file.ts +22 -2
  230. package/scripts/hooks/lane-plan-guard.ts +50 -0
  231. package/scripts/hooks/pre-commit-lint-switch.ts +9 -0
  232. package/scripts/hooks/pre-commit-lint.ts +14 -1
  233. package/scripts/hooks/pre-push-related-switch.ts +10 -0
  234. package/scripts/hooks/pre-push-unit.ts +76 -10
  235. package/scripts/hooks/pretool-guard.ts +2 -0
  236. package/scripts/hooks/reserved-run.ts +14 -1
  237. package/scripts/hooks/run-hook.sh +23 -8
  238. package/scripts/hooks/step-zero-notice.ts +6 -1
  239. package/scripts/hooks/stop-actions.ts +3 -15
  240. package/scripts/hooks/stop-guard.ts +7 -6
  241. package/scripts/init/distributed-paths.ts +1 -0
  242. package/scripts/init/hook-command-rewrite.ts +5 -1
  243. package/scripts/init/hook-launch.ts +4 -2
  244. package/scripts/issue/aggregation-split.ts +52 -0
  245. package/scripts/issue/defect-origin-line.ts +19 -1
  246. package/scripts/issue/defect-rate-cli.ts +5 -102
  247. package/scripts/issue/defect-report.ts +4 -4
  248. package/scripts/issue/effect-audit-cli.ts +178 -0
  249. package/scripts/issue/effect-audit.ts +185 -0
  250. package/scripts/issue/expected-effect-lint.ts +64 -9
  251. package/scripts/issue/git-next-issues.ts +5 -0
  252. package/scripts/issue/issue-body-or-comment.ts +38 -4
  253. package/scripts/issue/issue-cite-cli.ts +1 -3
  254. package/scripts/issue/issue-classification.ts +1 -0
  255. package/scripts/issue/issue-closing-pr.ts +8 -1
  256. package/scripts/issue/issue-evidence-exit.ts +4 -2
  257. package/scripts/issue/issue-file-cap.ts +58 -0
  258. package/scripts/issue/issue-file-cli.ts +111 -38
  259. package/scripts/issue/issue-file-deferral.ts +52 -0
  260. package/scripts/issue/issue-file-fold.ts +29 -10
  261. package/scripts/issue/issue-file-interrupt.ts +85 -0
  262. package/scripts/issue/issue-file-lane-hint.ts +30 -0
  263. package/scripts/issue/issue-file.ts +43 -6
  264. package/scripts/issue/issue-labels.ts +19 -2
  265. package/scripts/issue/issue-lint-cli.ts +27 -2
  266. package/scripts/issue/issue-measured-cli.ts +13 -35
  267. package/scripts/issue/issue-measured-close.ts +58 -0
  268. package/scripts/issue/issue-not-before-label.ts +2 -2
  269. package/scripts/issue/issue-not-before.ts +4 -1
  270. package/scripts/issue/issue-priority-cli.ts +60 -0
  271. package/scripts/issue/issue-priority-raise.ts +55 -0
  272. package/scripts/issue/issue-priority.ts +174 -43
  273. package/scripts/issue/issue-rank.ts +21 -4
  274. package/scripts/issue/issue-read-cli.ts +32 -6
  275. package/scripts/issue/issue-read.ts +37 -12
  276. package/scripts/issue/issue-sample-gate.ts +95 -74
  277. package/scripts/issue/issue-sample-prime.ts +127 -0
  278. package/scripts/issue/issue-sample-required.ts +57 -0
  279. package/scripts/issue/issue-sample-source.ts +12 -11
  280. package/scripts/issue/issue-search.ts +124 -0
  281. package/scripts/issue/issue-state.ts +13 -1
  282. package/scripts/issue/issue-template-section.ts +43 -0
  283. package/scripts/issue/issue-watch-diff.ts +31 -1
  284. package/scripts/issue/issue-watch-hook.ts +11 -2
  285. package/scripts/issue/issue-watch.ts +55 -12
  286. package/scripts/issue/markdown-section.ts +1 -0
  287. package/scripts/issue/measure-declaration.ts +121 -0
  288. package/scripts/issue/measure-rerun-cli.ts +7 -70
  289. package/scripts/issue/plan-consumers-section.ts +22 -1
  290. package/scripts/issue/reproduction-measure.ts +3 -1
  291. package/scripts/issue/size-estimate.ts +90 -0
  292. package/scripts/issue/trusted-measure.ts +84 -0
  293. package/scripts/josh/command-usage.ts +3 -2
  294. package/scripts/josh/durable-state-migrate.ts +105 -0
  295. package/scripts/josh/durable-state.ts +112 -0
  296. package/scripts/josh/josh-aliases.ts +95 -0
  297. package/scripts/josh/josh-command-map.ts +1 -82
  298. package/scripts/josh/josh-commands-agent-hooks.ts +6 -6
  299. package/scripts/josh/josh-commands-ai.ts +5 -5
  300. package/scripts/josh/josh-commands-development.ts +59 -58
  301. package/scripts/josh/josh-commands-issue-write.ts +23 -4
  302. package/scripts/josh/josh-commands-issue.ts +32 -0
  303. package/scripts/josh/josh-commands-lane.ts +87 -4
  304. package/scripts/josh/josh-commands-lint.ts +16 -3
  305. package/scripts/josh/josh-commands-maintenance.ts +15 -0
  306. package/scripts/josh/josh-commands-review.ts +41 -6
  307. package/scripts/josh/josh-commands-ship.ts +56 -8
  308. package/scripts/josh/josh-commands-test-check.ts +80 -0
  309. package/scripts/josh/josh-commands-workflow.ts +1 -1
  310. package/scripts/josh/josh-environment-file.ts +43 -3
  311. package/scripts/josh/josh-in-process.ts +2 -2
  312. package/scripts/josh/josh-logic.ts +5 -3
  313. package/scripts/josh/josh-run.ts +19 -1
  314. package/scripts/josh/run-record-path.ts +15 -0
  315. package/scripts/josh/stamp-file.ts +11 -2
  316. package/scripts/lane/lane-adopt-cli.ts +98 -0
  317. package/scripts/lane/lane-adopt.ts +208 -0
  318. package/scripts/lane/lane-await.ts +5 -8
  319. package/scripts/lane/lane-baseline.ts +123 -0
  320. package/scripts/lane/lane-breakdown-cli.ts +64 -0
  321. package/scripts/lane/lane-breakdown-implement.ts +170 -0
  322. package/scripts/lane/lane-breakdown-laps.ts +107 -0
  323. package/scripts/lane/lane-breakdown-pinned.ts +76 -0
  324. package/scripts/lane/lane-breakdown-text.ts +145 -0
  325. package/scripts/lane/lane-breakdown.ts +239 -0
  326. package/scripts/lane/lane-check-stats.ts +29 -8
  327. package/scripts/lane/lane-child-invocation.ts +9 -2
  328. package/scripts/lane/lane-child-mark-keys.ts +12 -0
  329. package/scripts/lane/lane-child-marker.ts +20 -1
  330. package/scripts/lane/lane-ci-path-stats.ts +73 -0
  331. package/scripts/lane/lane-claim-stats.ts +84 -0
  332. package/scripts/lane/lane-close.ts +8 -3
  333. package/scripts/lane/lane-dispatch-log.ts +3 -3
  334. package/scripts/lane/lane-dispatch.ts +2 -2
  335. package/scripts/lane/lane-gap-stats.ts +7 -6
  336. package/scripts/lane/lane-guard-policy.ts +7 -1
  337. package/scripts/lane/lane-implement-stats.ts +207 -0
  338. package/scripts/lane/lane-implement-subagents.ts +90 -0
  339. package/scripts/lane/lane-investigation-switch.ts +16 -0
  340. package/scripts/lane/lane-ledger-kind.ts +31 -0
  341. package/scripts/lane/lane-ledger-schema-ship.ts +49 -0
  342. package/scripts/lane/lane-ledger-schema.ts +119 -36
  343. package/scripts/lane/lane-ledger-write.ts +257 -0
  344. package/scripts/lane/lane-ledger.ts +31 -177
  345. package/scripts/lane/lane-load.ts +1 -1
  346. package/scripts/lane/lane-measure-cli.ts +176 -59
  347. package/scripts/lane/lane-net-read.ts +44 -0
  348. package/scripts/lane/lane-net-time.ts +212 -0
  349. package/scripts/lane/lane-open.ts +16 -7
  350. package/scripts/lane/lane-output.ts +2 -4
  351. package/scripts/lane/lane-overrun-prompt.ts +147 -0
  352. package/scripts/lane/lane-overrun.ts +274 -0
  353. package/scripts/lane/lane-paths.ts +24 -1
  354. package/scripts/lane/lane-pause-cli.ts +4 -1
  355. package/scripts/lane/lane-paused-spans.ts +97 -0
  356. package/scripts/lane/lane-plan-check.ts +207 -0
  357. package/scripts/lane/lane-plan-cli.ts +41 -0
  358. package/scripts/lane/lane-plan.ts +144 -0
  359. package/scripts/lane/lane-registry.ts +14 -1
  360. package/scripts/lane/lane-relaunch.ts +1 -1
  361. package/scripts/lane/lane-round-one-stats.ts +51 -0
  362. package/scripts/lane/lane-sampler.ts +23 -4
  363. package/scripts/lane/lane-session-action.ts +93 -18
  364. package/scripts/lane/lane-session-broker.ts +49 -21
  365. package/scripts/lane/lane-session-reread-main.ts +14 -0
  366. package/scripts/lane/lane-session-reread.ts +51 -0
  367. package/scripts/lane/lane-ship-lap-stats.ts +74 -0
  368. package/scripts/lane/lane-sleep.ts +58 -0
  369. package/scripts/lane/lane-spent.ts +1 -1
  370. package/scripts/lane/lane-split-stats.ts +28 -0
  371. package/scripts/lane/lane-stage-stats.ts +13 -1
  372. package/scripts/lane/lane-state.ts +41 -9
  373. package/scripts/lane/lane-stats-tables.ts +58 -0
  374. package/scripts/lane/lane-stats.ts +21 -5
  375. package/scripts/lane/lane-stop-stats.ts +51 -19
  376. package/scripts/lane/lane-tail-stats.ts +32 -0
  377. package/scripts/lane/lane-transcript-calls.ts +67 -10
  378. package/scripts/lane/lane-transcript-stats.ts +44 -12
  379. package/scripts/lane/lane-value-cell.ts +72 -0
  380. package/scripts/lane/lane-value.ts +118 -0
  381. package/scripts/lane/lane-withdraw-closed.ts +124 -0
  382. package/scripts/lane/lane-withdraw.ts +108 -31
  383. package/scripts/lane/lane-yield.ts +85 -0
  384. package/scripts/lane/openai-lane-ship.ts +12 -11
  385. package/scripts/lane/openai-lane-supervisor-decision.ts +6 -8
  386. package/scripts/lane/openai-lane-supervisor-owner.ts +5 -8
  387. package/scripts/lane/openai-lane-supervisor.ts +5 -4
  388. package/scripts/lib/poll.ts +38 -9
  389. package/scripts/lib/settled-together.ts +10 -0
  390. package/scripts/lib/shell-quote.ts +21 -0
  391. package/scripts/lib/token-shape.ts +111 -0
  392. package/scripts/lint/eslint-daemon-sources.ts +79 -0
  393. package/scripts/lint/eslint-daemon.ts +45 -6
  394. package/scripts/lint/eslint-warm-cli.ts +7 -0
  395. package/scripts/lint/eslint-warm.ts +66 -0
  396. package/scripts/lint/import-graph.ts +141 -11
  397. package/scripts/lint/lint-gate-scope.ts +2 -2
  398. package/scripts/lint/lint-parallel.ts +54 -6
  399. package/scripts/lint/lint-related.ts +154 -33
  400. package/scripts/lint/rename-cli.ts +179 -0
  401. package/scripts/lint/rename-identifier.ts +192 -0
  402. package/scripts/lint/type-only-imports.ts +58 -0
  403. package/scripts/notify/telegram-notify.ts +12 -3
  404. package/scripts/observations/observation-record.ts +42 -16
  405. package/scripts/observations/observations-flush.ts +32 -9
  406. package/scripts/overrides/overrides-check.ts +9 -1
  407. package/scripts/release/release-approval-prune.ts +7 -1
  408. package/scripts/repo/required-checks-logic.ts +4 -1
  409. package/scripts/repo/ruleset-check.ts +4 -3
  410. package/scripts/report/markdown-shape.ts +28 -0
  411. package/scripts/report/report-format-reference.ts +15 -1
  412. package/scripts/report/report-labels.ts +12 -1
  413. package/scripts/report/report-lint-child-summary.ts +94 -0
  414. package/scripts/report/report-lint-cli.ts +26 -7
  415. package/scripts/report/report-lint.ts +2 -20
  416. package/scripts/review/prose-stale-cli.ts +88 -0
  417. package/scripts/review/prose-stale-scan.ts +152 -0
  418. package/scripts/review/review-attest.ts +73 -23
  419. package/scripts/review/review-brief-cli.ts +68 -19
  420. package/scripts/review/review-brief-paths.ts +22 -0
  421. package/scripts/review/review-brief.ts +14 -7
  422. package/scripts/review/review-comment-carry.ts +47 -0
  423. package/scripts/review/review-comment-round.ts +85 -22
  424. package/scripts/review/review-finding-ledger.ts +109 -7
  425. package/scripts/review/review-finding-text.ts +43 -0
  426. package/scripts/review/review-interaction.ts +11 -0
  427. package/scripts/review/review-lane-handover.ts +68 -0
  428. package/scripts/review/review-lint-cli.ts +57 -0
  429. package/scripts/review/review-lint-findings.ts +92 -0
  430. package/scripts/review/review-lint-sections.ts +80 -0
  431. package/scripts/review/review-lint.ts +221 -0
  432. package/scripts/review/review-prior-findings.ts +102 -0
  433. package/scripts/review/review-readers-scan.ts +4 -2
  434. package/scripts/review/review-record-cli.ts +177 -54
  435. package/scripts/review/review-record-code-round.ts +55 -0
  436. package/scripts/review/review-record-comment.ts +60 -0
  437. package/scripts/review/review-record-interaction.ts +35 -0
  438. package/scripts/review/review-record-pinned.ts +108 -0
  439. package/scripts/review/review-record.ts +25 -1
  440. package/scripts/review/review-reviewed-tree.ts +307 -0
  441. package/scripts/review/review-round-one-closure.ts +62 -0
  442. package/scripts/review/review-round-reuse.ts +106 -0
  443. package/scripts/review/review-round2-cli.ts +91 -29
  444. package/scripts/review/review-round2-skip-comment.ts +55 -0
  445. package/scripts/review/review-round2.ts +24 -8
  446. package/scripts/review/review-stamps.ts +7 -3
  447. package/scripts/review/review-stop-log.ts +20 -6
  448. package/scripts/review/review-stops-cli.ts +2 -1
  449. package/scripts/review/review-submit-cli.ts +101 -0
  450. package/scripts/rules/agent-model.ts +1 -1
  451. package/scripts/rules/bash-triggers.ts +3 -3
  452. package/scripts/rules/concise-reply.ts +88 -0
  453. package/scripts/rules/credential-body.ts +77 -0
  454. package/scripts/rules/decision-oracle.ts +1 -1
  455. package/scripts/rules/delivered-rules.ts +36 -17
  456. package/scripts/rules/destructive-command.ts +3 -11
  457. package/scripts/rules/direct-issue-comment.ts +34 -12
  458. package/scripts/rules/direct-issue-read.ts +191 -0
  459. package/scripts/rules/direct-pr-create.ts +4 -24
  460. package/scripts/rules/early-heartbeat.ts +2 -0
  461. package/scripts/rules/edit-tool.ts +27 -0
  462. package/scripts/rules/file-edit-rows.ts +17 -0
  463. package/scripts/rules/file-rewrite.ts +146 -0
  464. package/scripts/rules/firing-point.ts +3 -2
  465. package/scripts/rules/gh-api.ts +128 -7
  466. package/scripts/rules/gh-repo-selector.ts +84 -0
  467. package/scripts/rules/git-force.ts +2 -2
  468. package/scripts/rules/guard-remedy.ts +14 -5
  469. package/scripts/rules/implementation-cut.ts +61 -28
  470. package/scripts/rules/investigator-foreground.ts +231 -0
  471. package/scripts/rules/issue-citation.ts +15 -60
  472. package/scripts/rules/issue-comments.ts +9 -4
  473. package/scripts/rules/josh-git-bare.ts +1 -1
  474. package/scripts/rules/lane-background.ts +41 -13
  475. package/scripts/rules/lane-direct-tool.ts +107 -9
  476. package/scripts/rules/lane-interactive-ask.ts +4 -1
  477. package/scripts/rules/lane-park.ts +4 -2
  478. package/scripts/rules/lane-spilled-read.ts +90 -0
  479. package/scripts/rules/lane-split-park.ts +1 -1
  480. package/scripts/rules/lane-switch-main.ts +4 -4
  481. package/scripts/rules/last-prompt.ts +20 -47
  482. package/scripts/rules/oracle-consulted.ts +1 -1
  483. package/scripts/rules/permission-guards.ts +5 -1
  484. package/scripts/rules/piped-verification-shapes.ts +110 -0
  485. package/scripts/rules/piped-verification.ts +67 -17
  486. package/scripts/rules/poll-loop.ts +72 -9
  487. package/scripts/rules/pr-merge.ts +5 -5
  488. package/scripts/rules/pre-gate-cut.ts +3 -3
  489. package/scripts/rules/protected-files.ts +88 -24
  490. package/scripts/rules/reply-language.ts +3 -17
  491. package/scripts/rules/reply-prose.ts +34 -0
  492. package/scripts/rules/repo-admin.ts +132 -0
  493. package/scripts/rules/reviewer-foreground.ts +88 -0
  494. package/scripts/rules/round-one-check-related.ts +120 -0
  495. package/scripts/rules/rule-body-guard.ts +5 -15
  496. package/scripts/rules/rule-value-cache.ts +53 -5
  497. package/scripts/rules/rule-value-candidates.ts +84 -0
  498. package/scripts/rules/rule-value-cli.ts +59 -11
  499. package/scripts/rules/rule-value.ts +17 -4
  500. package/scripts/rules/run-tail-rule.ts +1 -1
  501. package/scripts/rules/sed-in-place.ts +196 -0
  502. package/scripts/rules/shell-segments.ts +10 -2
  503. package/scripts/rules/stop-rule-rows.ts +1 -13
  504. package/scripts/rules/stop-rules.ts +33 -58
  505. package/scripts/rules/test-declared-commit.ts +1 -1
  506. package/scripts/rules/third-party-write.ts +110 -23
  507. package/scripts/rules/timed-rerun.ts +1 -1
  508. package/scripts/rules/turn-filings.ts +90 -0
  509. package/scripts/rules/worktree-guard.ts +22 -7
  510. package/scripts/run/board/run-board-ending-reason.ts +6 -2
  511. package/scripts/run/board/run-board-fit.ts +24 -1
  512. package/scripts/run/board/run-board-found.ts +134 -0
  513. package/scripts/run/board/run-board-header.ts +8 -0
  514. package/scripts/run/board/run-board-labels.ts +11 -1
  515. package/scripts/run/board/run-board-lane-time.ts +1 -0
  516. package/scripts/run/board/run-board-link.ts +15 -2
  517. package/scripts/run/board/run-board-notes.ts +7 -1
  518. package/scripts/run/board/run-board-operation.ts +4 -2
  519. package/scripts/run/board/run-board-phase.ts +2 -5
  520. package/scripts/run/board/run-board-plan.ts +1 -1
  521. package/scripts/run/board/run-board-read.ts +46 -1
  522. package/scripts/run/board/run-board-reason.ts +20 -8
  523. package/scripts/run/board/run-board-render-checks.ts +3 -2
  524. package/scripts/run/board/run-board-render-drawn.ts +11 -0
  525. package/scripts/run/board/run-board-render-found.ts +157 -0
  526. package/scripts/run/board/run-board-render-lead.ts +9 -0
  527. package/scripts/run/board/run-board-render-legend.ts +19 -0
  528. package/scripts/run/board/run-board-render-tail.ts +1 -1
  529. package/scripts/run/board/run-board-render.ts +82 -18
  530. package/scripts/run/board/run-board-spin.ts +1 -3
  531. package/scripts/run/board/run-board-status.ts +2 -0
  532. package/scripts/run/board/run-board-tick.ts +39 -10
  533. package/scripts/run/carry/run-carry-ended.ts +3 -2
  534. package/scripts/run/carry/run-carry.ts +3 -2
  535. package/scripts/run/cut/run-cut-cli.ts +33 -133
  536. package/scripts/run/cut/run-cut-digest.ts +152 -0
  537. package/scripts/run/cut/run-cut-handoff.ts +52 -8
  538. package/scripts/run/cut/run-cut-report.ts +24 -3
  539. package/scripts/run/cut/run-cut-resume.ts +129 -0
  540. package/scripts/run/cut/run-cut-review.ts +105 -0
  541. package/scripts/run/cut/run-cut.ts +18 -7
  542. package/scripts/run/detached-launch.ts +1 -1
  543. package/scripts/run/entry/run-entry-cli.ts +88 -19
  544. package/scripts/run/entry/run-entry-spill.ts +83 -0
  545. package/scripts/run/entry/run-entry-stop.ts +5 -1
  546. package/scripts/run/entry/run-entry-trust.ts +91 -0
  547. package/scripts/run/event/run-event-baseline.ts +56 -0
  548. package/scripts/run/event/run-event-filed.ts +9 -3
  549. package/scripts/run/event/run-event-overrun.ts +197 -0
  550. package/scripts/run/event/run-event-render.ts +4 -0
  551. package/scripts/run/event/run-event-stream.ts +25 -3
  552. package/scripts/run/hold/run-stop-notify.ts +3 -8
  553. package/scripts/run/merge/run-merge-cap.ts +57 -0
  554. package/scripts/run/merge/run-merge-cli.ts +66 -23
  555. package/scripts/run/merge/run-merge-outcome.ts +2 -0
  556. package/scripts/run/merge/run-merge-ship.ts +13 -3
  557. package/scripts/run/merge/run-merge-signals.ts +40 -23
  558. package/scripts/run/merge/run-merge-steps.ts +56 -36
  559. package/scripts/run/merge/run-merge-usage-limit.ts +53 -0
  560. package/scripts/run/merge/run-merge-withdrawn.ts +53 -0
  561. package/scripts/run/merge/run-merge.ts +41 -14
  562. package/scripts/run/review/run-review-cli.ts +306 -20
  563. package/scripts/run/review/run-review-early-push.ts +121 -0
  564. package/scripts/run/review/run-review-join-read.ts +94 -0
  565. package/scripts/run/review/run-review-pinned-accepted.ts +126 -0
  566. package/scripts/run/review/run-review-pinned-join.ts +216 -0
  567. package/scripts/run/review/run-review-pinned-steps.ts +383 -0
  568. package/scripts/run/review/run-review-pinned-tree.ts +37 -0
  569. package/scripts/run/review/run-review-pinned.ts +53 -0
  570. package/scripts/run/review/run-review-steps.ts +70 -34
  571. package/scripts/run/review/run-review.ts +26 -6
  572. package/scripts/run/run-parent-cut-hook.ts +3 -4
  573. package/scripts/run/run-prep.ts +1 -0
  574. package/scripts/run/run-stage-read.ts +2 -6
  575. package/scripts/run/run-step-cli.ts +17 -5
  576. package/scripts/run/run-step-lane-plan.ts +27 -0
  577. package/scripts/run/run-step-section.ts +26 -7
  578. package/scripts/run/run-step.ts +5 -2
  579. package/scripts/run/ship/run-ship-args.ts +19 -0
  580. package/scripts/run/ship/run-ship-brokered-review.ts +106 -0
  581. package/scripts/run/ship/run-ship-cli.ts +131 -39
  582. package/scripts/run/ship/run-ship-conflict-probe.ts +59 -0
  583. package/scripts/run/ship/run-ship-detach.ts +10 -4
  584. package/scripts/run/ship/run-ship-handover.ts +106 -0
  585. package/scripts/run/ship/run-ship-infra-retry.ts +16 -1
  586. package/scripts/run/ship/run-ship-lap.ts +63 -0
  587. package/scripts/run/ship/run-ship-next.ts +27 -26
  588. package/scripts/run/ship/run-ship-overlap.ts +8 -3
  589. package/scripts/run/ship/run-ship-place.ts +9 -2
  590. package/scripts/run/ship/run-ship-planned.ts +92 -0
  591. package/scripts/run/ship/run-ship-pre-detach-pinned.ts +197 -0
  592. package/scripts/run/ship/run-ship-pre-detach-timed.ts +7 -8
  593. package/scripts/run/ship/run-ship-pre-detach.ts +77 -23
  594. package/scripts/run/ship/run-ship-preflight.ts +16 -4
  595. package/scripts/run/ship/run-ship-probe.ts +23 -9
  596. package/scripts/run/ship/run-ship-relaunch-cap.ts +43 -7
  597. package/scripts/run/ship/run-ship-relaunch.ts +51 -0
  598. package/scripts/run/ship/run-ship-return.ts +103 -29
  599. package/scripts/run/ship/run-ship-review-reason.ts +24 -0
  600. package/scripts/run/ship/run-ship-review-steps.ts +230 -59
  601. package/scripts/run/ship/run-ship-review.ts +171 -51
  602. package/scripts/run/ship/run-ship-reviewer.ts +138 -42
  603. package/scripts/run/ship/run-ship-scoped.ts +39 -10
  604. package/scripts/run/ship/run-ship-stage.ts +49 -13
  605. package/scripts/run/ship/run-ship-steps.ts +24 -4
  606. package/scripts/run/ship/run-ship-stop-cause.ts +43 -2
  607. package/scripts/run/ship/run-ship-stop-context.ts +50 -13
  608. package/scripts/run/ship/run-ship-sync.ts +171 -30
  609. package/scripts/run/ship/run-ship-synced-scope.ts +178 -0
  610. package/scripts/run/ship/run-ship-wait-cli.ts +145 -0
  611. package/scripts/run/ship/run-ship-waiter.ts +114 -0
  612. package/scripts/run/ship/run-ship.ts +16 -2
  613. package/scripts/run/wake/run-wake-caffeinate.ts +48 -0
  614. package/scripts/run/wake/run-wake-cli.ts +6 -113
  615. package/scripts/run/wake/run-wake-code.ts +53 -11
  616. package/scripts/run/wake/run-wake-driver.ts +5 -3
  617. package/scripts/run/wake/run-wake-finish.ts +137 -0
  618. package/scripts/run/wake/run-wake-loop.ts +5 -3
  619. package/scripts/run/wake/run-wake-ports.ts +11 -3
  620. package/scripts/run/wake/run-wake-session.ts +2 -0
  621. package/scripts/run/wake/run-wake.ts +3 -2
  622. package/scripts/safe-chain/ci-installer-pin.ts +49 -8
  623. package/scripts/safe-chain/project-config.ts +3 -2
  624. package/scripts/security/secretlint-scan.ts +42 -9
  625. package/scripts/security/security-audit-provision-main.ts +9 -1
  626. package/scripts/security/security-audit-provision.ts +1 -1
  627. package/scripts/security/security-audit.ts +21 -1
  628. package/scripts/security/sonar-file.ts +10 -5
  629. package/scripts/split/split-assess.ts +12 -3
  630. package/scripts/split/split-early-notice.ts +116 -0
  631. package/scripts/split/split-measure.ts +20 -2
  632. package/scripts/split/split-resolution.ts +107 -0
  633. package/scripts/test/direct-importers.ts +185 -0
  634. package/scripts/test/pure-files-entries.ts +83 -0
  635. package/scripts/test/related-heavy-tests.ts +81 -0
  636. package/scripts/test/test-no-base.ts +88 -0
  637. package/scripts/test/test-pinned-cache-logic.ts +363 -0
  638. package/scripts/test/test-pinned-cache.ts +337 -0
  639. package/scripts/test/test-pinned-emit.ts +49 -0
  640. package/scripts/test/test-pinned-functions.ts +116 -0
  641. package/scripts/test/test-pinned-ledger.ts +80 -0
  642. package/scripts/test/test-pinned-logic.ts +208 -20
  643. package/scripts/test/test-pinned-main.ts +84 -18
  644. package/scripts/test/test-pinned-pool.ts +73 -0
  645. package/scripts/test/test-pinned-probe.ts +254 -0
  646. package/scripts/test/test-pinned-prune-logic.ts +118 -0
  647. package/scripts/test/test-pinned-reach.ts +194 -0
  648. package/scripts/test/test-pinned-record.ts +196 -0
  649. package/scripts/test/test-pinned-rewire.ts +148 -0
  650. package/scripts/test/test-pinned-spawn.ts +81 -0
  651. package/scripts/test/test-pinned-stage.ts +70 -0
  652. package/scripts/test/test-pinned.ts +258 -47
  653. package/scripts/test/test-reach-cli.ts +61 -0
  654. package/scripts/test/test-read-map.ts +35 -11
  655. package/scripts/test/test-read-recording.ts +17 -5
  656. package/scripts/test/test-read-trace.ts +26 -8
  657. package/scripts/test/test-red-logic.ts +46 -7
  658. package/scripts/test/test-red.ts +34 -14
  659. package/scripts/test/test-related-claim.ts +37 -0
  660. package/scripts/test/test-related-main.ts +4 -1
  661. package/scripts/test/test-related-moved.ts +91 -0
  662. package/scripts/test/test-related-record.ts +43 -23
  663. package/scripts/test/test-related-scope.ts +99 -34
  664. package/scripts/test/test-related-synced.ts +135 -0
  665. package/scripts/test/test-related-touched.ts +84 -0
  666. package/scripts/test/test-related.ts +167 -83
  667. package/scripts/test/test-unit-guard.ts +28 -5
  668. package/scripts/test/unit-durations.ts +41 -0
  669. package/scripts/test/unit-worker-share.ts +5 -4
  670. package/scripts/test/vitest-cache-directory.ts +19 -0
  671. package/scripts/test/vitest-cli-excludes.ts +14 -0
  672. package/scripts/test/vitest-failure-summary.ts +111 -0
  673. package/scripts/test/whole-suite-files.ts +12 -1
  674. package/scripts/time-runtime/time-batch-guard.ts +42 -4
  675. package/scripts/time-runtime/time-bundle-call.ts +1 -1
  676. package/scripts/time-runtime/time-bundles.ts +36 -5
  677. package/scripts/time-runtime/time-markers.ts +2 -2
  678. package/scripts/time-runtime/time-search-call.ts +38 -0
  679. package/scripts/time-runtime/time-shell.ts +1 -1
  680. package/scripts/time-runtime/time-transcript-line.ts +17 -5
  681. package/scripts/version/development-engines-verdict.ts +124 -0
  682. package/scripts/version/latest-corepack.ts +2 -0
  683. package/templates/gitignore +2 -0
  684. package/templates/workflows/ci.yml +41 -0
  685. package/dist/hooks/chunk-AZX4FGQ3.js +0 -207
  686. package/dist/hooks/chunk-PT5R6UJD.js +0 -7131
  687. package/dist/hooks/chunk-TUIFS5E7.js +0 -72
  688. package/dist/hooks/chunk-YCDOIR3I.js +0 -3456
  689. package/scripts/cost-runtime/context-cut-threshold.ts +0 -11
  690. package/scripts/rules/filing-cap.ts +0 -139
@@ -2,7 +2,7 @@ import { readFileSync } from 'node:fs'
2
2
  import path from 'node:path'
3
3
  import { PROJECT_ROOT } from '#scripts/init/init-paths'
4
4
  import { lint_related_scope } from '#scripts/lint/lint-related-scope'
5
- import { gate_plan } from './gate-plan'
5
+ import { gate_labels } from './gate-labels'
6
6
  import { input_fingerprint } from './input-fingerprint'
7
7
  import { toolchain_inputs } from './toolchain-inputs'
8
8
 
@@ -169,12 +169,27 @@ function compiled(is_input: FileTest): InputDeclaration {
169
169
  }
170
170
  }
171
171
 
172
+ // **cspell reads every file with dotfiles**, so any moved file — its config and word lists among
173
+ // them — answers "run again" (joshuafolkken/kit#5156).
174
+ async function is_any_file(): Promise<boolean> {
175
+ return true
176
+ }
177
+
178
+ const SPELLING: InputDeclaration = {
179
+ is_input: is_any_file,
180
+ reads: 'matched',
181
+ is_config: configures_toolchain,
182
+ tools: ['cspell'],
183
+ env: COMMON_ENV,
184
+ }
185
+
172
186
  const DECLARATIONS: ReadonlyMap<string, InputDeclaration> = new Map([
173
- [gate_plan.LINT_LABEL, LINT],
174
- [gate_plan.TYPE_CHECK_LABEL, compiled(is_source_input)],
175
- [gate_plan.EXPORTS_LABEL, compiled(is_source_input)],
176
- [gate_plan.METRICS_LABEL, compiled(is_metrics_input)],
177
- [gate_plan.UNIT_LABEL, UNIT],
187
+ [gate_labels.LINT_LABEL, LINT],
188
+ [gate_labels.SPELL_CHECK_LABEL, SPELLING],
189
+ [gate_labels.TYPE_CHECK_LABEL, compiled(is_source_input)],
190
+ [gate_labels.EXPORTS_LABEL, compiled(is_source_input)],
191
+ [gate_labels.METRICS_LABEL, compiled(is_metrics_input)],
192
+ [gate_labels.UNIT_LABEL, UNIT],
178
193
  ])
179
194
 
180
195
  function declaration_of(label: string): InputDeclaration | undefined {
@@ -0,0 +1,52 @@
1
+ import { status_icons } from '#scripts/lib/status-icons'
2
+ import { gate_log } from './gate-log'
3
+
4
+ // The end every josh verification check prints, in one place (joshuafolkken/kit#5162).
5
+ //
6
+ // **A run pipes a check into `tail` because the end is the answer.** Over 4,145 piped calls, 85% were a
7
+ // `tail -N` and most of the rest a `grep` for `FAIL`, `error` or a `✓`/`✗` — the run wanted to know
8
+ // whether the check passed and what to look at if it did not. `josh gate` already ended that way, while
9
+ // `lint:related` printed no verdict at all and `test:related` printed one only on a failure, so the run
10
+ // kept inventing the filter. Every check now ends with the same three parts, built here:
11
+ //
12
+ // 1. what failed and what to run next — nothing on a green run;
13
+ // 2. where the whole output was kept (`gate-log.ts`), for a check that keeps one;
14
+ // 3. the verdict, always the last line, for the reason `josh-verdict.ts` gives.
15
+
16
+ const { FAIL_ICON, PASS_ICON } = status_icons
17
+
18
+ // Where the whole output went: `path` is `undefined` when the write failed, which the notice says.
19
+ interface KeptLog {
20
+ path: string | undefined
21
+ }
22
+
23
+ interface VerificationTail {
24
+ // The lines above the log notice, each ending in a newline; empty on a green run.
25
+ failures: string
26
+ // Absent where the console is the only copy of the output.
27
+ log?: KeptLog | undefined
28
+ verdict: string
29
+ }
30
+
31
+ // `✓ <command> passed` or `✗ <command> failed: <what failed>`.
32
+ function format_verdict(command: string, failed: ReadonlyArray<string>): string {
33
+ if (failed.length === 0) return `${PASS_ICON} ${command} passed`
34
+
35
+ return `${FAIL_ICON} ${command} failed: ${failed.join(', ')}`
36
+ }
37
+
38
+ // One failure and the command that reproduces it, as `josh gate` names its failed checks.
39
+ function format_rerun(label: string, command: string): string {
40
+ return ` ${FAIL_ICON} ${label} — re-run: ${command}`
41
+ }
42
+
43
+ function format_tail(tail: VerificationTail): string {
44
+ const notice = tail.log === undefined ? '' : gate_log.format_log_notice(tail.log.path)
45
+
46
+ return `${tail.failures}${notice}${tail.verdict}\n`
47
+ }
48
+
49
+ const verification_tail = { format_rerun, format_tail, format_verdict }
50
+
51
+ export type { KeptLog, VerificationTail }
52
+ export { verification_tail }
@@ -1,5 +1,6 @@
1
1
  import { git_gh_api_path } from '#scripts/gh/git-gh-api-path'
2
2
  import { git_gh_exec } from '#scripts/gh/git-gh-exec'
3
+ import { author_fields_schema } from '#scripts/git/git-schemas'
3
4
  import { parse_json } from '#scripts/git/parse-json-array'
4
5
  import { z } from 'zod'
5
6
 
@@ -20,6 +21,9 @@ const WRITE_ROLES: ReadonlySet<string> = new Set(['admin', 'maintain', 'write'])
20
21
  // path, so anything else (a `[bot]` login, a slash) is refused before a request is made.
21
22
  const LOGIN_PATTERN = /^[\da-z](?:[\w-]*[\da-z])?$/iu
22
23
  const TRUSTED_LIST = 'OWNER, or MEMBER / COLLABORATOR with write access'
24
+ // The REST fields that name who wrote an issue, asked beside its body by every reader that decides
25
+ // whether to act on that body; `author_fields_schema` is the shape they parse to.
26
+ const AUTHOR_FIELDS = 'author_association,user'
23
27
 
24
28
  const permission_schema = z.looseObject({
25
29
  permission: z.string().nullish(),
@@ -33,6 +37,11 @@ interface Author {
33
37
  timeout_ms?: number | undefined
34
38
  }
35
39
 
40
+ interface AuthorFields {
41
+ author_association?: string | null | undefined
42
+ user?: { login: string } | null | undefined
43
+ }
44
+
36
45
  const answers = new Map<string, Promise<boolean | undefined>>()
37
46
 
38
47
  function permission_path(login: string): string {
@@ -95,7 +104,19 @@ async function is_trusted(author: Author): Promise<boolean> {
95
104
  return (await trust_of(author)) === true
96
105
  }
97
106
 
98
- const gh_author_association = { TRUSTED_LIST, is_trusted, trust_of }
107
+ // The author of a row read with `AUTHOR_FIELDS`.
108
+ function author_of(row: AuthorFields, timeout_ms?: number): Author {
109
+ return { login: row.user?.login, association: row.author_association, timeout_ms }
110
+ }
111
+
112
+ const gh_author_association = {
113
+ AUTHOR_FIELDS,
114
+ TRUSTED_LIST,
115
+ author_fields_schema,
116
+ author_of,
117
+ is_trusted,
118
+ trust_of,
119
+ }
99
120
 
100
- export type { Author }
121
+ export type { Author, AuthorFields }
101
122
  export { gh_author_association }
@@ -149,5 +149,5 @@ function classify_ai_review_comments(comments: ReadonlyArray<ReviewComment>): Cl
149
149
  }
150
150
  }
151
151
 
152
- export { classify_ai_review_comments }
152
+ export { classify_ai_review_comments, is_coderabbit_author, is_coderabbit_rate_limit }
153
153
  export type { ReviewComment, ClassifiedFinding, ClassifiedFindings, FindingKind }
@@ -99,20 +99,28 @@ function commit_status_api_path(commit_sha: string, repo?: string): string {
99
99
 
100
100
  // The rules that apply to one branch, from every ruleset that targets it — readable without the
101
101
  // admin access the classic branch protection endpoint needs.
102
+ // Ref names are encoded as one segment: a `?` or `#` would otherwise end the path, and GitHub reads
103
+ // an encoded `/` back as part of the branch name.
102
104
  function branch_rules_api_path(branch_name: string, repo?: string): string {
103
- return `${repo_api_path(repo)}/rules/branches/${branch_name}`
105
+ return `${repo_api_path(repo)}/rules/branches/${encodeURIComponent(branch_name)}`
106
+ }
107
+
108
+ // The status checks classic branch protection requires — the half of the required checks rulesets
109
+ // do not carry.
110
+ function branch_protection_checks_api_path(branch_name: string, repo?: string): string {
111
+ return `${repo_api_path(repo)}/branches/${encodeURIComponent(branch_name)}/protection/required_status_checks`
104
112
  }
105
113
 
106
114
  // A single tag reference. REST answers 404 when the tag does not exist, which is the whole of the
107
115
  // question the release command's tag watch asks.
108
116
  function tag_reference_api_path(tag: string, repo?: string): string {
109
- return `${repo_api_path(repo)}/git/ref/tags/${tag}`
117
+ return `${repo_api_path(repo)}/git/ref/tags/${encodeURIComponent(tag)}`
110
118
  }
111
119
 
112
120
  // The GitHub Release published for one tag. REST answers 404 until `publish.yml`'s `create-release`
113
121
  // job has run, which is what the release command's progress watch asks.
114
122
  function release_by_tag_api_path(tag: string, repo?: string): string {
115
- return `${repo_api_path(repo)}/releases/tags/${tag}`
123
+ return `${repo_api_path(repo)}/releases/tags/${encodeURIComponent(tag)}`
116
124
  }
117
125
 
118
126
  const git_gh_api_path = {
@@ -134,6 +142,7 @@ const git_gh_api_path = {
134
142
  commit_check_runs_api_path,
135
143
  commit_status_api_path,
136
144
  branch_rules_api_path,
145
+ branch_protection_checks_api_path,
137
146
  }
138
147
 
139
148
  export { git_gh_api_path, FULL_PAGE_QUERY }
@@ -0,0 +1,36 @@
1
+ // A pull request comment listing that could not be read (joshuafolkken/kit#5012).
2
+ //
3
+ // The reader warns with gh's reason, never swallowing it. Only the AI review gate stops on the
4
+ // unreadable listing — a CodeRabbit listing that could not be read is a note the followup carries
5
+ // past — so the gate alone prints `UNREADABLE_COMMENTS_STOP` on the standard output, which `josh ship`
6
+ // reads as the infrastructure and re-runs the followup on in place rather than relaunching the lane.
7
+ // Its own module, so the ship's stop classification reads the note without loading the gate.
8
+
9
+ const UNREADABLE_COMMENTS_STOP = 'the merge gate stopped on reviewer comments it could not read'
10
+
11
+ // Set by `josh ship` around an attempt it will run again on an infrastructure stop
12
+ // (`run-ship-infra-retry.ts`): the gate's `confirmation` then waits for the final attempt, so a read
13
+ // that recovers sends none and one that never does sends one.
14
+ const RETRY_PENDING_KEY = 'JOSH_SHIP_RETRY_PENDING'
15
+ const RETRY_PENDING_VALUE = '1'
16
+
17
+ function note_unreadable_comments(branch_name: string, reason: string): void {
18
+ console.warn(`⚠ pull request comments could not be read for ${branch_name}: ${reason}`)
19
+ }
20
+
21
+ function note_unreadable_stop(): void {
22
+ console.info(`⚠️ ${UNREADABLE_COMMENTS_STOP}`)
23
+ }
24
+
25
+ function is_retry_pending(): boolean {
26
+ return process.env[RETRY_PENDING_KEY] === RETRY_PENDING_VALUE
27
+ }
28
+
29
+ export {
30
+ is_retry_pending,
31
+ note_unreadable_comments,
32
+ note_unreadable_stop,
33
+ RETRY_PENDING_KEY,
34
+ RETRY_PENDING_VALUE,
35
+ UNREADABLE_COMMENTS_STOP,
36
+ }
@@ -1,9 +1,11 @@
1
1
  import { has_timed_out } from '#scripts/git/git-execa-error'
2
2
  import { agent_session_environment } from '#scripts/josh/agent-session-environment'
3
3
  import { error_text } from '#scripts/lib/error-message'
4
+ import { token_shape } from '#scripts/lib/token-shape'
4
5
  import { execa, execaSync } from 'execa'
5
6
  import { check_gh_installed } from './git-gh-check'
6
7
  import { gh_failure } from './git-gh-failure'
8
+ import { gh_retry } from './git-gh-retry'
7
9
 
8
10
  const BODY_FROM_STDIN = '-'
9
11
 
@@ -258,6 +260,7 @@ const INPUT_FLAG = '--input'
258
260
  const PAGINATE_FLAG = '--paginate'
259
261
  const SLURP_FLAG = '--slurp'
260
262
  const JQ_FLAG = '--jq'
263
+ const ALLOW_ESCAPES_FLAG = '--allow-escape-sequences'
261
264
 
262
265
  // One REST request through `gh api`. `path` is the only required field: a read names nothing else,
263
266
  // because `gh api` sends GET when neither `--method` nor a request body is given. **A `body` alone
@@ -292,16 +295,32 @@ interface GhApiRequest {
292
295
  // The checkout gh runs in, which is what `{owner}/{repo}` in `path` resolves against. Absent means
293
296
  // the process's own directory.
294
297
  cwd?: string
298
+ // `false` for a write that must not be sent twice: a transient failure may follow a write that
299
+ // already landed, and nothing reads it back (`git-gh-retry.ts`). Absent means retried.
300
+ should_retry?: boolean
301
+ // `true` for a plain-text body that carries terminal colors, such as an Actions job log: gh refuses
302
+ // to print one off a terminal without `--allow-escape-sequences`.
303
+ should_allow_escapes?: boolean
295
304
  }
296
305
 
297
306
  function optional_flag(flag: string, value?: string): Array<string> {
298
307
  return value === undefined ? [] : [flag, value]
299
308
  }
300
309
 
310
+ // Every Issue and pull-request body kit writes travels through the two entries below, so a credential
311
+ // pasted into one is refused here, once, before it reaches a public tracker. The writers pass the body
312
+ // JSON-encoded, so it is scanned decoded.
313
+ function refuse_credential_body(request: GhApiRequest): void {
314
+ if (request.body !== undefined) {
315
+ token_shape.refuse(token_shape.decoded(request.body), `The gh api ${request.path} body`)
316
+ }
317
+ }
318
+
301
319
  function to_gh_api_args(request: GhApiRequest): Array<string> {
302
320
  const body_args = request.body === undefined ? [] : [INPUT_FLAG, BODY_FROM_STDIN]
303
321
  const paginate_args = request.should_paginate === true ? [PAGINATE_FLAG] : []
304
322
  const slurp_args = request.should_slurp === true ? [SLURP_FLAG] : []
323
+ const escape_args = request.should_allow_escapes === true ? [ALLOW_ESCAPES_FLAG] : []
305
324
 
306
325
  return [
307
326
  'api',
@@ -310,6 +329,7 @@ function to_gh_api_args(request: GhApiRequest): Array<string> {
310
329
  ...body_args,
311
330
  ...paginate_args,
312
331
  ...slurp_args,
332
+ ...escape_args,
313
333
  ...optional_flag(JQ_FLAG, request.jq_filter),
314
334
  ]
315
335
  }
@@ -320,8 +340,9 @@ function to_gh_api_args(request: GhApiRequest): Array<string> {
320
340
  // `read_gh_api_sync` below.
321
341
  //
322
342
  // Failure handling funnels through `to_gh_error` on both paths below, so a failed request throws
323
- // with gh's stderr summary *and* the JSON error body it wrote to stdout.
324
- async function exec_gh_api(request: GhApiRequest): Promise<string> {
343
+ // with gh's stderr summary *and* the JSON error body it wrote to stdout. A transient failure — a 5xx
344
+ // or no answer at all — is asked again a bounded number of times first (`git-gh-retry.ts`).
345
+ async function send_gh_api(request: GhApiRequest): Promise<string> {
325
346
  const args = to_gh_api_args(request)
326
347
 
327
348
  if (request.body === undefined) {
@@ -336,6 +357,14 @@ async function exec_gh_api(request: GhApiRequest): Promise<string> {
336
357
  })
337
358
  }
338
359
 
360
+ async function exec_gh_api(request: GhApiRequest): Promise<string> {
361
+ refuse_credential_body(request)
362
+
363
+ if (request.should_retry === false) return await send_gh_api(request)
364
+
365
+ return await gh_retry.with_retry(async () => await send_gh_api(request))
366
+ }
367
+
339
368
  // The synchronous twin of `exec_gh_api`, for a caller that cannot await. `josh propagate` runs each
340
369
  // consumer's steps as a sequential chain of `execaSync` spawns with inherited stdio, and that shape
341
370
  // reaches from `open_issue` up through `RunStep`, `run_target` and `run_targets` — so the issue it
@@ -357,6 +386,7 @@ async function exec_gh_api(request: GhApiRequest): Promise<string> {
357
386
  // the spawn's own failure and is reported like any other, which is what the direct spawn this
358
387
  // replaced already did.
359
388
  function exec_gh_api_sync(request: GhApiRequest): string {
389
+ refuse_credential_body(request)
360
390
  const body_option = request.body === undefined ? {} : { input: request.body }
361
391
  const options = { ...body_option, ...to_spawn_options(request.timeout_ms, request.cwd) }
362
392
 
@@ -1,4 +1,5 @@
1
1
  import type { IssueReference } from '#scripts/issue/issue-reference'
2
+ import { gh_author_association } from './gh-author-association'
2
3
  import { git_gh_api_path } from './git-gh-api-path'
3
4
  import { git_gh_exec } from './git-gh-exec'
4
5
  import { gh_failure, type GhFailure } from './git-gh-failure'
@@ -284,8 +285,9 @@ async function issue_view_json(
284
285
  //
285
286
  // `body` rides along because `epic:next` holds a child until its declared start time
286
287
  // (joshuafolkken/kit#4007); the REST issue endpoint answers it in the same response, so it costs no
287
- // request.
288
- const STATE_AND_RELATIONS_FIELDS = 'number,state,labels,blockedBy,body'
288
+ // request. The author rides along for the same reason: `backlog:next` runs a child's body only when
289
+ // its author has write access (joshuafolkken/kit#4633), and the same response already names them.
290
+ const STATE_AND_RELATIONS_FIELDS = `number,state,labels,blockedBy,body,${gh_author_association.AUTHOR_FIELDS}`
289
291
 
290
292
  async function issue_get_state_and_relations(
291
293
  issue_number: string,
@@ -26,6 +26,7 @@ import { MERGED_STATE, to_gh_state } from './git-gh-rest-state'
26
26
  // readily as an issue, so it stays optional and tolerates an explicit null.
27
27
  const rest_issue_schema = z.looseObject({
28
28
  number: z.number(),
29
+ body: z.string().nullish(),
29
30
  issue_dependencies_summary: z.looseObject({ total_blocked_by: z.number().optional() }).nullish(),
30
31
  // Present only on a pull request, which this endpoint serves as readily as an issue.
31
32
  pull_request: z.looseObject({ merged_at: z.string().nullish() }).nullish(),
@@ -98,8 +98,12 @@ async function issue_comment(issue_number: string, body: string, repo?: string):
98
98
  // **after** the epic body already carries the record, so a refused comment costs that child's copy and
99
99
  // nothing else — an exception there would leave the caller unable to tell a landed insertion from one
100
100
  // that wrote nothing.
101
- async function issue_try_comment(issue_number: string, body: string): Promise<boolean> {
102
- return await did_write_succeed(async () => await issue_comment(issue_number, body))
101
+ async function issue_try_comment(
102
+ issue_number: string,
103
+ body: string,
104
+ repo?: string,
105
+ ): Promise<boolean> {
106
+ return await did_write_succeed(async () => await issue_comment(issue_number, body, repo))
103
107
  }
104
108
 
105
109
  // `gh issue close --comment` posted the comment and closed the issue in one call; REST splits them.
@@ -211,6 +215,8 @@ function issue_create_request(input: {
211
215
  body: input.body,
212
216
  }),
213
217
  jq_filter: HTML_URL_FILTER,
218
+ // A 502 can follow an issue GitHub already opened, and a retry would open a second one.
219
+ should_retry: false,
214
220
  }
215
221
  }
216
222
 
@@ -1,3 +1,4 @@
1
+ import { gh_author_association } from './gh-author-association'
1
2
  import { git_gh_issue_list, type IssueListOutcome } from './git-gh-issue-list'
2
3
  import { git_gh_issue_read } from './git-gh-issue-read'
3
4
  import { BLOCKED_BY_COUNT_FIELD } from './git-gh-issue-rest'
@@ -26,7 +27,8 @@ const BACKLOG_SCAN_FIELDS = `number,title,body,labels,${BLOCKED_BY_COUNT_FIELD}`
26
27
  // gets that from the epic listing, which by construction holds no closed epic.
27
28
  const NUMBER_TITLE_AND_LABELS_FIELDS = 'number,title,labels'
28
29
  // The fields every listing that is *ranked* asks for: `createdAt` to order by and `labels` to
29
- // exclude by. Shared by the next-issues display and the `auto-ok` pickup, which rank identically.
30
+ // exclude by. Shared by the next-issues display and the `auto-ok` pickup, which rank identically —
31
+ // each adds `body` for the causing-lane key.
30
32
  const SUMMARY_FIELDS = 'number,title,labels,createdAt'
31
33
  // The pickup's list, which is the display's plus the native blocker relation. Kept apart from
32
34
  // `SUMMARY_FIELDS` on purpose: a listing carries no `blockedBy`, so the field is answered from each
@@ -34,8 +36,9 @@ const SUMMARY_FIELDS = 'number,title,labels,createdAt'
34
36
  // behind the next-issues display too — where a refused one becomes a failure with no message at all,
35
37
  // since the listing swallows the error. `body` costs
36
38
  // no request — the REST listing row already carries it — and is what the backlog offer reads for
37
- // the paths each issue declares.
38
- const PICKUP_FIELDS = `${SUMMARY_FIELDS},blockedBy,body`
39
+ // the paths each issue declares. The author fields are the same row's too, and decide whether an
40
+ // unattended run may act on that body at all.
41
+ const PICKUP_FIELDS = `${SUMMARY_FIELDS},blockedBy,body,${gh_author_association.AUTHOR_FIELDS}`
39
42
 
40
43
  // Every listing below goes through the one REST invocation in `git-gh-issue-list.ts`. It kept the
41
44
  // `json_fields` / `limit` contract it had as a `gh issue list` wrapper, so these callers changed
@@ -62,9 +65,13 @@ const PICKUP_FIELDS = `${SUMMARY_FIELDS},blockedBy,body`
62
65
  const { issue_list } = git_gh_issue_list
63
66
 
64
67
  // The newest open issues, for the next-issues display at workflow completion. `createdAt`
65
- // rides along because the caller re-sorts explicitly rather than inheriting the listing's order.
68
+ // rides along because the caller re-sorts explicitly rather than inheriting the listing's order, and
69
+ // `body` because the ranking reads its causing-lane minutes — without it the display would order a
70
+ // priority differently from the pickup (joshuafolkken/kit#4859). It adds no listing request, as
71
+ // above; `backlog:plan`'s read now also hands the bodies to `issue_sample_prime.prime`, which reads
72
+ // the pull requests they cite.
66
73
  async function issue_list_recent(limit: number): Promise<IssueListOutcome> {
67
- return await issue_list({ json_fields: SUMMARY_FIELDS, limit })
74
+ return await issue_list({ json_fields: `${SUMMARY_FIELDS},body`, limit })
68
75
  }
69
76
 
70
77
  // Every open issue with its title and body. Used by `epic:bundle` to scan the backlog and by
@@ -1,7 +1,8 @@
1
1
  import { error_text } from '#scripts/lib/error-message'
2
2
  import { git_gh_api_path } from './git-gh-api-path'
3
3
  import { git_gh_exec } from './git-gh-exec'
4
- import { read_pull, require_pr_number } from './git-gh-pr-read'
4
+ import { GRAPHQL_PATH } from './git-gh-pr-graphql-state'
5
+ import { read_pull, read_pull_or_listed, require_pr_number } from './git-gh-pr-read'
5
6
  import { git_gh_pr_rest, type RestPull } from './git-gh-pr-rest'
6
7
 
7
8
  // Auto-merge for a pull request a josh command opens and would otherwise have to stay alive to land.
@@ -9,12 +10,12 @@ import { git_gh_pr_rest, type RestPull } from './git-gh-pr-rest'
9
10
  // inside its own wait, so a wait that ended early — a session cut, a killed process — left a green
10
11
  // pull request open with nobody to merge it.
11
12
  //
12
- // **This is the one GraphQL request in the pull-request layer, because REST has no equivalent.**
13
- // Enabling auto-merge is `enablePullRequestAutoMerge` and nothing else. A cloud session can be
13
+ // **This is a GraphQL request because REST has no equivalent** — the pull-request layer's only other
14
+ // one is `git-gh-pr-graphql-state.ts`. Enabling auto-merge is `enablePullRequestAutoMerge` and
15
+ // nothing else. A cloud session can be
14
16
  // answered 403 for GraphQL, so the caller treats a failure here as a lost
15
17
  // safety net rather than a failed command — the in-process wait still merges as it always did.
16
18
 
17
- const GRAPHQL_PATH = 'graphql'
18
19
  const OPEN_PULLS_QUERY = `${git_gh_api_path.FULL_PAGE_QUERY}&state=open`
19
20
  const MISSING_NODE_ID_MESSAGE = 'gh api answered a pull request without a node_id'
20
21
  // **`expectedHeadOid` binds the auto-merge to the commit the caller pushed** (#4036): GitHub then
@@ -28,8 +29,14 @@ interface OpenPull {
28
29
  has_auto_merge: boolean
29
30
  }
30
31
 
32
+ // The listing row stands in for a detail GitHub refuses as too many files changed: both carry
33
+ // `node_id` and `merged_at`, which is all the two readers below need (`git-gh-pr-too-large.ts`).
34
+ async function read_branch_pull(branch_name: string): Promise<RestPull> {
35
+ return await read_pull_or_listed(branch_name, await require_pr_number(branch_name), read_pull)
36
+ }
37
+
31
38
  async function pr_enable_auto_merge(branch_name: string, head_sha: string): Promise<void> {
32
- const pull = await read_pull(await require_pr_number(branch_name))
39
+ const pull = await read_branch_pull(branch_name)
33
40
  if (pull.node_id === undefined) throw new Error(MISSING_NODE_ID_MESSAGE)
34
41
 
35
42
  await git_gh_exec.exec_gh_api({
@@ -45,7 +52,7 @@ async function pr_enable_auto_merge(branch_name: string, head_sha: string): Prom
45
52
  // next attempt asks again, and running out of attempts is what ends the wait.
46
53
  async function pr_is_merged(branch_name: string): Promise<boolean> {
47
54
  try {
48
- return git_gh_pr_rest.is_merged(await read_pull(await require_pr_number(branch_name)))
55
+ return git_gh_pr_rest.is_merged(await read_branch_pull(branch_name))
49
56
  } catch (error) {
50
57
  error_text.trace_swallowed('git_gh_pr_auto_merge.pr_is_merged', error)
51
58
 
@@ -0,0 +1,56 @@
1
+ import { parse_json_object_or_undefined } from '#scripts/git/parse-json-array'
2
+ import { z } from 'zod'
3
+ import { git_gh_exec } from './git-gh-exec'
4
+ import type { RestPull } from './git-gh-pr-rest'
5
+
6
+ // `mergeStateStatus` for a pull request whose single-pull REST read GitHub refuses as too many files
7
+ // changed (`git-gh-pr-too-large.ts`). The listing row that stands in for that read carries no
8
+ // `mergeable_state`, and the merge gate never reads an unknown state as clean — it would wait out its
9
+ // whole budget. GraphQL still answers for the same pull request, so the state is read there.
10
+ //
11
+ // **A failure is a stop with its reason, never a guess.** A cloud session is answered 403 for
12
+ // GraphQL; the merge gate then has no way to judge the pull request, and says so.
13
+
14
+ const GRAPHQL_PATH = 'graphql'
15
+
16
+ const MERGE_STATE_QUERY =
17
+ 'query($id: ID!) { node(id: $id) { ... on PullRequest { mergeStateStatus } } }'
18
+
19
+ const NO_MERGE_STATE_MESSAGE =
20
+ 'The merge state cannot be judged: GitHub refuses this pull request as too many files changed, and GraphQL did not answer its mergeStateStatus'
21
+
22
+ const merge_state_node_schema = z.looseObject({ mergeStateStatus: z.string() })
23
+ const merge_state_data_schema = z.looseObject({ node: merge_state_node_schema })
24
+ const merge_state_response_schema = z.looseObject({ data: merge_state_data_schema })
25
+
26
+ async function query_merge_state(node_id: string): Promise<string | undefined> {
27
+ const json = await git_gh_exec.exec_gh_api({
28
+ path: GRAPHQL_PATH,
29
+ body: JSON.stringify({ query: MERGE_STATE_QUERY, variables: { id: node_id } }),
30
+ })
31
+
32
+ return parse_json_object_or_undefined(json, merge_state_response_schema)?.data.node
33
+ .mergeStateStatus
34
+ }
35
+
36
+ async function try_query_merge_state(node_id: string | undefined): Promise<string | undefined> {
37
+ if (node_id === undefined) return undefined
38
+
39
+ try {
40
+ return await query_merge_state(node_id)
41
+ } catch {
42
+ return undefined
43
+ }
44
+ }
45
+
46
+ // `detail_error` is the 422 that sent the read here, kept as the cause so the stop names it.
47
+ async function read_merge_state_status(listed: RestPull, detail_error: unknown): Promise<string> {
48
+ const state = await try_query_merge_state(listed.node_id)
49
+ if (state === undefined) throw new Error(NO_MERGE_STATE_MESSAGE, { cause: detail_error })
50
+
51
+ return state
52
+ }
53
+
54
+ const git_gh_pr_graphql_state = { read_merge_state_status }
55
+
56
+ export { git_gh_pr_graphql_state, GRAPHQL_PATH, MERGE_STATE_QUERY, NO_MERGE_STATE_MESSAGE }