@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
@@ -1,12 +1,27 @@
1
1
  #!/usr/bin/env tsx
2
- import { readdirSync, rmSync } from 'node:fs'
2
+ import {
3
+ mkdirSync,
4
+ mkdtempSync,
5
+ readdirSync,
6
+ readFileSync,
7
+ renameSync,
8
+ rmSync,
9
+ writeFileSync,
10
+ } from 'node:fs'
3
11
  import path from 'node:path'
4
12
  import { fileURLToPath } from 'node:url'
13
+ import { hook_bundle_stamp } from '#scripts/build/hook-bundle-stamp'
5
14
  import { error_text } from '#scripts/lib/error-message'
6
- import { build } from 'esbuild'
15
+ import { build, type OnLoadArgs, type OutputFile, type Plugin, type PluginBuild } from 'esbuild'
7
16
 
8
17
  const PACKAGE_DIR = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', '..')
9
18
  const OUT_DIR = path.join(PACKAGE_DIR, 'dist', 'hooks')
19
+ const { STAMP_NAME } = hook_bundle_stamp
20
+ const CHUNK_PREFIX = 'chunk-'
21
+ const STAGING_PREFIX = '.hooks-staging-'
22
+ // esbuild compiles a plugin filter as a Go regexp, which rejects the `u` flag.
23
+ // eslint-disable-next-line require-unicode-regexp
24
+ const ANY_PATH = /.*/
10
25
 
11
26
  // Each Claude Code hook is bundled to its own `dist/hooks/<name>.js`, so a consumer (and kit itself)
12
27
  // invokes `node dist/hooks/<name>.js` directly — no `pnpm` launch and no `tsx` re-spawn from the
@@ -60,20 +75,76 @@ function outfile_for(bundle: HookBundle): string {
60
75
  // The output directory is flat (every entry and chunk sits at its top level), so a file whose name
61
76
  // this build did not emit is a leftover of an earlier one.
62
77
  function prune_stale_outputs(out_directory: string, outputs: ReadonlyArray<string>): void {
63
- const live = new Set(outputs.map((output) => path.basename(output)))
78
+ const live = new Set([...outputs.map((output) => path.basename(output)), STAMP_NAME])
64
79
 
65
80
  for (const name of readdirSync(out_directory)) {
66
81
  if (!live.has(name)) rmSync(path.join(out_directory, name), { recursive: true, force: true })
67
82
  }
68
83
  }
69
84
 
85
+ // Every file the build loads is read here, so the stamp digests the exact bytes that were bundled —
86
+ // a source edited mid-build is recorded as what it was, and the next launch rebuilds it.
87
+ function source_recorder(sources: Map<string, Uint8Array>): Plugin {
88
+ return {
89
+ name: 'hook-source-recorder',
90
+ setup(plugin_build: PluginBuild): void {
91
+ plugin_build.onLoad({ filter: ANY_PATH, namespace: 'file' }, function load(args: OnLoadArgs) {
92
+ const contents = readFileSync(args.path)
93
+
94
+ sources.set(path.relative(PACKAGE_DIR, args.path), contents)
95
+
96
+ return { contents, loader: 'default' }
97
+ })
98
+ },
99
+ }
100
+ }
101
+
102
+ function is_chunk(file: OutputFile): boolean {
103
+ return path.basename(file.path).startsWith(CHUNK_PREFIX)
104
+ }
105
+
106
+ // Shared chunks first, then the entries that import them: an entry swapped in before its chunks
107
+ // would fail to load in a hook launched at that moment.
108
+ function is_chunk_first(left: OutputFile, right: OutputFile): number {
109
+ return Number(is_chunk(right)) - Number(is_chunk(left))
110
+ }
111
+
112
+ // Each file is written into a private staging directory and renamed into place, so a hook never
113
+ // reads a half-written bundle and two builds running side by side never write one file at once.
114
+ function place(staging: string, target: string, contents: Uint8Array | string): void {
115
+ const temporary = path.join(staging, path.basename(target))
116
+
117
+ writeFileSync(temporary, contents)
118
+ renameSync(temporary, target)
119
+ }
120
+
121
+ function place_build(out_directory: string, files: ReadonlyArray<OutputFile>, stamp: string): void {
122
+ mkdirSync(out_directory, { recursive: true })
123
+ const staging = mkdtempSync(path.join(path.dirname(out_directory), STAGING_PREFIX))
124
+
125
+ try {
126
+ for (const file of files.toSorted(is_chunk_first)) place(staging, file.path, file.contents)
127
+ prune_stale_outputs(
128
+ out_directory,
129
+ files.map((file) => file.path),
130
+ )
131
+ place(staging, path.join(out_directory, STAMP_NAME), stamp)
132
+ } finally {
133
+ rmSync(staging, { recursive: true, force: true })
134
+ }
135
+ }
136
+
70
137
  // With `splitting: true` every build emits freshly hashed `chunk-*.js` files, so without a cleanup
71
138
  // the chunks of every earlier build pile up beside the live ones and ship in any local pack
72
- // (joshuafolkken/kit#2885). The cleanup runs after the build rather than emptying the directory
73
- // first: this checkout's own settings.json launches `node dist/hooks/<name>.js` on every tool call,
74
- // and an emptied directory would make a hook launched mid-build fail to load and its guard fail open.
139
+ // (joshuafolkken/kit#2885). The cleanup runs after the new files are in place rather than emptying
140
+ // the directory first: this checkout's own settings.json launches `node dist/hooks/<name>.js` on
141
+ // every tool call, and an emptied directory would make a hook launched mid-build fail to load and its
142
+ // guard fail open. The source digest is placed last (`hook-bundle-stamp.ts`), so a launch only reads
143
+ // the bundles as fresh once every one of them is in place (joshuafolkken/kit#2984).
75
144
  async function build_hooks(out_directory: string = OUT_DIR): Promise<void> {
76
- const { metafile } = await build({
145
+ const sources = new Map<string, Uint8Array>()
146
+ const { outputFiles: files } = await build({
147
+ absWorkingDir: PACKAGE_DIR,
77
148
  entryPoints: HOOK_BUNDLES.map((bundle) => entry_point(bundle)),
78
149
  outdir: out_directory,
79
150
  bundle: true,
@@ -82,10 +153,15 @@ async function build_hooks(out_directory: string = OUT_DIR): Promise<void> {
82
153
  format: 'esm',
83
154
  target: 'node22',
84
155
  packages: 'external',
85
- metafile: true,
156
+ write: false,
157
+ plugins: [source_recorder(sources)],
86
158
  })
159
+ const stamp = hook_bundle_stamp.stamp_text(
160
+ sources,
161
+ files.map((file) => file.path),
162
+ )
87
163
 
88
- prune_stale_outputs(out_directory, Object.keys(metafile.outputs))
164
+ place_build(out_directory, files, stamp)
89
165
  }
90
166
 
91
167
  async function main(): Promise<void> {
@@ -0,0 +1,111 @@
1
+ import { createHash } from 'node:crypto'
2
+ import { existsSync, readFileSync } from 'node:fs'
3
+ import path from 'node:path'
4
+ import { json_value } from '#scripts/lib/json-value'
5
+
6
+ // What a hook build was made from, so a later launch can tell whether `dist/hooks/` still matches the
7
+ // source it runs beside (joshuafolkken/kit#2984). `dist/` is git-ignored and rebuilt only by
8
+ // `pnpm build`, so without this record an edited guard keeps running its old bundle with nothing to
9
+ // say so — and a lane's bundles are copied from the main checkout, whose source can differ.
10
+ //
11
+ // **The record is a content digest, not a timestamp.** A copy (`lane-cache.ts`) or a fresh checkout
12
+ // rewrites every mtime while leaving the content alone, and a digest is the only comparison that
13
+ // neither rebuilds on that nor misses an edit that kept the old mtime.
14
+ //
15
+ // **The digest is taken from the bytes the build read, never re-read from disk afterwards.** A source
16
+ // edited while the build runs would otherwise be recorded as built, and its stale bundle read as fresh.
17
+ //
18
+ // This module is loaded by plain `node` on every hook launch (`scripts/hooks/hook-bundle-ready.ts`),
19
+ // so it imports `node:` built-ins and `#scripts/*` subpaths alone — nothing slow to load.
20
+
21
+ const STAMP_NAME = 'inputs.json'
22
+ const DIGEST_ALGORITHM = 'sha256'
23
+ const JSON_INDENT = '\t'
24
+
25
+ interface HookBundleStamp {
26
+ digest: string
27
+ inputs: Array<string>
28
+ outputs: Array<string>
29
+ }
30
+
31
+ // Package-relative input path → the bytes the build read for it.
32
+ type HookSources = ReadonlyMap<string, Uint8Array>
33
+
34
+ // Code-unit order, so the digest does not depend on the locale of the machine that computes it.
35
+ function by_code_unit(left: string, right: string): number {
36
+ if (left === right) return 0
37
+
38
+ return left < right ? -1 : 1
39
+ }
40
+
41
+ // Inputs are hashed in sorted order with their names, so a rename or a reorder changes the digest.
42
+ function digest_of(sources: HookSources): string {
43
+ const hash = createHash(DIGEST_ALGORITHM)
44
+
45
+ for (const input of [...sources.keys()].toSorted(by_code_unit)) {
46
+ hash.update(`${input}\0`).update(sources.get(input) ?? new Uint8Array())
47
+ }
48
+
49
+ return hash.digest('hex')
50
+ }
51
+
52
+ // The record for a build that read `sources` and emitted `outputs`, as the text to write.
53
+ function stamp_text(sources: HookSources, outputs: ReadonlyArray<string>): string {
54
+ const stamp: HookBundleStamp = {
55
+ digest: digest_of(sources),
56
+ inputs: [...sources.keys()],
57
+ outputs: outputs.map((output) => path.basename(output)),
58
+ }
59
+
60
+ return `${JSON.stringify(stamp, undefined, JSON_INDENT)}\n`
61
+ }
62
+
63
+ // Undefined when an input is gone: a deleted input cannot match any digest.
64
+ function read_sources(
65
+ package_directory: string,
66
+ inputs: ReadonlyArray<string>,
67
+ ): HookSources | undefined {
68
+ const sources = new Map<string, Uint8Array>()
69
+
70
+ for (const input of inputs) {
71
+ const file_path = path.join(package_directory, input)
72
+ if (!existsSync(file_path)) return undefined
73
+ sources.set(input, readFileSync(file_path))
74
+ }
75
+
76
+ return sources
77
+ }
78
+
79
+ function is_string_array(value: unknown): value is Array<string> {
80
+ return Array.isArray(value) && value.every((item) => typeof item === 'string')
81
+ }
82
+
83
+ function is_stamp(value: unknown): value is HookBundleStamp {
84
+ if (!json_value.is_record(value) || typeof value['digest'] !== 'string') return false
85
+
86
+ return is_string_array(value['inputs']) && is_string_array(value['outputs'])
87
+ }
88
+
89
+ // A record of any other shape — hand-edited, truncated, or from an older format — reads as no record.
90
+ function read_stamp(out_directory: string): HookBundleStamp | undefined {
91
+ const stamp_path = path.join(out_directory, STAMP_NAME)
92
+ if (!existsSync(stamp_path)) return undefined
93
+ const stamp = json_value.parse_or_undefined(readFileSync(stamp_path, 'utf8'))
94
+
95
+ return is_stamp(stamp) ? stamp : undefined
96
+ }
97
+
98
+ // Fresh only when the record exists, every output it lists is still there, and the listed inputs hash
99
+ // to the recorded digest — a missing or deleted input counts as stale.
100
+ function is_fresh(out_directory: string, package_directory: string): boolean {
101
+ const stamp = read_stamp(out_directory)
102
+ if (!stamp?.outputs.every((output) => existsSync(path.join(out_directory, output)))) return false
103
+ const sources = read_sources(package_directory, stamp.inputs)
104
+
105
+ return sources !== undefined && digest_of(sources) === stamp.digest
106
+ }
107
+
108
+ const hook_bundle_stamp = { is_fresh, STAMP_NAME, stamp_text }
109
+
110
+ export type { HookSources }
111
+ export { hook_bundle_stamp }
@@ -41,7 +41,7 @@ function main(argv: ReadonlyArray<string>): void {
41
41
  process.exitCode = run(argv)
42
42
  }
43
43
 
44
- const cases_cli = { USAGE, main, run }
44
+ const cases_cli = { run }
45
45
 
46
46
  if (process.argv[1] === fileURLToPath(import.meta.url)) main(process.argv.slice(ARGV_OFFSET))
47
47
 
@@ -90,7 +90,7 @@ const VOCABULARY: ReadonlyArray<string> = [
90
90
  NONE,
91
91
  ]
92
92
 
93
- const cases = { BOUNDARIES, NONE, VOCABULARY, boundaries_in, cases_for }
93
+ const cases = { NONE, VOCABULARY, boundaries_in, cases_for }
94
94
 
95
95
  export type { Boundary }
96
96
  export { cases }
@@ -0,0 +1,30 @@
1
+ import { existsSync, readdirSync } from 'node:fs'
2
+
3
+ // A local composite action is one directory under `.github/actions`, and GitHub resolves
4
+ // `uses: ./.github/actions/<name>` to that directory's `action.yml` (or `action.yaml`). Workflow
5
+ // scanners that read `.github/workflows` read these files too: `.github/actions/setup-pnpm` holds
6
+ // the pnpm/setup pin and the safe-chain installer pin kit's workflows used to carry inline
7
+ // (joshuafolkken/kit#2982).
8
+ const ACTIONS_DIRECTORY = '.github/actions'
9
+ const ACTION_FILE_NAMES = ['action.yml', 'action.yaml']
10
+
11
+ function as_is(relative_path: string): string {
12
+ return relative_path
13
+ }
14
+
15
+ // Relative paths, resolved for the file-system calls through `resolve` — the identity for a
16
+ // consumer's working directory, `package_path` for kit's own package.
17
+ function list(resolve: (relative_path: string) => string = as_is): Array<string> {
18
+ if (!existsSync(resolve(ACTIONS_DIRECTORY))) return []
19
+
20
+ return readdirSync(resolve(ACTIONS_DIRECTORY))
21
+ .toSorted((left, right) => left.localeCompare(right))
22
+ .flatMap((name) =>
23
+ ACTION_FILE_NAMES.map((file_name) => `${ACTIONS_DIRECTORY}/${name}/${file_name}`),
24
+ )
25
+ .filter((relative_path) => existsSync(resolve(relative_path)))
26
+ }
27
+
28
+ const composite_actions = { list }
29
+
30
+ export { composite_actions }
@@ -1,13 +1,13 @@
1
1
  import { readFileSync } from 'node:fs'
2
2
  import { fileURLToPath } from 'node:url'
3
- import { git_gh_exec } from '#scripts/git/git-gh-exec'
3
+ import { git_gh_exec } from '#scripts/gh/git-gh-exec'
4
4
  import {
5
5
  BREAKING_CHANGE_LABEL as BREAKING,
6
6
  BUGFIX_LABEL as BUGFIX,
7
7
  RELEASE_CLASSIFICATION_NAMES as CLASSIFICATION_LABELS,
8
8
  ENHANCEMENT_LABEL,
9
9
  type ReleaseClassification,
10
- } from '#scripts/git/issue-labels'
10
+ } from '#scripts/issue/issue-labels'
11
11
  import { error_text } from '#scripts/lib/error-message'
12
12
  import { z } from 'zod'
13
13
 
@@ -144,4 +144,4 @@ export { pr_classification }
144
144
  export {
145
145
  RELEASE_CLASSIFICATION_NAMES as CLASSIFICATION_LABELS,
146
146
  type ReleaseClassification,
147
- } from '#scripts/git/issue-labels'
147
+ } from '#scripts/issue/issue-labels'
@@ -6,8 +6,17 @@
6
6
  // Matches a consumer workflow destination, absolute or repo-relative, on either separator.
7
7
  const WORKFLOW_DESTINATION_PATTERN = /(?:^|[/\\])\.github[/\\]workflows[/\\][^/\\]+\.ya?ml$/u
8
8
 
9
+ // A local composite action is a workflow file too: it pins actions of its own, the distributed
10
+ // `dependabot.yml` bumps it (`/.github/actions/*`), and the next sync writes it back — so it needs
11
+ // the same pins and the same managed stamp as the workflow that calls it (joshuafolkken/kit#3013).
12
+ const COMPOSITE_ACTION_DESTINATION_PATTERN =
13
+ /(?:^|[/\\])\.github[/\\]actions[/\\][^/\\]+[/\\]action\.ya?ml$/u
14
+
9
15
  function is_workflow_destination(destination: string): boolean {
10
- return WORKFLOW_DESTINATION_PATTERN.test(destination)
16
+ return (
17
+ WORKFLOW_DESTINATION_PATTERN.test(destination) ||
18
+ COMPOSITE_ACTION_DESTINATION_PATTERN.test(destination)
19
+ )
11
20
  }
12
21
 
13
22
  export { is_workflow_destination }
@@ -85,7 +85,6 @@ function fingerprints_for(source: string, site: FileSite): Array<Fingerprint> {
85
85
  }
86
86
 
87
87
  const clone_fingerprint = {
88
- WINDOW_SIZE,
89
88
  normalize,
90
89
  is_significant,
91
90
  significant_lines,
@@ -32,7 +32,7 @@ function main(argv: ReadonlyArray<string>): void {
32
32
  process.exitCode = run(argv)
33
33
  }
34
34
 
35
- const clone_scan_cli = { USAGE, main, run }
35
+ const clone_scan_cli = { USAGE, run }
36
36
 
37
37
  if (process.argv[1] === fileURLToPath(import.meta.url)) main(process.argv.slice(ARGV_OFFSET))
38
38
 
@@ -153,6 +153,6 @@ function format_report(groups: ReadonlyArray<CloneGroup>): string {
153
153
  return [header, ...groups.map((group) => format_group(group))].join('\n')
154
154
  }
155
155
 
156
- const clone_scan = { CLEAN_VERDICT, CLONES_PREFIX, scan, format_site, format_group, format_report }
156
+ const clone_scan = { CLEAN_VERDICT, CLONES_PREFIX, scan, format_report }
157
157
 
158
158
  export { clone_scan }
@@ -120,7 +120,6 @@ function format_package_json(value: unknown): string {
120
120
  }
121
121
 
122
122
  const json_format = {
123
- inline_short_arrays,
124
123
  format_json,
125
124
  format_package_json,
126
125
  }
@@ -1,5 +1,5 @@
1
1
  import { string_array_schema } from '#scripts/lib/schemas'
2
- import { yaml_document } from '#scripts/yaml/yaml-document'
2
+ import { yaml_document } from '#scripts/lib/yaml-document'
3
3
  import { dump, type DumpOptions } from 'js-yaml'
4
4
  import { list_patch, type ListEntryMatcher } from './list-patch'
5
5
 
@@ -1,5 +1,6 @@
1
1
  import { globSync, readFileSync } from 'node:fs'
2
2
  import path from 'node:path'
3
+ import { json_value } from '#scripts/lib/json-value'
3
4
  import { z } from 'zod'
4
5
  import { cost_transcript } from './cost-transcript'
5
6
  import type { OverMeasurement } from './cost-verdict'
@@ -23,14 +24,6 @@ const TOKEN_COUNT_SCHEMA = z.looseObject({
23
24
 
24
25
  type Environment = Readonly<Record<string, string | undefined>>
25
26
 
26
- function decode(line: string): unknown {
27
- try {
28
- return JSON.parse(line)
29
- } catch {
30
- return undefined
31
- }
32
- }
33
-
34
27
  function same_project(cwd: string, target: string): boolean {
35
28
  return cost_transcript.session_cwd(cwd) === cost_transcript.session_cwd(target)
36
29
  }
@@ -51,7 +44,7 @@ function measurement_from(
51
44
  target: string,
52
45
  thread_id: string,
53
46
  ): OverMeasurement | undefined {
54
- const values = content.split('\n').map((line) => decode(line))
47
+ const values = content.split('\n').map((line) => json_value.parse_or_undefined(line))
55
48
  const metadata = values.flatMap((value) => {
56
49
  const parsed = SESSION_META_SCHEMA.safeParse(value)
57
50
 
@@ -158,7 +158,6 @@ const cost_attribute = {
158
158
  UNATTRIBUTED_KEY,
159
159
  issue_from_branch,
160
160
  declared_issue,
161
- fill,
162
161
  attribute,
163
162
  group_by_issue,
164
163
  records_for_issue,
@@ -305,11 +305,8 @@ const cost_cli = {
305
305
  USAGE,
306
306
  parse_options,
307
307
  to_threshold,
308
- load_corpus: cost_corpus.load_corpus,
309
- attributed: cost_corpus.attributed,
310
308
  run,
311
309
  session_verdict,
312
- main,
313
310
  }
314
311
 
315
312
  if (process.argv[1] === fileURLToPath(import.meta.url)) main(process.argv.slice(ARGV_OFFSET))
@@ -265,11 +265,9 @@ function mainline_records(pairs: ReadonlyArray<AttributedRecord>): Array<Array<U
265
265
  }
266
266
 
267
267
  const cost_corpus = {
268
- accumulate_missing,
269
268
  load_corpus,
270
269
  attribute_corpus,
271
270
  floor_for_issue,
272
- dedupe_across_sessions,
273
271
  attributed,
274
272
  mainline_records,
275
273
  }
@@ -21,9 +21,6 @@ function format_share(part: number, whole: number): string {
21
21
  }
22
22
 
23
23
  const cost_format = {
24
- USD_DECIMALS,
25
- PERCENT_SCALE,
26
- PERCENT_DECIMALS,
27
24
  format_usd,
28
25
  format_tokens,
29
26
  format_share,
@@ -163,7 +163,6 @@ const cost_pricing = {
163
163
  CACHE_WRITE_5M_MULTIPLIER,
164
164
  CACHE_WRITE_1H_MULTIPLIER,
165
165
  CACHE_READ_MULTIPLIER,
166
- MODEL_PRICES,
167
166
  resolve_price,
168
167
  estimate_cost,
169
168
  estimate_composition,
@@ -74,7 +74,6 @@ function ascii_bytes_to_tokens(bytes: number): number {
74
74
 
75
75
  const cost_tokens = {
76
76
  ASCII_CHARS_PER_TOKEN,
77
- WIDE_TOKENS_PER_CHAR,
78
77
  count_chars,
79
78
  estimate,
80
79
  ascii_bytes_to_tokens,
@@ -84,7 +84,7 @@ function main(argv: ReadonlyArray<string>): void {
84
84
  process.exitCode = run(argv)
85
85
  }
86
86
 
87
- const delegation_cli = { USAGE, print_list, run, main }
87
+ const delegation_cli = { print_list, run }
88
88
 
89
89
  if (process.argv[1] === fileURLToPath(import.meta.url)) main(process.argv.slice(ARGV_OFFSET))
90
90
 
@@ -181,7 +181,6 @@ const delegation_policy = {
181
181
  REJECTED_STEPS,
182
182
  find_step,
183
183
  verdict_for,
184
- rejection_for,
185
184
  reason_for,
186
185
  }
187
186
 
@@ -216,14 +216,6 @@ const { deny_envelope, DISABLED_VALUES } = hook_decision
216
216
  const duplicate_reads = {
217
217
  REASON,
218
218
  NOTICE,
219
- SWITCH_ENV_KEY,
220
- is_candidate,
221
- is_rearmed,
222
- is_redundant_reread,
223
- is_refusable_call,
224
- is_unchanged_reread,
225
- last_read_ms,
226
- read_target,
227
219
  }
228
220
 
229
221
  if (process.argv[1] === fileURLToPath(import.meta.url)) {
@@ -54,7 +54,7 @@ function main(argv: ReadonlyArray<string>): void {
54
54
  process.exitCode = run(argv)
55
55
  }
56
56
 
57
- const fanout_cli = { USAGE, parse_unit, is_refused, run, main }
57
+ const fanout_cli = { parse_unit, run }
58
58
 
59
59
  if (process.argv[1] === fileURLToPath(import.meta.url)) main(process.argv.slice(ARGV_OFFSET))
60
60
 
@@ -86,8 +86,6 @@ function fanout_result(units: ReadonlyArray<FanoutUnit>): FanoutResult {
86
86
  const fanout = {
87
87
  PARALLEL_VERDICT,
88
88
  SERIAL_VERDICT,
89
- MIN_UNITS_TO_PARALLELIZE,
90
- overlapping_files,
91
89
  fanout_result,
92
90
  }
93
91