@joshuafolkken/kit 1.1784.0 → 1.2114.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 (690) hide show
  1. package/.claude/agents/reviewer-verification.md +19 -0
  2. package/.claude/agents/reviewer.md +19 -0
  3. package/.claude/settings.json +5 -6
  4. package/.claude/skills/dependency-update/SKILL.md +9 -10
  5. package/.claude/skills/workflow-commands/SKILL.md +6 -6
  6. package/.claude/skills/workflow-commands/background-commands.md +8 -5
  7. package/.claude/skills/workflow-commands/backlogrun-child.md +3 -1
  8. package/.claude/skills/workflow-commands/backlogrun-lanes.md +1 -1
  9. package/.claude/skills/workflow-commands/backlogrun-park.md +5 -2
  10. package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -3
  11. package/.claude/skills/workflow-commands/backlogrun-recovery.md +1 -1
  12. package/.claude/skills/workflow-commands/backlogrun-steps.md +3 -2
  13. package/.claude/skills/workflow-commands/backlogrun.md +1 -1
  14. package/.claude/skills/workflow-commands/chain-rule.md +41 -32
  15. package/.claude/skills/workflow-commands/delegation.md +6 -6
  16. package/.claude/skills/workflow-commands/entry-sequence.md +2 -2
  17. package/.claude/skills/workflow-commands/followup.md +7 -5
  18. package/.claude/skills/workflow-commands/fullrun-steps.md +6 -6
  19. package/.claude/skills/workflow-commands/fullrun.md +1 -1
  20. package/.claude/skills/workflow-commands/issue-comments.md +9 -4
  21. package/.claude/skills/workflow-commands/issue-fold-existing.md +2 -1
  22. package/.claude/skills/workflow-commands/kickoff.md +2 -2
  23. package/.claude/skills/workflow-commands/observation-filing.md +1 -1
  24. package/.claude/skills/workflow-commands/observation-ledger.md +6 -4
  25. package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -7
  26. package/.claude/skills/workflow-commands/prerequisite.md +3 -2
  27. package/.claude/skills/workflow-commands/retrospective.md +2 -2
  28. package/.claude/skills/workflow-commands/split-assessment.md +7 -5
  29. package/.codex/hooks.json +5 -5
  30. package/.github/actions/setup-pnpm/action.yml +9 -16
  31. package/.github/dependabot.yml +16 -0
  32. package/.github/workflows/auto-tag.yml +45 -0
  33. package/.github/workflows/ci.yml +155 -15
  34. package/.github/workflows/dependabot-auto-merge.yml +63 -4
  35. package/.github/workflows/production.yml +8 -0
  36. package/.github/workflows/publish.yml +59 -45
  37. package/.vscode/settings.json +19 -0
  38. package/CLAUDE.md +5 -12
  39. package/SECURITY.md +2 -2
  40. package/dist/CLAUDE.md +5 -12
  41. package/dist/commands/document-read-cli.js +2 -1
  42. package/dist/commands/document-section-main.js +2 -1
  43. package/dist/commands/read-set-cli.js +194 -134
  44. package/dist/commands/run-prep-main.js +9694 -10173
  45. package/dist/commands/run-step-cli.js +22138 -18285
  46. package/dist/hooks/audit-provision.js +23 -5
  47. package/dist/hooks/chunk-3GKE653K.js +6204 -0
  48. package/dist/hooks/chunk-45CJJOO7.js +1243 -0
  49. package/dist/hooks/{chunk-CWMBGKYW.js → chunk-5PM2JRGV.js} +2153 -856
  50. package/dist/hooks/{chunk-WR2KQAYZ.js → chunk-7SIUNQXK.js} +1207 -1470
  51. package/dist/hooks/{chunk-O2YBIDSI.js → chunk-CQD4LJE6.js} +1682 -1130
  52. package/dist/hooks/{chunk-VWWCFGWK.js → chunk-OPSRGWFU.js} +1 -1
  53. package/dist/hooks/{chunk-XGBNSWEI.js → chunk-UJ3FPMMM.js} +132 -49
  54. package/dist/hooks/chunk-VVNYJWEI.js +30 -0
  55. package/dist/hooks/chunk-Z6DQJKH3.js +2806 -0
  56. package/dist/hooks/codex-hook-adapter.js +8 -8
  57. package/dist/hooks/format-edited.js +4 -5
  58. package/dist/hooks/inputs.json +415 -389
  59. package/dist/hooks/pretool-guard.js +7 -6
  60. package/dist/hooks/session-lang.js +101 -258
  61. package/dist/hooks/stop-guard.js +1744 -2576
  62. package/dist/josh.js +7133 -6368
  63. package/dist/version/index.js +161 -1
  64. package/eslint/rules/comment-why-only.js +108 -0
  65. package/package.json +15 -8
  66. package/prompts/coding-standards.md +1 -1
  67. package/prompts/collaboration-workflow/file-edits.md +14 -11
  68. package/prompts/collaboration-workflow/issue-citation.md +0 -4
  69. package/prompts/collaboration-workflow/issue-template.md +40 -21
  70. package/prompts/collaboration-workflow/lane-instructions.md +3 -1
  71. package/prompts/collaboration-workflow/measurement.md +8 -1
  72. package/prompts/collaboration-workflow/operating-rules.md +11 -2
  73. package/prompts/collaboration-workflow/output-bounds.md +6 -2
  74. package/prompts/collaboration-workflow/plan-comment.md +1 -1
  75. package/prompts/collaboration-workflow/principles.md +9 -0
  76. package/prompts/collaboration-workflow/residency.md +3 -2
  77. package/prompts/collaboration-workflow/rule-delivery.md +13 -1
  78. package/prompts/collaboration-workflow/upstream-interrupt.md +2 -2
  79. package/prompts/collaboration-workflow/wip-cap.md +3 -1
  80. package/prompts/review-rubric.md +8 -0
  81. package/prompts/review.md +31 -22
  82. package/prompts/testing-guide.md +1 -0
  83. package/scripts/agent/agent-argv.ts +14 -16
  84. package/scripts/agent/agent-provider.ts +138 -0
  85. package/scripts/agent/agent-role-profile.ts +108 -156
  86. package/scripts/agent/agent-safe-text.ts +20 -5
  87. package/scripts/agent/api-usage-limit.ts +65 -0
  88. package/scripts/agent/claude-agent-argv.ts +19 -9
  89. package/scripts/agent/codex-agent-argv.ts +118 -22
  90. package/scripts/agent/usage-limit-reset.ts +179 -0
  91. package/scripts/auth/claude-token-output.ts +2 -2
  92. package/scripts/auto-ok/auto-ok-author.ts +53 -0
  93. package/scripts/auto-ok/auto-ok-cli.ts +20 -9
  94. package/scripts/backlog/backlog-defect-priority.ts +1 -1
  95. package/scripts/backlog/backlog-drive-cli.ts +6 -1
  96. package/scripts/backlog/backlog-drive-hold.ts +3 -3
  97. package/scripts/backlog/backlog-drive-idle.ts +10 -0
  98. package/scripts/backlog/backlog-drive-launch-pass.ts +90 -0
  99. package/scripts/backlog/backlog-drive-launch.ts +8 -2
  100. package/scripts/backlog/backlog-drive-named-offer.ts +73 -30
  101. package/scripts/backlog/backlog-drive-named.ts +28 -7
  102. package/scripts/backlog/backlog-drive-paused.ts +5 -4
  103. package/scripts/backlog/backlog-drive-restore.ts +11 -3
  104. package/scripts/backlog/backlog-drive.ts +21 -60
  105. package/scripts/backlog/backlog-gate-scope.ts +61 -0
  106. package/scripts/backlog/backlog-measure-close.ts +112 -0
  107. package/scripts/backlog/backlog-next.ts +39 -49
  108. package/scripts/backlog/backlog-occupied.ts +2 -2
  109. package/scripts/backlog/backlog-overlap.ts +42 -8
  110. package/scripts/backlog/backlog-plan-cli.ts +4 -1
  111. package/scripts/backlog/backlog-plan-comment.ts +81 -0
  112. package/scripts/backlog/backlog-plan-read.ts +19 -6
  113. package/scripts/backlog/backlog-pool.ts +50 -12
  114. package/scripts/backlog/backlog-rank.ts +60 -13
  115. package/scripts/backlog/backlog-stalled-detect.ts +2 -1
  116. package/scripts/backlog/backlog-waves.ts +17 -2
  117. package/scripts/backlog/backlogrun-launch.ts +7 -4
  118. package/scripts/cost-runtime/context-cut-payback.ts +27 -25
  119. package/scripts/cost-runtime/cost-cli.ts +37 -16
  120. package/scripts/cost-runtime/cost-pricing.ts +9 -0
  121. package/scripts/cost-runtime/cost-verdict.ts +4 -1
  122. package/scripts/delegation/delegation-policy.ts +2 -2
  123. package/scripts/delegation/duplicate-read-guard.ts +1 -0
  124. package/scripts/delegation/investigation-guard.ts +14 -2
  125. package/scripts/delegation/investigation-reads.ts +45 -23
  126. package/scripts/dependabot/dependabot-cooldown.ts +3 -2
  127. package/scripts/discovery/repo-party.ts +80 -20
  128. package/scripts/discovery/session-owner-pin.ts +51 -0
  129. package/scripts/document/capped-print.ts +1 -1
  130. package/scripts/document/command-reference-line-budget.ts +42 -0
  131. package/scripts/document/document-byte-budget.ts +17 -7
  132. package/scripts/document/document-checks.ts +20 -0
  133. package/scripts/document/document-ratchet-check.ts +101 -0
  134. package/scripts/document/document-section.ts +1 -0
  135. package/scripts/document/entry-read-budget.ts +7 -3
  136. package/scripts/document/issue-citation-budget.ts +94 -0
  137. package/scripts/epic/epic-cli-argv.ts +2 -2
  138. package/scripts/epic/epic-fetch.ts +4 -2
  139. package/scripts/epic/epic-graph.ts +7 -2
  140. package/scripts/epic/epic-issue.ts +3 -1
  141. package/scripts/epic/epic-rank.ts +5 -0
  142. package/scripts/exports/unused-members-check.ts +62 -0
  143. package/scripts/exports/unused-members-cli.ts +6 -51
  144. package/scripts/followup/followup-ci-path.ts +67 -0
  145. package/scripts/followup/followup-coderabbit-retrigger.ts +261 -0
  146. package/scripts/followup/followup-coderabbit-wait.ts +13 -10
  147. package/scripts/followup/followup-failed-tests.ts +160 -0
  148. package/scripts/followup/followup-job-needs.ts +100 -0
  149. package/scripts/followup/followup-job-rerun.ts +303 -0
  150. package/scripts/followup/followup-main-move.ts +113 -0
  151. package/scripts/followup/git-followup-finish.ts +43 -11
  152. package/scripts/followup/git-followup-pending.ts +3 -3
  153. package/scripts/followup/git-followup-stages.ts +41 -11
  154. package/scripts/followup/git-pr-followup-checks.ts +55 -16
  155. package/scripts/followup/git-pr-followup-wrapup.ts +24 -5
  156. package/scripts/followup/git-pr-followup.ts +62 -27
  157. package/scripts/fresh-machine/fresh-machine-script.ts +5 -9
  158. package/scripts/fresh-machine/specs/kit-test-backlogrun-python.json +2 -2
  159. package/scripts/fresh-machine/specs/kit-test-backlogrun.json +2 -2
  160. package/scripts/gate/busy-average.ts +34 -2
  161. package/scripts/gate/check-related-pinned.ts +43 -0
  162. package/scripts/gate/check-related-reuse.ts +64 -0
  163. package/scripts/gate/check-related-section.ts +57 -0
  164. package/scripts/gate/check-related-unplanned.ts +34 -0
  165. package/scripts/gate/check-related.ts +265 -0
  166. package/scripts/gate/command-memory.ts +1 -1
  167. package/scripts/gate/core-admission.ts +24 -6
  168. package/scripts/gate/core-budget-timing.ts +20 -6
  169. package/scripts/gate/core-budget.ts +40 -11
  170. package/scripts/gate/core-wait-record.ts +3 -2
  171. package/scripts/gate/core-wait.ts +25 -2
  172. package/scripts/gate/core-weights.ts +15 -7
  173. package/scripts/gate/gate-labels.ts +46 -0
  174. package/scripts/gate/gate-ledger.ts +14 -6
  175. package/scripts/gate/gate-plan.ts +103 -58
  176. package/scripts/gate/gate-report.ts +9 -7
  177. package/scripts/gate/gate-run-steps.ts +26 -3
  178. package/scripts/gate/gate-skip.ts +45 -6
  179. package/scripts/gate/gate-static-group.ts +60 -0
  180. package/scripts/gate/gate-steps.ts +2 -1
  181. package/scripts/gate/gate-tree.ts +4 -2
  182. package/scripts/gate/hook-gate-reuse.ts +19 -2
  183. package/scripts/gate/metrics-totals.ts +59 -0
  184. package/scripts/gate/scoped-green.ts +68 -15
  185. package/scripts/gate/since-green.ts +14 -6
  186. package/scripts/gate/structural-checks.ts +96 -0
  187. package/scripts/gate/verification-gate.ts +51 -16
  188. package/scripts/gate/verification-inputs.ts +21 -6
  189. package/scripts/gate/verification-tail.ts +52 -0
  190. package/scripts/gh/gh-author-association.ts +23 -2
  191. package/scripts/gh/git-ai-review-scan.ts +1 -1
  192. package/scripts/gh/git-gh-api-path.ts +12 -3
  193. package/scripts/gh/git-gh-comments-unreadable.ts +36 -0
  194. package/scripts/gh/git-gh-exec.ts +32 -2
  195. package/scripts/gh/git-gh-issue-read.ts +4 -2
  196. package/scripts/gh/git-gh-issue-rest.ts +1 -0
  197. package/scripts/gh/git-gh-issue-write.ts +8 -2
  198. package/scripts/gh/git-gh-issue.ts +12 -5
  199. package/scripts/gh/git-gh-pr-auto-merge.ts +13 -6
  200. package/scripts/gh/git-gh-pr-graphql-state.ts +56 -0
  201. package/scripts/gh/git-gh-pr-read.ts +74 -13
  202. package/scripts/gh/git-gh-pr-rest.ts +3 -1
  203. package/scripts/gh/git-gh-pr-snapshot.ts +22 -7
  204. package/scripts/gh/git-gh-pr-too-large.ts +20 -0
  205. package/scripts/gh/git-gh-pr.ts +21 -7
  206. package/scripts/gh/git-gh-retry.ts +141 -0
  207. package/scripts/gh/git-pr-ai-review.ts +15 -6
  208. package/scripts/gh/git-pr-checks-eval.ts +3 -0
  209. package/scripts/gh/git-pr-checks.ts +5 -5
  210. package/scripts/git/base-tree.ts +30 -0
  211. package/scripts/git/change-base.ts +4 -10
  212. package/scripts/git/changed-paths-sync.ts +63 -0
  213. package/scripts/git/changed-paths.ts +16 -1
  214. package/scripts/git/git-common-directory.ts +11 -1
  215. package/scripts/git/git-diff-reads.ts +66 -20
  216. package/scripts/git/git-error.ts +9 -2
  217. package/scripts/git/git-schemas.ts +13 -0
  218. package/scripts/git/git-worktree.ts +13 -0
  219. package/scripts/git/gone-branch.ts +4 -1
  220. package/scripts/git/main-merge-budget-conflict.ts +89 -0
  221. package/scripts/git/main-merge-guard.ts +55 -18
  222. package/scripts/git/main-merge-regenerate.ts +59 -25
  223. package/scripts/git/main-merge.ts +53 -5
  224. package/scripts/git/no-base-checkout.ts +127 -0
  225. package/scripts/git/stash/git-stash.ts +11 -2
  226. package/scripts/git/stash/stash-push-cli.ts +10 -0
  227. package/scripts/hooks/batch-guard.ts +40 -21
  228. package/scripts/hooks/edited-cspell.ts +37 -11
  229. package/scripts/hooks/format-edited-file.ts +22 -2
  230. package/scripts/hooks/lane-plan-guard.ts +50 -0
  231. package/scripts/hooks/pre-commit-lint-switch.ts +9 -0
  232. package/scripts/hooks/pre-commit-lint.ts +14 -1
  233. package/scripts/hooks/pre-push-related-switch.ts +10 -0
  234. package/scripts/hooks/pre-push-unit.ts +76 -10
  235. package/scripts/hooks/pretool-guard.ts +2 -0
  236. package/scripts/hooks/reserved-run.ts +14 -1
  237. package/scripts/hooks/run-hook.sh +23 -8
  238. package/scripts/hooks/step-zero-notice.ts +6 -1
  239. package/scripts/hooks/stop-actions.ts +3 -15
  240. package/scripts/hooks/stop-guard.ts +7 -6
  241. package/scripts/init/distributed-paths.ts +1 -0
  242. package/scripts/init/hook-command-rewrite.ts +5 -1
  243. package/scripts/init/hook-launch.ts +4 -2
  244. package/scripts/issue/aggregation-split.ts +52 -0
  245. package/scripts/issue/defect-origin-line.ts +19 -1
  246. package/scripts/issue/defect-rate-cli.ts +5 -102
  247. package/scripts/issue/defect-report.ts +4 -4
  248. package/scripts/issue/effect-audit-cli.ts +178 -0
  249. package/scripts/issue/effect-audit.ts +185 -0
  250. package/scripts/issue/expected-effect-lint.ts +64 -9
  251. package/scripts/issue/git-next-issues.ts +5 -0
  252. package/scripts/issue/issue-body-or-comment.ts +38 -4
  253. package/scripts/issue/issue-cite-cli.ts +1 -3
  254. package/scripts/issue/issue-classification.ts +1 -0
  255. package/scripts/issue/issue-closing-pr.ts +8 -1
  256. package/scripts/issue/issue-evidence-exit.ts +4 -2
  257. package/scripts/issue/issue-file-cap.ts +58 -0
  258. package/scripts/issue/issue-file-cli.ts +111 -38
  259. package/scripts/issue/issue-file-deferral.ts +52 -0
  260. package/scripts/issue/issue-file-fold.ts +29 -10
  261. package/scripts/issue/issue-file-interrupt.ts +85 -0
  262. package/scripts/issue/issue-file-lane-hint.ts +30 -0
  263. package/scripts/issue/issue-file.ts +43 -6
  264. package/scripts/issue/issue-labels.ts +19 -2
  265. package/scripts/issue/issue-lint-cli.ts +27 -2
  266. package/scripts/issue/issue-measured-cli.ts +13 -35
  267. package/scripts/issue/issue-measured-close.ts +58 -0
  268. package/scripts/issue/issue-not-before-label.ts +2 -2
  269. package/scripts/issue/issue-not-before.ts +4 -1
  270. package/scripts/issue/issue-priority-cli.ts +60 -0
  271. package/scripts/issue/issue-priority-raise.ts +55 -0
  272. package/scripts/issue/issue-priority.ts +174 -43
  273. package/scripts/issue/issue-rank.ts +21 -4
  274. package/scripts/issue/issue-read-cli.ts +32 -6
  275. package/scripts/issue/issue-read.ts +37 -12
  276. package/scripts/issue/issue-sample-gate.ts +95 -74
  277. package/scripts/issue/issue-sample-prime.ts +127 -0
  278. package/scripts/issue/issue-sample-required.ts +57 -0
  279. package/scripts/issue/issue-sample-source.ts +12 -11
  280. package/scripts/issue/issue-search.ts +124 -0
  281. package/scripts/issue/issue-state.ts +13 -1
  282. package/scripts/issue/issue-template-section.ts +43 -0
  283. package/scripts/issue/issue-watch-diff.ts +31 -1
  284. package/scripts/issue/issue-watch-hook.ts +11 -2
  285. package/scripts/issue/issue-watch.ts +55 -12
  286. package/scripts/issue/markdown-section.ts +1 -0
  287. package/scripts/issue/measure-declaration.ts +121 -0
  288. package/scripts/issue/measure-rerun-cli.ts +7 -70
  289. package/scripts/issue/plan-consumers-section.ts +22 -1
  290. package/scripts/issue/reproduction-measure.ts +3 -1
  291. package/scripts/issue/size-estimate.ts +90 -0
  292. package/scripts/issue/trusted-measure.ts +84 -0
  293. package/scripts/josh/command-usage.ts +3 -2
  294. package/scripts/josh/durable-state-migrate.ts +105 -0
  295. package/scripts/josh/durable-state.ts +112 -0
  296. package/scripts/josh/josh-aliases.ts +95 -0
  297. package/scripts/josh/josh-command-map.ts +1 -82
  298. package/scripts/josh/josh-commands-agent-hooks.ts +6 -6
  299. package/scripts/josh/josh-commands-ai.ts +5 -5
  300. package/scripts/josh/josh-commands-development.ts +59 -58
  301. package/scripts/josh/josh-commands-issue-write.ts +23 -4
  302. package/scripts/josh/josh-commands-issue.ts +32 -0
  303. package/scripts/josh/josh-commands-lane.ts +87 -4
  304. package/scripts/josh/josh-commands-lint.ts +16 -3
  305. package/scripts/josh/josh-commands-maintenance.ts +15 -0
  306. package/scripts/josh/josh-commands-review.ts +41 -6
  307. package/scripts/josh/josh-commands-ship.ts +56 -8
  308. package/scripts/josh/josh-commands-test-check.ts +80 -0
  309. package/scripts/josh/josh-commands-workflow.ts +1 -1
  310. package/scripts/josh/josh-environment-file.ts +43 -3
  311. package/scripts/josh/josh-in-process.ts +2 -2
  312. package/scripts/josh/josh-logic.ts +5 -3
  313. package/scripts/josh/josh-run.ts +19 -1
  314. package/scripts/josh/run-record-path.ts +15 -0
  315. package/scripts/josh/stamp-file.ts +11 -2
  316. package/scripts/lane/lane-adopt-cli.ts +98 -0
  317. package/scripts/lane/lane-adopt.ts +208 -0
  318. package/scripts/lane/lane-await.ts +5 -8
  319. package/scripts/lane/lane-baseline.ts +123 -0
  320. package/scripts/lane/lane-breakdown-cli.ts +64 -0
  321. package/scripts/lane/lane-breakdown-implement.ts +170 -0
  322. package/scripts/lane/lane-breakdown-laps.ts +107 -0
  323. package/scripts/lane/lane-breakdown-pinned.ts +76 -0
  324. package/scripts/lane/lane-breakdown-text.ts +145 -0
  325. package/scripts/lane/lane-breakdown.ts +239 -0
  326. package/scripts/lane/lane-check-stats.ts +29 -8
  327. package/scripts/lane/lane-child-invocation.ts +9 -2
  328. package/scripts/lane/lane-child-mark-keys.ts +12 -0
  329. package/scripts/lane/lane-child-marker.ts +20 -1
  330. package/scripts/lane/lane-ci-path-stats.ts +73 -0
  331. package/scripts/lane/lane-claim-stats.ts +84 -0
  332. package/scripts/lane/lane-close.ts +8 -3
  333. package/scripts/lane/lane-dispatch-log.ts +3 -3
  334. package/scripts/lane/lane-dispatch.ts +2 -2
  335. package/scripts/lane/lane-gap-stats.ts +7 -6
  336. package/scripts/lane/lane-guard-policy.ts +7 -1
  337. package/scripts/lane/lane-implement-stats.ts +207 -0
  338. package/scripts/lane/lane-implement-subagents.ts +90 -0
  339. package/scripts/lane/lane-investigation-switch.ts +16 -0
  340. package/scripts/lane/lane-ledger-kind.ts +31 -0
  341. package/scripts/lane/lane-ledger-schema-ship.ts +49 -0
  342. package/scripts/lane/lane-ledger-schema.ts +119 -36
  343. package/scripts/lane/lane-ledger-write.ts +257 -0
  344. package/scripts/lane/lane-ledger.ts +31 -177
  345. package/scripts/lane/lane-load.ts +1 -1
  346. package/scripts/lane/lane-measure-cli.ts +176 -59
  347. package/scripts/lane/lane-net-read.ts +44 -0
  348. package/scripts/lane/lane-net-time.ts +212 -0
  349. package/scripts/lane/lane-open.ts +16 -7
  350. package/scripts/lane/lane-output.ts +2 -4
  351. package/scripts/lane/lane-overrun-prompt.ts +147 -0
  352. package/scripts/lane/lane-overrun.ts +274 -0
  353. package/scripts/lane/lane-paths.ts +24 -1
  354. package/scripts/lane/lane-pause-cli.ts +4 -1
  355. package/scripts/lane/lane-paused-spans.ts +97 -0
  356. package/scripts/lane/lane-plan-check.ts +207 -0
  357. package/scripts/lane/lane-plan-cli.ts +41 -0
  358. package/scripts/lane/lane-plan.ts +144 -0
  359. package/scripts/lane/lane-registry.ts +14 -1
  360. package/scripts/lane/lane-relaunch.ts +1 -1
  361. package/scripts/lane/lane-round-one-stats.ts +51 -0
  362. package/scripts/lane/lane-sampler.ts +23 -4
  363. package/scripts/lane/lane-session-action.ts +93 -18
  364. package/scripts/lane/lane-session-broker.ts +49 -21
  365. package/scripts/lane/lane-session-reread-main.ts +14 -0
  366. package/scripts/lane/lane-session-reread.ts +51 -0
  367. package/scripts/lane/lane-ship-lap-stats.ts +74 -0
  368. package/scripts/lane/lane-sleep.ts +58 -0
  369. package/scripts/lane/lane-spent.ts +1 -1
  370. package/scripts/lane/lane-split-stats.ts +28 -0
  371. package/scripts/lane/lane-stage-stats.ts +13 -1
  372. package/scripts/lane/lane-state.ts +41 -9
  373. package/scripts/lane/lane-stats-tables.ts +58 -0
  374. package/scripts/lane/lane-stats.ts +21 -5
  375. package/scripts/lane/lane-stop-stats.ts +51 -19
  376. package/scripts/lane/lane-tail-stats.ts +32 -0
  377. package/scripts/lane/lane-transcript-calls.ts +67 -10
  378. package/scripts/lane/lane-transcript-stats.ts +44 -12
  379. package/scripts/lane/lane-value-cell.ts +72 -0
  380. package/scripts/lane/lane-value.ts +118 -0
  381. package/scripts/lane/lane-withdraw-closed.ts +124 -0
  382. package/scripts/lane/lane-withdraw.ts +108 -31
  383. package/scripts/lane/lane-yield.ts +85 -0
  384. package/scripts/lane/openai-lane-ship.ts +12 -11
  385. package/scripts/lane/openai-lane-supervisor-decision.ts +6 -8
  386. package/scripts/lane/openai-lane-supervisor-owner.ts +5 -8
  387. package/scripts/lane/openai-lane-supervisor.ts +5 -4
  388. package/scripts/lib/poll.ts +38 -9
  389. package/scripts/lib/settled-together.ts +10 -0
  390. package/scripts/lib/shell-quote.ts +21 -0
  391. package/scripts/lib/token-shape.ts +111 -0
  392. package/scripts/lint/eslint-daemon-sources.ts +79 -0
  393. package/scripts/lint/eslint-daemon.ts +45 -6
  394. package/scripts/lint/eslint-warm-cli.ts +7 -0
  395. package/scripts/lint/eslint-warm.ts +66 -0
  396. package/scripts/lint/import-graph.ts +141 -11
  397. package/scripts/lint/lint-gate-scope.ts +2 -2
  398. package/scripts/lint/lint-parallel.ts +54 -6
  399. package/scripts/lint/lint-related.ts +154 -33
  400. package/scripts/lint/rename-cli.ts +179 -0
  401. package/scripts/lint/rename-identifier.ts +192 -0
  402. package/scripts/lint/type-only-imports.ts +58 -0
  403. package/scripts/notify/telegram-notify.ts +12 -3
  404. package/scripts/observations/observation-record.ts +42 -16
  405. package/scripts/observations/observations-flush.ts +32 -9
  406. package/scripts/overrides/overrides-check.ts +9 -1
  407. package/scripts/release/release-approval-prune.ts +7 -1
  408. package/scripts/repo/required-checks-logic.ts +4 -1
  409. package/scripts/repo/ruleset-check.ts +4 -3
  410. package/scripts/report/markdown-shape.ts +28 -0
  411. package/scripts/report/report-format-reference.ts +15 -1
  412. package/scripts/report/report-labels.ts +12 -1
  413. package/scripts/report/report-lint-child-summary.ts +94 -0
  414. package/scripts/report/report-lint-cli.ts +26 -7
  415. package/scripts/report/report-lint.ts +2 -20
  416. package/scripts/review/prose-stale-cli.ts +88 -0
  417. package/scripts/review/prose-stale-scan.ts +152 -0
  418. package/scripts/review/review-attest.ts +73 -23
  419. package/scripts/review/review-brief-cli.ts +68 -19
  420. package/scripts/review/review-brief-paths.ts +22 -0
  421. package/scripts/review/review-brief.ts +14 -7
  422. package/scripts/review/review-comment-carry.ts +47 -0
  423. package/scripts/review/review-comment-round.ts +85 -22
  424. package/scripts/review/review-finding-ledger.ts +109 -7
  425. package/scripts/review/review-finding-text.ts +43 -0
  426. package/scripts/review/review-interaction.ts +11 -0
  427. package/scripts/review/review-lane-handover.ts +68 -0
  428. package/scripts/review/review-lint-cli.ts +57 -0
  429. package/scripts/review/review-lint-findings.ts +92 -0
  430. package/scripts/review/review-lint-sections.ts +80 -0
  431. package/scripts/review/review-lint.ts +221 -0
  432. package/scripts/review/review-prior-findings.ts +102 -0
  433. package/scripts/review/review-readers-scan.ts +4 -2
  434. package/scripts/review/review-record-cli.ts +177 -54
  435. package/scripts/review/review-record-code-round.ts +55 -0
  436. package/scripts/review/review-record-comment.ts +60 -0
  437. package/scripts/review/review-record-interaction.ts +35 -0
  438. package/scripts/review/review-record-pinned.ts +108 -0
  439. package/scripts/review/review-record.ts +25 -1
  440. package/scripts/review/review-reviewed-tree.ts +307 -0
  441. package/scripts/review/review-round-one-closure.ts +62 -0
  442. package/scripts/review/review-round-reuse.ts +106 -0
  443. package/scripts/review/review-round2-cli.ts +91 -29
  444. package/scripts/review/review-round2-skip-comment.ts +55 -0
  445. package/scripts/review/review-round2.ts +24 -8
  446. package/scripts/review/review-stamps.ts +7 -3
  447. package/scripts/review/review-stop-log.ts +20 -6
  448. package/scripts/review/review-stops-cli.ts +2 -1
  449. package/scripts/review/review-submit-cli.ts +101 -0
  450. package/scripts/rules/agent-model.ts +1 -1
  451. package/scripts/rules/bash-triggers.ts +3 -3
  452. package/scripts/rules/concise-reply.ts +88 -0
  453. package/scripts/rules/credential-body.ts +77 -0
  454. package/scripts/rules/decision-oracle.ts +1 -1
  455. package/scripts/rules/delivered-rules.ts +36 -17
  456. package/scripts/rules/destructive-command.ts +3 -11
  457. package/scripts/rules/direct-issue-comment.ts +34 -12
  458. package/scripts/rules/direct-issue-read.ts +191 -0
  459. package/scripts/rules/direct-pr-create.ts +4 -24
  460. package/scripts/rules/early-heartbeat.ts +2 -0
  461. package/scripts/rules/edit-tool.ts +27 -0
  462. package/scripts/rules/file-edit-rows.ts +17 -0
  463. package/scripts/rules/file-rewrite.ts +146 -0
  464. package/scripts/rules/firing-point.ts +3 -2
  465. package/scripts/rules/gh-api.ts +128 -7
  466. package/scripts/rules/gh-repo-selector.ts +84 -0
  467. package/scripts/rules/git-force.ts +2 -2
  468. package/scripts/rules/guard-remedy.ts +14 -5
  469. package/scripts/rules/implementation-cut.ts +61 -28
  470. package/scripts/rules/investigator-foreground.ts +231 -0
  471. package/scripts/rules/issue-citation.ts +15 -60
  472. package/scripts/rules/issue-comments.ts +9 -4
  473. package/scripts/rules/josh-git-bare.ts +1 -1
  474. package/scripts/rules/lane-background.ts +41 -13
  475. package/scripts/rules/lane-direct-tool.ts +107 -9
  476. package/scripts/rules/lane-interactive-ask.ts +4 -1
  477. package/scripts/rules/lane-park.ts +4 -2
  478. package/scripts/rules/lane-spilled-read.ts +90 -0
  479. package/scripts/rules/lane-split-park.ts +1 -1
  480. package/scripts/rules/lane-switch-main.ts +4 -4
  481. package/scripts/rules/last-prompt.ts +20 -47
  482. package/scripts/rules/oracle-consulted.ts +1 -1
  483. package/scripts/rules/permission-guards.ts +5 -1
  484. package/scripts/rules/piped-verification-shapes.ts +110 -0
  485. package/scripts/rules/piped-verification.ts +67 -17
  486. package/scripts/rules/poll-loop.ts +72 -9
  487. package/scripts/rules/pr-merge.ts +5 -5
  488. package/scripts/rules/pre-gate-cut.ts +3 -3
  489. package/scripts/rules/protected-files.ts +88 -24
  490. package/scripts/rules/reply-language.ts +3 -17
  491. package/scripts/rules/reply-prose.ts +34 -0
  492. package/scripts/rules/repo-admin.ts +132 -0
  493. package/scripts/rules/reviewer-foreground.ts +88 -0
  494. package/scripts/rules/round-one-check-related.ts +120 -0
  495. package/scripts/rules/rule-body-guard.ts +5 -15
  496. package/scripts/rules/rule-value-cache.ts +53 -5
  497. package/scripts/rules/rule-value-candidates.ts +84 -0
  498. package/scripts/rules/rule-value-cli.ts +59 -11
  499. package/scripts/rules/rule-value.ts +17 -4
  500. package/scripts/rules/run-tail-rule.ts +1 -1
  501. package/scripts/rules/sed-in-place.ts +196 -0
  502. package/scripts/rules/shell-segments.ts +10 -2
  503. package/scripts/rules/stop-rule-rows.ts +1 -13
  504. package/scripts/rules/stop-rules.ts +33 -58
  505. package/scripts/rules/test-declared-commit.ts +1 -1
  506. package/scripts/rules/third-party-write.ts +110 -23
  507. package/scripts/rules/timed-rerun.ts +1 -1
  508. package/scripts/rules/turn-filings.ts +90 -0
  509. package/scripts/rules/worktree-guard.ts +22 -7
  510. package/scripts/run/board/run-board-ending-reason.ts +6 -2
  511. package/scripts/run/board/run-board-fit.ts +24 -1
  512. package/scripts/run/board/run-board-found.ts +134 -0
  513. package/scripts/run/board/run-board-header.ts +8 -0
  514. package/scripts/run/board/run-board-labels.ts +11 -1
  515. package/scripts/run/board/run-board-lane-time.ts +1 -0
  516. package/scripts/run/board/run-board-link.ts +15 -2
  517. package/scripts/run/board/run-board-notes.ts +7 -1
  518. package/scripts/run/board/run-board-operation.ts +4 -2
  519. package/scripts/run/board/run-board-phase.ts +2 -5
  520. package/scripts/run/board/run-board-plan.ts +1 -1
  521. package/scripts/run/board/run-board-read.ts +46 -1
  522. package/scripts/run/board/run-board-reason.ts +20 -8
  523. package/scripts/run/board/run-board-render-checks.ts +3 -2
  524. package/scripts/run/board/run-board-render-drawn.ts +11 -0
  525. package/scripts/run/board/run-board-render-found.ts +157 -0
  526. package/scripts/run/board/run-board-render-lead.ts +9 -0
  527. package/scripts/run/board/run-board-render-legend.ts +19 -0
  528. package/scripts/run/board/run-board-render-tail.ts +1 -1
  529. package/scripts/run/board/run-board-render.ts +82 -18
  530. package/scripts/run/board/run-board-spin.ts +1 -3
  531. package/scripts/run/board/run-board-status.ts +2 -0
  532. package/scripts/run/board/run-board-tick.ts +39 -10
  533. package/scripts/run/carry/run-carry-ended.ts +3 -2
  534. package/scripts/run/carry/run-carry.ts +3 -2
  535. package/scripts/run/cut/run-cut-cli.ts +33 -133
  536. package/scripts/run/cut/run-cut-digest.ts +152 -0
  537. package/scripts/run/cut/run-cut-handoff.ts +52 -8
  538. package/scripts/run/cut/run-cut-report.ts +24 -3
  539. package/scripts/run/cut/run-cut-resume.ts +129 -0
  540. package/scripts/run/cut/run-cut-review.ts +105 -0
  541. package/scripts/run/cut/run-cut.ts +18 -7
  542. package/scripts/run/detached-launch.ts +1 -1
  543. package/scripts/run/entry/run-entry-cli.ts +88 -19
  544. package/scripts/run/entry/run-entry-spill.ts +83 -0
  545. package/scripts/run/entry/run-entry-stop.ts +5 -1
  546. package/scripts/run/entry/run-entry-trust.ts +91 -0
  547. package/scripts/run/event/run-event-baseline.ts +56 -0
  548. package/scripts/run/event/run-event-filed.ts +9 -3
  549. package/scripts/run/event/run-event-overrun.ts +197 -0
  550. package/scripts/run/event/run-event-render.ts +4 -0
  551. package/scripts/run/event/run-event-stream.ts +25 -3
  552. package/scripts/run/hold/run-stop-notify.ts +3 -8
  553. package/scripts/run/merge/run-merge-cap.ts +57 -0
  554. package/scripts/run/merge/run-merge-cli.ts +66 -23
  555. package/scripts/run/merge/run-merge-outcome.ts +2 -0
  556. package/scripts/run/merge/run-merge-ship.ts +13 -3
  557. package/scripts/run/merge/run-merge-signals.ts +40 -23
  558. package/scripts/run/merge/run-merge-steps.ts +56 -36
  559. package/scripts/run/merge/run-merge-usage-limit.ts +53 -0
  560. package/scripts/run/merge/run-merge-withdrawn.ts +53 -0
  561. package/scripts/run/merge/run-merge.ts +41 -14
  562. package/scripts/run/review/run-review-cli.ts +306 -20
  563. package/scripts/run/review/run-review-early-push.ts +121 -0
  564. package/scripts/run/review/run-review-join-read.ts +94 -0
  565. package/scripts/run/review/run-review-pinned-accepted.ts +126 -0
  566. package/scripts/run/review/run-review-pinned-join.ts +216 -0
  567. package/scripts/run/review/run-review-pinned-steps.ts +383 -0
  568. package/scripts/run/review/run-review-pinned-tree.ts +37 -0
  569. package/scripts/run/review/run-review-pinned.ts +53 -0
  570. package/scripts/run/review/run-review-steps.ts +70 -34
  571. package/scripts/run/review/run-review.ts +26 -6
  572. package/scripts/run/run-parent-cut-hook.ts +3 -4
  573. package/scripts/run/run-prep.ts +1 -0
  574. package/scripts/run/run-stage-read.ts +2 -6
  575. package/scripts/run/run-step-cli.ts +17 -5
  576. package/scripts/run/run-step-lane-plan.ts +27 -0
  577. package/scripts/run/run-step-section.ts +26 -7
  578. package/scripts/run/run-step.ts +5 -2
  579. package/scripts/run/ship/run-ship-args.ts +19 -0
  580. package/scripts/run/ship/run-ship-brokered-review.ts +106 -0
  581. package/scripts/run/ship/run-ship-cli.ts +131 -39
  582. package/scripts/run/ship/run-ship-conflict-probe.ts +59 -0
  583. package/scripts/run/ship/run-ship-detach.ts +10 -4
  584. package/scripts/run/ship/run-ship-handover.ts +106 -0
  585. package/scripts/run/ship/run-ship-infra-retry.ts +16 -1
  586. package/scripts/run/ship/run-ship-lap.ts +63 -0
  587. package/scripts/run/ship/run-ship-next.ts +27 -26
  588. package/scripts/run/ship/run-ship-overlap.ts +8 -3
  589. package/scripts/run/ship/run-ship-place.ts +9 -2
  590. package/scripts/run/ship/run-ship-planned.ts +92 -0
  591. package/scripts/run/ship/run-ship-pre-detach-pinned.ts +197 -0
  592. package/scripts/run/ship/run-ship-pre-detach-timed.ts +7 -8
  593. package/scripts/run/ship/run-ship-pre-detach.ts +77 -23
  594. package/scripts/run/ship/run-ship-preflight.ts +16 -4
  595. package/scripts/run/ship/run-ship-probe.ts +23 -9
  596. package/scripts/run/ship/run-ship-relaunch-cap.ts +43 -7
  597. package/scripts/run/ship/run-ship-relaunch.ts +51 -0
  598. package/scripts/run/ship/run-ship-return.ts +103 -29
  599. package/scripts/run/ship/run-ship-review-reason.ts +24 -0
  600. package/scripts/run/ship/run-ship-review-steps.ts +230 -59
  601. package/scripts/run/ship/run-ship-review.ts +171 -51
  602. package/scripts/run/ship/run-ship-reviewer.ts +138 -42
  603. package/scripts/run/ship/run-ship-scoped.ts +39 -10
  604. package/scripts/run/ship/run-ship-stage.ts +49 -13
  605. package/scripts/run/ship/run-ship-steps.ts +24 -4
  606. package/scripts/run/ship/run-ship-stop-cause.ts +43 -2
  607. package/scripts/run/ship/run-ship-stop-context.ts +50 -13
  608. package/scripts/run/ship/run-ship-sync.ts +171 -30
  609. package/scripts/run/ship/run-ship-synced-scope.ts +178 -0
  610. package/scripts/run/ship/run-ship-wait-cli.ts +145 -0
  611. package/scripts/run/ship/run-ship-waiter.ts +114 -0
  612. package/scripts/run/ship/run-ship.ts +16 -2
  613. package/scripts/run/wake/run-wake-caffeinate.ts +48 -0
  614. package/scripts/run/wake/run-wake-cli.ts +6 -113
  615. package/scripts/run/wake/run-wake-code.ts +53 -11
  616. package/scripts/run/wake/run-wake-driver.ts +5 -3
  617. package/scripts/run/wake/run-wake-finish.ts +137 -0
  618. package/scripts/run/wake/run-wake-loop.ts +5 -3
  619. package/scripts/run/wake/run-wake-ports.ts +11 -3
  620. package/scripts/run/wake/run-wake-session.ts +2 -0
  621. package/scripts/run/wake/run-wake.ts +3 -2
  622. package/scripts/safe-chain/ci-installer-pin.ts +49 -8
  623. package/scripts/safe-chain/project-config.ts +3 -2
  624. package/scripts/security/secretlint-scan.ts +42 -9
  625. package/scripts/security/security-audit-provision-main.ts +9 -1
  626. package/scripts/security/security-audit-provision.ts +1 -1
  627. package/scripts/security/security-audit.ts +21 -1
  628. package/scripts/security/sonar-file.ts +10 -5
  629. package/scripts/split/split-assess.ts +12 -3
  630. package/scripts/split/split-early-notice.ts +116 -0
  631. package/scripts/split/split-measure.ts +20 -2
  632. package/scripts/split/split-resolution.ts +107 -0
  633. package/scripts/test/direct-importers.ts +185 -0
  634. package/scripts/test/pure-files-entries.ts +83 -0
  635. package/scripts/test/related-heavy-tests.ts +81 -0
  636. package/scripts/test/test-no-base.ts +88 -0
  637. package/scripts/test/test-pinned-cache-logic.ts +363 -0
  638. package/scripts/test/test-pinned-cache.ts +337 -0
  639. package/scripts/test/test-pinned-emit.ts +49 -0
  640. package/scripts/test/test-pinned-functions.ts +116 -0
  641. package/scripts/test/test-pinned-ledger.ts +80 -0
  642. package/scripts/test/test-pinned-logic.ts +208 -20
  643. package/scripts/test/test-pinned-main.ts +84 -18
  644. package/scripts/test/test-pinned-pool.ts +73 -0
  645. package/scripts/test/test-pinned-probe.ts +254 -0
  646. package/scripts/test/test-pinned-prune-logic.ts +118 -0
  647. package/scripts/test/test-pinned-reach.ts +194 -0
  648. package/scripts/test/test-pinned-record.ts +196 -0
  649. package/scripts/test/test-pinned-rewire.ts +148 -0
  650. package/scripts/test/test-pinned-spawn.ts +81 -0
  651. package/scripts/test/test-pinned-stage.ts +70 -0
  652. package/scripts/test/test-pinned.ts +258 -47
  653. package/scripts/test/test-reach-cli.ts +61 -0
  654. package/scripts/test/test-read-map.ts +35 -11
  655. package/scripts/test/test-read-recording.ts +17 -5
  656. package/scripts/test/test-read-trace.ts +26 -8
  657. package/scripts/test/test-red-logic.ts +46 -7
  658. package/scripts/test/test-red.ts +34 -14
  659. package/scripts/test/test-related-claim.ts +37 -0
  660. package/scripts/test/test-related-main.ts +4 -1
  661. package/scripts/test/test-related-moved.ts +91 -0
  662. package/scripts/test/test-related-record.ts +43 -23
  663. package/scripts/test/test-related-scope.ts +99 -34
  664. package/scripts/test/test-related-synced.ts +135 -0
  665. package/scripts/test/test-related-touched.ts +84 -0
  666. package/scripts/test/test-related.ts +167 -83
  667. package/scripts/test/test-unit-guard.ts +28 -5
  668. package/scripts/test/unit-durations.ts +41 -0
  669. package/scripts/test/unit-worker-share.ts +5 -4
  670. package/scripts/test/vitest-cache-directory.ts +19 -0
  671. package/scripts/test/vitest-cli-excludes.ts +14 -0
  672. package/scripts/test/vitest-failure-summary.ts +111 -0
  673. package/scripts/test/whole-suite-files.ts +12 -1
  674. package/scripts/time-runtime/time-batch-guard.ts +42 -4
  675. package/scripts/time-runtime/time-bundle-call.ts +1 -1
  676. package/scripts/time-runtime/time-bundles.ts +36 -5
  677. package/scripts/time-runtime/time-markers.ts +2 -2
  678. package/scripts/time-runtime/time-search-call.ts +38 -0
  679. package/scripts/time-runtime/time-shell.ts +1 -1
  680. package/scripts/time-runtime/time-transcript-line.ts +17 -5
  681. package/scripts/version/development-engines-verdict.ts +124 -0
  682. package/scripts/version/latest-corepack.ts +2 -0
  683. package/templates/gitignore +2 -0
  684. package/templates/workflows/ci.yml +41 -0
  685. package/dist/hooks/chunk-AZX4FGQ3.js +0 -207
  686. package/dist/hooks/chunk-PT5R6UJD.js +0 -7131
  687. package/dist/hooks/chunk-TUIFS5E7.js +0 -72
  688. package/dist/hooks/chunk-YCDOIR3I.js +0 -3456
  689. package/scripts/cost-runtime/context-cut-threshold.ts +0 -11
  690. package/scripts/rules/filing-cap.ts +0 -139
@@ -360,6 +360,19 @@ async function collect_unfixed(
360
360
  return unfixed
361
361
  }
362
362
 
363
+ // The edited file as the daemon read it, or nothing when no eslint command linted it — a `.json`
364
+ // module prettier alone formats is still in the type program, and a refreshed record would hide its
365
+ // old copy there (joshuafolkken/kit#4867).
366
+ function linted_path(
367
+ plan: ReadonlyArray<FormatCommand>,
368
+ file_path: string,
369
+ project_root: string,
370
+ ): string | undefined {
371
+ if (plan.every((command) => command.bin !== ESLINT_BIN)) return undefined
372
+
373
+ return relative_to_root(project_root, file_path)
374
+ }
375
+
363
376
  async function format_edited_file(
364
377
  raw_payload: string,
365
378
  runner: CommandRunner,
@@ -376,7 +389,11 @@ async function format_edited_file(
376
389
  const daemon_before = eslint_daemon.read_record(project_root)
377
390
  const unfixed = await collect_unfixed(plan, runner, project_root)
378
391
 
379
- eslint_daemon.remember_started(project_root, daemon_before)
392
+ eslint_daemon.remember_after_edit(
393
+ project_root,
394
+ daemon_before,
395
+ linted_path(plan, file_path, project_root),
396
+ )
380
397
 
381
398
  return format_diagnostics(unfixed === '' ? undefined : unfixed)
382
399
  }
@@ -444,15 +461,18 @@ function report_no_payload(): void {
444
461
  // its content before the formatters ran against its content after — so it too is known only once they
445
462
  // have. The rewrite, lint and spell blocks are composed together first, then
446
463
  // joined to the density line — one envelope, since a `PostToolUse` hook's stdout carries only one.
464
+ // The spell check runs beside the formatters rather than after them, on the text as the edit left it:
465
+ // it was the hook's largest step (joshuafolkken/kit#4596), and a formatter rewrites layout, not words.
447
466
  // A hook killed at its 15s timeout is the one case this loses the density
448
467
  // line to — a run already gone pathologically wrong, per HOOK_PROCESS_TIMEOUT_MS.
449
468
  async function run_hook(payload: string): Promise<void> {
450
469
  const notice = time_density_hook.density_notice(payload)
451
470
  const file_path = parse_edited_path(payload)
452
471
  const before = rewrite_notice.read_text(file_path)
472
+ const pending_spelling = edited_cspell.spelling_diagnostics(file_path, process.cwd(), before)
453
473
  const lint = await format_edited_payload(payload, process.cwd())
454
474
  const rewrite = rewrite_notice.build(before, rewrite_notice.read_text(file_path))
455
- const spelling = await edited_cspell.spelling_diagnostics(file_path, process.cwd())
475
+ const spelling = await pending_spelling
456
476
  const parts = compose_context(rewrite, compose_context(lint, spelling))
457
477
  const context = compose_context(notice, parts)
458
478
 
@@ -0,0 +1,50 @@
1
+ import { lane_child_marker, type MarkerSource } from '#scripts/lane/lane-child-marker'
2
+ import { lane_plan } from '#scripts/lane/lane-plan'
3
+ import { step_zero_notice } from './step-zero-notice'
4
+
5
+ // A dispatched lane child's first implementation edit is refused until `josh lane:plan` has recorded
6
+ // the files its work summary changes and cleared them (joshuafolkken/kit#4864). The record is what holds a later lane
7
+ // back from those files, so it has to exist before the code does; a document asking for it would be
8
+ // read after the edit it governs.
9
+ //
10
+ // **A dispatched lane child only**, the trust condition `lane-phase.ts` applies: a person's session, or
11
+ // one carrying a mark leaked from a parent, runs no lanes beside it to wait on.
12
+
13
+ const COMMAND_DOC = '`docs/josh-commands-run.md` → "`josh lane:plan`"'
14
+ const OUTCOMES =
15
+ 'on `yield` end the session with no edit (its lane is given back); on `wait` run it again'
16
+
17
+ function reason_text(issue: string): string {
18
+ const command = `\`pnpm josh lane:plan ${issue} <path>...\``
19
+
20
+ return `⛔ lane plan: run ${command} naming every file the work summary changes before the first implementation edit — ${OUTCOMES} (${COMMAND_DOC}).`
21
+ }
22
+
23
+ // The issue of the dispatched lane child making this runtime edit, or `undefined` for any other call.
24
+ function lane_child_edit(
25
+ raw_payload: string,
26
+ directory: string,
27
+ source: MarkerSource,
28
+ ): string | undefined {
29
+ if (!lane_child_marker.is_child_of(directory, source)) return undefined
30
+
31
+ return step_zero_notice.is_runtime_edit(raw_payload, directory)
32
+ ? lane_child_marker.marked_issue(source)
33
+ : undefined
34
+ }
35
+
36
+ function reason(
37
+ raw_payload: string,
38
+ directory: string = process.cwd(),
39
+ source: MarkerSource = process.env,
40
+ ): string | undefined {
41
+ const issue = lane_child_edit(raw_payload, directory, source)
42
+
43
+ if (issue === undefined) return undefined
44
+
45
+ return lane_plan.is_uncleared(Number(issue), directory) ? reason_text(issue) : undefined
46
+ }
47
+
48
+ const lane_plan_guard = { reason }
49
+
50
+ export { lane_plan_guard }
@@ -0,0 +1,9 @@
1
+ // **Switched off, a pre-commit lint hook neither reserves the core budget nor runs** — set by `josh
2
+ // ship`'s local commit (`run-ship-sync.ts`), whose tree the gate or the scoped pair checks before
3
+ // anything is pushed (joshuafolkken/kit#4985). On by default like every other distributed guard. Its
4
+ // own module because the hook is an entry with a main guard, which nothing may import.
5
+ const SWITCH_ENV_KEY = 'JOSH_PRE_COMMIT_LINT'
6
+
7
+ const pre_commit_lint_switch = { SWITCH_ENV_KEY }
8
+
9
+ export { pre_commit_lint_switch }
@@ -1,6 +1,8 @@
1
1
  #!/usr/bin/env tsx
2
2
  import { fileURLToPath } from 'node:url'
3
3
  import { core_budget } from '#scripts/gate/core-budget'
4
+ import { pre_commit_lint_switch } from '#scripts/hooks/pre-commit-lint-switch'
5
+ import { hook_decision } from '#scripts/josh/hook-decision'
4
6
  import {
5
7
  CSPELL_COMMIT_CACHE_FLAGS,
6
8
  ESLINT_COMMIT_CACHE_FILE,
@@ -51,8 +53,13 @@ const TOOL_BUDGETS: Readonly<Record<string, 'spell_check' | 'format' | 'eslint_s
51
53
  eslint: 'eslint_scan',
52
54
  }
53
55
 
56
+ const SUCCESS_EXIT_CODE = 0
57
+
54
58
  const USAGE = `Usage: josh pre-commit-lint <${Object.keys(TOOL_ARGUMENTS).join('|')}> [files...]`
59
+ const END_OF_OPTIONS = '--'
55
60
 
61
+ // The staged files follow `--`, so a file named `--plugin=x.mjs` is read as a file, never as an
62
+ // option that loads code (joshuafolkken/kit#4634).
56
63
  function build_arguments(
57
64
  tool: string,
58
65
  staged_files: ReadonlyArray<string>,
@@ -60,7 +67,7 @@ function build_arguments(
60
67
  const tool_arguments = TOOL_ARGUMENTS[tool]
61
68
  if (tool_arguments === undefined) return undefined
62
69
 
63
- return [...tool_arguments, ...staged_files]
70
+ return [...tool_arguments, END_OF_OPTIONS, ...staged_files]
64
71
  }
65
72
 
66
73
  // eslint goes through the lane's warm daemon when one is reachable (joshuafolkken/kit#4358): the same
@@ -92,6 +99,10 @@ async function run_reserved(tool: string, staged_files: ReadonlyArray<string>):
92
99
  return await run_tool(command_arguments)
93
100
  }
94
101
 
102
+ function is_switched_on(): boolean {
103
+ return hook_decision.is_switch_enabled(pre_commit_lint_switch.SWITCH_ENV_KEY)
104
+ }
105
+
95
106
  async function run(argv: ReadonlyArray<string>): Promise<number> {
96
107
  const [tool = '', ...staged_files] = argv
97
108
  const budget = TOOL_BUDGETS[tool]
@@ -102,6 +113,8 @@ async function run(argv: ReadonlyArray<string>): Promise<number> {
102
113
  return USAGE_ERROR_EXIT_CODE
103
114
  }
104
115
 
116
+ if (!is_switched_on()) return SUCCESS_EXIT_CODE
117
+
105
118
  return await core_budget.with_command_reservation(
106
119
  core_budget.CORE_WEIGHTS[budget],
107
120
  async () => await run_reserved(tool, staged_files),
@@ -0,0 +1,10 @@
1
+ // **Switched on, a pre-push unit run the gate record does not cover runs the related tests rather than
2
+ // the whole suite** — set by `josh ship`'s push ahead of the gate (`run-ship-sync.ts`), whose gate over
3
+ // the same tree runs the whole suite next (joshuafolkken/kit#5067). Off by default. Its own module
4
+ // because the hook is an entry with a main guard, which nothing may import.
5
+ const SWITCH_ENV_KEY = 'JOSH_PRE_PUSH_RELATED'
6
+ const SWITCH_ON = '1'
7
+
8
+ const pre_push_related_switch = { SWITCH_ENV_KEY, SWITCH_ON }
9
+
10
+ export { pre_push_related_switch }
@@ -5,7 +5,10 @@ import { gate_plan } from '#scripts/gate/gate-plan'
5
5
  import { gate_skip, type GateReuse } from '#scripts/gate/gate-skip'
6
6
  import { gate_tree, type GateTree } from '#scripts/gate/gate-tree'
7
7
  import { hook_gate_reuse } from '#scripts/gate/hook-gate-reuse'
8
+ import type { PushMissRecord } from '#scripts/lane/lane-ledger-schema'
9
+ import { lane_ledger_write } from '#scripts/lane/lane-ledger-write'
8
10
  import { test_unit_guard } from '#scripts/test/test-unit-guard'
11
+ import { pre_push_related_switch } from './pre-push-related-switch'
9
12
 
10
13
  // The pre-push hook's unit run, which does not re-run a suite a green gate already covers: the gate
11
14
  // writes its record down, and re-running `vitest run` on a tree it just printed green is the bulk of
@@ -125,30 +128,93 @@ function format_miss(reason: string): string {
125
128
  return `↻ running the whole unit suite — the green gate record does not cover this push: ${reason}.`
126
129
  }
127
130
 
128
- // **The whole suite claims its place in the core budget, the one `josh test:unit` claims.** Without it
129
- // a push's suite ran beside other lanes' gates off the ledger, so their admission saw its workers only
130
- // as foreign load (joshuafolkken/kit#3874). Only the miss reserves: a reused record runs nothing, and a
131
+ // **A unit run claims its place in the core budget, the one `josh test:unit` claims.** Without it a
132
+ // push's run went beside other lanes' gates off the ledger, so their admission saw its workers only as
133
+ // foreign load (joshuafolkken/kit#3874). Only the miss reserves: a reused record runs nothing, and a
131
134
  // claim there could make a push wait out a full ledger for a suite it then skips.
132
- async function run_reserved_suite(vitest_arguments: ReadonlyArray<string>): Promise<number> {
135
+ async function run_reserved(command: string, run: () => Promise<number>): Promise<number> {
133
136
  const claim = gate_plan.DIRECT_UNIT_CLAIM
134
137
 
135
- return await core_budget.with_command_reservation(
136
- claim.core_weight(),
138
+ return await core_budget.with_command_reservation(claim.core_weight(), run, {
139
+ memory_mb: claim.memory_mb(),
140
+ command,
141
+ is_unit: claim.is_unit_claim,
142
+ })
143
+ }
144
+
145
+ async function run_reserved_suite(vitest_arguments: ReadonlyArray<string>): Promise<number> {
146
+ return await run_reserved(
147
+ 'pre-push test:unit',
137
148
  async () => await test_unit_guard.run_guarded_unit(process.cwd(), vitest_arguments),
138
- { memory_mb: claim.memory_mb(), command: 'pre-push test:unit', is_unit: claim.is_unit_claim },
139
149
  )
140
150
  }
141
151
 
152
+ // **A push its caller makes ahead of the gate runs the related tests, not the whole suite**
153
+ // (joshuafolkken/kit#5067). `josh ship` pushes the tree its sync merged with the default branch onto an
154
+ // open pull request so CI starts beside the gate, and the gate that follows runs the whole suite over
155
+ // that same tree; the push itself only needs what this branch's change reaches. Only the caller sets
156
+ // it, `--force` and the escape hatch still win, and a narrowed run asked for its own arguments rather
157
+ // than this scope.
158
+ function is_related_requested(extra_arguments: ReadonlyArray<string>): boolean {
159
+ const { SWITCH_ENV_KEY, SWITCH_ON } = pre_push_related_switch
160
+
161
+ if (process.env[SWITCH_ENV_KEY] !== SWITCH_ON || extra_arguments.length > 0) return false
162
+
163
+ return !hook_gate_reuse.is_force_requested(FORCE_ENV)
164
+ }
165
+
166
+ function format_related(reason: string): string {
167
+ return `↻ running the related unit tests — the push runs ahead of its gate, and the green gate record does not cover it: ${reason}.`
168
+ }
169
+
170
+ // Imported only on this path, so every other push leaves the import graph `test-related.ts` loads alone.
171
+ async function run_related(): Promise<number> {
172
+ const { test_related } = await import('#scripts/test/test-related')
173
+
174
+ return await run_reserved(
175
+ 'pre-push test:related',
176
+ async () => await test_related.run_related_tests([]),
177
+ )
178
+ }
179
+
180
+ // joshuafolkken/kit#5234: the miss's kind goes to the lane ledger, so `lane:stats` counts the suites a
181
+ // push ran and why beside the gate's own fallbacks.
182
+ async function record_miss(scope: PushMissRecord['scope'], kind: string): Promise<void> {
183
+ await lane_ledger_write.record_push_miss({ scope, reason: kind })
184
+ }
185
+
186
+ async function run_miss(
187
+ reason: string,
188
+ kind: string,
189
+ extra_arguments: ReadonlyArray<string>,
190
+ ): Promise<number> {
191
+ if (is_related_requested(extra_arguments)) {
192
+ process.stdout.write(`${format_related(reason)}\n`)
193
+ await record_miss('related', kind)
194
+
195
+ return await run_related()
196
+ }
197
+
198
+ process.stdout.write(`${format_miss(reason)}\n`)
199
+ await record_miss('whole', kind)
200
+
201
+ return await run_reserved_suite(forwarded_arguments(extra_arguments))
202
+ }
203
+
142
204
  async function run_pre_push_unit(
143
205
  extra_arguments: ReadonlyArray<string> = [],
144
206
  source?: string,
145
207
  ): Promise<number> {
146
- const reuse = push_reuse(await read_push_tree(), extra_arguments, source)
208
+ const tree = await read_push_tree()
209
+ const reuse = push_reuse(tree, extra_arguments, source)
147
210
 
148
211
  if ('miss' in reuse) {
149
- process.stdout.write(`${format_miss(reuse.miss)}\n`)
212
+ const kind = hook_gate_reuse.miss_kind(reuse.miss, {
213
+ carry_miss: tree.carry_miss,
214
+ force_env: FORCE_ENV,
215
+ })
150
216
 
151
- return await run_reserved_suite(forwarded_arguments(extra_arguments))
217
+ return await run_miss(reuse.miss, kind, extra_arguments)
152
218
  }
153
219
 
154
220
  process.stdout.write(`${format_skip(reuse.stamp.taken_at)}\n`)
@@ -11,6 +11,7 @@ import { run_poll_hook } from '#scripts/run/run-poll-hook'
11
11
  import { run_watcher_hook } from '#scripts/run/run-watcher-hook'
12
12
  import type { GuardedCall } from '#scripts/time-runtime/time-batch-guard'
13
13
  import { batch_outcome } from './batch-guard'
14
+ import { lane_plan_guard } from './lane-plan-guard'
14
15
  import { shell_rules_notice } from './shell-rules-notice'
15
16
  import { step_zero_notice } from './step-zero-notice'
16
17
 
@@ -72,6 +73,7 @@ function guard_outcome(raw_payload: string): GuardOutcome {
72
73
  batch_outcome(raw_payload),
73
74
  investigation_outcome(raw_payload),
74
75
  duplicate_read_outcome(raw_payload),
76
+ { reason: lane_plan_guard.reason(raw_payload), notice: undefined, fault: undefined },
75
77
  ]
76
78
 
77
79
  return combine_outcomes(outcomes, delivered_rules.delivery(raw_payload))
@@ -106,12 +106,25 @@ function reservation_options(parsed: ReservedCommand): {
106
106
  return { command, memory_mb: parsed.memory_mb ?? command_memory.estimated_memory_mb(command) }
107
107
  }
108
108
 
109
+ // The directory the caller typed the command in. **`pnpm josh` runs from the package root**, so without
110
+ // this a wrapped `eslint rules/a.ts` typed in `scripts/` would lint from the root and match nothing;
111
+ // pnpm records the caller's directory in `INIT_CWD` (joshuafolkken/kit#5147).
112
+ function command_directory(): string {
113
+ const initial = process.env['INIT_CWD']
114
+
115
+ return initial === undefined || initial === '' ? process.cwd() : initial
116
+ }
117
+
109
118
  // `stdio: 'inherit'` so the command's own progress reaches the push, and `reject: false` so a failing
110
119
  // command becomes an exit code the caller returns rather than a throw — the reservation is released by
111
120
  // `with_core_reservation`'s `finally` on either path.
112
121
  async function run_command(command: ReadonlyArray<string>): Promise<number> {
113
122
  const [file = '', ...args] = command
114
- const result = await execa(file, args, { stdio: 'inherit', reject: false })
123
+ const result = await execa(file, args, {
124
+ cwd: command_directory(),
125
+ stdio: 'inherit',
126
+ reject: false,
127
+ })
115
128
 
116
129
  return result.exitCode ?? FAIL_EXIT_CODE
117
130
  }
@@ -22,23 +22,38 @@
22
22
  # `dirname`, and `node` replaces this shell through `exec` rather than running beside it.
23
23
  # - An `if`/`else`, never `&&`/`||`: a guard's refusal is a non-zero exit, and a chain would read it as
24
24
  # a missing bundle and run the hook twice.
25
-
26
- location_variables='GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_COMMON_DIR GIT_DIR GIT_INDEX_FILE GIT_NAMESPACE GIT_OBJECT_DIRECTORY GIT_WORK_TREE'
27
- if [ -n "$GIT_ALTERNATE_OBJECT_DIRECTORIES$GIT_COMMON_DIR$GIT_DIR$GIT_INDEX_FILE$GIT_NAMESPACE$GIT_OBJECT_DIRECTORY$GIT_WORK_TREE" ] &&
28
- (unset $location_variables && git rev-parse --show-toplevel >/dev/null 2>&1); then
29
- unset $location_variables
30
- fi
25
+ # - A hook launched inside one of Claude Code's own worktrees (`EnterWorktree`, an
26
+ # `isolation: "worktree"` subagent) runs in that worktree. Claude Code keeps `CLAUDE_PROJECT_DIR` on
27
+ # the main checkout there, so the prefix lands on it and hands over where the hook was launched in
28
+ # `JOSH_HOOK_CWD` (joshuafolkken/kit#4617). The code still comes from the project root — a fresh
29
+ # worktree has no install and no bundles — so only the working directory moves.
31
30
 
32
31
  hook_name=$1
33
32
  shift
34
33
  case $0 in
35
- */*) hooks_dir=${0%/*} ;;
36
- *) hooks_dir=. ;;
34
+ /*) hooks_dir=${0%/*} ;;
35
+ */*) hooks_dir=$PWD/${0%/*} ;;
36
+ *) hooks_dir=$PWD ;;
37
37
  esac
38
38
  package_dir="$hooks_dir/../.."
39
39
  bundle="$package_dir/dist/hooks/$hook_name.js"
40
40
  josh_command="${hook_name%%-*}:${hook_name#*-}"
41
41
 
42
+ worktrees_dir=$PWD/.claude/worktrees/
43
+ case $JOSH_HOOK_CWD in
44
+ "$worktrees_dir"?*)
45
+ worktree_path=${JOSH_HOOK_CWD#"$worktrees_dir"}
46
+ cd "$worktrees_dir${worktree_path%%/*}" || exit
47
+ ;;
48
+ *) ;;
49
+ esac
50
+
51
+ location_variables='GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_COMMON_DIR GIT_DIR GIT_INDEX_FILE GIT_NAMESPACE GIT_OBJECT_DIRECTORY GIT_WORK_TREE'
52
+ if [ -n "$GIT_ALTERNATE_OBJECT_DIRECTORIES$GIT_COMMON_DIR$GIT_DIR$GIT_INDEX_FILE$GIT_NAMESPACE$GIT_OBJECT_DIRECTORY$GIT_WORK_TREE" ] &&
53
+ (unset $location_variables && git rev-parse --show-toplevel >/dev/null 2>&1); then
54
+ unset $location_variables
55
+ fi
56
+
42
57
  case $0 in
43
58
  *node_modules/*)
44
59
  if [ -d "$package_dir/dist/hooks" ]; then exec node "$bundle" "$@"; else exec node "$package_dir/dist/josh.js" "$josh_command" "$@"; fi
@@ -58,6 +58,11 @@ function is_candidate(raw_payload: string, root: string): string | undefined {
58
58
  return has_runtime_file ? payload.transcript_path : undefined
59
59
  }
60
60
 
61
+ // Whether the payload edits a runtime file under `root` — the edit Step 0 and the lane plan precede.
62
+ function is_runtime_edit(raw_payload: string, root: string = process.cwd()): boolean {
63
+ return is_candidate(raw_payload, root) !== undefined
64
+ }
65
+
61
66
  function notice(raw_payload: string, root: string = process.cwd()): string | undefined {
62
67
  const transcript = is_candidate(raw_payload, root)
63
68
 
@@ -72,6 +77,6 @@ function notice(raw_payload: string, root: string = process.cwd()): string | und
72
77
  return NOTICE
73
78
  }
74
79
 
75
- const step_zero_notice = { NOTICE, notice, stamp_path: STAMP.path }
80
+ const step_zero_notice = { NOTICE, is_runtime_edit, notice, stamp_path: STAMP.path }
76
81
 
77
82
  export { step_zero_notice }
@@ -1,12 +1,10 @@
1
1
  import { git_gh_repo } from '#scripts/gh/git-gh-repo'
2
2
  import { issue_cite } from '#scripts/issue/issue-cite'
3
- import { issue_cite_cli } from '#scripts/issue/issue-cite-cli'
4
3
  import { session_cite } from '#scripts/issue/session-cite'
5
4
  import { bounded_pool } from '#scripts/lib/bounded-pool'
6
5
  import { stdout_on_stderr } from '#scripts/lib/stdout-on-stderr'
7
6
  import { telegram_test } from '#scripts/notify/telegram-test'
8
7
  import type { CliValues } from '#scripts/notify/telegram-test-logic'
9
- import { issue_citation } from '#scripts/rules/issue-citation'
10
8
  import { stop_rules, type StopAction, type StopOutcome } from '#scripts/rules/stop-rules'
11
9
  import { run_hold } from '#scripts/run/hold/run-hold'
12
10
  import { run_hold_cli } from '#scripts/run/hold/run-hold-cli'
@@ -15,9 +13,8 @@ import { run_hold_session } from '#scripts/run/hold/run-hold-session'
15
13
  type NotifyAction = Extract<StopAction, { kind: 'notify' }>
16
14
 
17
15
  // The `Stop` hook running the operations whose answer is fixed (joshuafolkken/kit#3919): the
18
- // `confirmation` notify, the hold release and the citation lines, through the very calls
19
- // `josh notify`, `josh run:release` and `josh issue:cite` make — in process, since three `pnpm`
20
- // launches would spend most of the hook's 20-second budget. What each did reaches the person as a
16
+ // `confirmation` notify and the hold release, through the very calls `josh notify` and
17
+ // `josh run:release` make — in process, since two `pnpm` launches would spend most of the hook's 20-second budget. What each did reaches the person as a
21
18
  // `systemMessage`; one that did not take falls back to the refusal it replaced (`stop_rules.fallback_reason`).
22
19
 
23
20
  const SUCCESS_EXIT_CODE = 0
@@ -109,20 +106,11 @@ async function release(issue: string): Promise<string | undefined> {
109
106
  return code === SUCCESS_EXIT_CODE ? '🔓 stop:guard released the run:hold record.' : undefined
110
107
  }
111
108
 
112
- // Every line or none: a citation with a number missing is the half-fix the refusal exists to avoid.
113
- async function cite(references: ReadonlyArray<string>): Promise<string | undefined> {
114
- const cited = await issue_cite_cli.cite(issue_citation.cite_arguments(references))
115
- if (cited === undefined || cited.failures.length > 0) return undefined
116
-
117
- return ['Issue citations:', ...cited.lines].join(NOTICE_SEPARATOR)
118
- }
119
-
120
109
  // An action's line for the person, or `undefined` when it did not take.
121
110
  async function run_action(action: StopAction): Promise<string | undefined> {
122
111
  if (action.kind === 'notify') return await notify(action)
123
- if (action.kind === 'release') return await release(action.issue)
124
112
 
125
- return await cite(action.references)
113
+ return await release(action.issue)
126
114
  }
127
115
 
128
116
  // A throw is an action that did not take, the same as one that answered it had failed.
@@ -10,7 +10,6 @@ import { session_language } from '#scripts/josh/session-language'
10
10
  import { lane_child_marker } from '#scripts/lane/lane-child-marker'
11
11
  import { lane_handoff } from '#scripts/lane/lane-handoff'
12
12
  import { stdout_on_stderr } from '#scripts/lib/stdout-on-stderr'
13
- import { filing_cap } from '#scripts/rules/filing-cap'
14
13
  import { lane_background } from '#scripts/rules/lane-background'
15
14
  import { lane_park } from '#scripts/rules/lane-park'
16
15
  import { last_prompt } from '#scripts/rules/last-prompt'
@@ -18,6 +17,7 @@ import { pre_gate_cut } from '#scripts/rules/pre-gate-cut'
18
17
  import { stop_decision } from '#scripts/rules/stop-decision'
19
18
  import { stop_rules, type StopContext, type StopOutcome } from '#scripts/rules/stop-rules'
20
19
  import { tail_commands } from '#scripts/rules/tail-commands'
20
+ import { turn_filings } from '#scripts/rules/turn-filings'
21
21
  import { run_carry } from '#scripts/run/carry/run-carry'
22
22
  import { run_cut } from '#scripts/run/cut/run-cut'
23
23
  import { run_cut_report } from '#scripts/run/cut/run-cut-report'
@@ -82,10 +82,10 @@ function transcript_tail(transcript_path: string): string {
82
82
  return time_density_hook.read_tail(transcript)
83
83
  }
84
84
 
85
- // An Issue was filed on this turn — the tail from the last prompt on. The count is `filing_cap`'s, so a
86
- // filing a guard refused is not counted, and one an earlier turn made does not stand this turn down.
85
+ // An Issue was filed on this turn — the tail from the last prompt on. The count is `turn_filings`', so
86
+ // a filing a guard refused is not counted, and one an earlier turn made does not stand this turn down.
87
87
  function was_filed(tail: string): boolean {
88
- return filing_cap.turn_filing_count(tail) > 0
88
+ return turn_filings.turn_filing_count(tail) > 0
89
89
  }
90
90
 
91
91
  // This turn ended at a cut — a record still `carried`, or this turn's `run:cut` relaunching a successor.
@@ -95,7 +95,7 @@ function is_cut_stop(tail: string): boolean {
95
95
  if (run_cut.carried_cut_sync() !== undefined) return true
96
96
 
97
97
  return tail_commands.answered(
98
- filing_cap.current_turn(tail),
98
+ turn_filings.current_turn(tail),
99
99
  pre_gate_cut.takes_the_cut,
100
100
  run_cut_report.RELAUNCHED_CUT_MARKER,
101
101
  )
@@ -129,7 +129,7 @@ async function build_context(
129
129
  ...(await hold_facts(tail)),
130
130
  tree_clean: !(await run_hold.is_tree_dirty()),
131
131
  message: payload_tail.message,
132
- prompt: last_prompt.prompt_text(tail),
132
+ prompt: last_prompt.person_prompt(tail),
133
133
  answers_question: stop_decision.is_question(last_prompt.turn_prompt(tail)),
134
134
  stop_hook_active: payload_tail.stop_hook_active,
135
135
  cut_pending: is_cut_stop(tail),
@@ -139,6 +139,7 @@ async function build_context(
139
139
  headless_refusals: stop_rules.count_headless_refusals(tail),
140
140
  background_pending: lane_background.pending_background_ids(tail).length > 0,
141
141
  agent_pending: lane_background.pending_agent_ids(tail).length > 0,
142
+ command_pending: lane_background.pending_command_ids(tail).length > 0,
142
143
  handed_off: lane_handoff.is_handed_off(process.cwd()),
143
144
  session_lang: session_lang(),
144
145
  }
@@ -124,6 +124,7 @@ const distributed_paths = {
124
124
  ensure_claude_md_import,
125
125
  remove_claude_md_import,
126
126
  CLAUDE_MD_IMPORT_LINE,
127
+ KIT_PACKAGE_PATH_PREFIX,
127
128
  }
128
129
 
129
130
  export { distributed_paths }
@@ -56,9 +56,13 @@ const LOCATION_VARIABLES =
56
56
  'GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_COMMON_DIR GIT_DIR GIT_INDEX_FILE GIT_NAMESPACE GIT_OBJECT_DIRECTORY GIT_WORK_TREE'
57
57
  const ROOT_LOOKUP = 'git rev-parse --show-toplevel'
58
58
  const LEGACY_ROOT_PREFIX = `if project_root="$(unset ${LOCATION_VARIABLES}; ${ROOT_LOOKUP} 2>/dev/null)"; then unset ${LOCATION_VARIABLES}; else project_root="$(${ROOT_LOOKUP})"; fi && cd "$project_root" && `
59
+ // The root prefix kit wrote until joshuafolkken/kit#4617 exported the launch directory for a worktree.
60
+ // History, never edited; removable from kit 2.0.0.
61
+ const PRE_WORKTREE_ROOT_PREFIX = `project_root="\${CLAUDE_PROJECT_DIR:-$( (unset ${LOCATION_VARIABLES}; ${ROOT_LOOKUP} 2>/dev/null) || ${ROOT_LOOKUP})}" && cd "$project_root" && `
59
62
  // The values below are matched inside raw JSON text, so each root prefix is taken in its escaped form.
60
63
  const ROOT_PREFIXES: ReadonlyArray<string> = [
61
64
  hook_launch.PROJECT_ROOT_PREFIX,
65
+ PRE_WORKTREE_ROOT_PREFIX,
62
66
  LEGACY_ROOT_PREFIX,
63
67
  ].map((prefix) => JSON.stringify(prefix).slice(1, -1))
64
68
  const [PROJECT_ROOT_PREFIX = ''] = ROOT_PREFIXES
@@ -87,7 +91,7 @@ function rewrite_command_value(value: string): string {
87
91
  }
88
92
 
89
93
  // kit's own commands already start from the root (`hook-launch.ts`), and so does an already-rewritten
90
- // value. The prefix — the current one or the one before it — is taken off before the rewrite and the
94
+ // value. The prefix — the current one or an earlier one — is taken off before the rewrite and the
91
95
  // current one put back after it, so the install guard sits behind the `cd` it depends on and a second
92
96
  // pass never doubles the prefix.
93
97
  function without_root_prefix(value: string): string {
@@ -10,7 +10,9 @@
10
10
  // first without the git location variables a git hook leaks, since a relative or bare `GIT_DIR` read
11
11
  // from a subdirectory names the wrong work tree, and with them only when the checkout does not resolve
12
12
  // without them (its metadata lives outside the work tree). A lookup that fails ends the command before
13
- // the launcher (joshuafolkken/kit#4187).
13
+ // the launcher (joshuafolkken/kit#4187). Inside one of Claude Code's own worktrees `CLAUDE_PROJECT_DIR`
14
+ // still names the main checkout, so the prefix exports where the hook was launched as `JOSH_HOOK_CWD`
15
+ // and the launcher moves the hook's working directory into that worktree (joshuafolkken/kit#4617).
14
16
  //
15
17
  // **Everything after the root is one script** (`scripts/hooks/run-hook.sh`): the git location
16
18
  // variables a git hook exports, the bundle-ready gate and the live-source fallback live there once, so
@@ -23,7 +25,7 @@ const HOOK_DIST_DIR = 'dist/hooks'
23
25
  const RUN_HOOK_SCRIPT = 'scripts/hooks/run-hook.sh'
24
26
  const ROOT_LOOKUP = 'git rev-parse --show-toplevel'
25
27
  const CODEX_ROOT = `$( (unset ${GIT_LOCATION_VARIABLES.join(' ')}; ${ROOT_LOOKUP} 2>/dev/null) || ${ROOT_LOOKUP})`
26
- const PROJECT_ROOT_PREFIX = `project_root="\${CLAUDE_PROJECT_DIR:-${CODEX_ROOT}}" && cd "$project_root" && `
28
+ const PROJECT_ROOT_PREFIX = `export JOSH_HOOK_CWD="$PWD" && project_root="\${CLAUDE_PROJECT_DIR:-${CODEX_ROOT}}" && cd "$project_root" && `
27
29
 
28
30
  // `name` is the hook's bundle under `dist/hooks` without `.js` (e.g. `pretool-guard`), followed by any
29
31
  // arguments it takes (e.g. `codex-hook-adapter pretool`).
@@ -0,0 +1,52 @@
1
+ import { markdown_section } from './markdown-section'
2
+ import { size_estimate } from './size-estimate'
3
+
4
+ // joshuafolkken/kit#5190: #5162 carried "aggregate the transcripts and record it as an Issue comment"
5
+ // beside a six-file implementation; the aggregation's output filled the lane's context before the
6
+ // implementation began and cut the session. The aggregation is a mergeable result of its own, so a body
7
+ // asking for both is refused and the aggregation routed to a prior `--route split` Issue — the
8
+ // implementation Issue then starts from the comment it cites.
9
+
10
+ const CRITERIA_HEADING = '## 受け入れ条件'
11
+ const CRITERION_PREFIX = '- ['
12
+ // Recording on an Issue, not a feature that posts a PR comment: every one of these words names the
13
+ // lane's own act.
14
+ const RECORDING_WORDS: ReadonlyArray<string> = ['Issue', 'コメント', '記録']
15
+ // What is recorded: an aggregation, or a measurement — #5202's before / after reach count, which carried
16
+ // no aggregation word and passed (joshuafolkken/kit#5238). One of them is enough.
17
+ const SUBJECT_WORDS: ReadonlyArray<string> = ['集計', '計測', 'before', '変更前後']
18
+ // A criterion citing the prior aggregation Issue is the implementation this rule asks for.
19
+ const ISSUE_REFERENCE = /#\d+/u
20
+ // The implementation the estimate declares: a prior aggregation Issue may add a script or two of its own.
21
+ const IMPLEMENTATION_FILES = 3
22
+ const REFUSAL = `an acceptance criterion records an aggregation or a measurement as an Issue comment beside an implementation of ${String(IMPLEMENTATION_FILES)}+ files — file it as a prior Issue (\`--route split\`) and cite its comment under ## 背景 in this one; issue-template.md → "\`## 背景\` 直下の宣言と分類ラベル"`
23
+
24
+ function is_aggregation_criterion(line: string): boolean {
25
+ const text = line.trim()
26
+
27
+ if (!text.startsWith(CRITERION_PREFIX) || ISSUE_REFERENCE.test(text)) return false
28
+
29
+ return (
30
+ SUBJECT_WORDS.some((word) => text.includes(word)) &&
31
+ RECORDING_WORDS.every((word) => text.includes(word))
32
+ )
33
+ }
34
+
35
+ function has_aggregation_criterion(body: string): boolean {
36
+ const criteria = markdown_section.section_lines(body, CRITERIA_HEADING).join('\n')
37
+
38
+ return markdown_section.unfenced_lines(criteria).some((line) => is_aggregation_criterion(line))
39
+ }
40
+
41
+ function declares_implementation(body: string): boolean {
42
+ return (size_estimate.declared_files(body) ?? 0) >= IMPLEMENTATION_FILES
43
+ }
44
+
45
+ // The refusal for a body carrying both; empty for an aggregation alone or an implementation alone.
46
+ function problems(body: string): ReadonlyArray<string> {
47
+ return has_aggregation_criterion(body) && declares_implementation(body) ? [REFUSAL] : []
48
+ }
49
+
50
+ const aggregation_split = { IMPLEMENTATION_FILES, problems }
51
+
52
+ export { aggregation_split }