@joshuafolkken/kit 1.1050.0 → 1.1094.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (581) hide show
  1. package/.claude/settings.json +9 -8
  2. package/.claude/skills/epic-commands/SKILL.md +5 -7
  3. package/.claude/skills/workflow-commands/SKILL.md +19 -11
  4. package/.claude/skills/workflow-commands/background-commands.md +4 -3
  5. package/.claude/skills/workflow-commands/backlogrun-child.md +1 -1
  6. package/.claude/skills/workflow-commands/backlogrun-lanes.md +8 -6
  7. package/.claude/skills/workflow-commands/backlogrun-progress.md +1 -1
  8. package/.claude/skills/workflow-commands/backlogrun-steps.md +10 -10
  9. package/.claude/skills/workflow-commands/backlogrun.md +2 -2
  10. package/.claude/skills/workflow-commands/chain-rule.md +4 -2
  11. package/.claude/skills/workflow-commands/delegation.md +3 -3
  12. package/.claude/skills/workflow-commands/followup-reference.md +1 -1
  13. package/.claude/skills/workflow-commands/followup.md +7 -3
  14. package/.claude/skills/workflow-commands/fullrun-steps.md +3 -2
  15. package/.claude/skills/workflow-commands/fullrun.md +3 -2
  16. package/.claude/skills/workflow-commands/halfrun.md +16 -19
  17. package/.claude/skills/workflow-commands/issue-comments.md +1 -1
  18. package/.claude/skills/workflow-commands/issue-fold-existing.md +10 -10
  19. package/.claude/skills/workflow-commands/issue-scout.md +1 -1
  20. package/.claude/skills/workflow-commands/kickoff.md +9 -4
  21. package/.claude/skills/workflow-commands/latest-gate.md +1 -1
  22. package/.claude/skills/workflow-commands/needs-human-review.md +1 -1
  23. package/.claude/skills/workflow-commands/observation-filing.md +3 -3
  24. package/.claude/skills/workflow-commands/prerequisite.md +1 -1
  25. package/.claude/skills/workflow-commands/prrun.md +36 -0
  26. package/.claude/skills/workflow-commands/retrospective.md +1 -1
  27. package/.claude/skills/workflow-commands/working-tree-hold.md +22 -2
  28. package/.codex/hooks.json +16 -20
  29. package/.github/actions/setup-pnpm/action.yml +93 -0
  30. package/.github/dependabot.yml +5 -1
  31. package/.github/workflows/ci.yml +26 -128
  32. package/.github/workflows/pr-classification.yml +5 -41
  33. package/.github/workflows/publish.yml +33 -38
  34. package/.github/workflows/sonar-qube.yml +37 -4
  35. package/AGENTS.md +12 -2
  36. package/CLAUDE.md +15 -16
  37. package/GEMINI.md +14 -2
  38. package/README.md +59 -18
  39. package/SECURITY.md +36 -6
  40. package/cspell/index.yaml +2 -1
  41. package/dist/CLAUDE.md +15 -16
  42. package/dist/config-merge/index.js +15 -3
  43. package/dist/hooks/batch-guard.js +4 -4
  44. package/dist/hooks/{chunk-HJIISEAC.js → chunk-3C4YCCEF.js} +5 -13
  45. package/dist/hooks/{chunk-EJDX2TOB.js → chunk-7ZPFAVR7.js} +7 -88
  46. package/dist/hooks/{chunk-WQ4OSBSS.js → chunk-E54KGFEQ.js} +2 -2
  47. package/dist/hooks/{chunk-GQ7KP45M.js → chunk-IL27YTPH.js} +2 -2
  48. package/dist/hooks/{chunk-DMQN45FN.js → chunk-KHWHKJOM.js} +3 -3
  49. package/dist/hooks/{chunk-5BK3K7V4.js → chunk-M2XDCUKD.js} +997 -478
  50. package/dist/hooks/{chunk-7VPDUBRN.js → chunk-NKOG3XAV.js} +150 -153
  51. package/dist/hooks/{chunk-NJQOBE6L.js → chunk-O4LL4HTI.js} +2 -7
  52. package/dist/hooks/{chunk-NAS4C7GP.js → chunk-OIZUHPJI.js} +2 -2
  53. package/dist/hooks/{chunk-RLDX5SOC.js → chunk-UD24EAIL.js} +2084 -1412
  54. package/dist/hooks/codex-hook-adapter.js +10 -11
  55. package/dist/hooks/duplicate-read-guard.js +5 -5
  56. package/dist/hooks/format-edited.js +2 -2
  57. package/dist/hooks/inputs.json +279 -0
  58. package/dist/hooks/investigation-guard.js +5 -5
  59. package/dist/hooks/pretool-guard.js +9 -9
  60. package/dist/hooks/session-lang.js +0 -1
  61. package/dist/hooks/stop-guard.js +178 -324
  62. package/dist/josh.js +162 -119
  63. package/dist/managed-marker/index.js +2 -1
  64. package/dist/version/index.js +34 -58
  65. package/eslint/rules/promise.js +5 -0
  66. package/package.json +9 -4
  67. package/prompts/collaboration-workflow/issue-citation.md +5 -5
  68. package/prompts/collaboration-workflow/operating-rules.md +4 -4
  69. package/prompts/collaboration-workflow/overview.md +13 -1
  70. package/prompts/collaboration-workflow/report-format.md +1 -1
  71. package/prompts/collaboration-workflow/residency.md +3 -3
  72. package/prompts/collaboration-workflow/rule-delivery.md +1 -1
  73. package/prompts/collaboration-workflow/turn-batching.md +3 -3
  74. package/prompts/collaboration-workflow/upstream-interrupt.md +1 -1
  75. package/prompts/collaboration-workflow/wip-cap.md +25 -22
  76. package/prompts/collaboration-workflow.md +5 -8
  77. package/prompts/review-rubric.md +1 -1
  78. package/prompts/review.md +3 -3
  79. package/prompts/sonar-hotspot-handling.md +11 -3
  80. package/prompts/testing-guide.md +3 -3
  81. package/scripts/adopt/adopt-toolkits.ts +0 -2
  82. package/scripts/adopt/adopt.ts +0 -2
  83. package/scripts/agent/agent-argv.ts +0 -2
  84. package/scripts/agent/agent-diagnostics.ts +1 -1
  85. package/scripts/agent/agent-role-profile.ts +0 -7
  86. package/scripts/agent/claude-agent-argv.ts +0 -2
  87. package/scripts/agent/codex-agent-argv.ts +1 -1
  88. package/scripts/agent/codex-hooks.ts +92 -0
  89. package/scripts/agent/interactive-ask.ts +1 -1
  90. package/scripts/auto-ok/auto-ok-cli.ts +6 -16
  91. package/scripts/backlog/backlog-budget.ts +0 -2
  92. package/scripts/backlog/backlog-defect-priority.ts +2 -2
  93. package/scripts/backlog/backlog-drive-cli.ts +10 -8
  94. package/scripts/backlog/backlog-drive-named-offer.ts +16 -3
  95. package/scripts/backlog/backlog-drive-named.ts +2 -1
  96. package/scripts/backlog/backlog-drive.ts +76 -16
  97. package/scripts/backlog/backlog-named.ts +0 -3
  98. package/scripts/backlog/backlog-next.ts +9 -15
  99. package/scripts/backlog/backlog-offer-cli.ts +0 -5
  100. package/scripts/backlog/backlog-plan-cli.ts +1 -7
  101. package/scripts/backlog/backlog-plan.ts +1 -1
  102. package/scripts/backlog/backlog-pool.ts +3 -6
  103. package/scripts/backlog/backlog-rank.ts +2 -2
  104. package/scripts/backlog/backlog-ready.ts +19 -3
  105. package/scripts/backlog/backlog-scope.ts +1 -3
  106. package/scripts/backlog/backlog-stalled-detect.ts +2 -2
  107. package/scripts/backlog/backlog-stalled.ts +0 -1
  108. package/scripts/backlog/backlog-waves.ts +5 -2
  109. package/scripts/behavior/behavior-cli.ts +1 -1
  110. package/scripts/build/build-codex-hooks.ts +26 -0
  111. package/scripts/build/build-hooks.ts +85 -9
  112. package/scripts/build/hook-bundle-stamp.ts +111 -0
  113. package/scripts/cases/cases-cli.ts +1 -1
  114. package/scripts/cases/cases-logic.ts +1 -1
  115. package/scripts/ci/composite-actions.ts +30 -0
  116. package/scripts/ci/pr-classification.ts +3 -3
  117. package/scripts/claude/workflow-destination.ts +10 -1
  118. package/scripts/clone/clone-fingerprint.ts +0 -1
  119. package/scripts/clone/clone-scan-cli.ts +1 -1
  120. package/scripts/clone/clone-scan.ts +1 -1
  121. package/scripts/config-merge/json-format.ts +0 -1
  122. package/scripts/config-merge/patch-yaml-list.ts +1 -1
  123. package/scripts/cost-runtime/codex-usage.ts +2 -9
  124. package/scripts/cost-runtime/cost-attribute.ts +0 -1
  125. package/scripts/cost-runtime/cost-cli.ts +0 -3
  126. package/scripts/cost-runtime/cost-corpus.ts +0 -2
  127. package/scripts/cost-runtime/cost-format.ts +0 -3
  128. package/scripts/cost-runtime/cost-pricing.ts +0 -1
  129. package/scripts/cost-runtime/cost-tokens.ts +0 -1
  130. package/scripts/delegation/delegation-cli.ts +1 -1
  131. package/scripts/delegation/delegation-policy.ts +0 -1
  132. package/scripts/delegation/duplicate-read-guard.ts +0 -8
  133. package/scripts/delegation/fanout-cli.ts +1 -1
  134. package/scripts/delegation/fanout.ts +0 -2
  135. package/scripts/delegation/investigation-reads.ts +1 -164
  136. package/scripts/discovery/repo-map-logic.ts +0 -1
  137. package/scripts/discovery/repo-party-cli.ts +1 -1
  138. package/scripts/doctor/doctor-consumer.ts +4 -6
  139. package/scripts/doctor/doctor-logic.ts +0 -4
  140. package/scripts/doctor/doctor.ts +14 -9
  141. package/scripts/document/document-byte-budget.ts +4 -5
  142. package/scripts/document/document-byte-check.ts +0 -1
  143. package/scripts/document/document-read-cli.ts +0 -2
  144. package/scripts/document/document-section-cli.ts +1 -1
  145. package/scripts/document/document-section.ts +0 -3
  146. package/scripts/document/edit-files-cli.ts +0 -1
  147. package/scripts/document/entry-read-budget.ts +10 -2
  148. package/scripts/document/lane-child-read-set.ts +1 -6
  149. package/scripts/document/read-files-cli.ts +0 -4
  150. package/scripts/document/read-set-cli.ts +0 -2
  151. package/scripts/document/read-set-point-of-use.ts +1 -0
  152. package/scripts/document/read-set-pricing.ts +0 -1
  153. package/scripts/document/read-set-trim.ts +1 -1
  154. package/scripts/epic/epic-add.ts +1 -1
  155. package/scripts/epic/epic-audit-cli.ts +1 -4
  156. package/scripts/epic/epic-audit-orphans.ts +1 -3
  157. package/scripts/epic/epic-audit-rationale.ts +0 -1
  158. package/scripts/epic/epic-audit-report.ts +0 -2
  159. package/scripts/epic/epic-audit.ts +5 -4
  160. package/scripts/epic/epic-bundle-cli.ts +1 -1
  161. package/scripts/epic/epic-bundle-evidence.ts +0 -1
  162. package/scripts/epic/epic-bundle-referenced.ts +1 -5
  163. package/scripts/epic/epic-bundle.ts +0 -4
  164. package/scripts/epic/epic-busy.ts +4 -5
  165. package/scripts/epic/epic-candidate-confirm.ts +0 -5
  166. package/scripts/epic/epic-classify.ts +2 -2
  167. package/scripts/epic/epic-cli-argv.ts +0 -1
  168. package/scripts/epic/epic-close-comment.ts +1 -1
  169. package/scripts/epic/epic-close.ts +5 -2
  170. package/scripts/epic/epic-cross-repo.ts +2 -4
  171. package/scripts/epic/epic-decision.ts +0 -1
  172. package/scripts/epic/epic-fetch.ts +2 -2
  173. package/scripts/epic/epic-index.ts +2 -3
  174. package/scripts/epic/epic-issue.ts +1 -15
  175. package/scripts/epic/epic-lane-offer.ts +9 -8
  176. package/scripts/epic/epic-nested.ts +1 -1
  177. package/scripts/epic/epic-next-read.ts +1 -3
  178. package/scripts/epic/epic-next-views.ts +0 -1
  179. package/scripts/epic/epic-next.ts +1 -10
  180. package/scripts/epic/epic-parse.ts +0 -1
  181. package/scripts/epic/epic-promote.ts +0 -9
  182. package/scripts/epic/epic-rank.ts +2 -2
  183. package/scripts/epic/epic-read.ts +1 -2
  184. package/scripts/epic/epic-reconcile.ts +1 -1
  185. package/scripts/epic/epic-reference.ts +1 -13
  186. package/scripts/epic/epic-relation-recheck.ts +1 -1
  187. package/scripts/epic/epic-relations.ts +1 -1
  188. package/scripts/epic/epic-remove.ts +1 -1
  189. package/scripts/epic/epic-report.ts +0 -1
  190. package/scripts/epic/epic-run.ts +2 -3
  191. package/scripts/epic/epic-shape.ts +1 -1
  192. package/scripts/epic/epic-solo-stale.ts +107 -0
  193. package/scripts/epic/epic-solo.ts +3 -2
  194. package/scripts/epic/epic-triage.ts +1 -1
  195. package/scripts/epic/epic-validate.ts +1 -1
  196. package/scripts/epic/epic.ts +1 -1
  197. package/scripts/exports/unused-members-cli.ts +53 -0
  198. package/scripts/{git → followup}/followup-issue-number.ts +1 -6
  199. package/scripts/{git → followup}/git-followup-cleanup.ts +2 -1
  200. package/scripts/{git → followup}/git-followup-finish.ts +1 -3
  201. package/scripts/{git → followup}/git-followup-flush.ts +2 -2
  202. package/scripts/{git → followup}/git-followup-issue-close.ts +2 -2
  203. package/scripts/{git → followup}/git-followup-label.ts +4 -4
  204. package/scripts/followup/git-followup-merged.ts +112 -0
  205. package/scripts/{git → followup}/git-followup-pending.ts +1 -1
  206. package/scripts/{git → followup}/git-followup-workflow.ts +19 -11
  207. package/scripts/{git → followup}/git-pr-followup-wrapup.ts +9 -3
  208. package/scripts/{git → followup}/git-pr-followup.ts +53 -16
  209. package/scripts/gate/core-budget.ts +3 -9
  210. package/scripts/gate/gate-plan.ts +7 -4
  211. package/scripts/gate/gate-report.ts +0 -6
  212. package/scripts/gate/gate-tree.ts +1 -1
  213. package/scripts/gate/pre-commit-type-check.ts +0 -6
  214. package/scripts/gate/project-checks.ts +7 -8
  215. package/scripts/gate/scoped-green.ts +0 -1
  216. package/scripts/gate/type-check-step.ts +1 -1
  217. package/scripts/gate/verification-gate.ts +0 -2
  218. package/scripts/gh/fix-gh-packages.ts +15 -12
  219. package/scripts/gh/gh-spawn.ts +2 -2
  220. package/scripts/{git → gh}/git-ai-review-scan.ts +1 -5
  221. package/scripts/{git → gh}/git-gh-check.ts +2 -1
  222. package/scripts/{git → gh}/git-gh-exec.ts +1 -1
  223. package/scripts/{git → gh}/git-gh-failure.ts +1 -1
  224. package/scripts/{git → gh}/git-gh-helpers.ts +0 -1
  225. package/scripts/{git → gh}/git-gh-issue-list.ts +2 -0
  226. package/scripts/{git → gh}/git-gh-issue-read.ts +1 -1
  227. package/scripts/{git → gh}/git-gh-issue-rest.ts +6 -3
  228. package/scripts/{git → gh}/git-gh-pr-read.ts +24 -0
  229. package/scripts/{git → gh}/git-gh-pr-rest.ts +5 -2
  230. package/scripts/{git → gh}/git-gh-pr-review.ts +2 -2
  231. package/scripts/{git → gh}/git-gh-pr-rollup.ts +1 -3
  232. package/scripts/{git → gh}/git-gh-pr.ts +3 -1
  233. package/scripts/{git → gh}/git-pr-ai-review.ts +2 -5
  234. package/scripts/{git → gh}/git-pr-checks-eval.ts +0 -10
  235. package/scripts/{git → gh}/git-pr-checks-parse.ts +4 -20
  236. package/scripts/{git → gh}/git-pr-checks.ts +2 -1
  237. package/scripts/{git → gh}/git-pr-coderabbit.ts +2 -5
  238. package/scripts/{git → gh}/git-pr-confirmation.ts +1 -3
  239. package/scripts/{git → gh}/git-pr-managed-config.ts +2 -3
  240. package/scripts/{git → gh}/git-pr.ts +3 -3
  241. package/scripts/git/changed-file-scope.ts +0 -1
  242. package/scripts/git/git-branch.ts +3 -6
  243. package/scripts/git/git-commit.ts +1 -1
  244. package/scripts/git/git-common-directory.ts +80 -24
  245. package/scripts/git/git-error.ts +66 -9
  246. package/scripts/git/git-issue.ts +1 -1
  247. package/scripts/git/git-preflight.ts +2 -2
  248. package/scripts/git/git-prompt.ts +6 -31
  249. package/scripts/git/git-push.ts +1 -1
  250. package/scripts/git/git-staging.ts +1 -0
  251. package/scripts/git/git-status.ts +1 -1
  252. package/scripts/git/git-workflow.ts +1 -1
  253. package/scripts/git/gone-branch.ts +1 -0
  254. package/scripts/git/listing-cutoff.ts +1 -1
  255. package/scripts/git/main-merge.ts +1 -1
  256. package/scripts/git/main-sync.ts +19 -1
  257. package/scripts/git/parse-json-array.ts +0 -3
  258. package/scripts/git/repository-lock.ts +16 -16
  259. package/scripts/git/{git-stash.ts → stash/git-stash.ts} +1 -1
  260. package/scripts/git/{stash-pop-args.ts → stash/stash-pop-args.ts} +1 -1
  261. package/scripts/git/{stash-pop-cli.ts → stash/stash-pop-cli.ts} +0 -1
  262. package/scripts/git/{stash-sweep-lock.ts → stash/stash-sweep-lock.ts} +3 -3
  263. package/scripts/hooks/codex-hook-adapter.ts +0 -1
  264. package/scripts/hooks/edited-cspell.ts +1 -1
  265. package/scripts/hooks/format-edited-file.ts +2 -0
  266. package/scripts/hooks/pre-push-unit.ts +0 -4
  267. package/scripts/hooks/pretool-guard.ts +22 -4
  268. package/scripts/hooks/reserved-run.ts +1 -1
  269. package/scripts/hooks/step-zero-notice.ts +76 -0
  270. package/scripts/hooks/stop-guard.ts +47 -21
  271. package/scripts/init/claude-plugin-config.ts +4 -5
  272. package/scripts/init/hook-command-rewrite.ts +16 -8
  273. package/scripts/init/hook-launch.ts +41 -15
  274. package/scripts/init/init-basic.ts +2 -5
  275. package/scripts/init/init-logic.ts +7 -0
  276. package/scripts/init/init.ts +0 -3
  277. package/scripts/init/project-profile.ts +6 -11
  278. package/scripts/init/start-exec.ts +1 -1
  279. package/scripts/init/start-setup-pr.ts +6 -6
  280. package/scripts/init/start-steps.ts +1 -0
  281. package/scripts/issue/behavior-change-lint.ts +0 -1
  282. package/scripts/issue/defect-rate-cli.ts +3 -3
  283. package/scripts/issue/defect-rate.ts +1 -2
  284. package/scripts/{git → issue}/git-next-issues.ts +3 -3
  285. package/scripts/issue/issue-backlinks-cli.ts +1 -5
  286. package/scripts/issue/issue-cite-cli.ts +2 -6
  287. package/scripts/issue/issue-cite.ts +0 -2
  288. package/scripts/issue/issue-classification.ts +1 -9
  289. package/scripts/issue/issue-closing-pr.ts +4 -4
  290. package/scripts/issue/issue-comment-cli.ts +2 -2
  291. package/scripts/issue/issue-file-cli.ts +5 -5
  292. package/scripts/issue/issue-file.ts +2 -2
  293. package/scripts/issue/issue-fold-cli.ts +1 -1
  294. package/scripts/issue/issue-fold-existing-cli.ts +1 -1
  295. package/scripts/{git → issue}/issue-labels.ts +8 -0
  296. package/scripts/issue/issue-lint-cli.ts +1 -1
  297. package/scripts/issue/issue-merged.ts +2 -2
  298. package/scripts/{git → issue}/issue-rank.ts +1 -1
  299. package/scripts/issue/issue-read-cli.ts +8 -47
  300. package/scripts/issue/issue-read.ts +0 -2
  301. package/scripts/issue/issue-report-failures.ts +80 -0
  302. package/scripts/issue/issue-scout-cli.ts +1 -7
  303. package/scripts/issue/issue-scout-closed.ts +2 -2
  304. package/scripts/issue/issue-scout.ts +0 -2
  305. package/scripts/issue/issue-state-cli.ts +5 -46
  306. package/scripts/issue/issue-state.ts +1 -5
  307. package/scripts/issue/markdown-section.ts +1 -1
  308. package/scripts/issue/measure-rerun-cli.ts +1 -1
  309. package/scripts/issue/reproduction-measure.ts +1 -1
  310. package/scripts/josh/cli-body.ts +1 -1
  311. package/scripts/josh/file-map-stamp.ts +0 -3
  312. package/scripts/josh/josh-command-map.ts +2 -0
  313. package/scripts/josh/josh-commands-ai.ts +9 -102
  314. package/scripts/josh/josh-commands-backlog.ts +5 -1
  315. package/scripts/josh/josh-commands-development.ts +8 -1
  316. package/scripts/josh/josh-commands-issue.ts +2 -2
  317. package/scripts/josh/josh-commands-maintenance.ts +7 -0
  318. package/scripts/josh/josh-commands-project.ts +6 -0
  319. package/scripts/josh/josh-commands-run.ts +114 -0
  320. package/scripts/josh/josh-commands-versioning.ts +8 -0
  321. package/scripts/josh/josh-commands-workflow.ts +2 -2
  322. package/scripts/josh/path-decision.ts +0 -3
  323. package/scripts/josh/process-owner.ts +16 -0
  324. package/scripts/josh/session-language-cli.ts +0 -1
  325. package/scripts/lane/lane-await.ts +3 -6
  326. package/scripts/lane/lane-capacity.ts +6 -3
  327. package/scripts/lane/lane-child-invocation.ts +20 -7
  328. package/scripts/lane/lane-cli.ts +1 -4
  329. package/scripts/lane/lane-close.ts +1 -3
  330. package/scripts/lane/lane-dispatch.ts +3 -4
  331. package/scripts/lane/lane-environment.ts +0 -9
  332. package/scripts/lane/lane-handoff.ts +38 -0
  333. package/scripts/lane/lane-launch-cli.ts +21 -11
  334. package/scripts/lane/lane-open.ts +0 -3
  335. package/scripts/lane/lane-output.ts +0 -1
  336. package/scripts/lane/lane-registry.ts +9 -0
  337. package/scripts/lane/openai-lane-ship.ts +2 -0
  338. package/scripts/lane/openai-lane-supervisor-decision.ts +2 -1
  339. package/scripts/lane/openai-lane-supervisor.ts +6 -4
  340. package/scripts/lane/openai-review-broker.ts +3 -0
  341. package/scripts/lib/bounded-pool.ts +1 -0
  342. package/scripts/lib/json-value.ts +5 -4
  343. package/scripts/lib/poll.ts +3 -1
  344. package/scripts/lib/timed-fetch.ts +15 -0
  345. package/scripts/lib/timeouts.ts +13 -0
  346. package/scripts/{yaml → lib}/yaml-document.ts +3 -1
  347. package/scripts/{bytes → lines}/bytes-command.ts +0 -2
  348. package/scripts/lines/lines-command.ts +0 -1
  349. package/scripts/lint/lint-related-scope.ts +0 -1
  350. package/scripts/lint/lint-related.ts +1 -1
  351. package/scripts/{git → notify}/telegram-notify.ts +2 -2
  352. package/scripts/{git → notify}/telegram-test.ts +4 -4
  353. package/scripts/observations/observation-ledger-home.ts +0 -1
  354. package/scripts/observations/observation-ledger-line.ts +0 -1
  355. package/scripts/observations/observation-ledger-migrate.ts +1 -1
  356. package/scripts/observations/observations-flush-landing.ts +3 -3
  357. package/scripts/observations/observations-flush.ts +2 -2
  358. package/scripts/overrides/lockfile-overrides.ts +1 -1
  359. package/scripts/overrides/overrides-logic.ts +1 -1
  360. package/scripts/package/package-scout-cli.ts +2 -7
  361. package/scripts/package/package-scout.ts +0 -2
  362. package/scripts/propagate/propagate-git-failure.ts +0 -1
  363. package/scripts/propagate/propagate-git.ts +0 -2
  364. package/scripts/propagate/propagate-publish.ts +2 -3
  365. package/scripts/propagate/propagate-run.ts +0 -2
  366. package/scripts/propagate/propagate-steps.ts +3 -5
  367. package/scripts/propagate/propagate-targets.ts +0 -4
  368. package/scripts/propagate/propagate.ts +0 -4
  369. package/scripts/refactor/import-graph.ts +0 -1
  370. package/scripts/refactor/refactor-lint.ts +0 -2
  371. package/scripts/refactor/refactor-scan.ts +0 -1
  372. package/scripts/refactor/refactor-targets.ts +0 -1
  373. package/scripts/registry-migration/migrate-logic.ts +0 -2
  374. package/scripts/registry-migration/migrate.ts +19 -9
  375. package/scripts/release/github-release-cli.ts +8 -6
  376. package/scripts/release/github-release-environment.ts +46 -0
  377. package/scripts/release/github-release.ts +151 -94
  378. package/scripts/release/release-history.ts +0 -1
  379. package/scripts/release/release-plan.ts +0 -1
  380. package/scripts/release/release-publish.ts +2 -3
  381. package/scripts/release/release-scope-cli.ts +1 -2
  382. package/scripts/release/release-tag.ts +2 -4
  383. package/scripts/repo/auto-merge-setting-logic.ts +1 -4
  384. package/scripts/repo/repo-setting.ts +1 -1
  385. package/scripts/repo/repository-labels.ts +3 -3
  386. package/scripts/repo/required-checks-logic.ts +206 -0
  387. package/scripts/repo/required-checks-report.ts +71 -0
  388. package/scripts/repo/ruleset-check-cli.ts +53 -0
  389. package/scripts/repo/ruleset-check.ts +147 -0
  390. package/scripts/report/report-lint-cli.ts +0 -4
  391. package/scripts/review/disposition-cli.ts +1 -1
  392. package/scripts/review/live-evidence.ts +1 -1
  393. package/scripts/review/review-attest-cli.ts +0 -6
  394. package/scripts/review/review-attest.ts +4 -16
  395. package/scripts/review/review-brief-cli.ts +23 -6
  396. package/scripts/review/review-brief.ts +21 -8
  397. package/scripts/review/review-diff-parts.ts +89 -0
  398. package/scripts/review/review-diff-write.ts +97 -0
  399. package/scripts/review/review-finding-ledger.ts +0 -1
  400. package/scripts/review/review-record-cli.ts +1 -1
  401. package/scripts/review/review-record.ts +0 -1
  402. package/scripts/review/review-round2-cli.ts +1 -1
  403. package/scripts/review/review-stamps.ts +0 -3
  404. package/scripts/review/review-tree.ts +14 -2
  405. package/scripts/rules/decision-oracle-stage.ts +18 -0
  406. package/scripts/rules/decision-oracle.ts +10 -7
  407. package/scripts/rules/delivered-rules.ts +9 -1
  408. package/scripts/rules/destructive-command.ts +119 -0
  409. package/scripts/rules/direct-filing.ts +1 -1
  410. package/scripts/rules/file-body.ts +0 -3
  411. package/scripts/rules/filing-cap.ts +0 -2
  412. package/scripts/rules/gh-api.ts +7 -2
  413. package/scripts/rules/git-argv.ts +18 -7
  414. package/scripts/rules/git-force.ts +0 -2
  415. package/scripts/rules/implementation-cut.ts +0 -1
  416. package/scripts/rules/index-guard.ts +71 -0
  417. package/scripts/rules/issue-citation.ts +50 -25
  418. package/scripts/rules/lane-background.ts +15 -7
  419. package/scripts/rules/lane-park.ts +13 -6
  420. package/scripts/rules/last-prompt.ts +1 -0
  421. package/scripts/rules/oracle-consulted.ts +1 -1
  422. package/scripts/rules/oracle-firing.ts +1 -0
  423. package/scripts/rules/oracle-list-cli.ts +0 -3
  424. package/scripts/rules/permission-guards.ts +14 -0
  425. package/scripts/rules/protected-files.ts +74 -0
  426. package/scripts/rules/reply-language.ts +1 -1
  427. package/scripts/rules/rule-body-guard.ts +0 -3
  428. package/scripts/rules/rule-value-cli.ts +0 -1
  429. package/scripts/rules/shell-body-trigger.ts +0 -1
  430. package/scripts/rules/shell-segments.ts +0 -1
  431. package/scripts/rules/stop-rules.ts +13 -5
  432. package/scripts/rules/tail-commands.ts +1 -1
  433. package/scripts/rules/test-declared-commit.ts +1 -1
  434. package/scripts/rules/third-party-write.ts +0 -1
  435. package/scripts/rules/worktree-guard.ts +26 -9
  436. package/scripts/run/run-carry-cli.ts +0 -2
  437. package/scripts/run/run-carry-stash.ts +2 -2
  438. package/scripts/run/run-carry-streak.ts +1 -1
  439. package/scripts/run/run-cut-cli.ts +0 -7
  440. package/scripts/run/run-cut.ts +8 -54
  441. package/scripts/run/run-ending-cli.ts +1 -1
  442. package/scripts/run/run-ending.ts +1 -4
  443. package/scripts/run/run-entry-cli.ts +101 -24
  444. package/scripts/run/run-entry.ts +0 -1
  445. package/scripts/run/run-event-cli.ts +0 -2
  446. package/scripts/run/run-event-follow.ts +1 -0
  447. package/scripts/run/run-event-render.ts +1 -1
  448. package/scripts/run/run-event-scope.ts +53 -4
  449. package/scripts/run/run-event-stream.ts +0 -3
  450. package/scripts/run/run-event-watch.ts +1 -0
  451. package/scripts/run/run-halfrun-resume.ts +20 -7
  452. package/scripts/run/run-headless.ts +2 -2
  453. package/scripts/run/run-hold-cli.ts +33 -10
  454. package/scripts/run/run-hold.ts +25 -5
  455. package/scripts/run/run-issue-number.ts +1 -1
  456. package/scripts/run/run-liveness-cli.ts +1 -1
  457. package/scripts/run/run-liveness.ts +2 -3
  458. package/scripts/run/run-merge-cli.ts +5 -13
  459. package/scripts/run/run-merge-steps.ts +5 -5
  460. package/scripts/run/run-merge.ts +1 -1
  461. package/scripts/run/run-next-cli.ts +1 -1
  462. package/scripts/run/run-parent-cut-hook.ts +0 -1
  463. package/scripts/run/run-preflight.ts +2 -9
  464. package/scripts/run/run-prep-cli.ts +2 -2
  465. package/scripts/run/run-prep-locate.ts +1 -1
  466. package/scripts/run/run-progress-cli.ts +4 -7
  467. package/scripts/run/run-progress-clock.ts +6 -34
  468. package/scripts/run/run-progress-config.ts +0 -4
  469. package/scripts/run/run-progress-read.ts +1 -2
  470. package/scripts/run/run-progress.ts +1 -2
  471. package/scripts/run/run-prrun-resume.ts +117 -0
  472. package/scripts/run/run-report-cli.ts +1 -2
  473. package/scripts/run/run-report.ts +0 -1
  474. package/scripts/run/run-retrospective.ts +1 -1
  475. package/scripts/run/run-review-cli.ts +0 -3
  476. package/scripts/run/run-review-steps.ts +2 -0
  477. package/scripts/run/run-review.ts +0 -2
  478. package/scripts/run/run-ship-cli.ts +21 -3
  479. package/scripts/run/run-ship-detach.ts +1 -0
  480. package/scripts/run/run-ship-next.ts +106 -0
  481. package/scripts/run/run-ship-preflight.ts +1 -1
  482. package/scripts/run/run-ship-return.ts +8 -3
  483. package/scripts/run/run-ship-review-steps.ts +18 -4
  484. package/scripts/run/run-ship-review.ts +11 -0
  485. package/scripts/run/run-ship-scoped.ts +1 -0
  486. package/scripts/run/run-ship-steps.ts +1 -1
  487. package/scripts/run/run-ship.ts +0 -1
  488. package/scripts/run/run-stage-read.ts +62 -0
  489. package/scripts/run/run-stage.ts +160 -0
  490. package/scripts/run/run-status-cli.ts +1 -1
  491. package/scripts/run/run-step-cli.ts +21 -14
  492. package/scripts/run/run-step.ts +1 -1
  493. package/scripts/run/run-stop-notify.ts +1 -3
  494. package/scripts/run/run-stranded-cli.ts +0 -4
  495. package/scripts/run/run-stranded-detect.ts +2 -2
  496. package/scripts/run/run-tail-cli.ts +17 -11
  497. package/scripts/run/run-tail.ts +2 -0
  498. package/scripts/run/run-tidy-lanes.ts +2 -1
  499. package/scripts/run/run-tidy-stashes.ts +12 -12
  500. package/scripts/run/run-wake-cli.ts +2 -3
  501. package/scripts/run/run-wake-loop.ts +2 -2
  502. package/scripts/run/run-wake.ts +2 -4
  503. package/scripts/run/run-watcher-guard-cli.ts +0 -4
  504. package/scripts/run/run-watcher-guard.ts +9 -7
  505. package/scripts/run/run-watcher-hook.ts +1 -1
  506. package/scripts/safe-chain/ci-installer-pin.ts +11 -5
  507. package/scripts/safe-chain/project-config.ts +1 -1
  508. package/scripts/security/security-audit-provision-logic.ts +0 -1
  509. package/scripts/security/security-audit-provision.ts +3 -2
  510. package/scripts/security/security-audit.ts +0 -1
  511. package/scripts/security/security-updates-logic.ts +0 -1
  512. package/scripts/sonar/sonar-hotspots-cli.ts +10 -52
  513. package/scripts/sonar/sonar-hotspots.ts +0 -1
  514. package/scripts/sonar/sonar-new-code-cli.ts +150 -0
  515. package/scripts/sonar/sonar-new-code.ts +79 -0
  516. package/scripts/sonar/sonar-project.ts +97 -0
  517. package/scripts/split/split-assess-cli.ts +1 -1
  518. package/scripts/split/split-assess.ts +2 -5
  519. package/scripts/sync/managed-config-scope-cli.ts +1 -1
  520. package/scripts/sync/skill-migration.ts +0 -1
  521. package/scripts/sync/sync-hook-safety.ts +2 -3
  522. package/scripts/sync/sync.ts +1 -8
  523. package/scripts/sync/template-source-logic.ts +0 -1
  524. package/scripts/sync/workflow-pin-logic.ts +16 -28
  525. package/scripts/test/test-declared-logic.ts +0 -1
  526. package/scripts/test/test-declared.ts +0 -2
  527. package/scripts/test/test-red-commit.ts +2 -2
  528. package/scripts/test/test-red.ts +14 -7
  529. package/scripts/test/test-type-logic.ts +1 -1
  530. package/scripts/test/unit-worker-share.ts +7 -16
  531. package/scripts/time-runtime/time-batch-guard.ts +1 -2
  532. package/scripts/time-runtime/time-bundle-call.ts +0 -1
  533. package/scripts/time-runtime/time-bundles.ts +0 -4
  534. package/scripts/time-runtime/time-density-hook.ts +0 -2
  535. package/scripts/time-runtime/time-followup-stage.ts +1 -1
  536. package/scripts/time-runtime/time-format.ts +0 -73
  537. package/scripts/time-runtime/time-round-trips.ts +0 -4
  538. package/scripts/time-runtime/time-single-check.ts +1 -1
  539. package/scripts/time-runtime/time-spans.ts +1 -1
  540. package/scripts/time-runtime/time-transcript-line.ts +1 -2
  541. package/scripts/ui/ui-routes-cli.ts +0 -5
  542. package/scripts/ui/ui-routes.ts +0 -5
  543. package/scripts/version/effective-upstream.ts +2 -2
  544. package/scripts/version/latest-corepack.ts +7 -9
  545. package/scripts/version/latest-scope-cli.ts +0 -2
  546. package/scripts/version/latest-update.ts +0 -2
  547. package/scripts/version/npm-registry.ts +2 -2
  548. package/scripts/version/publishable-range-check.ts +1 -1
  549. package/scripts/version/release-hold.ts +0 -4
  550. package/scripts/version/running-binary.ts +2 -2
  551. package/scripts/version/version-check-logic.ts +0 -2
  552. package/scripts/version/version-remote.ts +3 -3
  553. package/scripts/version/version-targets.ts +4 -4
  554. package/templates/sonar-project.properties +28 -1
  555. package/templates/workflows/dependabot-auto-merge.yml +5 -3
  556. package/templates/workflows/github-release.yml +81 -0
  557. package/prompts/collaboration-workflow/cross-repo-epic.md +0 -5
  558. package/prompts/collaboration-workflow/epic-audit.md +0 -5
  559. package/prompts/collaboration-workflow/epic-bundle.md +0 -5
  560. package/scripts/init/plugin-install-hint.ts +0 -47
  561. package/scripts/version/parse-json.ts +0 -13
  562. /package/scripts/{git → followup}/git-followup-stages.ts +0 -0
  563. /package/scripts/{git → gh}/git-gh-api-path.ts +0 -0
  564. /package/scripts/{git → gh}/git-gh-command.ts +0 -0
  565. /package/scripts/{git → gh}/git-gh-issue-write.ts +0 -0
  566. /package/scripts/{git → gh}/git-gh-issue.ts +0 -0
  567. /package/scripts/{git → gh}/git-gh-pr-auto-merge.ts +0 -0
  568. /package/scripts/{git → gh}/git-gh-pr-snapshot.ts +0 -0
  569. /package/scripts/{git → gh}/git-gh-reachability.ts +0 -0
  570. /package/scripts/{git → gh}/git-gh-repo.ts +0 -0
  571. /package/scripts/{git → gh}/git-gh-rest-state.ts +0 -0
  572. /package/scripts/{git → gh}/git-pr-checks-watch.ts +0 -0
  573. /package/scripts/{git → gh}/git-pr-error.ts +0 -0
  574. /package/scripts/{git → gh}/git-pr-messages.ts +0 -0
  575. /package/scripts/{git → gh}/github-issue-url.ts +0 -0
  576. /package/scripts/git/{stash-orphans.ts → stash/stash-orphans.ts} +0 -0
  577. /package/scripts/{git → issue}/issue-reference.ts +0 -0
  578. /package/scripts/{git → lib}/animation-helpers.ts +0 -0
  579. /package/scripts/{git → lib}/git-animation.ts +0 -0
  580. /package/scripts/{git → notify}/git-notify.ts +0 -0
  581. /package/scripts/{git → notify}/telegram-test-logic.ts +0 -0
@@ -41,4 +41,4 @@ pnpm josh issue:file "<title>" --body-file <complete-draft.md> --depth <n> --dis
41
41
  - **The split path files each child through the same command.** The epic is created with
42
42
  `pnpm josh epic` over children that were scanned.
43
43
 
44
- Full behavior: `docs/josh-commands.md` → "`josh issue:file`" and "`josh issue:scout`".
44
+ Full behavior: `docs/josh-commands-automation.md` → "`josh issue:file`" and "`josh issue:scout`".
@@ -1,13 +1,18 @@
1
1
  # `kickoff` — Planning phase only (plan → Issue → Telegram notify → stop)
2
2
 
3
- - `kickoff #<N>`: Read existing Issue #N **and every comment on it** — `pnpm josh issue:read <N>`; a
3
+ - `kickoff #<N>`: **First `pnpm josh run:entry <N> --to kickoff`** (`SKILL.md` → §2k) — it claims
4
+ nothing and prints the stage line alone; `start: reached` means the Issue is already planned or further
5
+ up the ladder, so report the stage line and **stop**. Otherwise read existing Issue #N **and every comment on it** — `pnpm josh issue:read <N>`; a
4
6
  decision recorded after the body was written lives only in a comment, and the later text is the
5
7
  agreement in force (`SKILL.md` → §2g, which also carries the two answers that stop the run instead) →
6
8
  **normalize the title**: if the title is not in English or can be phrased more clearly, derive a
7
9
  better English title and run `gh api -X PATCH repos/{owner}/{repo}/issues/<N> -f title="<title>"` →
8
10
  analyze requirements → **scope assessment per `split-assessment.md`** → post the plan to the Issue (if
9
11
  body is blank, `gh api -X PATCH repos/{owner}/{repo}/issues/<N> -f body="<plan>"`; otherwise
10
- `pnpm josh issue:comment <N> --body-file <path>`) → send Telegram notification → **stop**
12
+ `pnpm josh issue:comment <N> --body-file <path>`) → **apply the `run:planned` label** — the mark the next
13
+ command's `run:entry` reads to start at the implementation, provisioned by `josh sync` (`gh api
14
+ repos/{owner}/{repo}/issues/<N>/labels -f 'labels[]=run:planned' --silent`) → send Telegram
15
+ notification, its last line `Next: halfrun #<N> | prrun #<N> | fullrun #<N>` → **stop**
11
16
  (do not implement). **When the assessment finds two or more separately-mergeable deliverables**, take
12
17
  the split path instead of posting a plan: create the children as in `kickoff new`, then either
13
18
  **promote `#N`** with `pnpm josh epic --promote <N> <N1> <N2> ... [--ordered] [--rationale-file
@@ -37,7 +42,7 @@ than filing.
37
42
  **Read `split-assessment.md` → "The question" first.** It is the split decision every entry point
38
43
  applies, including this one — `kickoff #N` assesses scope exactly as `kickoff new` does. Its default is
39
44
  not to split: separability and a scope that clearly exceeds what one verification gate can confirm in
40
- one pass (the guide is about 10 changed files and about 400 changed lines) have to hold **together**.
45
+ one pass (the size guide is stated there) have to hold **together**.
41
46
  The rest of `split-assessment.md` — what each entry does with the answer — is read on demand when a
42
47
  split is found.
43
48
 
@@ -80,4 +85,4 @@ split is found.
80
85
  creation call. (3) Send Telegram notification listing all created issues. (4) Present the command
81
86
  `backlogrun #<E> --only`. (5) **Stop** — do not implement.
82
87
 
83
- `pnpm josh issue:file` lints the body and applies the classification labels it declares, following `prompts/collaboration-workflow/issue-template.md` for classification (`docs/josh-commands.md` → `josh issue:file`).
88
+ `pnpm josh issue:file` lints the body and applies the classification labels it declares, following `prompts/collaboration-workflow/issue-template.md` for classification (`docs/josh-commands-automation.md` → `josh issue:file`).
@@ -82,4 +82,4 @@ found once — fix it forward before parking the issue for it.
82
82
 
83
83
  This file is the single source of the rule. `fullrun.md`, `halfrun.md`, `backlogrun.md` and `backlogrun.md`
84
84
  each name `pnpm josh latest:scope` at the point their procedure reaches it and route here for
85
- everything else; `docs/josh-commands.md` documents the command itself.
85
+ everything else; `docs/josh-commands-automation.md` documents the command itself.
@@ -57,7 +57,7 @@ run's *start*; this withholds its *end*. So a `needs-human-review` issue is stil
57
57
  the artifact a person is meant to look at would never be produced — and a child stopped by it **goes on
58
58
  holding its repository**, because the uncommitted work is still in the checkout; read as parked there,
59
59
  the next child would start `git switch main && git pull` on top of it. The code encodes both halves by
60
- leaving the label out of two sets: `scripts/git/issue-labels.ts` keeps it out of
60
+ leaving the label out of two sets: `scripts/issue/issue-labels.ts` keeps it out of
61
61
  `NOT_DIRECTLY_RUNNABLE_LABELS` and `scripts/epic/epic-busy.ts` keeps it out of the parked set.
62
62
 
63
63
  Each entry point's own branch stays in its own file — `fullrun.md`, `halfrun.md`,
@@ -19,7 +19,7 @@ Tier C (`CLAUDE.md`). Name what was filed in the completion report. An observati
19
19
  on is dropped rather than filed.
20
20
 
21
21
  **The filing ceilings still apply.** Count this filing in the ten-Issue limit for the run. An
22
- observation is discretionary, so above 30 open Issues in the target repository, close one first or do
22
+ observation is discretionary, so above the WIP cap in the target repository, close one first or do
23
23
  not file (`prompts/collaboration-workflow/wip-cap.md`). File it with `pnpm josh issue:file`
24
24
  (`issue-scout.md`), which lints the body against `prompts/collaboration-workflow/issue-template.md`,
25
25
  applies the classification labels it declares, runs the duplicate scan, and runs `epic:bundle` on the
@@ -42,7 +42,7 @@ The detail below is read at the filing decision, and the marker suite pins the r
42
42
 
43
43
  **The depth is recorded on the Issue as a label, and the label is applied when the Issue is filed**
44
44
  (joshuafolkken/kit#1729). `depth:0`, `depth:1` and `depth:2` are the three, defined once in
45
- `scripts/git/issue-labels.ts` and carrying no definition of their own — **the table above is the
45
+ `scripts/issue/issue-labels.ts` and carrying no definition of their own — **the table above is the
46
46
  single source**, and a label description that paraphrased it would be a second copy of the rule.
47
47
  **Every filing route applies one**, this route and the other three of §2d's table alike: a `new`
48
48
  entry point, a `route:tier-a` prerequisite, a `route:interrupt`, a split child and a review round
@@ -56,7 +56,7 @@ gh api repos/{owner}/{repo}/issues/<N>/labels -f 'labels[]=depth:1' # an Issue
56
56
 
57
57
  **Create the three once per repository**, before the first filing that applies one — REST auto-creates
58
58
  a missing label with a generated color and no description, and the three lines below are what give
59
- each a stable color a reader can scan a listing by. `DEPTH_LABELS` in `scripts/git/issue-labels.ts`
59
+ each a stable color a reader can scan a listing by. `DEPTH_LABELS` in `scripts/issue/issue-labels.ts`
60
60
  is the single source of the colors and descriptions, and `scripts/rules/issue-depth-label.test.ts` keys
61
61
  these lines to it so the two cannot drift.
62
62
 
@@ -31,7 +31,7 @@ pnpm josh issue:file "<title>" --body-file <body-file> --depth <n> --route tier-
31
31
 
32
32
  The command lints the body against `prompts/collaboration-workflow/issue-template.md`, applies the
33
33
  classification labels it declares, and runs the duplicate scan and `epic:bundle` itself
34
- (`docs/josh-commands.md` → `josh issue:file`).
34
+ (`docs/josh-commands-automation.md` → `josh issue:file`).
35
35
 
36
36
  Every "file the prerequisite" below means that labelled filing, and it always happens **first**: the
37
37
  steps after it name a number that does not exist until it is. **Its duplicate scan is read exactly as
@@ -0,0 +1,36 @@
1
+ # `prrun` — the manifest (plan → implement → PR → green → stop, a person merges)
2
+
3
+ `prrun` sits between `halfrun` (stop before commit) and `fullrun` (auto-merge). It runs `fullrun`
4
+ up to a green, mergeable pull request and **stops before the merge**, so a person merges by hand
5
+ (joshuafolkken/kit#3023). **Read `fullrun.md` for every step** — the entry sequence, the step lists,
6
+ the gate, the review and the stop branches are `fullrun`'s, unchanged. This file names only the
7
+ difference, never a second copy of the procedure.
8
+
9
+ ## The difference — the entry
10
+
11
+ `prrun #<N>` opens with `pnpm josh run:entry <N> --to prrun` where `fullrun` passes no `--to`
12
+ (`SKILL.md` → §2k): a planned Issue starts at the implementation, a `halfrun` stop is adopted and
13
+ resumes at the gate, and an Issue already stopped by a `prrun` is reached — report the stage line and
14
+ stop. A merged Issue is reached too, but the `entry #<N>` line after the stage line answers it (§2k).
15
+
16
+ ## The difference — the end of the run
17
+
18
+ Where `fullrun` runs `pnpm josh followup` and merges, `prrun` does three things and stops:
19
+
20
+ 1. **Watch the pull request to mergeable** — `pnpm josh followup "<title> #<N>" --no-merge`
21
+ (`followup.md` → "Run `pnpm josh followup`", read in the same turn): required CI green and the AI
22
+ review findings resolved. A failure stops the run exactly as it stops a `fullrun`.
23
+ 2. **Mark the stop — `pnpm josh run:hold <N> --prrun-stop`.** It records the commit the pull request is
24
+ on in this run's own hold, the record `fullrun #<N>` adopts (its prrun resume, `working-tree-hold.md`). **The hold and `in-progress` stay**: the run is not finished until the merge's tail runs.
25
+ 3. **Send a `confirmation` Telegram with the resume commands, then stop.** **`fullrun #<N>` first** —
26
+ its `run:entry` reads where the pull request stands and resumes from there; the direct command
27
+ follows for finishing without an agent:
28
+ `pnpm josh notify --task-type confirmation --issue-url "<issue-url>" --body=$'prrun ready to
29
+ merge: <pr-url>\nNext: fullrun #<N>\nAfter a manual merge, without an agent: pnpm josh followup
30
+ "<title> #<N>"'`. The stop report names the same two, in the same order.
31
+
32
+ **Invoking `prrun` is _not_ authorization to merge** — never run `pnpm josh followup` without
33
+ `--no-merge` in a `prrun`. After a person merges by hand, the same `pnpm josh followup "<title> #<N>"`
34
+ runs only the post-merge tail (`followup.md`).
35
+
36
+ `prrun new`: `fullrun new` up to the pull request, then the three steps above with the filed number.
@@ -65,7 +65,7 @@ Issue, as after any filing.
65
65
  input, so the next run picks the improvements up without waiting for a person. **`backlogrun-steps.md` →
66
66
  "What one invocation approves" is that carve-out's single source**; it is written there, beside the
67
67
  brakes that bound it, rather than restated here. Every brake still counts a retrospective's filings: the
68
- ten-per-invocation ceiling, the WIP cap of 30, `--max`, the 150,000-token session budget and the 8-hour
68
+ ten-per-invocation ceiling, the WIP cap, `--max`, the 150,000-token session budget and the 8-hour
69
69
  whole-run bound.
70
70
 
71
71
  **Close with `pnpm josh run:carry --retrospective --summary "<result>" --owner "$PPID"`.** It marks the
@@ -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,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
+ # (`pr-classification.yml`), stamped as managed like they are (joshuafolkken/kit#3013).
14
+ # `templates/workflows/ci.yml` still carries the same steps inline — it was written before this file
15
+ # was distributed, and moving it onto the action is a change of its own. `workflow_pin_logic` reads
16
+ # this file as a source of canonical action pins, so the template's refs still resolve from here.
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 /
@@ -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:
@@ -239,30 +229,6 @@ jobs:
239
229
  node-version: '24'
240
230
  registry-url: 'https://npm.pkg.github.com'
241
231
 
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
232
  - name: Setup ESLint cache
267
233
  uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
268
234
  id: eslint-cache
@@ -317,17 +283,10 @@ jobs:
317
283
  ${{ runner.os }}-cspell-cache-${{ hashFiles('pnpm-lock.yaml') }}-
318
284
  ${{ runner.os }}-cspell-cache-
319
285
 
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
286
+ - name: Setup pnpm and install dependencies
287
+ uses: ./.github/actions/setup-pnpm
288
+ with:
289
+ node-auth-token: ${{ secrets.GITHUB_TOKEN }}
331
290
 
332
291
  # One step rather than five, and concurrent rather than serial (joshuafolkken/kit#1216).
333
292
  # `josh gate` is the command a developer runs before committing; it fans out to the same
@@ -366,13 +325,10 @@ jobs:
366
325
  - name: Run verification gate
367
326
  run: pnpm josh gate --verbose --no-unit
368
327
 
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.
328
+ # The other half of the gate, on a runner of its own. A GitHub job is its own machine, so this job
329
+ # sets Node up again; the pnpm preamble is the shared `.github/actions/setup-pnpm` action
330
+ # (joshuafolkken/kit#2982), whose own action pins `scripts/ci/ci-yml-action-parity.test.ts` counts
331
+ # as this file's when it compares them with `templates/workflows/ci.yml`.
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:
@@ -396,41 +352,10 @@ jobs:
396
352
  node-version: '24'
397
353
  registry-url: 'https://npm.pkg.github.com'
398
354
 
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
408
- 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
355
+ - name: Setup pnpm and install dependencies
356
+ uses: ./.github/actions/setup-pnpm
417
357
  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
358
+ node-auth-token: ${{ secrets.GITHUB_TOKEN }}
434
359
 
435
360
  # **Through `josh test:unit`, never `vitest run` directly, and that is what makes a job split
436
361
  # safe rather than a hole.** The guard decides between a skip and a failure, and
@@ -457,6 +382,10 @@ jobs:
457
382
  # through with an E2E suite that never ran (see the `Detect E2E` job below, and
458
383
  # https://github.com/joshuafolkken/kit/issues/991). A skipped aggregator would have reproduced that
459
384
  # defect on the unit suite. Running always and failing explicitly is the only shape that cannot.
385
+ # That is also why this job alone keeps `always()` while the two halves use `!cancelled()`
386
+ # (joshuafolkken/kit#2980): a cancelled run must stop the minutes-long halves, but a skipped
387
+ # `Checks` on a cancelled head-SHA run would read as passing, so this seconds-long job still runs
388
+ # and fails on the halves' `cancelled` results.
460
389
  #
461
390
  # The results are read from the environment rather than interpolated into the script. `needs.*.result`
462
391
  # is a GitHub-controlled enum and not attacker-controlled, but a `${{ }}` expression spliced into a
@@ -601,30 +530,6 @@ jobs:
601
530
  node-version: '24'
602
531
  registry-url: 'https://npm.pkg.github.com'
603
532
 
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
533
  - name: Setup build cache
629
534
  uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
630
535
  id: build-cache
@@ -636,17 +541,10 @@ jobs:
636
541
  ${{ runner.os }}-build-cache-e2e-${{ hashFiles('pnpm-lock.yaml') }}-
637
542
  ${{ runner.os }}-build-cache-e2e-
638
543
 
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
544
+ - name: Setup pnpm and install dependencies
545
+ uses: ./.github/actions/setup-pnpm
546
+ with:
547
+ node-auth-token: ${{ secrets.GITHUB_TOKEN }}
650
548
 
651
549
  # Only needed on the fallback path: the container image already ships browsers
652
550
  # matching its own Playwright version. Invoked through the local bin rather than