@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
@@ -1,6 +1,7 @@
1
1
  import path from 'node:path'
2
+ import { since_green } from '#scripts/gate/since-green'
2
3
  import { changed_file_scope, type ChangedFileScope } from '#scripts/git/changed-file-scope'
3
- import { test_declared_logic } from './test-declared-logic'
4
+ import { pure_files_entries } from './pure-files-entries'
4
5
  import { test_read_map, type ReadMap } from './test-read-map'
5
6
  import { whole_suite_files } from './whole-suite-files'
6
7
 
@@ -14,10 +15,10 @@ import { whole_suite_files } from './whole-suite-files'
14
15
  // test-read map a whole-suite run records (`test-read-map.ts`). A changed document, config or
15
16
  // snapshot — which no module graph holds — reaches the modules that read it through that map alone. **Whatever neither can answer runs the whole suite**: no map, a
16
17
  // non-code file added since the recorded tree that no recorded test read, where a test read inside its
17
- // directory or the tree did not hold it, or a file every test
18
+ // directory, or a file every test
18
19
  // depends on — each counted only when this change moved it (joshuafolkken/kit#4527). A non-code file the recorded tree already held and no test read is one no test reads
19
- // (joshuafolkken/kit#4073), and so is one added since to a directory the tree held and no test read
20
- // inside (joshuafolkken/kit#4303), so a change made only of those runs nothing. CI runs the whole suite
20
+ // (joshuafolkken/kit#4073), and so is one added since to a directory no test read inside
21
+ // (joshuafolkken/kit#4303, joshuafolkken/kit#4597), so a change made only of those runs nothing. CI runs the whole suite
21
22
  // regardless, so a read the recorder could not see — one a child process makes — is still caught
22
23
  // before the merge.
23
24
  //
@@ -53,7 +54,7 @@ const { WHOLE_SUITE_FILES } = whole_suite_files
53
54
  const { UNREADABLE_REASON } = changed_file_scope
54
55
  const NOTHING_RELATABLE_REASON = 'no changed file is one a test can import or read'
55
56
  const NO_MAP_REASON = 'no test-read map covers the changed non-code file'
56
- const UNMOVED_REASON = 'nothing moved since its last green run on this checkout'
57
+ const { UNMOVED_REASON } = since_green
57
58
  const WHOLE_SUITE_SUFFIX = 'affects every test'
58
59
  const UNRECORDED_SUFFIX = 'is read by no recorded test'
59
60
 
@@ -97,13 +98,20 @@ interface ScopeRequest {
97
98
  recorded: ReadonlySet<string>
98
99
  is_present: (file_path: string) => boolean
99
100
  // The part of `changed` that joined only because it differs from the map's tree — which another
100
- // lane's branch records — not because this change moved it. A non-code file of it still adds the
101
- // tests reading it, a source file only through `naming_moved`, but neither ever sends the run to
102
- // the whole suite: this tree verified it already, or main's CI did (joshuafolkken/kit#4527).
101
+ // lane's branch records — not because this change moved it. Only a code file of it naming a moved
102
+ // file reaches vitest; the rest — its non-code files' readers among it — never runs a test nor sends
103
+ // the run to the whole suite: this tree verified it already, or main's CI did
104
+ // (joshuafolkken/kit#4527, joshuafolkken/kit#4896).
103
105
  since_map?: ReadonlyArray<string>
104
- // The source files of `since_map` that name a file this change moved — with its test files, the
105
- // only ones of that part handed to vitest (joshuafolkken/kit#4532). See `is_code_input`.
106
+ // The code files of `since_map` that name a file this change moved — the only ones of that part
107
+ // handed to vitest (joshuafolkken/kit#4532). See `is_code_input`.
106
108
  naming_moved?: ReadonlySet<string>
109
+ // The entries a change of `tools/test/pure-files.ts` moved, when it moved nothing else there — the
110
+ // list then reaches those test files rather than every test (`pure-files-entries.ts`).
111
+ pure_entries?: ReadonlyArray<string> | undefined
112
+ // The changed files every test imports, each with the test files importing it directly
113
+ // (`direct-importers.ts`) — the run narrows to those rather than the whole suite.
114
+ every_test_importers?: ReadonlyMap<string, ReadonlyArray<string>>
107
115
  }
108
116
 
109
117
  // What the decision narrows to: the files to hand vitest, and the changed files known to reach no
@@ -125,18 +133,17 @@ function is_moved(request: ScopeRequest, file: string): boolean {
125
133
  return request.since_map?.includes(file) !== true
126
134
  }
127
135
 
128
- // **A source file only the map's tree differs by — another lane's change, or main's since — is handed
129
- // to vitest only when it names a file this change moved** (joshuafolkken/kit#4532). Leaving the rest
130
- // out is safe: an import of a moved module is reached from that module itself, since `vitest related`
131
- // walks every test file's graph rather than the map's; the one read neither the graph nor the map sees
132
- // is a file-system read added since the map's tree, and such a read names the file it reads. A test
133
- // file of that part always joins: the map holds no entry for it, it may reach a moved file through a
134
- // helper's read rather than its own, and it runs only itself. A read whose path is assembled from
135
- // fragments or listed from a directory is missed here and caught by CI's whole suite before the merge,
136
- // as a child process's read is.
136
+ // **A code file only the map's tree differs by — another lane's change, or main's since, a test file
137
+ // among them — is handed to vitest only when it names a file this change moved**
138
+ // (joshuafolkken/kit#4532, joshuafolkken/kit#4896). Leaving the rest out is safe: an import of a moved
139
+ // module is reached from that module itself, since `vitest related` walks every test file's graph
140
+ // rather than the map's; the one read neither the graph nor the map sees is a file-system read added
141
+ // since the map's tree, and such a read names the file it reads. A test file reaching a moved file
142
+ // through a helper's read, or a read whose path is assembled from fragments or listed from a directory,
143
+ // is missed here and caught by CI's whole suite before the merge, as a child process's read is.
137
144
  function is_code_input(request: ScopeRequest, file: string): boolean {
138
145
  if (!is_relatable(file)) return false
139
- if (is_moved(request, file) || test_declared_logic.is_test_file(file)) return true
146
+ if (is_moved(request, file)) return true
140
147
 
141
148
  return request.naming_moved?.has(file) === true
142
149
  }
@@ -147,9 +154,9 @@ function all_scope(reason: string, triggers: ReadonlyArray<string> = [], root =
147
154
  return { mode: 'all', files: triggers.map((file) => path.join(root, file)), reason }
148
155
  }
149
156
 
150
- // A file no recorded test read narrows only when the recorded tree held it, or held its directory and
151
- // no recorded test read inside that: any other file added since is one the recorder never saw, so its
152
- // having no reader says nothing.
157
+ // A file no recorded test read narrows only when the recorded tree held it, or no recorded test read
158
+ // inside its directory: any other file added since is one the recorder never saw, so its having no
159
+ // reader says nothing.
153
160
  function resolve_through_map(others: ReadonlyArray<string>, request: ScopeRequest): MapResolution {
154
161
  const { map, recorded } = request
155
162
 
@@ -183,7 +190,7 @@ function code_readers(code: ReadonlyArray<string>, map: ReadMap | undefined): Ar
183
190
  function none_scope(unread: ReadonlyArray<string>, root: string): NoTestScope {
184
191
  const files = unread.map((file) => path.join(root, file))
185
192
 
186
- return { mode: 'none', files, reason: `${String(files.length)} changed file(s) no test reads` }
193
+ return { mode: 'none', files, reason: `${String(files.length)} changed file(s) reach no test` }
187
194
  }
188
195
 
189
196
  // Nothing to select is "no test" only when something settled it; an empty or vanished selection
@@ -202,28 +209,86 @@ function narrowed_scope(selection: Selection, request: ScopeRequest): RelatedSco
202
209
  return { mode: 'related', files: present, reason: `${String(present.length)} related file(s)` }
203
210
  }
204
211
 
205
- // `undefined` and `[]` are deliberately different inputs. The first says the change could not be
206
- // read; the second says it was read and held nothing to relate.
207
- function resolve_scope(request: ScopeRequest): RelatedScope {
208
- const { changed, root } = request
212
+ // The part only the map's tree differs by that reached no test — settled as surely as an unread file,
213
+ // so a tree holding nothing of this change's own runs no test rather than the whole suite.
214
+ function left_out(request: ScopeRequest, code: ReadonlyArray<string>): Array<string> {
215
+ return (request.since_map ?? []).filter((file) => !code.includes(file))
216
+ }
217
+
218
+ // The change with an entries-only `pure-files.ts` taken out of it, and the test files it reaches in
219
+ // its place — it would send `vitest related` to every test.
220
+ function without_pure_entries(
221
+ changed: ReadonlyArray<string>,
222
+ entries: ReadonlyArray<string> | undefined,
223
+ ): Selection {
224
+ if (entries === undefined) return { files: [], unread: changed }
225
+
226
+ const rest = changed.filter((file) => file !== pure_files_entries.PURE_FILES_PATH)
227
+
228
+ return { files: pure_files_entries.tests_of(entries), unread: rest }
229
+ }
230
+
231
+ function is_narrowed(request: ScopeRequest, file: string): boolean {
232
+ return request.every_test_importers?.has(file) === true
233
+ }
234
+
235
+ // **A moved file every test imports reaches only the test files importing it directly**
236
+ // (joshuafolkken/kit#5122): handed to vitest it would run the whole suite, which the gate's `test:unit`
237
+ // and CI run once regardless. One no test imports directly reaches no test here.
238
+ function direct_selection(request: ScopeRequest, changed: ReadonlyArray<string>): Selection {
239
+ const moved = changed.filter((file) => is_narrowed(request, file) && is_moved(request, file))
240
+ const tests = moved.map((file) => request.every_test_importers?.get(file) ?? [])
209
241
 
210
- if (changed === undefined) return all_scope(UNREADABLE_REASON)
242
+ return { files: tests.flat(), unread: moved.filter((_file, index) => tests[index]?.length === 0) }
243
+ }
244
+
245
+ function whole_suite_triggers(
246
+ request: ScopeRequest,
247
+ changed: ReadonlyArray<string>,
248
+ ): Array<string> {
249
+ return changed.filter(
250
+ (file) => WHOLE_SUITE_FILES.has(file) && !is_narrowed(request, file) && is_moved(request, file),
251
+ )
252
+ }
211
253
 
212
- const whole = changed.filter((file) => WHOLE_SUITE_FILES.has(file) && is_moved(request, file))
254
+ function resolve_read(
255
+ request: ScopeRequest & { changed: ReadonlyArray<string> },
256
+ entry_tests: ReadonlyArray<string>,
257
+ ): RelatedScope {
258
+ const { changed, root } = request
259
+ const whole = whole_suite_triggers(request, changed)
213
260
 
214
261
  if (whole.length > 0) return all_scope(`${String(whole[0])} ${WHOLE_SUITE_SUFFIX}`, whole, root)
215
262
 
216
- const code = changed.filter((file) => is_code_input(request, file))
263
+ const direct = direct_selection(request, changed)
264
+ const code = changed.filter((file) => !is_narrowed(request, file) && is_code_input(request, file))
217
265
  const resolution = resolve_through_map(
218
- changed.filter((file) => !is_relatable(file)),
266
+ changed.filter((file) => !is_relatable(file) && is_moved(request, file)),
219
267
  request,
220
268
  )
221
269
 
222
270
  if ('reason' in resolution) return all_scope(resolution.reason, resolution.triggers, root)
223
271
 
224
- const files = [...code, ...code_readers(code, request.map), ...resolution.files]
272
+ const files = [
273
+ ...code,
274
+ ...code_readers(code, request.map),
275
+ ...resolution.files,
276
+ ...entry_tests,
277
+ ...direct.files,
278
+ ]
279
+ const unread = [...resolution.unread, ...left_out(request, code), ...direct.unread]
280
+
281
+ return narrowed_scope({ files, unread }, request)
282
+ }
283
+
284
+ // `undefined` and `[]` are deliberately different inputs. The first says the change could not be
285
+ // read; the second says it was read and held nothing to relate.
286
+ function resolve_scope(request: ScopeRequest): RelatedScope {
287
+ if (request.changed === undefined) return all_scope(UNREADABLE_REASON)
288
+
289
+ const pure = without_pure_entries(request.changed, request.pure_entries)
225
290
 
226
- return narrowed_scope({ files, unread: resolution.unread }, request)
291
+ return resolve_read({ ...request, changed: pure.unread }, pure.files)
227
292
  }
228
293
 
229
294
  function describe_scope(scope: RelatedScope, root: string): string {
@@ -0,0 +1,135 @@
1
+ import { existsSync } from 'node:fs'
2
+ import path from 'node:path'
3
+ import { import_graph, type ImportGraph } from '#scripts/lint/import-graph'
4
+ import { test_declared_logic } from './test-declared-logic'
5
+ import { test_pinned_reach } from './test-pinned-reach'
6
+ import { test_read_map, type ReadMap } from './test-read-map'
7
+ import { related_scope } from './test-related-scope'
8
+ import { whole_suite_files } from './whole-suite-files'
9
+
10
+ // **A code module a main sync brought in reaches vitest only through a test this branch's change
11
+ // reaches too** (joshuafolkken/kit#4912). Handed to `vitest related` as a moved file, such a module ran
12
+ // every test importing it, and main's CI had already run those against it. The tests where the two can
13
+ // meet — whose imports reach both the synced module and this branch's own change — run through that
14
+ // change in its place (`own_of`), which `vitest related` walks by its own graph. `shared` names them as
15
+ // this graph reads them, but is never handed to vitest: the graph follows type-only imports and
16
+ // ambient declarations too, and so reaches hundreds of tests the branch's change never runs
17
+ // (joshuafolkken/kit#5066). Its being empty says the two never meet.
18
+ //
19
+ // **The import graph is TypeScript's, which drops an import it cannot resolve**, so only what it can
20
+ // follow is left out. Nothing is left out where no graph can be built, the branch change or the map
21
+ // cannot be read, the branch changed a file every test depends on, or the work tree holds a
22
+ // component TypeScript does not resolve; a synced module that is gone or is such a component stays a
23
+ // moved file. Each of those runs the tests importing it, as before. A synced module every test depends
24
+ // on is not split either: `test-related.ts` leaves it to main's CI unless this branch changed it too.
25
+
26
+ // `left` are the synced modules no longer handed to vitest, `shared` the tests where they meet the change,
27
+ // `meeting` every file whose imports reach both — `shared` and the code between, which `josh ship`'s
28
+ // lint settle reads (joshuafolkken/kit#4985) — all repository-root-relative.
29
+ interface SyncedSplit {
30
+ left: ReadonlyArray<string>
31
+ shared: ReadonlyArray<string>
32
+ meeting: ReadonlyArray<string>
33
+ }
34
+
35
+ // What the split is read from: the synced modules this branch did not change, the code of its own
36
+ // change, and every code file of the work tree, all absolute as the graph resolves them.
37
+ interface SplitInputs {
38
+ root: string
39
+ main_only: ReadonlyArray<string>
40
+ own: ReadonlyArray<string>
41
+ universe: ReadonlyArray<string>
42
+ }
43
+
44
+ const NOTHING_LEFT: SyncedSplit = { left: [], shared: [], meeting: [] }
45
+ const UNRESOLVED_EXTENSION = '.svelte'
46
+
47
+ function is_unresolved(file: string): boolean {
48
+ return path.extname(file) === UNRESOLVED_EXTENSION
49
+ }
50
+
51
+ function is_beyond_graph(file: string): boolean {
52
+ return whole_suite_files.WHOLE_SUITE_FILES.has(path.normalize(file)) || is_unresolved(file)
53
+ }
54
+
55
+ function is_vouched(root: string, file: string): boolean {
56
+ if (!related_scope.is_relatable(file) || is_beyond_graph(file)) return false
57
+
58
+ return existsSync(path.join(root, file))
59
+ }
60
+
61
+ // The branch's own change as the graph reads it: its code files and the recorded readers of its
62
+ // non-code ones. `undefined` where the graph cannot vouch for it.
63
+ function own_of(
64
+ branch: ReadonlyArray<string> | undefined,
65
+ map: ReadMap | undefined,
66
+ ): ReadonlyArray<string> | undefined {
67
+ if (branch === undefined || map === undefined) return undefined
68
+
69
+ const data = branch.filter((file) => !related_scope.is_relatable(file))
70
+ const readers = data.flatMap((file) => test_read_map.readers_of(map, file))
71
+ const code = branch.filter((file) => related_scope.is_relatable(file))
72
+
73
+ return branch.some((file) => is_beyond_graph(file)) ? undefined : [...code, ...readers]
74
+ }
75
+
76
+ function split_with(graph: ImportGraph, inputs: SplitInputs): SyncedSplit {
77
+ const { root, main_only, own, universe } = inputs
78
+ const from_branch = graph.runtime_importers(own, universe)
79
+ const meeting = [...graph.runtime_importers(main_only, universe)]
80
+ .filter((file) => from_branch.has(file))
81
+ .map((file) => path.relative(root, file))
82
+ const shared = meeting.filter((file) => test_declared_logic.is_test_file(file))
83
+
84
+ return { left: main_only.map((file) => path.relative(root, file)), shared, meeting }
85
+ }
86
+
87
+ function absolute_in(root: string, files: ReadonlyArray<string>): Array<string> {
88
+ return files.map((file) => path.join(root, file))
89
+ }
90
+
91
+ async function split_by_graph(
92
+ root: string,
93
+ main_only: ReadonlyArray<string>,
94
+ own: ReadonlyArray<string>,
95
+ ): Promise<SyncedSplit> {
96
+ const graph = await import_graph.create(root)
97
+
98
+ if (graph === undefined) return NOTHING_LEFT
99
+
100
+ const universe = await test_pinned_reach.code_universe()
101
+
102
+ if (universe.some((file) => is_unresolved(file))) return NOTHING_LEFT
103
+
104
+ return split_with(graph, {
105
+ root,
106
+ main_only: absolute_in(root, main_only),
107
+ own: absolute_in(root, own),
108
+ universe,
109
+ })
110
+ }
111
+
112
+ // The graph is built only when a synced module this branch did not change is there to split. A failure
113
+ // to build or walk it — git unreadable, a file gone mid-walk — leaves nothing out.
114
+ async function split(
115
+ root: string,
116
+ synced: ReadonlyArray<string>,
117
+ branch: ReadonlyArray<string> | undefined,
118
+ map: ReadMap | undefined,
119
+ ): Promise<SyncedSplit> {
120
+ const own = own_of(branch, map)
121
+ const main_only = synced.filter((file) => !own?.includes(file) && is_vouched(root, file))
122
+
123
+ if (own === undefined || main_only.length === 0) return NOTHING_LEFT
124
+
125
+ try {
126
+ return await split_by_graph(root, main_only, own)
127
+ } catch {
128
+ return NOTHING_LEFT
129
+ }
130
+ }
131
+
132
+ const test_related_synced = { own_of, split, split_with }
133
+
134
+ export type { SyncedSplit }
135
+ export { test_related_synced }
@@ -0,0 +1,84 @@
1
+ import { readdirSync } from 'node:fs'
2
+ import path from 'node:path'
3
+ import { related_scope, type RelatedScope } from './test-related-scope'
4
+
5
+ // `josh test:related --touched` — the implementation loop's re-check (joshuafolkken/kit#5237). A change
6
+ // near a hub reaches hundreds of test files, and paying that reach after every small edit repeats it
7
+ // minutes apart. **The touched scope reads no test-read map and no import graph**: it is the diff's own
8
+ // test files and, for each changed module `foo.ts`, its colocated `foo.test.ts` and `foo.*.test.ts`.
9
+ // What an edit breaks further away is the full-reach run's to find, so a touched run leaves no green
10
+ // record (`scoped-green.ts`) and is recorded in the lane ledger under its own kind.
11
+
12
+ const TOUCHED_FLAG = '--touched'
13
+ const TOUCHED_KIND = 'touched'
14
+ const TEST_SUFFIX = '.test.ts'
15
+ const TOUCHED_REASON = 'the diff test files and the tests named after its modules'
16
+ const NOTHING_TOUCHED_REASON = 'no test file is in the diff or named after a changed module'
17
+
18
+ type ListDirectory = (directory: string) => ReadonlyArray<string>
19
+
20
+ // A directory that cannot be listed holds no test to run.
21
+ function list_directory(directory: string): ReadonlyArray<string> {
22
+ try {
23
+ return readdirSync(directory)
24
+ } catch {
25
+ return []
26
+ }
27
+ }
28
+
29
+ function is_named_after(module_file: string, name: string): boolean {
30
+ const stem = path.basename(module_file, path.extname(module_file))
31
+
32
+ return name.startsWith(`${stem}.`) && name.endsWith(TEST_SUFFIX)
33
+ }
34
+
35
+ // A test file of the diff runs itself while it is still on disk; a module runs its same-named tests.
36
+ function tests_of(root: string, file: string, list: ListDirectory): Array<string> {
37
+ const directory = path.dirname(file)
38
+ const names = list(path.join(root, directory))
39
+
40
+ if (file.endsWith(TEST_SUFFIX)) return names.includes(path.basename(file)) ? [file] : []
41
+ if (!related_scope.is_relatable(file)) return []
42
+
43
+ return names
44
+ .filter((name) => is_named_after(file, name))
45
+ .map((name) => path.join(directory, name))
46
+ }
47
+
48
+ function touched_tests(
49
+ root: string,
50
+ changed: ReadonlyArray<string>,
51
+ list: ListDirectory = list_directory,
52
+ ): Array<string> {
53
+ return [...new Set(changed.flatMap((file) => tests_of(root, file, list)))]
54
+ }
55
+
56
+ // `changed` is repository-root-relative; `undefined` — a diff git could not read — runs the whole suite,
57
+ // as an unreadable change does for the full-reach run.
58
+ function touched_scope(
59
+ root: string,
60
+ changed: ReadonlyArray<string> | undefined,
61
+ list: ListDirectory = list_directory,
62
+ ): RelatedScope {
63
+ const { UNREADABLE_REASON } = related_scope
64
+
65
+ if (changed === undefined) return { mode: 'all', files: [], reason: UNREADABLE_REASON }
66
+
67
+ const files = touched_tests(root, changed, list).map((file) => path.join(root, file))
68
+
69
+ if (files.length === 0) return { mode: 'none', files: [], reason: NOTHING_TOUCHED_REASON }
70
+
71
+ return { mode: 'related', files, reason: TOUCHED_REASON }
72
+ }
73
+
74
+ const test_related_touched = {
75
+ NOTHING_TOUCHED_REASON,
76
+ TOUCHED_FLAG,
77
+ TOUCHED_KIND,
78
+ TOUCHED_REASON,
79
+ touched_scope,
80
+ touched_tests,
81
+ }
82
+
83
+ export type { ListDirectory }
84
+ export { test_related_touched }