@joshuafolkken/kit 1.1050.0 → 1.1094.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 (581) hide show
  1. package/.claude/settings.json +9 -8
  2. package/.claude/skills/epic-commands/SKILL.md +5 -7
  3. package/.claude/skills/workflow-commands/SKILL.md +19 -11
  4. package/.claude/skills/workflow-commands/background-commands.md +4 -3
  5. package/.claude/skills/workflow-commands/backlogrun-child.md +1 -1
  6. package/.claude/skills/workflow-commands/backlogrun-lanes.md +8 -6
  7. package/.claude/skills/workflow-commands/backlogrun-progress.md +1 -1
  8. package/.claude/skills/workflow-commands/backlogrun-steps.md +10 -10
  9. package/.claude/skills/workflow-commands/backlogrun.md +2 -2
  10. package/.claude/skills/workflow-commands/chain-rule.md +4 -2
  11. package/.claude/skills/workflow-commands/delegation.md +3 -3
  12. package/.claude/skills/workflow-commands/followup-reference.md +1 -1
  13. package/.claude/skills/workflow-commands/followup.md +7 -3
  14. package/.claude/skills/workflow-commands/fullrun-steps.md +3 -2
  15. package/.claude/skills/workflow-commands/fullrun.md +3 -2
  16. package/.claude/skills/workflow-commands/halfrun.md +16 -19
  17. package/.claude/skills/workflow-commands/issue-comments.md +1 -1
  18. package/.claude/skills/workflow-commands/issue-fold-existing.md +10 -10
  19. package/.claude/skills/workflow-commands/issue-scout.md +1 -1
  20. package/.claude/skills/workflow-commands/kickoff.md +9 -4
  21. package/.claude/skills/workflow-commands/latest-gate.md +1 -1
  22. package/.claude/skills/workflow-commands/needs-human-review.md +1 -1
  23. package/.claude/skills/workflow-commands/observation-filing.md +3 -3
  24. package/.claude/skills/workflow-commands/prerequisite.md +1 -1
  25. package/.claude/skills/workflow-commands/prrun.md +36 -0
  26. package/.claude/skills/workflow-commands/retrospective.md +1 -1
  27. package/.claude/skills/workflow-commands/working-tree-hold.md +22 -2
  28. package/.codex/hooks.json +16 -20
  29. package/.github/actions/setup-pnpm/action.yml +93 -0
  30. package/.github/dependabot.yml +5 -1
  31. package/.github/workflows/ci.yml +26 -128
  32. package/.github/workflows/pr-classification.yml +5 -41
  33. package/.github/workflows/publish.yml +33 -38
  34. package/.github/workflows/sonar-qube.yml +37 -4
  35. package/AGENTS.md +12 -2
  36. package/CLAUDE.md +15 -16
  37. package/GEMINI.md +14 -2
  38. package/README.md +59 -18
  39. package/SECURITY.md +36 -6
  40. package/cspell/index.yaml +2 -1
  41. package/dist/CLAUDE.md +15 -16
  42. package/dist/config-merge/index.js +15 -3
  43. package/dist/hooks/batch-guard.js +4 -4
  44. package/dist/hooks/{chunk-HJIISEAC.js → chunk-3C4YCCEF.js} +5 -13
  45. package/dist/hooks/{chunk-EJDX2TOB.js → chunk-7ZPFAVR7.js} +7 -88
  46. package/dist/hooks/{chunk-WQ4OSBSS.js → chunk-E54KGFEQ.js} +2 -2
  47. package/dist/hooks/{chunk-GQ7KP45M.js → chunk-IL27YTPH.js} +2 -2
  48. package/dist/hooks/{chunk-DMQN45FN.js → chunk-KHWHKJOM.js} +3 -3
  49. package/dist/hooks/{chunk-5BK3K7V4.js → chunk-M2XDCUKD.js} +997 -478
  50. package/dist/hooks/{chunk-7VPDUBRN.js → chunk-NKOG3XAV.js} +150 -153
  51. package/dist/hooks/{chunk-NJQOBE6L.js → chunk-O4LL4HTI.js} +2 -7
  52. package/dist/hooks/{chunk-NAS4C7GP.js → chunk-OIZUHPJI.js} +2 -2
  53. package/dist/hooks/{chunk-RLDX5SOC.js → chunk-UD24EAIL.js} +2084 -1412
  54. package/dist/hooks/codex-hook-adapter.js +10 -11
  55. package/dist/hooks/duplicate-read-guard.js +5 -5
  56. package/dist/hooks/format-edited.js +2 -2
  57. package/dist/hooks/inputs.json +279 -0
  58. package/dist/hooks/investigation-guard.js +5 -5
  59. package/dist/hooks/pretool-guard.js +9 -9
  60. package/dist/hooks/session-lang.js +0 -1
  61. package/dist/hooks/stop-guard.js +178 -324
  62. package/dist/josh.js +162 -119
  63. package/dist/managed-marker/index.js +2 -1
  64. package/dist/version/index.js +34 -58
  65. package/eslint/rules/promise.js +5 -0
  66. package/package.json +9 -4
  67. package/prompts/collaboration-workflow/issue-citation.md +5 -5
  68. package/prompts/collaboration-workflow/operating-rules.md +4 -4
  69. package/prompts/collaboration-workflow/overview.md +13 -1
  70. package/prompts/collaboration-workflow/report-format.md +1 -1
  71. package/prompts/collaboration-workflow/residency.md +3 -3
  72. package/prompts/collaboration-workflow/rule-delivery.md +1 -1
  73. package/prompts/collaboration-workflow/turn-batching.md +3 -3
  74. package/prompts/collaboration-workflow/upstream-interrupt.md +1 -1
  75. package/prompts/collaboration-workflow/wip-cap.md +25 -22
  76. package/prompts/collaboration-workflow.md +5 -8
  77. package/prompts/review-rubric.md +1 -1
  78. package/prompts/review.md +3 -3
  79. package/prompts/sonar-hotspot-handling.md +11 -3
  80. package/prompts/testing-guide.md +3 -3
  81. package/scripts/adopt/adopt-toolkits.ts +0 -2
  82. package/scripts/adopt/adopt.ts +0 -2
  83. package/scripts/agent/agent-argv.ts +0 -2
  84. package/scripts/agent/agent-diagnostics.ts +1 -1
  85. package/scripts/agent/agent-role-profile.ts +0 -7
  86. package/scripts/agent/claude-agent-argv.ts +0 -2
  87. package/scripts/agent/codex-agent-argv.ts +1 -1
  88. package/scripts/agent/codex-hooks.ts +92 -0
  89. package/scripts/agent/interactive-ask.ts +1 -1
  90. package/scripts/auto-ok/auto-ok-cli.ts +6 -16
  91. package/scripts/backlog/backlog-budget.ts +0 -2
  92. package/scripts/backlog/backlog-defect-priority.ts +2 -2
  93. package/scripts/backlog/backlog-drive-cli.ts +10 -8
  94. package/scripts/backlog/backlog-drive-named-offer.ts +16 -3
  95. package/scripts/backlog/backlog-drive-named.ts +2 -1
  96. package/scripts/backlog/backlog-drive.ts +76 -16
  97. package/scripts/backlog/backlog-named.ts +0 -3
  98. package/scripts/backlog/backlog-next.ts +9 -15
  99. package/scripts/backlog/backlog-offer-cli.ts +0 -5
  100. package/scripts/backlog/backlog-plan-cli.ts +1 -7
  101. package/scripts/backlog/backlog-plan.ts +1 -1
  102. package/scripts/backlog/backlog-pool.ts +3 -6
  103. package/scripts/backlog/backlog-rank.ts +2 -2
  104. package/scripts/backlog/backlog-ready.ts +19 -3
  105. package/scripts/backlog/backlog-scope.ts +1 -3
  106. package/scripts/backlog/backlog-stalled-detect.ts +2 -2
  107. package/scripts/backlog/backlog-stalled.ts +0 -1
  108. package/scripts/backlog/backlog-waves.ts +5 -2
  109. package/scripts/behavior/behavior-cli.ts +1 -1
  110. package/scripts/build/build-codex-hooks.ts +26 -0
  111. package/scripts/build/build-hooks.ts +85 -9
  112. package/scripts/build/hook-bundle-stamp.ts +111 -0
  113. package/scripts/cases/cases-cli.ts +1 -1
  114. package/scripts/cases/cases-logic.ts +1 -1
  115. package/scripts/ci/composite-actions.ts +30 -0
  116. package/scripts/ci/pr-classification.ts +3 -3
  117. package/scripts/claude/workflow-destination.ts +10 -1
  118. package/scripts/clone/clone-fingerprint.ts +0 -1
  119. package/scripts/clone/clone-scan-cli.ts +1 -1
  120. package/scripts/clone/clone-scan.ts +1 -1
  121. package/scripts/config-merge/json-format.ts +0 -1
  122. package/scripts/config-merge/patch-yaml-list.ts +1 -1
  123. package/scripts/cost-runtime/codex-usage.ts +2 -9
  124. package/scripts/cost-runtime/cost-attribute.ts +0 -1
  125. package/scripts/cost-runtime/cost-cli.ts +0 -3
  126. package/scripts/cost-runtime/cost-corpus.ts +0 -2
  127. package/scripts/cost-runtime/cost-format.ts +0 -3
  128. package/scripts/cost-runtime/cost-pricing.ts +0 -1
  129. package/scripts/cost-runtime/cost-tokens.ts +0 -1
  130. package/scripts/delegation/delegation-cli.ts +1 -1
  131. package/scripts/delegation/delegation-policy.ts +0 -1
  132. package/scripts/delegation/duplicate-read-guard.ts +0 -8
  133. package/scripts/delegation/fanout-cli.ts +1 -1
  134. package/scripts/delegation/fanout.ts +0 -2
  135. package/scripts/delegation/investigation-reads.ts +1 -164
  136. package/scripts/discovery/repo-map-logic.ts +0 -1
  137. package/scripts/discovery/repo-party-cli.ts +1 -1
  138. package/scripts/doctor/doctor-consumer.ts +4 -6
  139. package/scripts/doctor/doctor-logic.ts +0 -4
  140. package/scripts/doctor/doctor.ts +14 -9
  141. package/scripts/document/document-byte-budget.ts +4 -5
  142. package/scripts/document/document-byte-check.ts +0 -1
  143. package/scripts/document/document-read-cli.ts +0 -2
  144. package/scripts/document/document-section-cli.ts +1 -1
  145. package/scripts/document/document-section.ts +0 -3
  146. package/scripts/document/edit-files-cli.ts +0 -1
  147. package/scripts/document/entry-read-budget.ts +10 -2
  148. package/scripts/document/lane-child-read-set.ts +1 -6
  149. package/scripts/document/read-files-cli.ts +0 -4
  150. package/scripts/document/read-set-cli.ts +0 -2
  151. package/scripts/document/read-set-point-of-use.ts +1 -0
  152. package/scripts/document/read-set-pricing.ts +0 -1
  153. package/scripts/document/read-set-trim.ts +1 -1
  154. package/scripts/epic/epic-add.ts +1 -1
  155. package/scripts/epic/epic-audit-cli.ts +1 -4
  156. package/scripts/epic/epic-audit-orphans.ts +1 -3
  157. package/scripts/epic/epic-audit-rationale.ts +0 -1
  158. package/scripts/epic/epic-audit-report.ts +0 -2
  159. package/scripts/epic/epic-audit.ts +5 -4
  160. package/scripts/epic/epic-bundle-cli.ts +1 -1
  161. package/scripts/epic/epic-bundle-evidence.ts +0 -1
  162. package/scripts/epic/epic-bundle-referenced.ts +1 -5
  163. package/scripts/epic/epic-bundle.ts +0 -4
  164. package/scripts/epic/epic-busy.ts +4 -5
  165. package/scripts/epic/epic-candidate-confirm.ts +0 -5
  166. package/scripts/epic/epic-classify.ts +2 -2
  167. package/scripts/epic/epic-cli-argv.ts +0 -1
  168. package/scripts/epic/epic-close-comment.ts +1 -1
  169. package/scripts/epic/epic-close.ts +5 -2
  170. package/scripts/epic/epic-cross-repo.ts +2 -4
  171. package/scripts/epic/epic-decision.ts +0 -1
  172. package/scripts/epic/epic-fetch.ts +2 -2
  173. package/scripts/epic/epic-index.ts +2 -3
  174. package/scripts/epic/epic-issue.ts +1 -15
  175. package/scripts/epic/epic-lane-offer.ts +9 -8
  176. package/scripts/epic/epic-nested.ts +1 -1
  177. package/scripts/epic/epic-next-read.ts +1 -3
  178. package/scripts/epic/epic-next-views.ts +0 -1
  179. package/scripts/epic/epic-next.ts +1 -10
  180. package/scripts/epic/epic-parse.ts +0 -1
  181. package/scripts/epic/epic-promote.ts +0 -9
  182. package/scripts/epic/epic-rank.ts +2 -2
  183. package/scripts/epic/epic-read.ts +1 -2
  184. package/scripts/epic/epic-reconcile.ts +1 -1
  185. package/scripts/epic/epic-reference.ts +1 -13
  186. package/scripts/epic/epic-relation-recheck.ts +1 -1
  187. package/scripts/epic/epic-relations.ts +1 -1
  188. package/scripts/epic/epic-remove.ts +1 -1
  189. package/scripts/epic/epic-report.ts +0 -1
  190. package/scripts/epic/epic-run.ts +2 -3
  191. package/scripts/epic/epic-shape.ts +1 -1
  192. package/scripts/epic/epic-solo-stale.ts +107 -0
  193. package/scripts/epic/epic-solo.ts +3 -2
  194. package/scripts/epic/epic-triage.ts +1 -1
  195. package/scripts/epic/epic-validate.ts +1 -1
  196. package/scripts/epic/epic.ts +1 -1
  197. package/scripts/exports/unused-members-cli.ts +53 -0
  198. package/scripts/{git → followup}/followup-issue-number.ts +1 -6
  199. package/scripts/{git → followup}/git-followup-cleanup.ts +2 -1
  200. package/scripts/{git → followup}/git-followup-finish.ts +1 -3
  201. package/scripts/{git → followup}/git-followup-flush.ts +2 -2
  202. package/scripts/{git → followup}/git-followup-issue-close.ts +2 -2
  203. package/scripts/{git → followup}/git-followup-label.ts +4 -4
  204. package/scripts/followup/git-followup-merged.ts +112 -0
  205. package/scripts/{git → followup}/git-followup-pending.ts +1 -1
  206. package/scripts/{git → followup}/git-followup-workflow.ts +19 -11
  207. package/scripts/{git → followup}/git-pr-followup-wrapup.ts +9 -3
  208. package/scripts/{git → followup}/git-pr-followup.ts +53 -16
  209. package/scripts/gate/core-budget.ts +3 -9
  210. package/scripts/gate/gate-plan.ts +7 -4
  211. package/scripts/gate/gate-report.ts +0 -6
  212. package/scripts/gate/gate-tree.ts +1 -1
  213. package/scripts/gate/pre-commit-type-check.ts +0 -6
  214. package/scripts/gate/project-checks.ts +7 -8
  215. package/scripts/gate/scoped-green.ts +0 -1
  216. package/scripts/gate/type-check-step.ts +1 -1
  217. package/scripts/gate/verification-gate.ts +0 -2
  218. package/scripts/gh/fix-gh-packages.ts +15 -12
  219. package/scripts/gh/gh-spawn.ts +2 -2
  220. package/scripts/{git → gh}/git-ai-review-scan.ts +1 -5
  221. package/scripts/{git → gh}/git-gh-check.ts +2 -1
  222. package/scripts/{git → gh}/git-gh-exec.ts +1 -1
  223. package/scripts/{git → gh}/git-gh-failure.ts +1 -1
  224. package/scripts/{git → gh}/git-gh-helpers.ts +0 -1
  225. package/scripts/{git → gh}/git-gh-issue-list.ts +2 -0
  226. package/scripts/{git → gh}/git-gh-issue-read.ts +1 -1
  227. package/scripts/{git → gh}/git-gh-issue-rest.ts +6 -3
  228. package/scripts/{git → gh}/git-gh-pr-read.ts +24 -0
  229. package/scripts/{git → gh}/git-gh-pr-rest.ts +5 -2
  230. package/scripts/{git → gh}/git-gh-pr-review.ts +2 -2
  231. package/scripts/{git → gh}/git-gh-pr-rollup.ts +1 -3
  232. package/scripts/{git → gh}/git-gh-pr.ts +3 -1
  233. package/scripts/{git → gh}/git-pr-ai-review.ts +2 -5
  234. package/scripts/{git → gh}/git-pr-checks-eval.ts +0 -10
  235. package/scripts/{git → gh}/git-pr-checks-parse.ts +4 -20
  236. package/scripts/{git → gh}/git-pr-checks.ts +2 -1
  237. package/scripts/{git → gh}/git-pr-coderabbit.ts +2 -5
  238. package/scripts/{git → gh}/git-pr-confirmation.ts +1 -3
  239. package/scripts/{git → gh}/git-pr-managed-config.ts +2 -3
  240. package/scripts/{git → gh}/git-pr.ts +3 -3
  241. package/scripts/git/changed-file-scope.ts +0 -1
  242. package/scripts/git/git-branch.ts +3 -6
  243. package/scripts/git/git-commit.ts +1 -1
  244. package/scripts/git/git-common-directory.ts +80 -24
  245. package/scripts/git/git-error.ts +66 -9
  246. package/scripts/git/git-issue.ts +1 -1
  247. package/scripts/git/git-preflight.ts +2 -2
  248. package/scripts/git/git-prompt.ts +6 -31
  249. package/scripts/git/git-push.ts +1 -1
  250. package/scripts/git/git-staging.ts +1 -0
  251. package/scripts/git/git-status.ts +1 -1
  252. package/scripts/git/git-workflow.ts +1 -1
  253. package/scripts/git/gone-branch.ts +1 -0
  254. package/scripts/git/listing-cutoff.ts +1 -1
  255. package/scripts/git/main-merge.ts +1 -1
  256. package/scripts/git/main-sync.ts +19 -1
  257. package/scripts/git/parse-json-array.ts +0 -3
  258. package/scripts/git/repository-lock.ts +16 -16
  259. package/scripts/git/{git-stash.ts → stash/git-stash.ts} +1 -1
  260. package/scripts/git/{stash-pop-args.ts → stash/stash-pop-args.ts} +1 -1
  261. package/scripts/git/{stash-pop-cli.ts → stash/stash-pop-cli.ts} +0 -1
  262. package/scripts/git/{stash-sweep-lock.ts → stash/stash-sweep-lock.ts} +3 -3
  263. package/scripts/hooks/codex-hook-adapter.ts +0 -1
  264. package/scripts/hooks/edited-cspell.ts +1 -1
  265. package/scripts/hooks/format-edited-file.ts +2 -0
  266. package/scripts/hooks/pre-push-unit.ts +0 -4
  267. package/scripts/hooks/pretool-guard.ts +22 -4
  268. package/scripts/hooks/reserved-run.ts +1 -1
  269. package/scripts/hooks/step-zero-notice.ts +76 -0
  270. package/scripts/hooks/stop-guard.ts +47 -21
  271. package/scripts/init/claude-plugin-config.ts +4 -5
  272. package/scripts/init/hook-command-rewrite.ts +16 -8
  273. package/scripts/init/hook-launch.ts +41 -15
  274. package/scripts/init/init-basic.ts +2 -5
  275. package/scripts/init/init-logic.ts +7 -0
  276. package/scripts/init/init.ts +0 -3
  277. package/scripts/init/project-profile.ts +6 -11
  278. package/scripts/init/start-exec.ts +1 -1
  279. package/scripts/init/start-setup-pr.ts +6 -6
  280. package/scripts/init/start-steps.ts +1 -0
  281. package/scripts/issue/behavior-change-lint.ts +0 -1
  282. package/scripts/issue/defect-rate-cli.ts +3 -3
  283. package/scripts/issue/defect-rate.ts +1 -2
  284. package/scripts/{git → issue}/git-next-issues.ts +3 -3
  285. package/scripts/issue/issue-backlinks-cli.ts +1 -5
  286. package/scripts/issue/issue-cite-cli.ts +2 -6
  287. package/scripts/issue/issue-cite.ts +0 -2
  288. package/scripts/issue/issue-classification.ts +1 -9
  289. package/scripts/issue/issue-closing-pr.ts +4 -4
  290. package/scripts/issue/issue-comment-cli.ts +2 -2
  291. package/scripts/issue/issue-file-cli.ts +5 -5
  292. package/scripts/issue/issue-file.ts +2 -2
  293. package/scripts/issue/issue-fold-cli.ts +1 -1
  294. package/scripts/issue/issue-fold-existing-cli.ts +1 -1
  295. package/scripts/{git → issue}/issue-labels.ts +8 -0
  296. package/scripts/issue/issue-lint-cli.ts +1 -1
  297. package/scripts/issue/issue-merged.ts +2 -2
  298. package/scripts/{git → issue}/issue-rank.ts +1 -1
  299. package/scripts/issue/issue-read-cli.ts +8 -47
  300. package/scripts/issue/issue-read.ts +0 -2
  301. package/scripts/issue/issue-report-failures.ts +80 -0
  302. package/scripts/issue/issue-scout-cli.ts +1 -7
  303. package/scripts/issue/issue-scout-closed.ts +2 -2
  304. package/scripts/issue/issue-scout.ts +0 -2
  305. package/scripts/issue/issue-state-cli.ts +5 -46
  306. package/scripts/issue/issue-state.ts +1 -5
  307. package/scripts/issue/markdown-section.ts +1 -1
  308. package/scripts/issue/measure-rerun-cli.ts +1 -1
  309. package/scripts/issue/reproduction-measure.ts +1 -1
  310. package/scripts/josh/cli-body.ts +1 -1
  311. package/scripts/josh/file-map-stamp.ts +0 -3
  312. package/scripts/josh/josh-command-map.ts +2 -0
  313. package/scripts/josh/josh-commands-ai.ts +9 -102
  314. package/scripts/josh/josh-commands-backlog.ts +5 -1
  315. package/scripts/josh/josh-commands-development.ts +8 -1
  316. package/scripts/josh/josh-commands-issue.ts +2 -2
  317. package/scripts/josh/josh-commands-maintenance.ts +7 -0
  318. package/scripts/josh/josh-commands-project.ts +6 -0
  319. package/scripts/josh/josh-commands-run.ts +114 -0
  320. package/scripts/josh/josh-commands-versioning.ts +8 -0
  321. package/scripts/josh/josh-commands-workflow.ts +2 -2
  322. package/scripts/josh/path-decision.ts +0 -3
  323. package/scripts/josh/process-owner.ts +16 -0
  324. package/scripts/josh/session-language-cli.ts +0 -1
  325. package/scripts/lane/lane-await.ts +3 -6
  326. package/scripts/lane/lane-capacity.ts +6 -3
  327. package/scripts/lane/lane-child-invocation.ts +20 -7
  328. package/scripts/lane/lane-cli.ts +1 -4
  329. package/scripts/lane/lane-close.ts +1 -3
  330. package/scripts/lane/lane-dispatch.ts +3 -4
  331. package/scripts/lane/lane-environment.ts +0 -9
  332. package/scripts/lane/lane-handoff.ts +38 -0
  333. package/scripts/lane/lane-launch-cli.ts +21 -11
  334. package/scripts/lane/lane-open.ts +0 -3
  335. package/scripts/lane/lane-output.ts +0 -1
  336. package/scripts/lane/lane-registry.ts +9 -0
  337. package/scripts/lane/openai-lane-ship.ts +2 -0
  338. package/scripts/lane/openai-lane-supervisor-decision.ts +2 -1
  339. package/scripts/lane/openai-lane-supervisor.ts +6 -4
  340. package/scripts/lane/openai-review-broker.ts +3 -0
  341. package/scripts/lib/bounded-pool.ts +1 -0
  342. package/scripts/lib/json-value.ts +5 -4
  343. package/scripts/lib/poll.ts +3 -1
  344. package/scripts/lib/timed-fetch.ts +15 -0
  345. package/scripts/lib/timeouts.ts +13 -0
  346. package/scripts/{yaml → lib}/yaml-document.ts +3 -1
  347. package/scripts/{bytes → lines}/bytes-command.ts +0 -2
  348. package/scripts/lines/lines-command.ts +0 -1
  349. package/scripts/lint/lint-related-scope.ts +0 -1
  350. package/scripts/lint/lint-related.ts +1 -1
  351. package/scripts/{git → notify}/telegram-notify.ts +2 -2
  352. package/scripts/{git → notify}/telegram-test.ts +4 -4
  353. package/scripts/observations/observation-ledger-home.ts +0 -1
  354. package/scripts/observations/observation-ledger-line.ts +0 -1
  355. package/scripts/observations/observation-ledger-migrate.ts +1 -1
  356. package/scripts/observations/observations-flush-landing.ts +3 -3
  357. package/scripts/observations/observations-flush.ts +2 -2
  358. package/scripts/overrides/lockfile-overrides.ts +1 -1
  359. package/scripts/overrides/overrides-logic.ts +1 -1
  360. package/scripts/package/package-scout-cli.ts +2 -7
  361. package/scripts/package/package-scout.ts +0 -2
  362. package/scripts/propagate/propagate-git-failure.ts +0 -1
  363. package/scripts/propagate/propagate-git.ts +0 -2
  364. package/scripts/propagate/propagate-publish.ts +2 -3
  365. package/scripts/propagate/propagate-run.ts +0 -2
  366. package/scripts/propagate/propagate-steps.ts +3 -5
  367. package/scripts/propagate/propagate-targets.ts +0 -4
  368. package/scripts/propagate/propagate.ts +0 -4
  369. package/scripts/refactor/import-graph.ts +0 -1
  370. package/scripts/refactor/refactor-lint.ts +0 -2
  371. package/scripts/refactor/refactor-scan.ts +0 -1
  372. package/scripts/refactor/refactor-targets.ts +0 -1
  373. package/scripts/registry-migration/migrate-logic.ts +0 -2
  374. package/scripts/registry-migration/migrate.ts +19 -9
  375. package/scripts/release/github-release-cli.ts +8 -6
  376. package/scripts/release/github-release-environment.ts +46 -0
  377. package/scripts/release/github-release.ts +151 -94
  378. package/scripts/release/release-history.ts +0 -1
  379. package/scripts/release/release-plan.ts +0 -1
  380. package/scripts/release/release-publish.ts +2 -3
  381. package/scripts/release/release-scope-cli.ts +1 -2
  382. package/scripts/release/release-tag.ts +2 -4
  383. package/scripts/repo/auto-merge-setting-logic.ts +1 -4
  384. package/scripts/repo/repo-setting.ts +1 -1
  385. package/scripts/repo/repository-labels.ts +3 -3
  386. package/scripts/repo/required-checks-logic.ts +206 -0
  387. package/scripts/repo/required-checks-report.ts +71 -0
  388. package/scripts/repo/ruleset-check-cli.ts +53 -0
  389. package/scripts/repo/ruleset-check.ts +147 -0
  390. package/scripts/report/report-lint-cli.ts +0 -4
  391. package/scripts/review/disposition-cli.ts +1 -1
  392. package/scripts/review/live-evidence.ts +1 -1
  393. package/scripts/review/review-attest-cli.ts +0 -6
  394. package/scripts/review/review-attest.ts +4 -16
  395. package/scripts/review/review-brief-cli.ts +23 -6
  396. package/scripts/review/review-brief.ts +21 -8
  397. package/scripts/review/review-diff-parts.ts +89 -0
  398. package/scripts/review/review-diff-write.ts +97 -0
  399. package/scripts/review/review-finding-ledger.ts +0 -1
  400. package/scripts/review/review-record-cli.ts +1 -1
  401. package/scripts/review/review-record.ts +0 -1
  402. package/scripts/review/review-round2-cli.ts +1 -1
  403. package/scripts/review/review-stamps.ts +0 -3
  404. package/scripts/review/review-tree.ts +14 -2
  405. package/scripts/rules/decision-oracle-stage.ts +18 -0
  406. package/scripts/rules/decision-oracle.ts +10 -7
  407. package/scripts/rules/delivered-rules.ts +9 -1
  408. package/scripts/rules/destructive-command.ts +119 -0
  409. package/scripts/rules/direct-filing.ts +1 -1
  410. package/scripts/rules/file-body.ts +0 -3
  411. package/scripts/rules/filing-cap.ts +0 -2
  412. package/scripts/rules/gh-api.ts +7 -2
  413. package/scripts/rules/git-argv.ts +18 -7
  414. package/scripts/rules/git-force.ts +0 -2
  415. package/scripts/rules/implementation-cut.ts +0 -1
  416. package/scripts/rules/index-guard.ts +71 -0
  417. package/scripts/rules/issue-citation.ts +50 -25
  418. package/scripts/rules/lane-background.ts +15 -7
  419. package/scripts/rules/lane-park.ts +13 -6
  420. package/scripts/rules/last-prompt.ts +1 -0
  421. package/scripts/rules/oracle-consulted.ts +1 -1
  422. package/scripts/rules/oracle-firing.ts +1 -0
  423. package/scripts/rules/oracle-list-cli.ts +0 -3
  424. package/scripts/rules/permission-guards.ts +14 -0
  425. package/scripts/rules/protected-files.ts +74 -0
  426. package/scripts/rules/reply-language.ts +1 -1
  427. package/scripts/rules/rule-body-guard.ts +0 -3
  428. package/scripts/rules/rule-value-cli.ts +0 -1
  429. package/scripts/rules/shell-body-trigger.ts +0 -1
  430. package/scripts/rules/shell-segments.ts +0 -1
  431. package/scripts/rules/stop-rules.ts +13 -5
  432. package/scripts/rules/tail-commands.ts +1 -1
  433. package/scripts/rules/test-declared-commit.ts +1 -1
  434. package/scripts/rules/third-party-write.ts +0 -1
  435. package/scripts/rules/worktree-guard.ts +26 -9
  436. package/scripts/run/run-carry-cli.ts +0 -2
  437. package/scripts/run/run-carry-stash.ts +2 -2
  438. package/scripts/run/run-carry-streak.ts +1 -1
  439. package/scripts/run/run-cut-cli.ts +0 -7
  440. package/scripts/run/run-cut.ts +8 -54
  441. package/scripts/run/run-ending-cli.ts +1 -1
  442. package/scripts/run/run-ending.ts +1 -4
  443. package/scripts/run/run-entry-cli.ts +101 -24
  444. package/scripts/run/run-entry.ts +0 -1
  445. package/scripts/run/run-event-cli.ts +0 -2
  446. package/scripts/run/run-event-follow.ts +1 -0
  447. package/scripts/run/run-event-render.ts +1 -1
  448. package/scripts/run/run-event-scope.ts +53 -4
  449. package/scripts/run/run-event-stream.ts +0 -3
  450. package/scripts/run/run-event-watch.ts +1 -0
  451. package/scripts/run/run-halfrun-resume.ts +20 -7
  452. package/scripts/run/run-headless.ts +2 -2
  453. package/scripts/run/run-hold-cli.ts +33 -10
  454. package/scripts/run/run-hold.ts +25 -5
  455. package/scripts/run/run-issue-number.ts +1 -1
  456. package/scripts/run/run-liveness-cli.ts +1 -1
  457. package/scripts/run/run-liveness.ts +2 -3
  458. package/scripts/run/run-merge-cli.ts +5 -13
  459. package/scripts/run/run-merge-steps.ts +5 -5
  460. package/scripts/run/run-merge.ts +1 -1
  461. package/scripts/run/run-next-cli.ts +1 -1
  462. package/scripts/run/run-parent-cut-hook.ts +0 -1
  463. package/scripts/run/run-preflight.ts +2 -9
  464. package/scripts/run/run-prep-cli.ts +2 -2
  465. package/scripts/run/run-prep-locate.ts +1 -1
  466. package/scripts/run/run-progress-cli.ts +4 -7
  467. package/scripts/run/run-progress-clock.ts +6 -34
  468. package/scripts/run/run-progress-config.ts +0 -4
  469. package/scripts/run/run-progress-read.ts +1 -2
  470. package/scripts/run/run-progress.ts +1 -2
  471. package/scripts/run/run-prrun-resume.ts +117 -0
  472. package/scripts/run/run-report-cli.ts +1 -2
  473. package/scripts/run/run-report.ts +0 -1
  474. package/scripts/run/run-retrospective.ts +1 -1
  475. package/scripts/run/run-review-cli.ts +0 -3
  476. package/scripts/run/run-review-steps.ts +2 -0
  477. package/scripts/run/run-review.ts +0 -2
  478. package/scripts/run/run-ship-cli.ts +21 -3
  479. package/scripts/run/run-ship-detach.ts +1 -0
  480. package/scripts/run/run-ship-next.ts +106 -0
  481. package/scripts/run/run-ship-preflight.ts +1 -1
  482. package/scripts/run/run-ship-return.ts +8 -3
  483. package/scripts/run/run-ship-review-steps.ts +18 -4
  484. package/scripts/run/run-ship-review.ts +11 -0
  485. package/scripts/run/run-ship-scoped.ts +1 -0
  486. package/scripts/run/run-ship-steps.ts +1 -1
  487. package/scripts/run/run-ship.ts +0 -1
  488. package/scripts/run/run-stage-read.ts +62 -0
  489. package/scripts/run/run-stage.ts +160 -0
  490. package/scripts/run/run-status-cli.ts +1 -1
  491. package/scripts/run/run-step-cli.ts +21 -14
  492. package/scripts/run/run-step.ts +1 -1
  493. package/scripts/run/run-stop-notify.ts +1 -3
  494. package/scripts/run/run-stranded-cli.ts +0 -4
  495. package/scripts/run/run-stranded-detect.ts +2 -2
  496. package/scripts/run/run-tail-cli.ts +17 -11
  497. package/scripts/run/run-tail.ts +2 -0
  498. package/scripts/run/run-tidy-lanes.ts +2 -1
  499. package/scripts/run/run-tidy-stashes.ts +12 -12
  500. package/scripts/run/run-wake-cli.ts +2 -3
  501. package/scripts/run/run-wake-loop.ts +2 -2
  502. package/scripts/run/run-wake.ts +2 -4
  503. package/scripts/run/run-watcher-guard-cli.ts +0 -4
  504. package/scripts/run/run-watcher-guard.ts +9 -7
  505. package/scripts/run/run-watcher-hook.ts +1 -1
  506. package/scripts/safe-chain/ci-installer-pin.ts +11 -5
  507. package/scripts/safe-chain/project-config.ts +1 -1
  508. package/scripts/security/security-audit-provision-logic.ts +0 -1
  509. package/scripts/security/security-audit-provision.ts +3 -2
  510. package/scripts/security/security-audit.ts +0 -1
  511. package/scripts/security/security-updates-logic.ts +0 -1
  512. package/scripts/sonar/sonar-hotspots-cli.ts +10 -52
  513. package/scripts/sonar/sonar-hotspots.ts +0 -1
  514. package/scripts/sonar/sonar-new-code-cli.ts +150 -0
  515. package/scripts/sonar/sonar-new-code.ts +79 -0
  516. package/scripts/sonar/sonar-project.ts +97 -0
  517. package/scripts/split/split-assess-cli.ts +1 -1
  518. package/scripts/split/split-assess.ts +2 -5
  519. package/scripts/sync/managed-config-scope-cli.ts +1 -1
  520. package/scripts/sync/skill-migration.ts +0 -1
  521. package/scripts/sync/sync-hook-safety.ts +2 -3
  522. package/scripts/sync/sync.ts +1 -8
  523. package/scripts/sync/template-source-logic.ts +0 -1
  524. package/scripts/sync/workflow-pin-logic.ts +16 -28
  525. package/scripts/test/test-declared-logic.ts +0 -1
  526. package/scripts/test/test-declared.ts +0 -2
  527. package/scripts/test/test-red-commit.ts +2 -2
  528. package/scripts/test/test-red.ts +14 -7
  529. package/scripts/test/test-type-logic.ts +1 -1
  530. package/scripts/test/unit-worker-share.ts +7 -16
  531. package/scripts/time-runtime/time-batch-guard.ts +1 -2
  532. package/scripts/time-runtime/time-bundle-call.ts +0 -1
  533. package/scripts/time-runtime/time-bundles.ts +0 -4
  534. package/scripts/time-runtime/time-density-hook.ts +0 -2
  535. package/scripts/time-runtime/time-followup-stage.ts +1 -1
  536. package/scripts/time-runtime/time-format.ts +0 -73
  537. package/scripts/time-runtime/time-round-trips.ts +0 -4
  538. package/scripts/time-runtime/time-single-check.ts +1 -1
  539. package/scripts/time-runtime/time-spans.ts +1 -1
  540. package/scripts/time-runtime/time-transcript-line.ts +1 -2
  541. package/scripts/ui/ui-routes-cli.ts +0 -5
  542. package/scripts/ui/ui-routes.ts +0 -5
  543. package/scripts/version/effective-upstream.ts +2 -2
  544. package/scripts/version/latest-corepack.ts +7 -9
  545. package/scripts/version/latest-scope-cli.ts +0 -2
  546. package/scripts/version/latest-update.ts +0 -2
  547. package/scripts/version/npm-registry.ts +2 -2
  548. package/scripts/version/publishable-range-check.ts +1 -1
  549. package/scripts/version/release-hold.ts +0 -4
  550. package/scripts/version/running-binary.ts +2 -2
  551. package/scripts/version/version-check-logic.ts +0 -2
  552. package/scripts/version/version-remote.ts +3 -3
  553. package/scripts/version/version-targets.ts +4 -4
  554. package/templates/sonar-project.properties +28 -1
  555. package/templates/workflows/dependabot-auto-merge.yml +5 -3
  556. package/templates/workflows/github-release.yml +81 -0
  557. package/prompts/collaboration-workflow/cross-repo-epic.md +0 -5
  558. package/prompts/collaboration-workflow/epic-audit.md +0 -5
  559. package/prompts/collaboration-workflow/epic-bundle.md +0 -5
  560. package/scripts/init/plugin-install-hint.ts +0 -47
  561. package/scripts/version/parse-json.ts +0 -13
  562. /package/scripts/{git → followup}/git-followup-stages.ts +0 -0
  563. /package/scripts/{git → gh}/git-gh-api-path.ts +0 -0
  564. /package/scripts/{git → gh}/git-gh-command.ts +0 -0
  565. /package/scripts/{git → gh}/git-gh-issue-write.ts +0 -0
  566. /package/scripts/{git → gh}/git-gh-issue.ts +0 -0
  567. /package/scripts/{git → gh}/git-gh-pr-auto-merge.ts +0 -0
  568. /package/scripts/{git → gh}/git-gh-pr-snapshot.ts +0 -0
  569. /package/scripts/{git → gh}/git-gh-reachability.ts +0 -0
  570. /package/scripts/{git → gh}/git-gh-repo.ts +0 -0
  571. /package/scripts/{git → gh}/git-gh-rest-state.ts +0 -0
  572. /package/scripts/{git → gh}/git-pr-checks-watch.ts +0 -0
  573. /package/scripts/{git → gh}/git-pr-error.ts +0 -0
  574. /package/scripts/{git → gh}/git-pr-messages.ts +0 -0
  575. /package/scripts/{git → gh}/github-issue-url.ts +0 -0
  576. /package/scripts/git/{stash-orphans.ts → stash/stash-orphans.ts} +0 -0
  577. /package/scripts/{git → issue}/issue-reference.ts +0 -0
  578. /package/scripts/{git → lib}/animation-helpers.ts +0 -0
  579. /package/scripts/{git → lib}/git-animation.ts +0 -0
  580. /package/scripts/{git → notify}/git-notify.ts +0 -0
  581. /package/scripts/{git → notify}/telegram-test-logic.ts +0 -0
@@ -2,6 +2,7 @@ import { existsSync, globSync, readFileSync } from 'node:fs'
2
2
  import path from 'node:path'
3
3
  import { find_local_bin_upwards } from '#scripts/build/local-bin'
4
4
  import { project_profile } from '#scripts/init/project-profile'
5
+ import { json_value } from '#scripts/lib/json-value'
5
6
  import { SKIP_MARKER } from '#scripts/test/skip-marker'
6
7
  import { z } from 'zod'
7
8
 
@@ -70,23 +71,23 @@ function has_bin(directory: string, bin_name: string): boolean {
70
71
  }
71
72
 
72
73
  function josh_settings(manifest: unknown): unknown {
73
- if (typeof manifest !== 'object' || manifest === null || !('josh' in manifest)) return undefined
74
-
75
- return manifest.josh
74
+ return json_value.is_record(manifest) ? manifest['josh'] : undefined
76
75
  }
77
76
 
78
77
  function is_basic_manifest(manifest: unknown): boolean {
79
78
  const josh = josh_settings(manifest)
80
- if (typeof josh !== 'object' || josh === null || !('profile' in josh)) return false
79
+ if (!json_value.is_record(josh)) return false
81
80
 
82
- return project_profile.parse_profile(josh.profile) === 'basic'
81
+ return project_profile.parse_profile(josh['profile']) === 'basic'
83
82
  }
84
83
 
84
+ // The try covers the read alone — a missing or unreadable manifest — since the parse already answers
85
+ // `undefined` for text that is not JSON.
85
86
  function read_manifest(directory: string): unknown {
86
87
  try {
87
88
  const manifest_path = path.join(project_root(directory), PACKAGE_JSON)
88
89
 
89
- return JSON.parse(readFileSync(manifest_path, 'utf8'))
90
+ return json_value.parse_or_undefined(readFileSync(manifest_path, 'utf8'))
90
91
  } catch {
91
92
  return undefined
92
93
  }
@@ -158,8 +159,6 @@ function eslint_skip_reason(directory: string): string | undefined {
158
159
  const project_checks = {
159
160
  CSPELL_CONFIGS,
160
161
  ESLINT_CONFIGS,
161
- SCRIPT_FILES,
162
- TYPE_CONFIGS,
163
162
  TYPE_FILES,
164
163
  WEB_FILES,
165
164
  eslint_skip_reason,
@@ -252,7 +252,6 @@ const scoped_green = {
252
252
  read_before,
253
253
  record_green,
254
254
  record_if_green,
255
- refusal,
256
255
  refusal_for,
257
256
  }
258
257
 
@@ -74,6 +74,7 @@ async function resolve_toolkit_step(
74
74
  // The command the gate spawns through `pnpm`, so a toolkit step resolves the same shim `pnpm` would.
75
75
  async function resolve_type_check_args(start_directory: string): Promise<ReadonlyArray<string>> {
76
76
  for (const bin_name of TOOLKIT_BINS) {
77
+ // eslint-disable-next-line no-await-in-loop -- the first toolkit bin that resolves wins
77
78
  const step = await resolve_toolkit_step(start_directory, bin_name)
78
79
  if (step !== undefined) return step
79
80
  }
@@ -83,7 +84,6 @@ async function resolve_type_check_args(start_directory: string): Promise<Readonl
83
84
 
84
85
  const type_check_step = {
85
86
  parse_usage_commands,
86
- resolve_toolkit_step,
87
87
  resolve_type_check_args,
88
88
  }
89
89
 
@@ -488,10 +488,8 @@ const verification_gate = {
488
488
  mark_gate_running,
489
489
  record_green_gate,
490
490
  run_gate_steps,
491
- run_marked_gate,
492
491
  scoped_precheck_refusal,
493
492
  with_gate_marker,
494
- run_checked_gate,
495
493
  run_gate_command,
496
494
  run_gate_step,
497
495
  run_verification_gate,
@@ -1,7 +1,9 @@
1
1
  import { existsSync, readFileSync, realpathSync, writeFileSync } from 'node:fs'
2
2
  import path from 'node:path'
3
3
  import { fileURLToPath } from 'node:url'
4
+ import { bounded_pool } from '#scripts/lib/bounded-pool'
4
5
  import { file_reader } from '#scripts/lib/read-file'
6
+ import { timed_fetch } from '#scripts/lib/timed-fetch'
5
7
  import { z } from 'zod'
6
8
  import { fix_gh_packages_logic, type LockfilePackage } from './fix-gh-packages-logic'
7
9
  import { gh_cli_token } from './gh-cli-token'
@@ -9,7 +11,8 @@ import { gh_cli_token } from './gh-cli-token'
9
11
  const LOCKFILE = 'pnpm-lock.yaml'
10
12
  const NPMRC = '.npmrc'
11
13
  const GH_PACKAGES_HOST = 'npm.pkg.github.com'
12
- const FETCH_TIMEOUT_MS = 10_000
14
+ // The packument reads are independent; the width keeps a large lockfile from bursting the registry.
15
+ const FETCH_CONCURRENCY = 8
13
16
 
14
17
  const npm_distribution_schema = z.looseObject({ tarball: z.string().optional() })
15
18
  const npm_version_schema = z.looseObject({ dist: npm_distribution_schema.optional() })
@@ -42,10 +45,7 @@ async function fetch_tarball_url(
42
45
  token: string,
43
46
  ): Promise<string | undefined> {
44
47
  const url = `https://${GH_PACKAGES_HOST}/${package_path}`
45
- const response = await fetch(url, {
46
- headers: { Authorization: `Bearer ${token}` },
47
- signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
48
- })
48
+ const response = await timed_fetch(url, { headers: { Authorization: `Bearer ${token}` } })
49
49
 
50
50
  if (!response.ok) {
51
51
  console.warn(`fix-gh-packages: fetch failed for ${package_path} (${String(response.status)})`)
@@ -79,14 +79,13 @@ async function collect_fixes(
79
79
  scopes: Set<string>,
80
80
  token: string,
81
81
  ): Promise<Map<string, string>> {
82
- const fixes = new Map<string, string>()
83
-
84
- for (const [key, entry] of Object.entries(packages)) {
85
- const pair = await process_package_entry(key, entry, scopes, token)
86
- if (pair !== undefined) fixes.set(pair[0], pair[1])
87
- }
82
+ const pairs = await bounded_pool.bounded_map(
83
+ Object.entries(packages),
84
+ FETCH_CONCURRENCY,
85
+ async ([key, entry]) => await process_package_entry(key, entry, scopes, token),
86
+ )
88
87
 
89
- return fixes
88
+ return new Map(pairs.filter((pair) => pair !== undefined))
90
89
  }
91
90
 
92
91
  async function apply_fixes(cwd: string, scopes: Set<string>, token: string): Promise<void> {
@@ -128,3 +127,7 @@ async function main(): Promise<void> {
128
127
 
129
128
  const [, argv1] = process.argv
130
129
  if (argv1 !== undefined && realpathSync(argv1) === fileURLToPath(import.meta.url)) await main()
130
+
131
+ const fix_gh_packages = { collect_fixes }
132
+
133
+ export { fix_gh_packages }
@@ -1,6 +1,6 @@
1
- import { git_gh_api_path } from '#scripts/git/git-gh-api-path'
2
- import { git_gh_exec } from '#scripts/git/git-gh-exec'
3
1
  import { PROJECT_ROOT } from '#scripts/init/init-paths'
2
+ import { git_gh_api_path } from './git-gh-api-path'
3
+ import { git_gh_exec } from './git-gh-exec'
4
4
 
5
5
  // The synchronous twin of `git_gh_repo.repo_get_name_with_owner`: same fact, read the same way, but
6
6
  // synchronously because `josh init` / `josh sync` / `josh doctor` decide before they can await.
@@ -146,9 +146,5 @@ function classify_ai_review_comments(comments: ReadonlyArray<ReviewComment>): Cl
146
146
  }
147
147
  }
148
148
 
149
- const git_ai_review_scan = {
150
- classify_ai_review_comments,
151
- }
152
-
153
- export { git_ai_review_scan, classify_ai_review_comments }
149
+ export { classify_ai_review_comments }
154
150
  export type { ReviewComment, ClassifiedFinding, ClassifiedFindings, FindingKind }
@@ -1,3 +1,4 @@
1
+ import { COMMAND_TIMEOUT_MS } from '#scripts/lib/timeouts'
1
2
  import { execa } from 'execa'
2
3
 
3
4
  const GH_NOT_INSTALLED_MSG = 'gh CLI is not installed. Install it from https://cli.github.com/'
@@ -6,7 +7,7 @@ const gh_check: { promise?: Promise<void> } = {}
6
7
 
7
8
  async function run_gh_check(): Promise<void> {
8
9
  try {
9
- await execa('gh', ['--version'])
10
+ await execa('gh', ['--version'], { timeout: COMMAND_TIMEOUT_MS })
10
11
  } catch {
11
12
  delete gh_check.promise
12
13
  throw new Error(GH_NOT_INSTALLED_MSG)
@@ -1,7 +1,7 @@
1
+ import { has_timed_out } from '#scripts/git/git-execa-error'
1
2
  import { agent_session_environment } from '#scripts/josh/agent-session-environment'
2
3
  import { error_text } from '#scripts/lib/error-message'
3
4
  import { execa, execaSync } from 'execa'
4
- import { has_timed_out } from './git-execa-error'
5
5
  import { check_gh_installed } from './git-gh-check'
6
6
  import { gh_failure } from './git-gh-failure'
7
7
 
@@ -1,5 +1,5 @@
1
+ import { parse_json } from '#scripts/git/parse-json-array'
1
2
  import { z } from 'zod'
2
- import { parse_json } from './parse-json-array'
3
3
 
4
4
  // Why one `gh api` request failed, taken from **that request** rather than from a later probe
5
5
  // (joshuafolkken/kit#1690).
@@ -36,7 +36,6 @@ function handle_pr_create_error(error: unknown): never {
36
36
 
37
37
  const git_gh_helpers = {
38
38
  parse_pr_state_string,
39
- is_pr_already_exists_message,
40
39
  get_error_message_with_stderr,
41
40
  handle_pr_create_error,
42
41
  }
@@ -178,6 +178,7 @@ async function fetch_selected(request: IssueListRequest): Promise<SelectedRows>
178
178
  let has_more = true
179
179
 
180
180
  while (page <= MAX_PAGES && wants_more(has_more, selected.length, request.limit)) {
181
+ // eslint-disable-next-line no-await-in-loop -- paging stops as soon as enough rows are selected
181
182
  const result = await fetch_page(request, page)
182
183
 
183
184
  selected.push(...result.selected)
@@ -207,6 +208,7 @@ async function read_relations(
207
208
  const relations: Array<BlockedBy> = []
208
209
 
209
210
  for (const row of rows) {
211
+ // eslint-disable-next-line no-await-in-loop -- paced reads, so a rate limit does not fail rows
210
212
  relations.push(await read_blocked_by(String(row.number), row, repo))
211
213
  }
212
214
 
@@ -1,3 +1,4 @@
1
+ import type { IssueReference } from '#scripts/issue/issue-reference'
1
2
  import { git_gh_api_path } from './git-gh-api-path'
2
3
  import { git_gh_exec } from './git-gh-exec'
3
4
  import { gh_failure, type GhFailure } from './git-gh-failure'
@@ -9,7 +10,6 @@ import {
9
10
  type RestIssue,
10
11
  } from './git-gh-issue-rest'
11
12
  import { gh_reachability } from './git-gh-reachability'
12
- import type { IssueReference } from './issue-reference'
13
13
 
14
14
  // Reading one issue. Split out of `git-gh-issue.ts`, which had grown past the file-length limit
15
15
  // while holding both the reads and the writes; the reads are what every epic command goes through,
@@ -1,8 +1,11 @@
1
+ import {
2
+ parse_json_array_or_undefined,
3
+ parse_json_object_safe,
4
+ } from '#scripts/git/parse-json-array'
5
+ import { blocking_issue_schema } from '#scripts/git/schemas'
6
+ import type { IssueReference } from '#scripts/issue/issue-reference'
1
7
  import { z } from 'zod'
2
8
  import { MERGED_STATE, to_gh_state } from './git-gh-rest-state'
3
- import type { IssueReference } from './issue-reference'
4
- import { parse_json_array_or_undefined, parse_json_object_safe } from './parse-json-array'
5
- import { blocking_issue_schema } from './schemas'
6
9
 
7
10
  // The translation between one REST issue (`repos/{owner}/{repo}/issues/{N}`) and the JSON shape
8
11
  // `gh issue view --json <fields>` used to answer with.
@@ -77,6 +77,12 @@ async function fetch_pr_number(branch_name: string): Promise<number | undefined>
77
77
  // distinction is the point. The *classification* is cheaper here and needs no status probe: a branch
78
78
  // with no pull request is a 200 with an empty listing rather than a 404, so the lookup's own outcome
79
79
  // already separates them (joshuafolkken/kit#1048).
80
+ interface PullMergeState {
81
+ is_merged: boolean
82
+ merged_at: string | undefined
83
+ head_sha: string | undefined
84
+ }
85
+
80
86
  type PullNumberRead =
81
87
  { kind: 'read'; pr_number: number } | { kind: 'missing' } | { kind: 'unreadable'; cause: unknown }
82
88
 
@@ -215,6 +221,22 @@ async function pr_get_url(branch_name: string): Promise<string | undefined> {
215
221
  return git_gh_helpers.parse_pr_state_string(pull.html_url)
216
222
  }
217
223
 
224
+ // **Where the branch's pull request stands** — a merge a person made by hand included
225
+ // (joshuafolkken/kit#3023): whether it merged and when, and the commit its head is on, which a push
226
+ // made on GitHub moves without touching the local branch. `undefined` covers both "no pull request"
227
+ // and "nothing could be read": `followup` then takes its ordinary path, whose merge step settles a
228
+ // pull request that did merge after all (`pr_merge`), so an unread answer costs a wait, not a wrong tail.
229
+ async function pr_get_merge_state(branch_name: string): Promise<PullMergeState | undefined> {
230
+ const pull = await read_pull_of_branch(branch_name)
231
+ if (pull === undefined) return undefined
232
+
233
+ return {
234
+ is_merged: git_gh_pr_rest.is_merged(pull),
235
+ merged_at: pull.merged_at ?? undefined,
236
+ head_sha: pull.head?.sha,
237
+ }
238
+ }
239
+
218
240
  // REST answers JSON null for a pull request with no body where `gh --json body` answered an empty
219
241
  // string, and both used to arrive here as the empty answer this folds to `undefined`.
220
242
  async function pr_get_body(branch_name: string): Promise<string | undefined> {
@@ -281,6 +303,7 @@ const git_gh_pr_read = {
281
303
  pr_get_number,
282
304
  pr_get_url,
283
305
  pr_get_body,
306
+ pr_get_merge_state,
284
307
  pr_view,
285
308
  pr_get_comments,
286
309
  pr_get_review_comments,
@@ -290,6 +313,7 @@ const git_gh_pr_read = {
290
313
  // needs them separately: the reviews endpoint is keyed by number while the rollup is keyed by the
291
314
  // head commit the detail carries. Exported rather than re-derived so the memo above stays one memo
292
315
  // (joshuafolkken/kit#1028).
316
+ export type { PullMergeState }
293
317
  export {
294
318
  git_gh_pr_read,
295
319
  forget_pr_numbers,
@@ -1,7 +1,10 @@
1
+ import {
2
+ parse_json_array_or_undefined,
3
+ parse_json_object_safe,
4
+ } from '#scripts/git/parse-json-array'
5
+ import { rest_comment_schema } from '#scripts/git/schemas'
1
6
  import { z } from 'zod'
2
7
  import { MERGED_STATE, to_gh_state } from './git-gh-rest-state'
3
- import { parse_json_array_or_undefined, parse_json_object_safe } from './parse-json-array'
4
- import { rest_comment_schema } from './schemas'
5
8
 
6
9
  // The translation between one REST pull request (`repos/{owner}/{repo}/pulls/{N}`) and the JSON
7
10
  // shape `gh pr view --json <fields>` used to answer with.
@@ -1,5 +1,5 @@
1
+ import { parse_json_array_or_undefined } from '#scripts/git/parse-json-array'
1
2
  import { z } from 'zod'
2
- import { parse_json_array_or_undefined } from './parse-json-array'
3
3
 
4
4
  // GraphQL's `reviewDecision`, rebuilt from the review history REST serves.
5
5
  //
@@ -90,7 +90,7 @@ function to_review_decision(reviews_json: string): string {
90
90
  return latest.has(REVIEW_APPROVED) ? REVIEW_APPROVED : REVIEW_NONE
91
91
  }
92
92
 
93
- const git_gh_pr_review = { to_review_decision, parse_rest_reviews }
93
+ const git_gh_pr_review = { to_review_decision }
94
94
 
95
95
  export {
96
96
  git_gh_pr_review,
@@ -1,5 +1,5 @@
1
+ import { parse_json_array_or_undefined } from '#scripts/git/parse-json-array'
1
2
  import { z } from 'zod'
2
- import { parse_json_array_or_undefined } from './parse-json-array'
3
3
 
4
4
  // The two REST listings `gh pr view --json statusCheckRollup` served as one array, merged back into
5
5
  // that one array.
@@ -145,8 +145,6 @@ function to_status_check_rollup(input: {
145
145
  }
146
146
 
147
147
  const git_gh_pr_rollup = {
148
- to_check_run_items,
149
- to_status_context_items,
150
148
  to_status_check_rollup,
151
149
  }
152
150
 
@@ -1,7 +1,7 @@
1
1
  import { pr_classification, type ReleaseClassification } from '#scripts/ci/pr-classification'
2
+ import { git_command } from '#scripts/git/git-command'
2
3
  import { poll } from '#scripts/lib/poll'
3
4
  import { z } from 'zod'
4
- import { git_command } from './git-command'
5
5
  import { git_gh_api_path } from './git-gh-api-path'
6
6
  import { git_gh_exec } from './git-gh-exec'
7
7
  import { git_gh_helpers } from './git-gh-helpers'
@@ -207,9 +207,11 @@ async function sleep_between_read_backs(attempt: number): Promise<void> {
207
207
  // happen" from a read nobody got.
208
208
  async function has_merge_landed(pr_number: number, merge_error: unknown): Promise<boolean> {
209
209
  for (let attempt = 0; attempt < MERGE_READ_BACK_ATTEMPTS; attempt += 1) {
210
+ // eslint-disable-next-line no-await-in-loop -- a retry runs only after the previous attempt has answered
210
211
  const is_merged = await read_merge_state(pr_number)
211
212
  if (is_merged !== undefined) return is_merged
212
213
 
214
+ // eslint-disable-next-line no-await-in-loop -- a retry runs only after the previous attempt has answered
213
215
  await sleep_between_read_backs(attempt)
214
216
  }
215
217
 
@@ -1,4 +1,6 @@
1
1
  // cspell:words coderabbit coderabbitai
2
+ import { parse_json_array_or_undefined } from '#scripts/git/parse-json-array'
3
+ import { ai_review_pull_comment_schema } from '#scripts/git/schemas'
2
4
  import {
3
5
  classify_ai_review_comments,
4
6
  type ClassifiedFinding,
@@ -6,8 +8,6 @@ import {
6
8
  } from './git-ai-review-scan'
7
9
  import { git_gh_command } from './git-gh-command'
8
10
  import { git_pr_confirmation, has_ignore_reason, type TelegramContext } from './git-pr-confirmation'
9
- import { parse_json_array_or_undefined } from './parse-json-array'
10
- import { ai_review_pull_comment_schema } from './schemas'
11
11
 
12
12
  interface AiReviewPullComment {
13
13
  body?: string | undefined
@@ -163,9 +163,6 @@ async function handle_ai_review_findings(input: {
163
163
 
164
164
  const git_pr_ai_review = {
165
165
  handle_ai_review_findings,
166
- parse_ai_review_comments,
167
- to_review_comment,
168
- has_ignore_reason,
169
166
  }
170
167
 
171
168
  export {
@@ -240,17 +240,7 @@ function is_auto_merge_blocked(snapshot: PrStateSnapshot): boolean {
240
240
  )
241
241
  }
242
242
 
243
- const git_pr_checks_eval = {
244
- evaluate_pr_state,
245
- is_review_decision_decisive,
246
- read_required_statuses,
247
- is_coderabbit_check,
248
- collect_blocking_failures,
249
- describe_pr_failure,
250
- }
251
-
252
243
  export {
253
- git_pr_checks_eval,
254
244
  evaluate_pr_state,
255
245
  is_auto_merge_blocked,
256
246
  is_review_decision_decisive,
@@ -1,4 +1,5 @@
1
- import { pr_raw_schema, type RollupItemData } from './schemas'
1
+ import { pr_raw_schema, type RollupItemData } from '#scripts/git/schemas'
2
+ import { json_value } from '#scripts/lib/json-value'
2
3
 
3
4
  const CHECK_STATUS_PASS = 'pass'
4
5
  const CHECK_STATUS_PENDING = 'pending'
@@ -92,14 +93,6 @@ function read_rollup_array(parsed: unknown): Array<RollupItemData> {
92
93
  return result.data.statusCheckRollup ?? []
93
94
  }
94
95
 
95
- function parse_json_safe(raw_json: string): unknown {
96
- try {
97
- return JSON.parse(raw_json)
98
- } catch {
99
- return undefined
100
- }
101
- }
102
-
103
96
  function parse_rollup_item(item: RollupItemData): RollupCheck | undefined {
104
97
  const name = read_string(item[KEY_NAME]) ?? read_string(item[KEY_CONTEXT])
105
98
  if (name === undefined) return undefined
@@ -108,7 +101,7 @@ function parse_rollup_item(item: RollupItemData): RollupCheck | undefined {
108
101
  }
109
102
 
110
103
  function parse_rollup_checks(raw_json: string): Array<RollupCheck> {
111
- const parsed = parse_json_safe(raw_json)
104
+ const parsed = json_value.parse_or_undefined(raw_json)
112
105
  const rollup = read_rollup_array(parsed)
113
106
  const checks: Array<RollupCheck> = []
114
107
 
@@ -121,7 +114,7 @@ function parse_rollup_checks(raw_json: string): Array<RollupCheck> {
121
114
  }
122
115
 
123
116
  function parse_pr_state_snapshot(raw_json: string): PrStateSnapshot {
124
- const parsed = parse_json_safe(raw_json)
117
+ const parsed = json_value.parse_or_undefined(raw_json)
125
118
  const result = pr_raw_schema.safeParse(parsed)
126
119
  const data = result.success ? result.data : undefined
127
120
 
@@ -132,17 +125,8 @@ function parse_pr_state_snapshot(raw_json: string): PrStateSnapshot {
132
125
  }
133
126
  }
134
127
 
135
- const git_pr_checks_parse = {
136
- parse_rollup_checks,
137
- parse_json_safe,
138
- read_string,
139
- parse_pr_state_snapshot,
140
- }
141
-
142
128
  export {
143
- git_pr_checks_parse,
144
129
  parse_rollup_checks,
145
- parse_json_safe,
146
130
  read_string,
147
131
  parse_pr_state_snapshot,
148
132
  CHECK_STATUS_PASS,
@@ -1,3 +1,4 @@
1
+ import { package_name_schema } from '#scripts/git/schemas'
1
2
  import { poll } from '#scripts/lib/poll'
2
3
  import { git_gh_pr_auto_merge } from './git-gh-pr-auto-merge'
3
4
  import { git_gh_pr_snapshot } from './git-gh-pr-snapshot'
@@ -9,7 +10,6 @@ import {
9
10
  type PrEvaluation,
10
11
  } from './git-pr-checks-eval'
11
12
  import { parse_pr_state_snapshot, read_string, type PrStateSnapshot } from './git-pr-checks-parse'
12
- import { package_name_schema } from './schemas'
13
13
 
14
14
  const SECONDS_TO_MS = 1000
15
15
  const CHECK_WAIT_INTERVAL_MS = 10_000
@@ -262,6 +262,7 @@ async function wait_for_pr_success(options: WaitForPrSuccessOptions): Promise<Pr
262
262
 
263
263
  for (let attempt = 0; attempt < options.max_attempts; attempt += 1) {
264
264
  console.info(`Checking PR status… (${String(attempt + 1)}/${String(options.max_attempts)})`)
265
+ // eslint-disable-next-line no-await-in-loop -- polling: each read waits on the state the previous one saw
265
266
  carried = await attempt_pr_success_poll({
266
267
  options,
267
268
  stable_count: carried.next_stable_count,
@@ -1,7 +1,7 @@
1
+ import { parse_json_array_or_undefined } from '#scripts/git/parse-json-array'
2
+ import { pull_comment_schema } from '#scripts/git/schemas'
1
3
  import { git_gh_command } from './git-gh-command'
2
4
  import { has_ignore_reason } from './git-pr-ai-review'
3
- import { parse_json_array_or_undefined } from './parse-json-array'
4
- import { pull_comment_schema } from './schemas'
5
5
 
6
6
  // cspell:words coderabbit coderabbitai
7
7
 
@@ -120,9 +120,6 @@ async function handle_coderabbit_findings(input: {
120
120
  }
121
121
 
122
122
  const git_pr_coderabbit = {
123
- parse_pull_comments,
124
- read_unresolved_cr_urls,
125
- build_ignore_reason_comment,
126
123
  handle_coderabbit_findings,
127
124
  }
128
125
 
@@ -1,4 +1,4 @@
1
- import { telegram_notify, type TelegramSendInput } from './telegram-notify'
1
+ import { telegram_notify, type TelegramSendInput } from '#scripts/notify/telegram-notify'
2
2
 
3
3
  // What to type when the confirmation notification itself could not be delivered
4
4
  // (joshuafolkken/kit#1564). The `--body-file` spelling rather than `--body`, because the body names
@@ -53,8 +53,6 @@ function has_ignore_reason(reason: string | undefined): reason is string {
53
53
  // gates drift apart.
54
54
  const git_pr_confirmation = {
55
55
  notify_confirmation,
56
- build_confirmation_input,
57
- has_ignore_reason,
58
56
  }
59
57
 
60
58
  // `has_ignore_reason` stays a named export beside the namespace: `git-pr-coderabbit.ts` imports it
@@ -1,6 +1,6 @@
1
+ import { changed_paths } from '#scripts/git/changed-paths'
2
+ import { git_command } from '#scripts/git/git-command'
1
3
  import { managed_config_scope, type ManagedHit } from '#scripts/sync/managed-config-scope'
2
- import { changed_paths } from './changed-paths'
3
- import { git_command } from './git-command'
4
4
 
5
5
  // **The tracked diff against the merge base — untracked files excluded.**
6
6
  // `changed_paths.read_changed_paths(false)` appends the untracked files as well, and those are not in
@@ -63,7 +63,6 @@ async function handle_managed_config_changes(input: {
63
63
 
64
64
  const git_pr_managed_config = {
65
65
  handle_managed_config_changes,
66
- build_report,
67
66
  }
68
67
 
69
68
  export { git_pr_managed_config }
@@ -1,10 +1,10 @@
1
1
  import { pr_classification, type ReleaseClassification } from '#scripts/ci/pr-classification'
2
- import { animation_helpers, type AnimationOptions } from './animation-helpers'
2
+ import type { IssueInfo } from '#scripts/git/git-issue'
3
+ import { pr_info_schema } from '#scripts/git/schemas'
4
+ import { animation_helpers, type AnimationOptions } from '#scripts/lib/animation-helpers'
3
5
  import { git_gh_command } from './git-gh-command'
4
- import type { IssueInfo } from './git-issue'
5
6
  import { git_pr_error } from './git-pr-error'
6
7
  import { git_pr_messages } from './git-pr-messages'
7
- import { pr_info_schema } from './schemas'
8
8
 
9
9
  // **Answers the new pull request's URL, and `undefined` when one already existed.** `pr_create`
10
10
  // filters its REST response to `.html_url`, so the address is in hand the moment the call returns —
@@ -194,7 +194,6 @@ const changed_file_scope = {
194
194
  LISTED_FILE_LIMIT,
195
195
  UNREADABLE_REASON,
196
196
  describe_scope,
197
- explicit_files_of,
198
197
  flags_of,
199
198
  is_flag,
200
199
  read_changed_files,
@@ -2,9 +2,9 @@ import {
2
2
  animation_helpers,
3
3
  create_git_operation_config,
4
4
  type AnimationOptions,
5
- } from './animation-helpers'
5
+ } from '#scripts/lib/animation-helpers'
6
6
  import { git_command } from './git-command'
7
- import { git_error } from './git-error'
7
+ import { BranchMismatchError } from './git-error'
8
8
 
9
9
  async function current(): Promise<string> {
10
10
  const config: AnimationOptions<string> = {
@@ -124,7 +124,7 @@ async function check_and_create_branch(
124
124
  }
125
125
 
126
126
  if (is_mismatch(current_branch, target_branch_name, default_branch)) {
127
- git_error.display_branch_mismatch_error(current_branch, target_branch_name)
127
+ throw new BranchMismatchError({ current_branch, target_branch_name })
128
128
  }
129
129
 
130
130
  return current_branch
@@ -132,9 +132,6 @@ async function check_and_create_branch(
132
132
 
133
133
  const git_branch = {
134
134
  current,
135
- create,
136
- switch_to,
137
- exists,
138
135
  check_and_create_branch,
139
136
  is_mismatch,
140
137
  // Exported so a lane's branch name can be checked against the real matcher rather than against a
@@ -1,4 +1,4 @@
1
- import { animation_helpers, create_git_operation_config } from './animation-helpers'
1
+ import { animation_helpers, create_git_operation_config } from '#scripts/lib/animation-helpers'
2
2
  import { git_command } from './git-command'
3
3
 
4
4
  async function commit(commit_message: string): Promise<void> {