@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
@@ -5,6 +5,7 @@ import { delivered_rules } from '#scripts/rules/delivered-rules'
5
5
  import { run_parent_cut_hook } from '#scripts/run/run-parent-cut-hook'
6
6
  import { run_watcher_hook } from '#scripts/run/run-watcher-hook'
7
7
  import { batch_outcome } from './batch-guard'
8
+ import { step_zero_notice } from './step-zero-notice'
8
9
 
9
10
  // One PreToolUse process for the three guards that used to be three (joshuafolkken/kit#1930). A Bash
10
11
  // call used to spawn `batch:guard`, `investigation:guard` and `rule:guard` separately — three pnpm
@@ -49,10 +50,20 @@ function with_duplicate_notice(combined: GuardOutcome, notice: string | undefine
49
50
  return { reason: undefined, notice, fault: undefined }
50
51
  }
51
52
 
53
+ // The Step 0 reminder is the last word (joshuafolkken/kit#2994): asked only where every guard stayed
54
+ // clear, so a refusal or another notice never spends its once-per-session stamp unseen.
55
+ function with_step_zero_notice(outcome: GuardOutcome, raw_payload: string): GuardOutcome {
56
+ if (!is_clear(outcome)) return outcome
57
+
58
+ const notice = step_zero_notice.notice(raw_payload)
59
+
60
+ return notice === undefined ? outcome : { reason: undefined, notice, fault: undefined }
61
+ }
62
+
52
63
  // All guards run unconditionally, exactly as the separate PreToolUse entries did: each records its own
53
64
  // once-per-run stamp, so short-circuiting on the first refusal would change which guard is allowed to
54
65
  // fire on a later call.
55
- function pretool_outcome(raw_payload: string): GuardOutcome {
66
+ function guard_outcome(raw_payload: string): GuardOutcome {
56
67
  const batch = batch_outcome(raw_payload)
57
68
  const investigation = investigation_refusal(raw_payload)
58
69
  const duplicate = duplicate_read_outcome(raw_payload)
@@ -63,6 +74,11 @@ function pretool_outcome(raw_payload: string): GuardOutcome {
63
74
  return with_duplicate_notice(combined, duplicate.notice)
64
75
  }
65
76
 
77
+ // The synchronous verdict the Codex adapter asks for, with the Step 0 reminder as its last layer.
78
+ function pretool_outcome(raw_payload: string): GuardOutcome {
79
+ return with_step_zero_notice(guard_outcome(raw_payload), raw_payload)
80
+ }
81
+
66
82
  // The watcher guard is the one composed rule that cannot answer synchronously — it reads the lane
67
83
  // registry and the watcher's life record off disk (joshuafolkken/kit#2353). So it is asked after the
68
84
  // synchronous guards and only where they stayed clear: a refusal from any of them wins first, exactly
@@ -81,15 +97,17 @@ async function async_reason(raw_payload: string): Promise<string | undefined> {
81
97
  }
82
98
 
83
99
  async function pretool_outcome_async(raw_payload: string): Promise<GuardOutcome> {
84
- const base = pretool_outcome(raw_payload)
100
+ const base = guard_outcome(raw_payload)
85
101
 
86
102
  if (!is_clear(base)) return base
87
103
 
88
104
  const reason = await async_reason(raw_payload)
89
105
 
90
- return reason === undefined ? base : { reason, notice: undefined, fault: undefined }
106
+ if (reason !== undefined) return { reason, notice: undefined, fault: undefined }
107
+
108
+ return with_step_zero_notice(base, raw_payload)
91
109
  }
92
110
 
93
- const pretool_guard = { combine_outcomes, pretool_outcome, pretool_outcome_async }
111
+ const pretool_guard = { combine_outcomes, pretool_outcome }
94
112
 
95
113
  export { pretool_guard, pretool_outcome, pretool_outcome_async }
@@ -85,6 +85,6 @@ if (process.argv[1] === fileURLToPath(import.meta.url)) {
85
85
  process.exitCode = await run_reserved(process.argv.slice(FIRST_ARGUMENT_INDEX))
86
86
  }
87
87
 
88
- const reserved_run = { parse_arguments, run_command, run_reserved }
88
+ const reserved_run = { parse_arguments, run_reserved }
89
89
 
90
90
  export { reserved_run }
@@ -0,0 +1,76 @@
1
+ import path from 'node:path'
2
+ import { hook_decision } from '#scripts/josh/hook-decision'
3
+ import { json_value } from '#scripts/lib/json-value'
4
+ import { test_declared_logic } from '#scripts/test/test-declared-logic'
5
+
6
+ // The Code Change Rules Step 0 reminder, delivered at the moment implementation code is about to be
7
+ // written rather than on every prompt (joshuafolkken/kit#2994). As a `UserPromptSubmit` echo it was
8
+ // injected into every turn — a question that writes nothing included — and re-read as accumulated
9
+ // context on each turn after it. The trigger the rule names is "before writing any implementation
10
+ // code", so the hook that delivers it is the one that sees that write: the first `Edit` / `Write` of a
11
+ // runtime file in the session.
12
+ //
13
+ // **A runtime file only.** What counts is `test_declared_logic.is_exempt`, the same classification
14
+ // `pnpm josh test:declared` answers at the commit, so a doc or prompt edit neither shows the notice nor
15
+ // spends it. A path outside the working tree (a memory file, a scratchpad) is not this project's code.
16
+ //
17
+ // **Once per session**, on a stamp keyed by the transcript like every other guard record here. A stamp
18
+ // that cannot be written stays silent rather than repeating the notice on every edit.
19
+ const STAMP_PREFIX = 'josh-step-zero-notice-'
20
+ const EDIT_TOOLS: ReadonlySet<string> = new Set(['Edit', 'Write'])
21
+ const PARENT_PREFIX = '..'
22
+
23
+ const NOTICE =
24
+ 'Before writing any implementation code: present the two-layer work summary (Now / Change / Check, then every change with its test) once per Issue. Full rule: Code Change Rules Step 0 in CLAUDE.md.'
25
+
26
+ const STAMP = hook_decision.create_refusal_stamp(STAMP_PREFIX)
27
+
28
+ // A Codex `apply_patch` arrives translated with its first file as `file_path` and every file in
29
+ // `file_paths`, so a patch that leads with a doc and also writes code is still a runtime write.
30
+ function edited_paths(tool_input: unknown): Array<string> {
31
+ if (!json_value.is_record(tool_input)) return []
32
+
33
+ const { file_path, file_paths } = tool_input
34
+ const listed: ReadonlyArray<unknown> = Array.isArray(file_paths) ? file_paths : []
35
+
36
+ return [file_path, ...listed].filter(
37
+ (entry): entry is string => typeof entry === 'string' && entry.length > 0,
38
+ )
39
+ }
40
+
41
+ function is_runtime_file(file_path: string, root: string): boolean {
42
+ const relative = path.relative(root, path.resolve(root, file_path))
43
+
44
+ if (relative.startsWith(PARENT_PREFIX) || path.isAbsolute(relative)) return false
45
+
46
+ return !test_declared_logic.is_exempt(relative.split(path.sep).join('/'))
47
+ }
48
+
49
+ function is_candidate(raw_payload: string, root: string): string | undefined {
50
+ const payload = hook_decision.parse_hook_payload(raw_payload)
51
+
52
+ if (payload === undefined || !EDIT_TOOLS.has(payload.tool_name)) return undefined
53
+
54
+ const has_runtime_file = edited_paths(payload.tool_input).some((file_path) =>
55
+ is_runtime_file(file_path, root),
56
+ )
57
+
58
+ return has_runtime_file ? payload.transcript_path : undefined
59
+ }
60
+
61
+ function notice(raw_payload: string, root: string = process.cwd()): string | undefined {
62
+ const transcript = is_candidate(raw_payload, root)
63
+
64
+ if (transcript === undefined) return undefined
65
+
66
+ const target = STAMP.path(transcript)
67
+
68
+ if (STAMP.last_ms(target) !== hook_decision.NEVER_MS) return undefined
69
+ if (!STAMP.record(target, Date.now())) return undefined
70
+
71
+ return NOTICE
72
+ }
73
+
74
+ const step_zero_notice = { NOTICE, notice, stamp_path: STAMP.path }
75
+
76
+ export { step_zero_notice }
@@ -7,12 +7,15 @@ import { repo_party } from '#scripts/discovery/repo-party'
7
7
  import { hook_decision } from '#scripts/josh/hook-decision'
8
8
  import { session_language } from '#scripts/josh/session-language'
9
9
  import { lane_child_marker } from '#scripts/lane/lane-child-marker'
10
+ import { lane_handoff } from '#scripts/lane/lane-handoff'
10
11
  import { filing_cap } from '#scripts/rules/filing-cap'
11
12
  import { lane_background } from '#scripts/rules/lane-background'
12
13
  import { lane_park } from '#scripts/rules/lane-park'
13
14
  import { last_prompt } from '#scripts/rules/last-prompt'
14
15
  import { stop_rules, type StopContext, type StopOutcome } from '#scripts/rules/stop-rules'
16
+ import { run_carry } from '#scripts/run/run-carry'
15
17
  import { run_cut } from '#scripts/run/run-cut'
18
+ import { run_halfrun_resume } from '#scripts/run/run-halfrun-resume'
16
19
  import { run_headless } from '#scripts/run/run-headless'
17
20
  import { run_hold } from '#scripts/run/run-hold'
18
21
  import { run_stranded_detect } from '#scripts/run/run-stranded-detect'
@@ -29,16 +32,17 @@ import { time_hook_transcript } from '#scripts/time-runtime/time-hook-transcript
29
32
  // resolving (send the notify, release the hold) and `stop_hook_active` is the backstop, so failing
30
33
  // open here costs at most a missed nudge, never a stuck run.
31
34
 
32
- // The hold record for this working tree is still in place. `unreadable` reads as absent: the safe
33
- // direction for a stop guard is not to block, and an unreadable record is not proof a run is holding.
34
- async function is_hold_present(): Promise<boolean> {
35
+ // The hold record for this working tree is still in place, and whether it is a `prrun` stop's
36
+ // (joshuafolkken/kit#3023). `unreadable` reads as absent: the safe direction for a stop guard is not to
37
+ // block, and an unreadable record is not proof a run is holding.
38
+ async function hold_facts(): Promise<Pick<StopContext, 'hold_present' | 'prrun_stopped'>> {
35
39
  const directory = await run_hold.worktree_directory()
40
+ const hold =
41
+ directory === undefined
42
+ ? undefined
43
+ : run_halfrun_resume.hold_of(run_hold.read_hold(run_hold.hold_path(directory)))
36
44
 
37
- if (directory === undefined) return false
38
-
39
- const read = run_hold.read_hold(run_hold.hold_path(directory))
40
-
41
- return read.kind === 'held' || read.kind === 'stale'
45
+ return { hold_present: hold !== undefined, prrun_stopped: hold?.prrun_stop_head !== undefined }
42
46
  }
43
47
 
44
48
  // A `confirmation` notify sits on this run's transcript tail. The tail is derived exactly as the
@@ -67,7 +71,7 @@ async function build_context(
67
71
  const tail = transcript_tail(transcript_path)
68
72
 
69
73
  return {
70
- hold_present: await is_hold_present(),
74
+ ...(await hold_facts()),
71
75
  tree_clean: !(await run_hold.is_tree_dirty()),
72
76
  notified: lane_park.mentions_confirmation_notify(tail),
73
77
  message: payload_tail.message,
@@ -81,6 +85,7 @@ async function build_context(
81
85
  lane_child: lane_child_marker.is_child_of(process.cwd()),
82
86
  background_pending: lane_background.pending_background_ids(tail).length > 0,
83
87
  agent_pending: lane_background.pending_agent_ids(tail).length > 0,
88
+ handed_off: lane_handoff.is_handed_off(process.cwd()),
84
89
  session_lang: session_lang(),
85
90
  }
86
91
  }
@@ -106,22 +111,43 @@ async function outcome_of(raw_payload: string): Promise<StopOutcome> {
106
111
  }
107
112
  }
108
113
 
114
+ // A live carry record is in place — `carried` alone reads as a run. Both report checks below are about
115
+ // a carried run: the strand judge reads this very record and returns on anything but `carried`, and a
116
+ // stall needs a backlog driver, which begins one before its plan. A spent (`expired`) or `unreadable`
117
+ // record a crashed run left behind is no run either, so it does not re-arm the stall's backlog probe
118
+ // on every stop (joshuafolkken/kit#2995).
119
+ // A failed git read — outside a repository, `git rev-parse` exits non-zero — reads as no run, since this
120
+ // gate sits ahead of the checks' own swallowing and must not throw into the stop decision either.
121
+ async function has_run_record(): Promise<boolean> {
122
+ try {
123
+ const directory = await run_carry.repository_directory()
124
+
125
+ if (directory === undefined) return false
126
+
127
+ return run_carry.read_carry(run_carry.carry_path(directory)).kind === 'carried'
128
+ } catch {
129
+ return false
130
+ }
131
+ }
132
+
133
+ // The stall check rides the Stop hook because the stop *is* the loop boundary: a run alive but not
134
+ // advancing ends turns without dispatching (joshuafolkken/kit#2359). The strand check rides the same
135
+ // boundary and is the step before the stall (joshuafolkken/kit#2375): it fires when the driver is gone
136
+ // — the budget handed off, the owner dead, no supervisor watching. Both only report and swallow their
137
+ // own failures, so neither can change the stop decision. An ordinary stop with no run record skips
138
+ // both, so it pays one directory read rather than their reads and a stale stream's backlog probe.
139
+ async function run_report_checks(): Promise<void> {
140
+ if (!(await has_run_record())) return
141
+
142
+ await backlog_stalled_detect.run_stall_check(backlog_ready.DEFAULT_PORTS)
143
+ await run_stranded_detect.run_stranded_check()
144
+ }
145
+
109
146
  // Nothing reaches stdout on an ordinary stop, so what the harness parses stays empty unless the stop
110
147
  // is being held — all three rules block, so a bare `#N` is reported the same way (joshuafolkken/kit#2247).
111
148
  async function write_stop_decision(raw_payload: string): Promise<void> {
112
149
  hook_decision.load_environment_file()
113
-
114
- // The stall check rides the Stop hook because the stop *is* the loop boundary: a run alive but not
115
- // advancing ends turns without dispatching (joshuafolkken/kit#2359). It only reports — leaves a
116
- // marker, sends a notification — and swallows its own failures, so it can never change the decision
117
- // below or hold the stop.
118
- await backlog_stalled_detect.run_stall_check(backlog_ready.DEFAULT_PORTS)
119
-
120
- // The strand check rides the same boundary for the same reason, and is the step before the stall
121
- // (joshuafolkken/kit#2375): the stall detector needs a live driver that could dispatch, and this one
122
- // fires when that driver is gone — the budget handed off, the owner dead, no supervisor watching. It
123
- // too only reports and swallows its own failures, so it never touches the stop decision below.
124
- await run_stranded_detect.run_stranded_check()
150
+ await run_report_checks()
125
151
 
126
152
  const { reason } = await outcome_of(raw_payload)
127
153
 
@@ -13,9 +13,10 @@ const PLUGIN_ID = 'kit@kit'
13
13
  const MARKETPLACE_PATH = './node_modules/@joshuafolkken/kit'
14
14
  const CLAUDE_SETTINGS_DESTINATION = path.join('.claude', 'settings.json')
15
15
 
16
- // `enabledPlugins` declares the plugin; `extraKnownMarketplaces` says where to find it. The CLI does
17
- // not auto-install from these alone — a consumer runs `claude plugin install kit@kit` once — so the
18
- // declaration is what makes that one command resolve without further arguments.
16
+ // `enabledPlugins` declares the plugin; `extraKnownMarketplaces` says where to find it. Nothing needs
17
+ // installing: in a trusted workspace Claude Code registers the marketplace from this declaration and
18
+ // loads the skills — an interactive session from its first session, a headless one (`claude -p`) from
19
+ // its second (joshuafolkken/kit#2990).
19
20
  const PLUGIN_SETTINGS: Record<string, unknown> = {
20
21
  extraKnownMarketplaces: {
21
22
  [MARKETPLACE_NAME]: { source: { source: 'directory', path: MARKETPLACE_PATH } },
@@ -39,11 +40,9 @@ function apply_plugin_config_for_destination(destination_path: string, content:
39
40
  }
40
41
 
41
42
  const claude_plugin_config = {
42
- MARKETPLACE_NAME,
43
43
  PLUGIN_ID,
44
44
  MARKETPLACE_PATH,
45
45
  CLAUDE_SETTINGS_DESTINATION,
46
- PLUGIN_SETTINGS,
47
46
  inject_plugin_config,
48
47
  apply_plugin_config_for_destination,
49
48
  }
@@ -1,4 +1,3 @@
1
- import { GIT_LOCATION_VARIABLES } from '#scripts/git/git-location-environment'
2
1
  import { claude_plugin_config } from './claude-plugin-config'
3
2
  import { hook_launch } from './hook-launch'
4
3
 
@@ -27,8 +26,11 @@ const MISSING_INSTALL_NOTICE = 'kit hooks inactive: run pnpm install, then rerea
27
26
  const MISSING_INSTALL_GUARD = `if [ ! -f ${CONSUMER_PACKAGE_MANIFEST} ]; then echo '${MISSING_INSTALL_NOTICE}' >&2; exit 0; fi; `
28
27
  const CODEX_ADAPTER_BUNDLE = `node ${CONSUMER_HOOK_BUNDLE_DIR}codex-hook-adapter.js`
29
28
  const CODEX_HOOKS_DESTINATION = '.codex/hooks.json'
30
- const GIT_UNSET_OPTIONS = GIT_LOCATION_VARIABLES.map((name) => `-u ${name}`).join(' ')
31
- const PROJECT_ROOT_PREFIX = String.raw`if project_root=\"$(env ${GIT_UNSET_OPTIONS} git rev-parse --show-toplevel 2>/dev/null)\"; then unset ${GIT_LOCATION_VARIABLES.join(' ')}; else project_root=\"$(git rev-parse --show-toplevel)\" || exit 1; fi; cd \"$project_root\" && `
29
+ // The values below are matched inside raw JSON text, so the root prefix is taken in its escaped form.
30
+ const PROJECT_ROOT_PREFIX = JSON.stringify(hook_launch.PROJECT_ROOT_PREFIX).slice(1, -1)
31
+ // The installed package ships its bundles built, so they cannot be stale against a source the consumer
32
+ // never has: the ready gate kit's own commands pass (joshuafolkken/kit#2984) becomes a presence check.
33
+ const CONSUMER_READY_GATE = `[ -d ${CONSUMER_HOOK_BUNDLE_DIR} ]`
32
34
  // Capture the value of every `"command"` field, escapes and all, so the rewrites below touch command
33
35
  // values alone — never an echo reminder's prose or a `"description"` that merely mentions the string.
34
36
  const COMMAND_FIELD = /("command":\s*")((?:[^"\\]|\\.)*)(")/gu
@@ -49,6 +51,8 @@ function rebase_bundle_directory(value: string): string {
49
51
  // holds no `pnpm josh `), so the whole rewrite is safe to run more than once.
50
52
  function rewrite_command_value(value: string): string {
51
53
  const rewritten = rebase_bundle_directory(value)
54
+ .split(hook_launch.BUNDLE_READY_GATE)
55
+ .join(CONSUMER_READY_GATE)
52
56
  .split(PNPM_JOSH_PREFIX)
53
57
  .join(BUNDLE_INVOCATION)
54
58
  .split(CODEX_ADAPTER_SOURCE)
@@ -60,12 +64,18 @@ function rewrite_command_value(value: string): string {
60
64
  return `${MISSING_INSTALL_GUARD}${rewritten}`
61
65
  }
62
66
 
67
+ // kit's own commands already start from the root (`hook-launch.ts`), and so does an already-rewritten
68
+ // value. The prefix is taken off before the rewrite and put back after it, so the install guard sits
69
+ // behind the `cd` it depends on and a second pass never doubles the prefix.
70
+ function without_root_prefix(value: string): string {
71
+ return value.startsWith(PROJECT_ROOT_PREFIX) ? value.slice(PROJECT_ROOT_PREFIX.length) : value
72
+ }
73
+
63
74
  function rewrite_hook_commands(content: string, is_codex = false): string {
64
75
  return content.replaceAll(COMMAND_FIELD, (_match, open: string, value: string, close: string) => {
65
- const rewritten = rewrite_command_value(value)
76
+ const rewritten = rewrite_command_value(without_root_prefix(value))
66
77
  const should_select_root = is_codex || rewritten.includes(claude_plugin_config.MARKETPLACE_PATH)
67
- const prefix =
68
- should_select_root && !rewritten.startsWith(PROJECT_ROOT_PREFIX) ? PROJECT_ROOT_PREFIX : ''
78
+ const prefix = should_select_root ? PROJECT_ROOT_PREFIX : ''
69
79
 
70
80
  return `${open}${prefix}${rewritten}${close}`
71
81
  })
@@ -89,8 +99,6 @@ function apply_hook_command_rewrite_for_destination(
89
99
 
90
100
  const hook_command_rewrite = {
91
101
  apply_hook_command_rewrite_for_destination,
92
- BUNDLE_INVOCATION,
93
- PNPM_JOSH_PREFIX,
94
102
  rewrite_hook_commands,
95
103
  }
96
104
 
@@ -1,31 +1,57 @@
1
+ import { GIT_LOCATION_VARIABLES } from '#scripts/git/git-location-environment'
2
+
1
3
  // The shell command a Claude Code hook is launched with, so it starts without a `pnpm` wrapper — and,
2
4
  // for a consumer, without the `dist/josh.js` dispatcher re-spawning `tsx` for the hook's `.ts`
3
5
  // (joshuafolkken/kit#2023). Each hook is pre-built to its own `dist/hooks/<name>.js`
4
6
  // (`scripts/build/build-hooks.ts`) and launched directly with `node`.
5
7
  //
6
- // **The fallback is a real branch, not a courtesy.** A fresh clone has no `dist/hooks/` until
7
- // `pnpm build` runs, so the command prefers the bundle and drops to `pnpm josh <command>` (the live
8
- // `tsx` source) when the bundle is absent, rather than passing silently. **An `if`/`else`, never
9
- // `&&`/`||`**: a guard's refusal is a non-zero exit, and a `node … || pnpm josh …` chain would read
10
- // that refusal as a missing bundle and run the hook twice. `[ -f ]` decides on the file alone and
11
- // leaves the chosen branch's exit code untouched.
12
-
13
- // Relative to the working directory a hook runs in — kit's own root, where the built `dist/hooks/`
14
- // sits. The consumer rewrite (`hook-command-rewrite.ts`) rebases this onto the installed package.
8
+ // **The command starts from the project root, never from wherever the session happens to be**
9
+ // (joshuafolkken/kit#2984). Every path after the prefix is relative, so a hook fired from a
10
+ // subdirectory would otherwise miss its bundle. The root is git's, with the location variables a git
11
+ // hook exports cleared first — the same resolution the consumer rewrite (`hook-command-rewrite.ts`)
12
+ // applies, so both sides stay one mechanism for Claude Code and Codex alike.
13
+ //
14
+ // **The bundle runs only once the ready gate passes** (`scripts/hooks/hook-bundle-ready.ts`): it
15
+ // rebuilds `dist/hooks/` when the source beside it has changed, so an edited guard is never shadowed by
16
+ // its old bundle. The gate failing — a checkout that cannot build — drops to the fallback, the live
17
+ // source. **An `if`/`else`, never `&&`/`||`**: a guard's refusal is a non-zero exit, and a
18
+ // `node … || pnpm josh …` chain would read that refusal as a missing bundle and run the hook twice.
19
+
15
20
  const HOOK_DIST_DIR = 'dist/hooks'
21
+ const UNSET_OPTIONS = GIT_LOCATION_VARIABLES.map((name) => `-u ${name}`).join(' ')
22
+ const PROJECT_ROOT_PREFIX = `if project_root="$(env ${UNSET_OPTIONS} git rev-parse --show-toplevel 2>/dev/null)"; then unset ${GIT_LOCATION_VARIABLES.join(' ')}; else project_root="$(git rev-parse --show-toplevel)" || exit 1; fi; cd "$project_root" && `
23
+ // Plain `node` runs the gate's TypeScript directly; the flag keeps Node 22's type-stripping notice off
24
+ // every hook's stderr.
25
+ const BUNDLE_READY_GATE =
26
+ 'node --disable-warning=ExperimentalWarning scripts/hooks/hook-bundle-ready.ts'
16
27
 
17
- // Prefer `primary_path` (run as `node <path>`) when it exists, else run `fallback_command` verbatim.
18
- // Kept generic so a test can exercise the branch selection with stub commands rather than real hooks.
19
- function launch_command(primary_path: string, fallback_command: string): string {
20
- return `if [ -f ${primary_path} ]; then node ${primary_path}; else ${fallback_command}; fi`
28
+ // Run `primary_command` when `gate` exits 0, else `fallback_command` — both verbatim. Kept generic so
29
+ // a test can exercise the branch selection with stub commands rather than real hooks.
30
+ function launch_command(gate: string, primary_command: string, fallback_command: string): string {
31
+ return `if ${gate}; then ${primary_command}; else ${fallback_command}; fi`
32
+ }
33
+
34
+ // `invocation` is the hook's file under `dist/hooks` plus any arguments (e.g. `pretool-guard.js`);
35
+ // `fallback_command` runs the same hook from source.
36
+ function bundle_launch_command(invocation: string, fallback_command: string): string {
37
+ const primary = `node ${HOOK_DIST_DIR}/${invocation}`
38
+
39
+ return `${PROJECT_ROOT_PREFIX}${launch_command(BUNDLE_READY_GATE, primary, fallback_command)}`
21
40
  }
22
41
 
23
42
  // `bundle` is the hook's file under `dist/hooks` (e.g. `pretool-guard.js`); `command` is the josh
24
43
  // subcommand the fallback runs (e.g. `pretool:guard`).
25
44
  function hook_launch_command(bundle: string, command: string): string {
26
- return launch_command(`${HOOK_DIST_DIR}/${bundle}`, `pnpm josh ${command}`)
45
+ return bundle_launch_command(bundle, `pnpm josh ${command}`)
27
46
  }
28
47
 
29
- const hook_launch = { HOOK_DIST_DIR, hook_launch_command, launch_command }
48
+ const hook_launch = {
49
+ BUNDLE_READY_GATE,
50
+ bundle_launch_command,
51
+ HOOK_DIST_DIR,
52
+ hook_launch_command,
53
+ launch_command,
54
+ PROJECT_ROOT_PREFIX,
55
+ }
30
56
 
31
57
  export { hook_launch }
@@ -1,4 +1,5 @@
1
1
  import { json_format } from '#scripts/config-merge/json-format'
2
+ import { json_value } from '#scripts/lib/json-value'
2
3
  import { z } from 'zod'
3
4
  import { init_logic } from './init-logic'
4
5
  import type { ProjectShape } from './project-profile'
@@ -6,10 +7,6 @@ import type { ProjectShape } from './project-profile'
6
7
  const KIT_PACKAGE_NAME = '@joshuafolkken/kit'
7
8
  const record_schema = z.record(z.string(), z.unknown())
8
9
 
9
- function is_record(value: unknown): value is Record<string, unknown> {
10
- return typeof value === 'object' && value !== null && !Array.isArray(value)
11
- }
12
-
13
10
  interface BasicVersions {
14
11
  kit: string
15
12
  prettier: string
@@ -23,7 +20,7 @@ function with_recorded_profile(content: string, profile: ProjectShape['profile']
23
20
  const parsed: unknown = JSON.parse(content)
24
21
  const manifest = record_schema.parse(parsed)
25
22
  const existing = manifest['josh']
26
- const josh = is_record(existing) ? existing : {}
23
+ const josh = json_value.is_record(existing) ? existing : {}
27
24
 
28
25
  manifest['josh'] = { ...josh, profile }
29
26
 
@@ -92,6 +92,10 @@ const AI_COPY_FILES: ReadonlyArray<string> = [
92
92
  '.github/workflows/production.yml',
93
93
  '.github/workflows/sonar-qube.yml',
94
94
  '.github/workflows/pr-classification.yml',
95
+ // Called by `pr-classification.yml` as `uses: ./.github/actions/setup-pnpm`; without it the
96
+ // consumer's job cannot resolve the action and the Release classification check fails
97
+ // (joshuafolkken/kit#3013).
98
+ '.github/actions/setup-pnpm/action.yml',
95
99
  '.github/pull_request_template.md',
96
100
  '.github/release.yml',
97
101
  '.github/dependabot.yml',
@@ -118,6 +122,9 @@ const AI_COPY_FILE_MAPPINGS: ReadonlyArray<FileCopyMapping> = [
118
122
  src: 'templates/workflows/dependabot-auto-merge.yml',
119
123
  dest: '.github/workflows/dependabot-auto-merge.yml',
120
124
  },
125
+ // A template rather than a copy of kit's own file: kit releases from its publish.yml, so the file
126
+ // must not run in kit as well (joshuafolkken/kit#3007).
127
+ { src: 'templates/workflows/github-release.yml', dest: '.github/workflows/github-release.yml' },
121
128
  ]
122
129
 
123
130
  // Empty since joshuafolkken/kit#1879: the five skill directories kit used to copy whole
@@ -22,7 +22,6 @@ import { init_install } from './init-install'
22
22
  import { init_logic } from './init-logic'
23
23
  import { PACKAGE_DIR, PROJECT_ROOT } from './init-paths'
24
24
  import { kit_setup_state } from './kit-setup-state'
25
- import { plugin_install_hint_module } from './plugin-install-hint'
26
25
  import { project_profile, type ProjectProfile, type ProjectShape } from './project-profile'
27
26
 
28
27
  const PACKAGE_JSON = 'package.json'
@@ -295,8 +294,6 @@ function run_ai_file_actions(shape: ProjectShape): void {
295
294
  const name_with_owner = init_ai_copy.run_ai_copies(shape)
296
295
 
297
296
  if (shape.has_github) report_repository_settings(name_with_owner)
298
-
299
- if (shape.profile === 'full') plugin_install_hint_module.report_plugin_install_hint()
300
297
  }
301
298
 
302
299
  function initialize_project(shape: ProjectShape): void {
@@ -1,6 +1,7 @@
1
1
  import { existsSync, readdirSync, readFileSync, type Dirent } from 'node:fs'
2
2
  import path from 'node:path'
3
3
  import { repo_origin } from '#scripts/discovery/repo-origin'
4
+ import { json_value } from '#scripts/lib/json-value'
4
5
  import { KIT_PACKAGE_NAME } from '#scripts/version/kit-descriptor'
5
6
  import { execaSync } from 'execa'
6
7
 
@@ -73,32 +74,26 @@ function read_manifest(root: string): Record<string, unknown> | undefined {
73
74
  if (!existsSync(filename)) return undefined
74
75
  const parsed: unknown = JSON.parse(readFileSync(filename, 'utf8'))
75
76
 
76
- if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
77
- throw new Error('package.json must contain an object')
78
- }
79
-
80
- return parsed as Record<string, unknown>
81
- }
77
+ if (!json_value.is_record(parsed)) throw new Error('package.json must contain an object')
82
78
 
83
- function is_record(value: unknown): value is Record<string, unknown> {
84
- return typeof value === 'object' && value !== null && !Array.isArray(value)
79
+ return parsed
85
80
  }
86
81
 
87
82
  function recorded_profile(manifest: Record<string, unknown>): ProjectProfile | undefined {
88
83
  const { josh } = manifest
89
84
 
90
- return is_record(josh) ? parse_profile(josh['profile']) : undefined
85
+ return json_value.is_record(josh) ? parse_profile(josh['profile']) : undefined
91
86
  }
92
87
 
93
88
  function has_build_script(value: unknown): boolean {
94
- return is_record(value) && ('build' in value || 'dev' in value)
89
+ return json_value.is_record(value) && ('build' in value || 'dev' in value)
95
90
  }
96
91
 
97
92
  // kit itself is not evidence of a Node toolchain: `pnpm add -D @joshuafolkken/kit` before
98
93
  // `josh init` is the documented order, and it must still leave an `index.html` site on the basic
99
94
  // profile (joshuafolkken/kit#2693).
100
95
  function has_project_dependencies(value: unknown): boolean {
101
- if (!is_record(value)) return false
96
+ if (!json_value.is_record(value)) return false
102
97
 
103
98
  return Object.keys(value).some((name) => name !== KIT_PACKAGE_NAME)
104
99
  }
@@ -1,4 +1,4 @@
1
- import { git_gh_exec } from '#scripts/git/git-gh-exec'
1
+ import { git_gh_exec } from '#scripts/gh/git-gh-exec'
2
2
  import { execaSync } from 'execa'
3
3
 
4
4
  // The three spawn shapes every `josh start` step uses, shared by `start-steps.ts`, the setup pull
@@ -1,10 +1,10 @@
1
- import { git_gh_api_path } from '#scripts/git/git-gh-api-path'
2
- import { git_gh_exec } from '#scripts/git/git-gh-exec'
3
- import { git_gh_issue_write } from '#scripts/git/git-gh-issue-write'
1
+ import { git_gh_api_path } from '#scripts/gh/git-gh-api-path'
2
+ import { git_gh_exec } from '#scripts/gh/git-gh-exec'
3
+ import { git_gh_issue_write } from '#scripts/gh/git-gh-issue-write'
4
+ import { git_pr } from '#scripts/gh/git-pr'
5
+ import { github_issue_url } from '#scripts/gh/github-issue-url'
4
6
  import { git_issue, type IssueInfo } from '#scripts/git/git-issue'
5
- import { git_pr } from '#scripts/git/git-pr'
6
- import { github_issue_url } from '#scripts/git/github-issue-url'
7
- import { IGNORE_FOR_RELEASE_LABEL } from '#scripts/git/issue-labels'
7
+ import { IGNORE_FOR_RELEASE_LABEL } from '#scripts/issue/issue-labels'
8
8
  import { KIT_PACKAGE_NAME } from '#scripts/version/kit-descriptor'
9
9
  import { kit_written_paths } from './kit-written-paths'
10
10
  import { start_exec } from './start-exec'
@@ -163,6 +163,7 @@ async function run_steps(steps: ReadonlyArray<StartStep>, context: StepContext):
163
163
  const position = `${String(index + 1)}/${String(steps.length)}`
164
164
 
165
165
  console.info(`\n[${position}] ${labels[step]}`)
166
+ // eslint-disable-next-line no-await-in-loop -- each step builds on what the earlier ones set up
166
167
  await run_step(step, run_context, steps.slice(0, index))
167
168
  }
168
169
  }
@@ -112,7 +112,6 @@ function problems(body: string): ReadonlyArray<string> {
112
112
 
113
113
  const behavior_change_lint = {
114
114
  is_target,
115
- missing_headings,
116
115
  firing_point_name,
117
116
  problems,
118
117
  REQUIRED_HEADINGS,
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env tsx
2
2
  import { fileURLToPath } from 'node:url'
3
3
  import { parseArgs } from 'node:util'
4
- import { git_gh_command } from '#scripts/git/git-gh-command'
5
- import { git_gh_exec } from '#scripts/git/git-gh-exec'
4
+ import { git_gh_command } from '#scripts/gh/git-gh-command'
5
+ import { git_gh_exec } from '#scripts/gh/git-gh-exec'
6
6
  import { parse_json_array_or_undefined } from '#scripts/git/parse-json-array'
7
7
  import { issue_label_schema } from '#scripts/git/schemas'
8
8
  import { z } from 'zod'
@@ -160,7 +160,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
160
160
  process.exitCode = await run(argv)
161
161
  }
162
162
 
163
- const defect_rate_cli = { USAGE, read_days, search_path, measure_window, run, main }
163
+ const defect_rate_cli = { USAGE, read_days, search_path, measure_window, run }
164
164
 
165
165
  if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
166
166
 
@@ -1,5 +1,5 @@
1
- import { has_label_name, INTERRUPT_ROUTE_LABEL } from '#scripts/git/issue-labels'
2
1
  import { behavior_change_lint } from './behavior-change-lint'
2
+ import { has_label_name, INTERRUPT_ROUTE_LABEL } from './issue-labels'
3
3
  import { markdown_section } from './markdown-section'
4
4
 
5
5
  // The defect rate of merged work over a window (joshuafolkken/kit#2449): issues filed as defects
@@ -132,7 +132,6 @@ const defect_rate = {
132
132
  filed_query,
133
133
  format,
134
134
  is_above_baseline,
135
- is_behavior_change,
136
135
  is_defect,
137
136
  kind_of,
138
137
  measure,
@@ -1,8 +1,8 @@
1
- import { git_gh_command } from './git-gh-command'
1
+ import { git_gh_command } from '#scripts/gh/git-gh-command'
2
+ import { parse_json_array_safe } from '#scripts/git/parse-json-array'
3
+ import { open_issue_schema, type OpenIssueData } from '#scripts/git/schemas'
2
4
  import { has_any_label, NOT_DIRECTLY_RUNNABLE_LABELS } from './issue-labels'
3
5
  import { issue_rank, type DependencyRow } from './issue-rank'
4
- import { parse_json_array_safe } from './parse-json-array'
5
- import { open_issue_schema, type OpenIssueData } from './schemas'
6
6
 
7
7
  // The next-issues display printed when a workflow completes (#821): up to five open issues in
8
8
  // priority order, so the user picks the next run from the completion output instead of opening the