@joshuafolkken/kit 1.1050.0 → 1.1128.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 (630) 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 +20 -12
  4. package/.claude/skills/workflow-commands/background-commands.md +36 -84
  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 +30 -33
  8. package/.claude/skills/workflow-commands/backlogrun-steps.md +12 -12
  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 +8 -6
  16. package/.claude/skills/workflow-commands/halfrun.md +19 -21
  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 +8 -16
  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/pre-gate-cut.md +4 -8
  25. package/.claude/skills/workflow-commands/prerequisite.md +1 -1
  26. package/.claude/skills/workflow-commands/prrun.md +36 -0
  27. package/.claude/skills/workflow-commands/retrospective.md +1 -1
  28. package/.claude/skills/workflow-commands/split-assessment.md +4 -18
  29. package/.claude/skills/workflow-commands/working-tree-hold.md +22 -2
  30. package/.codex/hooks.json +16 -20
  31. package/.github/actions/setup-node/action.yml +33 -0
  32. package/.github/actions/setup-pnpm/action.yml +93 -0
  33. package/.github/dependabot.yml +5 -1
  34. package/.github/workflows/auto-tag.yml +2 -3
  35. package/.github/workflows/ci.yml +31 -134
  36. package/.github/workflows/dependabot-auto-merge.yml +1 -0
  37. package/.github/workflows/pr-classification.yml +6 -44
  38. package/.github/workflows/production.yml +1 -0
  39. package/.github/workflows/publish.yml +43 -47
  40. package/.github/workflows/sonar-qube.yml +41 -4
  41. package/.pnpmfile.mjs +29 -0
  42. package/AGENTS.md +5 -2
  43. package/CLAUDE.md +33 -27
  44. package/GEMINI.md +5 -2
  45. package/README.md +66 -20
  46. package/SECURITY.md +37 -6
  47. package/cspell/index.yaml +6 -1
  48. package/dist/CLAUDE.basic.md +6 -6
  49. package/dist/CLAUDE.md +33 -27
  50. package/dist/CLAUDE.static.md +6 -6
  51. package/dist/config-merge/index.js +48 -12
  52. package/dist/hooks/batch-guard.js +4 -4
  53. package/dist/hooks/{chunk-7VPDUBRN.js → chunk-4JZDP5X5.js} +152 -155
  54. package/dist/hooks/{chunk-HJIISEAC.js → chunk-5SD2YM7Z.js} +5 -13
  55. package/dist/hooks/{chunk-NAS4C7GP.js → chunk-77J7IEQM.js} +2 -2
  56. package/dist/hooks/{chunk-DMQN45FN.js → chunk-7HVB7SZG.js} +3 -3
  57. package/dist/hooks/{chunk-RLDX5SOC.js → chunk-AIOIOMPX.js} +4413 -1970
  58. package/dist/hooks/{chunk-5BK3K7V4.js → chunk-M7QKEKWO.js} +873 -2049
  59. package/dist/hooks/{chunk-WQ4OSBSS.js → chunk-MKVGBQPA.js} +2 -2
  60. package/dist/hooks/{chunk-EJDX2TOB.js → chunk-NXYMNPUQ.js} +7 -88
  61. package/dist/hooks/{chunk-NJQOBE6L.js → chunk-QVLT52OV.js} +2 -7
  62. package/dist/hooks/{chunk-GQ7KP45M.js → chunk-XYUIQOW3.js} +2 -2
  63. package/dist/hooks/codex-hook-adapter.js +12 -48
  64. package/dist/hooks/duplicate-read-guard.js +5 -5
  65. package/dist/hooks/format-edited.js +2 -2
  66. package/dist/hooks/inputs.json +280 -0
  67. package/dist/hooks/investigation-guard.js +5 -5
  68. package/dist/hooks/pretool-guard.js +9 -9
  69. package/dist/hooks/session-lang.js +0 -1
  70. package/dist/hooks/stop-guard.js +192 -333
  71. package/dist/josh.js +240 -148
  72. package/dist/managed-marker/index.js +2 -1
  73. package/dist/version/index.js +70 -78
  74. package/eslint/rules/promise.js +5 -0
  75. package/eslint/rules/unicorn.js +3 -2
  76. package/package.json +26 -5
  77. package/pnpm-workspace.yaml +5 -7
  78. package/prompts/collaboration-workflow/glossary.md +17 -0
  79. package/prompts/collaboration-workflow/issue-citation.md +5 -5
  80. package/prompts/collaboration-workflow/issue-template.md +1 -1
  81. package/prompts/collaboration-workflow/operating-rules.md +5 -5
  82. package/prompts/collaboration-workflow/overview.md +13 -1
  83. package/prompts/collaboration-workflow/principles.md +9 -0
  84. package/prompts/collaboration-workflow/report-format.md +1 -1
  85. package/prompts/collaboration-workflow/residency.md +3 -3
  86. package/prompts/collaboration-workflow/rule-delivery.md +1 -1
  87. package/prompts/collaboration-workflow/turn-batching.md +3 -3
  88. package/prompts/collaboration-workflow/upstream-interrupt.md +1 -1
  89. package/prompts/collaboration-workflow/wip-cap.md +25 -22
  90. package/prompts/collaboration-workflow.md +6 -8
  91. package/prompts/review-rubric.md +1 -1
  92. package/prompts/review.md +3 -3
  93. package/prompts/sonar-hotspot-handling.md +11 -3
  94. package/prompts/testing-guide.md +3 -3
  95. package/scripts/adopt/adopt-toolkits.ts +0 -2
  96. package/scripts/adopt/adopt.ts +0 -2
  97. package/scripts/agent/agent-argv.ts +0 -2
  98. package/scripts/agent/agent-diagnostics.ts +1 -1
  99. package/scripts/agent/agent-role-profile.ts +0 -7
  100. package/scripts/agent/claude-agent-argv.ts +0 -2
  101. package/scripts/agent/codex-agent-argv.ts +1 -1
  102. package/scripts/agent/codex-hooks.ts +92 -0
  103. package/scripts/agent/interactive-ask.ts +1 -1
  104. package/scripts/auto-ok/auto-ok-cli.ts +6 -16
  105. package/scripts/backlog/backlog-arrival.ts +30 -10
  106. package/scripts/backlog/backlog-budget-cli.ts +15 -16
  107. package/scripts/backlog/backlog-budget.ts +0 -2
  108. package/scripts/backlog/backlog-defect-priority.ts +2 -2
  109. package/scripts/backlog/backlog-drive-cli.ts +10 -8
  110. package/scripts/backlog/backlog-drive-named-offer.ts +16 -3
  111. package/scripts/backlog/backlog-drive-named.ts +2 -1
  112. package/scripts/backlog/backlog-drive.ts +76 -16
  113. package/scripts/backlog/backlog-named.ts +0 -3
  114. package/scripts/backlog/backlog-next.ts +9 -15
  115. package/scripts/backlog/backlog-offer-cli.ts +6 -19
  116. package/scripts/backlog/backlog-plan-cli.ts +1 -7
  117. package/scripts/backlog/backlog-plan.ts +30 -19
  118. package/scripts/backlog/backlog-pool.ts +3 -6
  119. package/scripts/backlog/backlog-rank.ts +2 -2
  120. package/scripts/backlog/backlog-ready.ts +39 -10
  121. package/scripts/backlog/backlog-scope.ts +1 -3
  122. package/scripts/backlog/backlog-stalled-detect.ts +2 -2
  123. package/scripts/backlog/backlog-stalled.ts +0 -1
  124. package/scripts/backlog/backlog-waves.ts +5 -2
  125. package/scripts/behavior/behavior-cli.ts +1 -1
  126. package/scripts/build/build-codex-hooks.ts +26 -0
  127. package/scripts/build/build-hooks.ts +85 -9
  128. package/scripts/build/hook-bundle-stamp.ts +111 -0
  129. package/scripts/cases/cases-cli.ts +1 -1
  130. package/scripts/cases/cases-logic.ts +1 -1
  131. package/scripts/ci/composite-actions.ts +30 -0
  132. package/scripts/ci/pr-classification.ts +3 -3
  133. package/scripts/claude/workflow-destination.ts +10 -1
  134. package/scripts/clone/clone-fingerprint.ts +0 -1
  135. package/scripts/clone/clone-scan-cli.ts +1 -1
  136. package/scripts/clone/clone-scan.ts +1 -1
  137. package/scripts/config-merge/json-format.ts +0 -1
  138. package/scripts/config-merge/parse-jsonc.ts +33 -3
  139. package/scripts/config-merge/patch-json-key.ts +13 -6
  140. package/scripts/config-merge/patch-yaml-list.ts +1 -1
  141. package/scripts/cost-runtime/codex-usage.ts +2 -9
  142. package/scripts/cost-runtime/cost-attribute.ts +0 -1
  143. package/scripts/cost-runtime/cost-cli.ts +3 -10
  144. package/scripts/cost-runtime/cost-corpus.ts +0 -2
  145. package/scripts/cost-runtime/cost-format.ts +0 -3
  146. package/scripts/cost-runtime/cost-pricing.ts +0 -1
  147. package/scripts/cost-runtime/cost-tokens.ts +0 -1
  148. package/scripts/delegation/delegation-cli.ts +1 -1
  149. package/scripts/delegation/delegation-policy.ts +0 -1
  150. package/scripts/delegation/duplicate-read-guard.ts +0 -8
  151. package/scripts/delegation/fanout-cli.ts +1 -1
  152. package/scripts/delegation/fanout.ts +0 -2
  153. package/scripts/delegation/investigation-reads.ts +1 -164
  154. package/scripts/discovery/repo-map-logic.ts +0 -1
  155. package/scripts/discovery/repo-party-cli.ts +1 -1
  156. package/scripts/doctor/doctor-consumer.ts +6 -10
  157. package/scripts/doctor/doctor-io.ts +9 -13
  158. package/scripts/doctor/doctor-logic.ts +0 -4
  159. package/scripts/doctor/doctor.ts +14 -9
  160. package/scripts/document/backlogrun-parent-read-set.ts +12 -1
  161. package/scripts/document/document-byte-budget.ts +5 -5
  162. package/scripts/document/document-byte-check.ts +0 -1
  163. package/scripts/document/document-read-cli.ts +0 -2
  164. package/scripts/document/document-section-cli.ts +1 -1
  165. package/scripts/document/document-section.ts +0 -3
  166. package/scripts/document/edit-files-cli.ts +0 -1
  167. package/scripts/document/entry-read-budget.ts +21 -7
  168. package/scripts/document/entry-read-set.ts +32 -8
  169. package/scripts/document/lane-child-read-set.ts +8 -6
  170. package/scripts/document/read-files-cli.ts +0 -4
  171. package/scripts/document/read-set-cli.ts +0 -2
  172. package/scripts/document/read-set-point-of-use.ts +9 -3
  173. package/scripts/document/read-set-pricing.ts +0 -1
  174. package/scripts/document/read-set-trim.ts +4 -2
  175. package/scripts/epic/epic-add.ts +1 -1
  176. package/scripts/epic/epic-audit-cli.ts +1 -4
  177. package/scripts/epic/epic-audit-orphans.ts +1 -3
  178. package/scripts/epic/epic-audit-rationale.ts +0 -1
  179. package/scripts/epic/epic-audit-report.ts +0 -2
  180. package/scripts/epic/epic-audit.ts +8 -22
  181. package/scripts/epic/epic-bundle-cli.ts +1 -1
  182. package/scripts/epic/epic-bundle-evidence.ts +0 -1
  183. package/scripts/epic/epic-bundle-referenced.ts +1 -5
  184. package/scripts/epic/epic-bundle.ts +0 -4
  185. package/scripts/epic/epic-busy.ts +4 -5
  186. package/scripts/epic/epic-candidate-confirm.ts +0 -5
  187. package/scripts/epic/epic-classify.ts +2 -2
  188. package/scripts/epic/epic-cli-argv.ts +0 -1
  189. package/scripts/epic/epic-close-comment.ts +1 -1
  190. package/scripts/epic/epic-close.ts +5 -2
  191. package/scripts/epic/epic-cross-repo.ts +2 -4
  192. package/scripts/epic/epic-decision.ts +0 -1
  193. package/scripts/epic/epic-fetch.ts +2 -2
  194. package/scripts/epic/epic-index.ts +2 -3
  195. package/scripts/epic/epic-issue.ts +1 -15
  196. package/scripts/epic/epic-lane-offer.ts +9 -8
  197. package/scripts/epic/epic-nested.ts +1 -1
  198. package/scripts/epic/epic-next-read.ts +1 -3
  199. package/scripts/epic/epic-next-views.ts +0 -1
  200. package/scripts/epic/epic-next.ts +1 -10
  201. package/scripts/epic/epic-parse.ts +0 -1
  202. package/scripts/epic/epic-promote.ts +0 -9
  203. package/scripts/epic/epic-rank.ts +2 -2
  204. package/scripts/epic/epic-read.ts +1 -2
  205. package/scripts/epic/epic-reconcile.ts +1 -1
  206. package/scripts/epic/epic-reference.ts +1 -13
  207. package/scripts/epic/epic-relation-recheck.ts +1 -1
  208. package/scripts/epic/epic-relations.ts +1 -1
  209. package/scripts/epic/epic-remove.ts +1 -1
  210. package/scripts/epic/epic-report.ts +0 -1
  211. package/scripts/epic/epic-run.ts +2 -3
  212. package/scripts/epic/epic-shape.ts +1 -1
  213. package/scripts/epic/epic-solo-stale.ts +107 -0
  214. package/scripts/epic/epic-solo.ts +3 -2
  215. package/scripts/epic/epic-triage.ts +1 -1
  216. package/scripts/epic/epic-validate.ts +1 -1
  217. package/scripts/epic/epic.ts +1 -1
  218. package/scripts/exports/unused-members-cli.ts +53 -0
  219. package/scripts/{git → followup}/followup-issue-number.ts +1 -6
  220. package/scripts/{git → followup}/git-followup-cleanup.ts +2 -1
  221. package/scripts/{git → followup}/git-followup-finish.ts +1 -3
  222. package/scripts/{git → followup}/git-followup-flush.ts +2 -2
  223. package/scripts/{git → followup}/git-followup-issue-close.ts +2 -2
  224. package/scripts/{git → followup}/git-followup-label.ts +4 -4
  225. package/scripts/followup/git-followup-merged.ts +112 -0
  226. package/scripts/{git → followup}/git-followup-pending.ts +1 -1
  227. package/scripts/{git → followup}/git-followup-workflow.ts +19 -11
  228. package/scripts/{git → followup}/git-pr-followup-wrapup.ts +9 -3
  229. package/scripts/{git → followup}/git-pr-followup.ts +53 -16
  230. package/scripts/gate/core-budget.ts +3 -9
  231. package/scripts/gate/gate-plan.ts +7 -4
  232. package/scripts/gate/gate-report.ts +0 -6
  233. package/scripts/gate/gate-tree.ts +1 -1
  234. package/scripts/gate/pre-commit-type-check.ts +0 -6
  235. package/scripts/gate/project-checks.ts +7 -8
  236. package/scripts/gate/scoped-green.ts +0 -1
  237. package/scripts/gate/type-check-step.ts +1 -1
  238. package/scripts/gate/verification-gate.ts +0 -2
  239. package/scripts/gh/fix-gh-packages.ts +15 -12
  240. package/scripts/gh/gh-spawn.ts +2 -2
  241. package/scripts/{git → gh}/git-ai-review-scan.ts +1 -5
  242. package/scripts/{git → gh}/git-gh-check.ts +2 -1
  243. package/scripts/{git → gh}/git-gh-exec.ts +1 -1
  244. package/scripts/{git → gh}/git-gh-failure.ts +1 -1
  245. package/scripts/{git → gh}/git-gh-helpers.ts +0 -1
  246. package/scripts/{git → gh}/git-gh-issue-list.ts +13 -10
  247. package/scripts/{git → gh}/git-gh-issue-read.ts +1 -1
  248. package/scripts/{git → gh}/git-gh-issue-rest.ts +6 -3
  249. package/scripts/{git → gh}/git-gh-issue-write.ts +4 -1
  250. package/scripts/{git → gh}/git-gh-pr-auto-merge.ts +4 -1
  251. package/scripts/{git → gh}/git-gh-pr-read.ts +24 -0
  252. package/scripts/{git → gh}/git-gh-pr-rest.ts +5 -2
  253. package/scripts/{git → gh}/git-gh-pr-review.ts +2 -2
  254. package/scripts/{git → gh}/git-gh-pr-rollup.ts +1 -3
  255. package/scripts/{git → gh}/git-gh-pr.ts +3 -1
  256. package/scripts/{git → gh}/git-pr-ai-review.ts +2 -5
  257. package/scripts/{git → gh}/git-pr-checks-eval.ts +0 -10
  258. package/scripts/{git → gh}/git-pr-checks-parse.ts +4 -20
  259. package/scripts/{git → gh}/git-pr-checks.ts +2 -1
  260. package/scripts/{git → gh}/git-pr-coderabbit.ts +2 -5
  261. package/scripts/{git → gh}/git-pr-confirmation.ts +1 -3
  262. package/scripts/{git → gh}/git-pr-managed-config.ts +2 -3
  263. package/scripts/{git → gh}/git-pr.ts +3 -3
  264. package/scripts/git/changed-file-scope.ts +0 -1
  265. package/scripts/git/git-branch.ts +3 -6
  266. package/scripts/git/git-command.ts +6 -1
  267. package/scripts/git/git-commit.ts +1 -1
  268. package/scripts/git/git-common-directory.ts +80 -24
  269. package/scripts/git/git-error.ts +66 -9
  270. package/scripts/git/git-issue.ts +1 -1
  271. package/scripts/git/git-preflight.ts +2 -2
  272. package/scripts/git/git-prompt.ts +6 -31
  273. package/scripts/git/git-push.ts +1 -1
  274. package/scripts/git/git-spawn-sync.ts +65 -0
  275. package/scripts/git/git-spawn.ts +5 -4
  276. package/scripts/git/git-staging.ts +1 -0
  277. package/scripts/git/git-status.ts +1 -1
  278. package/scripts/git/git-workflow.ts +1 -1
  279. package/scripts/git/gone-branch.ts +1 -0
  280. package/scripts/git/listing-cutoff.ts +1 -1
  281. package/scripts/git/main-merge.ts +1 -1
  282. package/scripts/git/main-sync.ts +19 -1
  283. package/scripts/git/parse-json-array.ts +0 -3
  284. package/scripts/git/repository-lock.ts +16 -16
  285. package/scripts/git/{git-stash.ts → stash/git-stash.ts} +1 -1
  286. package/scripts/git/{stash-pop-args.ts → stash/stash-pop-args.ts} +2 -7
  287. package/scripts/git/{stash-pop-cli.ts → stash/stash-pop-cli.ts} +0 -1
  288. package/scripts/git/{stash-sweep-lock.ts → stash/stash-sweep-lock.ts} +3 -3
  289. package/scripts/hooks/codex-hook-adapter.ts +0 -1
  290. package/scripts/hooks/edited-cspell.ts +1 -1
  291. package/scripts/hooks/format-edited-file.ts +2 -0
  292. package/scripts/hooks/pre-push-unit.ts +0 -4
  293. package/scripts/hooks/pretool-guard.ts +22 -4
  294. package/scripts/hooks/reserved-run.ts +1 -1
  295. package/scripts/hooks/step-zero-notice.ts +76 -0
  296. package/scripts/hooks/stop-guard.ts +47 -21
  297. package/scripts/init/claude-plugin-config.ts +4 -5
  298. package/scripts/init/hook-command-rewrite.ts +16 -8
  299. package/scripts/init/hook-launch.ts +41 -15
  300. package/scripts/init/init-basic.ts +2 -5
  301. package/scripts/init/init-file-action.ts +54 -0
  302. package/scripts/init/init-logic-migrate.ts +35 -17
  303. package/scripts/init/init-logic-secretlint.ts +1 -1
  304. package/scripts/init/init-logic.ts +10 -19
  305. package/scripts/init/init.ts +11 -71
  306. package/scripts/init/kit-written-paths.ts +2 -0
  307. package/scripts/init/project-profile.ts +9 -17
  308. package/scripts/init/start-exec.ts +1 -1
  309. package/scripts/init/start-setup-pr.ts +6 -6
  310. package/scripts/init/start-steps.ts +3 -1
  311. package/scripts/issue/behavior-change-lint.ts +0 -1
  312. package/scripts/issue/defect-rate-cli.ts +64 -23
  313. package/scripts/issue/defect-rate.ts +1 -2
  314. package/scripts/{git → issue}/git-next-issues.ts +3 -3
  315. package/scripts/issue/issue-backlinks-cli.ts +1 -5
  316. package/scripts/issue/issue-backlinks.ts +7 -14
  317. package/scripts/issue/issue-cite-cli.ts +2 -6
  318. package/scripts/issue/issue-cite.ts +12 -8
  319. package/scripts/issue/issue-classification.ts +1 -9
  320. package/scripts/issue/issue-closing-pr.ts +4 -4
  321. package/scripts/issue/issue-comment-cli.ts +2 -2
  322. package/scripts/issue/issue-file-cli.ts +5 -5
  323. package/scripts/issue/issue-file.ts +7 -14
  324. package/scripts/issue/issue-fold-cli.ts +1 -1
  325. package/scripts/issue/issue-fold-existing-cli.ts +1 -1
  326. package/scripts/{git → issue}/issue-labels.ts +8 -0
  327. package/scripts/issue/issue-lint-cli.ts +1 -1
  328. package/scripts/issue/issue-merged.ts +2 -2
  329. package/scripts/{git → issue}/issue-rank.ts +1 -1
  330. package/scripts/issue/issue-read-cli.ts +8 -47
  331. package/scripts/issue/issue-read.ts +0 -2
  332. package/scripts/issue/issue-report-failures.ts +80 -0
  333. package/scripts/issue/issue-scout-cli.ts +1 -7
  334. package/scripts/issue/issue-scout-closed.ts +2 -2
  335. package/scripts/issue/issue-scout.ts +0 -2
  336. package/scripts/issue/issue-state-cli.ts +5 -46
  337. package/scripts/issue/issue-state.ts +1 -5
  338. package/scripts/issue/markdown-section.ts +21 -6
  339. package/scripts/issue/measure-rerun-cli.ts +74 -15
  340. package/scripts/issue/reproduction-measure.ts +1 -1
  341. package/scripts/josh/cli-body.ts +1 -1
  342. package/scripts/josh/file-map-stamp.ts +0 -3
  343. package/scripts/josh/josh-command-map.ts +2 -0
  344. package/scripts/josh/josh-commands-ai.ts +9 -102
  345. package/scripts/josh/josh-commands-backlog.ts +5 -1
  346. package/scripts/josh/josh-commands-development.ts +8 -1
  347. package/scripts/josh/josh-commands-issue.ts +2 -2
  348. package/scripts/josh/josh-commands-maintenance.ts +7 -0
  349. package/scripts/josh/josh-commands-project.ts +7 -1
  350. package/scripts/josh/josh-commands-run.ts +114 -0
  351. package/scripts/josh/josh-commands-versioning.ts +8 -0
  352. package/scripts/josh/josh-commands-workflow.ts +3 -3
  353. package/scripts/josh/path-decision.ts +0 -3
  354. package/scripts/josh/process-owner.ts +16 -0
  355. package/scripts/josh/run-github-prerequisite.ts +3 -6
  356. package/scripts/josh/session-language-cli.ts +0 -1
  357. package/scripts/lane/lane-await.ts +46 -19
  358. package/scripts/lane/lane-capacity.ts +6 -3
  359. package/scripts/lane/lane-child-invocation.ts +20 -7
  360. package/scripts/lane/lane-cli.ts +1 -4
  361. package/scripts/lane/lane-close.ts +5 -4
  362. package/scripts/lane/lane-dispatch.ts +3 -4
  363. package/scripts/lane/lane-environment.ts +0 -9
  364. package/scripts/lane/lane-handoff.ts +38 -0
  365. package/scripts/lane/lane-launch-cli.ts +31 -27
  366. package/scripts/lane/lane-open.ts +0 -3
  367. package/scripts/lane/lane-output.ts +0 -1
  368. package/scripts/lane/lane-registry.ts +9 -0
  369. package/scripts/lane/openai-lane-ship.ts +2 -0
  370. package/scripts/lane/openai-lane-supervisor-decision.ts +2 -1
  371. package/scripts/lane/openai-lane-supervisor.ts +6 -4
  372. package/scripts/lane/openai-review-broker.ts +7 -1
  373. package/scripts/lib/bounded-pool.ts +1 -0
  374. package/scripts/lib/cli-flags.ts +31 -2
  375. package/scripts/lib/error-message.ts +12 -1
  376. package/scripts/lib/json-value.ts +5 -4
  377. package/scripts/lib/poll.ts +3 -1
  378. package/scripts/lib/timed-fetch.ts +15 -0
  379. package/scripts/lib/timeouts.ts +13 -0
  380. package/scripts/{yaml → lib}/yaml-document.ts +3 -1
  381. package/scripts/{bytes → lines}/bytes-command.ts +0 -2
  382. package/scripts/lines/line-targets.ts +0 -11
  383. package/scripts/lines/lines-command.ts +5 -4
  384. package/scripts/lint/lint-related-scope.ts +0 -1
  385. package/scripts/lint/lint-related.ts +1 -1
  386. package/scripts/{git → notify}/telegram-notify.ts +2 -2
  387. package/scripts/{git → notify}/telegram-test.ts +4 -4
  388. package/scripts/observations/observation-ledger-home.ts +0 -1
  389. package/scripts/observations/observation-ledger-line.ts +0 -1
  390. package/scripts/observations/observation-ledger-migrate.ts +1 -1
  391. package/scripts/observations/observations-flush-landing.ts +3 -3
  392. package/scripts/observations/observations-flush.ts +2 -2
  393. package/scripts/overrides/lockfile-overrides.ts +1 -1
  394. package/scripts/overrides/overrides-logic.ts +1 -1
  395. package/scripts/package/package-scout-cli.ts +2 -7
  396. package/scripts/package/package-scout.ts +0 -2
  397. package/scripts/propagate/propagate-git-failure.ts +0 -1
  398. package/scripts/propagate/propagate-git.ts +3 -10
  399. package/scripts/propagate/propagate-publish.ts +2 -3
  400. package/scripts/propagate/propagate-run.ts +0 -2
  401. package/scripts/propagate/propagate-steps.ts +3 -5
  402. package/scripts/propagate/propagate-targets.ts +0 -4
  403. package/scripts/propagate/propagate.ts +0 -4
  404. package/scripts/refactor/import-graph.ts +0 -1
  405. package/scripts/refactor/refactor-lint.ts +0 -2
  406. package/scripts/refactor/refactor-scan.ts +2 -2
  407. package/scripts/refactor/refactor-targets.ts +0 -1
  408. package/scripts/registry-migration/migrate-logic.ts +28 -21
  409. package/scripts/registry-migration/migrate.ts +25 -14
  410. package/scripts/release/github-release-cli.ts +19 -6
  411. package/scripts/release/github-release-environment.ts +46 -0
  412. package/scripts/release/github-release.ts +151 -94
  413. package/scripts/release/release-history.ts +0 -1
  414. package/scripts/release/release-plan.ts +0 -1
  415. package/scripts/release/release-publish.ts +38 -5
  416. package/scripts/release/release-scope-cli.ts +1 -2
  417. package/scripts/release/release-tag.ts +2 -4
  418. package/scripts/release/release-worktree.ts +97 -2
  419. package/scripts/repo/auto-merge-setting-logic.ts +1 -4
  420. package/scripts/repo/repo-setting.ts +1 -1
  421. package/scripts/repo/repository-labels.ts +3 -3
  422. package/scripts/repo/required-checks-logic.ts +206 -0
  423. package/scripts/repo/required-checks-report.ts +71 -0
  424. package/scripts/repo/ruleset-check-cli.ts +53 -0
  425. package/scripts/repo/ruleset-check.ts +147 -0
  426. package/scripts/report/report-lint-cli.ts +0 -4
  427. package/scripts/review/disposition-cli.ts +1 -1
  428. package/scripts/review/live-evidence.ts +1 -1
  429. package/scripts/review/review-attest-cli.ts +0 -6
  430. package/scripts/review/review-attest.ts +4 -16
  431. package/scripts/review/review-brief-cli.ts +23 -6
  432. package/scripts/review/review-brief.ts +21 -8
  433. package/scripts/review/review-checkout.ts +3 -2
  434. package/scripts/review/review-diff-parts.ts +89 -0
  435. package/scripts/review/review-diff-write.ts +97 -0
  436. package/scripts/review/review-finding-ledger.ts +0 -1
  437. package/scripts/review/review-record-cli.ts +10 -17
  438. package/scripts/review/review-record.ts +0 -1
  439. package/scripts/review/review-round2-cli.ts +1 -1
  440. package/scripts/review/review-stamps.ts +0 -3
  441. package/scripts/review/review-tree.ts +14 -2
  442. package/scripts/rules/decision-oracle-stage.ts +18 -0
  443. package/scripts/rules/decision-oracle.ts +10 -7
  444. package/scripts/rules/delivered-rules.ts +9 -1
  445. package/scripts/rules/destructive-command.ts +119 -0
  446. package/scripts/rules/direct-filing.ts +1 -1
  447. package/scripts/rules/early-heartbeat.ts +4 -3
  448. package/scripts/rules/file-body.ts +0 -3
  449. package/scripts/rules/filing-cap.ts +0 -2
  450. package/scripts/rules/gh-api.ts +7 -2
  451. package/scripts/rules/git-argv.ts +18 -7
  452. package/scripts/rules/git-force.ts +0 -2
  453. package/scripts/rules/implementation-cut.ts +0 -1
  454. package/scripts/rules/index-guard.ts +71 -0
  455. package/scripts/rules/issue-citation.ts +50 -25
  456. package/scripts/rules/lane-background.ts +15 -7
  457. package/scripts/rules/lane-park.ts +22 -6
  458. package/scripts/rules/last-prompt.ts +1 -0
  459. package/scripts/rules/oracle-consulted.ts +1 -1
  460. package/scripts/rules/oracle-firing.ts +1 -0
  461. package/scripts/rules/oracle-list-cli.ts +0 -3
  462. package/scripts/rules/permission-guards.ts +14 -0
  463. package/scripts/rules/protected-files.ts +74 -0
  464. package/scripts/rules/reply-language.ts +1 -1
  465. package/scripts/rules/rule-body-guard.ts +0 -3
  466. package/scripts/rules/rule-value-cli.ts +0 -1
  467. package/scripts/rules/shell-body-trigger.ts +0 -1
  468. package/scripts/rules/shell-segments.ts +0 -1
  469. package/scripts/rules/stop-rules.ts +20 -9
  470. package/scripts/rules/tail-commands.ts +1 -1
  471. package/scripts/rules/test-declared-commit.ts +1 -1
  472. package/scripts/rules/third-party-write.ts +0 -1
  473. package/scripts/rules/worktree-guard.ts +26 -9
  474. package/scripts/run/run-carry-args.ts +8 -12
  475. package/scripts/run/run-carry-cli.ts +0 -2
  476. package/scripts/run/run-carry-stash.ts +2 -2
  477. package/scripts/run/run-carry-streak.ts +1 -1
  478. package/scripts/run/run-cut-args.ts +1 -6
  479. package/scripts/run/run-cut-cli.ts +0 -7
  480. package/scripts/run/run-cut.ts +8 -54
  481. package/scripts/run/run-ending-cli.ts +2 -6
  482. package/scripts/run/run-ending.ts +1 -4
  483. package/scripts/run/run-entry-cli.ts +133 -25
  484. package/scripts/run/run-entry-stop.ts +104 -0
  485. package/scripts/run/run-entry.ts +0 -1
  486. package/scripts/run/run-event-cli.ts +0 -2
  487. package/scripts/run/run-event-follow.ts +1 -0
  488. package/scripts/run/run-event-render.ts +1 -1
  489. package/scripts/run/run-event-scope.ts +53 -4
  490. package/scripts/run/run-event-stream-emit.ts +7 -2
  491. package/scripts/run/run-event-stream.ts +0 -3
  492. package/scripts/run/run-event-watch.ts +1 -0
  493. package/scripts/run/run-halfrun-resume.ts +20 -7
  494. package/scripts/run/run-headless.ts +2 -2
  495. package/scripts/run/run-hold-cli.ts +33 -10
  496. package/scripts/run/run-hold.ts +29 -6
  497. package/scripts/run/run-issue-number.ts +1 -1
  498. package/scripts/run/run-liveness-cli.ts +2 -6
  499. package/scripts/run/run-liveness.ts +2 -3
  500. package/scripts/run/run-merge-cli.ts +7 -23
  501. package/scripts/run/run-merge-steps.ts +5 -5
  502. package/scripts/run/run-merge.ts +1 -1
  503. package/scripts/run/run-next-cli.ts +1 -1
  504. package/scripts/run/run-parent-cut-hook.ts +4 -2
  505. package/scripts/run/run-preflight.ts +2 -9
  506. package/scripts/run/run-prep-cli.ts +6 -3
  507. package/scripts/run/run-prep-locate.ts +1 -1
  508. package/scripts/run/run-progress-args.ts +20 -4
  509. package/scripts/run/run-progress-cli.ts +35 -36
  510. package/scripts/run/run-progress-clock.ts +10 -35
  511. package/scripts/run/run-progress-config.ts +0 -4
  512. package/scripts/run/run-progress-read.ts +1 -2
  513. package/scripts/run/run-progress.ts +1 -2
  514. package/scripts/run/run-prrun-resume.ts +117 -0
  515. package/scripts/run/run-report-cli.ts +1 -2
  516. package/scripts/run/run-report.ts +0 -1
  517. package/scripts/run/run-retrospective.ts +1 -1
  518. package/scripts/run/run-review-cli.ts +0 -3
  519. package/scripts/run/run-review-steps.ts +2 -0
  520. package/scripts/run/run-review.ts +0 -2
  521. package/scripts/run/run-ship-cli.ts +29 -19
  522. package/scripts/run/run-ship-detach.ts +1 -0
  523. package/scripts/run/run-ship-next.ts +106 -0
  524. package/scripts/run/run-ship-preflight.ts +1 -1
  525. package/scripts/run/run-ship-probe.ts +4 -1
  526. package/scripts/run/run-ship-return.ts +8 -3
  527. package/scripts/run/run-ship-review-steps.ts +18 -4
  528. package/scripts/run/run-ship-review.ts +11 -0
  529. package/scripts/run/run-ship-scoped.ts +1 -0
  530. package/scripts/run/run-ship-steps.ts +1 -1
  531. package/scripts/run/run-ship.ts +0 -1
  532. package/scripts/run/run-stage-read.ts +62 -0
  533. package/scripts/run/run-stage.ts +160 -0
  534. package/scripts/run/run-status-cli.ts +3 -16
  535. package/scripts/run/run-step-cli.ts +21 -14
  536. package/scripts/run/run-step.ts +1 -1
  537. package/scripts/run/run-stop-notify.ts +1 -3
  538. package/scripts/run/run-stranded-cli.ts +0 -4
  539. package/scripts/run/run-stranded-detect.ts +2 -2
  540. package/scripts/run/run-tail-cli.ts +17 -11
  541. package/scripts/run/run-tail.ts +2 -0
  542. package/scripts/run/run-tidy-lanes.ts +6 -2
  543. package/scripts/run/run-tidy-stashes.ts +12 -12
  544. package/scripts/run/run-wake-cli.ts +4 -13
  545. package/scripts/run/run-wake-loop.ts +2 -2
  546. package/scripts/run/run-wake.ts +2 -4
  547. package/scripts/run/run-watcher-guard-cli.ts +0 -4
  548. package/scripts/run/run-watcher-guard.ts +18 -12
  549. package/scripts/run/run-watcher-hook.ts +1 -1
  550. package/scripts/safe-chain/ci-installer-pin.ts +11 -5
  551. package/scripts/safe-chain/pack-hook.ts +92 -0
  552. package/scripts/safe-chain/project-config.ts +1 -1
  553. package/scripts/security/security-audit-provision-logic.ts +0 -1
  554. package/scripts/security/security-audit-provision.ts +3 -2
  555. package/scripts/security/security-audit.ts +0 -1
  556. package/scripts/security/security-updates-logic.ts +0 -1
  557. package/scripts/sonar/sonar-hotspots-cli.ts +10 -52
  558. package/scripts/sonar/sonar-hotspots.ts +0 -1
  559. package/scripts/sonar/sonar-new-code-cli.ts +150 -0
  560. package/scripts/sonar/sonar-new-code.ts +79 -0
  561. package/scripts/sonar/sonar-project.ts +97 -0
  562. package/scripts/split/split-assess-cli.ts +1 -1
  563. package/scripts/split/split-assess.ts +2 -5
  564. package/scripts/sync/managed-config-scope-cli.ts +1 -1
  565. package/scripts/sync/skill-migration.ts +0 -1
  566. package/scripts/sync/sync-ai-files.ts +4 -0
  567. package/scripts/sync/sync-hook-safety.ts +2 -3
  568. package/scripts/sync/sync.ts +1 -8
  569. package/scripts/sync/template-source-logic.ts +0 -1
  570. package/scripts/sync/workflow-pin-logic.ts +16 -28
  571. package/scripts/test/test-declared-changed.ts +13 -16
  572. package/scripts/test/test-declared-logic.ts +0 -1
  573. package/scripts/test/test-declared.ts +3 -9
  574. package/scripts/test/test-red-commit.ts +2 -2
  575. package/scripts/test/test-red.ts +14 -7
  576. package/scripts/test/test-type-logic.ts +1 -1
  577. package/scripts/test/unit-worker-share.ts +7 -16
  578. package/scripts/time-runtime/time-batch-guard.ts +1 -2
  579. package/scripts/time-runtime/time-bundle-call.ts +0 -1
  580. package/scripts/time-runtime/time-bundles.ts +0 -4
  581. package/scripts/time-runtime/time-density-hook.ts +0 -2
  582. package/scripts/time-runtime/time-followup-stage.ts +1 -1
  583. package/scripts/time-runtime/time-format.ts +0 -73
  584. package/scripts/time-runtime/time-round-trips.ts +0 -4
  585. package/scripts/time-runtime/time-single-check.ts +1 -1
  586. package/scripts/time-runtime/time-spans.ts +1 -1
  587. package/scripts/time-runtime/time-transcript-line.ts +1 -2
  588. package/scripts/ui/ui-routes-cli.ts +0 -5
  589. package/scripts/ui/ui-routes.ts +0 -5
  590. package/scripts/version/effective-upstream.ts +2 -2
  591. package/scripts/version/latest-corepack.ts +7 -9
  592. package/scripts/version/latest-scope-cli.ts +0 -2
  593. package/scripts/version/latest-update.ts +0 -2
  594. package/scripts/version/npm-registry.ts +2 -2
  595. package/scripts/version/publishable-range-check.ts +1 -1
  596. package/scripts/version/release-hold.ts +0 -4
  597. package/scripts/version/running-binary.ts +2 -2
  598. package/scripts/version/version-check-logic.ts +0 -2
  599. package/scripts/version/version-commands.ts +11 -1
  600. package/scripts/version/version-remote.ts +3 -3
  601. package/scripts/version/version-targets.ts +4 -4
  602. package/templates/CLAUDE.basic.md +6 -6
  603. package/templates/sonar-project.properties +28 -1
  604. package/templates/workflows/ci.yml +16 -82
  605. package/templates/workflows/dependabot-auto-merge.yml +6 -3
  606. package/templates/workflows/github-release.yml +79 -0
  607. package/tsconfig.sonar.json +4 -22
  608. package/prompts/collaboration-workflow/cross-repo-epic.md +0 -5
  609. package/prompts/collaboration-workflow/epic-audit.md +0 -5
  610. package/prompts/collaboration-workflow/epic-bundle.md +0 -5
  611. package/scripts/init/plugin-install-hint.ts +0 -47
  612. package/scripts/version/parse-json.ts +0 -13
  613. /package/scripts/{git → followup}/git-followup-stages.ts +0 -0
  614. /package/scripts/{git → gh}/git-gh-api-path.ts +0 -0
  615. /package/scripts/{git → gh}/git-gh-command.ts +0 -0
  616. /package/scripts/{git → gh}/git-gh-issue.ts +0 -0
  617. /package/scripts/{git → gh}/git-gh-pr-snapshot.ts +0 -0
  618. /package/scripts/{git → gh}/git-gh-reachability.ts +0 -0
  619. /package/scripts/{git → gh}/git-gh-repo.ts +0 -0
  620. /package/scripts/{git → gh}/git-gh-rest-state.ts +0 -0
  621. /package/scripts/{git → gh}/git-pr-checks-watch.ts +0 -0
  622. /package/scripts/{git → gh}/git-pr-error.ts +0 -0
  623. /package/scripts/{git → gh}/git-pr-messages.ts +0 -0
  624. /package/scripts/{git → gh}/github-issue-url.ts +0 -0
  625. /package/scripts/git/{stash-orphans.ts → stash/stash-orphans.ts} +0 -0
  626. /package/scripts/{git → issue}/issue-reference.ts +0 -0
  627. /package/scripts/{git → lib}/animation-helpers.ts +0 -0
  628. /package/scripts/{git → lib}/git-animation.ts +0 -0
  629. /package/scripts/{git → notify}/git-notify.ts +0 -0
  630. /package/scripts/{git → notify}/telegram-test-logic.ts +0 -0
@@ -33,27 +33,13 @@ does. **There is no second criterion.** §2i's observation, the review round cap
33
33
  prerequisite each route a second filing through it, delivered by `pnpm josh rule:guard` at the run's
34
34
  second `pnpm josh issue:file` call, never the first.
35
35
 
36
- ## Why the default is not to split
37
-
38
- **The rules were manufacturing Issues faster than runs could close them.** Execution was never the
39
- bottleneck; arrival was, and this assessment was one of the routes producing it: `route:split`
40
- accounted for **28 of the 119 open Issues (24%)**.
41
-
42
- **Separability is not scarce, which is why a test made only of it splits nearly everything.** Almost
43
- any request can be described as several deliverables that could each ship alone, so the old test bit on
44
- requests worth a handful of lines. The second question is what makes the test bite only where one Issue
45
- would genuinely be unverifiable in one pass. The review round cap's default and the WIP cap changed
46
- alongside it, in one commit.
47
-
48
36
  ## Diff size is not a reason to split, and that is measured
49
37
 
50
38
  **Size is a bar a split has to clear; it is never a reason to split.** Question 2 is a *minimum* — below
51
- it the work stays whole — and nothing makes a large diff a reason to divide one. Splitting an Issue in
52
- two to shorten review round 1 lengthens it, because each Issue pays round 1's fixed cost again while
53
- the size-dependent part is merely divided between the halves (measured in joshuafolkken/kit#1436:
54
- round 1's cost is dominated by a fixed part that two Issues pay twice, so there is no diff size at
55
- which splitting to cut it pays). **A proposal to add a size threshold that splits more is required to
56
- say why that data does not reach it.**
39
+ it the work stays whole — and nothing makes a large diff a reason to divide one. **A proposal to add a
40
+ size threshold that splits more is required to say why the round-1 measurement does not reach it.**
41
+ Rationale: `docs/maintainers/split-assessment-rationale.md` → "Why the default is not to split" and
42
+ `docs/maintainers/split-assessment-rationale.md` → "Why diff size is not a reason to split".
57
43
 
58
44
  **The size half is measured, not eyeballed — `pnpm josh split:assess`.** It counts the branch's
59
45
  changed files and changed lines with test files excluded and answers `split` / `single` on size
@@ -63,12 +63,13 @@ or release once the work is done; only an expired record over a clean tree is re
63
63
  **The batch entry points claim per child, not per batch.** `backlogrun` never
64
64
  call it themselves; each child runs the `fullrun` procedure, so it claims on entry and `pnpm josh
65
65
  followup` releases it at that child's merge. The command's behavior and the answer table are
66
- `docs/josh-commands.md` → "`josh run:hold` / `josh run:release`"; this file is the single source of
66
+ `docs/josh-commands-automation.md` → "`josh run:hold` / `josh run:release`"; this file is the single source of
67
67
  the procedure.
68
68
 
69
69
  ## The halfrun resume
70
70
 
71
- **`fullrun #<N>` after a `halfrun` stop resumes it instead of claiming** (joshuafolkken/kit#2796). The
71
+ **`fullrun #<N>` or `prrun #<N>` after a `halfrun` stop resumes it instead of claiming**
72
+ (joshuafolkken/kit#2796, #3042). The
72
73
  stop is **recorded, never inferred**: the `halfrun` ends with `pnpm josh run:hold <N> --halfrun-stop`,
73
74
  which marks its own record (re-keying a `halfrun new`'s unnumbered one to the filed issue) — a
74
75
  `halfrun` still implementing or a `backlogrun` child leaves the same hold over the same dirty tree, and
@@ -79,3 +80,22 @@ halfrun`. **Skip the title, the plan, the split assessment, `git switch main &&
79
80
  issue (`pnpm josh issue:read <N>`), then run the gate **in full** from the refactor (`chain-rule.md` →
80
81
  "Run the review-to-merge chain") — a fix made during the manual check has had no gate — and ship as
81
82
  any `fullrun` does.
83
+
84
+ ## The prrun resume
85
+
86
+ **`fullrun #<N>` after a `prrun` stop resumes it the same way** (joshuafolkken/kit#3023). The `prrun`
87
+ ends with `pnpm josh run:hold <N> --prrun-stop`, which writes the commit its pull request is on into its
88
+ own record; only a record carrying that commit is adopted. `run:entry` asks the session budget, adopts
89
+ the hold with the `fullrun` mark and prints one of three tokens — read, never inferred:
90
+
91
+ - **`resume: prrun-merged`** — a person merged the pull request. Run `pnpm josh followup "<title>
92
+ #<N>"` alone: it detects the merge and runs only the post-merge tail.
93
+ - **`resume: prrun-merge`** — the branch is still on the stop's commit, both here and on the pull
94
+ request, and the tree is clean, so what was verified is what would merge. Skip the gate and the
95
+ review; run `pnpm josh followup` to merge.
96
+ - **`resume: prrun-gate`** — the branch moved (locally, or by a push made on GitHub), its pull request
97
+ could not be read, or the tree is dirty: a person changed something. Run the
98
+ gate **in full** and the review (`chain-rule.md` → "Run the review-to-merge chain"), then ship as any
99
+ `fullrun` does.
100
+
101
+ All three skip the title, the plan, the split assessment and the implementation.
package/.codex/hooks.json CHANGED
@@ -1,52 +1,48 @@
1
1
  {
2
2
  "hooks": {
3
- "PreToolUse": [
3
+ "SessionStart": [
4
4
  {
5
- "matcher": "Bash|Edit|Read|Write|AskUserQuestion|apply_patch",
5
+ "matcher": "",
6
6
  "hooks": [
7
7
  {
8
8
  "type": "command",
9
- "command": "if [ -f dist/hooks/codex-hook-adapter.js ]; then node dist/hooks/codex-hook-adapter.js pretool; else pnpm exec tsx scripts/hooks/codex-hook-adapter.ts pretool; fi",
10
- "timeout": 20
9
+ "command": "pnpm josh audit:provision",
10
+ "timeout": 180
11
11
  }
12
12
  ]
13
13
  }
14
14
  ],
15
- "PostToolUse": [
15
+ "UserPromptSubmit": [
16
16
  {
17
- "matcher": "Edit|Write|apply_patch",
18
17
  "hooks": [
19
18
  {
20
19
  "type": "command",
21
- "command": "if [ -f dist/hooks/codex-hook-adapter.js ]; then node dist/hooks/codex-hook-adapter.js posttool; else pnpm exec tsx scripts/hooks/codex-hook-adapter.ts posttool; fi",
22
- "timeout": 90
20
+ "command": "if project_root=\"$(env -u GIT_ALTERNATE_OBJECT_DIRECTORIES -u GIT_COMMON_DIR -u GIT_DIR -u GIT_INDEX_FILE -u GIT_NAMESPACE -u GIT_OBJECT_DIRECTORY -u GIT_WORK_TREE git rev-parse --show-toplevel 2>/dev/null)\"; then unset GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_COMMON_DIR GIT_DIR GIT_INDEX_FILE GIT_NAMESPACE GIT_OBJECT_DIRECTORY GIT_WORK_TREE; else project_root=\"$(git rev-parse --show-toplevel)\" || exit 1; fi; cd \"$project_root\" && if node --disable-warning=ExperimentalWarning scripts/hooks/hook-bundle-ready.ts; then node dist/hooks/session-lang.js; else pnpm josh session:lang; fi",
21
+ "timeout": 10
23
22
  }
24
23
  ]
25
24
  }
26
25
  ],
27
- "SessionStart": [
26
+ "PreToolUse": [
28
27
  {
29
- "matcher": "",
28
+ "matcher": "Bash|Edit|Read|Write|AskUserQuestion|apply_patch",
30
29
  "hooks": [
31
30
  {
32
31
  "type": "command",
33
- "command": "pnpm josh audit:provision",
34
- "timeout": 180
32
+ "command": "if project_root=\"$(env -u GIT_ALTERNATE_OBJECT_DIRECTORIES -u GIT_COMMON_DIR -u GIT_DIR -u GIT_INDEX_FILE -u GIT_NAMESPACE -u GIT_OBJECT_DIRECTORY -u GIT_WORK_TREE git rev-parse --show-toplevel 2>/dev/null)\"; then unset GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_COMMON_DIR GIT_DIR GIT_INDEX_FILE GIT_NAMESPACE GIT_OBJECT_DIRECTORY GIT_WORK_TREE; else project_root=\"$(git rev-parse --show-toplevel)\" || exit 1; fi; cd \"$project_root\" && if node --disable-warning=ExperimentalWarning scripts/hooks/hook-bundle-ready.ts; then node dist/hooks/codex-hook-adapter.js pretool; else pnpm exec tsx scripts/hooks/codex-hook-adapter.ts pretool; fi",
33
+ "timeout": 20
35
34
  }
36
35
  ]
37
36
  }
38
37
  ],
39
- "UserPromptSubmit": [
38
+ "PostToolUse": [
40
39
  {
40
+ "matcher": "Edit|Write|apply_patch",
41
41
  "hooks": [
42
42
  {
43
43
  "type": "command",
44
- "command": "echo 'MANDATORY before writing any implementation code: present the two-layer work summary (Now / Change / Check, then every change with its test). Full rule: Code Change Rules Step 0 in CLAUDE.md.'"
45
- },
46
- {
47
- "type": "command",
48
- "command": "if [ -f dist/hooks/session-lang.js ]; then node dist/hooks/session-lang.js; else pnpm josh session:lang; fi",
49
- "timeout": 10
44
+ "command": "if project_root=\"$(env -u GIT_ALTERNATE_OBJECT_DIRECTORIES -u GIT_COMMON_DIR -u GIT_DIR -u GIT_INDEX_FILE -u GIT_NAMESPACE -u GIT_OBJECT_DIRECTORY -u GIT_WORK_TREE git rev-parse --show-toplevel 2>/dev/null)\"; then unset GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_COMMON_DIR GIT_DIR GIT_INDEX_FILE GIT_NAMESPACE GIT_OBJECT_DIRECTORY GIT_WORK_TREE; else project_root=\"$(git rev-parse --show-toplevel)\" || exit 1; fi; cd \"$project_root\" && if node --disable-warning=ExperimentalWarning scripts/hooks/hook-bundle-ready.ts; then node dist/hooks/codex-hook-adapter.js posttool; else pnpm exec tsx scripts/hooks/codex-hook-adapter.ts posttool; fi",
45
+ "timeout": 90
50
46
  }
51
47
  ]
52
48
  }
@@ -57,7 +53,7 @@
57
53
  "hooks": [
58
54
  {
59
55
  "type": "command",
60
- "command": "if [ -f dist/hooks/stop-guard.js ]; then node dist/hooks/stop-guard.js; else pnpm josh stop:guard; fi",
56
+ "command": "if project_root=\"$(env -u GIT_ALTERNATE_OBJECT_DIRECTORIES -u GIT_COMMON_DIR -u GIT_DIR -u GIT_INDEX_FILE -u GIT_NAMESPACE -u GIT_OBJECT_DIRECTORY -u GIT_WORK_TREE git rev-parse --show-toplevel 2>/dev/null)\"; then unset GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_COMMON_DIR GIT_DIR GIT_INDEX_FILE GIT_NAMESPACE GIT_OBJECT_DIRECTORY GIT_WORK_TREE; else project_root=\"$(git rev-parse --show-toplevel)\" || exit 1; fi; cd \"$project_root\" && if node --disable-warning=ExperimentalWarning scripts/hooks/hook-bundle-ready.ts; then node dist/hooks/stop-guard.js; else pnpm josh stop:guard; fi",
61
57
  "timeout": 20
62
58
  }
63
59
  ]
@@ -0,0 +1,33 @@
1
+ name: Setup Node.js
2
+ description: >
3
+ Set Node.js up at the version every kit workflow runs on, optionally pointed at a package
4
+ registry.
5
+
6
+ # The one place the Node.js version of kit's workflows is written (joshuafolkken/kit#3084). Every
7
+ # job used to call actions/setup-node with its own `node-version` literal, so a version move had to
8
+ # find all of them. A job that needs a different runtime says so explicitly — `node-26-pnpm` in
9
+ # `ci.yml` passes its own runtime to `.github/actions/setup-pnpm` instead of calling this.
10
+ #
11
+ # Distributed: `josh sync` writes this file into a consumer beside the workflows that call it, the
12
+ # same way as `.github/actions/setup-pnpm`. `workflow_pin_logic` reads this file as a source of
13
+ # canonical action pins.
14
+
15
+ inputs:
16
+ registry-url:
17
+ description: Passed to actions/setup-node's `registry-url`; empty writes no `.npmrc`.
18
+ required: false
19
+ default: ''
20
+ scope:
21
+ description: Passed to actions/setup-node's `scope`, for a scoped registry.
22
+ required: false
23
+ default: ''
24
+
25
+ runs:
26
+ using: composite
27
+ steps:
28
+ - name: Setup Node.js
29
+ uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
30
+ with:
31
+ node-version: '24'
32
+ registry-url: ${{ inputs.registry-url }}
33
+ scope: ${{ inputs.scope }}
@@ -0,0 +1,93 @@
1
+ name: Setup pnpm
2
+ description: >
3
+ Resolve the project's pnpm version, set pnpm up, and — unless `install` is false — restore the
4
+ pnpm store, install safe-chain from its hash-verified release installer and install the
5
+ dependencies through it.
6
+
7
+ # The one place kit's own workflows prepare pnpm (joshuafolkken/kit#2982). Every job that installed
8
+ # dependencies used to carry these steps itself, and `publish.yml` — the workflow holding the npm
9
+ # and GitHub Packages publish rights — had been left without safe-chain while `ci.yml` had it. A
10
+ # job that calls this action cannot install without the scan.
11
+ #
12
+ # Distributed: `josh sync` writes this file into a consumer beside the workflows that call it
13
+ # (`ci.yml` and `pr-classification.yml`), stamped as managed like they are (joshuafolkken/kit#3013).
14
+ # The distributed `ci.yml` calls it exactly as kit's own does, so a consumer's CI prepares pnpm on
15
+ # the path kit's CI runs (joshuafolkken/kit#3095). `workflow_pin_logic` reads this file as a source
16
+ # of canonical action pins.
17
+
18
+ inputs:
19
+ install:
20
+ description: Install the dependencies. False sets pnpm up alone, for a job that only runs pnpm.
21
+ required: false
22
+ default: 'true'
23
+ cache:
24
+ description: >
25
+ Restore and save the pnpm store. A release job passes false, so nothing another run saved
26
+ reaches a job that holds publish credentials.
27
+ required: false
28
+ default: 'true'
29
+ runtime:
30
+ description: Passed to pnpm/setup's `runtime` input; empty leaves the runtime to setup-node.
31
+ required: false
32
+ default: ''
33
+ node-auth-token:
34
+ description: >
35
+ NODE_AUTH_TOKEN for the install, for a job whose `.npmrc` authenticates to GitHub Packages.
36
+ Empty keeps whatever the job already has.
37
+ required: false
38
+ default: ''
39
+
40
+ runs:
41
+ using: composite
42
+ steps:
43
+ - name: Resolve pnpm version
44
+ id: pnpm-version
45
+ shell: bash
46
+ run: |
47
+ version=$(node -p "const m = require('./package.json'); m.packageManager?.match(/^pnpm@([^+]+)/)?.[1] ?? (m.devEngines?.packageManager?.name === 'pnpm' ? m.devEngines.packageManager.version?.split('+')[0] : 'latest') ?? 'latest'")
48
+ test -n "$version"
49
+ echo "version=$version" >> "$GITHUB_OUTPUT"
50
+
51
+ - name: Setup pnpm
52
+ uses: pnpm/setup@fbda4c85fc2e1e08721cd8763afea8f48d60f024 # v3.0.0
53
+ with:
54
+ version: ${{ steps.pnpm-version.outputs.version }}
55
+ runtime: ${{ inputs.runtime }}
56
+ install: false
57
+
58
+ - name: Resolve pnpm store path
59
+ if: inputs.install == 'true' && inputs.cache == 'true'
60
+ shell: bash
61
+ run: echo "PNPM_STORE_PATH=$(pnpm store path)" >> "$GITHUB_ENV"
62
+
63
+ - name: Setup pnpm store cache
64
+ if: inputs.install == 'true' && inputs.cache == 'true'
65
+ uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
66
+ with:
67
+ path: ${{ env.PNPM_STORE_PATH }}
68
+ key: ${{ runner.os }}-pnpm-store-${{ hashFiles('pnpm-lock.yaml') }}
69
+ restore-keys: |
70
+ ${{ runner.os }}-pnpm-store-
71
+
72
+ # The safe-chain release and the SHA-256 of that release's install-safe-chain.sh. The installer
73
+ # puts the safe-chain binary under ~/.safe-chain/bin and adds it to PATH beside the shims;
74
+ # `pnpm dlx … setup-ci` left only the shims, which then let every install through without a scan
75
+ # (joshuafolkken/kit#2711). `josh latest` moves both together.
76
+ - name: Setup safe-chain
77
+ if: inputs.install == 'true'
78
+ shell: bash
79
+ env:
80
+ SAFE_CHAIN_INSTALLER_VERSION: 1.5.20
81
+ SAFE_CHAIN_INSTALLER_SHA256: 0ad25efe15d1fa56105157a454d647223e78eb0c53d1f85e3d10afcd722e7bfd
82
+ run: |
83
+ installer="$RUNNER_TEMP/install-safe-chain.sh"
84
+ curl --proto '=https' -fsSL "https://github.com/AikidoSec/safe-chain/releases/download/$SAFE_CHAIN_INSTALLER_VERSION/install-safe-chain.sh" -o "$installer"
85
+ echo "$SAFE_CHAIN_INSTALLER_SHA256 $installer" | sha256sum -c -
86
+ sh "$installer" --ci
87
+
88
+ - name: Install dependencies
89
+ if: inputs.install == 'true'
90
+ shell: bash
91
+ env:
92
+ NODE_AUTH_TOKEN: ${{ inputs.node-auth-token || env.NODE_AUTH_TOKEN }}
93
+ run: pnpm install --frozen-lockfile --ignore-scripts
@@ -1,7 +1,11 @@
1
1
  version: 2
2
2
  updates:
3
+ # The local composite actions pin actions of their own, and Dependabot reads only the directories
4
+ # it is given — `/` covers `.github/workflows` and no `.github/actions/*/action.yml`.
3
5
  - package-ecosystem: 'github-actions'
4
- directory: '/'
6
+ directories:
7
+ - '/'
8
+ - '/.github/actions/*'
5
9
  schedule:
6
10
  interval: 'weekly'
7
11
  # Version updates are disabled: `josh latest` runs at the start of every fullrun / halfrun /
@@ -8,6 +8,7 @@ jobs:
8
8
  create-tag:
9
9
  name: Create Git Tag if Version Changed
10
10
  runs-on: ubuntu-latest
11
+ timeout-minutes: 10
11
12
  permissions:
12
13
  actions: write
13
14
  contents: write
@@ -19,9 +20,7 @@ jobs:
19
20
  fetch-depth: 2
20
21
 
21
22
  - name: Setup Node.js
22
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
23
- with:
24
- node-version: '24'
23
+ uses: ./.github/actions/setup-node
25
24
 
26
25
  - name: Check if package.json changed
27
26
  id: pkg_changed
@@ -27,13 +27,10 @@ concurrency:
27
27
  # set the JOSH_PLAYWRIGHT_BROWSERS repository variable to a space-separated list to widen it.
28
28
  env:
29
29
  JOSH_PLAYWRIGHT_BROWSERS: ${{ vars.JOSH_PLAYWRIGHT_BROWSERS || 'chromium' }}
30
- # The safe-chain release every "Setup safe-chain" step installs, and the SHA-256 of that release's
31
- # install-safe-chain.sh. The installer puts the safe-chain binary under ~/.safe-chain/bin and
32
- # adds it to PATH beside the shims; `pnpm dlx … setup-ci` left only the shims, which then let
33
- # every install through without a scan (joshuafolkken/kit#2711). `josh latest` moves both together.
34
- SAFE_CHAIN_INSTALLER_VERSION: 1.5.20
35
- SAFE_CHAIN_INSTALLER_SHA256: 0ad25efe15d1fa56105157a454d647223e78eb0c53d1f85e3d10afcd722e7bfd
36
30
 
31
+ # Every job that needs pnpm prepares it through `.github/actions/setup-pnpm`, which carries the
32
+ # pnpm version resolution, the store cache, the safe-chain installer pin and the install
33
+ # (joshuafolkken/kit#2982).
37
34
  jobs:
38
35
  node-26-pnpm:
39
36
  name: Node 26 pnpm
@@ -43,17 +40,10 @@ jobs:
43
40
  contents: read
44
41
  steps:
45
42
  - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
46
- - name: Resolve pnpm version
47
- id: pnpm-version
48
- run: |
49
- version=$(node -p "const m = require('./package.json'); m.packageManager?.match(/^pnpm@([^+]+)/)?.[1] ?? (m.devEngines?.packageManager?.name === 'pnpm' ? m.devEngines.packageManager.version?.split('+')[0] : 'latest') ?? 'latest'")
50
- test -n "$version"
51
- echo "version=$version" >> "$GITHUB_OUTPUT"
52
- - uses: pnpm/setup@fbda4c85fc2e1e08721cd8763afea8f48d60f024 # v3.0.0
43
+ - uses: ./.github/actions/setup-pnpm
53
44
  with:
54
- version: ${{ steps.pnpm-version.outputs.version }}
55
45
  runtime: node@26
56
- install: false
46
+ install: 'false'
57
47
  - run: node --version && pnpm --version
58
48
 
59
49
  playwright-image:
@@ -223,7 +213,7 @@ jobs:
223
213
  static-checks:
224
214
  name: Static Checks
225
215
  needs: reuse-pr-checks
226
- if: ${{ always() && needs.reuse-pr-checks.outputs.reuse != 'true' }}
216
+ if: ${{ !cancelled() && needs.reuse-pr-checks.outputs.reuse != 'true' }}
227
217
  runs-on: ubuntu-latest
228
218
  timeout-minutes: 8
229
219
  permissions:
@@ -234,35 +224,10 @@ jobs:
234
224
  uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
235
225
 
236
226
  - name: Setup Node.js
237
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
227
+ uses: ./.github/actions/setup-node
238
228
  with:
239
- node-version: '24'
240
229
  registry-url: 'https://npm.pkg.github.com'
241
230
 
242
- - name: Resolve pnpm version
243
- id: pnpm-version
244
- run: |
245
- version=$(node -p "const m = require('./package.json'); m.packageManager?.match(/^pnpm@([^+]+)/)?.[1] ?? (m.devEngines?.packageManager?.name === 'pnpm' ? m.devEngines.packageManager.version?.split('+')[0] : 'latest') ?? 'latest'")
246
- test -n "$version"
247
- echo "version=$version" >> "$GITHUB_OUTPUT"
248
-
249
- - name: Setup pnpm
250
- uses: pnpm/setup@fbda4c85fc2e1e08721cd8763afea8f48d60f024 # v3.0.0
251
- with:
252
- version: ${{ steps.pnpm-version.outputs.version }}
253
- install: false
254
-
255
- - name: Resolve pnpm store path
256
- run: echo "PNPM_STORE_PATH=$(pnpm store path)" >> "$GITHUB_ENV"
257
-
258
- - name: Setup pnpm store cache
259
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
260
- with:
261
- path: ${{ env.PNPM_STORE_PATH }}
262
- key: ${{ runner.os }}-pnpm-store-${{ hashFiles('pnpm-lock.yaml') }}
263
- restore-keys: |
264
- ${{ runner.os }}-pnpm-store-
265
-
266
231
  - name: Setup ESLint cache
267
232
  uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
268
233
  id: eslint-cache
@@ -317,17 +282,10 @@ jobs:
317
282
  ${{ runner.os }}-cspell-cache-${{ hashFiles('pnpm-lock.yaml') }}-
318
283
  ${{ runner.os }}-cspell-cache-
319
284
 
320
- - name: Setup safe-chain
321
- run: |
322
- installer="$RUNNER_TEMP/install-safe-chain.sh"
323
- curl --proto '=https' -fsSL "https://github.com/AikidoSec/safe-chain/releases/download/$SAFE_CHAIN_INSTALLER_VERSION/install-safe-chain.sh" -o "$installer"
324
- echo "$SAFE_CHAIN_INSTALLER_SHA256 $installer" | sha256sum -c -
325
- sh "$installer" --ci
326
-
327
- - name: Install dependencies
328
- env:
329
- NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
330
- run: pnpm install --frozen-lockfile --ignore-scripts
285
+ - name: Setup pnpm and install dependencies
286
+ uses: ./.github/actions/setup-pnpm
287
+ with:
288
+ node-auth-token: ${{ secrets.GITHUB_TOKEN }}
331
289
 
332
290
  # One step rather than five, and concurrent rather than serial (joshuafolkken/kit#1216).
333
291
  # `josh gate` is the command a developer runs before committing; it fans out to the same
@@ -366,13 +324,11 @@ jobs:
366
324
  - name: Run verification gate
367
325
  run: pnpm josh gate --verbose --no-unit
368
326
 
369
- # The other half of the gate, on a runner of its own. It carries the same setup steps as
370
- # `static-checks` rather than sharing them: a GitHub job is its own machine, so every job that
371
- # needs Node sets Node up, and this workflow already writes that preamble once per job. The
372
- # single-source alternative — a local composite action under `.github/actions/` — is ruled out by
373
- # `scripts/ci/ci-yml-action-parity.test.ts`, which pins the set of action names in this file to the
374
- # set in `templates/workflows/ci.yml`; a local action cannot appear in a distributed template,
375
- # because the template travels to consumers without it.
327
+ # The other half of the gate, on a runner of its own. A GitHub job is its own machine, so this job
328
+ # sets Node up again; the pnpm preamble is the shared `.github/actions/setup-pnpm` action
329
+ # (joshuafolkken/kit#2982), which `templates/workflows/ci.yml` calls the same way, so
330
+ # `scripts/ci/ci-yml-action-parity.test.ts` compares the two files without the action's own pins
331
+ # (joshuafolkken/kit#3095).
376
332
  #
377
333
  # No ESLint cache here — nothing in this job lints — and no `--maxWorkers`: `gate-plan.ts` leaves
378
334
  # any machine below its measured 11 cores uncapped, so vitest sizes its own pool from the runner
@@ -380,7 +336,7 @@ jobs:
380
336
  unit:
381
337
  name: Unit Tests
382
338
  needs: reuse-pr-checks
383
- if: ${{ always() && needs.reuse-pr-checks.outputs.reuse != 'true' }}
339
+ if: ${{ !cancelled() && needs.reuse-pr-checks.outputs.reuse != 'true' }}
384
340
  runs-on: ubuntu-latest
385
341
  timeout-minutes: 8
386
342
  permissions:
@@ -391,46 +347,14 @@ jobs:
391
347
  uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
392
348
 
393
349
  - name: Setup Node.js
394
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
350
+ uses: ./.github/actions/setup-node
395
351
  with:
396
- node-version: '24'
397
352
  registry-url: 'https://npm.pkg.github.com'
398
353
 
399
- - name: Resolve pnpm version
400
- id: pnpm-version
401
- run: |
402
- version=$(node -p "const m = require('./package.json'); m.packageManager?.match(/^pnpm@([^+]+)/)?.[1] ?? (m.devEngines?.packageManager?.name === 'pnpm' ? m.devEngines.packageManager.version?.split('+')[0] : 'latest') ?? 'latest'")
403
- test -n "$version"
404
- echo "version=$version" >> "$GITHUB_OUTPUT"
405
-
406
- - name: Setup pnpm
407
- uses: pnpm/setup@fbda4c85fc2e1e08721cd8763afea8f48d60f024 # v3.0.0
354
+ - name: Setup pnpm and install dependencies
355
+ uses: ./.github/actions/setup-pnpm
408
356
  with:
409
- version: ${{ steps.pnpm-version.outputs.version }}
410
- install: false
411
-
412
- - name: Resolve pnpm store path
413
- run: echo "PNPM_STORE_PATH=$(pnpm store path)" >> "$GITHUB_ENV"
414
-
415
- - name: Setup pnpm store cache
416
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
417
- with:
418
- path: ${{ env.PNPM_STORE_PATH }}
419
- key: ${{ runner.os }}-pnpm-store-${{ hashFiles('pnpm-lock.yaml') }}
420
- restore-keys: |
421
- ${{ runner.os }}-pnpm-store-
422
-
423
- - name: Setup safe-chain
424
- run: |
425
- installer="$RUNNER_TEMP/install-safe-chain.sh"
426
- curl --proto '=https' -fsSL "https://github.com/AikidoSec/safe-chain/releases/download/$SAFE_CHAIN_INSTALLER_VERSION/install-safe-chain.sh" -o "$installer"
427
- echo "$SAFE_CHAIN_INSTALLER_SHA256 $installer" | sha256sum -c -
428
- sh "$installer" --ci
429
-
430
- - name: Install dependencies
431
- env:
432
- NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
433
- run: pnpm install --frozen-lockfile --ignore-scripts
357
+ node-auth-token: ${{ secrets.GITHUB_TOKEN }}
434
358
 
435
359
  # **Through `josh test:unit`, never `vitest run` directly, and that is what makes a job split
436
360
  # safe rather than a hole.** The guard decides between a skip and a failure, and
@@ -457,6 +381,10 @@ jobs:
457
381
  # through with an E2E suite that never ran (see the `Detect E2E` job below, and
458
382
  # https://github.com/joshuafolkken/kit/issues/991). A skipped aggregator would have reproduced that
459
383
  # defect on the unit suite. Running always and failing explicitly is the only shape that cannot.
384
+ # That is also why this job alone keeps `always()` while the two halves use `!cancelled()`
385
+ # (joshuafolkken/kit#2980): a cancelled run must stop the minutes-long halves, but a skipped
386
+ # `Checks` on a cancelled head-SHA run would read as passing, so this seconds-long job still runs
387
+ # and fails on the halves' `cancelled` results.
460
388
  #
461
389
  # The results are read from the environment rather than interpolated into the script. `needs.*.result`
462
390
  # is a GitHub-controlled enum and not attacker-controlled, but a `${{ }}` expression spliced into a
@@ -596,35 +524,10 @@ jobs:
596
524
  uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
597
525
 
598
526
  - name: Setup Node.js
599
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
527
+ uses: ./.github/actions/setup-node
600
528
  with:
601
- node-version: '24'
602
529
  registry-url: 'https://npm.pkg.github.com'
603
530
 
604
- - name: Resolve pnpm version
605
- id: pnpm-version
606
- run: |
607
- version=$(node -p "const m = require('./package.json'); m.packageManager?.match(/^pnpm@([^+]+)/)?.[1] ?? (m.devEngines?.packageManager?.name === 'pnpm' ? m.devEngines.packageManager.version?.split('+')[0] : 'latest') ?? 'latest'")
608
- test -n "$version"
609
- echo "version=$version" >> "$GITHUB_OUTPUT"
610
-
611
- - name: Setup pnpm
612
- uses: pnpm/setup@fbda4c85fc2e1e08721cd8763afea8f48d60f024 # v3.0.0
613
- with:
614
- version: ${{ steps.pnpm-version.outputs.version }}
615
- install: false
616
-
617
- - name: Resolve pnpm store path
618
- run: echo "PNPM_STORE_PATH=$(pnpm store path)" >> "$GITHUB_ENV"
619
-
620
- - name: Setup pnpm store cache
621
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
622
- with:
623
- path: ${{ env.PNPM_STORE_PATH }}
624
- key: ${{ runner.os }}-pnpm-store-${{ hashFiles('pnpm-lock.yaml') }}
625
- restore-keys: |
626
- ${{ runner.os }}-pnpm-store-
627
-
628
531
  - name: Setup build cache
629
532
  uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
630
533
  id: build-cache
@@ -636,17 +539,10 @@ jobs:
636
539
  ${{ runner.os }}-build-cache-e2e-${{ hashFiles('pnpm-lock.yaml') }}-
637
540
  ${{ runner.os }}-build-cache-e2e-
638
541
 
639
- - name: Setup safe-chain
640
- run: |
641
- installer="$RUNNER_TEMP/install-safe-chain.sh"
642
- curl --proto '=https' -fsSL "https://github.com/AikidoSec/safe-chain/releases/download/$SAFE_CHAIN_INSTALLER_VERSION/install-safe-chain.sh" -o "$installer"
643
- echo "$SAFE_CHAIN_INSTALLER_SHA256 $installer" | sha256sum -c -
644
- sh "$installer" --ci
645
-
646
- - name: Install dependencies
647
- env:
648
- NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
649
- run: pnpm install --frozen-lockfile --ignore-scripts
542
+ - name: Setup pnpm and install dependencies
543
+ uses: ./.github/actions/setup-pnpm
544
+ with:
545
+ node-auth-token: ${{ secrets.GITHUB_TOKEN }}
650
546
 
651
547
  # Only needed on the fallback path: the container image already ships browsers
652
548
  # matching its own Playwright version. Invoked through the local bin rather than
@@ -697,6 +593,7 @@ jobs:
697
593
  needs.e2e-detect.result == 'success' &&
698
594
  (needs.e2e.result == 'success' || needs.e2e.result == 'skipped')
699
595
  runs-on: ubuntu-latest
596
+ timeout-minutes: 5
700
597
  permissions:
701
598
  contents: write
702
599
  steps:
@@ -18,6 +18,7 @@ permissions:
18
18
  jobs:
19
19
  auto-merge:
20
20
  runs-on: ubuntu-latest
21
+ timeout-minutes: 10
21
22
  if: github.actor == 'dependabot[bot]'
22
23
  steps:
23
24
  - name: Fetch Dependabot metadata
@@ -15,13 +15,6 @@ on:
15
15
  # nothing here needs it: every run reads the pull request's labels as they stand when it runs, not as
16
16
  # its event carried them, so whichever suite GitHub counts as newest holds a current verdict.
17
17
 
18
- # The same safe-chain installer pin as ci.yml — the release and its install-safe-chain.sh SHA-256.
19
- # `pnpm dlx … setup-ci` left only shims, so the install below ran without a scan (joshuafolkken/kit#2765).
20
- # `josh latest` moves both together, in this file and in ci.yml.
21
- env:
22
- SAFE_CHAIN_INSTALLER_VERSION: 1.5.20
23
- SAFE_CHAIN_INSTALLER_SHA256: 0ad25efe15d1fa56105157a454d647223e78eb0c53d1f85e3d10afcd722e7bfd
24
-
25
18
  jobs:
26
19
  classification:
27
20
  name: Release classification
@@ -38,48 +31,17 @@ jobs:
38
31
  persist-credentials: false
39
32
 
40
33
  - name: Setup Node.js
41
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
42
- with:
43
- node-version: '24'
34
+ uses: ./.github/actions/setup-node
44
35
 
45
36
  - name: Configure GitHub Packages authentication for existing projects
46
37
  run: printf '//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}\n' >> "$HOME/.npmrc"
47
38
 
48
- - name: Resolve pnpm version
49
- id: pnpm-version
50
- run: |
51
- version=$(node -p "const m = require('./package.json'); m.packageManager?.match(/^pnpm@([^+]+)/)?.[1] ?? (m.devEngines?.packageManager?.name === 'pnpm' ? m.devEngines.packageManager.version?.split('+')[0] : 'latest') ?? 'latest'")
52
- test -n "$version"
53
- echo "version=$version" >> "$GITHUB_OUTPUT"
54
-
55
- - name: Setup pnpm
56
- uses: pnpm/setup@fbda4c85fc2e1e08721cd8763afea8f48d60f024 # v3.0.0
39
+ # The shared pnpm preamble — version, store cache, the safe-chain installer pin and the install
40
+ # (joshuafolkken/kit#2765, joshuafolkken/kit#2982).
41
+ - name: Setup pnpm and install dependencies
42
+ uses: ./.github/actions/setup-pnpm
57
43
  with:
58
- version: ${{ steps.pnpm-version.outputs.version }}
59
- install: false
60
-
61
- - name: Resolve pnpm store path
62
- run: echo "PNPM_STORE_PATH=$(pnpm store path)" >> "$GITHUB_ENV"
63
-
64
- - name: Setup pnpm store cache
65
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
66
- with:
67
- path: ${{ env.PNPM_STORE_PATH }}
68
- key: ${{ runner.os }}-pnpm-store-${{ hashFiles('pnpm-lock.yaml') }}
69
- restore-keys: |
70
- ${{ runner.os }}-pnpm-store-
71
-
72
- - name: Setup safe-chain
73
- run: |
74
- installer="$RUNNER_TEMP/install-safe-chain.sh"
75
- curl --proto '=https' -fsSL "https://github.com/AikidoSec/safe-chain/releases/download/$SAFE_CHAIN_INSTALLER_VERSION/install-safe-chain.sh" -o "$installer"
76
- echo "$SAFE_CHAIN_INSTALLER_SHA256 $installer" | sha256sum -c -
77
- sh "$installer" --ci
78
-
79
- - name: Install dependencies
80
- env:
81
- NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
82
- run: pnpm install --frozen-lockfile --ignore-scripts
44
+ node-auth-token: ${{ secrets.GITHUB_TOKEN }}
83
45
 
84
46
  - name: Check release classification
85
47
  env: