@joshuafolkken/kit 1.1471.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 (895) hide show
  1. package/.claude/agents/investigator.md +1 -1
  2. package/.claude/settings.json +6 -6
  3. package/.claude/skills/epic-commands/SKILL.md +26 -77
  4. package/.claude/skills/epic-commands/epic-bundle.md +12 -6
  5. package/.claude/skills/epic-commands/execution-waves.md +1 -2
  6. package/.claude/skills/verify-ui/SKILL.md +1 -2
  7. package/.claude/skills/workflow-commands/SKILL.md +12 -14
  8. package/.claude/skills/workflow-commands/background-commands.md +8 -12
  9. package/.claude/skills/workflow-commands/backlogrun-child.md +13 -18
  10. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
  11. package/.claude/skills/workflow-commands/backlogrun-lanes.md +23 -28
  12. package/.claude/skills/workflow-commands/backlogrun-park.md +16 -31
  13. package/.claude/skills/workflow-commands/backlogrun-progress.md +12 -21
  14. package/.claude/skills/workflow-commands/backlogrun-recovery.md +12 -12
  15. package/.claude/skills/workflow-commands/backlogrun-steps.md +12 -20
  16. package/.claude/skills/workflow-commands/backlogrun.md +32 -51
  17. package/.claude/skills/workflow-commands/chain-rule.md +18 -11
  18. package/.claude/skills/workflow-commands/delegation.md +13 -8
  19. package/.claude/skills/workflow-commands/entry-sequence.md +10 -12
  20. package/.claude/skills/workflow-commands/followup.md +10 -35
  21. package/.claude/skills/workflow-commands/fullrun-steps.md +38 -49
  22. package/.claude/skills/workflow-commands/fullrun.md +6 -8
  23. package/.claude/skills/workflow-commands/halfrun.md +20 -32
  24. package/.claude/skills/workflow-commands/into-target.md +1 -2
  25. package/.claude/skills/workflow-commands/issue-comments.md +19 -15
  26. package/.claude/skills/workflow-commands/issue-scout.md +5 -4
  27. package/.claude/skills/workflow-commands/kickoff.md +24 -23
  28. package/.claude/skills/workflow-commands/latest-gate.md +9 -18
  29. package/.claude/skills/workflow-commands/needs-human-review.md +11 -19
  30. package/.claude/skills/workflow-commands/observation-filing.md +4 -50
  31. package/.claude/skills/workflow-commands/observation-ledger.md +5 -10
  32. package/.claude/skills/workflow-commands/pre-gate-cut.md +22 -44
  33. package/.claude/skills/workflow-commands/prerequisite.md +11 -18
  34. package/.claude/skills/workflow-commands/progress-watcher.md +3 -8
  35. package/.claude/skills/workflow-commands/prrun.md +6 -12
  36. package/.claude/skills/workflow-commands/retrospective.md +5 -5
  37. package/.claude/skills/workflow-commands/split-assessment.md +14 -4
  38. package/.claude/skills/workflow-commands/target-repository.md +1 -2
  39. package/.claude/skills/workflow-commands/working-tree-hold.md +11 -13
  40. package/.codex/hooks.json +6 -6
  41. package/.github/actions/setup-node/action.yml +10 -1
  42. package/.github/actions/setup-pnpm/action.yml +1 -1
  43. package/.github/dependabot.yml +16 -0
  44. package/.github/release.yml +0 -2
  45. package/.github/workflows/ci.yml +121 -11
  46. package/.github/workflows/publish.yml +10 -3
  47. package/.github/workflows/sonar-qube.yml +1 -0
  48. package/.prettierignore +2 -0
  49. package/.vscode/tasks.json +1 -2
  50. package/CLAUDE.md +4 -8
  51. package/README.md +4 -2
  52. package/SECURITY.md +1 -1
  53. package/cspell/index.yaml +7 -0
  54. package/dist/CLAUDE.md +4 -8
  55. package/dist/commands/document-read-cli.js +882 -0
  56. package/dist/commands/{document-section-cli.js → document-section-main.js} +137 -62
  57. package/dist/commands/read-set-cli.js +1867 -0
  58. package/dist/commands/run-prep-main.js +21653 -0
  59. package/dist/commands/run-step-cli.js +23880 -0
  60. package/dist/config-merge/index.js +5 -1
  61. package/dist/hooks/audit-provision.js +20 -35
  62. package/dist/hooks/{chunk-DGT54IH5.js → chunk-AZX4FGQ3.js} +63 -17
  63. package/dist/hooks/chunk-CWMBGKYW.js +6483 -0
  64. package/dist/hooks/chunk-O2YBIDSI.js +4306 -0
  65. package/dist/hooks/{chunk-AS74OU3D.js → chunk-PT5R6UJD.js} +4582 -2118
  66. package/dist/hooks/chunk-TUIFS5E7.js +72 -0
  67. package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
  68. package/dist/hooks/{chunk-E7OIKX5Z.js → chunk-WR2KQAYZ.js} +1863 -382
  69. package/dist/hooks/{chunk-KC5AK2GF.js → chunk-XGBNSWEI.js} +248 -46
  70. package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
  71. package/dist/hooks/codex-hook-adapter.js +10 -19
  72. package/dist/hooks/format-edited.js +5 -5
  73. package/dist/hooks/inputs.json +436 -257
  74. package/dist/hooks/pretool-guard.js +7 -22
  75. package/dist/hooks/session-lang.js +380 -42
  76. package/dist/hooks/stop-guard.js +8711 -782
  77. package/dist/josh.js +5263 -997
  78. package/dist/self-sync-guard/index.js +74 -10
  79. package/dist/version/index.js +115 -406
  80. package/eslint/base.js +1 -1
  81. package/lefthook/base.yml +8 -4
  82. package/package.json +17 -53
  83. package/pnpm-workspace.yaml +4 -2
  84. package/prompts/coding-standards.md +1 -1
  85. package/prompts/collaboration-workflow/file-edits.md +1 -9
  86. package/prompts/collaboration-workflow/gh-rest.md +1 -2
  87. package/prompts/collaboration-workflow/issue-citation.md +2 -4
  88. package/prompts/collaboration-workflow/issue-template.md +42 -17
  89. package/prompts/collaboration-workflow/lane-instructions.md +34 -0
  90. package/prompts/collaboration-workflow/measurement.md +37 -0
  91. package/prompts/collaboration-workflow/operating-rules.md +6 -12
  92. package/prompts/collaboration-workflow/output-bounds.md +4 -9
  93. package/prompts/collaboration-workflow/overview.md +1 -1
  94. package/prompts/collaboration-workflow/plan-comment.md +3 -42
  95. package/prompts/collaboration-workflow/principles.md +19 -8
  96. package/prompts/collaboration-workflow/report-format.md +37 -57
  97. package/prompts/collaboration-workflow/residency.md +12 -8
  98. package/prompts/collaboration-workflow/rule-delivery.md +3 -11
  99. package/prompts/collaboration-workflow/shell-body.md +8 -18
  100. package/prompts/collaboration-workflow/turn-batching.md +4 -6
  101. package/prompts/collaboration-workflow/upstream-interrupt.md +16 -6
  102. package/prompts/collaboration-workflow/wip-cap.md +7 -7
  103. package/prompts/collaboration-workflow.md +4 -7
  104. package/prompts/refactoring.md +1 -1
  105. package/prompts/review-rubric.md +1 -2
  106. package/prompts/review.md +45 -26
  107. package/prompts/testing-guide.md +10 -45
  108. package/scripts/agent/agent-argv.ts +20 -4
  109. package/scripts/agent/agent-event.ts +15 -15
  110. package/scripts/agent/agent-exit-record.ts +13 -1
  111. package/scripts/agent/agent-role-profile.ts +101 -45
  112. package/scripts/agent/agent-safe-text.ts +60 -0
  113. package/scripts/agent/api-auth.ts +41 -0
  114. package/scripts/agent/api-outage.ts +1 -1
  115. package/scripts/agent/claude-agent-argv.ts +14 -0
  116. package/scripts/agent/codex-agent-argv.ts +2 -0
  117. package/scripts/agent/lane-instructions.ts +144 -0
  118. package/scripts/auto-ok/auto-ok-cli.ts +14 -16
  119. package/scripts/auto-ok/auto-ok-judge-read.ts +12 -3
  120. package/scripts/auto-ok/auto-ok-judge-write.ts +46 -19
  121. package/scripts/auto-ok/auto-ok-judge.ts +13 -2
  122. package/scripts/auto-ok/auto-ok-main.ts +17 -0
  123. package/scripts/backlog/backlog-arrival.ts +14 -3
  124. package/scripts/backlog/backlog-budget-cli.ts +7 -33
  125. package/scripts/backlog/backlog-budget-main.ts +16 -0
  126. package/scripts/backlog/backlog-budget.ts +6 -7
  127. package/scripts/backlog/backlog-defect-priority.ts +4 -3
  128. package/scripts/backlog/backlog-drive-adopt.ts +67 -0
  129. package/scripts/backlog/backlog-drive-args.ts +4 -5
  130. package/scripts/backlog/backlog-drive-cli.ts +113 -28
  131. package/scripts/backlog/backlog-drive-hold.ts +162 -0
  132. package/scripts/backlog/backlog-drive-idle.ts +151 -0
  133. package/scripts/backlog/backlog-drive-judge.ts +25 -0
  134. package/scripts/backlog/backlog-drive-memory.ts +126 -0
  135. package/scripts/backlog/backlog-drive-named-offer.ts +5 -10
  136. package/scripts/backlog/backlog-drive-named.ts +54 -7
  137. package/scripts/backlog/backlog-drive-offer-argv.ts +3 -8
  138. package/scripts/backlog/backlog-drive-paused.ts +169 -0
  139. package/scripts/backlog/backlog-drive-restore.ts +39 -8
  140. package/scripts/backlog/backlog-drive-seats.ts +18 -8
  141. package/scripts/backlog/backlog-drive-token-handling.ts +38 -0
  142. package/scripts/backlog/backlog-drive.ts +79 -75
  143. package/scripts/backlog/backlog-next-main.ts +16 -0
  144. package/scripts/backlog/backlog-next-shared.ts +73 -0
  145. package/scripts/backlog/backlog-next.ts +48 -16
  146. package/scripts/backlog/backlog-occupied.ts +69 -0
  147. package/scripts/backlog/backlog-offer-cli.ts +6 -21
  148. package/scripts/backlog/backlog-offer-exclude.ts +15 -0
  149. package/scripts/backlog/backlog-offer-main.ts +12 -0
  150. package/scripts/backlog/backlog-offer.ts +36 -3
  151. package/scripts/backlog/backlog-overlap.ts +22 -4
  152. package/scripts/backlog/backlog-plan-read.ts +6 -2
  153. package/scripts/backlog/backlog-plan.ts +18 -4
  154. package/scripts/backlog/backlog-pool.ts +10 -10
  155. package/scripts/backlog/backlog-rank.ts +10 -2
  156. package/scripts/backlog/backlog-ready.ts +137 -18
  157. package/scripts/backlog/backlog-stalled-detect.ts +109 -36
  158. package/scripts/backlog/backlog-stalled.ts +52 -16
  159. package/scripts/backlog/backlog-wait-cause.ts +86 -0
  160. package/scripts/backlog/backlog-waves.ts +39 -13
  161. package/scripts/backlog/backlogrun-args.ts +19 -7
  162. package/scripts/backlog/backlogrun-cli.ts +19 -5
  163. package/scripts/backlog/backlogrun-launch.ts +6 -0
  164. package/scripts/backlog/backlogrun-restart.ts +97 -0
  165. package/scripts/backlog/backlogrun-stop.ts +79 -7
  166. package/scripts/behavior/behavior-cli.ts +2 -2
  167. package/scripts/behavior/behavior-rules.ts +47 -24
  168. package/scripts/build/build-bin.ts +2 -16
  169. package/scripts/build/build-claude-md.ts +0 -7
  170. package/scripts/build/build-commands.ts +0 -13
  171. package/scripts/build/build-hooks.ts +49 -48
  172. package/scripts/build/hook-bundle-stamp.ts +29 -11
  173. package/scripts/build/local-bin.ts +1 -1
  174. package/scripts/cases/cases-cli.ts +25 -13
  175. package/scripts/cases/cases-interaction-scan.ts +134 -0
  176. package/scripts/cases/cases-interaction.ts +183 -0
  177. package/scripts/cases/cases-logic.ts +39 -6
  178. package/scripts/ci/pr-classification-main.ts +18 -0
  179. package/scripts/ci/pr-classification.ts +10 -17
  180. package/scripts/clone/clone-scan.ts +1 -1
  181. package/scripts/cost-runtime/cost-blocks.ts +22 -37
  182. package/scripts/cost-runtime/cost-cli.ts +31 -14
  183. package/scripts/cost-runtime/cost-main.ts +12 -0
  184. package/scripts/cost-runtime/cost-transcript.ts +1 -0
  185. package/scripts/delegation/delegation-policy.ts +17 -4
  186. package/scripts/delegation/duplicate-read-guard.ts +2 -10
  187. package/scripts/delegation/investigation-guard.ts +15 -73
  188. package/scripts/delegation/investigation-reads.ts +3 -5
  189. package/scripts/dependabot/dependabot-cooldown.ts +194 -0
  190. package/scripts/discovery/repo-discovery.ts +24 -6
  191. package/scripts/doctor/doctor-consumer.ts +2 -5
  192. package/scripts/document/document-byte-budget.ts +9 -6
  193. package/scripts/document/document-scan.ts +1 -1
  194. package/scripts/document/document-section-cli.ts +17 -13
  195. package/scripts/document/document-section-main.ts +12 -0
  196. package/scripts/document/entry-read-budget.ts +2 -2
  197. package/scripts/document/read-set-cli.ts +4 -1
  198. package/scripts/epic/epic-audit-cli.ts +12 -6
  199. package/scripts/epic/epic-audit-orphans.ts +5 -8
  200. package/scripts/epic/epic-audit.ts +52 -1
  201. package/scripts/epic/epic-bundle-apply.ts +137 -0
  202. package/scripts/epic/epic-bundle-cli.ts +32 -121
  203. package/scripts/epic/epic-bundle-evidence.ts +49 -26
  204. package/scripts/epic/epic-bundle-format.ts +116 -0
  205. package/scripts/epic/epic-bundle-main.ts +17 -0
  206. package/scripts/epic/epic-bundle-referenced.ts +14 -3
  207. package/scripts/epic/epic-bundle.ts +17 -9
  208. package/scripts/epic/epic-busy.ts +5 -12
  209. package/scripts/epic/epic-classify.ts +24 -15
  210. package/scripts/epic/epic-cli-argv.ts +31 -0
  211. package/scripts/epic/epic-cli-decide.ts +42 -0
  212. package/scripts/epic/epic-cli.ts +6 -38
  213. package/scripts/epic/epic-close.ts +112 -55
  214. package/scripts/epic/epic-cross-repo.ts +4 -7
  215. package/scripts/epic/epic-decide.ts +119 -0
  216. package/scripts/epic/epic-decision.ts +9 -0
  217. package/scripts/epic/epic-fetch.ts +4 -0
  218. package/scripts/epic/epic-graph.ts +2 -0
  219. package/scripts/epic/epic-issue.ts +5 -1
  220. package/scripts/epic/epic-label-age.ts +1 -1
  221. package/scripts/epic/epic-lane-offer.ts +39 -4
  222. package/scripts/epic/epic-next-main.ts +24 -0
  223. package/scripts/epic/epic-next.ts +6 -24
  224. package/scripts/epic/epic-outside-blocker.ts +6 -2
  225. package/scripts/epic/epic-parse.ts +9 -3
  226. package/scripts/epic/epic-read.ts +1 -0
  227. package/scripts/epic/epic-reconcile.ts +39 -0
  228. package/scripts/epic/epic-run.ts +10 -1
  229. package/scripts/epic/epic-solo.ts +50 -14
  230. package/scripts/epic/epic.ts +41 -7
  231. package/scripts/exports/unused-members-cli.ts +2 -2
  232. package/scripts/followup/followup-checks-event.ts +8 -3
  233. package/scripts/followup/followup-coderabbit-wait.ts +82 -0
  234. package/scripts/followup/followup-review-gates.ts +81 -0
  235. package/scripts/followup/git-followup-stages.ts +13 -3
  236. package/scripts/followup/git-followup-workflow.ts +31 -60
  237. package/scripts/followup/git-pr-followup-wrapup.ts +9 -14
  238. package/scripts/followup/git-pr-followup.ts +36 -8
  239. package/scripts/fresh-machine/fresh-machine-cli.ts +1 -1
  240. package/scripts/fresh-machine/fresh-machine-run.ts +8 -8
  241. package/scripts/fresh-machine/specs/kit-test-backlogrun.json +1 -1
  242. package/scripts/gate/busy-average.ts +58 -0
  243. package/scripts/gate/check-cpu.ts +60 -0
  244. package/scripts/gate/check-inputs.ts +73 -0
  245. package/scripts/gate/check-reuse.ts +141 -0
  246. package/scripts/gate/command-memory.ts +192 -0
  247. package/scripts/gate/core-admission.ts +218 -28
  248. package/scripts/gate/core-budget-timing.ts +37 -0
  249. package/scripts/gate/core-budget.ts +150 -119
  250. package/scripts/gate/core-wait-record.ts +48 -0
  251. package/scripts/gate/core-wait.ts +162 -0
  252. package/scripts/gate/core-weights.ts +86 -0
  253. package/scripts/gate/free-cores.ts +72 -0
  254. package/scripts/gate/gate-ledger.ts +49 -7
  255. package/scripts/gate/gate-plan.ts +44 -15
  256. package/scripts/gate/gate-report.ts +29 -4
  257. package/scripts/gate/gate-run-steps.ts +195 -0
  258. package/scripts/gate/gate-skip.ts +12 -2
  259. package/scripts/gate/gate-steps.ts +12 -1
  260. package/scripts/gate/held-mark.ts +55 -0
  261. package/scripts/gate/input-fingerprint.ts +42 -0
  262. package/scripts/gate/machine-capacity.ts +124 -31
  263. package/scripts/gate/moved-paths.ts +67 -0
  264. package/scripts/gate/pre-commit-type-check.ts +14 -1
  265. package/scripts/gate/project-checks.ts +5 -12
  266. package/scripts/gate/scoped-green.ts +12 -8
  267. package/scripts/gate/since-green.ts +62 -0
  268. package/scripts/gate/toolchain-inputs.ts +115 -0
  269. package/scripts/gate/verification-gate.ts +65 -129
  270. package/scripts/gate/verification-inputs.ts +250 -0
  271. package/scripts/gh/gh-author-association.ts +96 -9
  272. package/scripts/gh/git-ai-review-scan.ts +4 -2
  273. package/scripts/gh/git-gh-api-path.ts +15 -0
  274. package/scripts/gh/git-gh-branch-rules.ts +73 -0
  275. package/scripts/gh/git-gh-conditional.ts +5 -2
  276. package/scripts/gh/git-gh-issue-read.ts +5 -1
  277. package/scripts/gh/git-gh-issue-rest.ts +1 -0
  278. package/scripts/gh/git-gh-issue-write.ts +77 -17
  279. package/scripts/gh/git-gh-issue.ts +7 -3
  280. package/scripts/gh/git-gh-poll-read.ts +89 -0
  281. package/scripts/gh/git-gh-pr-auto-merge.ts +8 -3
  282. package/scripts/gh/git-gh-pr-rest.ts +1 -1
  283. package/scripts/gh/git-gh-pr-snapshot.ts +33 -20
  284. package/scripts/gh/git-gh-pr.ts +27 -15
  285. package/scripts/gh/git-pr-checks-eval.ts +39 -7
  286. package/scripts/gh/git-pr-checks-parse.ts +39 -9
  287. package/scripts/gh/git-pr-merge-checked.ts +80 -0
  288. package/scripts/gh/git-pr.ts +13 -1
  289. package/scripts/git/base-tree.ts +19 -2
  290. package/scripts/git/changed-file-scope.ts +6 -4
  291. package/scripts/git/changed-paths.ts +18 -1
  292. package/scripts/git/git-diff-reads.ts +27 -2
  293. package/scripts/git/git-grep-hits.ts +85 -0
  294. package/scripts/git/git-location-environment.ts +1 -1
  295. package/scripts/git/git-merge-conflicts.ts +83 -0
  296. package/scripts/git/git-preflight.ts +37 -12
  297. package/scripts/git/git-push-transport.ts +1 -2
  298. package/scripts/git/git-schemas.ts +17 -7
  299. package/scripts/git/git-spawn.ts +1 -2
  300. package/scripts/git/git-status.ts +4 -4
  301. package/scripts/git/main-merge-main.ts +12 -0
  302. package/scripts/git/main-merge-regenerate.ts +78 -0
  303. package/scripts/git/main-merge.ts +39 -14
  304. package/scripts/git/main-sync-main.ts +12 -0
  305. package/scripts/git/main-sync.ts +0 -9
  306. package/scripts/git/stash/git-stash.ts +27 -4
  307. package/scripts/git/stash/{stash-pop-args.ts → stash-args.ts} +13 -10
  308. package/scripts/git/stash/stash-pop-cli.ts +6 -12
  309. package/scripts/git/stash/stash-pop-main.ts +12 -0
  310. package/scripts/git/stash/stash-push-cli.ts +76 -0
  311. package/scripts/git/stash/stash-push-main.ts +12 -0
  312. package/scripts/hooks/batch-guard.ts +5 -16
  313. package/scripts/hooks/check-commit-message-main.ts +8 -0
  314. package/scripts/hooks/check-commit-message.ts +4 -7
  315. package/scripts/hooks/format-edited-file.ts +8 -24
  316. package/scripts/hooks/pre-commit-lint.ts +118 -0
  317. package/scripts/hooks/pre-push-unit.ts +4 -2
  318. package/scripts/hooks/pretool-guard-cli.ts +1 -8
  319. package/scripts/hooks/pretool-guard.ts +57 -69
  320. package/scripts/hooks/reserved-run.ts +67 -8
  321. package/scripts/hooks/run-hook.sh +18 -11
  322. package/scripts/hooks/shell-rules-notice.ts +37 -0
  323. package/scripts/hooks/stop-actions.ts +185 -0
  324. package/scripts/hooks/stop-guard.ts +72 -27
  325. package/scripts/init/hook-command-rewrite.ts +19 -5
  326. package/scripts/init/hook-launch.ts +15 -12
  327. package/scripts/init/init-actions.ts +0 -6
  328. package/scripts/init/init-ai-copy.ts +10 -36
  329. package/scripts/init/init-bootstrap.ts +9 -8
  330. package/scripts/init/init-dry-run-report.ts +1 -1
  331. package/scripts/init/init-dry-run.ts +1 -1
  332. package/scripts/init/init-file-action.ts +7 -9
  333. package/scripts/init/init-logic-json-merge.ts +2 -2
  334. package/scripts/init/init-logic-migrate.ts +9 -82
  335. package/scripts/init/init-logic.ts +3 -2
  336. package/scripts/init/init-main.ts +12 -0
  337. package/scripts/init/init.ts +5 -12
  338. package/scripts/init/kit-development-versions.ts +3 -7
  339. package/scripts/init/kit-written-paths.ts +2 -2
  340. package/scripts/init/project-profile.ts +5 -4
  341. package/scripts/init/tsconfig-preset-migration.ts +2 -1
  342. package/scripts/init/vscode-tasks.ts +1 -1
  343. package/scripts/issue/defect-origin-cli.ts +106 -0
  344. package/scripts/issue/defect-origin-line.ts +60 -0
  345. package/scripts/issue/defect-origin-main.ts +11 -0
  346. package/scripts/issue/defect-origin.ts +114 -0
  347. package/scripts/issue/defect-rate-cli.ts +34 -78
  348. package/scripts/issue/defect-rate.ts +0 -16
  349. package/scripts/issue/defect-report-cli.ts +128 -0
  350. package/scripts/issue/defect-report-format.ts +56 -0
  351. package/scripts/issue/defect-report-main.ts +11 -0
  352. package/scripts/issue/defect-report.ts +160 -0
  353. package/scripts/issue/expected-effect-lint.ts +60 -0
  354. package/scripts/issue/issue-already-done-cli.ts +62 -0
  355. package/scripts/issue/issue-body-or-comment.ts +40 -0
  356. package/scripts/issue/issue-cite-cli.ts +33 -22
  357. package/scripts/issue/issue-cite-main.ts +12 -0
  358. package/scripts/issue/issue-classification.ts +13 -8
  359. package/scripts/issue/issue-comment-cli.ts +10 -24
  360. package/scripts/issue/issue-comment-main.ts +12 -0
  361. package/scripts/issue/issue-evidence-exit.ts +100 -0
  362. package/scripts/issue/issue-file-cli.ts +29 -7
  363. package/scripts/issue/issue-file.ts +19 -19
  364. package/scripts/issue/issue-fold-cli.ts +2 -11
  365. package/scripts/issue/issue-fold-main.ts +12 -0
  366. package/scripts/issue/issue-labels.ts +81 -90
  367. package/scripts/issue/issue-lint-cli.ts +7 -13
  368. package/scripts/issue/issue-lint-main.ts +12 -0
  369. package/scripts/issue/issue-measured-cli.ts +56 -0
  370. package/scripts/issue/issue-merged.ts +19 -2
  371. package/scripts/issue/issue-not-before-label.ts +135 -0
  372. package/scripts/issue/issue-not-before.ts +111 -0
  373. package/scripts/issue/issue-number-shape.ts +15 -1
  374. package/scripts/issue/issue-park.ts +28 -0
  375. package/scripts/issue/issue-plan-cli.ts +151 -0
  376. package/scripts/issue/issue-priority.ts +151 -0
  377. package/scripts/issue/issue-rank.ts +7 -1
  378. package/scripts/issue/issue-read-cli.ts +3 -10
  379. package/scripts/issue/issue-read-main.ts +12 -0
  380. package/scripts/issue/issue-read.ts +29 -5
  381. package/scripts/issue/issue-release-cli.ts +0 -10
  382. package/scripts/issue/issue-release-main.ts +13 -0
  383. package/scripts/issue/issue-release.ts +7 -12
  384. package/scripts/issue/issue-sample-gate.ts +192 -0
  385. package/scripts/issue/issue-sample-source.ts +76 -0
  386. package/scripts/issue/issue-scout-cli.ts +19 -25
  387. package/scripts/issue/issue-scout-main.ts +14 -0
  388. package/scripts/issue/issue-state-cli.ts +0 -10
  389. package/scripts/issue/issue-state-main.ts +12 -0
  390. package/scripts/issue/issue-watch-diff.ts +56 -15
  391. package/scripts/issue/issue-watch.ts +2 -1
  392. package/scripts/issue/issue-wip.ts +2 -7
  393. package/scripts/issue/markdown-section.ts +19 -5
  394. package/scripts/issue/measure-rerun-cli.ts +13 -8
  395. package/scripts/issue/plan-consumers-cli.ts +39 -0
  396. package/scripts/issue/plan-consumers-main.ts +11 -0
  397. package/scripts/issue/plan-consumers-section.ts +55 -0
  398. package/scripts/issue/plan-consumers.ts +127 -0
  399. package/scripts/josh/agent-session-environment.ts +1 -1
  400. package/scripts/josh/command-usage.ts +82 -0
  401. package/scripts/josh/file-map-stamp.ts +49 -16
  402. package/scripts/josh/hook-decision.ts +32 -20
  403. package/scripts/josh/josh-command-map.ts +6 -1
  404. package/scripts/josh/josh-command-types.ts +65 -13
  405. package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
  406. package/scripts/josh/josh-commands-ai.ts +169 -157
  407. package/scripts/josh/josh-commands-backlog.ts +82 -16
  408. package/scripts/josh/josh-commands-clone.ts +1 -0
  409. package/scripts/josh/josh-commands-development.ts +111 -71
  410. package/scripts/josh/josh-commands-document.ts +43 -1
  411. package/scripts/josh/josh-commands-epic.ts +171 -0
  412. package/scripts/josh/josh-commands-hooks.ts +31 -2
  413. package/scripts/josh/josh-commands-issue-write.ts +181 -0
  414. package/scripts/josh/josh-commands-issue.ts +124 -24
  415. package/scripts/josh/josh-commands-lane.ts +112 -2
  416. package/scripts/josh/josh-commands-lint.ts +19 -8
  417. package/scripts/josh/josh-commands-maintenance.ts +112 -4
  418. package/scripts/josh/josh-commands-pause.ts +29 -0
  419. package/scripts/josh/josh-commands-progress.ts +87 -0
  420. package/scripts/josh/josh-commands-project.ts +138 -9
  421. package/scripts/josh/josh-commands-review.ts +124 -0
  422. package/scripts/josh/josh-commands-run.ts +211 -23
  423. package/scripts/josh/josh-commands-ship.ts +169 -0
  424. package/scripts/josh/josh-commands-split.ts +9 -0
  425. package/scripts/josh/josh-commands-versioning.ts +49 -2
  426. package/scripts/josh/josh-commands-workflow.ts +149 -6
  427. package/scripts/josh/josh-logic.ts +11 -27
  428. package/scripts/josh/josh.ts +14 -5
  429. package/scripts/josh/package-directory.ts +18 -0
  430. package/scripts/josh/process-identity.ts +13 -4
  431. package/scripts/josh/session-language-cli.ts +4 -8
  432. package/scripts/josh/session-language-main.ts +13 -0
  433. package/scripts/josh/session-language.ts +6 -1
  434. package/scripts/josh/shared-cache.ts +90 -0
  435. package/scripts/josh/stamp-file.ts +9 -15
  436. package/scripts/lane/lane-await.ts +51 -12
  437. package/scripts/lane/lane-cache.ts +5 -30
  438. package/scripts/lane/lane-capacity.ts +19 -22
  439. package/scripts/lane/lane-check-stats.ts +97 -0
  440. package/scripts/lane/lane-child-invocation.ts +43 -4
  441. package/scripts/lane/lane-cli.ts +15 -5
  442. package/scripts/lane/lane-close.ts +86 -18
  443. package/scripts/lane/lane-core-wait-stats.ts +66 -0
  444. package/scripts/lane/lane-dispatch.ts +27 -6
  445. package/scripts/lane/lane-gap-stats.ts +156 -0
  446. package/scripts/lane/lane-guard-policy.ts +2 -2
  447. package/scripts/lane/lane-handoff.ts +76 -1
  448. package/scripts/lane/lane-held-stats.ts +129 -0
  449. package/scripts/lane/lane-install.ts +16 -15
  450. package/scripts/lane/lane-launch-cli.ts +0 -9
  451. package/scripts/lane/lane-launch-main.ts +12 -0
  452. package/scripts/lane/lane-ledger-schema.ts +266 -0
  453. package/scripts/lane/lane-ledger.ts +108 -97
  454. package/scripts/lane/lane-limit-cli.ts +19 -9
  455. package/scripts/lane/lane-measure-cli.ts +58 -10
  456. package/scripts/lane/lane-open.ts +9 -1
  457. package/scripts/lane/lane-parked.ts +3 -3
  458. package/scripts/lane/lane-pause-cli.ts +130 -0
  459. package/scripts/lane/lane-pause.ts +158 -0
  460. package/scripts/lane/lane-preserve.ts +29 -1
  461. package/scripts/lane/lane-process-table.ts +166 -0
  462. package/scripts/lane/lane-reap-settle.ts +124 -0
  463. package/scripts/lane/lane-reap.ts +50 -15
  464. package/scripts/lane/lane-registry.ts +33 -10
  465. package/scripts/lane/lane-residents.ts +162 -0
  466. package/scripts/lane/lane-restart.ts +26 -27
  467. package/scripts/lane/lane-round-two-stats.ts +49 -0
  468. package/scripts/lane/lane-sampler.ts +4 -0
  469. package/scripts/lane/lane-session-action.ts +160 -0
  470. package/scripts/lane/lane-session-broker.ts +134 -134
  471. package/scripts/lane/lane-snapshot-trace.ts +84 -0
  472. package/scripts/lane/lane-spans.ts +51 -0
  473. package/scripts/lane/lane-spent.ts +6 -3
  474. package/scripts/lane/lane-stage-stats.ts +7 -2
  475. package/scripts/lane/lane-state.ts +302 -0
  476. package/scripts/lane/lane-stats.ts +58 -4
  477. package/scripts/lane/lane-stop-stats.ts +113 -37
  478. package/scripts/lane/lane-test-related-stats.ts +127 -0
  479. package/scripts/lane/lane-transcript-calls.ts +145 -0
  480. package/scripts/lane/lane-transcript-stats.ts +168 -0
  481. package/scripts/lane/lane-vacant.ts +13 -3
  482. package/scripts/lane/lane-withdraw-cli.ts +72 -0
  483. package/scripts/lane/lane-withdraw.ts +183 -0
  484. package/scripts/lane/process-directories.ts +70 -0
  485. package/scripts/lane/process-lane-marks.ts +94 -0
  486. package/scripts/lib/atomic-write.ts +62 -0
  487. package/scripts/lib/buffered-process.ts +12 -5
  488. package/scripts/lib/cli-flags.ts +53 -0
  489. package/scripts/lib/figure-format.ts +63 -0
  490. package/scripts/lib/json-value.ts +9 -1
  491. package/scripts/lib/package-manifest.ts +35 -0
  492. package/scripts/lib/read-file.ts +3 -1
  493. package/scripts/lib/stamped-memo.ts +63 -0
  494. package/scripts/lib/stdout-on-stderr.ts +24 -0
  495. package/scripts/lib/timeouts.ts +9 -0
  496. package/scripts/lib/transcript-record.ts +91 -0
  497. package/scripts/lines/effective-limit.ts +1 -1
  498. package/scripts/lint/eslint-cache-dependencies.ts +145 -0
  499. package/scripts/lint/eslint-daemon.ts +265 -0
  500. package/scripts/lint/format.ts +14 -5
  501. package/scripts/lint/import-graph.ts +279 -0
  502. package/scripts/lint/lint-gate-scope.ts +102 -0
  503. package/scripts/lint/lint-parallel-main.ts +19 -0
  504. package/scripts/lint/lint-parallel.ts +72 -33
  505. package/scripts/lint/lint-related-scope.ts +33 -24
  506. package/scripts/lint/lint-related.ts +38 -6
  507. package/scripts/notify/confirmation-options.ts +1 -2
  508. package/scripts/notify/telegram-notify.ts +20 -20
  509. package/scripts/notify/telegram-test-logic.ts +0 -1
  510. package/scripts/notify/telegram-test-main.ts +8 -0
  511. package/scripts/notify/telegram-test.ts +12 -11
  512. package/scripts/observations/observation-ledger.ts +13 -0
  513. package/scripts/observations/observations-flush-landing.ts +5 -3
  514. package/scripts/observations/observations-flush.ts +6 -1
  515. package/scripts/overrides/overrides-check.ts +2 -5
  516. package/scripts/overrides/overrides-files.ts +2 -1
  517. package/scripts/overrides/overrides-logic.ts +3 -6
  518. package/scripts/package/verify-optional-eslint-install.ts +8 -6
  519. package/scripts/propagate/propagate-publish.ts +2 -7
  520. package/scripts/propagate/propagate-targets.ts +4 -12
  521. package/scripts/refactor/import-graph.ts +9 -7
  522. package/scripts/release/github-release-runs.ts +17 -6
  523. package/scripts/release/release-approval-prune.ts +18 -0
  524. package/scripts/release/release-history.ts +1 -3
  525. package/scripts/release/release-progress.ts +42 -22
  526. package/scripts/release/release-publish-run.ts +39 -0
  527. package/scripts/release/release-publish.ts +6 -6
  528. package/scripts/release/release-scope-cli.ts +0 -10
  529. package/scripts/release/release-scope-main.ts +12 -0
  530. package/scripts/repo/repo-setting.ts +3 -6
  531. package/scripts/repo/required-checks-logic.ts +6 -15
  532. package/scripts/report/report-format-reference.ts +4 -0
  533. package/scripts/report/report-labels.ts +155 -0
  534. package/scripts/report/report-lint-cli.ts +3 -0
  535. package/scripts/report/report-lint.ts +85 -110
  536. package/scripts/report/report-template-cli.ts +59 -0
  537. package/scripts/report/report-template.ts +112 -0
  538. package/scripts/review/acceptance-map-check.ts +61 -0
  539. package/scripts/review/acceptance-map.ts +206 -0
  540. package/scripts/review/removed-tests-check.ts +86 -0
  541. package/scripts/review/removed-tests.ts +149 -0
  542. package/scripts/review/review-brief-cli.ts +82 -16
  543. package/scripts/review/review-brief-main.ts +12 -0
  544. package/scripts/review/review-brief.ts +31 -3
  545. package/scripts/review/review-code-tree.ts +10 -6
  546. package/scripts/review/review-comment-round.ts +26 -8
  547. package/scripts/review/review-finding-ledger.ts +30 -15
  548. package/scripts/review/review-interaction.ts +94 -0
  549. package/scripts/review/review-readers-scan.ts +163 -0
  550. package/scripts/review/review-record-cli.ts +69 -30
  551. package/scripts/review/review-record-main.ts +12 -0
  552. package/scripts/review/review-round-one-blobs.ts +221 -0
  553. package/scripts/review/review-round2-cli.ts +49 -12
  554. package/scripts/review/review-round2.ts +80 -12
  555. package/scripts/review/review-stamps.ts +19 -1
  556. package/scripts/review/review-stop-log.ts +96 -0
  557. package/scripts/review/review-stops-cli.ts +85 -0
  558. package/scripts/review/review-tree.ts +6 -17
  559. package/scripts/review/review-untouched-readers.ts +146 -0
  560. package/scripts/review/test-titles.ts +118 -0
  561. package/scripts/rules/agent-model.ts +67 -0
  562. package/scripts/rules/bash-triggers.ts +46 -3
  563. package/scripts/rules/decision-oracle-batch.ts +9 -1
  564. package/scripts/rules/decision-oracle.ts +2 -2
  565. package/scripts/rules/delivered-rules.ts +90 -3
  566. package/scripts/rules/destructive-command.ts +8 -1
  567. package/scripts/rules/direct-filing.ts +10 -2
  568. package/scripts/rules/direct-issue-comment.ts +117 -0
  569. package/scripts/rules/direct-pr-create.ts +69 -3
  570. package/scripts/rules/early-heartbeat.ts +2 -1
  571. package/scripts/rules/file-body.ts +7 -0
  572. package/scripts/rules/filing-cap.ts +8 -0
  573. package/scripts/rules/firing-point.ts +6 -5
  574. package/scripts/rules/git-argv.ts +72 -14
  575. package/scripts/rules/git-force.ts +12 -2
  576. package/scripts/rules/guard-remedy.ts +121 -0
  577. package/scripts/rules/implementation-cut-verdict.ts +1 -1
  578. package/scripts/rules/implementation-cut.ts +11 -3
  579. package/scripts/rules/index-guard.ts +8 -1
  580. package/scripts/rules/issue-comments.ts +76 -7
  581. package/scripts/rules/josh-git-bare.ts +7 -0
  582. package/scripts/rules/lane-background.ts +67 -25
  583. package/scripts/rules/lane-carry-conflict.ts +6 -0
  584. package/scripts/rules/lane-direct-tool.ts +74 -0
  585. package/scripts/rules/lane-interactive-ask.ts +9 -2
  586. package/scripts/rules/lane-park.ts +45 -23
  587. package/scripts/rules/lane-split-park.ts +10 -2
  588. package/scripts/rules/lane-switch-main.ts +7 -0
  589. package/scripts/rules/last-prompt.ts +50 -5
  590. package/scripts/rules/oracle-consulted.ts +10 -0
  591. package/scripts/rules/oracle-firing.ts +1 -0
  592. package/scripts/rules/oracle-list-cli.ts +7 -0
  593. package/scripts/rules/permission-guards.ts +3 -0
  594. package/scripts/rules/piped-verification.ts +4 -2
  595. package/scripts/rules/poll-loop.ts +7 -0
  596. package/scripts/rules/pr-merge.ts +123 -0
  597. package/scripts/rules/protected-files.ts +32 -5
  598. package/scripts/rules/raw-field-body.ts +6 -0
  599. package/scripts/rules/rule-body-guard.ts +8 -0
  600. package/scripts/rules/rule-list.ts +12 -28
  601. package/scripts/rules/rule-rewrite.ts +114 -0
  602. package/scripts/rules/rule-value-cache.ts +4 -9
  603. package/scripts/rules/rule-value-cli.ts +51 -32
  604. package/scripts/rules/rule-value.ts +8 -2
  605. package/scripts/rules/shell-segments.ts +50 -0
  606. package/scripts/rules/stop-decision.ts +77 -0
  607. package/scripts/rules/stop-rule-rows.ts +64 -0
  608. package/scripts/rules/stop-rules.ts +150 -51
  609. package/scripts/rules/tail-commands.ts +15 -1
  610. package/scripts/rules/test-declared-commit.ts +11 -1
  611. package/scripts/rules/third-party-write.ts +7 -0
  612. package/scripts/rules/timed-rerun.ts +69 -0
  613. package/scripts/rules/worktree-guard.ts +13 -3
  614. package/scripts/run/board/run-board-app-name.ts +23 -0
  615. package/scripts/run/board/run-board-cli.ts +65 -30
  616. package/scripts/run/board/run-board-closed.ts +8 -2
  617. package/scripts/run/board/run-board-earlier.ts +94 -0
  618. package/scripts/run/board/run-board-ending-reason.ts +67 -0
  619. package/scripts/run/board/run-board-estimate-schedule.ts +103 -0
  620. package/scripts/run/board/run-board-estimate.ts +98 -0
  621. package/scripts/run/board/run-board-fit.ts +153 -36
  622. package/scripts/run/board/run-board-fold.ts +123 -0
  623. package/scripts/run/board/run-board-fresh.ts +2 -2
  624. package/scripts/run/board/run-board-gather-live.ts +29 -0
  625. package/scripts/run/board/run-board-gather-thread.ts +189 -0
  626. package/scripts/run/board/run-board-gather-worker.ts +29 -0
  627. package/scripts/run/board/run-board-gather.ts +187 -0
  628. package/scripts/run/board/run-board-github.ts +119 -31
  629. package/scripts/run/board/run-board-header.ts +86 -21
  630. package/scripts/run/board/run-board-keys.ts +58 -0
  631. package/scripts/run/board/run-board-kind.ts +20 -6
  632. package/scripts/run/board/run-board-labels.ts +118 -71
  633. package/scripts/run/board/run-board-lane-state.ts +109 -0
  634. package/scripts/run/board/run-board-lane-time.ts +122 -0
  635. package/scripts/run/board/run-board-layout.ts +240 -61
  636. package/scripts/run/board/run-board-length.ts +52 -0
  637. package/scripts/run/board/run-board-machine.ts +8 -4
  638. package/scripts/run/board/run-board-main.ts +12 -0
  639. package/scripts/run/board/run-board-notes.ts +52 -31
  640. package/scripts/run/board/run-board-now.ts +1 -1
  641. package/scripts/run/board/run-board-operation.ts +15 -33
  642. package/scripts/run/board/run-board-phase.ts +1 -1
  643. package/scripts/run/board/run-board-plan-shared.ts +115 -0
  644. package/scripts/run/board/run-board-plan.ts +55 -3
  645. package/scripts/run/board/run-board-planning.ts +45 -0
  646. package/scripts/run/board/run-board-priority.ts +44 -0
  647. package/scripts/run/board/run-board-process-groups.ts +195 -0
  648. package/scripts/run/board/run-board-read.ts +153 -13
  649. package/scripts/run/board/run-board-reason.ts +238 -45
  650. package/scripts/run/board/run-board-released.ts +35 -0
  651. package/scripts/run/board/run-board-render-checks.ts +39 -5
  652. package/scripts/run/board/run-board-render-condition.ts +96 -0
  653. package/scripts/run/board/run-board-render-drawn.ts +67 -0
  654. package/scripts/run/board/run-board-render-foot.ts +59 -0
  655. package/scripts/run/board/run-board-render-icon.ts +35 -0
  656. package/scripts/run/board/run-board-render-lanes.ts +145 -0
  657. package/scripts/run/board/run-board-render-lead.ts +80 -0
  658. package/scripts/run/board/run-board-render-legend.ts +117 -47
  659. package/scripts/run/board/run-board-render-notes.ts +156 -29
  660. package/scripts/run/board/run-board-render-processes.ts +196 -0
  661. package/scripts/run/board/run-board-render-section.ts +119 -0
  662. package/scripts/run/board/run-board-render-slot.ts +3 -36
  663. package/scripts/run/board/run-board-render-tail.ts +115 -48
  664. package/scripts/run/board/run-board-render-time.ts +56 -0
  665. package/scripts/run/board/run-board-render-title.ts +117 -24
  666. package/scripts/run/board/run-board-render-waits.ts +125 -0
  667. package/scripts/run/board/run-board-render.ts +206 -259
  668. package/scripts/run/board/run-board-roots.ts +54 -0
  669. package/scripts/run/board/run-board-row-yield.ts +10 -4
  670. package/scripts/run/board/run-board-setup.ts +1 -12
  671. package/scripts/run/board/run-board-snapshot.ts +111 -0
  672. package/scripts/run/board/run-board-spin.ts +2 -2
  673. package/scripts/run/board/run-board-state.ts +23 -29
  674. package/scripts/run/board/run-board-status.ts +206 -79
  675. package/scripts/run/board/run-board-thanks-read.ts +2 -2
  676. package/scripts/run/board/run-board-tick.ts +123 -104
  677. package/scripts/run/board/run-board-usage-board.ts +78 -0
  678. package/scripts/run/board/run-board-usage-lanes.ts +113 -0
  679. package/scripts/run/board/run-board-usage-listing.ts +93 -0
  680. package/scripts/run/board/run-board-usage-read.ts +120 -150
  681. package/scripts/run/board/run-board-usage-rusage.ts +19 -7
  682. package/scripts/run/board/run-board-usage-text.ts +139 -51
  683. package/scripts/run/board/run-board-usage-top.ts +102 -0
  684. package/scripts/run/board/run-board-usage.ts +89 -72
  685. package/scripts/run/board/run-board-usual.ts +20 -9
  686. package/scripts/run/carry/run-carry-args.ts +4 -7
  687. package/scripts/run/carry/run-carry-conversation.ts +1 -1
  688. package/scripts/run/carry/run-carry.ts +9 -4
  689. package/scripts/run/cut/run-cut-cli.ts +3 -2
  690. package/scripts/run/cut/run-cut-handoff.ts +2 -2
  691. package/scripts/run/cut/run-cut-report.ts +16 -0
  692. package/scripts/run/detached-launch.ts +23 -4
  693. package/scripts/run/entry/run-entry-cli.ts +8 -1
  694. package/scripts/run/event/run-event-cli.ts +1 -5
  695. package/scripts/run/event/run-event-filed.ts +12 -6
  696. package/scripts/run/event/run-event-follow.ts +2 -3
  697. package/scripts/run/event/run-event-render.ts +7 -10
  698. package/scripts/run/event/run-event-scope.ts +20 -2
  699. package/scripts/run/event/run-event-stream-emit.ts +78 -11
  700. package/scripts/run/event/run-event-stream.ts +37 -7
  701. package/scripts/run/hold/run-hold-adopt.ts +65 -0
  702. package/scripts/run/hold/run-hold-cli.ts +93 -22
  703. package/scripts/run/hold/run-hold-main.ts +12 -0
  704. package/scripts/run/hold/run-hold-member.ts +37 -0
  705. package/scripts/run/hold/run-hold-session.ts +46 -0
  706. package/scripts/run/hold/run-hold.ts +7 -1
  707. package/scripts/run/hold/run-stop-notify.ts +183 -0
  708. package/scripts/run/launch-priority.ts +32 -0
  709. package/scripts/run/merge/run-merge-auth.ts +31 -0
  710. package/scripts/run/merge/run-merge-cli.ts +72 -107
  711. package/scripts/run/merge/run-merge-close.ts +74 -0
  712. package/scripts/run/merge/run-merge-collect.ts +6 -13
  713. package/scripts/run/merge/run-merge-driver.ts +71 -0
  714. package/scripts/run/merge/run-merge-main.ts +12 -0
  715. package/scripts/run/merge/run-merge-outcome.ts +23 -0
  716. package/scripts/run/merge/run-merge-restart.ts +39 -0
  717. package/scripts/run/merge/run-merge-ship.ts +20 -4
  718. package/scripts/run/merge/run-merge-signals.ts +123 -0
  719. package/scripts/run/merge/run-merge-steps.ts +128 -83
  720. package/scripts/run/merge/run-merge.ts +53 -40
  721. package/scripts/run/park/run-park-cli.ts +91 -0
  722. package/scripts/run/park/run-park.ts +88 -0
  723. package/scripts/run/park/run-stalled.ts +68 -0
  724. package/scripts/run/pause/run-pause-cli.ts +73 -0
  725. package/scripts/run/pause/run-pause.ts +251 -0
  726. package/scripts/run/progress/run-progress-cli.ts +4 -12
  727. package/scripts/run/progress/run-progress-clock.ts +1 -1
  728. package/scripts/run/progress/run-progress-config.ts +6 -14
  729. package/scripts/run/progress/run-progress-main.ts +12 -0
  730. package/scripts/run/progress/run-progress.ts +1 -4
  731. package/scripts/run/review/run-review.ts +2 -1
  732. package/scripts/run/run-ending.ts +1 -0
  733. package/scripts/run/run-invocation.ts +5 -6
  734. package/scripts/run/run-liveness-cli.ts +6 -8
  735. package/scripts/run/run-liveness.ts +61 -30
  736. package/scripts/run/run-next.ts +1 -1
  737. package/scripts/run/run-parent-cut-hook.ts +2 -2
  738. package/scripts/run/run-poll-hook.ts +157 -0
  739. package/scripts/run/run-preflight.ts +18 -3
  740. package/scripts/run/run-prep-cli.ts +1 -10
  741. package/scripts/run/run-prep-locate.ts +7 -50
  742. package/scripts/run/run-prep-main.ts +12 -0
  743. package/scripts/run/run-prep.ts +6 -0
  744. package/scripts/run/run-report-cli.ts +101 -13
  745. package/scripts/run/run-report-handoff.ts +114 -0
  746. package/scripts/run/run-step-cli.ts +22 -15
  747. package/scripts/run/run-step-section.ts +85 -0
  748. package/scripts/run/run-step.ts +1 -1
  749. package/scripts/run/run-stranded-detect.ts +13 -0
  750. package/scripts/run/run-watcher-guard-cli.ts +1 -1
  751. package/scripts/run/run-watcher-guard.ts +1 -1
  752. package/scripts/run/ship/run-ship-args.ts +121 -0
  753. package/scripts/run/ship/run-ship-body-draft.ts +110 -0
  754. package/scripts/run/ship/run-ship-cli.ts +67 -151
  755. package/scripts/run/ship/run-ship-detach.ts +27 -7
  756. package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
  757. package/scripts/run/ship/run-ship-next.ts +27 -3
  758. package/scripts/run/ship/run-ship-overlap.ts +232 -0
  759. package/scripts/run/ship/run-ship-place.ts +96 -0
  760. package/scripts/run/ship/run-ship-pre-detach-timed.ts +43 -0
  761. package/scripts/run/ship/run-ship-pre-detach.ts +102 -27
  762. package/scripts/run/ship/run-ship-preflight.ts +161 -30
  763. package/scripts/run/ship/run-ship-probe.ts +11 -3
  764. package/scripts/run/ship/run-ship-relaunch-cap.ts +70 -0
  765. package/scripts/run/ship/run-ship-removed-rows.ts +61 -0
  766. package/scripts/run/ship/run-ship-return.ts +123 -15
  767. package/scripts/run/ship/run-ship-review-steps.ts +105 -149
  768. package/scripts/run/ship/run-ship-review.ts +73 -6
  769. package/scripts/run/ship/run-ship-reviewer.ts +207 -0
  770. package/scripts/run/ship/run-ship-stage.ts +55 -6
  771. package/scripts/run/ship/run-ship-steps.ts +46 -15
  772. package/scripts/run/ship/run-ship-stop-cause.ts +135 -0
  773. package/scripts/run/ship/run-ship-stop-context.ts +206 -0
  774. package/scripts/run/ship/run-ship-stop-text.ts +11 -6
  775. package/scripts/run/ship/run-ship-sync.ts +57 -12
  776. package/scripts/run/ship/run-ship.ts +30 -2
  777. package/scripts/run/tidy/run-tidy-cli.ts +0 -4
  778. package/scripts/run/tidy/run-tidy-lanes.ts +3 -0
  779. package/scripts/run/tidy/run-tidy-main.ts +8 -0
  780. package/scripts/run/wake/run-wake-cli.ts +119 -100
  781. package/scripts/run/wake/run-wake-code.ts +83 -0
  782. package/scripts/run/wake/run-wake-driver.ts +19 -8
  783. package/scripts/run/wake/run-wake-loop.ts +34 -3
  784. package/scripts/run/wake/run-wake-main.ts +13 -0
  785. package/scripts/run/wake/run-wake-ports.ts +90 -0
  786. package/scripts/run/wake/run-wake-takeover.ts +66 -0
  787. package/scripts/run/wake/run-wake.ts +2 -1
  788. package/scripts/safe-chain/pack-hook.ts +2 -2
  789. package/scripts/safe-chain/preinstall-command.ts +2 -1
  790. package/scripts/safe-chain/project-config.ts +3 -9
  791. package/scripts/security/security-audit-main.ts +8 -0
  792. package/scripts/security/security-audit-provision-logic.ts +0 -11
  793. package/scripts/security/security-audit-provision-main.ts +12 -0
  794. package/scripts/security/security-audit-provision.ts +11 -26
  795. package/scripts/security/security-audit.ts +6 -7
  796. package/scripts/self-sync-guard/self-sync-guard-logic.ts +6 -13
  797. package/scripts/split/split-assess-cli.ts +2 -2
  798. package/scripts/split/split-assess.ts +15 -0
  799. package/scripts/split/split-measure.ts +65 -0
  800. package/scripts/sync/claude-settings-merge.ts +8 -15
  801. package/scripts/sync/directory-copy-guard.ts +4 -9
  802. package/scripts/sync/file-content.ts +78 -8
  803. package/scripts/sync/sync-ai-files.ts +3 -5
  804. package/scripts/sync/sync-configs.ts +11 -23
  805. package/scripts/sync/sync-hook-safety.ts +4 -10
  806. package/scripts/sync/sync-main.ts +11 -0
  807. package/scripts/sync/sync.ts +25 -37
  808. package/scripts/test/test-declared-changed.ts +2 -2
  809. package/scripts/test/test-declared.ts +1 -1
  810. package/scripts/test/test-e2e-guard.ts +55 -6
  811. package/scripts/test/test-e2e-stamp.ts +38 -0
  812. package/scripts/test/test-pinned-logic.ts +145 -0
  813. package/scripts/test/test-pinned-main.ts +78 -0
  814. package/scripts/test/test-pinned.ts +100 -0
  815. package/scripts/test/test-read-map.ts +264 -0
  816. package/scripts/test/test-read-recording.ts +91 -0
  817. package/scripts/test/test-read-trace.ts +148 -0
  818. package/scripts/test/test-red-main.ts +12 -0
  819. package/scripts/test/test-red.ts +12 -30
  820. package/scripts/test/test-related-main.ts +18 -0
  821. package/scripts/test/test-related-record.ts +119 -0
  822. package/scripts/test/test-related-scope.ts +229 -43
  823. package/scripts/test/test-related.ts +300 -22
  824. package/scripts/test/test-unit-guard-main.ts +15 -0
  825. package/scripts/test/test-unit-guard.ts +54 -21
  826. package/scripts/test/unit-count-file.ts +37 -0
  827. package/scripts/test/unit-run-marker.ts +162 -0
  828. package/scripts/test/unit-setup-files.ts +51 -0
  829. package/scripts/test/unit-worker-share.ts +71 -137
  830. package/scripts/test/whole-suite-files.ts +63 -0
  831. package/scripts/time-runtime/time-background.ts +20 -2
  832. package/scripts/time-runtime/time-bundles.ts +4 -3
  833. package/scripts/time-runtime/time-density-hook.ts +8 -6
  834. package/scripts/time-runtime/time-followup-stage.ts +1 -3
  835. package/scripts/time-runtime/time-format.ts +5 -28
  836. package/scripts/time-runtime/time-markers.ts +10 -1
  837. package/scripts/time-runtime/time-shell.ts +126 -14
  838. package/scripts/time-runtime/time-spans.ts +1 -0
  839. package/scripts/time-runtime/time-tool-call.ts +7 -0
  840. package/scripts/time-runtime/time-transcript-line.ts +49 -62
  841. package/scripts/uninstall/uninstall.ts +1 -1
  842. package/scripts/version/bump-version-main.ts +12 -0
  843. package/scripts/version/bump-version.ts +25 -25
  844. package/scripts/version/effective-upstream.ts +6 -12
  845. package/scripts/version/latest-corepack.ts +17 -32
  846. package/scripts/version/latest-if-required-cli.ts +93 -0
  847. package/scripts/version/latest-lane-guard-main.ts +8 -0
  848. package/scripts/version/latest-lane-guard.ts +0 -4
  849. package/scripts/version/latest-scope-cli.ts +0 -9
  850. package/scripts/version/latest-scope-main.ts +12 -0
  851. package/scripts/version/latest-update.ts +5 -5
  852. package/scripts/version/npm-registry.ts +44 -6
  853. package/scripts/version/publishable-range-check.ts +5 -16
  854. package/scripts/version/release-age.ts +1 -1
  855. package/scripts/version/release-hold.ts +1 -1
  856. package/scripts/version/release-window.ts +38 -0
  857. package/scripts/version/running-binary.ts +1 -1
  858. package/scripts/version/safe-chain-version-update.ts +3 -8
  859. package/scripts/version/version-targets.ts +6 -28
  860. package/templates/dependabot.yml +29 -0
  861. package/templates/gitignore +10 -3
  862. package/templates/pnpm-workspace.basic.yaml +1 -1
  863. package/templates/sonar-project.properties +3 -2
  864. package/templates/workflows/ci.yml +12 -4
  865. package/templates/workflows/github-release.yml +4 -0
  866. package/tsconfig.sonar.json +1 -1
  867. package/.ncurc.json +0 -3
  868. package/dist/hooks/batch-guard.js +0 -29
  869. package/dist/hooks/chunk-43ZHT22P.js +0 -3495
  870. package/dist/hooks/chunk-CDY4NFQG.js +0 -15
  871. package/dist/hooks/chunk-EUMACUK2.js +0 -2038
  872. package/dist/hooks/chunk-H5HVWYXK.js +0 -359
  873. package/dist/hooks/chunk-IIGFYXKC.js +0 -7104
  874. package/dist/hooks/chunk-IX6TTTI6.js +0 -95
  875. package/dist/hooks/chunk-J47HU5H5.js +0 -237
  876. package/dist/hooks/chunk-K4EOONYM.js +0 -45
  877. package/dist/hooks/chunk-K4LMBQC2.js +0 -68
  878. package/dist/hooks/chunk-SHGPANFB.js +0 -56
  879. package/dist/hooks/chunk-YHBZAJSV.js +0 -79
  880. package/dist/hooks/chunk-YYPI7SJZ.js +0 -131
  881. package/dist/hooks/duplicate-read-guard.js +0 -30
  882. package/dist/hooks/investigation-guard.js +0 -32
  883. package/scripts/backlog/backlog-stalled-cli.ts +0 -30
  884. package/scripts/cost-runtime/cost-format.ts +0 -29
  885. package/scripts/init/basic-path-migration.ts +0 -24
  886. package/scripts/issue/issue-backlinks-cli.ts +0 -93
  887. package/scripts/josh/josh-commands-guard.ts +0 -38
  888. package/scripts/lint/cross-file-recheck.ts +0 -155
  889. package/scripts/registry-migration/migrate-logic.ts +0 -237
  890. package/scripts/registry-migration/migrate.ts +0 -292
  891. package/scripts/registry-migration/user-npmrc.ts +0 -15
  892. package/scripts/rules/rule-guard.ts +0 -23
  893. package/scripts/rules/rule-registry-rows.ts +0 -282
  894. package/scripts/rules/rule-registry.ts +0 -109
  895. package/scripts/run/run-stranded-cli.ts +0 -27
@@ -0,0 +1,65 @@
1
+ import { readFile } from 'node:fs/promises'
2
+ import path from 'node:path'
3
+ import { changed_paths } from '#scripts/git/changed-paths'
4
+ import { git_command } from '#scripts/git/git-command'
5
+ import { git_spawn } from '#scripts/git/git-spawn'
6
+ import { split_assess } from './split-assess'
7
+
8
+ // The branch's size measurement — the one reading every `split_assess` caller takes.
9
+ //
10
+ // joshuafolkken/kit#4302: `git diff` never lists an untracked file, and a run has staged nothing
11
+ // when it measures, so the diff alone counted every new file a branch created as absent. Each
12
+ // untracked file is added as a numstat row of its line count, so a branch made of new modules
13
+ // measures as large as it is. A file holding a NUL byte is binary and counts zero lines, as
14
+ // `git diff --numstat` counts it. An entry with no readable content — a dangling symlink, a nested
15
+ // repository's directory — still counts as a file, of zero lines, so one such entry cannot reject
16
+ // the whole measurement.
17
+
18
+ const NUL_BYTE = 0
19
+ const NO_CONTENT = Buffer.alloc(0)
20
+ const NEWLINE = '\n'
21
+
22
+ function line_count(content: Buffer): number {
23
+ if (content.includes(NUL_BYTE)) return 0
24
+
25
+ const text = content.toString('utf8')
26
+ const newlines = text.split(NEWLINE).length - 1
27
+
28
+ return text === '' || text.endsWith(NEWLINE) ? newlines : newlines + 1
29
+ }
30
+
31
+ async function read_content(file_path: string): Promise<Buffer> {
32
+ try {
33
+ return await readFile(file_path)
34
+ } catch {
35
+ return NO_CONTENT
36
+ }
37
+ }
38
+
39
+ async function untracked_row(root: string, file: string): Promise<string> {
40
+ const lines = line_count(await read_content(path.join(root, file)))
41
+
42
+ return `${String(lines)}\t0\t${file}`
43
+ }
44
+
45
+ async function untracked_numstat(): Promise<string> {
46
+ const files = changed_paths.to_paths(await git_command.untracked_names())
47
+
48
+ if (files.length === 0) return ''
49
+
50
+ const toplevel = await git_spawn.read(['rev-parse', '--show-toplevel'])
51
+ const root = toplevel.trim()
52
+ const rows = await Promise.all(files.map(async (file) => await untracked_row(root, file)))
53
+
54
+ return rows.join(NEWLINE)
55
+ }
56
+
57
+ async function read_branch(): Promise<ReturnType<typeof split_assess.assess>> {
58
+ const tracked = await git_command.diff_main_numstat()
59
+
60
+ return split_assess.assess(`${tracked}${NEWLINE}${await untracked_numstat()}`)
61
+ }
62
+
63
+ const split_measure = { line_count, read_branch }
64
+
65
+ export { split_measure }
@@ -1,5 +1,6 @@
1
1
  import { json_format } from '#scripts/config-merge/json-format'
2
2
  import { hook_command_rewrite } from '#scripts/init/hook-command-rewrite'
3
+ import { json_value } from '#scripts/lib/json-value'
3
4
 
4
5
  // `josh sync` used to replace a project's `.claude/settings.json` with the distributed file, which
5
6
  // deleted every hook and permission the project had added — and `.claude/settings.local.json` is
@@ -29,10 +30,6 @@ const WITHDRAWN_KIT_PERMISSIONS: ReadonlySet<unknown> = new Set([
29
30
  'Bash(git commit --all*)',
30
31
  ])
31
32
 
32
- function is_json_object(value: unknown): value is JsonObject {
33
- return typeof value === 'object' && value !== null && !Array.isArray(value)
34
- }
35
-
36
33
  function as_array(value: unknown): Array<unknown> {
37
34
  return Array.isArray(value) ? value : []
38
35
  }
@@ -46,7 +43,7 @@ function merge_objects(kit: JsonObject, own: JsonObject, merge_entry: EntryMerge
46
43
  }
47
44
 
48
45
  function merge_kit_value(kit: unknown, own: unknown): unknown {
49
- if (!is_json_object(kit) || !is_json_object(own)) return kit
46
+ if (!json_value.is_record(kit) || !json_value.is_record(own)) return kit
50
47
 
51
48
  return merge_objects(kit, own, (_key, kit_entry, own_entry) =>
52
49
  merge_kit_value(kit_entry, own_entry),
@@ -68,7 +65,7 @@ function without_withdrawn(value: unknown): unknown {
68
65
  // The withdrawn entries are taken out of every list first, so one goes even when kit no longer ships
69
66
  // the list it sat in.
70
67
  function merge_permissions(kit: unknown, own: unknown): unknown {
71
- if (!is_json_object(kit) || !is_json_object(own)) return kit
68
+ if (!json_value.is_record(kit) || !json_value.is_record(own)) return kit
72
69
  const kept = Object.entries(own).map(([key, value]) => [key, without_withdrawn(value)] as const)
73
70
 
74
71
  return merge_objects(kit, Object.fromEntries(kept), (_key, kit_entry, own_entry) =>
@@ -77,7 +74,7 @@ function merge_permissions(kit: unknown, own: unknown): unknown {
77
74
  }
78
75
 
79
76
  function is_kit_handler(handler: unknown): boolean {
80
- if (!is_json_object(handler)) return false
77
+ if (!json_value.is_record(handler)) return false
81
78
  const { command } = handler
82
79
 
83
80
  return typeof command === 'string' && hook_command_rewrite.is_kit_hook_command(command)
@@ -85,7 +82,7 @@ function is_kit_handler(handler: unknown): boolean {
85
82
 
86
83
  // A matcher group left with no handler of the project's own was kit's alone, and goes with them.
87
84
  function without_kit_handlers(group: unknown): unknown {
88
- if (!is_json_object(group)) return group
85
+ if (!json_value.is_record(group)) return group
89
86
  const handlers = as_array(group[HOOKS_KEY]).filter((handler) => !is_kit_handler(handler))
90
87
 
91
88
  return handlers.length === 0 ? undefined : { ...group, [HOOKS_KEY]: handlers }
@@ -104,7 +101,7 @@ function own_hook_events(own: JsonObject): JsonObject {
104
101
  }
105
102
 
106
103
  function merge_hooks(kit: unknown, own: unknown): unknown {
107
- if (!is_json_object(kit) || !is_json_object(own)) return kit
104
+ if (!json_value.is_record(kit) || !json_value.is_record(own)) return kit
108
105
 
109
106
  return merge_objects(kit, own_hook_events(own), (_event, kit_groups, groups) => [
110
107
  ...as_array(kit_groups),
@@ -120,13 +117,9 @@ function merge_top_level(key: string, kit: unknown, own: unknown): unknown {
120
117
  }
121
118
 
122
119
  function parse_object(content: string): JsonObject | undefined {
123
- try {
124
- const parsed: unknown = JSON.parse(content)
120
+ const parsed = json_value.parse_or_undefined(content)
125
121
 
126
- return is_json_object(parsed) ? parsed : undefined
127
- } catch {
128
- return undefined
129
- }
122
+ return json_value.is_record(parsed) ? parsed : undefined
130
123
  }
131
124
 
132
125
  // A file that does not parse as a JSON object has nothing the merge can keep, so it is replaced with
@@ -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 = {