@joshuafolkken/kit 1.1240.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 (934) 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 +19 -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 +26 -16
  27. package/.claude/skills/workflow-commands/latest-gate.md +17 -28
  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/.vscode/tasks.json +14 -0
  42. package/CLAUDE.md +10 -61
  43. package/README.md +29 -47
  44. package/SECURITY.md +1 -1
  45. package/dist/CLAUDE.md +10 -61
  46. package/dist/commands/document-section-cli.js +42 -10
  47. package/dist/config-merge/index.js +11 -2
  48. package/dist/hooks/audit-provision.js +2 -2
  49. package/dist/hooks/batch-guard.js +7 -7
  50. package/dist/hooks/{chunk-KHGB5S3Y.js → chunk-43G45XJF.js} +18 -20
  51. package/dist/hooks/{chunk-4TZVB44A.js → chunk-4TW4MQUL.js} +284 -362
  52. package/dist/hooks/{chunk-XZYKEM6J.js → chunk-76RK6E3H.js} +13 -11
  53. package/dist/hooks/{chunk-F3ELQ2AF.js → chunk-DZWZ3DKY.js} +4 -4
  54. package/dist/hooks/{chunk-5VNDSNG3.js → chunk-FZ6FUSBM.js} +1 -1
  55. package/dist/hooks/{chunk-GPTFMK5E.js → chunk-GG72ANKI.js} +1 -1
  56. package/dist/hooks/{chunk-ZQGD4GBY.js → chunk-KPM4YIIX.js} +8 -44
  57. package/dist/hooks/chunk-MXVQMLDP.js +3705 -0
  58. package/dist/hooks/{chunk-ELCN5LCH.js → chunk-NEC4AT4Z.js} +34 -12
  59. package/dist/hooks/{chunk-QVSWU24O.js → chunk-NZBHG6FW.js} +7 -5
  60. package/dist/hooks/chunk-NZN2UFI6.js +2409 -0
  61. package/dist/hooks/{chunk-KRBERBBI.js → chunk-R6CRQEAL.js} +4 -4
  62. package/dist/hooks/chunk-SYSRHRWU.js +1589 -0
  63. package/dist/hooks/{chunk-WK2XSHSI.js → chunk-TLJYAGZK.js} +549 -874
  64. package/dist/hooks/chunk-Z5TMJIPW.js +45 -0
  65. package/dist/hooks/codex-hook-adapter.js +26 -21
  66. package/dist/hooks/duplicate-read-guard.js +8 -8
  67. package/dist/hooks/format-edited.js +4 -4
  68. package/dist/hooks/inputs.json +216 -202
  69. package/dist/hooks/investigation-guard.js +8 -8
  70. package/dist/hooks/pretool-guard.js +15 -15
  71. package/dist/hooks/session-lang.js +406 -8
  72. package/dist/hooks/stop-guard.js +122 -187
  73. package/dist/josh.js +281 -94
  74. package/dist/version/index.js +15 -13
  75. package/eslint/base.js +43 -5
  76. package/eslint/rules/english-only-prose.js +3 -3
  77. package/eslint/rules/import.js +12 -0
  78. package/eslint/rules/namespace-object-export.js +2 -2
  79. package/package.json +16 -10
  80. package/pnpm-workspace.yaml +2 -4
  81. package/prompts/coding-standards.md +14 -48
  82. package/prompts/collaboration-workflow/file-edits.md +1 -1
  83. package/prompts/collaboration-workflow/issue-citation.md +1 -1
  84. package/prompts/collaboration-workflow/issue-template.md +3 -10
  85. package/prompts/collaboration-workflow/operating-rules.md +7 -8
  86. package/prompts/collaboration-workflow/output-bounds.md +1 -1
  87. package/prompts/collaboration-workflow/overview.md +1 -1
  88. package/prompts/collaboration-workflow/plan-comment.md +2 -1
  89. package/prompts/collaboration-workflow/principles.md +21 -3
  90. package/prompts/collaboration-workflow/report-format.md +16 -29
  91. package/prompts/collaboration-workflow/residency.md +1 -1
  92. package/prompts/collaboration-workflow/rule-delivery.md +7 -95
  93. package/prompts/collaboration-workflow/shell-body.md +3 -23
  94. package/prompts/collaboration-workflow/turn-batching.md +4 -13
  95. package/prompts/collaboration-workflow/wip-cap.md +5 -11
  96. package/prompts/refactoring.md +1 -1
  97. package/prompts/review-rubric.md +3 -22
  98. package/prompts/review.md +15 -38
  99. package/prompts/testing-guide.md +2 -4
  100. package/scripts/adopt/adopt-logic.ts +5 -5
  101. package/scripts/adopt/adopt-toolkits.ts +4 -5
  102. package/scripts/adopt/adopt.ts +2 -3
  103. package/scripts/agent/agent-argv.ts +7 -7
  104. package/scripts/agent/agent-diagnostics.ts +2 -2
  105. package/scripts/agent/agent-exit-record.ts +1 -1
  106. package/scripts/agent/agent-headless.ts +1 -1
  107. package/scripts/agent/agent-launch-environment.ts +6 -1
  108. package/scripts/agent/agent-role-profile.ts +49 -22
  109. package/scripts/agent/agent-session-role.ts +32 -0
  110. package/scripts/agent/api-outage.ts +1 -1
  111. package/scripts/agent/claude-agent-argv.ts +4 -4
  112. package/scripts/agent/claude-result-event.ts +4 -4
  113. package/scripts/agent/codex-hooks.ts +2 -2
  114. package/scripts/agent/interactive-ask.ts +3 -6
  115. package/scripts/auto-ok/auto-ok-cli.ts +46 -60
  116. package/scripts/backlog/backlog-arrival-added.ts +34 -0
  117. package/scripts/backlog/backlog-arrival.ts +54 -17
  118. package/scripts/backlog/backlog-budget-cli.ts +34 -6
  119. package/scripts/backlog/backlog-budget.ts +17 -24
  120. package/scripts/backlog/backlog-defect-priority.ts +1 -1
  121. package/scripts/backlog/backlog-drive-args.ts +5 -4
  122. package/scripts/backlog/backlog-drive-cli.ts +14 -10
  123. package/scripts/backlog/backlog-drive-epic.ts +85 -0
  124. package/scripts/backlog/backlog-drive-launch.ts +1 -1
  125. package/scripts/backlog/backlog-drive-named-offer.ts +60 -9
  126. package/scripts/backlog/backlog-drive-named.ts +39 -9
  127. package/scripts/backlog/backlog-drive-offer-argv.ts +1 -1
  128. package/scripts/backlog/backlog-drive-restore.ts +1 -1
  129. package/scripts/backlog/backlog-drive-retrospective.ts +2 -2
  130. package/scripts/backlog/backlog-drive.ts +43 -28
  131. package/scripts/backlog/backlog-idle.ts +88 -0
  132. package/scripts/backlog/backlog-named.ts +11 -15
  133. package/scripts/backlog/backlog-next.ts +26 -30
  134. package/scripts/backlog/backlog-offer-cli.ts +28 -23
  135. package/scripts/backlog/backlog-offer.ts +7 -7
  136. package/scripts/backlog/backlog-overlap.ts +178 -0
  137. package/scripts/backlog/backlog-plan-cli.ts +14 -90
  138. package/scripts/backlog/backlog-plan-read.ts +111 -0
  139. package/scripts/backlog/backlog-plan.ts +11 -10
  140. package/scripts/backlog/backlog-pool.ts +13 -14
  141. package/scripts/backlog/backlog-rank.ts +11 -11
  142. package/scripts/backlog/backlog-ready.ts +15 -10
  143. package/scripts/backlog/backlog-scope.ts +14 -15
  144. package/scripts/backlog/backlog-stalled-cli.ts +2 -2
  145. package/scripts/backlog/backlog-stalled-detect.ts +4 -4
  146. package/scripts/backlog/backlog-stalled.ts +5 -6
  147. package/scripts/backlog/backlog-waves.ts +4 -4
  148. package/scripts/backlog/backlogrun-args.ts +74 -0
  149. package/scripts/backlog/backlogrun-cli.ts +113 -0
  150. package/scripts/backlog/backlogrun-launch.ts +178 -0
  151. package/scripts/behavior/behavior-assertion.ts +6 -8
  152. package/scripts/behavior/behavior-cli.ts +1 -1
  153. package/scripts/behavior/behavior-rules.ts +3 -3
  154. package/scripts/build/build-claude-md.ts +4 -4
  155. package/scripts/build/build-codex-hooks.ts +2 -2
  156. package/scripts/build/build-commands.ts +1 -1
  157. package/scripts/build/build-hooks.ts +5 -5
  158. package/scripts/build/build.ts +1 -1
  159. package/scripts/build/hook-bundle-stamp.ts +109 -7
  160. package/scripts/build/local-bin.ts +2 -2
  161. package/scripts/cases/cases-cli.ts +1 -1
  162. package/scripts/cases/cases-logic.ts +2 -2
  163. package/scripts/ci/composite-actions.ts +1 -2
  164. package/scripts/ci/pr-classification.ts +2 -2
  165. package/scripts/claude/workflow-destination.ts +1 -1
  166. package/scripts/clone/clone-aggregate.ts +1 -1
  167. package/scripts/clone/clone-fingerprint.ts +1 -1
  168. package/scripts/clone/clone-scan-cli.ts +1 -1
  169. package/scripts/clone/clone-scan.ts +1 -1
  170. package/scripts/config-merge/index.ts +1 -1
  171. package/scripts/config-merge/json-format.ts +1 -3
  172. package/scripts/config-merge/patch-json-array.ts +90 -0
  173. package/scripts/config-merge/patch-json-key.ts +6 -3
  174. package/scripts/config-merge/patch-json-list.ts +1 -1
  175. package/scripts/cost-runtime/codex-usage.ts +1 -1
  176. package/scripts/cost-runtime/context-cut-payback.ts +4 -5
  177. package/scripts/cost-runtime/context-cut-threshold.ts +4 -6
  178. package/scripts/cost-runtime/cost-attribute.ts +3 -3
  179. package/scripts/cost-runtime/cost-blocks.ts +3 -4
  180. package/scripts/cost-runtime/cost-cli.ts +14 -11
  181. package/scripts/cost-runtime/cost-corpus.ts +11 -11
  182. package/scripts/cost-runtime/cost-pricing.ts +4 -4
  183. package/scripts/cost-runtime/cost-tokens.ts +1 -2
  184. package/scripts/cost-runtime/cost-transcript.ts +29 -29
  185. package/scripts/cost-runtime/cost-usage.ts +6 -7
  186. package/scripts/cost-runtime/cost-verdict.ts +10 -11
  187. package/scripts/cost-runtime/own-session.ts +1 -1
  188. package/scripts/cost-runtime/transcript-cwd.ts +2 -2
  189. package/scripts/delegation/delegation-cli.ts +4 -4
  190. package/scripts/delegation/delegation-policy.ts +13 -15
  191. package/scripts/delegation/duplicate-read-guard.ts +9 -10
  192. package/scripts/delegation/fanout-cli.ts +1 -1
  193. package/scripts/delegation/fanout.ts +1 -1
  194. package/scripts/delegation/investigation-guard.ts +18 -22
  195. package/scripts/delegation/investigation-reads.ts +48 -238
  196. package/scripts/discovery/repo-discovery.ts +1 -1
  197. package/scripts/discovery/repo-map-logic.ts +1 -2
  198. package/scripts/discovery/repo-origin.ts +3 -3
  199. package/scripts/discovery/repo-party-cli.ts +2 -2
  200. package/scripts/discovery/repo-party.ts +2 -2
  201. package/scripts/doctor/doctor-consumer.ts +1 -1
  202. package/scripts/doctor/doctor-io.ts +6 -7
  203. package/scripts/doctor/doctor-logic.ts +1 -1
  204. package/scripts/doctor/doctor-ports.ts +1 -1
  205. package/scripts/doctor/doctor.ts +8 -9
  206. package/scripts/document/backlogrun-parent-read-set.ts +5 -6
  207. package/scripts/document/bash-output-cap.ts +5 -7
  208. package/scripts/document/capped-print-part.ts +1 -1
  209. package/scripts/document/capped-print.ts +1 -1
  210. package/scripts/document/document-byte-budget.ts +33 -64
  211. package/scripts/document/document-byte-check.ts +4 -4
  212. package/scripts/document/document-reachability.ts +7 -8
  213. package/scripts/document/document-read-cli.ts +2 -2
  214. package/scripts/document/document-scan.ts +26 -2
  215. package/scripts/document/document-section-cli.ts +6 -8
  216. package/scripts/document/document-section.ts +8 -12
  217. package/scripts/document/edit-files-cli.ts +3 -4
  218. package/scripts/document/entry-read-budget.ts +8 -70
  219. package/scripts/document/entry-read-set.ts +51 -34
  220. package/scripts/document/lane-child-read-set.ts +9 -9
  221. package/scripts/document/read-files-cli.ts +1 -2
  222. package/scripts/document/read-set-cli.ts +16 -19
  223. package/scripts/document/read-set-cost.ts +4 -4
  224. package/scripts/document/read-set-point-of-use.ts +28 -38
  225. package/scripts/document/read-set-pricing.ts +1 -1
  226. package/scripts/document/read-set-trim.ts +3 -3
  227. package/scripts/document/resident-budget.ts +8 -10
  228. package/scripts/epic/epic-add-body.ts +15 -18
  229. package/scripts/epic/epic-add-plan.ts +26 -28
  230. package/scripts/epic/epic-add.ts +32 -25
  231. package/scripts/epic/epic-audit-checks.ts +27 -37
  232. package/scripts/epic/epic-audit-cli.ts +21 -22
  233. package/scripts/epic/epic-audit-orphans.ts +16 -17
  234. package/scripts/epic/epic-audit-rationale.ts +10 -15
  235. package/scripts/epic/epic-audit-report.ts +2 -5
  236. package/scripts/epic/epic-audit.ts +18 -14
  237. package/scripts/epic/epic-body.ts +10 -10
  238. package/scripts/epic/epic-bundle-cli.ts +36 -34
  239. package/scripts/epic/epic-bundle-evidence.ts +5 -5
  240. package/scripts/epic/epic-bundle-gaps.ts +6 -9
  241. package/scripts/epic/epic-bundle-poll.ts +1 -1
  242. package/scripts/epic/epic-bundle-referenced.ts +11 -14
  243. package/scripts/epic/epic-bundle.ts +19 -20
  244. package/scripts/epic/epic-busy.ts +44 -21
  245. package/scripts/epic/epic-candidate-confirm.ts +15 -18
  246. package/scripts/epic/epic-chains.ts +18 -23
  247. package/scripts/epic/epic-classify.ts +11 -12
  248. package/scripts/epic/epic-cli-argv.ts +5 -6
  249. package/scripts/epic/epic-cli-remove.ts +9 -4
  250. package/scripts/epic/epic-cli.ts +38 -26
  251. package/scripts/epic/epic-close-comment.ts +14 -15
  252. package/scripts/epic/epic-close.ts +25 -29
  253. package/scripts/epic/epic-cross-repo.ts +18 -21
  254. package/scripts/epic/epic-decision.ts +14 -18
  255. package/scripts/epic/epic-fetch.ts +25 -31
  256. package/scripts/epic/epic-graph.ts +15 -17
  257. package/scripts/epic/epic-index.ts +14 -16
  258. package/scripts/epic/epic-issue.ts +9 -11
  259. package/scripts/epic/epic-label-age.ts +74 -0
  260. package/scripts/epic/epic-lane-offer.ts +35 -24
  261. package/scripts/epic/epic-nested.ts +1 -1
  262. package/scripts/epic/epic-next-read.ts +8 -8
  263. package/scripts/epic/epic-next-views.ts +12 -12
  264. package/scripts/epic/epic-next.ts +29 -33
  265. package/scripts/epic/epic-outside-blocker.ts +11 -10
  266. package/scripts/epic/epic-parse.ts +22 -24
  267. package/scripts/epic/epic-promote.ts +3 -2
  268. package/scripts/epic/epic-rank.ts +1 -1
  269. package/scripts/epic/epic-read.ts +10 -8
  270. package/scripts/epic/epic-reconcile.ts +8 -6
  271. package/scripts/epic/epic-reference.ts +5 -4
  272. package/scripts/epic/epic-relation-recheck.ts +10 -11
  273. package/scripts/epic/epic-relations.ts +9 -8
  274. package/scripts/epic/epic-remove-plan.ts +4 -5
  275. package/scripts/epic/epic-remove.ts +7 -5
  276. package/scripts/epic/epic-report.ts +18 -20
  277. package/scripts/epic/epic-run.ts +6 -5
  278. package/scripts/epic/epic-sections.ts +2 -2
  279. package/scripts/epic/epic-shape.ts +3 -3
  280. package/scripts/epic/epic-solo-stale.ts +3 -2
  281. package/scripts/epic/epic-solo.ts +8 -8
  282. package/scripts/epic/epic-triage.ts +5 -4
  283. package/scripts/epic/epic-validate.ts +8 -7
  284. package/scripts/epic/epic.ts +5 -5
  285. package/scripts/exports/unused-members-cli.ts +1 -1
  286. package/scripts/followup/followup-issue-number.ts +1 -2
  287. package/scripts/followup/git-followup-cleanup.ts +6 -7
  288. package/scripts/followup/git-followup-finish.ts +11 -13
  289. package/scripts/followup/git-followup-flush.ts +11 -7
  290. package/scripts/followup/git-followup-issue-close.ts +16 -13
  291. package/scripts/followup/git-followup-label.ts +9 -6
  292. package/scripts/followup/git-followup-merged.ts +1 -1
  293. package/scripts/followup/git-followup-pending.ts +7 -9
  294. package/scripts/followup/git-followup-stages.ts +28 -17
  295. package/scripts/followup/git-followup-workflow.ts +19 -21
  296. package/scripts/followup/git-pr-followup-checks.ts +13 -20
  297. package/scripts/followup/git-pr-followup-wrapup.ts +7 -7
  298. package/scripts/followup/git-pr-followup.ts +18 -17
  299. package/scripts/gate/core-admission.ts +2 -2
  300. package/scripts/gate/core-budget.ts +15 -26
  301. package/scripts/gate/gate-ledger.ts +114 -0
  302. package/scripts/gate/gate-log.ts +7 -9
  303. package/scripts/gate/gate-plan.ts +70 -35
  304. package/scripts/gate/gate-report.ts +14 -15
  305. package/scripts/gate/gate-skip.ts +11 -13
  306. package/scripts/gate/gate-steps.ts +5 -1
  307. package/scripts/gate/gate-tree.ts +3 -4
  308. package/scripts/gate/hook-gate-reuse.ts +9 -9
  309. package/scripts/gate/machine-capacity.ts +168 -30
  310. package/scripts/gate/pre-commit-type-check.ts +4 -4
  311. package/scripts/gate/project-checks.ts +12 -4
  312. package/scripts/gate/scoped-green.ts +11 -18
  313. package/scripts/gate/type-check-command.ts +2 -2
  314. package/scripts/gate/type-check-step.ts +4 -4
  315. package/scripts/gate/verification-gate.ts +53 -51
  316. package/scripts/gh/gh-spawn.ts +2 -2
  317. package/scripts/gh/git-ai-review-scan.ts +3 -2
  318. package/scripts/gh/git-gh-api-path.ts +10 -11
  319. package/scripts/gh/git-gh-exec.ts +43 -48
  320. package/scripts/gh/git-gh-failure.ts +6 -9
  321. package/scripts/gh/git-gh-helpers.ts +1 -1
  322. package/scripts/gh/git-gh-issue-list.ts +15 -19
  323. package/scripts/gh/git-gh-issue-read.ts +43 -60
  324. package/scripts/gh/git-gh-issue-rest.ts +14 -15
  325. package/scripts/gh/git-gh-issue-write.ts +52 -40
  326. package/scripts/gh/git-gh-issue.ts +23 -24
  327. package/scripts/gh/git-gh-pr-auto-merge.ts +3 -3
  328. package/scripts/gh/git-gh-pr-read.ts +46 -50
  329. package/scripts/gh/git-gh-pr-rest.ts +23 -26
  330. package/scripts/gh/git-gh-pr-review.ts +2 -2
  331. package/scripts/gh/git-gh-pr-rollup.ts +4 -4
  332. package/scripts/gh/git-gh-pr-snapshot.ts +8 -10
  333. package/scripts/gh/git-gh-pr.ts +16 -16
  334. package/scripts/gh/git-gh-reachability.ts +11 -12
  335. package/scripts/gh/git-gh-repo.ts +2 -3
  336. package/scripts/gh/git-gh-rest-state.ts +1 -1
  337. package/scripts/gh/git-pr-ai-review.ts +6 -5
  338. package/scripts/gh/git-pr-checks-eval.ts +28 -30
  339. package/scripts/gh/git-pr-checks-parse.ts +14 -16
  340. package/scripts/gh/git-pr-checks-watch.ts +17 -17
  341. package/scripts/gh/git-pr-checks.ts +20 -23
  342. package/scripts/gh/git-pr-coderabbit.ts +8 -6
  343. package/scripts/gh/git-pr-confirmation.ts +5 -5
  344. package/scripts/gh/git-pr-managed-config.ts +7 -9
  345. package/scripts/gh/git-pr-messages.ts +1 -1
  346. package/scripts/gh/git-pr.ts +15 -16
  347. package/scripts/gh/github-issue-url.ts +8 -9
  348. package/scripts/git/base-tree.ts +66 -0
  349. package/scripts/git/change-base.ts +42 -2
  350. package/scripts/git/changed-file-scope.ts +5 -5
  351. package/scripts/git/changed-paths.ts +1 -2
  352. package/scripts/git/constants.ts +2 -2
  353. package/scripts/git/git-branch.ts +1 -1
  354. package/scripts/git/git-closes-keyword.ts +3 -3
  355. package/scripts/git/git-command.ts +53 -41
  356. package/scripts/git/git-common-directory.ts +3 -3
  357. package/scripts/git/git-diff-reads.ts +14 -15
  358. package/scripts/git/git-error.ts +1 -1
  359. package/scripts/git/git-execa-error.ts +1 -2
  360. package/scripts/git/git-issue.ts +10 -8
  361. package/scripts/git/git-location-environment.ts +3 -4
  362. package/scripts/git/git-ls-remote.ts +6 -8
  363. package/scripts/git/git-pre-push-hook.ts +11 -10
  364. package/scripts/git/git-preflight.ts +5 -5
  365. package/scripts/git/git-push-transport.ts +2 -2
  366. package/scripts/git/git-remote-branch.ts +1 -2
  367. package/scripts/git/git-schemas.ts +16 -23
  368. package/scripts/git/git-spawn-sync.ts +1 -1
  369. package/scripts/git/git-spawn.ts +37 -14
  370. package/scripts/git/git-ssh-keepalive.ts +12 -5
  371. package/scripts/git/git-staging.ts +7 -8
  372. package/scripts/git/git-workflow.ts +1 -1
  373. package/scripts/git/git-worktree.ts +35 -27
  374. package/scripts/git/gone-branch.ts +2 -2
  375. package/scripts/git/listing-cutoff.ts +1 -2
  376. package/scripts/git/lockfile-sync.ts +65 -0
  377. package/scripts/git/main-merge-guard.ts +1 -2
  378. package/scripts/git/main-merge.ts +7 -7
  379. package/scripts/git/main-sync.ts +23 -8
  380. package/scripts/git/parse-json-array.ts +18 -23
  381. package/scripts/git/repository-lock.ts +34 -2
  382. package/scripts/git/stash/git-stash.ts +4 -5
  383. package/scripts/git/stash/stash-orphans.ts +5 -3
  384. package/scripts/git/stash/stash-pop-args.ts +1 -1
  385. package/scripts/git/stash/stash-pop-cli.ts +3 -3
  386. package/scripts/git/stash/stash-sweep-lock.ts +2 -2
  387. package/scripts/hooks/batch-guard.ts +11 -13
  388. package/scripts/hooks/check-commit-message.ts +12 -9
  389. package/scripts/hooks/codex-hook-adapter.ts +16 -10
  390. package/scripts/hooks/edited-cspell.ts +3 -4
  391. package/scripts/hooks/format-edited-cli.ts +1 -1
  392. package/scripts/hooks/format-edited-file.ts +11 -17
  393. package/scripts/hooks/format-rewrite-notice.ts +19 -17
  394. package/scripts/hooks/pre-push-unit.ts +10 -14
  395. package/scripts/hooks/pretool-guard-cli.ts +4 -4
  396. package/scripts/hooks/pretool-guard.ts +93 -18
  397. package/scripts/hooks/reserved-run.ts +2 -2
  398. package/scripts/hooks/step-zero-notice.ts +1 -1
  399. package/scripts/hooks/stop-guard.ts +21 -10
  400. package/scripts/init/basic-path-migration.ts +2 -2
  401. package/scripts/init/claude-kit-only-settings.ts +2 -2
  402. package/scripts/init/claude-plugin-config.ts +2 -2
  403. package/scripts/init/distributed-paths.ts +4 -4
  404. package/scripts/init/hook-command-rewrite.ts +3 -3
  405. package/scripts/init/hook-launch.ts +5 -5
  406. package/scripts/init/init-actions.ts +13 -0
  407. package/scripts/init/init-ai-copy.ts +11 -11
  408. package/scripts/init/init-bootstrap.ts +3 -3
  409. package/scripts/init/init-copy-content.ts +4 -4
  410. package/scripts/init/init-logic-json-merge.ts +7 -9
  411. package/scripts/init/init-logic-migrate.ts +1 -1
  412. package/scripts/init/init-logic-templates.ts +1 -1
  413. package/scripts/init/init-logic-workspace.ts +4 -4
  414. package/scripts/init/init-logic-yaml-merge.ts +2 -2
  415. package/scripts/init/init-logic.ts +19 -22
  416. package/scripts/init/init.ts +7 -7
  417. package/scripts/init/kit-base-preset.ts +1 -1
  418. package/scripts/init/kit-setup-state.ts +1 -1
  419. package/scripts/init/kit-written-paths.ts +1 -2
  420. package/scripts/init/package-manager-pin.ts +1 -1
  421. package/scripts/init/project-profile-cli.ts +1 -1
  422. package/scripts/init/project-profile.ts +3 -3
  423. package/scripts/init/session-language-environment.ts +1 -1
  424. package/scripts/init/start-exec.ts +3 -4
  425. package/scripts/init/start-plan.ts +2 -2
  426. package/scripts/init/start-setup-pr.ts +3 -2
  427. package/scripts/init/start-steps.ts +2 -2
  428. package/scripts/init/tsconfig-preset-migration.ts +1 -1
  429. package/scripts/init/vscode-tasks.ts +62 -0
  430. package/scripts/issue/baseline-measure.ts +2 -2
  431. package/scripts/issue/behavior-change-lint.ts +2 -2
  432. package/scripts/issue/defect-rate-cli.ts +6 -7
  433. package/scripts/issue/defect-rate.ts +37 -27
  434. package/scripts/issue/git-next-issues.ts +9 -8
  435. package/scripts/issue/issue-auto-ok.ts +24 -11
  436. package/scripts/issue/issue-backlinks-cli.ts +5 -5
  437. package/scripts/issue/issue-backlinks.ts +6 -6
  438. package/scripts/issue/issue-cite-cli.ts +20 -18
  439. package/scripts/issue/issue-cite.ts +18 -8
  440. package/scripts/issue/issue-closing-pr.ts +4 -4
  441. package/scripts/issue/issue-comment-cli.ts +6 -4
  442. package/scripts/issue/issue-file-cli.ts +52 -15
  443. package/scripts/issue/issue-file-fold.ts +155 -0
  444. package/scripts/issue/issue-file.ts +9 -6
  445. package/scripts/issue/issue-fold-cli.ts +14 -9
  446. package/scripts/issue/issue-fold.ts +23 -8
  447. package/scripts/issue/issue-labels.ts +34 -38
  448. package/scripts/issue/issue-lint-cli.ts +2 -2
  449. package/scripts/issue/issue-lint.ts +1 -1
  450. package/scripts/issue/issue-merged.ts +10 -4
  451. package/scripts/issue/issue-number-shape.ts +27 -0
  452. package/scripts/issue/issue-rank.ts +1 -1
  453. package/scripts/issue/issue-read-cli.ts +4 -5
  454. package/scripts/issue/issue-read.ts +4 -5
  455. package/scripts/issue/issue-reference.ts +5 -5
  456. package/scripts/issue/issue-release-cli.ts +17 -7
  457. package/scripts/issue/issue-release.ts +3 -3
  458. package/scripts/issue/issue-report-failures.ts +7 -4
  459. package/scripts/issue/issue-scout-cli.ts +11 -11
  460. package/scripts/issue/issue-scout-closed.ts +4 -4
  461. package/scripts/issue/issue-scout.ts +4 -5
  462. package/scripts/issue/issue-state-cli.ts +17 -10
  463. package/scripts/issue/issue-state.ts +12 -13
  464. package/scripts/issue/issue-wip.ts +7 -7
  465. package/scripts/issue/markdown-section.ts +3 -3
  466. package/scripts/issue/measure-rerun-cli.ts +10 -9
  467. package/scripts/issue/reproduction-measure.ts +3 -3
  468. package/scripts/issue/session-cite.ts +56 -0
  469. package/scripts/josh/agent-session-environment.ts +10 -8
  470. package/scripts/josh/cli-body.ts +2 -2
  471. package/scripts/josh/command-suggest.ts +1 -1
  472. package/scripts/josh/file-map-stamp.ts +20 -23
  473. package/scripts/josh/hook-decision.ts +24 -28
  474. package/scripts/josh/josh-command-map.ts +4 -1
  475. package/scripts/josh/josh-command-types.ts +30 -35
  476. package/scripts/josh/josh-commands-ai.ts +6 -6
  477. package/scripts/josh/josh-commands-backlog.ts +15 -3
  478. package/scripts/josh/josh-commands-clone.ts +1 -1
  479. package/scripts/josh/josh-commands-development.ts +25 -4
  480. package/scripts/josh/josh-commands-document.ts +3 -3
  481. package/scripts/josh/josh-commands-guard.ts +3 -3
  482. package/scripts/josh/josh-commands-issue.ts +4 -5
  483. package/scripts/josh/josh-commands-lane.ts +14 -4
  484. package/scripts/josh/josh-commands-lint.ts +1 -1
  485. package/scripts/josh/josh-commands-run.ts +20 -6
  486. package/scripts/josh/josh-commands-split.ts +1 -2
  487. package/scripts/josh/josh-commands-versioning.ts +5 -5
  488. package/scripts/josh/josh-commands-workflow.ts +30 -22
  489. package/scripts/josh/josh-environment-file.ts +1 -1
  490. package/scripts/josh/josh-in-process.ts +3 -3
  491. package/scripts/josh/josh-logic.ts +6 -7
  492. package/scripts/josh/josh-run.ts +3 -3
  493. package/scripts/josh/josh-verdict.ts +9 -12
  494. package/scripts/josh/josh.ts +3 -3
  495. package/scripts/josh/kit-only.ts +2 -2
  496. package/scripts/josh/path-decision.ts +3 -3
  497. package/scripts/josh/platform-temporary.ts +7 -5
  498. package/scripts/josh/process-identity.ts +24 -6
  499. package/scripts/josh/process-owner.ts +4 -4
  500. package/scripts/josh/session-language-cli.ts +53 -11
  501. package/scripts/josh/session-language.ts +1 -1
  502. package/scripts/josh/stamp-file.ts +48 -29
  503. package/scripts/josh/stamp-record.ts +57 -0
  504. package/scripts/lane/lane-await.ts +35 -11
  505. package/scripts/lane/lane-cache.ts +6 -6
  506. package/scripts/lane/lane-capacity.ts +32 -17
  507. package/scripts/lane/lane-child-invocation.ts +17 -15
  508. package/scripts/lane/lane-child-marker.ts +12 -12
  509. package/scripts/lane/lane-cli.ts +12 -13
  510. package/scripts/lane/lane-close.ts +6 -6
  511. package/scripts/lane/lane-dispatch.ts +61 -72
  512. package/scripts/lane/lane-environment.ts +5 -5
  513. package/scripts/lane/lane-guard-policy.ts +7 -21
  514. package/scripts/lane/lane-handoff.ts +2 -2
  515. package/scripts/lane/lane-install.ts +9 -10
  516. package/scripts/lane/lane-launch-cli.ts +13 -8
  517. package/scripts/lane/lane-ledger.ts +73 -11
  518. package/scripts/lane/lane-leftover.ts +2 -2
  519. package/scripts/lane/lane-limit-cli.ts +160 -0
  520. package/scripts/lane/lane-limit-override.ts +74 -0
  521. package/scripts/lane/lane-load.ts +19 -68
  522. package/scripts/lane/lane-measure-cli.ts +15 -25
  523. package/scripts/lane/lane-occupancy.ts +6 -4
  524. package/scripts/lane/lane-open.ts +20 -19
  525. package/scripts/lane/lane-output.ts +4 -3
  526. package/scripts/lane/lane-paths.ts +12 -11
  527. package/scripts/lane/lane-phase.ts +33 -0
  528. package/scripts/lane/lane-reap.ts +2 -2
  529. package/scripts/lane/lane-registry.ts +16 -15
  530. package/scripts/lane/lane-relaunch.ts +9 -9
  531. package/scripts/lane/lane-report.ts +5 -4
  532. package/scripts/lane/lane-resume.ts +2 -2
  533. package/scripts/lane/lane-sampler.ts +55 -0
  534. package/scripts/lane/lane-seed.ts +7 -7
  535. package/scripts/lane/lane-stage-stats.ts +135 -0
  536. package/scripts/lane/lane-start-point.ts +8 -11
  537. package/scripts/lane/lane-stats.ts +60 -15
  538. package/scripts/lane/lane-stray.ts +1 -1
  539. package/scripts/lane/lane-vacant.ts +1 -1
  540. package/scripts/lane/openai-lane-supervisor-decision.ts +3 -7
  541. package/scripts/lane/openai-lane-supervisor-owner.ts +3 -9
  542. package/scripts/lane/openai-review-broker.ts +2 -4
  543. package/scripts/lib/ancestor-directories.ts +1 -1
  544. package/scripts/lib/bounded-pool.ts +2 -2
  545. package/scripts/lib/buffered-process.ts +4 -6
  546. package/scripts/lib/caddy-logs.sh +0 -0
  547. package/scripts/lib/cli-flags.ts +39 -6
  548. package/scripts/lib/error-message.ts +1 -1
  549. package/scripts/lib/json-value.ts +17 -3
  550. package/scripts/lib/poll.ts +1 -1
  551. package/scripts/lib/status-icons.ts +3 -3
  552. package/scripts/lib/timed-fetch.ts +1 -1
  553. package/scripts/lib/timeouts.ts +1 -1
  554. package/scripts/lines/bytes-command.ts +3 -4
  555. package/scripts/lines/effective-limit.ts +25 -12
  556. package/scripts/lines/line-budget.ts +47 -55
  557. package/scripts/lines/line-targets.ts +6 -2
  558. package/scripts/lines/lines-command.ts +3 -3
  559. package/scripts/lint/cspell-cached.ts +1 -1
  560. package/scripts/lint/cycle-recheck.ts +122 -0
  561. package/scripts/lint/format.ts +1 -2
  562. package/scripts/lint/lint-parallel.ts +34 -19
  563. package/scripts/lint/lint-related-scope.ts +25 -15
  564. package/scripts/lint/lint-related.ts +6 -7
  565. package/scripts/managed-marker/index.ts +1 -1
  566. package/scripts/managed-marker/managed-marker-logic.ts +1 -2
  567. package/scripts/notify/git-notify.ts +9 -7
  568. package/scripts/notify/telegram-notify.ts +53 -37
  569. package/scripts/notify/telegram-test-logic.ts +3 -3
  570. package/scripts/notify/telegram-test.ts +45 -30
  571. package/scripts/observations/observation-ledger-home.ts +14 -8
  572. package/scripts/observations/observation-ledger-line.ts +3 -2
  573. package/scripts/observations/observation-ledger-migrate.ts +3 -4
  574. package/scripts/observations/observation-ledger-prepare.ts +4 -4
  575. package/scripts/observations/observation-ledger.ts +14 -15
  576. package/scripts/observations/observation-record-cli.ts +83 -0
  577. package/scripts/observations/observation-record.ts +91 -0
  578. package/scripts/observations/observations-flush-cli.ts +1 -1
  579. package/scripts/observations/observations-flush-landing.ts +7 -6
  580. package/scripts/observations/observations-flush.ts +26 -27
  581. package/scripts/overrides/overrides-check.ts +18 -8
  582. package/scripts/package/package-scout-cli.ts +1 -1
  583. package/scripts/package/package-scout-format.ts +2 -2
  584. package/scripts/package/package-scout.ts +1 -1
  585. package/scripts/propagate/propagate-git-failure.ts +1 -1
  586. package/scripts/propagate/propagate-git.ts +7 -7
  587. package/scripts/propagate/propagate-plan.ts +2 -2
  588. package/scripts/propagate/propagate-publish.ts +2 -3
  589. package/scripts/propagate/propagate-run.ts +5 -7
  590. package/scripts/propagate/propagate-select.ts +1 -1
  591. package/scripts/propagate/propagate-steps.ts +19 -20
  592. package/scripts/propagate/propagate-targets.ts +6 -10
  593. package/scripts/propagate/propagate.ts +5 -5
  594. package/scripts/refactor/import-graph.ts +1 -1
  595. package/scripts/refactor/refactor-lint.ts +4 -10
  596. package/scripts/refactor/refactor-scan-cli.ts +1 -1
  597. package/scripts/refactor/refactor-scan.ts +2 -2
  598. package/scripts/refactor/refactor-targets.ts +1 -1
  599. package/scripts/release/github-release-cli.ts +25 -3
  600. package/scripts/release/github-release-runs.ts +1 -1
  601. package/scripts/release/release-cli.ts +21 -4
  602. package/scripts/release/release-history.ts +6 -10
  603. package/scripts/release/release-plan.ts +3 -3
  604. package/scripts/release/release-progress.ts +3 -4
  605. package/scripts/release/release-publish.ts +8 -9
  606. package/scripts/release/release-scope-cli.ts +8 -10
  607. package/scripts/release/release-tag.ts +6 -8
  608. package/scripts/release/release-worktree.ts +5 -5
  609. package/scripts/repo/auto-merge-setting-logic.ts +7 -9
  610. package/scripts/repo/auto-merge-setting.ts +1 -1
  611. package/scripts/repo/repo-setting.ts +4 -4
  612. package/scripts/repo/repository-labels.ts +1 -1
  613. package/scripts/repo/required-checks-logic.ts +3 -3
  614. package/scripts/repo/required-checks-report.ts +1 -1
  615. package/scripts/repo/ruleset-check-cli.ts +1 -1
  616. package/scripts/repo/ruleset-check.ts +1 -1
  617. package/scripts/report/report-format-reference.ts +26 -0
  618. package/scripts/report/report-lint-cli.ts +2 -2
  619. package/scripts/report/report-lint.ts +16 -2
  620. package/scripts/review/disposition-cli.ts +2 -2
  621. package/scripts/review/disposition-logic.ts +1 -1
  622. package/scripts/review/live-evidence.ts +9 -6
  623. package/scripts/review/review-attest-cli.ts +1 -2
  624. package/scripts/review/review-attest.ts +3 -3
  625. package/scripts/review/review-brief-cli.ts +19 -20
  626. package/scripts/review/review-brief.ts +29 -32
  627. package/scripts/review/review-checkout.ts +2 -2
  628. package/scripts/review/review-diff-parts.ts +3 -5
  629. package/scripts/review/review-diff-write.ts +1 -1
  630. package/scripts/review/review-finding-ledger.ts +7 -4
  631. package/scripts/review/review-findings-cli.ts +2 -2
  632. package/scripts/review/review-level.ts +4 -7
  633. package/scripts/review/review-record-cli.ts +73 -16
  634. package/scripts/review/review-record.ts +5 -4
  635. package/scripts/review/review-round2-cli.ts +2 -3
  636. package/scripts/review/review-round2.ts +13 -21
  637. package/scripts/review/review-stamps.ts +9 -71
  638. package/scripts/review/review-tree.ts +4 -5
  639. package/scripts/rules/bash-triggers.ts +4 -4
  640. package/scripts/rules/decision-oracle-batch.ts +5 -6
  641. package/scripts/rules/decision-oracle-stage.ts +1 -1
  642. package/scripts/rules/decision-oracle-tokens.ts +1 -2
  643. package/scripts/rules/decision-oracle.ts +2 -2
  644. package/scripts/rules/delivered-rules.ts +61 -406
  645. package/scripts/rules/destructive-command.ts +2 -2
  646. package/scripts/rules/direct-filing.ts +4 -4
  647. package/scripts/rules/direct-pr-create.ts +2 -2
  648. package/scripts/rules/early-heartbeat.ts +15 -19
  649. package/scripts/rules/file-body.ts +5 -6
  650. package/scripts/rules/filing-cap.ts +6 -7
  651. package/scripts/rules/filing-offer.ts +1 -1
  652. package/scripts/rules/firing-point.ts +6 -6
  653. package/scripts/rules/gh-api.ts +2 -2
  654. package/scripts/rules/git-argv.ts +3 -3
  655. package/scripts/rules/git-force.ts +2 -2
  656. package/scripts/rules/hook-context-line.ts +31 -0
  657. package/scripts/rules/implementation-cut-verdict.ts +5 -8
  658. package/scripts/rules/implementation-cut.ts +35 -32
  659. package/scripts/rules/index-guard.ts +2 -2
  660. package/scripts/rules/issue-citation.ts +7 -7
  661. package/scripts/rules/issue-comments.ts +21 -13
  662. package/scripts/rules/josh-git-bare.ts +2 -2
  663. package/scripts/rules/lane-background.ts +14 -16
  664. package/scripts/rules/lane-carry-conflict.ts +41 -5
  665. package/scripts/rules/lane-interactive-ask.ts +6 -9
  666. package/scripts/rules/lane-park.ts +12 -16
  667. package/scripts/rules/lane-split-park.ts +1 -2
  668. package/scripts/rules/lane-switch-main.ts +10 -13
  669. package/scripts/rules/last-prompt.ts +1 -1
  670. package/scripts/rules/oracle-consulted.ts +5 -5
  671. package/scripts/rules/oracle-firing.ts +6 -9
  672. package/scripts/rules/oracle-list-cli.ts +2 -2
  673. package/scripts/rules/permission-guards.ts +2 -2
  674. package/scripts/rules/piped-verification.ts +79 -9
  675. package/scripts/rules/poll-loop.ts +9 -11
  676. package/scripts/rules/pre-gate-cut.ts +33 -30
  677. package/scripts/rules/prior-comment-read.ts +3 -3
  678. package/scripts/rules/protected-files.ts +25 -13
  679. package/scripts/rules/raw-field-body.ts +3 -4
  680. package/scripts/rules/reply-language.ts +1 -1
  681. package/scripts/rules/rule-body-guard.ts +10 -12
  682. package/scripts/rules/rule-guard.ts +1 -1
  683. package/scripts/rules/rule-list.ts +51 -0
  684. package/scripts/rules/rule-registry-rows.ts +282 -0
  685. package/scripts/rules/rule-registry.ts +109 -0
  686. package/scripts/rules/rule-value-cache.ts +2 -2
  687. package/scripts/rules/rule-value-cli.ts +6 -4
  688. package/scripts/rules/rule-value.ts +61 -22
  689. package/scripts/rules/run-tail-rule.ts +11 -15
  690. package/scripts/rules/shell-body-trigger.ts +7 -7
  691. package/scripts/rules/shell-segments.ts +2 -4
  692. package/scripts/rules/stop-rules.ts +54 -41
  693. package/scripts/rules/tail-commands.ts +1 -1
  694. package/scripts/rules/test-declared-commit.ts +2 -2
  695. package/scripts/rules/third-party-write.ts +3 -3
  696. package/scripts/rules/worktree-guard.ts +12 -5
  697. package/scripts/run/add/run-add-cli.ts +165 -0
  698. package/scripts/run/add/run-add.ts +124 -0
  699. package/scripts/run/board/run-board-cli.ts +207 -0
  700. package/scripts/run/board/run-board-closed.ts +95 -0
  701. package/scripts/run/board/run-board-every.ts +60 -0
  702. package/scripts/run/board/run-board-fetch.ts +38 -0
  703. package/scripts/run/board/run-board-fit.ts +219 -0
  704. package/scripts/run/board/run-board-github.ts +162 -0
  705. package/scripts/run/board/run-board-header.ts +275 -0
  706. package/scripts/run/board/run-board-kind.ts +35 -0
  707. package/scripts/run/board/run-board-labels.ts +299 -0
  708. package/scripts/run/board/run-board-layout.ts +222 -0
  709. package/scripts/run/board/run-board-link.ts +31 -0
  710. package/scripts/run/board/run-board-machine.ts +198 -0
  711. package/scripts/run/board/run-board-notes.ts +103 -0
  712. package/scripts/run/board/run-board-phase.ts +136 -0
  713. package/scripts/run/board/run-board-plan.ts +129 -0
  714. package/scripts/run/board/run-board-read.ts +62 -0
  715. package/scripts/run/board/run-board-render-legend.ts +82 -0
  716. package/scripts/run/board/run-board-render-notes.ts +77 -0
  717. package/scripts/run/board/run-board-render-slot.ts +50 -0
  718. package/scripts/run/board/run-board-render.ts +407 -0
  719. package/scripts/run/board/run-board-scope.ts +17 -0
  720. package/scripts/run/board/run-board-screen.ts +43 -0
  721. package/scripts/run/board/run-board-span.ts +66 -0
  722. package/scripts/run/board/run-board-spin.ts +115 -0
  723. package/scripts/run/board/run-board-state.ts +113 -0
  724. package/scripts/run/board/run-board-status.ts +279 -0
  725. package/scripts/run/board/run-board-tick.ts +210 -0
  726. package/scripts/run/board/run-board-track.ts +22 -0
  727. package/scripts/run/board/run-board-usage-read.ts +255 -0
  728. package/scripts/run/board/run-board-usage-rusage.ts +124 -0
  729. package/scripts/run/board/run-board-usage-text.ts +80 -0
  730. package/scripts/run/board/run-board-usage.ts +165 -0
  731. package/scripts/run/carry/run-carry-added.ts +62 -0
  732. package/scripts/run/carry/run-carry-args.ts +25 -22
  733. package/scripts/run/carry/run-carry-change.ts +1 -1
  734. package/scripts/run/carry/run-carry-cli.ts +71 -48
  735. package/scripts/run/carry/run-carry-conversation.ts +6 -7
  736. package/scripts/run/carry/run-carry-ended.ts +85 -0
  737. package/scripts/run/carry/run-carry-reclaim.ts +1 -1
  738. package/scripts/run/carry/run-carry-stash.ts +3 -2
  739. package/scripts/run/carry/run-carry-streak.ts +8 -10
  740. package/scripts/run/carry/run-carry.ts +85 -89
  741. package/scripts/run/cut/run-cut-args.ts +7 -7
  742. package/scripts/run/cut/run-cut-cli.ts +54 -36
  743. package/scripts/run/cut/run-cut-handoff.ts +15 -15
  744. package/scripts/run/cut/run-cut-report.ts +37 -16
  745. package/scripts/run/cut/run-cut.ts +63 -77
  746. package/scripts/run/detached-launch.ts +35 -50
  747. package/scripts/run/entry/run-entry-cli.ts +48 -27
  748. package/scripts/run/entry/run-entry-stop.ts +7 -9
  749. package/scripts/run/entry/run-entry.ts +5 -6
  750. package/scripts/run/event/run-event-cli.ts +5 -6
  751. package/scripts/run/event/run-event-filed.ts +69 -0
  752. package/scripts/run/event/run-event-follow.ts +3 -3
  753. package/scripts/run/event/run-event-plan.ts +38 -0
  754. package/scripts/run/event/run-event-render.ts +9 -4
  755. package/scripts/run/event/run-event-scope.ts +47 -18
  756. package/scripts/run/event/run-event-stream-emit.ts +64 -11
  757. package/scripts/run/event/run-event-stream.ts +171 -46
  758. package/scripts/run/event/run-event-watch.ts +4 -6
  759. package/scripts/run/hold/run-hold-cli.ts +65 -62
  760. package/scripts/run/hold/run-hold.ts +88 -46
  761. package/scripts/run/merge/run-merge-cli.ts +116 -77
  762. package/scripts/run/merge/run-merge-collect.ts +107 -0
  763. package/scripts/run/merge/run-merge-steps.ts +112 -65
  764. package/scripts/run/merge/run-merge-token.ts +30 -0
  765. package/scripts/run/merge/run-merge.ts +31 -22
  766. package/scripts/run/progress/run-progress-args.ts +4 -4
  767. package/scripts/run/progress/run-progress-cli.ts +39 -50
  768. package/scripts/run/progress/run-progress-clock.ts +25 -32
  769. package/scripts/run/progress/run-progress-config.ts +6 -9
  770. package/scripts/run/progress/run-progress-read.ts +9 -10
  771. package/scripts/run/progress/run-progress.ts +48 -53
  772. package/scripts/run/review/run-review-cli.ts +6 -6
  773. package/scripts/run/review/run-review-steps.ts +6 -6
  774. package/scripts/run/review/run-review.ts +9 -11
  775. package/scripts/run/run-cli-fault.ts +29 -0
  776. package/scripts/run/run-ending-cli.ts +3 -3
  777. package/scripts/run/run-ending.ts +10 -14
  778. package/scripts/run/run-halfrun-resume.ts +6 -8
  779. package/scripts/run/run-headless.ts +25 -12
  780. package/scripts/run/run-invocation.ts +17 -22
  781. package/scripts/run/run-label.ts +7 -5
  782. package/scripts/run/run-liveness-cli.ts +19 -6
  783. package/scripts/run/run-liveness.ts +27 -38
  784. package/scripts/run/run-next-cli.ts +5 -9
  785. package/scripts/run/run-next.ts +4 -5
  786. package/scripts/run/run-parent-cut-hook.ts +10 -12
  787. package/scripts/run/run-preflight.ts +25 -29
  788. package/scripts/run/run-prep-cli.ts +17 -13
  789. package/scripts/run/run-prep-locate.ts +4 -5
  790. package/scripts/run/run-prep.ts +7 -10
  791. package/scripts/run/run-prrun-resume.ts +2 -2
  792. package/scripts/run/run-report-cli.ts +4 -4
  793. package/scripts/run/run-report.ts +9 -14
  794. package/scripts/run/run-retrospective.ts +3 -3
  795. package/scripts/run/run-section.ts +42 -0
  796. package/scripts/run/run-stage-read.ts +2 -2
  797. package/scripts/run/run-stage.ts +6 -4
  798. package/scripts/run/run-status-cli.ts +7 -5
  799. package/scripts/run/run-status.ts +6 -7
  800. package/scripts/run/run-step-cli.ts +13 -15
  801. package/scripts/run/run-step.ts +58 -47
  802. package/scripts/run/run-stop-notify.ts +7 -8
  803. package/scripts/run/run-stranded-cli.ts +1 -1
  804. package/scripts/run/run-stranded-detect.ts +4 -4
  805. package/scripts/run/run-stranded.ts +11 -13
  806. package/scripts/run/run-tail-cli.ts +15 -16
  807. package/scripts/run/run-tail.ts +14 -33
  808. package/scripts/run/run-watcher-guard-cli.ts +3 -4
  809. package/scripts/run/run-watcher-guard.ts +11 -12
  810. package/scripts/run/run-watcher-hook.ts +6 -12
  811. package/scripts/run/ship/run-ship-cli.ts +67 -33
  812. package/scripts/run/ship/run-ship-detach.ts +15 -13
  813. package/scripts/run/ship/run-ship-lock.ts +1 -1
  814. package/scripts/run/ship/run-ship-next.ts +7 -8
  815. package/scripts/run/ship/run-ship-pre-detach.ts +27 -11
  816. package/scripts/run/ship/run-ship-preflight.ts +10 -11
  817. package/scripts/run/ship/run-ship-probe.ts +4 -4
  818. package/scripts/run/ship/run-ship-return.ts +1 -1
  819. package/scripts/run/ship/run-ship-review-steps.ts +43 -24
  820. package/scripts/run/ship/run-ship-review.ts +12 -14
  821. package/scripts/run/ship/run-ship-scoped.ts +15 -6
  822. package/scripts/run/ship/run-ship-stage.ts +80 -26
  823. package/scripts/run/ship/run-ship-steps.ts +26 -16
  824. package/scripts/run/ship/run-ship-stop-text.ts +4 -2
  825. package/scripts/run/ship/run-ship-sync.ts +9 -8
  826. package/scripts/run/ship/run-ship.ts +17 -32
  827. package/scripts/run/tidy/run-tidy-cli.ts +9 -5
  828. package/scripts/run/tidy/run-tidy-lanes.ts +18 -7
  829. package/scripts/run/tidy/run-tidy-stashes.ts +8 -8
  830. package/scripts/run/tidy/run-tidy.ts +4 -3
  831. package/scripts/run/wake/run-wake-cli.ts +27 -32
  832. package/scripts/run/wake/run-wake-describe.ts +24 -28
  833. package/scripts/run/wake/run-wake-driver.ts +14 -14
  834. package/scripts/run/wake/run-wake-handoff.ts +6 -6
  835. package/scripts/run/wake/run-wake-loop.ts +9 -9
  836. package/scripts/run/wake/run-wake-restart.ts +4 -5
  837. package/scripts/run/wake/run-wake-session.ts +23 -27
  838. package/scripts/run/wake/run-wake.ts +57 -279
  839. package/scripts/safe-chain/ci-installer-pin.ts +3 -3
  840. package/scripts/safe-chain/pack-hook.ts +2 -2
  841. package/scripts/safe-chain/preinstall-command.ts +2 -2
  842. package/scripts/security/security-audit-logic.ts +1 -1
  843. package/scripts/security/security-audit-provision-logic.ts +1 -1
  844. package/scripts/security/security-audit-provision.ts +2 -2
  845. package/scripts/security/security-audit.ts +5 -5
  846. package/scripts/security/security-updates-logic.ts +2 -3
  847. package/scripts/security/security-updates.ts +2 -4
  848. package/scripts/self-sync-guard/index.ts +1 -1
  849. package/scripts/self-sync-guard/self-sync-guard-logic.ts +2 -2
  850. package/scripts/self-sync-guard/self-sync-refusal.ts +1 -1
  851. package/scripts/sonar/sonar-hotspots-cli.ts +1 -1
  852. package/scripts/sonar/sonar-hotspots.ts +1 -1
  853. package/scripts/sonar/sonar-new-code-cli.ts +1 -1
  854. package/scripts/sonar/sonar-new-code.ts +1 -1
  855. package/scripts/sonar/sonar-project.ts +1 -1
  856. package/scripts/split/split-assess-cli.ts +1 -1
  857. package/scripts/split/split-assess.ts +3 -3
  858. package/scripts/sync/directory-copy-guard.ts +2 -3
  859. package/scripts/sync/managed-config-scope-cli.ts +1 -2
  860. package/scripts/sync/managed-config-scope.ts +4 -4
  861. package/scripts/sync/plugin-skill-directories.ts +2 -2
  862. package/scripts/sync/reconcile-templates.ts +17 -8
  863. package/scripts/sync/removed-skill-manifest.ts +2 -3
  864. package/scripts/sync/sync-ai-files.ts +7 -7
  865. package/scripts/sync/sync-configs.ts +30 -3
  866. package/scripts/sync/sync-hook-safety.ts +2 -2
  867. package/scripts/sync/sync.ts +23 -10
  868. package/scripts/sync/synced-paths.ts +2 -1
  869. package/scripts/sync/workflow-pin-logic.ts +1 -1
  870. package/scripts/test/test-declared-changed.ts +4 -4
  871. package/scripts/test/test-declared-logic.ts +2 -3
  872. package/scripts/test/test-declared-match.ts +25 -4
  873. package/scripts/test/test-declared.ts +26 -9
  874. package/scripts/test/test-red-commit.ts +3 -2
  875. package/scripts/test/test-red-logic.ts +7 -14
  876. package/scripts/test/test-red.ts +12 -47
  877. package/scripts/test/test-related-scope.ts +2 -3
  878. package/scripts/test/test-related.ts +3 -3
  879. package/scripts/test/test-type-logic.ts +1 -2
  880. package/scripts/test/test-unit-guard.ts +13 -17
  881. package/scripts/test/unit-worker-share.ts +7 -8
  882. package/scripts/time-runtime/time-agent-bundles.ts +2 -4
  883. package/scripts/time-runtime/time-background.ts +17 -21
  884. package/scripts/time-runtime/time-batch-guard.ts +67 -342
  885. package/scripts/time-runtime/time-bundle-call.ts +26 -28
  886. package/scripts/time-runtime/time-bundles.ts +11 -12
  887. package/scripts/time-runtime/time-call-identity.ts +1 -1
  888. package/scripts/time-runtime/time-command-key.ts +2 -2
  889. package/scripts/time-runtime/time-density-hook.ts +8 -11
  890. package/scripts/time-runtime/time-density.ts +5 -5
  891. package/scripts/time-runtime/time-followup-stage.ts +7 -7
  892. package/scripts/time-runtime/time-format.ts +5 -5
  893. package/scripts/time-runtime/time-hook-transcript.ts +3 -3
  894. package/scripts/time-runtime/time-instant.ts +1 -1
  895. package/scripts/time-runtime/time-markers.ts +15 -19
  896. package/scripts/time-runtime/time-phase-names.ts +3 -3
  897. package/scripts/time-runtime/time-reported-failure.ts +15 -19
  898. package/scripts/time-runtime/time-round-trips.ts +20 -23
  899. package/scripts/time-runtime/time-shell.ts +8 -8
  900. package/scripts/time-runtime/time-single-check.ts +1 -2
  901. package/scripts/time-runtime/time-spans.ts +35 -40
  902. package/scripts/time-runtime/time-tool-call.ts +15 -16
  903. package/scripts/time-runtime/time-transcript-line.ts +53 -34
  904. package/scripts/time-runtime/time-writes.ts +5 -5
  905. package/scripts/ui/ui-routes-cli.ts +1 -2
  906. package/scripts/ui/ui-routes.ts +1 -2
  907. package/scripts/version/bump-version.ts +1 -1
  908. package/scripts/version/fresh-metadata-cache.ts +2 -2
  909. package/scripts/version/latest-corepack.ts +26 -26
  910. package/scripts/version/latest-lane-guard.ts +1 -1
  911. package/scripts/version/latest-scope-cli.ts +2 -2
  912. package/scripts/version/latest-stamp.ts +1 -2
  913. package/scripts/version/latest-update.ts +2 -2
  914. package/scripts/version/npm-registry.ts +2 -2
  915. package/scripts/version/package-manager-version.ts +18 -0
  916. package/scripts/version/publishable-range-check.ts +2 -1
  917. package/scripts/version/publishable-range.ts +1 -1
  918. package/scripts/version/release-age.ts +11 -11
  919. package/scripts/version/release-hold.ts +2 -2
  920. package/scripts/version/safe-chain-version-update.ts +3 -3
  921. package/scripts/version/version-check-logic.ts +2 -3
  922. package/scripts/version/version-check.ts +1 -2
  923. package/scripts/version/version-command-config.ts +2 -2
  924. package/scripts/version/version-commands.ts +3 -3
  925. package/scripts/version/version-remote.ts +4 -4
  926. package/scripts/version/version-targets.ts +2 -2
  927. package/templates/gitignore +7 -0
  928. package/dist/hooks/chunk-KHX4U3BG.js +0 -6400
  929. package/dist/hooks/chunk-RKUAD3I6.js +0 -90
  930. package/dist/hooks/chunk-WPALEIRX.js +0 -18
  931. package/scripts/backlog/backlog-restructure.ts +0 -152
  932. package/scripts/rules/issue-fold-rule.ts +0 -72
  933. package/scripts/rules/wip-cap.ts +0 -63
  934. package/scripts/run/run-issue-number.ts +0 -19
@@ -3,7 +3,7 @@ import path from 'node:path'
3
3
  import { buffered_process } from '#scripts/lib/buffered-process'
4
4
  import { INSTALL_TIMEOUT_MS } from '#scripts/lib/timeouts'
5
5
 
6
- // Filling the lane, which is the other half of opening one (joshuafolkken/kit#1554).
6
+ // Filling the lane, which is the other half of opening one.
7
7
  //
8
8
  // **A work tree with no `node_modules` is not a lane yet.** A linked work tree starts as a checkout
9
9
  // and nothing else, and the lane root is a hidden *sibling* of the repository, so nothing above it
@@ -19,7 +19,7 @@ import { INSTALL_TIMEOUT_MS } from '#scripts/lib/timeouts'
19
19
  // The child is spawned through `buffered_process` rather than through `execa` here. What this needs
20
20
  // is exactly that module's contract — output buffered rather than inherited, a non-zero exit
21
21
  // reported rather than thrown, and a bound on how long the child may hang — and a second copy of it
22
- // is how a fix to one missed the other before (joshuafolkken/kit#914).
22
+ // is how a fix to one missed the other before.
23
23
 
24
24
  // `--frozen-lockfile` because a lane is cut from `refs/remotes/origin/<default>` and has to build
25
25
  // exactly the lock committed there. A lock the install would rather rewrite is a finding, not
@@ -27,8 +27,8 @@ import { INSTALL_TIMEOUT_MS } from '#scripts/lib/timeouts'
27
27
  const INSTALL_ARGUMENTS = ['install', '--frozen-lockfile']
28
28
  // The manifest whose absence is the whole skip condition. A lane cut from a repository that has no
29
29
  // `package.json` has nothing to install, so running `pnpm install` there could only fail on a
30
- // manifest that was never there — which is exactly the fixture a cross-process lane test needs
31
- // (joshuafolkken/kit#2148). The condition is strictly "the file does not exist": a manifest that is
30
+ // manifest that was never there — which is exactly the fixture a cross-process lane test needs.
31
+ // The condition is strictly "the file does not exist": a manifest that is
32
32
  // present but unreadable or broken still runs the install and still fails as before, so a genuinely
33
33
  // broken repository is never passed silently.
34
34
  const MANIFEST_FILE_NAME = 'package.json'
@@ -46,10 +46,9 @@ interface InstallResult {
46
46
 
47
47
  // A lane with no manifest has nothing to install, so the install is skipped rather than run — the
48
48
  // seam a cross-process lane test needs, and a root-cause fix rather than a switch, because running
49
- // an install with no install target was the defect (joshuafolkken/kit#2148). The condition is
50
- // strictly the file's absence: `existsSync` answers only whether the path is there, never whether
51
- // its contents parse, so a present-but-broken manifest falls through to the real install and fails
52
- // exactly as before.
49
+ // an install with no install target is the defect. The condition is strictly the file's absence:
50
+ // `existsSync` answers only whether the path is there, never whether its contents parse, so a
51
+ // present-but-broken manifest falls through to the real install and fails there.
53
52
  function has_manifest(directory: string): boolean {
54
53
  return existsSync(path.join(directory, MANIFEST_FILE_NAME))
55
54
  }
@@ -58,12 +57,12 @@ function has_manifest(directory: string): boolean {
58
57
  * Install the lane's dependencies, and report whether it worked rather than throwing.
59
58
  *
60
59
  * **A lane with no `package.json` skips the install** — there is nothing to install, so the reported
61
- * state is installed rather than failed, and no child is spawned (joshuafolkken/kit#2148). This is
60
+ * state is installed rather than failed, and no child is spawned. This is
62
61
  * the only seam: the production call path, its arguments and its environment are all unchanged.
63
62
  *
64
63
  * **The verdict is the exit code and only the exit code.** `pnpm install` runs `prepare`, which runs
65
64
  * the lefthook installer, and in a linked work tree the hooks are shared with the primary repository
66
- * — so a warning from it is expected and correct (joshuafolkken/kit#1503, #1507). Reading the child's
65
+ * — so a warning from it is expected and correct. Reading the child's
67
66
  * text for a word like "failed" would turn that correct warning into a refusal to open a lane.
68
67
  */
69
68
  async function install_dependencies(directory: string): Promise<InstallResult> {
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env tsx
2
2
  import { fileURLToPath } from 'node:url'
3
+ import { issue_number_shape } from '#scripts/issue/issue-number-shape'
3
4
  import { josh_command } from '#scripts/josh/josh-run'
4
5
  import { lane_registry, type LaneInfo } from '#scripts/lane/lane-registry'
5
6
  import { lane_vacant } from '#scripts/lane/lane-vacant'
@@ -8,7 +9,7 @@ import { INSTALL_TIMEOUT_MS } from '#scripts/lib/timeouts'
8
9
  import { execa } from 'execa'
9
10
 
10
11
  // `josh lane:launch <issue> [--stash <message>]` — one composite command for a `backlogrun` lane-start
11
- // event (joshuafolkken/kit#2162). Opening one lane was four to six turns of the parent: `lane:open`,
12
+ // event. Opening one lane was four to six turns of the parent: `lane:open`,
12
13
  // then — only the first lane, and only when `josh latest` had stashed — `stash:pop` and a re-install,
13
14
  // then `lane:dispatch`. This collapses them into one call that returns the child's pid, or a refusal,
14
15
  // the same shape `lane:dispatch` alone has.
@@ -24,7 +25,6 @@ const SUCCESS_EXIT_CODE = 0
24
25
  const FAILURE_EXIT_CODE = 1
25
26
  const should_forward_stderr = true
26
27
  const PNPM = 'pnpm'
27
- const ISSUE_PATTERN = /^[1-9]\d*$/u
28
28
 
29
29
  const USAGE = 'Usage: josh lane:launch <issue-number> [--stash <message>]'
30
30
 
@@ -44,7 +44,13 @@ function read_context(argv: ReadonlyArray<string>): LaunchContext | undefined {
44
44
 
45
45
  const [issue, ...rest] = parsed.positionals
46
46
 
47
- if (issue === undefined || rest.length > 0 || !ISSUE_PATTERN.test(issue)) return undefined
47
+ if (
48
+ issue === undefined ||
49
+ rest.length > 0 ||
50
+ !issue_number_shape.ISSUE_NUMBER_PATTERN.test(issue)
51
+ ) {
52
+ return undefined
53
+ }
48
54
 
49
55
  return { issue, stash: parsed.values.stash }
50
56
  }
@@ -82,8 +88,7 @@ async function prepare(stash: string | undefined, directory: string): Promise<bo
82
88
  }
83
89
 
84
90
  // Where the chain ended. `unopened` is a `lane:open` refusal — no lane was taken; `failed` is a step
85
- // after it, which leaves the opened lane holding a seat, so a caller cannot read the two alike
86
- // (joshuafolkken/kit#3027).
91
+ // after it, which leaves the opened lane holding a seat, so a caller cannot read the two alike.
87
92
  type LaunchOutcome = { kind: 'launched'; pid: string } | { kind: 'unopened' } | { kind: 'failed' }
88
93
 
89
94
  const UNOPENED: LaunchOutcome = { kind: 'unopened' }
@@ -95,7 +100,7 @@ async function close_if_vacant(lane: LaneInfo | undefined): Promise<void> {
95
100
  await josh_command.josh_run(['lane:close', lane.issue], should_forward_stderr)
96
101
  }
97
102
 
98
- // **A lane a park kept open is resumed, not reopened** (joshuafolkken/kit#3228). A child parked before
103
+ // **A lane a park kept open is resumed, not reopened**. A child parked before
99
104
  // its commit leaves its uncommitted work in its lane, and `lane:open` refuses that lane as
100
105
  // `already-open` — so the released child is dispatched into the kept tree instead. **Only a lane a
101
106
  // child was already dispatched into counts as kept**: `lane:dispatch` records the child's output in the
@@ -103,7 +108,7 @@ async function close_if_vacant(lane: LaneInfo | undefined): Promise<void> {
103
108
  // `lane:open` and its refusal. So does a stranded lane, whose `.env` is gone with its tree.
104
109
  //
105
110
  // **A lane no child was dispatched into and that holds nothing is closed and opened afresh**
106
- // (joshuafolkken/kit#3289) — a run cut between the open and the dispatch leaves one. It is reopened
111
+ // — a run cut between the open and the dispatch leaves one. It is reopened
107
112
  // rather than reused because nothing recorded whether its install finished. A lane with work or a live
108
113
  // process in it still meets `lane:open`'s refusal.
109
114
  async function lane_directory(issue: string): Promise<string | undefined> {
@@ -119,7 +124,7 @@ async function lane_directory(issue: string): Promise<string | undefined> {
119
124
  }
120
125
 
121
126
  // The launch chain in-process. The CLI prints the pid; `backlog:drive` launches through this same
122
- // chain (joshuafolkken/kit#2508).
127
+ // chain.
123
128
  async function launch_lane(context: LaunchContext): Promise<LaunchOutcome> {
124
129
  const directory = await lane_directory(context.issue)
125
130
 
@@ -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 }
@@ -5,7 +5,7 @@ import { ENV_FILE_NAME } from '#ports'
5
5
  import { git_spawn } from '#scripts/git/git-spawn'
6
6
  import { IGNORED_CACHE_FILES } from '#scripts/josh/josh-command-types'
7
7
 
8
- // 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.
9
9
  //
10
10
  // **Nothing else can see it.** `lane:list` and `lane:prune` read `git worktree list`, so a directory
11
11
  // whose registration is gone is invisible to both, and `git worktree add` refuses its path for good —
@@ -15,7 +15,7 @@ import { IGNORED_CACHE_FILES } from '#scripts/josh/josh-command-types'
15
15
  // **The test for removing it is that removing it loses nothing**, not a list of names. Every file in
16
16
  // it has to hold content the repository's history already stores — a blob some ref reaches — so git
17
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** (joshuafolkken/kit#3370): a
18
+ // gone. **Any commit's content, not only `HEAD`'s at the same path**: a
19
19
  // leftover is a checkout of whatever commit its lane was on, and measured against `HEAD` the
20
20
  // leftovers that issue found differed in 167 to 1,431 files each while every one of them was in the
21
21
  // history. A list of generated names would break the next time a file is generated, and would delete
@@ -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