@joshuafolkken/kit 1.1229.0 → 1.1370.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 (939) hide show
  1. package/.claude/agents/investigator.md +1 -0
  2. package/.claude/settings.json +4 -0
  3. package/.claude/skills/dependency-update/SKILL.md +5 -3
  4. package/.claude/skills/epic-commands/SKILL.md +82 -113
  5. package/.claude/skills/epic-commands/epic-bundle.md +38 -63
  6. package/.claude/skills/epic-commands/execution-waves.md +30 -51
  7. package/.claude/skills/verify-ui/SKILL.md +13 -20
  8. package/.claude/skills/workflow-commands/SKILL.md +10 -10
  9. package/.claude/skills/workflow-commands/background-commands.md +4 -4
  10. package/.claude/skills/workflow-commands/backlogrun-child.md +30 -105
  11. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +29 -0
  12. package/.claude/skills/workflow-commands/backlogrun-lanes.md +45 -131
  13. package/.claude/skills/workflow-commands/backlogrun-park.md +36 -53
  14. package/.claude/skills/workflow-commands/backlogrun-progress.md +81 -331
  15. package/.claude/skills/workflow-commands/backlogrun-recovery.md +29 -83
  16. package/.claude/skills/workflow-commands/backlogrun-steps.md +105 -424
  17. package/.claude/skills/workflow-commands/backlogrun.md +50 -61
  18. package/.claude/skills/workflow-commands/chain-rule.md +36 -40
  19. package/.claude/skills/workflow-commands/entry-sequence.md +6 -6
  20. package/.claude/skills/workflow-commands/followup.md +24 -20
  21. package/.claude/skills/workflow-commands/fullrun-steps.md +23 -27
  22. package/.claude/skills/workflow-commands/fullrun.md +10 -10
  23. package/.claude/skills/workflow-commands/halfrun.md +9 -8
  24. package/.claude/skills/workflow-commands/into-target.md +12 -18
  25. package/.claude/skills/workflow-commands/issue-comments.md +11 -26
  26. package/.claude/skills/workflow-commands/kickoff.md +27 -16
  27. package/.claude/skills/workflow-commands/latest-gate.md +18 -29
  28. package/.claude/skills/workflow-commands/needs-human-review.md +13 -24
  29. package/.claude/skills/workflow-commands/observation-filing.md +37 -28
  30. package/.claude/skills/workflow-commands/observation-ledger.md +48 -38
  31. package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -9
  32. package/.claude/skills/workflow-commands/prerequisite.md +23 -15
  33. package/.claude/skills/workflow-commands/progress-watcher.md +17 -11
  34. package/.claude/skills/workflow-commands/prrun.md +3 -3
  35. package/.claude/skills/workflow-commands/retrospective.md +13 -18
  36. package/.claude/skills/workflow-commands/split-assessment.md +6 -4
  37. package/.claude/skills/workflow-commands/target-repository.md +25 -28
  38. package/.claude/skills/workflow-commands/working-tree-hold.md +11 -17
  39. package/.gitattributes +2 -1
  40. package/.github/workflows/ci.yml +14 -0
  41. package/.github/workflows/publish.yml +2 -0
  42. package/.vscode/tasks.json +14 -0
  43. package/CLAUDE.md +10 -61
  44. package/README.md +38 -57
  45. package/SECURITY.md +1 -1
  46. package/dist/CLAUDE.md +10 -61
  47. package/dist/commands/document-section-cli.js +42 -10
  48. package/dist/config-merge/index.js +11 -2
  49. package/dist/hooks/audit-provision.js +2 -2
  50. package/dist/hooks/batch-guard.js +7 -7
  51. package/dist/hooks/{chunk-FIVDHQGT.js → chunk-43G45XJF.js} +18 -20
  52. package/dist/hooks/{chunk-JUDKDCDP.js → chunk-4TW4MQUL.js} +284 -362
  53. package/dist/hooks/{chunk-5VMKCCC4.js → chunk-76RK6E3H.js} +13 -11
  54. package/dist/hooks/{chunk-RNWHN5BP.js → chunk-DZWZ3DKY.js} +4 -4
  55. package/dist/hooks/{chunk-5VNDSNG3.js → chunk-FZ6FUSBM.js} +1 -1
  56. package/dist/hooks/{chunk-VC3PZPZO.js → chunk-GG72ANKI.js} +1 -1
  57. package/dist/hooks/{chunk-6HJJXRBX.js → chunk-KPM4YIIX.js} +8 -44
  58. package/dist/hooks/chunk-MXVQMLDP.js +3705 -0
  59. package/dist/hooks/{chunk-ELCN5LCH.js → chunk-NEC4AT4Z.js} +34 -12
  60. package/dist/hooks/{chunk-TQNPDZNH.js → chunk-NZBHG6FW.js} +7 -5
  61. package/dist/hooks/chunk-NZN2UFI6.js +2409 -0
  62. package/dist/hooks/{chunk-F56MFS4B.js → chunk-R6CRQEAL.js} +4 -4
  63. package/dist/hooks/chunk-SYSRHRWU.js +1589 -0
  64. package/dist/hooks/{chunk-55HHG5PX.js → chunk-TLJYAGZK.js} +799 -903
  65. package/dist/hooks/chunk-Z5TMJIPW.js +45 -0
  66. package/dist/hooks/codex-hook-adapter.js +26 -21
  67. package/dist/hooks/duplicate-read-guard.js +8 -8
  68. package/dist/hooks/format-edited.js +4 -4
  69. package/dist/hooks/inputs.json +213 -197
  70. package/dist/hooks/investigation-guard.js +8 -8
  71. package/dist/hooks/pretool-guard.js +15 -15
  72. package/dist/hooks/session-lang.js +406 -8
  73. package/dist/hooks/stop-guard.js +122 -201
  74. package/dist/josh.js +540 -137
  75. package/dist/version/index.js +15 -13
  76. package/eslint/base.js +43 -5
  77. package/eslint/rules/english-only-prose.js +3 -3
  78. package/eslint/rules/import.js +12 -0
  79. package/eslint/rules/namespace-object-export.js +2 -2
  80. package/package.json +16 -10
  81. package/pnpm-workspace.yaml +2 -4
  82. package/prompts/coding-standards.md +14 -48
  83. package/prompts/collaboration-workflow/file-edits.md +1 -1
  84. package/prompts/collaboration-workflow/issue-citation.md +1 -1
  85. package/prompts/collaboration-workflow/issue-template.md +4 -10
  86. package/prompts/collaboration-workflow/operating-rules.md +7 -8
  87. package/prompts/collaboration-workflow/output-bounds.md +1 -1
  88. package/prompts/collaboration-workflow/overview.md +1 -1
  89. package/prompts/collaboration-workflow/plan-comment.md +2 -1
  90. package/prompts/collaboration-workflow/principles.md +21 -3
  91. package/prompts/collaboration-workflow/report-format.md +16 -29
  92. package/prompts/collaboration-workflow/residency.md +1 -1
  93. package/prompts/collaboration-workflow/rule-delivery.md +7 -95
  94. package/prompts/collaboration-workflow/shell-body.md +3 -23
  95. package/prompts/collaboration-workflow/turn-batching.md +4 -13
  96. package/prompts/collaboration-workflow/wip-cap.md +5 -11
  97. package/prompts/refactoring.md +1 -1
  98. package/prompts/review-rubric.md +3 -22
  99. package/prompts/review.md +15 -38
  100. package/prompts/testing-guide.md +2 -4
  101. package/scripts/adopt/adopt-logic.ts +5 -5
  102. package/scripts/adopt/adopt-toolkits.ts +4 -5
  103. package/scripts/adopt/adopt.ts +2 -3
  104. package/scripts/agent/agent-argv.ts +7 -7
  105. package/scripts/agent/agent-diagnostics.ts +2 -2
  106. package/scripts/agent/agent-exit-record.ts +1 -1
  107. package/scripts/agent/agent-headless.ts +1 -1
  108. package/scripts/agent/agent-launch-environment.ts +6 -1
  109. package/scripts/agent/agent-role-profile.ts +49 -22
  110. package/scripts/agent/agent-session-role.ts +32 -0
  111. package/scripts/agent/api-outage.ts +1 -1
  112. package/scripts/agent/claude-agent-argv.ts +4 -4
  113. package/scripts/agent/claude-result-event.ts +4 -4
  114. package/scripts/agent/codex-hooks.ts +2 -2
  115. package/scripts/agent/interactive-ask.ts +3 -6
  116. package/scripts/auto-ok/auto-ok-cli.ts +46 -60
  117. package/scripts/backlog/backlog-arrival-added.ts +34 -0
  118. package/scripts/backlog/backlog-arrival.ts +54 -17
  119. package/scripts/backlog/backlog-budget-cli.ts +34 -6
  120. package/scripts/backlog/backlog-budget.ts +17 -24
  121. package/scripts/backlog/backlog-defect-priority.ts +1 -1
  122. package/scripts/backlog/backlog-drive-args.ts +5 -4
  123. package/scripts/backlog/backlog-drive-cli.ts +14 -10
  124. package/scripts/backlog/backlog-drive-epic.ts +85 -0
  125. package/scripts/backlog/backlog-drive-launch.ts +1 -1
  126. package/scripts/backlog/backlog-drive-named-offer.ts +60 -9
  127. package/scripts/backlog/backlog-drive-named.ts +39 -9
  128. package/scripts/backlog/backlog-drive-offer-argv.ts +1 -1
  129. package/scripts/backlog/backlog-drive-restore.ts +1 -1
  130. package/scripts/backlog/backlog-drive-retrospective.ts +2 -2
  131. package/scripts/backlog/backlog-drive.ts +43 -28
  132. package/scripts/backlog/backlog-idle.ts +88 -0
  133. package/scripts/backlog/backlog-named.ts +11 -15
  134. package/scripts/backlog/backlog-next.ts +26 -30
  135. package/scripts/backlog/backlog-offer-cli.ts +28 -23
  136. package/scripts/backlog/backlog-offer.ts +7 -7
  137. package/scripts/backlog/backlog-overlap.ts +178 -0
  138. package/scripts/backlog/backlog-plan-cli.ts +14 -90
  139. package/scripts/backlog/backlog-plan-read.ts +111 -0
  140. package/scripts/backlog/backlog-plan.ts +11 -10
  141. package/scripts/backlog/backlog-pool.ts +13 -14
  142. package/scripts/backlog/backlog-rank.ts +11 -11
  143. package/scripts/backlog/backlog-ready.ts +15 -10
  144. package/scripts/backlog/backlog-scope.ts +14 -15
  145. package/scripts/backlog/backlog-stalled-cli.ts +2 -2
  146. package/scripts/backlog/backlog-stalled-detect.ts +4 -4
  147. package/scripts/backlog/backlog-stalled.ts +5 -6
  148. package/scripts/backlog/backlog-waves.ts +4 -4
  149. package/scripts/backlog/backlogrun-args.ts +74 -0
  150. package/scripts/backlog/backlogrun-cli.ts +113 -0
  151. package/scripts/backlog/backlogrun-launch.ts +178 -0
  152. package/scripts/behavior/behavior-assertion.ts +6 -8
  153. package/scripts/behavior/behavior-cli.ts +1 -1
  154. package/scripts/behavior/behavior-rules.ts +3 -3
  155. package/scripts/build/build-claude-md.ts +4 -4
  156. package/scripts/build/build-codex-hooks.ts +2 -2
  157. package/scripts/build/build-commands.ts +1 -1
  158. package/scripts/build/build-hooks.ts +5 -5
  159. package/scripts/build/build.ts +1 -1
  160. package/scripts/build/hook-bundle-stamp.ts +109 -7
  161. package/scripts/build/local-bin.ts +2 -2
  162. package/scripts/cases/cases-cli.ts +1 -1
  163. package/scripts/cases/cases-logic.ts +2 -2
  164. package/scripts/ci/composite-actions.ts +1 -2
  165. package/scripts/ci/pr-classification.ts +2 -2
  166. package/scripts/claude/workflow-destination.ts +1 -1
  167. package/scripts/clone/clone-aggregate.ts +1 -1
  168. package/scripts/clone/clone-fingerprint.ts +1 -1
  169. package/scripts/clone/clone-scan-cli.ts +1 -1
  170. package/scripts/clone/clone-scan.ts +1 -1
  171. package/scripts/config-merge/index.ts +1 -1
  172. package/scripts/config-merge/json-format.ts +1 -3
  173. package/scripts/config-merge/patch-json-array.ts +90 -0
  174. package/scripts/config-merge/patch-json-key.ts +6 -3
  175. package/scripts/config-merge/patch-json-list.ts +1 -1
  176. package/scripts/cost-runtime/codex-usage.ts +1 -1
  177. package/scripts/cost-runtime/context-cut-payback.ts +4 -5
  178. package/scripts/cost-runtime/context-cut-threshold.ts +4 -6
  179. package/scripts/cost-runtime/cost-attribute.ts +3 -3
  180. package/scripts/cost-runtime/cost-blocks.ts +3 -4
  181. package/scripts/cost-runtime/cost-cli.ts +14 -11
  182. package/scripts/cost-runtime/cost-corpus.ts +11 -11
  183. package/scripts/cost-runtime/cost-pricing.ts +4 -4
  184. package/scripts/cost-runtime/cost-tokens.ts +1 -2
  185. package/scripts/cost-runtime/cost-transcript.ts +29 -29
  186. package/scripts/cost-runtime/cost-usage.ts +6 -7
  187. package/scripts/cost-runtime/cost-verdict.ts +10 -11
  188. package/scripts/cost-runtime/own-session.ts +1 -1
  189. package/scripts/cost-runtime/transcript-cwd.ts +2 -2
  190. package/scripts/delegation/delegation-cli.ts +4 -4
  191. package/scripts/delegation/delegation-policy.ts +13 -15
  192. package/scripts/delegation/duplicate-read-guard.ts +9 -10
  193. package/scripts/delegation/fanout-cli.ts +1 -1
  194. package/scripts/delegation/fanout.ts +1 -1
  195. package/scripts/delegation/investigation-guard.ts +18 -22
  196. package/scripts/delegation/investigation-reads.ts +48 -238
  197. package/scripts/discovery/repo-discovery.ts +1 -1
  198. package/scripts/discovery/repo-map-logic.ts +1 -2
  199. package/scripts/discovery/repo-origin.ts +3 -3
  200. package/scripts/discovery/repo-party-cli.ts +2 -2
  201. package/scripts/discovery/repo-party.ts +2 -2
  202. package/scripts/doctor/doctor-consumer.ts +1 -1
  203. package/scripts/doctor/doctor-io.ts +6 -7
  204. package/scripts/doctor/doctor-logic.ts +1 -1
  205. package/scripts/doctor/doctor-ports.ts +1 -1
  206. package/scripts/doctor/doctor.ts +8 -9
  207. package/scripts/document/backlogrun-parent-read-set.ts +5 -6
  208. package/scripts/document/bash-output-cap.ts +5 -7
  209. package/scripts/document/capped-print-part.ts +1 -1
  210. package/scripts/document/capped-print.ts +1 -1
  211. package/scripts/document/document-byte-budget.ts +33 -64
  212. package/scripts/document/document-byte-check.ts +4 -4
  213. package/scripts/document/document-reachability.ts +7 -8
  214. package/scripts/document/document-read-cli.ts +2 -2
  215. package/scripts/document/document-scan.ts +26 -2
  216. package/scripts/document/document-section-cli.ts +6 -8
  217. package/scripts/document/document-section.ts +8 -12
  218. package/scripts/document/edit-files-cli.ts +3 -4
  219. package/scripts/document/entry-read-budget.ts +8 -70
  220. package/scripts/document/entry-read-set.ts +51 -34
  221. package/scripts/document/lane-child-read-set.ts +9 -9
  222. package/scripts/document/read-files-cli.ts +1 -2
  223. package/scripts/document/read-set-cli.ts +16 -19
  224. package/scripts/document/read-set-cost.ts +4 -4
  225. package/scripts/document/read-set-point-of-use.ts +28 -38
  226. package/scripts/document/read-set-pricing.ts +1 -1
  227. package/scripts/document/read-set-trim.ts +3 -3
  228. package/scripts/document/resident-budget.ts +8 -10
  229. package/scripts/epic/epic-add-body.ts +15 -18
  230. package/scripts/epic/epic-add-plan.ts +26 -28
  231. package/scripts/epic/epic-add.ts +32 -25
  232. package/scripts/epic/epic-audit-checks.ts +27 -37
  233. package/scripts/epic/epic-audit-cli.ts +21 -22
  234. package/scripts/epic/epic-audit-orphans.ts +16 -17
  235. package/scripts/epic/epic-audit-rationale.ts +10 -15
  236. package/scripts/epic/epic-audit-report.ts +2 -5
  237. package/scripts/epic/epic-audit.ts +18 -14
  238. package/scripts/epic/epic-body.ts +10 -10
  239. package/scripts/epic/epic-bundle-cli.ts +36 -34
  240. package/scripts/epic/epic-bundle-evidence.ts +5 -5
  241. package/scripts/epic/epic-bundle-gaps.ts +6 -9
  242. package/scripts/epic/epic-bundle-poll.ts +1 -1
  243. package/scripts/epic/epic-bundle-referenced.ts +11 -14
  244. package/scripts/epic/epic-bundle.ts +19 -20
  245. package/scripts/epic/epic-busy.ts +44 -21
  246. package/scripts/epic/epic-candidate-confirm.ts +15 -18
  247. package/scripts/epic/epic-chains.ts +18 -23
  248. package/scripts/epic/epic-classify.ts +11 -12
  249. package/scripts/epic/epic-cli-argv.ts +5 -6
  250. package/scripts/epic/epic-cli-remove.ts +9 -4
  251. package/scripts/epic/epic-cli.ts +38 -26
  252. package/scripts/epic/epic-close-comment.ts +14 -15
  253. package/scripts/epic/epic-close.ts +25 -29
  254. package/scripts/epic/epic-cross-repo.ts +18 -21
  255. package/scripts/epic/epic-decision.ts +14 -18
  256. package/scripts/epic/epic-fetch.ts +25 -31
  257. package/scripts/epic/epic-graph.ts +15 -17
  258. package/scripts/epic/epic-index.ts +14 -16
  259. package/scripts/epic/epic-issue.ts +9 -11
  260. package/scripts/epic/epic-label-age.ts +74 -0
  261. package/scripts/epic/epic-lane-offer.ts +35 -24
  262. package/scripts/epic/epic-nested.ts +1 -1
  263. package/scripts/epic/epic-next-read.ts +8 -8
  264. package/scripts/epic/epic-next-views.ts +12 -12
  265. package/scripts/epic/epic-next.ts +29 -33
  266. package/scripts/epic/epic-outside-blocker.ts +11 -10
  267. package/scripts/epic/epic-parse.ts +22 -24
  268. package/scripts/epic/epic-promote.ts +3 -2
  269. package/scripts/epic/epic-rank.ts +1 -1
  270. package/scripts/epic/epic-read.ts +10 -8
  271. package/scripts/epic/epic-reconcile.ts +8 -6
  272. package/scripts/epic/epic-reference.ts +5 -4
  273. package/scripts/epic/epic-relation-recheck.ts +10 -11
  274. package/scripts/epic/epic-relations.ts +9 -8
  275. package/scripts/epic/epic-remove-plan.ts +4 -5
  276. package/scripts/epic/epic-remove.ts +7 -5
  277. package/scripts/epic/epic-report.ts +18 -20
  278. package/scripts/epic/epic-run.ts +6 -5
  279. package/scripts/epic/epic-sections.ts +2 -2
  280. package/scripts/epic/epic-shape.ts +3 -3
  281. package/scripts/epic/epic-solo-stale.ts +3 -2
  282. package/scripts/epic/epic-solo.ts +8 -8
  283. package/scripts/epic/epic-triage.ts +5 -4
  284. package/scripts/epic/epic-validate.ts +8 -7
  285. package/scripts/epic/epic.ts +5 -5
  286. package/scripts/exports/unused-members-cli.ts +1 -1
  287. package/scripts/followup/followup-issue-number.ts +1 -2
  288. package/scripts/followup/git-followup-cleanup.ts +6 -7
  289. package/scripts/followup/git-followup-finish.ts +11 -13
  290. package/scripts/followup/git-followup-flush.ts +11 -7
  291. package/scripts/followup/git-followup-issue-close.ts +16 -13
  292. package/scripts/followup/git-followup-label.ts +9 -6
  293. package/scripts/followup/git-followup-merged.ts +1 -1
  294. package/scripts/followup/git-followup-pending.ts +7 -9
  295. package/scripts/followup/git-followup-stages.ts +28 -17
  296. package/scripts/followup/git-followup-workflow.ts +19 -21
  297. package/scripts/followup/git-pr-followup-checks.ts +13 -20
  298. package/scripts/followup/git-pr-followup-wrapup.ts +7 -7
  299. package/scripts/followup/git-pr-followup.ts +18 -17
  300. package/scripts/gate/core-admission.ts +162 -0
  301. package/scripts/gate/core-budget.ts +134 -91
  302. package/scripts/gate/gate-ledger.ts +114 -0
  303. package/scripts/gate/gate-log.ts +7 -9
  304. package/scripts/gate/gate-plan.ts +103 -35
  305. package/scripts/gate/gate-report.ts +39 -21
  306. package/scripts/gate/gate-skip.ts +11 -13
  307. package/scripts/gate/gate-steps.ts +5 -1
  308. package/scripts/gate/gate-tree.ts +3 -4
  309. package/scripts/gate/hook-gate-reuse.ts +9 -9
  310. package/scripts/gate/machine-capacity.ts +313 -0
  311. package/scripts/gate/pre-commit-type-check.ts +4 -4
  312. package/scripts/gate/project-checks.ts +12 -4
  313. package/scripts/gate/scoped-green.ts +11 -18
  314. package/scripts/gate/type-check-command.ts +2 -2
  315. package/scripts/gate/type-check-step.ts +4 -4
  316. package/scripts/gate/verification-gate.ts +60 -53
  317. package/scripts/gh/gh-spawn.ts +2 -2
  318. package/scripts/gh/git-ai-review-scan.ts +3 -2
  319. package/scripts/gh/git-gh-api-path.ts +10 -11
  320. package/scripts/gh/git-gh-exec.ts +43 -48
  321. package/scripts/gh/git-gh-failure.ts +6 -9
  322. package/scripts/gh/git-gh-helpers.ts +1 -1
  323. package/scripts/gh/git-gh-issue-list.ts +15 -19
  324. package/scripts/gh/git-gh-issue-read.ts +43 -60
  325. package/scripts/gh/git-gh-issue-rest.ts +14 -15
  326. package/scripts/gh/git-gh-issue-write.ts +52 -40
  327. package/scripts/gh/git-gh-issue.ts +23 -24
  328. package/scripts/gh/git-gh-pr-auto-merge.ts +3 -3
  329. package/scripts/gh/git-gh-pr-read.ts +46 -50
  330. package/scripts/gh/git-gh-pr-rest.ts +23 -26
  331. package/scripts/gh/git-gh-pr-review.ts +2 -2
  332. package/scripts/gh/git-gh-pr-rollup.ts +4 -4
  333. package/scripts/gh/git-gh-pr-snapshot.ts +8 -10
  334. package/scripts/gh/git-gh-pr.ts +16 -16
  335. package/scripts/gh/git-gh-reachability.ts +11 -12
  336. package/scripts/gh/git-gh-repo.ts +2 -3
  337. package/scripts/gh/git-gh-rest-state.ts +1 -1
  338. package/scripts/gh/git-pr-ai-review.ts +6 -5
  339. package/scripts/gh/git-pr-checks-eval.ts +28 -30
  340. package/scripts/gh/git-pr-checks-parse.ts +14 -16
  341. package/scripts/gh/git-pr-checks-watch.ts +17 -17
  342. package/scripts/gh/git-pr-checks.ts +20 -23
  343. package/scripts/gh/git-pr-coderabbit.ts +8 -6
  344. package/scripts/gh/git-pr-confirmation.ts +5 -5
  345. package/scripts/gh/git-pr-managed-config.ts +7 -9
  346. package/scripts/gh/git-pr-messages.ts +1 -1
  347. package/scripts/gh/git-pr.ts +15 -16
  348. package/scripts/gh/github-issue-url.ts +8 -9
  349. package/scripts/git/base-tree.ts +66 -0
  350. package/scripts/git/change-base.ts +42 -2
  351. package/scripts/git/changed-file-scope.ts +5 -5
  352. package/scripts/git/changed-paths.ts +1 -2
  353. package/scripts/git/constants.ts +2 -2
  354. package/scripts/git/git-branch.ts +1 -1
  355. package/scripts/git/git-closes-keyword.ts +3 -3
  356. package/scripts/git/git-command.ts +53 -41
  357. package/scripts/git/git-common-directory.ts +3 -3
  358. package/scripts/git/git-diff-reads.ts +14 -15
  359. package/scripts/git/git-error.ts +1 -1
  360. package/scripts/git/git-execa-error.ts +1 -2
  361. package/scripts/git/git-issue.ts +10 -8
  362. package/scripts/git/git-location-environment.ts +3 -4
  363. package/scripts/git/git-ls-remote.ts +6 -8
  364. package/scripts/git/git-pre-push-hook.ts +11 -10
  365. package/scripts/git/git-preflight.ts +5 -5
  366. package/scripts/git/git-push-transport.ts +2 -2
  367. package/scripts/git/git-remote-branch.ts +1 -2
  368. package/scripts/git/git-schemas.ts +16 -23
  369. package/scripts/git/git-spawn-sync.ts +1 -1
  370. package/scripts/git/git-spawn.ts +37 -14
  371. package/scripts/git/git-ssh-keepalive.ts +12 -5
  372. package/scripts/git/git-staging.ts +7 -8
  373. package/scripts/git/git-workflow.ts +1 -1
  374. package/scripts/git/git-worktree.ts +35 -27
  375. package/scripts/git/gone-branch.ts +2 -2
  376. package/scripts/git/listing-cutoff.ts +1 -2
  377. package/scripts/git/lockfile-sync.ts +65 -0
  378. package/scripts/git/main-merge-guard.ts +1 -2
  379. package/scripts/git/main-merge.ts +7 -7
  380. package/scripts/git/main-sync.ts +23 -8
  381. package/scripts/git/parse-json-array.ts +18 -23
  382. package/scripts/git/repository-lock.ts +34 -2
  383. package/scripts/git/stash/git-stash.ts +4 -5
  384. package/scripts/git/stash/stash-orphans.ts +5 -3
  385. package/scripts/git/stash/stash-pop-args.ts +1 -1
  386. package/scripts/git/stash/stash-pop-cli.ts +3 -3
  387. package/scripts/git/stash/stash-sweep-lock.ts +2 -2
  388. package/scripts/hooks/batch-guard.ts +11 -13
  389. package/scripts/hooks/check-commit-message.ts +12 -9
  390. package/scripts/hooks/codex-hook-adapter.ts +16 -10
  391. package/scripts/hooks/edited-cspell.ts +3 -4
  392. package/scripts/hooks/format-edited-cli.ts +1 -1
  393. package/scripts/hooks/format-edited-file.ts +11 -17
  394. package/scripts/hooks/format-rewrite-notice.ts +19 -17
  395. package/scripts/hooks/pre-push-unit.ts +10 -14
  396. package/scripts/hooks/pretool-guard-cli.ts +4 -4
  397. package/scripts/hooks/pretool-guard.ts +93 -18
  398. package/scripts/hooks/reserved-run.ts +2 -2
  399. package/scripts/hooks/step-zero-notice.ts +1 -1
  400. package/scripts/hooks/stop-guard.ts +21 -10
  401. package/scripts/init/basic-path-migration.ts +2 -2
  402. package/scripts/init/claude-kit-only-settings.ts +2 -2
  403. package/scripts/init/claude-plugin-config.ts +2 -2
  404. package/scripts/init/distributed-paths.ts +4 -4
  405. package/scripts/init/hook-command-rewrite.ts +3 -3
  406. package/scripts/init/hook-launch.ts +5 -5
  407. package/scripts/init/init-actions.ts +13 -0
  408. package/scripts/init/init-ai-copy.ts +11 -11
  409. package/scripts/init/init-bootstrap.ts +3 -3
  410. package/scripts/init/init-copy-content.ts +4 -4
  411. package/scripts/init/init-logic-json-merge.ts +7 -9
  412. package/scripts/init/init-logic-migrate.ts +1 -1
  413. package/scripts/init/init-logic-templates.ts +1 -1
  414. package/scripts/init/init-logic-workspace.ts +4 -4
  415. package/scripts/init/init-logic-yaml-merge.ts +2 -2
  416. package/scripts/init/init-logic.ts +19 -22
  417. package/scripts/init/init.ts +12 -8
  418. package/scripts/init/kit-base-preset.ts +1 -1
  419. package/scripts/init/kit-setup-state.ts +1 -1
  420. package/scripts/init/kit-written-paths.ts +1 -2
  421. package/scripts/init/package-manager-pin.ts +35 -0
  422. package/scripts/init/project-profile-cli.ts +1 -1
  423. package/scripts/init/project-profile.ts +3 -3
  424. package/scripts/init/session-language-environment.ts +1 -1
  425. package/scripts/init/start-exec.ts +3 -4
  426. package/scripts/init/start-plan.ts +2 -2
  427. package/scripts/init/start-setup-pr.ts +3 -2
  428. package/scripts/init/start-steps.ts +2 -2
  429. package/scripts/init/tsconfig-preset-migration.ts +1 -1
  430. package/scripts/init/vscode-tasks.ts +62 -0
  431. package/scripts/issue/baseline-measure.ts +2 -2
  432. package/scripts/issue/behavior-change-lint.ts +2 -2
  433. package/scripts/issue/defect-rate-cli.ts +6 -7
  434. package/scripts/issue/defect-rate.ts +37 -27
  435. package/scripts/issue/git-next-issues.ts +9 -8
  436. package/scripts/issue/issue-auto-ok.ts +49 -11
  437. package/scripts/issue/issue-backlinks-cli.ts +5 -5
  438. package/scripts/issue/issue-backlinks.ts +6 -6
  439. package/scripts/issue/issue-cite-cli.ts +20 -18
  440. package/scripts/issue/issue-cite.ts +18 -8
  441. package/scripts/issue/issue-closing-pr.ts +4 -4
  442. package/scripts/issue/issue-comment-cli.ts +6 -4
  443. package/scripts/issue/issue-file-cli.ts +75 -15
  444. package/scripts/issue/issue-file-fold.ts +155 -0
  445. package/scripts/issue/issue-file.ts +14 -6
  446. package/scripts/issue/issue-fold-cli.ts +14 -9
  447. package/scripts/issue/issue-fold.ts +23 -8
  448. package/scripts/issue/issue-labels.ts +46 -37
  449. package/scripts/issue/issue-lint-cli.ts +2 -2
  450. package/scripts/issue/issue-lint.ts +1 -1
  451. package/scripts/issue/issue-merged.ts +10 -4
  452. package/scripts/issue/issue-number-shape.ts +27 -0
  453. package/scripts/issue/issue-rank.ts +1 -1
  454. package/scripts/issue/issue-read-cli.ts +4 -5
  455. package/scripts/issue/issue-read.ts +4 -5
  456. package/scripts/issue/issue-reference.ts +5 -5
  457. package/scripts/issue/issue-release-cli.ts +165 -0
  458. package/scripts/issue/issue-release.ts +58 -0
  459. package/scripts/issue/issue-report-failures.ts +7 -4
  460. package/scripts/issue/issue-scout-cli.ts +11 -11
  461. package/scripts/issue/issue-scout-closed.ts +4 -4
  462. package/scripts/issue/issue-scout.ts +4 -5
  463. package/scripts/issue/issue-state-cli.ts +17 -10
  464. package/scripts/issue/issue-state.ts +12 -13
  465. package/scripts/issue/issue-wip.ts +7 -7
  466. package/scripts/issue/markdown-section.ts +3 -3
  467. package/scripts/issue/measure-rerun-cli.ts +10 -9
  468. package/scripts/issue/reproduction-measure.ts +3 -3
  469. package/scripts/issue/session-cite.ts +56 -0
  470. package/scripts/josh/agent-session-environment.ts +10 -8
  471. package/scripts/josh/cli-body.ts +2 -2
  472. package/scripts/josh/command-suggest.ts +1 -1
  473. package/scripts/josh/file-map-stamp.ts +20 -23
  474. package/scripts/josh/hook-decision.ts +24 -28
  475. package/scripts/josh/josh-command-map.ts +4 -1
  476. package/scripts/josh/josh-command-types.ts +32 -34
  477. package/scripts/josh/josh-commands-ai.ts +6 -6
  478. package/scripts/josh/josh-commands-backlog.ts +15 -3
  479. package/scripts/josh/josh-commands-clone.ts +1 -1
  480. package/scripts/josh/josh-commands-development.ts +33 -4
  481. package/scripts/josh/josh-commands-document.ts +3 -3
  482. package/scripts/josh/josh-commands-guard.ts +3 -3
  483. package/scripts/josh/josh-commands-issue.ts +11 -5
  484. package/scripts/josh/josh-commands-lane.ts +16 -5
  485. package/scripts/josh/josh-commands-lint.ts +1 -1
  486. package/scripts/josh/josh-commands-maintenance.ts +2 -2
  487. package/scripts/josh/josh-commands-run.ts +20 -6
  488. package/scripts/josh/josh-commands-split.ts +1 -2
  489. package/scripts/josh/josh-commands-versioning.ts +5 -5
  490. package/scripts/josh/josh-commands-workflow.ts +30 -22
  491. package/scripts/josh/josh-environment-file.ts +1 -1
  492. package/scripts/josh/josh-in-process.ts +3 -3
  493. package/scripts/josh/josh-logic.ts +10 -10
  494. package/scripts/josh/josh-run.ts +3 -3
  495. package/scripts/josh/josh-verdict.ts +9 -12
  496. package/scripts/josh/josh.ts +3 -3
  497. package/scripts/josh/kit-only.ts +2 -2
  498. package/scripts/josh/path-decision.ts +3 -3
  499. package/scripts/josh/platform-temporary.ts +7 -5
  500. package/scripts/josh/process-identity.ts +24 -6
  501. package/scripts/josh/process-owner.ts +4 -4
  502. package/scripts/josh/session-language-cli.ts +53 -11
  503. package/scripts/josh/session-language.ts +1 -1
  504. package/scripts/josh/stamp-file.ts +48 -29
  505. package/scripts/josh/stamp-record.ts +57 -0
  506. package/scripts/lane/lane-await.ts +35 -11
  507. package/scripts/lane/lane-cache.ts +6 -6
  508. package/scripts/lane/lane-capacity.ts +32 -17
  509. package/scripts/lane/lane-child-invocation.ts +17 -15
  510. package/scripts/lane/lane-child-marker.ts +12 -12
  511. package/scripts/lane/lane-cli.ts +20 -13
  512. package/scripts/lane/lane-close.ts +6 -6
  513. package/scripts/lane/lane-dispatch.ts +61 -72
  514. package/scripts/lane/lane-environment.ts +5 -5
  515. package/scripts/lane/lane-guard-policy.ts +7 -21
  516. package/scripts/lane/lane-handoff.ts +2 -2
  517. package/scripts/lane/lane-install.ts +9 -10
  518. package/scripts/lane/lane-launch-cli.ts +13 -8
  519. package/scripts/lane/lane-ledger.ts +73 -11
  520. package/scripts/lane/lane-leftover.ts +44 -30
  521. package/scripts/lane/lane-limit-cli.ts +160 -0
  522. package/scripts/lane/lane-limit-override.ts +74 -0
  523. package/scripts/lane/lane-load.ts +19 -68
  524. package/scripts/lane/lane-measure-cli.ts +15 -25
  525. package/scripts/lane/lane-occupancy.ts +6 -4
  526. package/scripts/lane/lane-open.ts +25 -24
  527. package/scripts/lane/lane-output.ts +4 -3
  528. package/scripts/lane/lane-paths.ts +22 -8
  529. package/scripts/lane/lane-phase.ts +33 -0
  530. package/scripts/lane/lane-reap.ts +2 -2
  531. package/scripts/lane/lane-registry.ts +27 -15
  532. package/scripts/lane/lane-relaunch.ts +9 -9
  533. package/scripts/lane/lane-report.ts +5 -4
  534. package/scripts/lane/lane-resume.ts +2 -2
  535. package/scripts/lane/lane-sampler.ts +55 -0
  536. package/scripts/lane/lane-seed.ts +7 -7
  537. package/scripts/lane/lane-stage-stats.ts +135 -0
  538. package/scripts/lane/lane-start-point.ts +8 -11
  539. package/scripts/lane/lane-stats.ts +60 -15
  540. package/scripts/lane/lane-stray.ts +140 -0
  541. package/scripts/lane/lane-vacant.ts +1 -1
  542. package/scripts/lane/openai-lane-supervisor-decision.ts +3 -7
  543. package/scripts/lane/openai-lane-supervisor-owner.ts +3 -9
  544. package/scripts/lane/openai-review-broker.ts +2 -4
  545. package/scripts/lib/ancestor-directories.ts +1 -1
  546. package/scripts/lib/bounded-pool.ts +2 -2
  547. package/scripts/lib/buffered-process.ts +4 -6
  548. package/scripts/lib/caddy-logs.sh +0 -0
  549. package/scripts/lib/cli-flags.ts +39 -6
  550. package/scripts/lib/error-message.ts +1 -1
  551. package/scripts/lib/json-value.ts +17 -3
  552. package/scripts/lib/poll.ts +1 -1
  553. package/scripts/lib/status-icons.ts +3 -3
  554. package/scripts/lib/timed-fetch.ts +1 -1
  555. package/scripts/lib/timeouts.ts +1 -1
  556. package/scripts/lines/bytes-command.ts +3 -4
  557. package/scripts/lines/effective-limit.ts +25 -12
  558. package/scripts/lines/line-budget.ts +47 -55
  559. package/scripts/lines/line-targets.ts +6 -2
  560. package/scripts/lines/lines-command.ts +3 -3
  561. package/scripts/lint/cspell-cached.ts +1 -1
  562. package/scripts/lint/cycle-recheck.ts +122 -0
  563. package/scripts/lint/format.ts +1 -2
  564. package/scripts/lint/lint-parallel.ts +34 -19
  565. package/scripts/lint/lint-related-scope.ts +25 -15
  566. package/scripts/lint/lint-related.ts +6 -7
  567. package/scripts/managed-marker/index.ts +1 -1
  568. package/scripts/managed-marker/managed-marker-logic.ts +1 -2
  569. package/scripts/notify/git-notify.ts +9 -7
  570. package/scripts/notify/telegram-notify.ts +53 -37
  571. package/scripts/notify/telegram-test-logic.ts +3 -3
  572. package/scripts/notify/telegram-test.ts +45 -30
  573. package/scripts/observations/observation-ledger-home.ts +14 -8
  574. package/scripts/observations/observation-ledger-line.ts +3 -2
  575. package/scripts/observations/observation-ledger-migrate.ts +3 -4
  576. package/scripts/observations/observation-ledger-prepare.ts +4 -4
  577. package/scripts/observations/observation-ledger.ts +14 -15
  578. package/scripts/observations/observation-record-cli.ts +83 -0
  579. package/scripts/observations/observation-record.ts +91 -0
  580. package/scripts/observations/observations-flush-cli.ts +1 -1
  581. package/scripts/observations/observations-flush-landing.ts +7 -6
  582. package/scripts/observations/observations-flush.ts +26 -27
  583. package/scripts/overrides/overrides-check.ts +18 -8
  584. package/scripts/package/package-scout-cli.ts +1 -1
  585. package/scripts/package/package-scout-format.ts +2 -2
  586. package/scripts/package/package-scout.ts +1 -1
  587. package/scripts/propagate/propagate-git-failure.ts +1 -1
  588. package/scripts/propagate/propagate-git.ts +7 -7
  589. package/scripts/propagate/propagate-plan.ts +2 -2
  590. package/scripts/propagate/propagate-publish.ts +2 -3
  591. package/scripts/propagate/propagate-run.ts +5 -7
  592. package/scripts/propagate/propagate-select.ts +1 -1
  593. package/scripts/propagate/propagate-steps.ts +19 -20
  594. package/scripts/propagate/propagate-targets.ts +6 -10
  595. package/scripts/propagate/propagate.ts +5 -5
  596. package/scripts/refactor/import-graph.ts +1 -1
  597. package/scripts/refactor/refactor-lint.ts +4 -10
  598. package/scripts/refactor/refactor-scan-cli.ts +1 -1
  599. package/scripts/refactor/refactor-scan.ts +2 -2
  600. package/scripts/refactor/refactor-targets.ts +1 -1
  601. package/scripts/release/github-release-cli.ts +25 -3
  602. package/scripts/release/github-release-environment.ts +1 -0
  603. package/scripts/release/github-release-runs.ts +115 -0
  604. package/scripts/release/github-release.ts +13 -67
  605. package/scripts/release/release-cli.ts +21 -4
  606. package/scripts/release/release-history.ts +6 -10
  607. package/scripts/release/release-plan.ts +3 -3
  608. package/scripts/release/release-progress.ts +3 -4
  609. package/scripts/release/release-publish.ts +8 -9
  610. package/scripts/release/release-scope-cli.ts +8 -10
  611. package/scripts/release/release-tag.ts +6 -8
  612. package/scripts/release/release-worktree.ts +5 -5
  613. package/scripts/repo/auto-merge-setting-logic.ts +7 -9
  614. package/scripts/repo/auto-merge-setting.ts +1 -1
  615. package/scripts/repo/repo-setting.ts +4 -4
  616. package/scripts/repo/repository-labels.ts +1 -1
  617. package/scripts/repo/required-checks-logic.ts +3 -3
  618. package/scripts/repo/required-checks-report.ts +1 -1
  619. package/scripts/repo/ruleset-check-cli.ts +1 -1
  620. package/scripts/repo/ruleset-check.ts +1 -1
  621. package/scripts/report/report-format-reference.ts +26 -0
  622. package/scripts/report/report-lint-cli.ts +2 -2
  623. package/scripts/report/report-lint.ts +16 -2
  624. package/scripts/review/disposition-cli.ts +2 -2
  625. package/scripts/review/disposition-logic.ts +1 -1
  626. package/scripts/review/live-evidence.ts +9 -6
  627. package/scripts/review/review-attest-cli.ts +1 -2
  628. package/scripts/review/review-attest.ts +3 -3
  629. package/scripts/review/review-brief-cli.ts +19 -20
  630. package/scripts/review/review-brief.ts +29 -32
  631. package/scripts/review/review-checkout.ts +2 -2
  632. package/scripts/review/review-diff-parts.ts +3 -5
  633. package/scripts/review/review-diff-write.ts +1 -1
  634. package/scripts/review/review-finding-ledger.ts +7 -4
  635. package/scripts/review/review-findings-cli.ts +2 -2
  636. package/scripts/review/review-level.ts +4 -7
  637. package/scripts/review/review-record-cli.ts +73 -16
  638. package/scripts/review/review-record.ts +5 -4
  639. package/scripts/review/review-round2-cli.ts +2 -3
  640. package/scripts/review/review-round2.ts +13 -21
  641. package/scripts/review/review-stamps.ts +9 -71
  642. package/scripts/review/review-tree.ts +4 -5
  643. package/scripts/rules/bash-triggers.ts +4 -4
  644. package/scripts/rules/decision-oracle-batch.ts +5 -6
  645. package/scripts/rules/decision-oracle-stage.ts +1 -1
  646. package/scripts/rules/decision-oracle-tokens.ts +1 -2
  647. package/scripts/rules/decision-oracle.ts +2 -2
  648. package/scripts/rules/delivered-rules.ts +61 -406
  649. package/scripts/rules/destructive-command.ts +2 -2
  650. package/scripts/rules/direct-filing.ts +4 -4
  651. package/scripts/rules/direct-pr-create.ts +2 -2
  652. package/scripts/rules/early-heartbeat.ts +15 -19
  653. package/scripts/rules/file-body.ts +5 -6
  654. package/scripts/rules/filing-cap.ts +6 -7
  655. package/scripts/rules/filing-offer.ts +1 -1
  656. package/scripts/rules/firing-point.ts +6 -6
  657. package/scripts/rules/gh-api.ts +2 -2
  658. package/scripts/rules/git-argv.ts +3 -3
  659. package/scripts/rules/git-force.ts +2 -2
  660. package/scripts/rules/hook-context-line.ts +31 -0
  661. package/scripts/rules/implementation-cut-verdict.ts +5 -8
  662. package/scripts/rules/implementation-cut.ts +35 -32
  663. package/scripts/rules/index-guard.ts +2 -2
  664. package/scripts/rules/issue-citation.ts +7 -7
  665. package/scripts/rules/issue-comments.ts +21 -13
  666. package/scripts/rules/josh-git-bare.ts +2 -2
  667. package/scripts/rules/lane-background.ts +14 -16
  668. package/scripts/rules/lane-carry-conflict.ts +41 -5
  669. package/scripts/rules/lane-interactive-ask.ts +6 -9
  670. package/scripts/rules/lane-park.ts +12 -16
  671. package/scripts/rules/lane-split-park.ts +1 -2
  672. package/scripts/rules/lane-switch-main.ts +10 -13
  673. package/scripts/rules/last-prompt.ts +1 -1
  674. package/scripts/rules/oracle-consulted.ts +5 -5
  675. package/scripts/rules/oracle-firing.ts +6 -9
  676. package/scripts/rules/oracle-list-cli.ts +2 -2
  677. package/scripts/rules/permission-guards.ts +2 -2
  678. package/scripts/rules/piped-verification.ts +79 -9
  679. package/scripts/rules/poll-loop.ts +9 -11
  680. package/scripts/rules/pre-gate-cut.ts +33 -30
  681. package/scripts/rules/prior-comment-read.ts +3 -3
  682. package/scripts/rules/protected-files.ts +25 -13
  683. package/scripts/rules/raw-field-body.ts +3 -4
  684. package/scripts/rules/reply-language.ts +1 -1
  685. package/scripts/rules/rule-body-guard.ts +10 -12
  686. package/scripts/rules/rule-guard.ts +1 -1
  687. package/scripts/rules/rule-list.ts +51 -0
  688. package/scripts/rules/rule-registry-rows.ts +282 -0
  689. package/scripts/rules/rule-registry.ts +109 -0
  690. package/scripts/rules/rule-value-cache.ts +2 -2
  691. package/scripts/rules/rule-value-cli.ts +6 -4
  692. package/scripts/rules/rule-value.ts +61 -22
  693. package/scripts/rules/run-tail-rule.ts +11 -15
  694. package/scripts/rules/shell-body-trigger.ts +7 -7
  695. package/scripts/rules/shell-segments.ts +2 -4
  696. package/scripts/rules/stop-rules.ts +54 -41
  697. package/scripts/rules/tail-commands.ts +1 -1
  698. package/scripts/rules/test-declared-commit.ts +2 -2
  699. package/scripts/rules/third-party-write.ts +3 -3
  700. package/scripts/rules/worktree-guard.ts +12 -5
  701. package/scripts/run/add/run-add-cli.ts +165 -0
  702. package/scripts/run/add/run-add.ts +124 -0
  703. package/scripts/run/board/run-board-cli.ts +207 -0
  704. package/scripts/run/board/run-board-closed.ts +95 -0
  705. package/scripts/run/board/run-board-every.ts +60 -0
  706. package/scripts/run/board/run-board-fetch.ts +38 -0
  707. package/scripts/run/board/run-board-fit.ts +219 -0
  708. package/scripts/run/board/run-board-github.ts +162 -0
  709. package/scripts/run/board/run-board-header.ts +275 -0
  710. package/scripts/run/board/run-board-kind.ts +35 -0
  711. package/scripts/run/board/run-board-labels.ts +299 -0
  712. package/scripts/run/board/run-board-layout.ts +222 -0
  713. package/scripts/run/board/run-board-link.ts +31 -0
  714. package/scripts/run/board/run-board-machine.ts +198 -0
  715. package/scripts/run/board/run-board-notes.ts +103 -0
  716. package/scripts/run/board/run-board-phase.ts +136 -0
  717. package/scripts/run/board/run-board-plan.ts +129 -0
  718. package/scripts/run/board/run-board-read.ts +62 -0
  719. package/scripts/run/board/run-board-render-legend.ts +82 -0
  720. package/scripts/run/board/run-board-render-notes.ts +77 -0
  721. package/scripts/run/board/run-board-render-slot.ts +50 -0
  722. package/scripts/run/board/run-board-render.ts +407 -0
  723. package/scripts/run/board/run-board-scope.ts +17 -0
  724. package/scripts/run/board/run-board-screen.ts +43 -0
  725. package/scripts/run/board/run-board-span.ts +66 -0
  726. package/scripts/run/board/run-board-spin.ts +115 -0
  727. package/scripts/run/board/run-board-state.ts +113 -0
  728. package/scripts/run/board/run-board-status.ts +279 -0
  729. package/scripts/run/board/run-board-tick.ts +210 -0
  730. package/scripts/run/board/run-board-track.ts +22 -0
  731. package/scripts/run/board/run-board-usage-read.ts +255 -0
  732. package/scripts/run/board/run-board-usage-rusage.ts +124 -0
  733. package/scripts/run/board/run-board-usage-text.ts +80 -0
  734. package/scripts/run/board/run-board-usage.ts +165 -0
  735. package/scripts/run/carry/run-carry-added.ts +62 -0
  736. package/scripts/run/carry/run-carry-args.ts +25 -22
  737. package/scripts/run/carry/run-carry-change.ts +1 -1
  738. package/scripts/run/carry/run-carry-cli.ts +71 -48
  739. package/scripts/run/carry/run-carry-conversation.ts +6 -7
  740. package/scripts/run/carry/run-carry-ended.ts +85 -0
  741. package/scripts/run/carry/run-carry-reclaim.ts +1 -1
  742. package/scripts/run/carry/run-carry-stash.ts +3 -2
  743. package/scripts/run/carry/run-carry-streak.ts +8 -10
  744. package/scripts/run/carry/run-carry.ts +85 -89
  745. package/scripts/run/cut/run-cut-args.ts +7 -7
  746. package/scripts/run/cut/run-cut-cli.ts +68 -37
  747. package/scripts/run/cut/run-cut-handoff.ts +15 -15
  748. package/scripts/run/cut/run-cut-report.ts +37 -16
  749. package/scripts/run/cut/run-cut.ts +63 -77
  750. package/scripts/run/detached-launch.ts +35 -50
  751. package/scripts/run/entry/run-entry-cli.ts +48 -27
  752. package/scripts/run/entry/run-entry-stop.ts +7 -9
  753. package/scripts/run/entry/run-entry.ts +5 -6
  754. package/scripts/run/event/run-event-cli.ts +5 -6
  755. package/scripts/run/event/run-event-filed.ts +69 -0
  756. package/scripts/run/event/run-event-follow.ts +3 -3
  757. package/scripts/run/event/run-event-plan.ts +38 -0
  758. package/scripts/run/event/run-event-render.ts +10 -4
  759. package/scripts/run/event/run-event-scope.ts +47 -18
  760. package/scripts/run/event/run-event-stream-emit.ts +64 -11
  761. package/scripts/run/event/run-event-stream.ts +172 -43
  762. package/scripts/run/event/run-event-watch.ts +4 -6
  763. package/scripts/run/hold/run-hold-cli.ts +65 -62
  764. package/scripts/run/hold/run-hold.ts +88 -46
  765. package/scripts/run/merge/run-merge-cli.ts +116 -77
  766. package/scripts/run/merge/run-merge-collect.ts +107 -0
  767. package/scripts/run/merge/run-merge-steps.ts +112 -65
  768. package/scripts/run/merge/run-merge-token.ts +30 -0
  769. package/scripts/run/merge/run-merge.ts +31 -22
  770. package/scripts/run/progress/run-progress-args.ts +4 -4
  771. package/scripts/run/progress/run-progress-cli.ts +39 -50
  772. package/scripts/run/progress/run-progress-clock.ts +25 -32
  773. package/scripts/run/progress/run-progress-config.ts +6 -9
  774. package/scripts/run/progress/run-progress-read.ts +9 -10
  775. package/scripts/run/progress/run-progress.ts +48 -53
  776. package/scripts/run/review/run-review-cli.ts +6 -6
  777. package/scripts/run/review/run-review-steps.ts +6 -6
  778. package/scripts/run/review/run-review.ts +9 -11
  779. package/scripts/run/run-cli-fault.ts +29 -0
  780. package/scripts/run/run-ending-cli.ts +3 -3
  781. package/scripts/run/run-ending.ts +10 -14
  782. package/scripts/run/run-halfrun-resume.ts +6 -8
  783. package/scripts/run/run-headless.ts +25 -12
  784. package/scripts/run/run-invocation.ts +17 -22
  785. package/scripts/run/run-label.ts +7 -5
  786. package/scripts/run/run-liveness-cli.ts +19 -6
  787. package/scripts/run/run-liveness.ts +27 -38
  788. package/scripts/run/run-next-cli.ts +5 -9
  789. package/scripts/run/run-next.ts +4 -5
  790. package/scripts/run/run-parent-cut-hook.ts +10 -12
  791. package/scripts/run/run-preflight.ts +25 -29
  792. package/scripts/run/run-prep-cli.ts +17 -13
  793. package/scripts/run/run-prep-locate.ts +4 -5
  794. package/scripts/run/run-prep.ts +7 -10
  795. package/scripts/run/run-prrun-resume.ts +2 -2
  796. package/scripts/run/run-report-cli.ts +4 -4
  797. package/scripts/run/run-report.ts +9 -14
  798. package/scripts/run/run-retrospective.ts +3 -3
  799. package/scripts/run/run-section.ts +42 -0
  800. package/scripts/run/run-stage-read.ts +2 -2
  801. package/scripts/run/run-stage.ts +6 -4
  802. package/scripts/run/run-status-cli.ts +7 -5
  803. package/scripts/run/run-status.ts +6 -7
  804. package/scripts/run/run-step-cli.ts +13 -15
  805. package/scripts/run/run-step.ts +62 -48
  806. package/scripts/run/run-stop-notify.ts +7 -8
  807. package/scripts/run/run-stranded-cli.ts +1 -1
  808. package/scripts/run/run-stranded-detect.ts +4 -4
  809. package/scripts/run/run-stranded.ts +11 -13
  810. package/scripts/run/run-tail-cli.ts +15 -16
  811. package/scripts/run/run-tail.ts +14 -33
  812. package/scripts/run/run-watcher-guard-cli.ts +3 -4
  813. package/scripts/run/run-watcher-guard.ts +11 -12
  814. package/scripts/run/run-watcher-hook.ts +6 -12
  815. package/scripts/run/ship/run-ship-cli.ts +67 -33
  816. package/scripts/run/ship/run-ship-detach.ts +15 -13
  817. package/scripts/run/ship/run-ship-lock.ts +1 -1
  818. package/scripts/run/ship/run-ship-next.ts +7 -8
  819. package/scripts/run/ship/run-ship-pre-detach.ts +27 -11
  820. package/scripts/run/ship/run-ship-preflight.ts +10 -11
  821. package/scripts/run/ship/run-ship-probe.ts +4 -4
  822. package/scripts/run/ship/run-ship-return.ts +1 -1
  823. package/scripts/run/ship/run-ship-review-steps.ts +43 -24
  824. package/scripts/run/ship/run-ship-review.ts +12 -14
  825. package/scripts/run/ship/run-ship-scoped.ts +15 -6
  826. package/scripts/run/ship/run-ship-stage.ts +80 -26
  827. package/scripts/run/ship/run-ship-steps.ts +26 -16
  828. package/scripts/run/ship/run-ship-stop-text.ts +4 -2
  829. package/scripts/run/ship/run-ship-sync.ts +9 -8
  830. package/scripts/run/ship/run-ship.ts +17 -32
  831. package/scripts/run/tidy/run-tidy-cli.ts +9 -5
  832. package/scripts/run/tidy/run-tidy-lanes.ts +18 -7
  833. package/scripts/run/tidy/run-tidy-stashes.ts +8 -8
  834. package/scripts/run/tidy/run-tidy.ts +4 -3
  835. package/scripts/run/wake/run-wake-cli.ts +27 -33
  836. package/scripts/run/wake/run-wake-describe.ts +76 -29
  837. package/scripts/run/wake/run-wake-driver.ts +14 -14
  838. package/scripts/run/wake/run-wake-handoff.ts +6 -6
  839. package/scripts/run/wake/run-wake-loop.ts +13 -21
  840. package/scripts/run/wake/run-wake-restart.ts +4 -5
  841. package/scripts/run/wake/run-wake-session.ts +23 -27
  842. package/scripts/run/wake/run-wake.ts +57 -328
  843. package/scripts/safe-chain/ci-installer-pin.ts +3 -3
  844. package/scripts/safe-chain/pack-hook.ts +2 -2
  845. package/scripts/safe-chain/preinstall-command.ts +2 -2
  846. package/scripts/security/security-audit-logic.ts +1 -1
  847. package/scripts/security/security-audit-provision-logic.ts +1 -1
  848. package/scripts/security/security-audit-provision.ts +2 -2
  849. package/scripts/security/security-audit.ts +5 -5
  850. package/scripts/security/security-updates-logic.ts +2 -3
  851. package/scripts/security/security-updates.ts +2 -4
  852. package/scripts/self-sync-guard/index.ts +1 -1
  853. package/scripts/self-sync-guard/self-sync-guard-logic.ts +2 -2
  854. package/scripts/self-sync-guard/self-sync-refusal.ts +1 -1
  855. package/scripts/sonar/sonar-hotspots-cli.ts +1 -1
  856. package/scripts/sonar/sonar-hotspots.ts +1 -1
  857. package/scripts/sonar/sonar-new-code-cli.ts +1 -1
  858. package/scripts/sonar/sonar-new-code.ts +1 -1
  859. package/scripts/sonar/sonar-project.ts +1 -1
  860. package/scripts/split/split-assess-cli.ts +1 -1
  861. package/scripts/split/split-assess.ts +3 -3
  862. package/scripts/sync/directory-copy-guard.ts +2 -3
  863. package/scripts/sync/managed-config-scope-cli.ts +1 -2
  864. package/scripts/sync/managed-config-scope.ts +4 -4
  865. package/scripts/sync/plugin-skill-directories.ts +2 -2
  866. package/scripts/sync/reconcile-templates.ts +17 -8
  867. package/scripts/sync/removed-skill-manifest.ts +2 -3
  868. package/scripts/sync/sync-ai-files.ts +7 -7
  869. package/scripts/sync/sync-configs.ts +30 -3
  870. package/scripts/sync/sync-hook-safety.ts +2 -2
  871. package/scripts/sync/sync.ts +23 -10
  872. package/scripts/sync/synced-paths.ts +2 -1
  873. package/scripts/sync/workflow-pin-logic.ts +1 -1
  874. package/scripts/test/test-declared-changed.ts +4 -4
  875. package/scripts/test/test-declared-logic.ts +2 -3
  876. package/scripts/test/test-declared-match.ts +25 -4
  877. package/scripts/test/test-declared.ts +26 -9
  878. package/scripts/test/test-red-commit.ts +3 -2
  879. package/scripts/test/test-red-logic.ts +7 -14
  880. package/scripts/test/test-red.ts +12 -47
  881. package/scripts/test/test-related-scope.ts +2 -3
  882. package/scripts/test/test-related.ts +3 -3
  883. package/scripts/test/test-type-logic.ts +1 -2
  884. package/scripts/test/test-unit-guard.ts +13 -17
  885. package/scripts/test/unit-worker-share.ts +7 -8
  886. package/scripts/time-runtime/time-agent-bundles.ts +2 -4
  887. package/scripts/time-runtime/time-background.ts +17 -21
  888. package/scripts/time-runtime/time-batch-guard.ts +67 -342
  889. package/scripts/time-runtime/time-bundle-call.ts +26 -28
  890. package/scripts/time-runtime/time-bundles.ts +11 -12
  891. package/scripts/time-runtime/time-call-identity.ts +1 -1
  892. package/scripts/time-runtime/time-command-key.ts +2 -2
  893. package/scripts/time-runtime/time-density-hook.ts +8 -11
  894. package/scripts/time-runtime/time-density.ts +5 -5
  895. package/scripts/time-runtime/time-followup-stage.ts +7 -7
  896. package/scripts/time-runtime/time-format.ts +5 -5
  897. package/scripts/time-runtime/time-hook-transcript.ts +3 -3
  898. package/scripts/time-runtime/time-instant.ts +1 -1
  899. package/scripts/time-runtime/time-markers.ts +15 -19
  900. package/scripts/time-runtime/time-phase-names.ts +3 -3
  901. package/scripts/time-runtime/time-reported-failure.ts +15 -19
  902. package/scripts/time-runtime/time-round-trips.ts +20 -23
  903. package/scripts/time-runtime/time-shell.ts +8 -8
  904. package/scripts/time-runtime/time-single-check.ts +1 -2
  905. package/scripts/time-runtime/time-spans.ts +35 -40
  906. package/scripts/time-runtime/time-tool-call.ts +15 -16
  907. package/scripts/time-runtime/time-transcript-line.ts +53 -34
  908. package/scripts/time-runtime/time-writes.ts +5 -5
  909. package/scripts/ui/ui-routes-cli.ts +1 -2
  910. package/scripts/ui/ui-routes.ts +1 -2
  911. package/scripts/version/bump-version.ts +1 -1
  912. package/scripts/version/fresh-metadata-cache.ts +2 -2
  913. package/scripts/version/latest-corepack.ts +129 -98
  914. package/scripts/version/latest-lane-guard.ts +1 -1
  915. package/scripts/version/latest-scope-cli.ts +2 -2
  916. package/scripts/version/latest-stamp.ts +1 -2
  917. package/scripts/version/latest-update.ts +2 -2
  918. package/scripts/version/npm-registry.ts +2 -2
  919. package/scripts/version/package-manager-version.ts +18 -0
  920. package/scripts/version/publishable-range-check.ts +2 -1
  921. package/scripts/version/publishable-range.ts +1 -1
  922. package/scripts/version/release-age.ts +11 -11
  923. package/scripts/version/release-hold.ts +2 -2
  924. package/scripts/version/safe-chain-version-update.ts +3 -3
  925. package/scripts/version/version-check-logic.ts +2 -3
  926. package/scripts/version/version-check.ts +1 -2
  927. package/scripts/version/version-command-config.ts +2 -2
  928. package/scripts/version/version-commands.ts +3 -3
  929. package/scripts/version/version-remote.ts +4 -4
  930. package/scripts/version/version-targets.ts +2 -2
  931. package/templates/gitignore +7 -0
  932. package/templates/workflows/github-release.yml +4 -0
  933. package/dist/hooks/chunk-NV2JRZZO.js +0 -6385
  934. package/dist/hooks/chunk-RKUAD3I6.js +0 -90
  935. package/dist/hooks/chunk-WPALEIRX.js +0 -18
  936. package/scripts/backlog/backlog-restructure.ts +0 -152
  937. package/scripts/rules/issue-fold-rule.ts +0 -72
  938. package/scripts/rules/wip-cap.ts +0 -63
  939. package/scripts/run/run-issue-number.ts +0 -19
@@ -4,8 +4,9 @@ import { json_value } from '#scripts/lib/json-value'
4
4
  import { run_carry } from '#scripts/run/carry/run-carry'
5
5
  import { z } from 'zod'
6
6
 
7
- // The measurement ledger the lane limit is tuned against (joshuafolkken/kit#3355): one JSON line per
8
- // lane merge, per finished `josh gate`, and per machine-load sample, read back by `josh lane:stats`.
7
+ // The measurement ledger the lane limit is tuned against: one JSON line per
8
+ // lane merge, per finished `josh gate`, per machine-load sample, per lane dispatch and per finished
9
+ // `josh ship` stage, read back by `josh lane:stats`.
9
10
  //
10
11
  // **Its own file rather than the run's event stream.** The stream is capped at 500 events and is
11
12
  // rewritten whole on every append, which is right for "where is the run" and wrong for a measurement
@@ -20,13 +21,21 @@ import { z } from 'zod'
20
21
  const LEDGER_PREFIX = 'josh-lane-ledger-'
21
22
  const LEDGER_SUFFIX = '.jsonl'
22
23
  const LINE_SEPARATOR = '\n'
24
+ // `followup`'s wait for CI — a stage of a lane's run that no `josh ship` stage is the whole of.
25
+ const CI_WAIT_STAGE = 'ci-wait'
23
26
  const LEDGER_FILE_MODE = 0o600
24
27
  // The flags `detached-launch.ts` appends its log with, for the same deterministic shared-temp path.
25
28
  const { O_APPEND, O_CREAT, O_NOFOLLOW, O_WRONLY } = constants
26
29
  // eslint-disable-next-line no-bitwise -- POSIX open flags are a bit field; `||` here would be a bug
27
30
  const APPEND_FLAGS = O_WRONLY | O_APPEND | O_CREAT | O_NOFOLLOW
28
31
 
29
- const KIND = { MERGE: 'merge', GATE: 'gate', LOAD: 'load' } as const
32
+ const KIND = {
33
+ MERGE: 'merge',
34
+ GATE: 'gate',
35
+ LOAD: 'load',
36
+ DISPATCH: 'dispatch',
37
+ STAGE: 'stage',
38
+ } as const
30
39
 
31
40
  const merge_schema = z.object({ kind: z.literal(KIND.MERGE), at: z.string(), issue: z.number() })
32
41
  const gate_schema = z.object({
@@ -34,23 +43,59 @@ const gate_schema = z.object({
34
43
  at: z.string(),
35
44
  elapsed_ms: z.number(),
36
45
  is_passed: z.boolean(),
46
+ // The unit suite's own duration, present when this gate ran it — the one
47
+ // record of a full vitest run `josh metrics` reads, so the suite is never timed twice.
48
+ unit_ms: z.number().optional(),
49
+ // The whole cores busy outside this gate, beyond the machine's baseline, at its start or its end —
50
+ // whichever was higher. Absent when the machine could not be read.
51
+ external_cores: z.number().optional(),
37
52
  })
38
- // `swap_mb` and `lanes` are optional because either read can fail on its own — a platform with no
39
- // swap reading, a `git worktree` call that did not answer — and a sample is still worth its load.
53
+ // `available_mb`, `swapped_mb` and `lanes` are optional because each read can fail on its own — a
54
+ // platform with no memory reading, a `git worktree` call that did not answer — and a sample is still
55
+ // worth its load. `swapped_mb` is `machine_capacity`'s counter, every page swapped since boot.
56
+ // Both memory fields were renamed with their meaning (joshuafolkken/kit#3593): an older row's
57
+ // `free_mb` / `swap_mb` are stripped on read, so the two measurements never share a column.
40
58
  const load_schema = z.object({
41
59
  kind: z.literal(KIND.LOAD),
42
60
  at: z.string(),
43
61
  load: z.number(),
44
- free_mb: z.number(),
45
- swap_mb: z.number().optional(),
62
+ available_mb: z.number().optional(),
63
+ swapped_mb: z.number().optional(),
46
64
  lanes: z.number().optional(),
47
65
  })
48
- const entry_schema = z.discriminatedUnion('kind', [merge_schema, gate_schema, load_schema])
66
+ // A lane child started on `issue` — the instant its implementation is timed from.
67
+ const dispatch_schema = z.object({
68
+ kind: z.literal(KIND.DISPATCH),
69
+ at: z.string(),
70
+ issue: z.number(),
71
+ })
72
+ // One finished stage of a lane's run, passed or failed: `at` is its end and `elapsed_ms` its length, so
73
+ // its start is read from the two. `issue` is absent where the writer does not hold one — `followup`'s
74
+ // CI wait, which is timed on a path that fails before the issue is known.
75
+ const stage_schema = z.object({
76
+ kind: z.literal(KIND.STAGE),
77
+ at: z.string(),
78
+ stage: z.string(),
79
+ elapsed_ms: z.number(),
80
+ issue: z.number().optional(),
81
+ })
82
+ const entry_schema = z.discriminatedUnion('kind', [
83
+ merge_schema,
84
+ gate_schema,
85
+ load_schema,
86
+ dispatch_schema,
87
+ stage_schema,
88
+ ])
49
89
 
50
90
  type LedgerEntry = z.infer<typeof entry_schema>
51
91
  type MergeEntry = z.infer<typeof merge_schema>
52
92
  type GateEntry = z.infer<typeof gate_schema>
53
93
  type LoadEntry = z.infer<typeof load_schema>
94
+ type DispatchEntry = z.infer<typeof dispatch_schema>
95
+ type StageEntry = z.infer<typeof stage_schema>
96
+ // What a finished gate reports; the ledger stamps the kind and the time.
97
+ type GateRecord = Omit<GateEntry, 'kind' | 'at'>
98
+ type StageRecord = Omit<StageEntry, 'kind' | 'at'>
54
99
 
55
100
  function target_of(repository: string): string {
56
101
  return stamp_file.stamp_path(LEDGER_PREFIX, repository, LEDGER_SUFFIX)
@@ -59,7 +104,13 @@ function target_of(repository: string): string {
59
104
  // The ledger of the repository this checkout belongs to, or `undefined` outside one. `git rev-parse`
60
105
  // rejects outside a repository, and `josh gate` resolves this before it runs a check, so the rejection
61
106
  // is read as "no ledger" rather than allowed to fail the gate it would only have measured.
107
+ //
108
+ // **A test run has no ledger either.** The writers sit on paths dozens of suites exercise — a ship
109
+ // stage, a dispatch, a `followup` — and one suite that forgot to mock this module would append its
110
+ // fixture durations to the real measurement; a test that writes passes its own path instead.
62
111
  async function target(): Promise<string | undefined> {
112
+ if (process.env['VITEST'] !== undefined) return undefined
113
+
63
114
  try {
64
115
  const repository = await run_carry.repository_directory()
65
116
 
@@ -101,14 +152,22 @@ function now_iso(): string {
101
152
  }
102
153
 
103
154
  // One finished `josh gate`, whether it passed or not — a failing gate cost the lane its time as well.
104
- async function record_gate(path: string, elapsed_ms: number, is_passed: boolean): Promise<void> {
105
- await record({ kind: KIND.GATE, at: now_iso(), elapsed_ms, is_passed }, path)
155
+ async function record_gate(path: string, gate: GateRecord): Promise<void> {
156
+ await record({ kind: KIND.GATE, at: now_iso(), ...gate }, path)
106
157
  }
107
158
 
108
159
  async function record_merge(issue: number): Promise<void> {
109
160
  await record({ kind: KIND.MERGE, at: now_iso(), issue })
110
161
  }
111
162
 
163
+ async function record_dispatch(issue: number, path?: string): Promise<void> {
164
+ await record({ kind: KIND.DISPATCH, at: now_iso(), issue }, path)
165
+ }
166
+
167
+ async function record_stage(stage: StageRecord, path?: string): Promise<void> {
168
+ await record({ kind: KIND.STAGE, at: now_iso(), ...stage }, path)
169
+ }
170
+
112
171
  function parse_line(line: string): LedgerEntry | undefined {
113
172
  return entry_schema.safeParse(json_value.parse_or_undefined(line)).data
114
173
  }
@@ -131,15 +190,18 @@ function read_entries(path: string): ReadonlyArray<LedgerEntry> {
131
190
  }
132
191
 
133
192
  const lane_ledger = {
193
+ CI_WAIT_STAGE,
134
194
  KIND,
135
195
  append,
136
196
  read_entries,
137
197
  record,
198
+ record_dispatch,
138
199
  record_gate,
139
200
  record_merge,
201
+ record_stage,
140
202
  target,
141
203
  target_of,
142
204
  }
143
205
 
144
- export type { GateEntry, LedgerEntry, LoadEntry, MergeEntry }
206
+ export type { DispatchEntry, GateEntry, LedgerEntry, LoadEntry, MergeEntry, StageEntry }
145
207
  export { lane_ledger }
@@ -1,9 +1,11 @@
1
1
  import { createHash } from 'node:crypto'
2
2
  import { existsSync, lstatSync, readdirSync, readFileSync, readlinkSync, rmSync } from 'node:fs'
3
3
  import path from 'node:path'
4
+ import { ENV_FILE_NAME } from '#ports'
4
5
  import { git_spawn } from '#scripts/git/git-spawn'
6
+ import { IGNORED_CACHE_FILES } from '#scripts/josh/josh-command-types'
5
7
 
6
- // A lane directory git no longer registers as a work tree (joshuafolkken/kit#2857).
8
+ // A lane directory git no longer registers as a work tree.
7
9
  //
8
10
  // **Nothing else can see it.** `lane:list` and `lane:prune` read `git worktree list`, so a directory
9
11
  // whose registration is gone is invisible to both, and `git worktree add` refuses its path for good —
@@ -11,31 +13,38 @@ import { git_spawn } from '#scripts/git/git-spawn'
11
13
  // here before it adds the tree.
12
14
  //
13
15
  // **The test for removing it is that removing it loses nothing**, not a list of names. Every file in
14
- // it has to be one the repository already holds with the same content, so it is a checkout git would
15
- // write again; the one exception is the `.git` file, a pointer to the registration that is gone. A
16
- // list of generated names would break the next time a file is generated, and would delete whatever
17
- // shares one of those names.
18
-
19
- // `git ls-tree -r -z`: `<mode> <type> <object>\t<path>`, entries separated by NUL — the `-z` form
20
- // leaves a path with an unusual character unquoted, so it can be compared to the path on disk.
21
- const TREE_ENTRY_PATTERN = /^\d+ blob (?<object>[\da-f]+)\t(?<path>.+)$/su
16
+ // it has to hold content the repository's history already stores — a blob some ref reaches — so git
17
+ // can write it again; the one exception is the `.git` file, a pointer to the registration that is
18
+ // gone. **Any commit's content, not only `HEAD`'s at the same path**: a
19
+ // leftover is a checkout of whatever commit its lane was on, and measured against `HEAD` the
20
+ // leftovers that issue found differed in 167 to 1,431 files each while every one of them was in the
21
+ // history. A list of generated names would break the next time a file is generated, and would delete
22
+ // whatever shares one of those names.
23
+ //
24
+ // **The one list of names is what `lane:open` and the gate regenerate**, and only at the top level:
25
+ // the install's `node_modules`, the build's `dist`, the `.env` `lane:open` writes from the root's, and
26
+ // the gate's caches. A lane carries them on top of its checkout, none is in the history, and walking
27
+ // `node_modules` alone would hash tens of thousands of files.
28
+ const REGENERATED_PATHS: ReadonlySet<string> = new Set([
29
+ 'node_modules',
30
+ 'dist',
31
+ ENV_FILE_NAME,
32
+ ...IGNORED_CACHE_FILES,
33
+ ])
22
34
  const GIT_POINTER = '.git'
23
35
  const GITDIR_PREFIX = 'gitdir: '
24
36
  // The foreign paths a refusal names before it summarizes the rest as a count.
25
37
  const NAMED_PATH_LIMIT = 10
26
38
 
27
- // One blob entry as `[path, object id]`; a tree, a commit (a submodule) or the trailing empty entry is
28
- // none.
29
- function tree_entry(entry: string): Array<[string, string]> {
30
- const { path: entry_path, object } = TREE_ENTRY_PATTERN.exec(entry)?.groups ?? {}
31
-
32
- if (entry_path === undefined || object === undefined) return []
33
-
34
- return [[entry_path, object]]
39
+ // `git rev-list --objects --all`: one `<object>[ <path>]` line per object any ref reaches — commits,
40
+ // trees and blobs alike, which costs nothing here, because only a blob id can equal a file's.
41
+ function parse_objects(listing: string): Set<string> {
42
+ return new Set(listing.split('\n').map((line) => line.split(' ', 1)[0] ?? ''))
35
43
  }
36
44
 
37
- function parse_tree(listing: string): Map<string, string> {
38
- return new Map(listing.split('\0').flatMap((entry) => tree_entry(entry)))
45
+ /** Every object id the repository's refs reach — the content a leftover can be restored from. */
46
+ async function recoverable_objects(): Promise<Set<string>> {
47
+ return parse_objects(await git_spawn.read(['rev-list', '--objects', '--all']))
39
48
  }
40
49
 
41
50
  // The object id git gives this file — a symbolic link's is that of its target string, as git stores it.
@@ -63,9 +72,14 @@ function walk_files(directory: string, relative: string): Array<string> {
63
72
  })
64
73
  }
65
74
 
66
- // Every file under `directory` as a repository path, symbolic links included and never followed.
75
+ // Every file under `directory` as a repository path, symbolic links included and never followed —
76
+ // less the regenerated top-level entries, which are neither walked nor listed.
67
77
  function list_files(directory: string): Array<string> {
68
- return walk_files(directory, '')
78
+ return readdirSync(directory)
79
+ .filter((name) => !REGENERATED_PATHS.has(name))
80
+ .flatMap((name) =>
81
+ lstatSync(path.join(directory, name)).isDirectory() ? walk_files(directory, name) : name,
82
+ )
69
83
  }
70
84
 
71
85
  // The `.git` file is disposable only while the registration it points to is gone: one that still
@@ -85,25 +99,25 @@ function is_dangling_pointer(directory: string): boolean {
85
99
  function is_reclaimable_file(
86
100
  directory: string,
87
101
  relative: string,
88
- tracked: ReadonlyMap<string, string>,
102
+ recoverable: ReadonlySet<string>,
89
103
  ): boolean {
90
104
  if (relative === GIT_POINTER) return is_dangling_pointer(directory)
91
105
 
92
- return tracked.get(relative) === blob_id(path.join(directory, relative))
106
+ return recoverable.has(blob_id(path.join(directory, relative)))
93
107
  }
94
108
 
95
109
  /**
96
110
  * The paths under `directory` whose removal would lose something — empty when it holds nothing but
97
- * the repository's own files and the `.git` pointer. A `.git` directory is a repository of its own,
98
- * so it is foreign as a whole rather than walked.
111
+ * content the history stores, the regenerated entries and the `.git` pointer. A `.git` directory is a
112
+ * repository of its own, so it is foreign as a whole rather than walked.
99
113
  */
100
- function foreign_paths(directory: string, tracked: ReadonlyMap<string, string>): Array<string> {
114
+ function foreign_paths(directory: string, recoverable: ReadonlySet<string>): Array<string> {
101
115
  const pointer = lstatSync(path.join(directory, GIT_POINTER), { throwIfNoEntry: false })
102
116
 
103
117
  if (pointer?.isDirectory() === true) return [GIT_POINTER]
104
118
 
105
119
  return list_files(directory).filter(
106
- (relative) => !is_reclaimable_file(directory, relative, tracked),
120
+ (relative) => !is_reclaimable_file(directory, relative, recoverable),
107
121
  )
108
122
  }
109
123
 
@@ -125,8 +139,7 @@ function refusal(directory: string, foreign: ReadonlyArray<string>): Error {
125
139
  async function reclaim(directory: string): Promise<void> {
126
140
  if (!existsSync(directory)) return
127
141
 
128
- const tracked = parse_tree(await git_spawn.read(['ls-tree', '-r', '-z', '--full-tree', 'HEAD']))
129
- const foreign = foreign_paths(directory, tracked)
142
+ const foreign = foreign_paths(directory, await recoverable_objects())
130
143
 
131
144
  if (foreign.length > 0) throw refusal(directory, foreign)
132
145
 
@@ -136,8 +149,9 @@ async function reclaim(directory: string): Promise<void> {
136
149
  const lane_leftover = {
137
150
  blob_id,
138
151
  foreign_paths,
139
- parse_tree,
152
+ parse_objects,
140
153
  reclaim,
154
+ recoverable_objects,
141
155
  }
142
156
 
143
157
  export { lane_leftover }
@@ -0,0 +1,160 @@
1
+ #!/usr/bin/env tsx
2
+ import { fileURLToPath } from 'node:url'
3
+ import { backlog_ready } from '#scripts/backlog/backlog-ready'
4
+ import { cli_flags } from '#scripts/lib/cli-flags'
5
+ import { lane_capacity, type LimitChoice } from './lane-capacity'
6
+ import { lane_limit_override } from './lane-limit-override'
7
+
8
+ // `josh lane:limit [<limit>] [--reset]` — change a live `backlogrun`'s lane limit without stopping it.
9
+ // A running parent keeps the environment it started with, so `JOSH_LANE_LIMIT`
10
+ // cannot move under it; this writes an override onto the run's carry record, which
11
+ // `lane_capacity.lane_limit` reads first. Bare, it prints the limit, the lanes in use and the free ones.
12
+ //
13
+ // **Only a raise wakes anyone.** Lowering stops no child — a finished lane is simply not refilled — so
14
+ // there is nothing for the parent to do; a raise frees lanes, and its `lane-limit` event is what the
15
+ // `--wait` watcher's arrival probe wakes the parent for.
16
+
17
+ const ARGV_OFFSET = 2
18
+ const SUCCESS_EXIT_CODE = 0
19
+ const FAILURE_EXIT_CODE = 1
20
+ const MAX_POSITIONALS = 1
21
+ const NO_LIMIT = 0
22
+ const LIMIT_NAME = '<limit>'
23
+ const OVERRIDE_SOURCE = 'lane:limit override'
24
+ const USAGE = 'Usage: josh lane:limit [<limit>] [--reset]'
25
+ const NO_RUN_MESSAGE = `No run is in progress: lane:limit changes a live run's limit. Set ${lane_capacity.LANE_LIMIT_KEY} for the next run.`
26
+
27
+ const OPTIONS = { reset: { type: 'boolean' } } as const
28
+
29
+ // `set` with no limit is `--reset`: the override is cleared and the environment's limit stands.
30
+ type LimitRequest =
31
+ | { kind: 'show' }
32
+ | { kind: 'set'; limit: number | undefined }
33
+ | { kind: 'refuse'; message: string }
34
+
35
+ interface LimitPorts {
36
+ read_limit: () => Promise<LimitChoice>
37
+ read_override: () => Promise<number | undefined>
38
+ write_override: (limit: number | undefined) => Promise<boolean>
39
+ emit_raise: (text: string) => Promise<void>
40
+ live_lane_count: () => Promise<number>
41
+ }
42
+
43
+ interface LimitStatus {
44
+ limit: number
45
+ override: number | undefined
46
+ in_use: number
47
+ }
48
+
49
+ const SHOW: LimitRequest = { kind: 'show' }
50
+ const RESET: LimitRequest = { kind: 'set', limit: undefined }
51
+ const USAGE_REFUSAL: LimitRequest = { kind: 'refuse', message: USAGE }
52
+
53
+ const DEFAULT_PORTS: LimitPorts = {
54
+ read_limit: async () => await lane_capacity.lane_limit(),
55
+ read_override: lane_limit_override.read_override,
56
+ write_override: lane_limit_override.write_override,
57
+ emit_raise: lane_limit_override.emit_raise,
58
+ live_lane_count: backlog_ready.live_lane_count,
59
+ }
60
+
61
+ function refuse(message: string): number {
62
+ console.error(message)
63
+
64
+ return FAILURE_EXIT_CODE
65
+ }
66
+
67
+ // The rule `JOSH_LANE_LIMIT` is read by, so the two refuse alike.
68
+ function limit_request(raw: string): LimitRequest {
69
+ const choice = lane_capacity.read_limit(raw, LIMIT_NAME)
70
+
71
+ return choice.kind === 'limit'
72
+ ? { kind: 'set', limit: choice.limit }
73
+ : { kind: 'refuse', message: choice.problem }
74
+ }
75
+
76
+ function request_of(raw: string | undefined, is_reset: boolean): LimitRequest {
77
+ if (is_reset) return raw === undefined ? RESET : USAGE_REFUSAL
78
+
79
+ return raw === undefined ? SHOW : limit_request(raw)
80
+ }
81
+
82
+ function parse_request(argv: ReadonlyArray<string>): LimitRequest {
83
+ const parsed = cli_flags.arguments_of(argv, OPTIONS)
84
+
85
+ if (parsed === undefined || parsed.positionals.length > MAX_POSITIONALS) return USAGE_REFUSAL
86
+
87
+ return request_of(parsed.positionals[0], parsed.values.reset === true)
88
+ }
89
+
90
+ // A limit past the port seats is shown at the seats it can actually fill, as `free_lanes` counts it.
91
+ function limit_text(limit: number): string {
92
+ const seated = lane_capacity.seated_limit(limit)
93
+
94
+ return seated === limit
95
+ ? String(limit)
96
+ : `${String(seated)} (${String(limit)} capped at the seats)`
97
+ }
98
+
99
+ function status_line(status: LimitStatus): string {
100
+ const source = status.override === undefined ? lane_capacity.LANE_LIMIT_KEY : OVERRIDE_SOURCE
101
+ const free = lane_capacity.free_lanes(status.limit, status.in_use)
102
+
103
+ return `lane limit ${limit_text(status.limit)} (${source}) · in use ${String(status.in_use)} · free ${String(free)}`
104
+ }
105
+
106
+ async function show(ports: LimitPorts): Promise<number> {
107
+ const choice = await ports.read_limit()
108
+
109
+ if (choice.kind === 'problem') return refuse(choice.problem)
110
+
111
+ const override = await ports.read_override()
112
+
113
+ console.info(
114
+ status_line({ limit: choice.limit, override, in_use: await ports.live_lane_count() }),
115
+ )
116
+
117
+ return SUCCESS_EXIT_CODE
118
+ }
119
+
120
+ // An unreadable limit counts as none, so a valid one set over it is a raise.
121
+ async function seated_now(ports: LimitPorts): Promise<number> {
122
+ const choice = await ports.read_limit()
123
+
124
+ return choice.kind === 'limit' ? lane_capacity.seated_limit(choice.limit) : NO_LIMIT
125
+ }
126
+
127
+ // Measured in seats, so a raise past the seats — which frees no lane — wakes nobody.
128
+ async function change(limit: number | undefined, ports: LimitPorts): Promise<number> {
129
+ const before = await seated_now(ports)
130
+
131
+ if (!(await ports.write_override(limit))) return refuse(NO_RUN_MESSAGE)
132
+
133
+ const after = await seated_now(ports)
134
+
135
+ if (after > before) await ports.emit_raise(`lane limit ${String(before)} → ${String(after)}`)
136
+
137
+ return await show(ports)
138
+ }
139
+
140
+ async function run(
141
+ argv: ReadonlyArray<string>,
142
+ ports: LimitPorts = DEFAULT_PORTS,
143
+ ): Promise<number> {
144
+ const request = parse_request(argv)
145
+
146
+ if (request.kind === 'refuse') return refuse(request.message)
147
+
148
+ return request.kind === 'show' ? await show(ports) : await change(request.limit, ports)
149
+ }
150
+
151
+ async function main(argv: ReadonlyArray<string>): Promise<void> {
152
+ process.exitCode = await run(argv)
153
+ }
154
+
155
+ const lane_limit_cli = { USAGE, run }
156
+
157
+ if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
158
+
159
+ export type { LimitPorts }
160
+ export { lane_limit_cli }
@@ -0,0 +1,74 @@
1
+ import { stamp_file } from '#scripts/josh/stamp-file'
2
+ import { run_carry, type RunCarry } from '#scripts/run/carry/run-carry'
3
+ import { run_event_stream } from '#scripts/run/event/run-event-stream'
4
+ import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
5
+
6
+ // The live run's lane-limit override: where `josh lane:limit` writes it, where
7
+ // `lane_capacity.lane_limit` reads it, and how the `--wait` watcher sees a raise.
8
+ //
9
+ // **It lives on the run's carry record**, not in a file of its own. A running parent keeps the
10
+ // environment it started with, so `JOSH_LANE_LIMIT` cannot change under it; the record is keyed on the
11
+ // common git directory, so the parent, its lanes and a person's shell all resolve the same one — and it
12
+ // is removed with the run at `run:carry --end`, so an override never outlives the run it was set on.
13
+
14
+ const STREAM_START = 0
15
+
16
+ async function carry_target(): Promise<string | undefined> {
17
+ const repository = await run_carry.repository_directory()
18
+
19
+ return repository === undefined ? undefined : run_carry.carry_path(repository)
20
+ }
21
+
22
+ function live_carry(target: string): RunCarry | undefined {
23
+ const read = run_carry.read_carry(target)
24
+
25
+ return read.kind === 'carried' ? read.carry : undefined
26
+ }
27
+
28
+ // The override, or `undefined` where no live run set one — the environment's limit then stands.
29
+ async function read_override(): Promise<number | undefined> {
30
+ const target = await carry_target()
31
+
32
+ return target === undefined ? undefined : live_carry(target)?.lane_limit
33
+ }
34
+
35
+ // `undefined` clears the override. Answers whether a live run took it: with no run there is no record
36
+ // to write to, and the next run reads `JOSH_LANE_LIMIT` as it starts.
37
+ async function write_override(limit: number | undefined): Promise<boolean> {
38
+ const target = await carry_target()
39
+ const carry = target === undefined ? undefined : live_carry(target)
40
+
41
+ if (target === undefined || carry === undefined) return false
42
+
43
+ stamp_file.write_stamp(target, { ...carry, lane_limit: limit })
44
+
45
+ return true
46
+ }
47
+
48
+ async function emit_raise(text: string): Promise<void> {
49
+ await run_event_stream_emit.emit(run_event_stream.EVENT_KIND.LANE_LIMIT, text)
50
+ }
51
+
52
+ function never_raised(): boolean {
53
+ return false
54
+ }
55
+
56
+ // A check for a raise written after this call — the watcher takes it at its start, so a raise it was
57
+ // started after is not one it wakes for.
58
+ async function watch_raise(): Promise<() => boolean> {
59
+ const target = await run_event_stream_emit.stream_target()
60
+
61
+ if (target === undefined) return never_raised
62
+
63
+ const start = run_event_stream.read_from(target, STREAM_START).next_position
64
+
65
+ return function is_raised(): boolean {
66
+ const { events } = run_event_stream.read_from(target, start)
67
+
68
+ return events.some((event) => event.kind === run_event_stream.EVENT_KIND.LANE_LIMIT)
69
+ }
70
+ }
71
+
72
+ const lane_limit_override = { emit_raise, read_override, watch_raise, write_override }
73
+
74
+ export { lane_limit_override }
@@ -1,70 +1,20 @@
1
- import { readFile } from 'node:fs/promises'
2
- import { freemem, loadavg } from 'node:os'
3
- import { execa } from 'execa'
1
+ import { loadavg } from 'node:os'
2
+ import { machine_capacity } from '#scripts/gate/machine-capacity'
4
3
  import { lane_await } from './lane-await'
5
4
  import type { LoadEntry } from './lane-ledger'
6
5
  import { lane_registry, type LaneInfo } from './lane-registry'
7
6
 
8
- // One machine-load sample for the lane-limit measurement (joshuafolkken/kit#3355): the one-minute load
9
- // average, free memory, swap in use and how many lanes have a child working, read at one instant so
10
- // `josh lane:stats` can set the load beside the lane count that produced it.
7
+ // One machine-load sample for the lane-limit measurement: the one-minute load
8
+ // average, available memory, the swap counter and how many lanes have a child working, read at one
9
+ // instant so `josh lane:stats` can set the load beside the lane count that produced it.
11
10
  //
12
- // **Swap is read per platform and is optional.** Node exposes no swap figure, so macOS asks `sysctl` and
13
- // Linux reads `/proc/meminfo`; any other platform, or an output neither parser recognizes, records the
14
- // sample without it rather than as a zero nobody measured.
15
-
16
- const BYTES_PER_MB = 1_048_576
17
- const MB_PER_GB = 1024
18
- const KB_PER_MB = 1024
19
- const DARWIN_SWAP = /used = (?<amount>[\d.]+)(?<unit>[MG])/u
20
- const LINUX_SWAP_TOTAL = /^SwapTotal:\s+(?<kb>\d+) kB/mu
21
- const LINUX_SWAP_FREE = /^SwapFree:\s+(?<kb>\d+) kB/mu
22
- const MEMINFO_PATH = '/proc/meminfo'
23
- const SYSCTL_ARGUMENTS = ['-n', 'vm.swapusage']
24
- const GB_UNIT = 'G'
25
-
26
- // `sysctl -n vm.swapusage` → `total = 5120.00M used = 3993.25M free = 1126.75M (encrypted)`.
27
- function parse_darwin_swap(output: string): number | undefined {
28
- const groups = DARWIN_SWAP.exec(output)?.groups
29
-
30
- if (groups?.['amount'] === undefined) return undefined
31
-
32
- const scale = groups['unit'] === GB_UNIT ? MB_PER_GB : 1
33
-
34
- return Number(groups['amount']) * scale
35
- }
36
-
37
- function kilobytes_of(meminfo: string, pattern: RegExp): number | undefined {
38
- const kb = pattern.exec(meminfo)?.groups?.['kb']
39
-
40
- return kb === undefined ? undefined : Number(kb)
41
- }
42
-
43
- // `/proc/meminfo` carries the total and the free swap; what is in use is their difference.
44
- function parse_linux_swap(meminfo: string): number | undefined {
45
- const total = kilobytes_of(meminfo, LINUX_SWAP_TOTAL)
46
- const free = kilobytes_of(meminfo, LINUX_SWAP_FREE)
47
-
48
- if (total === undefined || free === undefined) return undefined
49
-
50
- return (total - free) / KB_PER_MB
51
- }
52
-
53
- async function read_swap_mb(
54
- platform: NodeJS.Platform = process.platform,
55
- ): Promise<number | undefined> {
56
- try {
57
- if (platform === 'darwin') {
58
- const { stdout } = await execa('sysctl', SYSCTL_ARGUMENTS)
59
-
60
- return parse_darwin_swap(stdout)
61
- }
62
-
63
- return platform === 'linux' ? parse_linux_swap(await readFile(MEMINFO_PATH, 'utf8')) : undefined
64
- } catch {
65
- return undefined
66
- }
67
- }
11
+ // **The memory is `machine_capacity`'s reading, the one the gate admits against.** `os.freemem()` reads
12
+ // near zero on macOS with gigabytes to spare, and a second swap parser here measured swap in use while
13
+ // the gate measured pages swapped — two figures for one machine. `swapped_mb` is that counter, every
14
+ // page swapped since boot, so `lane:stats` reads a rate from the difference between two samples.
15
+ //
16
+ // **Either figure is optional.** A platform the reading does not cover, or a probe that did not answer,
17
+ // records the sample without it rather than as a zero nobody measured.
68
18
 
69
19
  // The lanes with a child at work. An open lane is not enough: a stranded lane, or one a park kept, holds
70
20
  // a tree but no running child, so it adds no load — the child's process is what `lane:await` polls.
@@ -83,25 +33,26 @@ async function read_lanes(): Promise<number | undefined> {
83
33
  }
84
34
  }
85
35
 
36
+ function rounded(megabytes: number | undefined): number | undefined {
37
+ return megabytes === undefined ? undefined : Math.round(megabytes)
38
+ }
39
+
86
40
  async function sample(at: string): Promise<LoadEntry> {
87
- const [swap_mb, lanes] = await Promise.all([read_swap_mb(), read_lanes()])
41
+ const [memory, lanes] = await Promise.all([machine_capacity.read_memory(), read_lanes()])
88
42
  const [load = 0] = loadavg()
89
43
 
90
44
  return {
91
45
  kind: 'load',
92
46
  at,
93
47
  load,
94
- free_mb: Math.round(freemem() / BYTES_PER_MB),
95
- swap_mb,
48
+ available_mb: rounded(memory.available_mb),
49
+ swapped_mb: rounded(memory.swapped_mb),
96
50
  lanes,
97
51
  }
98
52
  }
99
53
 
100
54
  const lane_load = {
101
55
  count_working,
102
- parse_darwin_swap,
103
- parse_linux_swap,
104
- read_swap_mb,
105
56
  sample,
106
57
  }
107
58