@joshuafolkken/kit 1.1514.0 → 1.1784.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 (858) hide show
  1. package/.claude/agents/investigator.md +1 -1
  2. package/.claude/settings.json +5 -5
  3. package/.claude/skills/epic-commands/SKILL.md +26 -65
  4. package/.claude/skills/epic-commands/epic-bundle.md +3 -1
  5. package/.claude/skills/workflow-commands/SKILL.md +5 -5
  6. package/.claude/skills/workflow-commands/background-commands.md +5 -5
  7. package/.claude/skills/workflow-commands/backlogrun-child.md +10 -8
  8. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
  9. package/.claude/skills/workflow-commands/backlogrun-lanes.md +17 -13
  10. package/.claude/skills/workflow-commands/backlogrun-park.md +14 -23
  11. package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -2
  12. package/.claude/skills/workflow-commands/backlogrun-recovery.md +5 -5
  13. package/.claude/skills/workflow-commands/backlogrun-steps.md +10 -10
  14. package/.claude/skills/workflow-commands/backlogrun.md +1 -1
  15. package/.claude/skills/workflow-commands/chain-rule.md +13 -7
  16. package/.claude/skills/workflow-commands/delegation.md +6 -5
  17. package/.claude/skills/workflow-commands/entry-sequence.md +9 -9
  18. package/.claude/skills/workflow-commands/followup.md +9 -31
  19. package/.claude/skills/workflow-commands/fullrun-steps.md +36 -45
  20. package/.claude/skills/workflow-commands/fullrun.md +2 -2
  21. package/.claude/skills/workflow-commands/halfrun.md +17 -25
  22. package/.claude/skills/workflow-commands/issue-comments.md +16 -12
  23. package/.claude/skills/workflow-commands/issue-scout.md +2 -2
  24. package/.claude/skills/workflow-commands/kickoff.md +24 -23
  25. package/.claude/skills/workflow-commands/latest-gate.md +7 -12
  26. package/.claude/skills/workflow-commands/needs-human-review.md +9 -14
  27. package/.claude/skills/workflow-commands/observation-filing.md +4 -36
  28. package/.claude/skills/workflow-commands/observation-ledger.md +1 -1
  29. package/.claude/skills/workflow-commands/pre-gate-cut.md +13 -30
  30. package/.claude/skills/workflow-commands/prerequisite.md +10 -16
  31. package/.claude/skills/workflow-commands/progress-watcher.md +1 -1
  32. package/.claude/skills/workflow-commands/prrun.md +3 -7
  33. package/.claude/skills/workflow-commands/retrospective.md +1 -1
  34. package/.claude/skills/workflow-commands/split-assessment.md +13 -1
  35. package/.claude/skills/workflow-commands/working-tree-hold.md +9 -9
  36. package/.codex/hooks.json +5 -5
  37. package/.github/actions/setup-node/action.yml +9 -0
  38. package/.github/actions/setup-pnpm/action.yml +1 -1
  39. package/.github/dependabot.yml +16 -0
  40. package/.github/release.yml +0 -2
  41. package/.github/workflows/ci.yml +120 -10
  42. package/.github/workflows/publish.yml +8 -1
  43. package/.github/workflows/sonar-qube.yml +1 -0
  44. package/.prettierignore +2 -0
  45. package/.vscode/tasks.json +1 -2
  46. package/CLAUDE.md +3 -7
  47. package/README.md +4 -2
  48. package/SECURITY.md +1 -1
  49. package/dist/CLAUDE.md +3 -7
  50. package/dist/commands/document-read-cli.js +882 -0
  51. package/dist/commands/{document-section-cli.js → document-section-main.js} +79 -37
  52. package/dist/commands/read-set-cli.js +1867 -0
  53. package/dist/commands/run-prep-main.js +21653 -0
  54. package/dist/commands/run-step-cli.js +23880 -0
  55. package/dist/config-merge/index.js +5 -1
  56. package/dist/hooks/audit-provision.js +20 -35
  57. package/dist/hooks/{chunk-DGT54IH5.js → chunk-AZX4FGQ3.js} +63 -17
  58. package/dist/hooks/chunk-CWMBGKYW.js +6483 -0
  59. package/dist/hooks/chunk-O2YBIDSI.js +4306 -0
  60. package/dist/hooks/{chunk-TNUMY6NL.js → chunk-PT5R6UJD.js} +4193 -1900
  61. package/dist/hooks/chunk-TUIFS5E7.js +72 -0
  62. package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
  63. package/dist/hooks/{chunk-APUO6U4J.js → chunk-WR2KQAYZ.js} +1843 -440
  64. package/dist/hooks/{chunk-O6GDRNJB.js → chunk-XGBNSWEI.js} +248 -46
  65. package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
  66. package/dist/hooks/codex-hook-adapter.js +10 -22
  67. package/dist/hooks/format-edited.js +5 -6
  68. package/dist/hooks/inputs.json +443 -317
  69. package/dist/hooks/pretool-guard.js +7 -25
  70. package/dist/hooks/session-lang.js +44 -51
  71. package/dist/hooks/stop-guard.js +7716 -2187
  72. package/dist/josh.js +6002 -3583
  73. package/dist/self-sync-guard/index.js +74 -10
  74. package/dist/version/index.js +115 -406
  75. package/eslint/base.js +1 -1
  76. package/lefthook/base.yml +3 -1
  77. package/package.json +10 -48
  78. package/pnpm-workspace.yaml +4 -2
  79. package/prompts/coding-standards.md +1 -1
  80. package/prompts/collaboration-workflow/file-edits.md +1 -7
  81. package/prompts/collaboration-workflow/issue-citation.md +1 -1
  82. package/prompts/collaboration-workflow/issue-template.md +33 -16
  83. package/prompts/collaboration-workflow/lane-instructions.md +1 -2
  84. package/prompts/collaboration-workflow/measurement.md +37 -0
  85. package/prompts/collaboration-workflow/operating-rules.md +4 -6
  86. package/prompts/collaboration-workflow/output-bounds.md +2 -7
  87. package/prompts/collaboration-workflow/plan-comment.md +3 -42
  88. package/prompts/collaboration-workflow/principles.md +5 -0
  89. package/prompts/collaboration-workflow/report-format.md +31 -60
  90. package/prompts/collaboration-workflow/residency.md +2 -2
  91. package/prompts/collaboration-workflow/shell-body.md +6 -16
  92. package/prompts/collaboration-workflow/turn-batching.md +0 -2
  93. package/prompts/collaboration-workflow/upstream-interrupt.md +14 -4
  94. package/prompts/collaboration-workflow/wip-cap.md +1 -1
  95. package/prompts/collaboration-workflow.md +3 -7
  96. package/prompts/refactoring.md +1 -1
  97. package/prompts/review-rubric.md +1 -2
  98. package/prompts/review.md +41 -21
  99. package/prompts/testing-guide.md +8 -43
  100. package/scripts/agent/agent-event.ts +15 -15
  101. package/scripts/agent/agent-exit-record.ts +13 -1
  102. package/scripts/agent/api-auth.ts +41 -0
  103. package/scripts/agent/api-outage.ts +1 -1
  104. package/scripts/auto-ok/auto-ok-cli.ts +14 -16
  105. package/scripts/auto-ok/auto-ok-judge-read.ts +12 -3
  106. package/scripts/auto-ok/auto-ok-judge-write.ts +46 -19
  107. package/scripts/auto-ok/auto-ok-judge.ts +13 -2
  108. package/scripts/auto-ok/auto-ok-main.ts +17 -0
  109. package/scripts/backlog/backlog-arrival.ts +14 -3
  110. package/scripts/backlog/backlog-budget-cli.ts +7 -33
  111. package/scripts/backlog/backlog-budget-main.ts +16 -0
  112. package/scripts/backlog/backlog-budget.ts +2 -3
  113. package/scripts/backlog/backlog-defect-priority.ts +4 -3
  114. package/scripts/backlog/backlog-drive-adopt.ts +67 -0
  115. package/scripts/backlog/backlog-drive-args.ts +4 -5
  116. package/scripts/backlog/backlog-drive-cli.ts +113 -28
  117. package/scripts/backlog/backlog-drive-hold.ts +162 -0
  118. package/scripts/backlog/backlog-drive-idle.ts +151 -0
  119. package/scripts/backlog/backlog-drive-judge.ts +25 -0
  120. package/scripts/backlog/backlog-drive-memory.ts +126 -0
  121. package/scripts/backlog/backlog-drive-named-offer.ts +5 -10
  122. package/scripts/backlog/backlog-drive-named.ts +53 -6
  123. package/scripts/backlog/backlog-drive-offer-argv.ts +3 -8
  124. package/scripts/backlog/backlog-drive-paused.ts +169 -0
  125. package/scripts/backlog/backlog-drive-restore.ts +30 -7
  126. package/scripts/backlog/backlog-drive-seats.ts +18 -8
  127. package/scripts/backlog/backlog-drive-token-handling.ts +38 -0
  128. package/scripts/backlog/backlog-drive.ts +79 -75
  129. package/scripts/backlog/backlog-next-main.ts +16 -0
  130. package/scripts/backlog/backlog-next-shared.ts +73 -0
  131. package/scripts/backlog/backlog-next.ts +48 -16
  132. package/scripts/backlog/backlog-occupied.ts +52 -39
  133. package/scripts/backlog/backlog-offer-cli.ts +6 -21
  134. package/scripts/backlog/backlog-offer-exclude.ts +15 -0
  135. package/scripts/backlog/backlog-offer-main.ts +12 -0
  136. package/scripts/backlog/backlog-offer.ts +36 -3
  137. package/scripts/backlog/backlog-overlap.ts +22 -4
  138. package/scripts/backlog/backlog-plan-read.ts +6 -2
  139. package/scripts/backlog/backlog-plan.ts +18 -4
  140. package/scripts/backlog/backlog-pool.ts +10 -10
  141. package/scripts/backlog/backlog-rank.ts +10 -2
  142. package/scripts/backlog/backlog-ready.ts +112 -30
  143. package/scripts/backlog/backlog-stalled-detect.ts +109 -36
  144. package/scripts/backlog/backlog-stalled.ts +52 -16
  145. package/scripts/backlog/backlog-wait-cause.ts +86 -0
  146. package/scripts/backlog/backlog-waves.ts +39 -13
  147. package/scripts/backlog/backlogrun-args.ts +19 -7
  148. package/scripts/backlog/backlogrun-cli.ts +19 -5
  149. package/scripts/backlog/backlogrun-launch.ts +6 -0
  150. package/scripts/backlog/backlogrun-restart.ts +97 -0
  151. package/scripts/backlog/backlogrun-stop.ts +79 -7
  152. package/scripts/behavior/behavior-cli.ts +2 -2
  153. package/scripts/behavior/behavior-rules.ts +47 -24
  154. package/scripts/build/build-bin.ts +2 -16
  155. package/scripts/build/build-claude-md.ts +0 -7
  156. package/scripts/build/build-commands.ts +0 -13
  157. package/scripts/build/build-hooks.ts +49 -48
  158. package/scripts/build/hook-bundle-stamp.ts +29 -11
  159. package/scripts/build/local-bin.ts +1 -1
  160. package/scripts/cases/cases-cli.ts +25 -13
  161. package/scripts/cases/cases-interaction-scan.ts +134 -0
  162. package/scripts/cases/cases-interaction.ts +183 -0
  163. package/scripts/cases/cases-logic.ts +39 -6
  164. package/scripts/ci/pr-classification-main.ts +18 -0
  165. package/scripts/ci/pr-classification.ts +10 -17
  166. package/scripts/clone/clone-scan.ts +1 -1
  167. package/scripts/cost-runtime/cost-blocks.ts +22 -37
  168. package/scripts/cost-runtime/cost-cli.ts +31 -14
  169. package/scripts/cost-runtime/cost-main.ts +12 -0
  170. package/scripts/cost-runtime/cost-transcript.ts +1 -0
  171. package/scripts/delegation/delegation-policy.ts +17 -4
  172. package/scripts/delegation/duplicate-read-guard.ts +0 -8
  173. package/scripts/delegation/investigation-guard.ts +0 -8
  174. package/scripts/delegation/investigation-reads.ts +3 -4
  175. package/scripts/dependabot/dependabot-cooldown.ts +194 -0
  176. package/scripts/discovery/repo-discovery.ts +24 -6
  177. package/scripts/doctor/doctor-consumer.ts +2 -5
  178. package/scripts/document/document-byte-budget.ts +8 -6
  179. package/scripts/document/document-scan.ts +1 -1
  180. package/scripts/document/document-section-cli.ts +0 -8
  181. package/scripts/document/document-section-main.ts +12 -0
  182. package/scripts/epic/epic-audit-cli.ts +12 -6
  183. package/scripts/epic/epic-bundle-apply.ts +137 -0
  184. package/scripts/epic/epic-bundle-cli.ts +32 -121
  185. package/scripts/epic/epic-bundle-format.ts +116 -0
  186. package/scripts/epic/epic-bundle-main.ts +17 -0
  187. package/scripts/epic/epic-busy.ts +5 -12
  188. package/scripts/epic/epic-classify.ts +24 -15
  189. package/scripts/epic/epic-cli-argv.ts +31 -0
  190. package/scripts/epic/epic-cli-decide.ts +42 -0
  191. package/scripts/epic/epic-cli.ts +6 -38
  192. package/scripts/epic/epic-close.ts +112 -55
  193. package/scripts/epic/epic-cross-repo.ts +4 -7
  194. package/scripts/epic/epic-decide.ts +119 -0
  195. package/scripts/epic/epic-decision.ts +9 -0
  196. package/scripts/epic/epic-fetch.ts +4 -0
  197. package/scripts/epic/epic-graph.ts +2 -0
  198. package/scripts/epic/epic-issue.ts +5 -1
  199. package/scripts/epic/epic-label-age.ts +1 -1
  200. package/scripts/epic/epic-lane-offer.ts +39 -4
  201. package/scripts/epic/epic-next-main.ts +24 -0
  202. package/scripts/epic/epic-next.ts +6 -24
  203. package/scripts/epic/epic-outside-blocker.ts +6 -2
  204. package/scripts/epic/epic-parse.ts +9 -3
  205. package/scripts/epic/epic-read.ts +1 -0
  206. package/scripts/epic/epic-reconcile.ts +39 -0
  207. package/scripts/epic/epic-run.ts +10 -1
  208. package/scripts/epic/epic-solo.ts +50 -14
  209. package/scripts/epic/epic.ts +41 -7
  210. package/scripts/exports/unused-members-cli.ts +2 -2
  211. package/scripts/followup/followup-checks-event.ts +8 -3
  212. package/scripts/followup/followup-coderabbit-wait.ts +82 -0
  213. package/scripts/followup/followup-review-gates.ts +81 -0
  214. package/scripts/followup/git-followup-stages.ts +13 -3
  215. package/scripts/followup/git-followup-workflow.ts +19 -66
  216. package/scripts/followup/git-pr-followup-wrapup.ts +9 -14
  217. package/scripts/followup/git-pr-followup.ts +36 -8
  218. package/scripts/fresh-machine/fresh-machine-cli.ts +1 -1
  219. package/scripts/fresh-machine/fresh-machine-run.ts +8 -8
  220. package/scripts/fresh-machine/specs/kit-test-backlogrun.json +1 -1
  221. package/scripts/gate/busy-average.ts +58 -0
  222. package/scripts/gate/check-cpu.ts +60 -0
  223. package/scripts/gate/check-inputs.ts +39 -95
  224. package/scripts/gate/check-reuse.ts +33 -54
  225. package/scripts/gate/command-memory.ts +192 -0
  226. package/scripts/gate/core-admission.ts +218 -28
  227. package/scripts/gate/core-budget-timing.ts +37 -0
  228. package/scripts/gate/core-budget.ts +80 -98
  229. package/scripts/gate/core-wait-record.ts +48 -0
  230. package/scripts/gate/core-wait.ts +37 -5
  231. package/scripts/gate/core-weights.ts +86 -0
  232. package/scripts/gate/free-cores.ts +27 -4
  233. package/scripts/gate/gate-ledger.ts +32 -4
  234. package/scripts/gate/gate-plan.ts +41 -34
  235. package/scripts/gate/gate-report.ts +14 -2
  236. package/scripts/gate/gate-run-steps.ts +53 -8
  237. package/scripts/gate/gate-skip.ts +12 -2
  238. package/scripts/gate/gate-steps.ts +12 -1
  239. package/scripts/gate/input-fingerprint.ts +42 -0
  240. package/scripts/gate/machine-capacity.ts +65 -31
  241. package/scripts/gate/moved-paths.ts +67 -0
  242. package/scripts/gate/project-checks.ts +5 -12
  243. package/scripts/gate/scoped-green.ts +12 -8
  244. package/scripts/gate/since-green.ts +62 -0
  245. package/scripts/gate/toolchain-inputs.ts +115 -0
  246. package/scripts/gate/verification-gate.ts +27 -24
  247. package/scripts/gate/verification-inputs.ts +250 -0
  248. package/scripts/gh/gh-author-association.ts +96 -9
  249. package/scripts/gh/git-ai-review-scan.ts +4 -2
  250. package/scripts/gh/git-gh-api-path.ts +15 -0
  251. package/scripts/gh/git-gh-branch-rules.ts +73 -0
  252. package/scripts/gh/git-gh-conditional.ts +5 -2
  253. package/scripts/gh/git-gh-issue-read.ts +5 -1
  254. package/scripts/gh/git-gh-issue-write.ts +67 -29
  255. package/scripts/gh/git-gh-issue.ts +7 -3
  256. package/scripts/gh/git-gh-poll-read.ts +89 -0
  257. package/scripts/gh/git-gh-pr-auto-merge.ts +8 -3
  258. package/scripts/gh/git-gh-pr-rest.ts +1 -1
  259. package/scripts/gh/git-gh-pr-snapshot.ts +33 -20
  260. package/scripts/gh/git-gh-pr.ts +27 -15
  261. package/scripts/gh/git-pr-checks-eval.ts +39 -7
  262. package/scripts/gh/git-pr-checks-parse.ts +39 -9
  263. package/scripts/gh/git-pr-merge-checked.ts +80 -0
  264. package/scripts/git/base-tree.ts +19 -2
  265. package/scripts/git/changed-file-scope.ts +6 -4
  266. package/scripts/git/changed-paths.ts +18 -1
  267. package/scripts/git/git-diff-reads.ts +27 -2
  268. package/scripts/git/git-grep-hits.ts +85 -0
  269. package/scripts/git/git-location-environment.ts +1 -1
  270. package/scripts/git/git-merge-conflicts.ts +83 -0
  271. package/scripts/git/git-preflight.ts +37 -12
  272. package/scripts/git/git-push-transport.ts +1 -2
  273. package/scripts/git/git-schemas.ts +17 -7
  274. package/scripts/git/git-spawn.ts +1 -2
  275. package/scripts/git/git-status.ts +4 -4
  276. package/scripts/git/main-merge-main.ts +12 -0
  277. package/scripts/git/main-merge-regenerate.ts +2 -2
  278. package/scripts/git/main-merge.ts +25 -9
  279. package/scripts/git/main-sync-main.ts +12 -0
  280. package/scripts/git/main-sync.ts +0 -9
  281. package/scripts/git/stash/git-stash.ts +27 -4
  282. package/scripts/git/stash/{stash-pop-args.ts → stash-args.ts} +13 -10
  283. package/scripts/git/stash/stash-pop-cli.ts +6 -12
  284. package/scripts/git/stash/stash-pop-main.ts +12 -0
  285. package/scripts/git/stash/stash-push-cli.ts +76 -0
  286. package/scripts/git/stash/stash-push-main.ts +12 -0
  287. package/scripts/hooks/batch-guard.ts +0 -8
  288. package/scripts/hooks/check-commit-message-main.ts +8 -0
  289. package/scripts/hooks/check-commit-message.ts +4 -7
  290. package/scripts/hooks/format-edited-file.ts +8 -24
  291. package/scripts/hooks/pre-commit-lint.ts +30 -3
  292. package/scripts/hooks/pre-push-unit.ts +4 -2
  293. package/scripts/hooks/pretool-guard-cli.ts +1 -8
  294. package/scripts/hooks/pretool-guard.ts +32 -19
  295. package/scripts/hooks/reserved-run.ts +67 -9
  296. package/scripts/hooks/run-hook.sh +13 -4
  297. package/scripts/hooks/shell-rules-notice.ts +37 -0
  298. package/scripts/hooks/stop-actions.ts +2 -21
  299. package/scripts/hooks/stop-guard.ts +13 -9
  300. package/scripts/init/hook-command-rewrite.ts +19 -5
  301. package/scripts/init/hook-launch.ts +15 -17
  302. package/scripts/init/init-actions.ts +0 -6
  303. package/scripts/init/init-ai-copy.ts +10 -36
  304. package/scripts/init/init-bootstrap.ts +9 -8
  305. package/scripts/init/init-dry-run-report.ts +1 -1
  306. package/scripts/init/init-dry-run.ts +1 -1
  307. package/scripts/init/init-file-action.ts +7 -9
  308. package/scripts/init/init-logic-json-merge.ts +2 -2
  309. package/scripts/init/init-logic-migrate.ts +9 -82
  310. package/scripts/init/init-logic.ts +3 -2
  311. package/scripts/init/init-main.ts +12 -0
  312. package/scripts/init/init.ts +5 -12
  313. package/scripts/init/kit-development-versions.ts +3 -7
  314. package/scripts/init/kit-written-paths.ts +2 -2
  315. package/scripts/init/project-profile.ts +5 -4
  316. package/scripts/init/tsconfig-preset-migration.ts +2 -1
  317. package/scripts/init/vscode-tasks.ts +1 -1
  318. package/scripts/issue/defect-origin-cli.ts +106 -0
  319. package/scripts/issue/defect-origin-line.ts +60 -0
  320. package/scripts/issue/defect-origin-main.ts +11 -0
  321. package/scripts/issue/defect-origin.ts +114 -0
  322. package/scripts/issue/defect-rate-cli.ts +34 -78
  323. package/scripts/issue/defect-rate.ts +0 -16
  324. package/scripts/issue/defect-report-cli.ts +128 -0
  325. package/scripts/issue/defect-report-format.ts +56 -0
  326. package/scripts/issue/defect-report-main.ts +11 -0
  327. package/scripts/issue/defect-report.ts +160 -0
  328. package/scripts/issue/expected-effect-lint.ts +1 -0
  329. package/scripts/issue/issue-already-done-cli.ts +62 -0
  330. package/scripts/issue/issue-body-or-comment.ts +40 -0
  331. package/scripts/issue/issue-cite-cli.ts +0 -9
  332. package/scripts/issue/issue-cite-main.ts +12 -0
  333. package/scripts/issue/issue-classification.ts +12 -7
  334. package/scripts/issue/issue-comment-cli.ts +10 -24
  335. package/scripts/issue/issue-comment-main.ts +12 -0
  336. package/scripts/issue/issue-evidence-exit.ts +100 -0
  337. package/scripts/issue/issue-file-cli.ts +29 -7
  338. package/scripts/issue/issue-file.ts +19 -19
  339. package/scripts/issue/issue-fold-cli.ts +2 -11
  340. package/scripts/issue/issue-fold-main.ts +12 -0
  341. package/scripts/issue/issue-labels.ts +81 -90
  342. package/scripts/issue/issue-lint-cli.ts +2 -10
  343. package/scripts/issue/issue-lint-main.ts +12 -0
  344. package/scripts/issue/issue-measured-cli.ts +56 -0
  345. package/scripts/issue/issue-merged.ts +19 -2
  346. package/scripts/issue/issue-not-before-label.ts +135 -0
  347. package/scripts/issue/issue-not-before.ts +111 -0
  348. package/scripts/issue/issue-number-shape.ts +15 -1
  349. package/scripts/issue/issue-park.ts +28 -0
  350. package/scripts/issue/issue-plan-cli.ts +151 -0
  351. package/scripts/issue/issue-priority.ts +151 -0
  352. package/scripts/issue/issue-rank.ts +7 -1
  353. package/scripts/issue/issue-read-cli.ts +3 -10
  354. package/scripts/issue/issue-read-main.ts +12 -0
  355. package/scripts/issue/issue-read.ts +29 -5
  356. package/scripts/issue/issue-release-cli.ts +0 -10
  357. package/scripts/issue/issue-release-main.ts +13 -0
  358. package/scripts/issue/issue-release.ts +7 -12
  359. package/scripts/issue/issue-sample-gate.ts +192 -0
  360. package/scripts/issue/issue-sample-source.ts +76 -0
  361. package/scripts/issue/issue-scout-cli.ts +0 -11
  362. package/scripts/issue/issue-scout-main.ts +14 -0
  363. package/scripts/issue/issue-state-cli.ts +0 -10
  364. package/scripts/issue/issue-state-main.ts +12 -0
  365. package/scripts/issue/issue-watch-diff.ts +56 -15
  366. package/scripts/issue/issue-watch.ts +2 -1
  367. package/scripts/issue/issue-wip.ts +2 -7
  368. package/scripts/issue/measure-rerun-cli.ts +13 -8
  369. package/scripts/issue/plan-consumers-cli.ts +39 -0
  370. package/scripts/issue/plan-consumers-main.ts +11 -0
  371. package/scripts/issue/plan-consumers-section.ts +55 -0
  372. package/scripts/issue/plan-consumers.ts +127 -0
  373. package/scripts/josh/agent-session-environment.ts +1 -1
  374. package/scripts/josh/command-usage.ts +15 -43
  375. package/scripts/josh/file-map-stamp.ts +49 -16
  376. package/scripts/josh/hook-decision.ts +32 -20
  377. package/scripts/josh/josh-command-map.ts +4 -1
  378. package/scripts/josh/josh-command-types.ts +12 -6
  379. package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
  380. package/scripts/josh/josh-commands-ai.ts +157 -158
  381. package/scripts/josh/josh-commands-backlog.ts +82 -16
  382. package/scripts/josh/josh-commands-clone.ts +1 -0
  383. package/scripts/josh/josh-commands-development.ts +111 -71
  384. package/scripts/josh/josh-commands-document.ts +43 -1
  385. package/scripts/josh/josh-commands-epic.ts +171 -0
  386. package/scripts/josh/josh-commands-hooks.ts +25 -2
  387. package/scripts/josh/josh-commands-issue-write.ts +181 -0
  388. package/scripts/josh/josh-commands-issue.ts +124 -24
  389. package/scripts/josh/josh-commands-lane.ts +103 -2
  390. package/scripts/josh/josh-commands-lint.ts +19 -8
  391. package/scripts/josh/josh-commands-maintenance.ts +112 -4
  392. package/scripts/josh/josh-commands-pause.ts +29 -0
  393. package/scripts/josh/josh-commands-progress.ts +87 -0
  394. package/scripts/josh/josh-commands-project.ts +138 -9
  395. package/scripts/josh/josh-commands-review.ts +124 -0
  396. package/scripts/josh/josh-commands-run.ts +211 -23
  397. package/scripts/josh/josh-commands-ship.ts +169 -0
  398. package/scripts/josh/josh-commands-split.ts +9 -0
  399. package/scripts/josh/josh-commands-versioning.ts +49 -2
  400. package/scripts/josh/josh-commands-workflow.ts +144 -6
  401. package/scripts/josh/josh-logic.ts +6 -13
  402. package/scripts/josh/package-directory.ts +2 -4
  403. package/scripts/josh/process-identity.ts +13 -4
  404. package/scripts/josh/session-language-cli.ts +4 -8
  405. package/scripts/josh/session-language-main.ts +13 -0
  406. package/scripts/josh/session-language.ts +6 -1
  407. package/scripts/josh/shared-cache.ts +90 -0
  408. package/scripts/josh/stamp-file.ts +9 -15
  409. package/scripts/lane/lane-await.ts +51 -12
  410. package/scripts/lane/lane-cache.ts +5 -30
  411. package/scripts/lane/lane-capacity.ts +14 -23
  412. package/scripts/lane/lane-check-stats.ts +62 -21
  413. package/scripts/lane/lane-child-invocation.ts +8 -0
  414. package/scripts/lane/lane-cli.ts +15 -5
  415. package/scripts/lane/lane-close.ts +86 -18
  416. package/scripts/lane/lane-core-wait-stats.ts +66 -0
  417. package/scripts/lane/lane-dispatch.ts +24 -3
  418. package/scripts/lane/lane-gap-stats.ts +156 -0
  419. package/scripts/lane/lane-handoff.ts +69 -1
  420. package/scripts/lane/lane-held-stats.ts +129 -0
  421. package/scripts/lane/lane-install.ts +4 -11
  422. package/scripts/lane/lane-launch-cli.ts +0 -9
  423. package/scripts/lane/lane-launch-main.ts +12 -0
  424. package/scripts/lane/lane-ledger-schema.ts +266 -0
  425. package/scripts/lane/lane-ledger.ts +92 -123
  426. package/scripts/lane/lane-limit-cli.ts +12 -1
  427. package/scripts/lane/lane-measure-cli.ts +57 -11
  428. package/scripts/lane/lane-open.ts +9 -1
  429. package/scripts/lane/lane-parked.ts +3 -3
  430. package/scripts/lane/lane-pause-cli.ts +130 -0
  431. package/scripts/lane/lane-pause.ts +158 -0
  432. package/scripts/lane/lane-process-table.ts +166 -0
  433. package/scripts/lane/lane-reap-settle.ts +124 -0
  434. package/scripts/lane/lane-reap.ts +50 -15
  435. package/scripts/lane/lane-registry.ts +24 -3
  436. package/scripts/lane/lane-residents.ts +162 -0
  437. package/scripts/lane/lane-restart.ts +22 -2
  438. package/scripts/lane/lane-round-two-stats.ts +49 -0
  439. package/scripts/lane/lane-sampler.ts +4 -0
  440. package/scripts/lane/lane-session-action.ts +19 -5
  441. package/scripts/lane/lane-session-broker.ts +102 -21
  442. package/scripts/lane/lane-snapshot-trace.ts +84 -0
  443. package/scripts/lane/lane-spans.ts +51 -0
  444. package/scripts/lane/lane-spent.ts +6 -3
  445. package/scripts/lane/lane-stage-stats.ts +7 -2
  446. package/scripts/lane/lane-state.ts +302 -0
  447. package/scripts/lane/lane-stats.ts +58 -4
  448. package/scripts/lane/lane-stop-stats.ts +113 -37
  449. package/scripts/lane/lane-test-related-stats.ts +127 -0
  450. package/scripts/lane/lane-transcript-calls.ts +145 -0
  451. package/scripts/lane/lane-transcript-stats.ts +168 -0
  452. package/scripts/lane/lane-vacant.ts +13 -3
  453. package/scripts/lane/lane-withdraw-cli.ts +5 -4
  454. package/scripts/lane/lane-withdraw.ts +50 -49
  455. package/scripts/lane/process-directories.ts +70 -0
  456. package/scripts/lane/process-lane-marks.ts +94 -0
  457. package/scripts/lib/atomic-write.ts +62 -0
  458. package/scripts/lib/buffered-process.ts +12 -5
  459. package/scripts/lib/cli-flags.ts +53 -0
  460. package/scripts/lib/figure-format.ts +63 -0
  461. package/scripts/lib/json-value.ts +9 -1
  462. package/scripts/lib/package-manifest.ts +35 -0
  463. package/scripts/lib/read-file.ts +3 -1
  464. package/scripts/lib/stamped-memo.ts +63 -0
  465. package/scripts/lib/stdout-on-stderr.ts +24 -0
  466. package/scripts/lib/timeouts.ts +9 -0
  467. package/scripts/lib/transcript-record.ts +91 -0
  468. package/scripts/lines/effective-limit.ts +1 -1
  469. package/scripts/lint/eslint-cache-dependencies.ts +145 -0
  470. package/scripts/lint/eslint-daemon.ts +265 -0
  471. package/scripts/lint/format.ts +11 -2
  472. package/scripts/lint/import-graph.ts +279 -0
  473. package/scripts/lint/lint-gate-scope.ts +102 -0
  474. package/scripts/lint/lint-parallel-main.ts +19 -0
  475. package/scripts/lint/lint-parallel.ts +62 -30
  476. package/scripts/lint/lint-related-scope.ts +30 -24
  477. package/scripts/lint/lint-related.ts +38 -6
  478. package/scripts/notify/confirmation-options.ts +1 -2
  479. package/scripts/notify/telegram-notify.ts +20 -20
  480. package/scripts/notify/telegram-test-logic.ts +0 -1
  481. package/scripts/notify/telegram-test-main.ts +8 -0
  482. package/scripts/notify/telegram-test.ts +2 -6
  483. package/scripts/observations/observation-ledger.ts +13 -0
  484. package/scripts/observations/observations-flush-landing.ts +5 -3
  485. package/scripts/observations/observations-flush.ts +6 -1
  486. package/scripts/overrides/overrides-check.ts +2 -5
  487. package/scripts/overrides/overrides-files.ts +2 -1
  488. package/scripts/overrides/overrides-logic.ts +3 -6
  489. package/scripts/package/verify-optional-eslint-install.ts +8 -6
  490. package/scripts/propagate/propagate-publish.ts +2 -7
  491. package/scripts/propagate/propagate-targets.ts +4 -12
  492. package/scripts/refactor/import-graph.ts +9 -7
  493. package/scripts/release/github-release-runs.ts +17 -6
  494. package/scripts/release/release-approval-prune.ts +18 -0
  495. package/scripts/release/release-history.ts +1 -3
  496. package/scripts/release/release-progress.ts +42 -22
  497. package/scripts/release/release-publish-run.ts +39 -0
  498. package/scripts/release/release-publish.ts +6 -6
  499. package/scripts/release/release-scope-cli.ts +0 -10
  500. package/scripts/release/release-scope-main.ts +12 -0
  501. package/scripts/repo/repo-setting.ts +3 -6
  502. package/scripts/repo/required-checks-logic.ts +6 -15
  503. package/scripts/report/report-format-reference.ts +2 -0
  504. package/scripts/report/report-labels.ts +155 -0
  505. package/scripts/report/report-lint-cli.ts +3 -0
  506. package/scripts/report/report-lint.ts +85 -110
  507. package/scripts/report/report-template-cli.ts +59 -0
  508. package/scripts/report/report-template.ts +112 -0
  509. package/scripts/review/acceptance-map.ts +1 -0
  510. package/scripts/review/removed-tests-check.ts +86 -0
  511. package/scripts/review/removed-tests.ts +149 -0
  512. package/scripts/review/review-brief-cli.ts +81 -15
  513. package/scripts/review/review-brief-main.ts +12 -0
  514. package/scripts/review/review-brief.ts +31 -3
  515. package/scripts/review/review-code-tree.ts +10 -6
  516. package/scripts/review/review-comment-round.ts +26 -8
  517. package/scripts/review/review-finding-ledger.ts +30 -15
  518. package/scripts/review/review-interaction.ts +94 -0
  519. package/scripts/review/review-readers-scan.ts +163 -0
  520. package/scripts/review/review-record-cli.ts +69 -30
  521. package/scripts/review/review-record-main.ts +12 -0
  522. package/scripts/review/review-round-one-blobs.ts +221 -0
  523. package/scripts/review/review-round2-cli.ts +49 -12
  524. package/scripts/review/review-round2.ts +80 -12
  525. package/scripts/review/review-stamps.ts +19 -1
  526. package/scripts/review/review-stop-log.ts +96 -0
  527. package/scripts/review/review-stops-cli.ts +85 -0
  528. package/scripts/review/review-tree.ts +6 -17
  529. package/scripts/review/review-untouched-readers.ts +146 -0
  530. package/scripts/review/test-titles.ts +118 -0
  531. package/scripts/rules/agent-model.ts +8 -0
  532. package/scripts/rules/bash-triggers.ts +46 -3
  533. package/scripts/rules/decision-oracle-batch.ts +9 -1
  534. package/scripts/rules/decision-oracle.ts +2 -2
  535. package/scripts/rules/delivered-rules.ts +80 -2
  536. package/scripts/rules/destructive-command.ts +8 -1
  537. package/scripts/rules/direct-filing.ts +10 -2
  538. package/scripts/rules/direct-issue-comment.ts +117 -0
  539. package/scripts/rules/direct-pr-create.ts +69 -3
  540. package/scripts/rules/early-heartbeat.ts +2 -1
  541. package/scripts/rules/file-body.ts +7 -0
  542. package/scripts/rules/filing-cap.ts +7 -0
  543. package/scripts/rules/git-argv.ts +72 -14
  544. package/scripts/rules/git-force.ts +12 -2
  545. package/scripts/rules/guard-remedy.ts +4 -0
  546. package/scripts/rules/implementation-cut-verdict.ts +1 -1
  547. package/scripts/rules/implementation-cut.ts +11 -3
  548. package/scripts/rules/index-guard.ts +8 -1
  549. package/scripts/rules/issue-comments.ts +9 -1
  550. package/scripts/rules/josh-git-bare.ts +7 -0
  551. package/scripts/rules/lane-background.ts +67 -25
  552. package/scripts/rules/lane-carry-conflict.ts +6 -0
  553. package/scripts/rules/lane-direct-tool.ts +74 -0
  554. package/scripts/rules/lane-interactive-ask.ts +9 -2
  555. package/scripts/rules/lane-park.ts +45 -23
  556. package/scripts/rules/lane-split-park.ts +10 -2
  557. package/scripts/rules/lane-switch-main.ts +7 -0
  558. package/scripts/rules/oracle-consulted.ts +10 -0
  559. package/scripts/rules/oracle-firing.ts +1 -0
  560. package/scripts/rules/permission-guards.ts +3 -0
  561. package/scripts/rules/piped-verification.ts +1 -1
  562. package/scripts/rules/poll-loop.ts +7 -0
  563. package/scripts/rules/pr-merge.ts +123 -0
  564. package/scripts/rules/protected-files.ts +32 -5
  565. package/scripts/rules/raw-field-body.ts +6 -0
  566. package/scripts/rules/rule-body-guard.ts +8 -0
  567. package/scripts/rules/rule-list.ts +9 -28
  568. package/scripts/rules/rule-value-cache.ts +4 -9
  569. package/scripts/rules/rule-value-cli.ts +51 -32
  570. package/scripts/rules/rule-value.ts +1 -1
  571. package/scripts/rules/shell-segments.ts +35 -0
  572. package/scripts/rules/stop-rule-rows.ts +64 -0
  573. package/scripts/rules/stop-rules.ts +3 -4
  574. package/scripts/rules/test-declared-commit.ts +11 -1
  575. package/scripts/rules/third-party-write.ts +7 -0
  576. package/scripts/rules/timed-rerun.ts +69 -0
  577. package/scripts/rules/worktree-guard.ts +13 -3
  578. package/scripts/run/board/run-board-app-name.ts +23 -0
  579. package/scripts/run/board/run-board-cli.ts +65 -32
  580. package/scripts/run/board/run-board-earlier.ts +94 -0
  581. package/scripts/run/board/run-board-ending-reason.ts +67 -0
  582. package/scripts/run/board/run-board-estimate-schedule.ts +103 -0
  583. package/scripts/run/board/run-board-estimate.ts +98 -0
  584. package/scripts/run/board/run-board-fit.ts +153 -36
  585. package/scripts/run/board/run-board-fold.ts +123 -0
  586. package/scripts/run/board/run-board-fresh.ts +2 -2
  587. package/scripts/run/board/run-board-gather-live.ts +29 -0
  588. package/scripts/run/board/run-board-gather-thread.ts +189 -0
  589. package/scripts/run/board/run-board-gather-worker.ts +29 -0
  590. package/scripts/run/board/run-board-gather.ts +187 -0
  591. package/scripts/run/board/run-board-github.ts +118 -38
  592. package/scripts/run/board/run-board-header.ts +82 -20
  593. package/scripts/run/board/run-board-keys.ts +58 -0
  594. package/scripts/run/board/run-board-kind.ts +20 -6
  595. package/scripts/run/board/run-board-labels.ts +116 -71
  596. package/scripts/run/board/run-board-lane-state.ts +109 -0
  597. package/scripts/run/board/run-board-lane-time.ts +122 -0
  598. package/scripts/run/board/run-board-layout.ts +239 -60
  599. package/scripts/run/board/run-board-length.ts +52 -0
  600. package/scripts/run/board/run-board-machine.ts +8 -4
  601. package/scripts/run/board/run-board-main.ts +12 -0
  602. package/scripts/run/board/run-board-notes.ts +52 -31
  603. package/scripts/run/board/run-board-now.ts +1 -1
  604. package/scripts/run/board/run-board-operation.ts +15 -33
  605. package/scripts/run/board/run-board-phase.ts +1 -1
  606. package/scripts/run/board/run-board-plan-shared.ts +115 -0
  607. package/scripts/run/board/run-board-plan.ts +55 -3
  608. package/scripts/run/board/run-board-planning.ts +45 -0
  609. package/scripts/run/board/run-board-priority.ts +44 -0
  610. package/scripts/run/board/run-board-process-groups.ts +195 -0
  611. package/scripts/run/board/run-board-read.ts +151 -27
  612. package/scripts/run/board/run-board-reason.ts +235 -51
  613. package/scripts/run/board/run-board-released.ts +35 -0
  614. package/scripts/run/board/run-board-render-checks.ts +39 -5
  615. package/scripts/run/board/run-board-render-condition.ts +96 -0
  616. package/scripts/run/board/run-board-render-drawn.ts +67 -0
  617. package/scripts/run/board/run-board-render-foot.ts +59 -0
  618. package/scripts/run/board/run-board-render-icon.ts +35 -0
  619. package/scripts/run/board/run-board-render-lanes.ts +145 -0
  620. package/scripts/run/board/run-board-render-lead.ts +80 -0
  621. package/scripts/run/board/run-board-render-legend.ts +117 -48
  622. package/scripts/run/board/run-board-render-notes.ts +156 -29
  623. package/scripts/run/board/run-board-render-processes.ts +196 -0
  624. package/scripts/run/board/run-board-render-section.ts +119 -0
  625. package/scripts/run/board/run-board-render-slot.ts +3 -36
  626. package/scripts/run/board/run-board-render-tail.ts +115 -48
  627. package/scripts/run/board/run-board-render-time.ts +56 -0
  628. package/scripts/run/board/run-board-render-title.ts +117 -24
  629. package/scripts/run/board/run-board-render-waits.ts +104 -20
  630. package/scripts/run/board/run-board-render.ts +207 -265
  631. package/scripts/run/board/run-board-roots.ts +54 -0
  632. package/scripts/run/board/run-board-row-yield.ts +9 -4
  633. package/scripts/run/board/run-board-setup.ts +1 -12
  634. package/scripts/run/board/run-board-snapshot.ts +111 -0
  635. package/scripts/run/board/run-board-spin.ts +2 -2
  636. package/scripts/run/board/run-board-state.ts +22 -33
  637. package/scripts/run/board/run-board-status.ts +147 -71
  638. package/scripts/run/board/run-board-thanks-read.ts +2 -2
  639. package/scripts/run/board/run-board-tick.ts +122 -107
  640. package/scripts/run/board/run-board-usage-board.ts +78 -0
  641. package/scripts/run/board/run-board-usage-lanes.ts +113 -0
  642. package/scripts/run/board/run-board-usage-listing.ts +93 -0
  643. package/scripts/run/board/run-board-usage-read.ts +120 -150
  644. package/scripts/run/board/run-board-usage-rusage.ts +19 -7
  645. package/scripts/run/board/run-board-usage-text.ts +139 -51
  646. package/scripts/run/board/run-board-usage-top.ts +102 -0
  647. package/scripts/run/board/run-board-usage.ts +89 -72
  648. package/scripts/run/board/run-board-usual.ts +20 -9
  649. package/scripts/run/carry/run-carry-args.ts +4 -7
  650. package/scripts/run/carry/run-carry-conversation.ts +1 -1
  651. package/scripts/run/carry/run-carry.ts +9 -4
  652. package/scripts/run/cut/run-cut-handoff.ts +2 -2
  653. package/scripts/run/event/run-event-cli.ts +1 -5
  654. package/scripts/run/event/run-event-filed.ts +12 -6
  655. package/scripts/run/event/run-event-follow.ts +2 -3
  656. package/scripts/run/event/run-event-render.ts +6 -10
  657. package/scripts/run/event/run-event-scope.ts +2 -2
  658. package/scripts/run/event/run-event-stream-emit.ts +82 -22
  659. package/scripts/run/event/run-event-stream.ts +34 -8
  660. package/scripts/run/hold/run-hold-adopt.ts +65 -0
  661. package/scripts/run/hold/run-hold-cli.ts +93 -22
  662. package/scripts/run/hold/run-hold-main.ts +12 -0
  663. package/scripts/run/hold/run-hold-member.ts +37 -0
  664. package/scripts/run/hold/run-stop-notify.ts +183 -0
  665. package/scripts/run/merge/run-merge-auth.ts +31 -0
  666. package/scripts/run/merge/run-merge-cli.ts +62 -48
  667. package/scripts/run/merge/run-merge-close.ts +74 -0
  668. package/scripts/run/merge/run-merge-collect.ts +6 -13
  669. package/scripts/run/merge/run-merge-driver.ts +71 -0
  670. package/scripts/run/merge/run-merge-main.ts +12 -0
  671. package/scripts/run/merge/run-merge-outcome.ts +23 -0
  672. package/scripts/run/merge/run-merge-restart.ts +39 -0
  673. package/scripts/run/merge/run-merge-ship.ts +20 -4
  674. package/scripts/run/merge/run-merge-signals.ts +33 -9
  675. package/scripts/run/merge/run-merge-steps.ts +120 -85
  676. package/scripts/run/merge/run-merge.ts +38 -37
  677. package/scripts/run/park/run-park-cli.ts +91 -0
  678. package/scripts/run/park/run-park.ts +88 -0
  679. package/scripts/run/park/run-stalled.ts +68 -0
  680. package/scripts/run/pause/run-pause-cli.ts +73 -0
  681. package/scripts/run/pause/run-pause.ts +251 -0
  682. package/scripts/run/progress/run-progress-cli.ts +4 -12
  683. package/scripts/run/progress/run-progress-clock.ts +1 -1
  684. package/scripts/run/progress/run-progress-config.ts +6 -14
  685. package/scripts/run/progress/run-progress-main.ts +12 -0
  686. package/scripts/run/progress/run-progress.ts +1 -4
  687. package/scripts/run/review/run-review.ts +2 -1
  688. package/scripts/run/run-ending.ts +1 -0
  689. package/scripts/run/run-invocation.ts +5 -6
  690. package/scripts/run/run-liveness-cli.ts +6 -8
  691. package/scripts/run/run-liveness.ts +60 -29
  692. package/scripts/run/run-next.ts +1 -1
  693. package/scripts/run/run-parent-cut-hook.ts +2 -2
  694. package/scripts/run/run-preflight.ts +18 -3
  695. package/scripts/run/run-prep-cli.ts +1 -10
  696. package/scripts/run/run-prep-locate.ts +7 -50
  697. package/scripts/run/run-prep-main.ts +12 -0
  698. package/scripts/run/run-prep.ts +6 -0
  699. package/scripts/run/run-report-cli.ts +101 -13
  700. package/scripts/run/run-report-handoff.ts +114 -0
  701. package/scripts/run/run-step.ts +1 -1
  702. package/scripts/run/run-stranded-detect.ts +13 -0
  703. package/scripts/run/run-watcher-guard-cli.ts +1 -1
  704. package/scripts/run/run-watcher-guard.ts +1 -1
  705. package/scripts/run/ship/run-ship-args.ts +121 -0
  706. package/scripts/run/ship/run-ship-body-draft.ts +110 -0
  707. package/scripts/run/ship/run-ship-cli.ts +63 -140
  708. package/scripts/run/ship/run-ship-detach.ts +19 -8
  709. package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
  710. package/scripts/run/ship/run-ship-next.ts +18 -2
  711. package/scripts/run/ship/run-ship-overlap.ts +42 -5
  712. package/scripts/run/ship/run-ship-place.ts +96 -0
  713. package/scripts/run/ship/run-ship-pre-detach-timed.ts +43 -0
  714. package/scripts/run/ship/run-ship-pre-detach.ts +81 -24
  715. package/scripts/run/ship/run-ship-preflight.ts +137 -32
  716. package/scripts/run/ship/run-ship-probe.ts +11 -3
  717. package/scripts/run/ship/run-ship-relaunch-cap.ts +70 -0
  718. package/scripts/run/ship/run-ship-removed-rows.ts +61 -0
  719. package/scripts/run/ship/run-ship-return.ts +107 -23
  720. package/scripts/run/ship/run-ship-review-steps.ts +105 -151
  721. package/scripts/run/ship/run-ship-review.ts +73 -6
  722. package/scripts/run/ship/run-ship-reviewer.ts +207 -0
  723. package/scripts/run/ship/run-ship-stage.ts +55 -6
  724. package/scripts/run/ship/run-ship-steps.ts +46 -15
  725. package/scripts/run/ship/run-ship-stop-cause.ts +135 -0
  726. package/scripts/run/ship/run-ship-stop-text.ts +11 -6
  727. package/scripts/run/ship/run-ship-sync.ts +43 -6
  728. package/scripts/run/ship/run-ship.ts +30 -2
  729. package/scripts/run/tidy/run-tidy-cli.ts +0 -4
  730. package/scripts/run/tidy/run-tidy-lanes.ts +3 -0
  731. package/scripts/run/tidy/run-tidy-main.ts +8 -0
  732. package/scripts/run/wake/run-wake-cli.ts +119 -100
  733. package/scripts/run/wake/run-wake-code.ts +83 -0
  734. package/scripts/run/wake/run-wake-driver.ts +19 -8
  735. package/scripts/run/wake/run-wake-loop.ts +34 -3
  736. package/scripts/run/wake/run-wake-main.ts +13 -0
  737. package/scripts/run/wake/run-wake-ports.ts +90 -0
  738. package/scripts/run/wake/run-wake-takeover.ts +66 -0
  739. package/scripts/run/wake/run-wake.ts +2 -1
  740. package/scripts/safe-chain/pack-hook.ts +2 -2
  741. package/scripts/safe-chain/preinstall-command.ts +2 -1
  742. package/scripts/safe-chain/project-config.ts +3 -9
  743. package/scripts/security/security-audit-main.ts +8 -0
  744. package/scripts/security/security-audit-provision-logic.ts +0 -11
  745. package/scripts/security/security-audit-provision-main.ts +12 -0
  746. package/scripts/security/security-audit-provision.ts +11 -26
  747. package/scripts/security/security-audit.ts +6 -7
  748. package/scripts/self-sync-guard/self-sync-guard-logic.ts +6 -13
  749. package/scripts/split/split-assess-cli.ts +2 -2
  750. package/scripts/split/split-assess.ts +15 -0
  751. package/scripts/split/split-measure.ts +65 -0
  752. package/scripts/sync/claude-settings-merge.ts +8 -15
  753. package/scripts/sync/directory-copy-guard.ts +4 -9
  754. package/scripts/sync/file-content.ts +78 -8
  755. package/scripts/sync/sync-ai-files.ts +3 -5
  756. package/scripts/sync/sync-configs.ts +11 -23
  757. package/scripts/sync/sync-hook-safety.ts +4 -10
  758. package/scripts/sync/sync-main.ts +11 -0
  759. package/scripts/sync/sync.ts +25 -37
  760. package/scripts/test/test-declared-changed.ts +2 -2
  761. package/scripts/test/test-declared.ts +1 -1
  762. package/scripts/test/test-e2e-guard.ts +25 -1
  763. package/scripts/test/test-e2e-stamp.ts +38 -0
  764. package/scripts/test/test-pinned-logic.ts +145 -0
  765. package/scripts/test/test-pinned-main.ts +78 -0
  766. package/scripts/test/test-pinned.ts +100 -0
  767. package/scripts/test/test-read-map.ts +264 -0
  768. package/scripts/test/test-read-recording.ts +91 -0
  769. package/scripts/test/test-read-trace.ts +148 -0
  770. package/scripts/test/test-red-main.ts +12 -0
  771. package/scripts/test/test-red.ts +12 -30
  772. package/scripts/test/test-related-main.ts +18 -0
  773. package/scripts/test/test-related-record.ts +119 -0
  774. package/scripts/test/test-related-scope.ts +229 -43
  775. package/scripts/test/test-related.ts +300 -22
  776. package/scripts/test/test-unit-guard-main.ts +15 -0
  777. package/scripts/test/test-unit-guard.ts +42 -24
  778. package/scripts/test/unit-count-file.ts +37 -0
  779. package/scripts/test/unit-run-marker.ts +162 -0
  780. package/scripts/test/unit-setup-files.ts +51 -0
  781. package/scripts/test/unit-worker-share.ts +61 -149
  782. package/scripts/test/whole-suite-files.ts +63 -0
  783. package/scripts/time-runtime/time-background.ts +20 -2
  784. package/scripts/time-runtime/time-bundles.ts +4 -3
  785. package/scripts/time-runtime/time-density-hook.ts +8 -6
  786. package/scripts/time-runtime/time-followup-stage.ts +1 -3
  787. package/scripts/time-runtime/time-format.ts +5 -28
  788. package/scripts/time-runtime/time-markers.ts +10 -1
  789. package/scripts/time-runtime/time-shell.ts +97 -10
  790. package/scripts/time-runtime/time-transcript-line.ts +49 -62
  791. package/scripts/uninstall/uninstall.ts +1 -1
  792. package/scripts/version/bump-version-main.ts +12 -0
  793. package/scripts/version/bump-version.ts +25 -25
  794. package/scripts/version/effective-upstream.ts +6 -12
  795. package/scripts/version/latest-corepack.ts +17 -32
  796. package/scripts/version/latest-if-required-cli.ts +93 -0
  797. package/scripts/version/latest-lane-guard-main.ts +8 -0
  798. package/scripts/version/latest-lane-guard.ts +0 -4
  799. package/scripts/version/latest-scope-cli.ts +0 -9
  800. package/scripts/version/latest-scope-main.ts +12 -0
  801. package/scripts/version/latest-update.ts +5 -5
  802. package/scripts/version/npm-registry.ts +44 -6
  803. package/scripts/version/publishable-range-check.ts +5 -16
  804. package/scripts/version/release-age.ts +1 -1
  805. package/scripts/version/release-hold.ts +1 -1
  806. package/scripts/version/release-window.ts +38 -0
  807. package/scripts/version/running-binary.ts +1 -1
  808. package/scripts/version/safe-chain-version-update.ts +3 -8
  809. package/scripts/version/version-targets.ts +6 -28
  810. package/templates/dependabot.yml +29 -0
  811. package/templates/gitignore +4 -1
  812. package/templates/pnpm-workspace.basic.yaml +1 -1
  813. package/templates/sonar-project.properties +3 -2
  814. package/templates/workflows/ci.yml +12 -4
  815. package/templates/workflows/github-release.yml +4 -0
  816. package/tsconfig.sonar.json +1 -1
  817. package/.ncurc.json +0 -3
  818. package/dist/hooks/batch-guard.js +0 -29
  819. package/dist/hooks/chunk-4KKD2UTK.js +0 -66
  820. package/dist/hooks/chunk-6TS2JD6D.js +0 -237
  821. package/dist/hooks/chunk-7DSBJVFH.js +0 -50
  822. package/dist/hooks/chunk-A65Y4YOR.js +0 -79
  823. package/dist/hooks/chunk-CDY4NFQG.js +0 -15
  824. package/dist/hooks/chunk-EFXE6C37.js +0 -81
  825. package/dist/hooks/chunk-GP4IEC4O.js +0 -20
  826. package/dist/hooks/chunk-JP45SOCJ.js +0 -56
  827. package/dist/hooks/chunk-LAOV7NLM.js +0 -45
  828. package/dist/hooks/chunk-M4HGZV7U.js +0 -83
  829. package/dist/hooks/chunk-PF2NZL2A.js +0 -131
  830. package/dist/hooks/chunk-PTICX4OL.js +0 -358
  831. package/dist/hooks/chunk-RT27QRJW.js +0 -6247
  832. package/dist/hooks/chunk-SYOTDYCI.js +0 -3533
  833. package/dist/hooks/chunk-UPUZF3AN.js +0 -279
  834. package/dist/hooks/chunk-WK6SMBIC.js +0 -3180
  835. package/dist/hooks/duplicate-read-guard.js +0 -30
  836. package/dist/hooks/investigation-guard.js +0 -29
  837. package/scripts/backlog/backlog-stalled-cli.ts +0 -30
  838. package/scripts/cost-runtime/cost-format.ts +0 -29
  839. package/scripts/init/basic-path-migration.ts +0 -24
  840. package/scripts/issue/issue-backlinks-cli.ts +0 -93
  841. package/scripts/josh/josh-commands-guard.ts +0 -38
  842. package/scripts/josh/josh-usage-automation.ts +0 -121
  843. package/scripts/josh/josh-usage-backlog.ts +0 -180
  844. package/scripts/josh/josh-usage-developer.ts +0 -230
  845. package/scripts/josh/josh-usage-hooks.ts +0 -38
  846. package/scripts/josh/josh-usage-issue.ts +0 -205
  847. package/scripts/josh/josh-usage-review.ts +0 -101
  848. package/scripts/josh/josh-usage-run.ts +0 -252
  849. package/scripts/josh/josh-usage-session.ts +0 -238
  850. package/scripts/josh/josh-usage-workflow.ts +0 -212
  851. package/scripts/lint/cross-file-recheck.ts +0 -155
  852. package/scripts/registry-migration/migrate-logic.ts +0 -237
  853. package/scripts/registry-migration/migrate.ts +0 -292
  854. package/scripts/registry-migration/user-npmrc.ts +0 -15
  855. package/scripts/rules/rule-guard.ts +0 -23
  856. package/scripts/rules/rule-registry-rows.ts +0 -292
  857. package/scripts/rules/rule-registry.ts +0 -112
  858. package/scripts/run/run-stranded-cli.ts +0 -27
@@ -1,7 +1,8 @@
1
- import { cpSync, lstatSync, readdirSync, readFileSync, writeFileSync } from 'node:fs'
1
+ import { cpSync, lstatSync, readdirSync, readFileSync } from 'node:fs'
2
2
  import path from 'node:path'
3
3
  import { transform_copied_content } from '#scripts/init/init-copy-content'
4
4
  import { error_text } from '#scripts/lib/error-message'
5
+ import { file_reader } from '#scripts/lib/read-file'
5
6
  import { file_content } from './file-content'
6
7
 
7
8
  // `josh init` and `josh sync` both copy a distributed directory with `cpSync`, and both have to
@@ -20,17 +21,11 @@ type DestinationKind = 'absent' | 'directory' | 'other'
20
21
  // says the opposite — something is there and cannot be inspected — and ENOTDIR says a component of
21
22
  // the path is a file, which is also something rather than nothing. Reading either as absent would
22
23
  // send the caller into the `cpSync` that then throws uncaught, the abort this module exists to stop.
23
- const ABSENT_CODE = 'ENOENT'
24
-
25
- function error_code_of(error: unknown): string {
26
- return error instanceof Error && 'code' in error ? String(error.code) : ''
27
- }
28
-
29
24
  function classify_path(candidate_path: string): DestinationKind {
30
25
  try {
31
26
  return lstatSync(candidate_path).isDirectory() ? 'directory' : 'other'
32
27
  } catch (error) {
33
- return error_code_of(error) === ABSENT_CODE ? 'absent' : 'other'
28
+ return file_reader.is_absent(error) ? 'absent' : 'other'
34
29
  }
35
30
  }
36
31
 
@@ -79,7 +74,7 @@ function is_transformable(candidate_path: string): boolean {
79
74
  function transform_copied_file(file_path: string): void {
80
75
  const content = readFileSync(file_path, 'utf8')
81
76
  const transformed = transform_copied_content(file_path, content)
82
- if (transformed !== content) writeFileSync(file_path, transformed)
77
+ if (transformed !== content) file_content.write_contained(file_path, transformed)
83
78
  }
84
79
 
85
80
  // The walk reads the SOURCE listing and rewrites the matching destination paths, never the
@@ -1,9 +1,10 @@
1
- import { lstatSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
1
+ import { lstatSync, mkdirSync, readFileSync, readlinkSync, writeFileSync } from 'node:fs'
2
2
  import path from 'node:path'
3
+ import { PROJECT_ROOT } from '#scripts/init/init-paths'
4
+ import { file_reader } from '#scripts/lib/read-file'
3
5
 
4
- function is_absent_error(error: unknown): boolean {
5
- return error instanceof Error && 'code' in error && error.code === 'ENOENT'
6
- }
6
+ const PATH_SEPARATORS = path.sep === '\\' ? /[/\\]/u : /\//u
7
+ const MAX_RESOLVE_STEPS = 4096
7
8
 
8
9
  function is_read_denied(error: unknown): boolean {
9
10
  return (
@@ -15,7 +16,7 @@ function is_regular_existing_file(destination_path: string): boolean {
15
16
  try {
16
17
  return lstatSync(destination_path).isFile()
17
18
  } catch (error) {
18
- if (is_absent_error(error)) return false
19
+ if (file_reader.is_absent(error)) return false
19
20
  throw error
20
21
  }
21
22
  }
@@ -37,13 +38,82 @@ function is_same_file_content(destination_path: string, content: string | Buffer
37
38
  return does_read_match(destination_path, expected)
38
39
  }
39
40
 
40
- function write_text_if_changed(destination_path: string, content: string): boolean {
41
- if (is_same_file_content(destination_path, content)) return false
41
+ function read_symlink(target: string): string | undefined {
42
+ if (!lstatSync(target, { throwIfNoEntry: false })?.isSymbolicLink()) return undefined
43
+
44
+ return readlinkSync(target)
45
+ }
46
+
47
+ function split_components(target: string): Array<string> {
48
+ return target.split(PATH_SEPARATORS).filter((part) => part !== '' && part !== '.')
49
+ }
50
+
51
+ // One component, as the kernel takes it: `..` steps up from the real directory reached so far, and
52
+ // a link — dangling or not — splices its own text in, from the root when it is absolute.
53
+ function enter_component(current: string, name: string, pending: Array<string>): string {
54
+ if (name === '..') return path.dirname(current)
55
+
56
+ const next = path.join(current, name)
57
+ const link = read_symlink(next)
58
+ if (link === undefined) return next
59
+ const root = path.isAbsolute(link) ? path.parse(link).root : ''
60
+
61
+ pending.unshift(...split_components(link.slice(root.length)))
62
+
63
+ return root === '' ? current : root
64
+ }
65
+
66
+ // Where a write to `target` lands. The path is walked component by component rather than through
67
+ // `path.resolve` or `realpathSync`: the first folds `link/..` lexically while the kernel climbs
68
+ // out of where `link` points, and the second refuses the not-yet-created file a dangling link
69
+ // names. A link cycle the walk would never leave is cut off rather than spun on.
70
+ function resolve_write_path(target: string): string {
71
+ const absolute = path.isAbsolute(target) ? target : `${process.cwd()}${path.sep}${target}`
72
+ let current = path.parse(absolute).root
73
+ const pending = split_components(absolute.slice(current.length))
74
+
75
+ for (let steps = 0; steps <= MAX_RESOLVE_STEPS; steps += 1) {
76
+ const name = pending.shift()
77
+ if (name === undefined) return current
78
+ current = enter_component(current, name, pending)
79
+ }
80
+
81
+ throw new Error(`Refusing to write ${target}: too many links`)
82
+ }
83
+
84
+ function is_within(root: string, target: string): boolean {
85
+ const relative = path.relative(root, target)
86
+
87
+ return relative !== '..' && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative)
88
+ }
89
+
90
+ // Only a path named inside the project is held to it: one the caller names elsewhere (a scratch
91
+ // directory) is that caller's choice, and the link the guard is for sits inside the project.
92
+ function does_escape_project(destination_path: string): boolean {
93
+ if (!is_within(path.resolve(PROJECT_ROOT), path.resolve(destination_path))) return false
94
+
95
+ return !is_within(resolve_write_path(PROJECT_ROOT), resolve_write_path(destination_path))
96
+ }
97
+
98
+ // A symlinked destination is written through, and one pointing outside the project (`~/.zshrc`)
99
+ // would let a sync overwrite a file the project does not own. A link that stays inside —
100
+ // `CLAUDE.md` → `AGENTS.md`, `.agents/skills` — is written through as before. The check runs before
101
+ // the parent directories are created, so a directory link to outside gets none created through it.
102
+ function write_contained(destination_path: string, content: string | Buffer): void {
103
+ if (does_escape_project(destination_path)) {
104
+ throw new Error(`Refusing to write ${destination_path}: it resolves outside the project`)
105
+ }
42
106
 
43
107
  mkdirSync(path.dirname(destination_path), { recursive: true })
44
108
  writeFileSync(destination_path, content)
109
+ }
110
+
111
+ function write_text_if_changed(destination_path: string, content: string): boolean {
112
+ if (is_same_file_content(destination_path, content)) return false
113
+
114
+ write_contained(destination_path, content)
45
115
 
46
116
  return true
47
117
  }
48
118
 
49
- export const file_content = { is_same_file_content, write_text_if_changed }
119
+ export const file_content = { is_same_file_content, write_contained, write_text_if_changed }
@@ -1,4 +1,4 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
1
+ import { existsSync, readFileSync } from 'node:fs'
2
2
  import path from 'node:path'
3
3
  import { init_ai_copy } from '#scripts/init/init-ai-copy'
4
4
  import { transform_copied_content } from '#scripts/init/init-copy-content'
@@ -16,7 +16,6 @@ import { skill_migration, type MigrationResult } from './skill-migration'
16
16
  import { sync_hook_safety } from './sync-hook-safety'
17
17
 
18
18
  const WORKSPACE_YAML = 'pnpm-workspace.yaml'
19
- const PACKAGE_JSON = 'package.json'
20
19
  const CLAUDE_MD_FILENAME = 'CLAUDE.md'
21
20
  const CLAUDE_SETTINGS_FILE = '.claude/settings.json'
22
21
  const CODEX_HOOKS_FILE = '.codex/hooks.json'
@@ -37,7 +36,7 @@ function should_skip_hook_file(filename: string): boolean {
37
36
  if (filename !== CLAUDE_SETTINGS_FILE && filename !== CODEX_HOOKS_FILE) return false
38
37
  const warning = sync_hook_safety.hook_write_warning(
39
38
  PROJECT_ROOT,
40
- sync_hook_safety.read_version_at(path.join(PACKAGE_DIR, PACKAGE_JSON)),
39
+ sync_hook_safety.read_version_at(PACKAGE_DIR),
41
40
  filename,
42
41
  )
43
42
  if (warning === undefined) return false
@@ -191,8 +190,7 @@ function sync_claude_md(destination_path: string, shape?: ProjectShape): void {
191
190
  return
192
191
  }
193
192
 
194
- mkdirSync(path.dirname(destination_path), { recursive: true })
195
- writeFileSync(destination_path, ensured)
193
+ file_content.write_contained(destination_path, ensured)
196
194
  console.info(` ✔ synced ${CLAUDE_MD_FILENAME}`)
197
195
  }
198
196
 
@@ -1,9 +1,10 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
1
+ import { existsSync, readFileSync } from 'node:fs'
2
2
  import path from 'node:path'
3
3
  import { init_logic } from '#scripts/init/init-logic'
4
4
  import { PACKAGE_DIR } from '#scripts/init/init-paths'
5
5
  import { vscode_tasks } from '#scripts/init/vscode-tasks'
6
6
  import { string_array_schema, vscode_settings_schema } from '#scripts/lib/schemas'
7
+ import { file_content } from './file-content'
7
8
 
8
9
  type MergeFunction = (existing: string) => string
9
10
 
@@ -26,7 +27,7 @@ function sync_with_merge(
26
27
  return
27
28
  }
28
29
 
29
- writeFileSync(destination_path, merged)
30
+ file_content.write_contained(destination_path, merged)
30
31
  console.info(` ✔ synced ${destination_name}`)
31
32
  }
32
33
 
@@ -107,7 +108,7 @@ function sync_secretlint_config(destination_path: string): void {
107
108
  return
108
109
  }
109
110
 
110
- writeFileSync(destination_path, init_logic.generate_secretlint_config())
111
+ file_content.write_contained(destination_path, init_logic.generate_secretlint_config())
111
112
  console.info(' ✔ created .secretlintrc.json')
112
113
  }
113
114
 
@@ -143,29 +144,16 @@ function sync_vscode_settings_json(destination_path: string): void {
143
144
  )
144
145
  }
145
146
 
146
- // Creates the file when absent, unlike the other `.vscode` syncs: the folder-open board task is the
147
- // whole point of distributing it, and a consumer
148
- // without a tasks.json has nothing of its own to protect. An existing file keeps every task whose
149
- // label kit does not ship.
147
+ // Like the other `.vscode` syncs, never creates the file: `josh init` does, and a project without it
148
+ // opted out. An existing file keeps every task whose label kit does not ship.
150
149
  function sync_vscode_tasks_json(destination_path: string): void {
151
- const kit_content = readFileSync(
152
- path.join(PACKAGE_DIR, '.vscode', vscode_tasks.VSCODE_TASKS_FILENAME),
153
- 'utf8',
150
+ const kit_tasks = vscode_tasks.read_kit_tasks(
151
+ readFileSync(path.join(PACKAGE_DIR, '.vscode', vscode_tasks.VSCODE_TASKS_FILENAME), 'utf8'),
154
152
  )
155
153
 
156
- if (existsSync(destination_path)) {
157
- const kit_tasks = vscode_tasks.read_kit_tasks(kit_content)
158
-
159
- sync_with_merge(destination_path, '.vscode/tasks.json', (existing) =>
160
- vscode_tasks.merge_tasks(existing, kit_tasks),
161
- )
162
-
163
- return
164
- }
165
-
166
- mkdirSync(path.dirname(destination_path), { recursive: true })
167
- writeFileSync(destination_path, kit_content)
168
- console.info(' ✔ created .vscode/tasks.json')
154
+ sync_with_merge(destination_path, '.vscode/tasks.json', (existing) =>
155
+ vscode_tasks.merge_tasks(existing, kit_tasks),
156
+ )
169
157
  }
170
158
 
171
159
  const sync_configs = {
@@ -1,6 +1,5 @@
1
- import { existsSync, readFileSync } from 'node:fs'
2
1
  import path from 'node:path'
3
- import { json_value } from '#scripts/lib/json-value'
2
+ import { package_manifest } from '#scripts/lib/package-manifest'
4
3
  import { package_version_schema } from '#scripts/lib/schemas'
5
4
  import { KIT_PACKAGE_NAME } from '#scripts/version/kit-descriptor'
6
5
  import semver from 'semver'
@@ -18,20 +17,15 @@ import semver from 'semver'
18
17
 
19
18
  const NODE_MODULES = 'node_modules'
20
19
 
21
- function read_version_at(package_json_path: string): string | undefined {
22
- if (!existsSync(package_json_path)) return undefined
23
- const parsed = package_version_schema.safeParse(
24
- json_value.parse_or_undefined(readFileSync(package_json_path, 'utf8')),
25
- )
26
-
27
- return parsed.success ? parsed.data.version : undefined
20
+ function read_version_at(package_directory: string): string | undefined {
21
+ return package_manifest.read_manifest_if_valid(package_directory, package_version_schema)?.version
28
22
  }
29
23
 
30
24
  // The version of kit installed in the consumer's node_modules — the bundle the rewritten hooks
31
25
  // actually run. Undefined before the first install, which is safe: a fresh install receives the
32
26
  // matching bundle, so there is nothing older to break.
33
27
  function installed_consumer_version(project_root: string): string | undefined {
34
- return read_version_at(path.join(project_root, NODE_MODULES, KIT_PACKAGE_NAME, 'package.json'))
28
+ return read_version_at(path.join(project_root, NODE_MODULES, KIT_PACKAGE_NAME))
35
29
  }
36
30
 
37
31
  // Unsafe only when both versions are known AND the installed bundle the hooks run is older than the
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env tsx
2
+ import { fileURLToPath } from 'node:url'
3
+ import { main } from './sync'
4
+
5
+ // The `josh sync` entry, kept apart from `sync.ts` because `init.ts` imports that one: a bundle is one
6
+ // file, so a main guard there would fire for every command that carries it (joshuafolkken/kit#4186).
7
+ if (process.argv[1] === fileURLToPath(import.meta.url)) {
8
+ const ARGV_OFFSET = 2
9
+
10
+ main(process.argv.slice(ARGV_OFFSET))
11
+ }
@@ -1,13 +1,12 @@
1
- #!/usr/bin/env tsx
2
- import { existsSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
1
+ import { existsSync, readFileSync, rmSync } from 'node:fs'
3
2
  import path from 'node:path'
4
- import { fileURLToPath } from 'node:url'
3
+ import { dependabot_cooldown } from '#scripts/dependabot/dependabot-cooldown'
5
4
  import { project_checks } from '#scripts/gate/project-checks'
6
5
  import { gh_spawn } from '#scripts/gh/gh-spawn'
7
- import { basic_path_migration } from '#scripts/init/basic-path-migration'
8
6
  import { init_logic } from '#scripts/init/init-logic'
9
7
  import { PACKAGE_DIR, PROJECT_ROOT } from '#scripts/init/init-paths'
10
8
  import { project_profile } from '#scripts/init/project-profile'
9
+ import { PACKAGE_JSON } from '#scripts/lib/package-manifest'
11
10
  import { auto_merge_setting } from '#scripts/repo/auto-merge-setting'
12
11
  import { repository_labels } from '#scripts/repo/repository-labels'
13
12
  import { project_config } from '#scripts/safe-chain/project-config'
@@ -19,9 +18,7 @@ import { file_content } from './file-content'
19
18
  import { sync_ai_files } from './sync-ai-files'
20
19
  import { sync_configs } from './sync-configs'
21
20
 
22
- const PACKAGE_JSON = 'package.json'
23
- const PACKAGE_JSON_UNCHANGED_MSG = ' ✔ unchanged package.json'
24
- const BASIC_PRETTIER_CONFIG = 'prettier.config.mjs'
21
+ const PACKAGE_JSON_UNCHANGED_MSG = ` ✔ unchanged ${PACKAGE_JSON}`
25
22
 
26
23
  function did_migrate_prettierrc(destination_path: string): boolean {
27
24
  const legacy_path = path.join(path.dirname(destination_path), '.prettierrc')
@@ -29,7 +26,7 @@ function did_migrate_prettierrc(destination_path: string): boolean {
29
26
 
30
27
  const existing = readFileSync(legacy_path, 'utf8')
31
28
 
32
- writeFileSync(
29
+ file_content.write_contained(
33
30
  destination_path,
34
31
  init_logic.merge_prettier_config(existing, path.dirname(destination_path)),
35
32
  )
@@ -48,7 +45,7 @@ function write_merged_prettier_config(destination_path: string): void {
48
45
  return
49
46
  }
50
47
 
51
- writeFileSync(destination_path, merged)
48
+ file_content.write_contained(destination_path, merged)
52
49
  console.info(' ✔ synced prettier.config.js')
53
50
  }
54
51
 
@@ -64,20 +61,6 @@ function sync_prettier_config(destination_path: string): void {
64
61
  write_merged_prettier_config(destination_path)
65
62
  }
66
63
 
67
- // A basic project's prettier config written under the static profile name still imports the static
68
- // preset path; it is moved onto the basic one with the rule `josh init` applies.
69
- function sync_basic_prettier_config(destination_path: string): void {
70
- if (!existsSync(destination_path)) return
71
-
72
- const existing = readFileSync(destination_path, 'utf8')
73
- const did_change = file_content.write_text_if_changed(
74
- destination_path,
75
- basic_path_migration.migrate_basic_paths(existing),
76
- )
77
-
78
- console.info(` ✔ ${did_change ? 'synced ' : 'unchanged'} ${BASIC_PRETTIER_CONFIG}`)
79
- }
80
-
81
64
  function sync_playwright_config(destination_path: string): void {
82
65
  if (!existsSync(destination_path)) return
83
66
 
@@ -90,7 +73,7 @@ function sync_playwright_config(destination_path: string): void {
90
73
  return
91
74
  }
92
75
 
93
- writeFileSync(destination_path, template)
76
+ file_content.write_contained(destination_path, template)
94
77
  console.info(' ✔ synced playwright.config.ts')
95
78
  }
96
79
 
@@ -106,7 +89,7 @@ function sync_deploy_vps(destination_path: string): void {
106
89
  return
107
90
  }
108
91
 
109
- writeFileSync(destination_path, patched)
92
+ file_content.write_contained(destination_path, patched)
110
93
  console.info(' ✔ synced deploy-vps.yml')
111
94
  }
112
95
 
@@ -156,7 +139,7 @@ function sync_package_json_with(
156
139
  return
157
140
  }
158
141
 
159
- writeFileSync(destination_path, transformed)
142
+ file_content.write_contained(destination_path, transformed)
160
143
  console.info(synced_message)
161
144
  }
162
145
 
@@ -255,6 +238,13 @@ function report_repository_settings(name_with_owner: string | undefined): void {
255
238
  repository_labels.ensure_labels(name_with_owner)
256
239
  }
257
240
 
241
+ // Every file that restates the workspace's `minimumReleaseAge`: Safe Chain's `.aikido` and
242
+ // Dependabot's `cooldown`.
243
+ function sync_release_window_mirrors(root: string): void {
244
+ project_config.sync_project_config(root)
245
+ dependabot_cooldown.sync_dependabot_cooldown(root)
246
+ }
247
+
258
248
  function sync_project_artifacts(is_force: boolean): void {
259
249
  sync_ai_files.sync_ai_copy_all(is_force)
260
250
  sync_prettier_config(path.join(PROJECT_ROOT, 'prettier.config.js'))
@@ -267,20 +257,19 @@ function sync_project_artifacts(is_force: boolean): void {
267
257
 
268
258
  sync_sonar_with_template(name_with_owner, is_force)
269
259
  sync_config_files()
270
- // After `sync_ai_copy_all`, which may add the `pnpm-workspace.yaml` window `.aikido`'s age is
271
- // derived from.
272
- project_config.sync_project_config(PROJECT_ROOT)
260
+ // After `sync_ai_copy_all`, which may add the `pnpm-workspace.yaml` window both mirrors are derived
261
+ // from, and which rewrites `.github/dependabot.yml` itself.
262
+ sync_release_window_mirrors(PROJECT_ROOT)
273
263
  sync_package_json_migrations(path.join(PROJECT_ROOT, PACKAGE_JSON))
274
264
  report_repository_settings(name_with_owner)
275
265
  }
276
266
 
277
- // A basic project gets what `josh init` gives that profile and nothing more: its AI file set and the
278
- // move of its prettier preset path. The full toolchain's configs, Sonar, package.json migrations and
279
- // repository settings are never written into it.
267
+ // A basic project gets what `josh init` gives that profile and nothing more: its AI file set. The full
268
+ // toolchain's configs, Sonar, package.json migrations and repository settings are never written into
269
+ // it.
280
270
  function sync_basic_artifacts(is_force: boolean): void {
281
271
  console.info('profile: basic (package.json josh.profile)\n')
282
272
  sync_ai_files.sync_ai_copy_all(is_force, project_profile.inspect_project(PROJECT_ROOT, 'basic'))
283
- sync_basic_prettier_config(path.join(PROJECT_ROOT, BASIC_PRETTIER_CONFIG))
284
273
  }
285
274
 
286
275
  // Checked before anything is written, never per file: the damage is the whole run, and a partial
@@ -289,10 +278,10 @@ function sync_basic_artifacts(is_force: boolean): void {
289
278
  //
290
279
  // Only a recorded basic profile switches the file set; an unrecorded one stays full, as every
291
280
  // project initialized before the profile was recorded was set up.
292
- function main(): void {
281
+ function main(args: ReadonlyArray<string> = []): void {
293
282
  if (did_refuse_self_run(PACKAGE_DIR, PROJECT_ROOT)) return
294
283
 
295
- const is_force = process.argv.includes('--force')
284
+ const is_force = args.includes('--force')
296
285
 
297
286
  console.info('\n🔄 Syncing @joshuafolkken/kit AI files\n')
298
287
  if (project_checks.is_basic(PROJECT_ROOT)) sync_basic_artifacts(is_force)
@@ -300,8 +289,6 @@ function main(): void {
300
289
  console.info('\n✅ Done.\n')
301
290
  }
302
291
 
303
- if (process.argv[1] === fileURLToPath(import.meta.url)) main()
304
-
305
292
  const sync = {
306
293
  should_skip_hook_file: sync_ai_files.should_skip_hook_file,
307
294
  sync_file_mapping: sync_ai_files.sync_file_mapping,
@@ -318,6 +305,7 @@ const sync = {
318
305
  sync_prepare_lefthook_warning,
319
306
  sync_safe_chain_preinstall,
320
307
  sync_package_json_migrations,
308
+ sync_release_window_mirrors,
321
309
  migrate_prettierrc: did_migrate_prettierrc,
322
310
  }
323
311
 
@@ -75,8 +75,8 @@ function restore_injection(previous: ReadonlyArray<string> | undefined): void {
75
75
  injected.paths = previous
76
76
  }
77
77
 
78
- // The seam the `rule_delivery` call path needs. `is_untested_commit` reads the
79
- // tree at trigger time rather than from an argument, so a unit test driving `rule_delivery` cannot reach
78
+ // The seam the `delivered_rules.delivery` call path needs. `is_untested_commit` reads the
79
+ // tree at trigger time rather than from an argument, so a unit test driving `delivered_rules.delivery` cannot reach
80
80
  // `current_verdict`'s `paths` port from the outside. Running `body` inside `with_paths` fixes the read
81
81
  // to `paths` for its duration and restores it afterwards — the `PreToolUse` production path, which never
82
82
  // calls this, still reads the live tree.
@@ -27,7 +27,7 @@ const ARGV_OFFSET = 2
27
27
  const NO_DECLARATIONS =
28
28
  'no Test: declarations parsed from stdin — pipe the Step 0 work summary in, e.g. `pnpm josh test:declared --match < summary.md`'
29
29
 
30
- // **An unknown flag is a refusal, not a default** — `scripts/time/time-cli.ts` states the same
30
+ // **An unknown flag is a refusal, not a default** — `tools/time/time-cli.ts` states the same
31
31
  // convention. Ignoring `--foo` and re-printing the verdict is what sent a
32
32
  // reader off to read the source by hand, so a misspelled or retired flag stops here with the usage.
33
33
  const PARSE_ARGS_OPTIONS = {
@@ -4,7 +4,9 @@ import path from 'node:path'
4
4
  import { fileURLToPath } from 'node:url'
5
5
  import { environment_flags } from '@joshuafolkken/kit/env'
6
6
  import { core_budget } from '#scripts/gate/core-budget'
7
+ import { gate_tree } from '#scripts/gate/gate-tree'
7
8
  import { execa } from 'execa'
9
+ import { test_e2e_stamp } from './test-e2e-stamp'
8
10
 
9
11
  const PNPM = 'pnpm'
10
12
  // `--workers`, `--workers=<n>` and Playwright's `-j` short form.
@@ -93,9 +95,30 @@ async function run_guarded_e2e(
93
95
  return 0
94
96
  }
95
97
 
98
+ // A filter (`--grep`, a file, `--project`) answers for part of the suite, so only a run whose every
99
+ // argument is a worker count answers for the whole of it.
100
+ function is_whole_suite(extra_arguments: ReadonlyArray<string>): boolean {
101
+ return extra_arguments.every((argument) => WORKER_FLAGS.test(argument))
102
+ }
103
+
104
+ // A green answer — a pass or a printed skip — is recorded against the tree it ran on, which is what a
105
+ // stop before commit asks (`test-e2e-stamp.ts`). The tree is read before the run, so an edit made while
106
+ // the suite ran leaves a record that matches nothing.
107
+ async function run_and_record(
108
+ project_directory: string,
109
+ extra_arguments: ReadonlyArray<string>,
110
+ ): Promise<number> {
111
+ const tree = await gate_tree.read_gate_tree()
112
+ const exit_code = await run_guarded_e2e(project_directory, extra_arguments)
113
+
114
+ if (exit_code === 0 && is_whole_suite(extra_arguments)) test_e2e_stamp.record(tree)
115
+
116
+ return exit_code
117
+ }
118
+
96
119
  if (process.argv[1] === fileURLToPath(import.meta.url)) {
97
120
  const extra_arguments = process.argv.slice(ARGV_START)
98
- const exit_code = await run_guarded_e2e(process.cwd(), extra_arguments)
121
+ const exit_code = await run_and_record(process.cwd(), extra_arguments)
99
122
 
100
123
  process.exit(exit_code)
101
124
  }
@@ -104,6 +127,7 @@ const test_e2e_guard = {
104
127
  resolve_guard_action,
105
128
  is_playwright_installed,
106
129
  has_e2e_tests,
130
+ is_whole_suite,
107
131
  run_guarded_e2e,
108
132
  }
109
133
 
@@ -0,0 +1,38 @@
1
+ import { gate_tree, type GateTree } from '#scripts/gate/gate-tree'
2
+ import { review_brief } from '#scripts/review/review-brief'
3
+ import { review_stamps } from '#scripts/review/review-stamps'
4
+
5
+ // The record that `josh test:e2e` answered green on this exact tree (joshuafolkken/kit#4156). A stop
6
+ // before commit — `halfrun`'s, `needs-human-review`'s — has no CI E2E job behind it, so the stop asks
7
+ // this record instead of trusting that the run remembered to run the suite.
8
+ //
9
+ // **A printed skip is recorded too**: a project with no suite, or without `@playwright/test`, has
10
+ // answered the question, and refusing its stop would make the record a requirement no such project
11
+ // could meet. **Any edit after the run moves the tree**, so the record no longer matches — the same
12
+ // reading the gate's own record takes (`gate-skip.ts`).
13
+
14
+ // Swallowed: a record not written is the safe answer — the stop refuses and the run re-runs the suite.
15
+ function record(tree: GateTree, target?: string): void {
16
+ try {
17
+ review_stamps.e2e_stamp.write(tree.files, target, tree.base)
18
+ } catch {
19
+ /* no record — the stop asks for the suite again */
20
+ }
21
+ }
22
+
23
+ // An unread base or an unreadable record answers no: nothing established, nothing concluded.
24
+ function is_current(tree: GateTree, source?: string): boolean {
25
+ if (tree.base === undefined) return false
26
+
27
+ const stamp = review_brief.matching_stamp(review_stamps.e2e_stamp.read(source), tree.files)
28
+
29
+ return stamp?.base === tree.base
30
+ }
31
+
32
+ async function is_current_tree(): Promise<boolean> {
33
+ return is_current(await gate_tree.read_gate_tree())
34
+ }
35
+
36
+ const test_e2e_stamp = { is_current, is_current_tree, record }
37
+
38
+ export { test_e2e_stamp }