@joshuafolkken/kit 1.1035.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 (605) hide show
  1. package/.claude/settings.json +9 -8
  2. package/.claude/skills/epic-commands/SKILL.md +5 -7
  3. package/.claude/skills/verify-ui/SKILL.md +1 -1
  4. package/.claude/skills/workflow-commands/SKILL.md +21 -13
  5. package/.claude/skills/workflow-commands/background-commands.md +5 -4
  6. package/.claude/skills/workflow-commands/backlogrun-child.md +3 -3
  7. package/.claude/skills/workflow-commands/backlogrun-lanes.md +9 -7
  8. package/.claude/skills/workflow-commands/backlogrun-park.md +6 -0
  9. package/.claude/skills/workflow-commands/backlogrun-progress.md +31 -37
  10. package/.claude/skills/workflow-commands/backlogrun-steps.md +25 -25
  11. package/.claude/skills/workflow-commands/backlogrun.md +2 -2
  12. package/.claude/skills/workflow-commands/chain-rule.md +6 -4
  13. package/.claude/skills/workflow-commands/delegation.md +3 -3
  14. package/.claude/skills/workflow-commands/followup-reference.md +3 -3
  15. package/.claude/skills/workflow-commands/followup.md +7 -3
  16. package/.claude/skills/workflow-commands/fullrun-steps.md +3 -2
  17. package/.claude/skills/workflow-commands/fullrun.md +3 -2
  18. package/.claude/skills/workflow-commands/halfrun.md +16 -19
  19. package/.claude/skills/workflow-commands/issue-comments.md +2 -2
  20. package/.claude/skills/workflow-commands/issue-fold-existing.md +10 -10
  21. package/.claude/skills/workflow-commands/issue-scout.md +1 -1
  22. package/.claude/skills/workflow-commands/kickoff.md +9 -4
  23. package/.claude/skills/workflow-commands/latest-gate.md +1 -1
  24. package/.claude/skills/workflow-commands/needs-human-review.md +1 -1
  25. package/.claude/skills/workflow-commands/observation-filing.md +44 -89
  26. package/.claude/skills/workflow-commands/pre-gate-cut.md +33 -36
  27. package/.claude/skills/workflow-commands/prerequisite.md +1 -1
  28. package/.claude/skills/workflow-commands/prrun.md +36 -0
  29. package/.claude/skills/workflow-commands/retrospective.md +1 -1
  30. package/.claude/skills/workflow-commands/working-tree-hold.md +24 -4
  31. package/.codex/hooks.json +16 -20
  32. package/.github/actions/setup-pnpm/action.yml +93 -0
  33. package/.github/dependabot.yml +5 -1
  34. package/.github/workflows/auto-tag.yml +21 -0
  35. package/.github/workflows/ci.yml +26 -128
  36. package/.github/workflows/pr-classification.yml +5 -41
  37. package/.github/workflows/publish.yml +42 -48
  38. package/.github/workflows/sonar-qube.yml +37 -4
  39. package/AGENTS.md +12 -2
  40. package/CLAUDE.md +15 -16
  41. package/GEMINI.md +14 -2
  42. package/README.md +59 -18
  43. package/SECURITY.md +36 -6
  44. package/cspell/index.yaml +2 -1
  45. package/dist/CLAUDE.md +15 -16
  46. package/dist/config-merge/index.js +15 -3
  47. package/dist/hooks/batch-guard.js +4 -4
  48. package/dist/hooks/{chunk-Y27M6A7X.js → chunk-3C4YCCEF.js} +5 -13
  49. package/dist/hooks/{chunk-D67KVGGY.js → chunk-7ZPFAVR7.js} +17 -88
  50. package/dist/hooks/{chunk-HOYJU5RM.js → chunk-E54KGFEQ.js} +11 -4
  51. package/dist/hooks/{chunk-KG6PZD72.js → chunk-IL27YTPH.js} +2 -2
  52. package/dist/hooks/{chunk-GJT4BNVE.js → chunk-KHWHKJOM.js} +3 -3
  53. package/dist/hooks/{chunk-HU66PWWL.js → chunk-M2XDCUKD.js} +1076 -509
  54. package/dist/hooks/{chunk-GLBDBJOK.js → chunk-NKOG3XAV.js} +199 -304
  55. package/dist/hooks/{chunk-ZXNE6NY3.js → chunk-O4LL4HTI.js} +2 -7
  56. package/dist/hooks/{chunk-XPLP27WA.js → chunk-OIZUHPJI.js} +5 -27
  57. package/dist/hooks/{chunk-EIFCAJRB.js → chunk-UD24EAIL.js} +2546 -1636
  58. package/dist/hooks/codex-hook-adapter.js +10 -11
  59. package/dist/hooks/duplicate-read-guard.js +5 -5
  60. package/dist/hooks/format-edited.js +15 -34
  61. package/dist/hooks/inputs.json +279 -0
  62. package/dist/hooks/investigation-guard.js +5 -5
  63. package/dist/hooks/pretool-guard.js +23 -16
  64. package/dist/hooks/session-lang.js +0 -1
  65. package/dist/hooks/stop-guard.js +188 -509
  66. package/dist/josh.js +166 -225
  67. package/dist/managed-marker/index.js +2 -1
  68. package/dist/version/index.js +412 -64
  69. package/eslint/rules/promise.js +5 -0
  70. package/package.json +13 -8
  71. package/prompts/collaboration-workflow/file-edits.md +6 -53
  72. package/prompts/collaboration-workflow/issue-citation.md +5 -5
  73. package/prompts/collaboration-workflow/operating-rules.md +4 -4
  74. package/prompts/collaboration-workflow/overview.md +13 -1
  75. package/prompts/collaboration-workflow/report-format.md +1 -1
  76. package/prompts/collaboration-workflow/residency.md +4 -4
  77. package/prompts/collaboration-workflow/rule-delivery.md +5 -36
  78. package/prompts/collaboration-workflow/shell-body.md +7 -9
  79. package/prompts/collaboration-workflow/turn-batching.md +21 -37
  80. package/prompts/collaboration-workflow/upstream-interrupt.md +1 -1
  81. package/prompts/collaboration-workflow/wip-cap.md +36 -36
  82. package/prompts/collaboration-workflow.md +5 -8
  83. package/prompts/review-rubric.md +1 -1
  84. package/prompts/review.md +3 -3
  85. package/prompts/sonar-hotspot-handling.md +12 -4
  86. package/prompts/testing-guide.md +3 -3
  87. package/scripts/adopt/adopt-toolkits.ts +2 -2
  88. package/scripts/adopt/adopt.ts +0 -2
  89. package/scripts/agent/agent-argv.ts +0 -2
  90. package/scripts/agent/agent-diagnostics.ts +1 -1
  91. package/scripts/agent/agent-role-profile.ts +0 -7
  92. package/scripts/agent/claude-agent-argv.ts +0 -2
  93. package/scripts/agent/codex-agent-argv.ts +1 -1
  94. package/scripts/agent/codex-hooks.ts +92 -0
  95. package/scripts/agent/interactive-ask.ts +1 -1
  96. package/scripts/auto-ok/auto-ok-cli.ts +15 -25
  97. package/scripts/backlog/backlog-budget.ts +0 -2
  98. package/scripts/backlog/backlog-defect-priority.ts +2 -2
  99. package/scripts/backlog/backlog-drive-cli.ts +10 -8
  100. package/scripts/backlog/backlog-drive-named-offer.ts +16 -3
  101. package/scripts/backlog/backlog-drive-named.ts +2 -1
  102. package/scripts/backlog/backlog-drive.ts +76 -16
  103. package/scripts/backlog/backlog-named.ts +0 -3
  104. package/scripts/backlog/backlog-next.ts +32 -22
  105. package/scripts/backlog/backlog-offer-cli.ts +0 -5
  106. package/scripts/backlog/backlog-plan-cli.ts +6 -8
  107. package/scripts/backlog/backlog-plan.ts +1 -1
  108. package/scripts/backlog/backlog-pool.ts +34 -17
  109. package/scripts/backlog/backlog-rank.ts +106 -0
  110. package/scripts/backlog/backlog-ready.ts +19 -3
  111. package/scripts/backlog/backlog-scope.ts +1 -3
  112. package/scripts/backlog/backlog-stalled-detect.ts +2 -2
  113. package/scripts/backlog/backlog-stalled.ts +0 -1
  114. package/scripts/backlog/backlog-waves.ts +47 -31
  115. package/scripts/behavior/behavior-cli.ts +1 -1
  116. package/scripts/build/build-codex-hooks.ts +26 -0
  117. package/scripts/build/build-hooks.ts +92 -11
  118. package/scripts/build/hook-bundle-stamp.ts +111 -0
  119. package/scripts/cases/cases-cli.ts +1 -1
  120. package/scripts/cases/cases-logic.ts +1 -1
  121. package/scripts/ci/composite-actions.ts +30 -0
  122. package/scripts/ci/pr-classification.ts +3 -3
  123. package/scripts/claude/workflow-destination.ts +10 -1
  124. package/scripts/clone/clone-fingerprint.ts +0 -1
  125. package/scripts/clone/clone-scan-cli.ts +1 -1
  126. package/scripts/clone/clone-scan.ts +1 -1
  127. package/scripts/config-merge/json-format.ts +0 -1
  128. package/scripts/config-merge/patch-yaml-list.ts +1 -1
  129. package/scripts/cost-runtime/codex-usage.ts +2 -9
  130. package/scripts/cost-runtime/cost-attribute.ts +0 -1
  131. package/scripts/cost-runtime/cost-cli.ts +0 -3
  132. package/scripts/cost-runtime/cost-corpus.ts +0 -2
  133. package/scripts/cost-runtime/cost-format.ts +0 -3
  134. package/scripts/cost-runtime/cost-pricing.ts +0 -1
  135. package/scripts/cost-runtime/cost-tokens.ts +0 -1
  136. package/scripts/delegation/delegation-cli.ts +1 -1
  137. package/scripts/delegation/delegation-policy.ts +11 -1
  138. package/scripts/delegation/duplicate-read-guard.ts +0 -8
  139. package/scripts/delegation/fanout-cli.ts +1 -1
  140. package/scripts/delegation/fanout.ts +0 -2
  141. package/scripts/delegation/investigation-reads.ts +1 -164
  142. package/scripts/discovery/repo-map-logic.ts +0 -1
  143. package/scripts/discovery/repo-party-cli.ts +1 -1
  144. package/scripts/doctor/doctor-consumer.ts +4 -6
  145. package/scripts/doctor/doctor-logic.ts +0 -4
  146. package/scripts/doctor/doctor.ts +14 -9
  147. package/scripts/document/document-byte-budget.ts +8 -9
  148. package/scripts/document/document-byte-check.ts +0 -1
  149. package/scripts/document/document-read-cli.ts +0 -2
  150. package/scripts/document/document-section-cli.ts +1 -1
  151. package/scripts/document/document-section.ts +0 -3
  152. package/scripts/document/edit-files-cli.ts +0 -1
  153. package/scripts/document/entry-read-budget.ts +13 -4
  154. package/scripts/document/lane-child-read-set.ts +1 -6
  155. package/scripts/document/read-files-cli.ts +0 -4
  156. package/scripts/document/read-set-cli.ts +0 -2
  157. package/scripts/document/read-set-point-of-use.ts +1 -0
  158. package/scripts/document/read-set-pricing.ts +0 -1
  159. package/scripts/document/read-set-trim.ts +1 -1
  160. package/scripts/epic/epic-add.ts +1 -1
  161. package/scripts/epic/epic-audit-cli.ts +1 -4
  162. package/scripts/epic/epic-audit-orphans.ts +1 -3
  163. package/scripts/epic/epic-audit-rationale.ts +0 -1
  164. package/scripts/epic/epic-audit-report.ts +0 -2
  165. package/scripts/epic/epic-audit.ts +5 -4
  166. package/scripts/epic/epic-bundle-cli.ts +1 -1
  167. package/scripts/epic/epic-bundle-evidence.ts +0 -1
  168. package/scripts/epic/epic-bundle-referenced.ts +1 -5
  169. package/scripts/epic/epic-bundle.ts +0 -4
  170. package/scripts/epic/epic-busy.ts +4 -5
  171. package/scripts/epic/epic-candidate-confirm.ts +0 -5
  172. package/scripts/epic/epic-classify.ts +2 -2
  173. package/scripts/epic/epic-cli-argv.ts +0 -1
  174. package/scripts/epic/epic-close-comment.ts +1 -1
  175. package/scripts/epic/epic-close.ts +5 -2
  176. package/scripts/epic/epic-cross-repo.ts +2 -4
  177. package/scripts/epic/epic-decision.ts +0 -1
  178. package/scripts/epic/epic-fetch.ts +2 -2
  179. package/scripts/epic/epic-index.ts +2 -3
  180. package/scripts/epic/epic-issue.ts +1 -15
  181. package/scripts/epic/epic-lane-offer.ts +20 -30
  182. package/scripts/epic/epic-nested.ts +1 -1
  183. package/scripts/epic/epic-next-read.ts +1 -3
  184. package/scripts/epic/epic-next-views.ts +0 -1
  185. package/scripts/epic/epic-next.ts +1 -10
  186. package/scripts/epic/epic-parse.ts +0 -1
  187. package/scripts/epic/epic-promote.ts +0 -9
  188. package/scripts/epic/epic-rank.ts +37 -0
  189. package/scripts/epic/epic-read.ts +1 -2
  190. package/scripts/epic/epic-reconcile.ts +1 -1
  191. package/scripts/epic/epic-reference.ts +1 -13
  192. package/scripts/epic/epic-relation-recheck.ts +1 -1
  193. package/scripts/epic/epic-relations.ts +1 -1
  194. package/scripts/epic/epic-remove.ts +1 -1
  195. package/scripts/epic/epic-report.ts +0 -1
  196. package/scripts/epic/epic-run.ts +2 -3
  197. package/scripts/epic/epic-shape.ts +1 -1
  198. package/scripts/epic/epic-solo-stale.ts +107 -0
  199. package/scripts/epic/epic-solo.ts +32 -30
  200. package/scripts/epic/epic-triage.ts +1 -1
  201. package/scripts/epic/epic-validate.ts +1 -1
  202. package/scripts/epic/epic.ts +1 -1
  203. package/scripts/exports/unused-members-cli.ts +53 -0
  204. package/scripts/{git → followup}/followup-issue-number.ts +1 -6
  205. package/scripts/{git → followup}/git-followup-cleanup.ts +2 -1
  206. package/scripts/{git → followup}/git-followup-finish.ts +1 -3
  207. package/scripts/{git → followup}/git-followup-flush.ts +2 -2
  208. package/scripts/{git → followup}/git-followup-issue-close.ts +2 -2
  209. package/scripts/{git → followup}/git-followup-label.ts +4 -4
  210. package/scripts/followup/git-followup-merged.ts +112 -0
  211. package/scripts/{git → followup}/git-followup-pending.ts +1 -1
  212. package/scripts/{git → followup}/git-followup-workflow.ts +19 -11
  213. package/scripts/{git → followup}/git-pr-followup-wrapup.ts +9 -3
  214. package/scripts/{git → followup}/git-pr-followup.ts +53 -16
  215. package/scripts/gate/core-budget.ts +3 -9
  216. package/scripts/gate/gate-plan.ts +7 -4
  217. package/scripts/gate/gate-report.ts +0 -6
  218. package/scripts/gate/gate-tree.ts +1 -1
  219. package/scripts/gate/pre-commit-type-check.ts +0 -6
  220. package/scripts/gate/project-checks.ts +7 -8
  221. package/scripts/gate/scoped-green.ts +0 -1
  222. package/scripts/gate/type-check-step.ts +1 -1
  223. package/scripts/gate/verification-gate.ts +0 -2
  224. package/scripts/gh/fix-gh-packages.ts +15 -12
  225. package/scripts/gh/gh-spawn.ts +2 -2
  226. package/scripts/{git → gh}/git-ai-review-scan.ts +1 -5
  227. package/scripts/{git → gh}/git-gh-check.ts +2 -1
  228. package/scripts/{git → gh}/git-gh-exec.ts +1 -1
  229. package/scripts/{git → gh}/git-gh-failure.ts +1 -1
  230. package/scripts/{git → gh}/git-gh-helpers.ts +0 -1
  231. package/scripts/{git → gh}/git-gh-issue-list.ts +2 -0
  232. package/scripts/{git → gh}/git-gh-issue-read.ts +1 -1
  233. package/scripts/{git → gh}/git-gh-issue-rest.ts +6 -3
  234. package/scripts/{git → gh}/git-gh-pr-read.ts +24 -0
  235. package/scripts/{git → gh}/git-gh-pr-rest.ts +5 -2
  236. package/scripts/{git → gh}/git-gh-pr-review.ts +2 -2
  237. package/scripts/{git → gh}/git-gh-pr-rollup.ts +1 -3
  238. package/scripts/{git → gh}/git-gh-pr.ts +3 -1
  239. package/scripts/{git → gh}/git-pr-ai-review.ts +2 -5
  240. package/scripts/{git → gh}/git-pr-checks-eval.ts +0 -10
  241. package/scripts/{git → gh}/git-pr-checks-parse.ts +4 -20
  242. package/scripts/{git → gh}/git-pr-checks.ts +2 -1
  243. package/scripts/{git → gh}/git-pr-coderabbit.ts +2 -5
  244. package/scripts/{git → gh}/git-pr-confirmation.ts +1 -3
  245. package/scripts/{git → gh}/git-pr-managed-config.ts +2 -3
  246. package/scripts/{git → gh}/git-pr.ts +3 -3
  247. package/scripts/git/changed-file-scope.ts +0 -1
  248. package/scripts/git/git-branch.ts +3 -6
  249. package/scripts/git/git-command.ts +1 -1
  250. package/scripts/git/git-commit.ts +1 -1
  251. package/scripts/git/git-common-directory.ts +80 -24
  252. package/scripts/git/git-error.ts +66 -9
  253. package/scripts/git/git-execa-error.ts +6 -1
  254. package/scripts/git/git-issue.ts +1 -1
  255. package/scripts/git/git-preflight.ts +24 -6
  256. package/scripts/git/git-prompt.ts +6 -31
  257. package/scripts/git/git-push-transport.ts +12 -69
  258. package/scripts/git/git-push.ts +1 -1
  259. package/scripts/git/git-spawn.ts +79 -3
  260. package/scripts/git/git-ssh-keepalive.ts +74 -0
  261. package/scripts/git/git-staging.ts +1 -0
  262. package/scripts/git/git-status.ts +1 -1
  263. package/scripts/git/git-workflow.ts +1 -1
  264. package/scripts/git/gone-branch.ts +4 -2
  265. package/scripts/git/listing-cutoff.ts +1 -1
  266. package/scripts/git/main-merge.ts +1 -1
  267. package/scripts/git/main-sync.ts +19 -1
  268. package/scripts/git/parse-json-array.ts +0 -3
  269. package/scripts/git/repository-lock.ts +16 -16
  270. package/scripts/git/{git-stash.ts → stash/git-stash.ts} +1 -1
  271. package/scripts/git/{stash-pop-args.ts → stash/stash-pop-args.ts} +1 -1
  272. package/scripts/git/{stash-pop-cli.ts → stash/stash-pop-cli.ts} +0 -1
  273. package/scripts/git/{stash-sweep-lock.ts → stash/stash-sweep-lock.ts} +3 -3
  274. package/scripts/hooks/codex-hook-adapter.ts +0 -1
  275. package/scripts/hooks/edited-cspell.ts +1 -1
  276. package/scripts/hooks/format-edited-cli.ts +15 -0
  277. package/scripts/hooks/format-edited-file.ts +4 -9
  278. package/scripts/hooks/pre-push-unit.ts +0 -4
  279. package/scripts/hooks/pretool-guard-cli.ts +21 -0
  280. package/scripts/hooks/pretool-guard.ts +36 -19
  281. package/scripts/hooks/reserved-run.ts +1 -1
  282. package/scripts/hooks/step-zero-notice.ts +76 -0
  283. package/scripts/hooks/stop-guard.ts +47 -21
  284. package/scripts/init/claude-plugin-config.ts +4 -5
  285. package/scripts/init/hook-command-rewrite.ts +16 -8
  286. package/scripts/init/hook-launch.ts +41 -15
  287. package/scripts/init/init-basic.ts +2 -5
  288. package/scripts/init/init-logic.ts +7 -0
  289. package/scripts/init/init.ts +0 -3
  290. package/scripts/init/project-profile.ts +6 -11
  291. package/scripts/init/start-exec.ts +8 -2
  292. package/scripts/init/start-plan.ts +18 -5
  293. package/scripts/init/start-setup-pr.ts +52 -25
  294. package/scripts/init/start-steps.ts +42 -9
  295. package/scripts/init/start.ts +40 -10
  296. package/scripts/issue/behavior-change-lint.ts +0 -1
  297. package/scripts/issue/defect-rate-cli.ts +3 -3
  298. package/scripts/issue/defect-rate.ts +1 -2
  299. package/scripts/{git → issue}/git-next-issues.ts +37 -8
  300. package/scripts/issue/issue-backlinks-cli.ts +1 -5
  301. package/scripts/issue/issue-cite-cli.ts +2 -6
  302. package/scripts/issue/issue-cite.ts +19 -3
  303. package/scripts/issue/issue-classification.ts +1 -9
  304. package/scripts/issue/issue-closing-pr.ts +4 -4
  305. package/scripts/issue/issue-comment-cli.ts +2 -2
  306. package/scripts/issue/issue-file-cli.ts +5 -5
  307. package/scripts/issue/issue-file.ts +2 -2
  308. package/scripts/issue/issue-fold-cli.ts +1 -1
  309. package/scripts/issue/issue-fold-existing-cli.ts +1 -1
  310. package/scripts/{git → issue}/issue-labels.ts +20 -0
  311. package/scripts/issue/issue-lint-cli.ts +1 -1
  312. package/scripts/issue/issue-merged.ts +2 -2
  313. package/scripts/issue/issue-rank.ts +89 -0
  314. package/scripts/issue/issue-read-cli.ts +8 -47
  315. package/scripts/issue/issue-read.ts +0 -2
  316. package/scripts/issue/issue-report-failures.ts +80 -0
  317. package/scripts/issue/issue-scout-cli.ts +1 -7
  318. package/scripts/issue/issue-scout-closed.ts +2 -2
  319. package/scripts/issue/issue-scout.ts +0 -2
  320. package/scripts/issue/issue-state-cli.ts +5 -46
  321. package/scripts/issue/issue-state.ts +1 -5
  322. package/scripts/issue/markdown-section.ts +1 -1
  323. package/scripts/issue/measure-rerun-cli.ts +1 -1
  324. package/scripts/issue/reproduction-measure.ts +1 -1
  325. package/scripts/josh/cli-body.ts +1 -1
  326. package/scripts/josh/file-map-stamp.ts +0 -3
  327. package/scripts/josh/josh-command-map.ts +2 -102
  328. package/scripts/josh/josh-commands-ai.ts +9 -102
  329. package/scripts/josh/josh-commands-backlog.ts +5 -1
  330. package/scripts/josh/josh-commands-development.ts +10 -3
  331. package/scripts/josh/josh-commands-issue.ts +2 -2
  332. package/scripts/josh/josh-commands-maintenance.ts +7 -0
  333. package/scripts/josh/josh-commands-project.ts +7 -1
  334. package/scripts/josh/josh-commands-run.ts +114 -0
  335. package/scripts/josh/josh-commands-versioning.ts +8 -0
  336. package/scripts/josh/josh-commands-workflow.ts +2 -2
  337. package/scripts/josh/path-decision.ts +0 -3
  338. package/scripts/josh/process-owner.ts +16 -0
  339. package/scripts/josh/session-language-cli.ts +0 -1
  340. package/scripts/lane/lane-await.ts +3 -6
  341. package/scripts/lane/lane-capacity.ts +6 -3
  342. package/scripts/lane/lane-child-invocation.ts +20 -7
  343. package/scripts/lane/lane-child-marker.ts +16 -2
  344. package/scripts/lane/lane-cli.ts +33 -18
  345. package/scripts/lane/lane-close.ts +1 -3
  346. package/scripts/lane/lane-dispatch.ts +3 -4
  347. package/scripts/lane/lane-environment.ts +0 -9
  348. package/scripts/lane/lane-handoff.ts +38 -0
  349. package/scripts/lane/lane-launch-cli.ts +21 -11
  350. package/scripts/lane/lane-open.ts +0 -3
  351. package/scripts/lane/lane-output.ts +0 -1
  352. package/scripts/lane/lane-registry.ts +9 -0
  353. package/scripts/lane/lane-report.ts +10 -4
  354. package/scripts/lane/openai-lane-ship.ts +2 -0
  355. package/scripts/lane/openai-lane-supervisor-decision.ts +2 -1
  356. package/scripts/lane/openai-lane-supervisor.ts +6 -4
  357. package/scripts/lane/openai-review-broker.ts +3 -0
  358. package/scripts/lib/bounded-pool.ts +1 -0
  359. package/scripts/lib/json-value.ts +5 -4
  360. package/scripts/lib/poll.ts +3 -1
  361. package/scripts/lib/timed-fetch.ts +15 -0
  362. package/scripts/lib/timeouts.ts +13 -0
  363. package/scripts/{yaml → lib}/yaml-document.ts +3 -1
  364. package/scripts/{bytes → lines}/bytes-command.ts +0 -2
  365. package/scripts/lines/lines-command.ts +0 -1
  366. package/scripts/lint/lint-related-scope.ts +0 -1
  367. package/scripts/lint/lint-related.ts +1 -1
  368. package/scripts/{git → notify}/telegram-notify.ts +2 -2
  369. package/scripts/{git → notify}/telegram-test.ts +4 -4
  370. package/scripts/observations/observation-ledger-home.ts +0 -1
  371. package/scripts/observations/observation-ledger-line.ts +0 -1
  372. package/scripts/observations/observation-ledger-migrate.ts +1 -1
  373. package/scripts/observations/observations-flush-landing.ts +3 -3
  374. package/scripts/observations/observations-flush.ts +2 -2
  375. package/scripts/overrides/lockfile-overrides.ts +1 -1
  376. package/scripts/overrides/overrides-logic.ts +1 -1
  377. package/scripts/package/package-scout-cli.ts +2 -7
  378. package/scripts/package/package-scout.ts +0 -2
  379. package/scripts/propagate/propagate-git-failure.ts +0 -1
  380. package/scripts/propagate/propagate-git.ts +0 -2
  381. package/scripts/propagate/propagate-plan.ts +185 -0
  382. package/scripts/propagate/propagate-publish.ts +2 -3
  383. package/scripts/propagate/propagate-run.ts +5 -3
  384. package/scripts/propagate/propagate-steps.ts +19 -6
  385. package/scripts/propagate/propagate-targets.ts +13 -6
  386. package/scripts/propagate/propagate.ts +60 -46
  387. package/scripts/refactor/import-graph.ts +0 -1
  388. package/scripts/refactor/refactor-lint.ts +0 -2
  389. package/scripts/refactor/refactor-scan.ts +0 -1
  390. package/scripts/refactor/refactor-targets.ts +0 -1
  391. package/scripts/registry-migration/migrate-logic.ts +1 -2
  392. package/scripts/registry-migration/migrate.ts +19 -9
  393. package/scripts/release/github-release-cli.ts +8 -6
  394. package/scripts/release/github-release-environment.ts +46 -0
  395. package/scripts/release/github-release.ts +151 -94
  396. package/scripts/release/release-history.ts +0 -1
  397. package/scripts/release/release-plan.ts +0 -1
  398. package/scripts/release/release-publish.ts +2 -3
  399. package/scripts/release/release-scope-cli.ts +1 -2
  400. package/scripts/release/release-tag.ts +2 -4
  401. package/scripts/repo/auto-merge-setting-logic.ts +1 -4
  402. package/scripts/repo/repo-setting.ts +1 -1
  403. package/scripts/repo/repository-labels.ts +3 -3
  404. package/scripts/repo/required-checks-logic.ts +206 -0
  405. package/scripts/repo/required-checks-report.ts +71 -0
  406. package/scripts/repo/ruleset-check-cli.ts +53 -0
  407. package/scripts/repo/ruleset-check.ts +147 -0
  408. package/scripts/report/report-lint-cli.ts +0 -4
  409. package/scripts/review/disposition-cli.ts +1 -1
  410. package/scripts/review/live-evidence.ts +1 -1
  411. package/scripts/review/review-attest-cli.ts +0 -6
  412. package/scripts/review/review-attest.ts +48 -16
  413. package/scripts/review/review-brief-cli.ts +72 -8
  414. package/scripts/review/review-brief.ts +67 -9
  415. package/scripts/review/review-diff-parts.ts +89 -0
  416. package/scripts/review/review-diff-write.ts +97 -0
  417. package/scripts/review/review-finding-ledger.ts +0 -1
  418. package/scripts/review/review-record-cli.ts +1 -1
  419. package/scripts/review/review-record.ts +0 -1
  420. package/scripts/review/review-round2-cli.ts +1 -1
  421. package/scripts/review/review-stamps.ts +6 -2
  422. package/scripts/review/review-tree.ts +14 -2
  423. package/scripts/rules/decision-oracle-stage.ts +18 -0
  424. package/scripts/rules/decision-oracle.ts +10 -7
  425. package/scripts/rules/delivered-rules.ts +9 -1
  426. package/scripts/rules/destructive-command.ts +119 -0
  427. package/scripts/rules/direct-filing.ts +1 -1
  428. package/scripts/rules/file-body.ts +0 -3
  429. package/scripts/rules/filing-cap.ts +0 -2
  430. package/scripts/rules/gh-api.ts +7 -2
  431. package/scripts/rules/git-argv.ts +18 -7
  432. package/scripts/rules/git-force.ts +0 -2
  433. package/scripts/rules/implementation-cut.ts +1 -2
  434. package/scripts/rules/index-guard.ts +71 -0
  435. package/scripts/rules/issue-citation.ts +50 -25
  436. package/scripts/rules/issue-fold.ts +1 -2
  437. package/scripts/rules/lane-background.ts +15 -7
  438. package/scripts/rules/lane-carry-conflict.ts +1 -2
  439. package/scripts/rules/lane-park.ts +14 -8
  440. package/scripts/rules/last-prompt.ts +1 -0
  441. package/scripts/rules/oracle-consulted.ts +1 -1
  442. package/scripts/rules/oracle-firing.ts +1 -0
  443. package/scripts/rules/oracle-list-cli.ts +0 -3
  444. package/scripts/rules/permission-guards.ts +14 -0
  445. package/scripts/rules/pre-gate-cut.ts +2 -2
  446. package/scripts/rules/protected-files.ts +74 -0
  447. package/scripts/rules/reply-language.ts +1 -1
  448. package/scripts/rules/rule-body-guard.ts +0 -3
  449. package/scripts/rules/rule-value-cli.ts +0 -1
  450. package/scripts/rules/shell-body-trigger.ts +0 -1
  451. package/scripts/rules/shell-segments.ts +0 -1
  452. package/scripts/rules/stop-rules.ts +13 -5
  453. package/scripts/rules/tail-commands.ts +1 -1
  454. package/scripts/rules/test-declared-commit.ts +1 -1
  455. package/scripts/rules/third-party-write.ts +0 -1
  456. package/scripts/rules/worktree-guard.ts +26 -9
  457. package/scripts/run/run-carry-cli.ts +0 -2
  458. package/scripts/run/run-carry-stash.ts +2 -2
  459. package/scripts/run/run-carry-streak.ts +1 -1
  460. package/scripts/run/run-cut-cli.ts +0 -7
  461. package/scripts/run/run-cut.ts +8 -54
  462. package/scripts/run/run-ending-cli.ts +1 -1
  463. package/scripts/run/run-ending.ts +1 -4
  464. package/scripts/run/run-entry-cli.ts +101 -24
  465. package/scripts/run/run-entry.ts +0 -1
  466. package/scripts/run/run-event-cli.ts +0 -2
  467. package/scripts/run/run-event-follow.ts +1 -0
  468. package/scripts/run/run-event-render.ts +1 -1
  469. package/scripts/run/run-event-scope.ts +53 -4
  470. package/scripts/run/run-event-stream.ts +0 -3
  471. package/scripts/run/run-event-watch.ts +1 -0
  472. package/scripts/run/run-halfrun-resume.ts +20 -7
  473. package/scripts/run/run-headless.ts +24 -8
  474. package/scripts/run/run-hold-cli.ts +33 -10
  475. package/scripts/run/run-hold.ts +25 -5
  476. package/scripts/run/run-issue-number.ts +1 -1
  477. package/scripts/run/run-liveness-cli.ts +1 -1
  478. package/scripts/run/run-liveness.ts +2 -3
  479. package/scripts/run/run-merge-cli.ts +5 -13
  480. package/scripts/run/run-merge-steps.ts +5 -5
  481. package/scripts/run/run-merge.ts +1 -1
  482. package/scripts/run/run-next-cli.ts +1 -1
  483. package/scripts/run/run-parent-cut-hook.ts +143 -0
  484. package/scripts/run/run-preflight.ts +2 -9
  485. package/scripts/run/run-prep-cli.ts +2 -2
  486. package/scripts/run/run-prep-locate.ts +1 -1
  487. package/scripts/run/run-progress-cli.ts +4 -7
  488. package/scripts/run/run-progress-clock.ts +6 -34
  489. package/scripts/run/run-progress-config.ts +0 -4
  490. package/scripts/run/run-progress-read.ts +3 -3
  491. package/scripts/run/run-progress.ts +22 -10
  492. package/scripts/run/run-prrun-resume.ts +117 -0
  493. package/scripts/run/run-report-cli.ts +1 -2
  494. package/scripts/run/run-report.ts +0 -1
  495. package/scripts/run/run-retrospective.ts +1 -1
  496. package/scripts/run/run-review-cli.ts +0 -3
  497. package/scripts/run/run-review-steps.ts +2 -0
  498. package/scripts/run/run-review.ts +0 -2
  499. package/scripts/run/run-ship-cli.ts +27 -77
  500. package/scripts/run/run-ship-detach.ts +1 -0
  501. package/scripts/run/run-ship-next.ts +106 -0
  502. package/scripts/run/run-ship-preflight.ts +87 -0
  503. package/scripts/run/run-ship-return.ts +8 -3
  504. package/scripts/run/run-ship-review-steps.ts +23 -30
  505. package/scripts/run/run-ship-review.ts +20 -0
  506. package/scripts/run/run-ship-scoped.ts +45 -0
  507. package/scripts/run/run-ship-stage.ts +5 -1
  508. package/scripts/run/run-ship-steps.ts +105 -0
  509. package/scripts/run/run-ship.ts +2 -1
  510. package/scripts/run/run-stage-read.ts +62 -0
  511. package/scripts/run/run-stage.ts +160 -0
  512. package/scripts/run/run-status-cli.ts +1 -1
  513. package/scripts/run/run-step-cli.ts +21 -14
  514. package/scripts/run/run-step.ts +1 -1
  515. package/scripts/run/run-stop-notify.ts +1 -3
  516. package/scripts/run/run-stranded-cli.ts +0 -4
  517. package/scripts/run/run-stranded-detect.ts +2 -2
  518. package/scripts/run/run-tail-cli.ts +17 -11
  519. package/scripts/run/run-tail.ts +2 -0
  520. package/scripts/run/run-tidy-lanes.ts +2 -1
  521. package/scripts/run/run-tidy-stashes.ts +12 -12
  522. package/scripts/run/run-wake-cli.ts +4 -5
  523. package/scripts/run/run-wake-describe.ts +19 -1
  524. package/scripts/run/run-wake-loop.ts +2 -2
  525. package/scripts/run/run-wake.ts +2 -4
  526. package/scripts/run/run-watcher-guard-cli.ts +0 -4
  527. package/scripts/run/run-watcher-guard.ts +9 -7
  528. package/scripts/run/run-watcher-hook.ts +1 -1
  529. package/scripts/safe-chain/ci-installer-pin.ts +11 -5
  530. package/scripts/safe-chain/project-config.ts +1 -1
  531. package/scripts/security/security-audit-provision-logic.ts +0 -1
  532. package/scripts/security/security-audit-provision.ts +3 -2
  533. package/scripts/security/security-audit.ts +0 -1
  534. package/scripts/security/security-updates-logic.ts +0 -1
  535. package/scripts/sonar/sonar-hotspots-cli.ts +10 -52
  536. package/scripts/sonar/sonar-hotspots.ts +0 -1
  537. package/scripts/sonar/sonar-new-code-cli.ts +150 -0
  538. package/scripts/sonar/sonar-new-code.ts +79 -0
  539. package/scripts/sonar/sonar-project.ts +97 -0
  540. package/scripts/split/split-assess-cli.ts +1 -1
  541. package/scripts/split/split-assess.ts +2 -5
  542. package/scripts/sync/managed-config-scope-cli.ts +1 -1
  543. package/scripts/sync/skill-migration.ts +0 -1
  544. package/scripts/sync/sync-hook-safety.ts +2 -3
  545. package/scripts/sync/sync.ts +1 -8
  546. package/scripts/sync/template-source-logic.ts +0 -1
  547. package/scripts/sync/workflow-pin-logic.ts +16 -28
  548. package/scripts/test/test-declared-logic.ts +0 -1
  549. package/scripts/test/test-declared.ts +0 -2
  550. package/scripts/test/test-red-commit.ts +2 -2
  551. package/scripts/test/test-red.ts +14 -7
  552. package/scripts/test/test-type-logic.ts +1 -1
  553. package/scripts/test/unit-worker-share.ts +7 -16
  554. package/scripts/time-runtime/time-batch-guard.ts +1 -2
  555. package/scripts/time-runtime/time-bundle-call.ts +2 -3
  556. package/scripts/time-runtime/time-bundles.ts +0 -4
  557. package/scripts/time-runtime/time-density-hook.ts +0 -2
  558. package/scripts/time-runtime/time-followup-stage.ts +1 -1
  559. package/scripts/time-runtime/time-format.ts +0 -73
  560. package/scripts/time-runtime/time-round-trips.ts +0 -4
  561. package/scripts/time-runtime/time-single-check.ts +1 -1
  562. package/scripts/time-runtime/time-spans.ts +1 -1
  563. package/scripts/time-runtime/time-transcript-line.ts +1 -2
  564. package/scripts/ui/ui-routes-cli.ts +0 -5
  565. package/scripts/ui/ui-routes.ts +0 -5
  566. package/scripts/version/effective-upstream.ts +2 -2
  567. package/scripts/version/latest-corepack.ts +7 -9
  568. package/scripts/version/latest-scope-cli.ts +0 -2
  569. package/scripts/version/latest-update.ts +0 -2
  570. package/scripts/version/npm-registry.ts +97 -0
  571. package/scripts/version/publishable-range-check.ts +1 -1
  572. package/scripts/version/release-hold.ts +0 -4
  573. package/scripts/version/running-binary.ts +2 -2
  574. package/scripts/version/version-check-logic.ts +0 -2
  575. package/scripts/version/version-commands.ts +5 -4
  576. package/scripts/version/version-remote.ts +28 -14
  577. package/scripts/version/version-targets.ts +4 -4
  578. package/templates/sonar-project.properties +28 -1
  579. package/templates/workflows/dependabot-auto-merge.yml +5 -3
  580. package/templates/workflows/github-release.yml +81 -0
  581. package/prompts/collaboration-workflow/cross-repo-epic.md +0 -5
  582. package/prompts/collaboration-workflow/epic-audit.md +0 -5
  583. package/prompts/collaboration-workflow/epic-bundle.md +0 -5
  584. package/scripts/init/plugin-install-hint.ts +0 -47
  585. package/scripts/version/parse-json.ts +0 -13
  586. /package/scripts/{git → followup}/git-followup-stages.ts +0 -0
  587. /package/scripts/{git → gh}/git-gh-api-path.ts +0 -0
  588. /package/scripts/{git → gh}/git-gh-command.ts +0 -0
  589. /package/scripts/{git → gh}/git-gh-issue-write.ts +0 -0
  590. /package/scripts/{git → gh}/git-gh-issue.ts +0 -0
  591. /package/scripts/{git → gh}/git-gh-pr-auto-merge.ts +0 -0
  592. /package/scripts/{git → gh}/git-gh-pr-snapshot.ts +0 -0
  593. /package/scripts/{git → gh}/git-gh-reachability.ts +0 -0
  594. /package/scripts/{git → gh}/git-gh-repo.ts +0 -0
  595. /package/scripts/{git → gh}/git-gh-rest-state.ts +0 -0
  596. /package/scripts/{git → gh}/git-pr-checks-watch.ts +0 -0
  597. /package/scripts/{git → gh}/git-pr-error.ts +0 -0
  598. /package/scripts/{git → gh}/git-pr-messages.ts +0 -0
  599. /package/scripts/{git → gh}/github-issue-url.ts +0 -0
  600. /package/scripts/git/{stash-orphans.ts → stash/stash-orphans.ts} +0 -0
  601. /package/scripts/{git → issue}/issue-reference.ts +0 -0
  602. /package/scripts/{git → lib}/animation-helpers.ts +0 -0
  603. /package/scripts/{git → lib}/git-animation.ts +0 -0
  604. /package/scripts/{git → notify}/git-notify.ts +0 -0
  605. /package/scripts/{git → notify}/telegram-test-logic.ts +0 -0
@@ -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
@@ -418,7 +418,7 @@ async function push(): Promise<void> {
418
418
  // has diverged is a state to fail loudly on rather than to grow a merge commit over. The name says
419
419
  // which of the two this is, as `merge_fast_forward` does beside `merge_branch`.
420
420
  async function pull_fast_forward(): Promise<void> {
421
- await git_spawn.with_output('pull', ['--ff-only'])
421
+ await git_spawn.with_output_remote('pull', ['--ff-only'])
422
422
  }
423
423
 
424
424
  // Every local branch matching a `git branch --list` pattern, one name per line. The boolean below is
@@ -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> {
@@ -1,46 +1,102 @@
1
1
  import { execFileSync } from 'node:child_process'
2
2
  import { git_utilities } from './constants'
3
3
  import { git_command } from './git-command'
4
+ import { git_location_environment, GIT_LOCATION_VARIABLES } from './git-location-environment'
5
+
6
+ // The one synchronous read of a checkout's two git directories (joshuafolkken/kit#2986) — the same
7
+ // `GIT_DIRECTORY_ARGUMENTS` `git_command.git_directories` asks asynchronously, so the two spellings
8
+ // cannot name different directories. It had been run in three places with three timeouts and no
9
+ // memory of the answer, though a `PreToolUse` hook may ask it several times in one call.
4
10
 
5
11
  const OWN_GIT_DIRECTORY = 0
6
12
  const COMMON_GIT_DIRECTORY = 1
7
- const PROBE_TIMEOUT_MS = 2000
13
+ // The read runs inside `PreToolUse` hooks, which hold the tool call for as long as it takes;
14
+ // `rev-parse` takes no lock, so anything past a few seconds is a fault rather than slow work.
15
+ const PROBE_TIMEOUT_MS = 5000
16
+
17
+ // **Only an answer is remembered, never a failure** — a timeout or a directory that is not yet a
18
+ // repository is asked again next time. The key carries every input git resolves from: the directory
19
+ // asked about and, where the environment is inherited, the git location variables it holds.
20
+ const answers = new Map<string, ReadonlyArray<string>>()
8
21
 
9
- function read_directories(cwd: string): Array<string> {
10
- const git = git_utilities.get_git_command_for_spawn()
11
- const output = execFileSync(git, [...git_command.GIT_DIRECTORY_ARGUMENTS], {
12
- cwd,
13
- encoding: 'utf8',
14
- stdio: ['ignore', 'pipe', 'ignore'],
15
- timeout: PROBE_TIMEOUT_MS,
16
- })
22
+ // With an explicit `cwd`, the git location variables are cleared so that directory is what git answers
23
+ // for: a hook exports `GIT_DIR`, which beats `cwd` and would name the hook's checkout instead
24
+ // (joshuafolkken/kit#2515). Without one the environment is kept, so the read resolves the same
25
+ // checkout as the asynchronous `git_directories`.
26
+ function probe_environment(cwd: string | undefined): NodeJS.ProcessEnv {
27
+ if (cwd === undefined) return process.env
17
28
 
18
- return output.trim().split('\n')
29
+ return { ...process.env, ...git_location_environment.location_free_environment() }
19
30
  }
20
31
 
21
- function select_linked(directories: ReadonlyArray<string>): string | undefined {
22
- const own = directories[OWN_GIT_DIRECTORY]
23
- const common = directories[COMMON_GIT_DIRECTORY]
32
+ function cache_key(cwd: string | undefined): string {
33
+ if (cwd !== undefined) return `explicit\0${cwd}`
34
+
35
+ const locations = GIT_LOCATION_VARIABLES.map((name) => process.env[name] ?? '')
24
36
 
25
- return own !== undefined && common !== undefined && own !== common ? common : undefined
37
+ return ['inherited', process.cwd(), ...locations].join('\0')
26
38
  }
27
39
 
28
- function resolve(cwd: string): string | undefined {
40
+ // git's own diagnostics are discarded: a checkout it cannot describe is already the empty answer, and
41
+ // a hook that let `fatal: not a git repository` through would print it in front of a tool call. The
42
+ // binary is resolved through `git_utilities` exactly as `git-spawn.ts` resolves it and run with an
43
+ // argument array and no `shell`; both are internally controlled, never untrusted input.
44
+ function read_directories(cwd: string | undefined): ReadonlyArray<string> {
29
45
  try {
30
- return select_linked(read_directories(cwd))
46
+ const output = execFileSync(
47
+ git_utilities.get_git_command_for_spawn(),
48
+ [...git_command.GIT_DIRECTORY_ARGUMENTS],
49
+ {
50
+ cwd,
51
+ env: probe_environment(cwd),
52
+ encoding: 'utf8',
53
+ stdio: ['ignore', 'pipe', 'ignore'],
54
+ timeout: PROBE_TIMEOUT_MS,
55
+ },
56
+ ) // NOSONAR
57
+
58
+ return output.split('\n').filter((line) => line !== '')
31
59
  } catch {
32
- return undefined
60
+ return []
33
61
  }
34
62
  }
35
63
 
36
- function repository(cwd: string): string | undefined {
37
- try {
38
- return read_directories(cwd)[COMMON_GIT_DIRECTORY]
39
- } catch {
40
- return undefined
41
- }
64
+ // The work tree's own git directory, then the common one every work tree of the repository shares —
65
+ // or nothing, where git cannot describe the checkout.
66
+ function directories(cwd?: string): ReadonlyArray<string> {
67
+ const key = cache_key(cwd)
68
+ const known = answers.get(key)
69
+
70
+ if (known !== undefined) return known
71
+
72
+ const read = read_directories(cwd)
73
+
74
+ if (read.length > 0) answers.set(key, read)
75
+
76
+ return read
77
+ }
78
+
79
+ function own(cwd?: string): string | undefined {
80
+ return directories(cwd)[OWN_GIT_DIRECTORY]
81
+ }
82
+
83
+ function repository(cwd?: string): string | undefined {
84
+ return directories(cwd)[COMMON_GIT_DIRECTORY]
85
+ }
86
+
87
+ function select_linked(found: ReadonlyArray<string>): string | undefined {
88
+ const own_directory = found[OWN_GIT_DIRECTORY]
89
+ const common = found[COMMON_GIT_DIRECTORY]
90
+
91
+ return own_directory !== undefined && common !== undefined && own_directory !== common
92
+ ? common
93
+ : undefined
94
+ }
95
+
96
+ function resolve(cwd: string): string | undefined {
97
+ return select_linked(directories(cwd))
42
98
  }
43
99
 
44
- const git_common_directory = { repository, resolve, select_linked }
100
+ const git_common_directory = { directories, own, repository, resolve, select_linked }
45
101
 
46
102
  export { git_common_directory }
@@ -1,5 +1,5 @@
1
+ import { has_stderr_field } from '#scripts/gh/git-gh-exec'
1
2
  import { error_text } from '#scripts/lib/error-message'
2
- import { has_stderr_field } from './git-gh-exec'
3
3
 
4
4
  function get_stderr_from_error(cause: Error): string | undefined {
5
5
  if (!has_stderr_field(cause)) return undefined
@@ -42,7 +42,41 @@ function display_error_details(cause: unknown): void {
42
42
  console.error('💡 Details:', cause_message)
43
43
  }
44
44
 
45
- function handle(error: unknown): void {
45
+ const FAILURE_EXIT_CODE = 1
46
+ const OPERATION_CANCELLED_MESSAGE = '💡 Operation cancelled.'
47
+
48
+ // **A library refuses by throwing; only the CLI entry decides the exit code** (joshuafolkken/kit#2985).
49
+ // `process.exit()` from an imported module skips every `finally` above it (a lock release included)
50
+ // and truncates a piped stdout, so these modules throw a typed error instead, and `handle` — the catch
51
+ // at each entry — renders it and sets `process.exitCode`.
52
+ interface BranchMismatch {
53
+ current_branch: string
54
+ target_branch_name: string
55
+ }
56
+
57
+ class BranchMismatchError extends Error {
58
+ readonly current_branch: string
59
+ readonly target_branch_name: string
60
+
61
+ constructor(mismatch: BranchMismatch, options?: ErrorOptions) {
62
+ super(
63
+ `Branch mismatch: on ${mismatch.current_branch}, expected ${mismatch.target_branch_name}`,
64
+ options,
65
+ )
66
+ this.name = 'BranchMismatchError'
67
+ this.current_branch = mismatch.current_branch
68
+ this.target_branch_name = mismatch.target_branch_name
69
+ }
70
+ }
71
+
72
+ class OperationCancelledError extends Error {
73
+ constructor() {
74
+ super('Operation cancelled')
75
+ this.name = 'OperationCancelledError'
76
+ }
77
+ }
78
+
79
+ function display_failure(error: unknown): void {
46
80
  const error_message = error_text.message_of(error)
47
81
 
48
82
  console.error('')
@@ -53,23 +87,46 @@ function handle(error: unknown): void {
53
87
  }
54
88
 
55
89
  console.error('')
56
- process.exit(1)
57
90
  }
58
91
 
59
- function display_branch_mismatch_error(current_branch: string, target_branch_name: string): void {
92
+ function display_branch_mismatch(error: BranchMismatchError): void {
60
93
  console.error('')
61
94
  console.error('❌ Branch mismatch detected')
62
95
  console.error('')
63
- console.error(`Current branch: ${current_branch}`)
64
- console.error(`Expected branch: ${target_branch_name}`)
96
+ console.error(`Current branch: ${error.current_branch}`)
97
+ console.error(`Expected branch: ${error.target_branch_name}`)
65
98
  console.error('')
66
99
  console.error('💡 Please update main branch to the latest and try again.')
67
- process.exit(1)
100
+ }
101
+
102
+ function display_cancelled(): void {
103
+ console.info(OPERATION_CANCELLED_MESSAGE)
104
+ console.info('')
105
+ }
106
+
107
+ function display(error: unknown): void {
108
+ if (error instanceof BranchMismatchError) {
109
+ display_branch_mismatch(error)
110
+
111
+ return
112
+ }
113
+
114
+ if (error instanceof OperationCancelledError) {
115
+ display_cancelled()
116
+
117
+ return
118
+ }
119
+
120
+ display_failure(error)
121
+ }
122
+
123
+ function handle(error: unknown): void {
124
+ display(error)
125
+ process.exitCode = FAILURE_EXIT_CODE
68
126
  }
69
127
 
70
128
  const git_error = {
71
129
  handle,
72
- display_branch_mismatch_error,
73
130
  }
74
131
 
75
- export { git_error }
132
+ export { git_error, BranchMismatchError, OperationCancelledError }
@@ -22,6 +22,11 @@ function has_timed_out(error: unknown): boolean {
22
22
  return error.timedOut === true
23
23
  }
24
24
 
25
+ // A timeout has no exit code — the process was killed rather than allowed to exit — so `cause` says
26
+ // so in the slot every other git failure puts a number in. Shared by every git spawn that carries a
27
+ // budget: the push (`git-push-transport.ts`) and the fetch and pull (`git-spawn.ts`).
28
+ const TIMEOUT_EXIT_CODE = 'timeout'
29
+
25
30
  // The error a spawned git command fails with. The exit code is carried on `cause` as well as in the
26
31
  // message, because callers branch on it rather than parse it: `git_command.push` reads 128 there to
27
32
  // decide whether to retry with `--set-upstream`.
@@ -32,4 +37,4 @@ function create_spawn_error(command: string, exit_code: number | undefined): Err
32
37
  return new Error(error_message, { cause: { exit_code: exit_code_string } })
33
38
  }
34
39
 
35
- export { create_spawn_error, get_exit_code, has_timed_out }
40
+ export { create_spawn_error, get_exit_code, has_timed_out, TIMEOUT_EXIT_CODE }
@@ -1,6 +1,6 @@
1
+ import { git_gh_issue_read } from '#scripts/gh/git-gh-issue-read'
1
2
  import { lane_paths } from '#scripts/lane/lane-paths'
2
3
  import { SEPARATOR_LINE } from './constants'
3
- import { git_gh_issue_read } from './git-gh-issue-read'
4
4
  import { git_prompt } from './git-prompt'
5
5
 
6
6
  interface IssueInfo {
@@ -1,11 +1,11 @@
1
+ import { git_gh_command } from '#scripts/gh/git-gh-command'
2
+ import { git_pr } from '#scripts/gh/git-pr'
1
3
  import { error_text } from '#scripts/lib/error-message'
2
4
  import { live_evidence } from '#scripts/review/live-evidence'
3
5
  import { changed_paths } from './changed-paths'
4
6
  import { git_branch } from './git-branch'
5
7
  import { git_command } from './git-command'
6
- import { git_gh_command } from './git-gh-command'
7
8
  import { git_issue, type IssueInfo } from './git-issue'
8
- import { git_pr } from './git-pr'
9
9
 
10
10
  // joshuafolkken/kit#2817. A first `josh git -y` was refused once per unmet precondition — the title's
11
11
  // issue number, the branch name, the issue's release classification — each only after the stage
@@ -117,19 +117,37 @@ function refusal(problems: ReadonlyArray<string>): Error {
117
117
  )
118
118
  }
119
119
 
120
- async function check(input: PreflightInput): Promise<void> {
120
+ interface PreflightAnswer {
121
+ pr_target: Target | undefined
122
+ problems: Array<string>
123
+ }
124
+
125
+ async function answer(input: PreflightInput): Promise<PreflightAnswer> {
121
126
  const { target, problems } = await resolve_target(input.cli_input)
122
127
  // The classification and the evidence belong to the pull request, so a `--skip-pr` run asks neither.
123
128
  const pr_target = input.will_open_pr ? target : undefined
124
129
  const pr_problems = pr_target === undefined ? [] : await classification_problems(pr_target)
125
- const all_problems = [...problems, ...pr_problems]
126
130
 
127
- if (all_problems.length > 0) throw refusal(all_problems)
131
+ return { pr_target, problems: [...problems, ...pr_problems] }
132
+ }
133
+
134
+ // joshuafolkken/kit#2946: the unmet preconditions as a list, so `josh ship` can ask them before its
135
+ // review and gate start instead of meeting the refusal at the commit stage.
136
+ async function problems_of(input: PreflightInput): Promise<Array<string>> {
137
+ const { problems } = await answer(input)
138
+
139
+ return problems
140
+ }
141
+
142
+ async function check(input: PreflightInput): Promise<void> {
143
+ const { pr_target, problems } = await answer(input)
144
+
145
+ if (problems.length > 0) throw refusal(problems)
128
146
 
129
147
  if (pr_target !== undefined) await announce_evidence(pr_target.branch_name)
130
148
  }
131
149
 
132
- const git_preflight = { check }
150
+ const git_preflight = { check, problems_of }
133
151
 
134
152
  export type { PreflightInput }
135
153
  export { git_preflight }
@@ -1,9 +1,8 @@
1
1
  import { stdin as input, stdout as output } from 'node:process'
2
2
  import { createInterface, type Interface } from 'node:readline/promises'
3
+ import { OperationCancelledError } from './git-error'
3
4
  import { git_prompt_display } from './git-prompt-display'
4
5
 
5
- const OPERATION_CANCELLED_MESSAGE = '💡 Operation cancelled.'
6
-
7
6
  const PROMPT_MESSAGES = {
8
7
  unstaged_files: '💬 Unstaged files found. Continue anyway? (y/n): ',
9
8
  package_json_not_staged: '💬 package.json is not staged. Continue anyway? (y/n): ',
@@ -85,16 +84,10 @@ async function with_prompt<T>(callback: PromptCallback<T>, fallback_value?: T):
85
84
  }
86
85
  }
87
86
 
88
- async function confirm_with_exit_on_cancel(should_continue: () => Promise<boolean>): Promise<void> {
87
+ async function confirm_or_cancel(should_continue: () => Promise<boolean>): Promise<void> {
89
88
  const is_confirmed = await should_continue()
90
89
 
91
- if (is_confirmed) {
92
- return
93
- }
94
-
95
- console.info(OPERATION_CANCELLED_MESSAGE)
96
- console.info('')
97
- process.exit(1)
90
+ if (!is_confirmed) throw new OperationCancelledError()
98
91
  }
99
92
 
100
93
  function create_confirm_function(message: string): () => Promise<boolean> {
@@ -112,11 +105,11 @@ async function confirm_without_package_json(): Promise<boolean> {
112
105
  }
113
106
 
114
107
  async function confirm_unstaged_files(): Promise<void> {
115
- await confirm_with_exit_on_cancel(confirm_continue)
108
+ await confirm_or_cancel(confirm_continue)
116
109
  }
117
110
 
118
111
  async function confirm_missing_package_json(): Promise<void> {
119
- await confirm_with_exit_on_cancel(confirm_without_package_json)
112
+ await confirm_or_cancel(confirm_without_package_json)
120
113
  }
121
114
 
122
115
  async function confirm_version_not_updated(): Promise<boolean> {
@@ -124,19 +117,7 @@ async function confirm_version_not_updated(): Promise<boolean> {
124
117
  }
125
118
 
126
119
  async function confirm_without_version_update(): Promise<void> {
127
- await confirm_with_exit_on_cancel(confirm_version_not_updated)
128
- }
129
-
130
- async function confirm_commit(): Promise<boolean> {
131
- return await create_confirm_function(PROMPT_MESSAGES.commit)()
132
- }
133
-
134
- async function confirm_push(): Promise<boolean> {
135
- return await create_confirm_function(PROMPT_MESSAGES.push)()
136
- }
137
-
138
- async function confirm_pr(): Promise<boolean> {
139
- return await create_confirm_function(PROMPT_MESSAGES.pr)()
120
+ await confirm_or_cancel(confirm_version_not_updated)
140
121
  }
141
122
 
142
123
  async function ask_issue_info(prompt: Interface, question: string): Promise<string> {
@@ -190,15 +171,9 @@ async function confirm_workflow_steps(): Promise<WorkflowConfirmations> {
190
171
  }
191
172
 
192
173
  const git_prompt = {
193
- confirm_continue,
194
174
  confirm_unstaged_files,
195
- confirm_without_package_json,
196
175
  confirm_missing_package_json,
197
- confirm_version_not_updated,
198
176
  confirm_without_version_update,
199
- confirm_commit,
200
- confirm_push,
201
- confirm_pr,
202
177
  get_issue_info,
203
178
  confirm_workflow_steps,
204
179
  }