@joshuafolkken/kit 1.1514.0 → 1.1784.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (858) hide show
  1. package/.claude/agents/investigator.md +1 -1
  2. package/.claude/settings.json +5 -5
  3. package/.claude/skills/epic-commands/SKILL.md +26 -65
  4. package/.claude/skills/epic-commands/epic-bundle.md +3 -1
  5. package/.claude/skills/workflow-commands/SKILL.md +5 -5
  6. package/.claude/skills/workflow-commands/background-commands.md +5 -5
  7. package/.claude/skills/workflow-commands/backlogrun-child.md +10 -8
  8. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
  9. package/.claude/skills/workflow-commands/backlogrun-lanes.md +17 -13
  10. package/.claude/skills/workflow-commands/backlogrun-park.md +14 -23
  11. package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -2
  12. package/.claude/skills/workflow-commands/backlogrun-recovery.md +5 -5
  13. package/.claude/skills/workflow-commands/backlogrun-steps.md +10 -10
  14. package/.claude/skills/workflow-commands/backlogrun.md +1 -1
  15. package/.claude/skills/workflow-commands/chain-rule.md +13 -7
  16. package/.claude/skills/workflow-commands/delegation.md +6 -5
  17. package/.claude/skills/workflow-commands/entry-sequence.md +9 -9
  18. package/.claude/skills/workflow-commands/followup.md +9 -31
  19. package/.claude/skills/workflow-commands/fullrun-steps.md +36 -45
  20. package/.claude/skills/workflow-commands/fullrun.md +2 -2
  21. package/.claude/skills/workflow-commands/halfrun.md +17 -25
  22. package/.claude/skills/workflow-commands/issue-comments.md +16 -12
  23. package/.claude/skills/workflow-commands/issue-scout.md +2 -2
  24. package/.claude/skills/workflow-commands/kickoff.md +24 -23
  25. package/.claude/skills/workflow-commands/latest-gate.md +7 -12
  26. package/.claude/skills/workflow-commands/needs-human-review.md +9 -14
  27. package/.claude/skills/workflow-commands/observation-filing.md +4 -36
  28. package/.claude/skills/workflow-commands/observation-ledger.md +1 -1
  29. package/.claude/skills/workflow-commands/pre-gate-cut.md +13 -30
  30. package/.claude/skills/workflow-commands/prerequisite.md +10 -16
  31. package/.claude/skills/workflow-commands/progress-watcher.md +1 -1
  32. package/.claude/skills/workflow-commands/prrun.md +3 -7
  33. package/.claude/skills/workflow-commands/retrospective.md +1 -1
  34. package/.claude/skills/workflow-commands/split-assessment.md +13 -1
  35. package/.claude/skills/workflow-commands/working-tree-hold.md +9 -9
  36. package/.codex/hooks.json +5 -5
  37. package/.github/actions/setup-node/action.yml +9 -0
  38. package/.github/actions/setup-pnpm/action.yml +1 -1
  39. package/.github/dependabot.yml +16 -0
  40. package/.github/release.yml +0 -2
  41. package/.github/workflows/ci.yml +120 -10
  42. package/.github/workflows/publish.yml +8 -1
  43. package/.github/workflows/sonar-qube.yml +1 -0
  44. package/.prettierignore +2 -0
  45. package/.vscode/tasks.json +1 -2
  46. package/CLAUDE.md +3 -7
  47. package/README.md +4 -2
  48. package/SECURITY.md +1 -1
  49. package/dist/CLAUDE.md +3 -7
  50. package/dist/commands/document-read-cli.js +882 -0
  51. package/dist/commands/{document-section-cli.js → document-section-main.js} +79 -37
  52. package/dist/commands/read-set-cli.js +1867 -0
  53. package/dist/commands/run-prep-main.js +21653 -0
  54. package/dist/commands/run-step-cli.js +23880 -0
  55. package/dist/config-merge/index.js +5 -1
  56. package/dist/hooks/audit-provision.js +20 -35
  57. package/dist/hooks/{chunk-DGT54IH5.js → chunk-AZX4FGQ3.js} +63 -17
  58. package/dist/hooks/chunk-CWMBGKYW.js +6483 -0
  59. package/dist/hooks/chunk-O2YBIDSI.js +4306 -0
  60. package/dist/hooks/{chunk-TNUMY6NL.js → chunk-PT5R6UJD.js} +4193 -1900
  61. package/dist/hooks/chunk-TUIFS5E7.js +72 -0
  62. package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
  63. package/dist/hooks/{chunk-APUO6U4J.js → chunk-WR2KQAYZ.js} +1843 -440
  64. package/dist/hooks/{chunk-O6GDRNJB.js → chunk-XGBNSWEI.js} +248 -46
  65. package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
  66. package/dist/hooks/codex-hook-adapter.js +10 -22
  67. package/dist/hooks/format-edited.js +5 -6
  68. package/dist/hooks/inputs.json +443 -317
  69. package/dist/hooks/pretool-guard.js +7 -25
  70. package/dist/hooks/session-lang.js +44 -51
  71. package/dist/hooks/stop-guard.js +7716 -2187
  72. package/dist/josh.js +6002 -3583
  73. package/dist/self-sync-guard/index.js +74 -10
  74. package/dist/version/index.js +115 -406
  75. package/eslint/base.js +1 -1
  76. package/lefthook/base.yml +3 -1
  77. package/package.json +10 -48
  78. package/pnpm-workspace.yaml +4 -2
  79. package/prompts/coding-standards.md +1 -1
  80. package/prompts/collaboration-workflow/file-edits.md +1 -7
  81. package/prompts/collaboration-workflow/issue-citation.md +1 -1
  82. package/prompts/collaboration-workflow/issue-template.md +33 -16
  83. package/prompts/collaboration-workflow/lane-instructions.md +1 -2
  84. package/prompts/collaboration-workflow/measurement.md +37 -0
  85. package/prompts/collaboration-workflow/operating-rules.md +4 -6
  86. package/prompts/collaboration-workflow/output-bounds.md +2 -7
  87. package/prompts/collaboration-workflow/plan-comment.md +3 -42
  88. package/prompts/collaboration-workflow/principles.md +5 -0
  89. package/prompts/collaboration-workflow/report-format.md +31 -60
  90. package/prompts/collaboration-workflow/residency.md +2 -2
  91. package/prompts/collaboration-workflow/shell-body.md +6 -16
  92. package/prompts/collaboration-workflow/turn-batching.md +0 -2
  93. package/prompts/collaboration-workflow/upstream-interrupt.md +14 -4
  94. package/prompts/collaboration-workflow/wip-cap.md +1 -1
  95. package/prompts/collaboration-workflow.md +3 -7
  96. package/prompts/refactoring.md +1 -1
  97. package/prompts/review-rubric.md +1 -2
  98. package/prompts/review.md +41 -21
  99. package/prompts/testing-guide.md +8 -43
  100. package/scripts/agent/agent-event.ts +15 -15
  101. package/scripts/agent/agent-exit-record.ts +13 -1
  102. package/scripts/agent/api-auth.ts +41 -0
  103. package/scripts/agent/api-outage.ts +1 -1
  104. package/scripts/auto-ok/auto-ok-cli.ts +14 -16
  105. package/scripts/auto-ok/auto-ok-judge-read.ts +12 -3
  106. package/scripts/auto-ok/auto-ok-judge-write.ts +46 -19
  107. package/scripts/auto-ok/auto-ok-judge.ts +13 -2
  108. package/scripts/auto-ok/auto-ok-main.ts +17 -0
  109. package/scripts/backlog/backlog-arrival.ts +14 -3
  110. package/scripts/backlog/backlog-budget-cli.ts +7 -33
  111. package/scripts/backlog/backlog-budget-main.ts +16 -0
  112. package/scripts/backlog/backlog-budget.ts +2 -3
  113. package/scripts/backlog/backlog-defect-priority.ts +4 -3
  114. package/scripts/backlog/backlog-drive-adopt.ts +67 -0
  115. package/scripts/backlog/backlog-drive-args.ts +4 -5
  116. package/scripts/backlog/backlog-drive-cli.ts +113 -28
  117. package/scripts/backlog/backlog-drive-hold.ts +162 -0
  118. package/scripts/backlog/backlog-drive-idle.ts +151 -0
  119. package/scripts/backlog/backlog-drive-judge.ts +25 -0
  120. package/scripts/backlog/backlog-drive-memory.ts +126 -0
  121. package/scripts/backlog/backlog-drive-named-offer.ts +5 -10
  122. package/scripts/backlog/backlog-drive-named.ts +53 -6
  123. package/scripts/backlog/backlog-drive-offer-argv.ts +3 -8
  124. package/scripts/backlog/backlog-drive-paused.ts +169 -0
  125. package/scripts/backlog/backlog-drive-restore.ts +30 -7
  126. package/scripts/backlog/backlog-drive-seats.ts +18 -8
  127. package/scripts/backlog/backlog-drive-token-handling.ts +38 -0
  128. package/scripts/backlog/backlog-drive.ts +79 -75
  129. package/scripts/backlog/backlog-next-main.ts +16 -0
  130. package/scripts/backlog/backlog-next-shared.ts +73 -0
  131. package/scripts/backlog/backlog-next.ts +48 -16
  132. package/scripts/backlog/backlog-occupied.ts +52 -39
  133. package/scripts/backlog/backlog-offer-cli.ts +6 -21
  134. package/scripts/backlog/backlog-offer-exclude.ts +15 -0
  135. package/scripts/backlog/backlog-offer-main.ts +12 -0
  136. package/scripts/backlog/backlog-offer.ts +36 -3
  137. package/scripts/backlog/backlog-overlap.ts +22 -4
  138. package/scripts/backlog/backlog-plan-read.ts +6 -2
  139. package/scripts/backlog/backlog-plan.ts +18 -4
  140. package/scripts/backlog/backlog-pool.ts +10 -10
  141. package/scripts/backlog/backlog-rank.ts +10 -2
  142. package/scripts/backlog/backlog-ready.ts +112 -30
  143. package/scripts/backlog/backlog-stalled-detect.ts +109 -36
  144. package/scripts/backlog/backlog-stalled.ts +52 -16
  145. package/scripts/backlog/backlog-wait-cause.ts +86 -0
  146. package/scripts/backlog/backlog-waves.ts +39 -13
  147. package/scripts/backlog/backlogrun-args.ts +19 -7
  148. package/scripts/backlog/backlogrun-cli.ts +19 -5
  149. package/scripts/backlog/backlogrun-launch.ts +6 -0
  150. package/scripts/backlog/backlogrun-restart.ts +97 -0
  151. package/scripts/backlog/backlogrun-stop.ts +79 -7
  152. package/scripts/behavior/behavior-cli.ts +2 -2
  153. package/scripts/behavior/behavior-rules.ts +47 -24
  154. package/scripts/build/build-bin.ts +2 -16
  155. package/scripts/build/build-claude-md.ts +0 -7
  156. package/scripts/build/build-commands.ts +0 -13
  157. package/scripts/build/build-hooks.ts +49 -48
  158. package/scripts/build/hook-bundle-stamp.ts +29 -11
  159. package/scripts/build/local-bin.ts +1 -1
  160. package/scripts/cases/cases-cli.ts +25 -13
  161. package/scripts/cases/cases-interaction-scan.ts +134 -0
  162. package/scripts/cases/cases-interaction.ts +183 -0
  163. package/scripts/cases/cases-logic.ts +39 -6
  164. package/scripts/ci/pr-classification-main.ts +18 -0
  165. package/scripts/ci/pr-classification.ts +10 -17
  166. package/scripts/clone/clone-scan.ts +1 -1
  167. package/scripts/cost-runtime/cost-blocks.ts +22 -37
  168. package/scripts/cost-runtime/cost-cli.ts +31 -14
  169. package/scripts/cost-runtime/cost-main.ts +12 -0
  170. package/scripts/cost-runtime/cost-transcript.ts +1 -0
  171. package/scripts/delegation/delegation-policy.ts +17 -4
  172. package/scripts/delegation/duplicate-read-guard.ts +0 -8
  173. package/scripts/delegation/investigation-guard.ts +0 -8
  174. package/scripts/delegation/investigation-reads.ts +3 -4
  175. package/scripts/dependabot/dependabot-cooldown.ts +194 -0
  176. package/scripts/discovery/repo-discovery.ts +24 -6
  177. package/scripts/doctor/doctor-consumer.ts +2 -5
  178. package/scripts/document/document-byte-budget.ts +8 -6
  179. package/scripts/document/document-scan.ts +1 -1
  180. package/scripts/document/document-section-cli.ts +0 -8
  181. package/scripts/document/document-section-main.ts +12 -0
  182. package/scripts/epic/epic-audit-cli.ts +12 -6
  183. package/scripts/epic/epic-bundle-apply.ts +137 -0
  184. package/scripts/epic/epic-bundle-cli.ts +32 -121
  185. package/scripts/epic/epic-bundle-format.ts +116 -0
  186. package/scripts/epic/epic-bundle-main.ts +17 -0
  187. package/scripts/epic/epic-busy.ts +5 -12
  188. package/scripts/epic/epic-classify.ts +24 -15
  189. package/scripts/epic/epic-cli-argv.ts +31 -0
  190. package/scripts/epic/epic-cli-decide.ts +42 -0
  191. package/scripts/epic/epic-cli.ts +6 -38
  192. package/scripts/epic/epic-close.ts +112 -55
  193. package/scripts/epic/epic-cross-repo.ts +4 -7
  194. package/scripts/epic/epic-decide.ts +119 -0
  195. package/scripts/epic/epic-decision.ts +9 -0
  196. package/scripts/epic/epic-fetch.ts +4 -0
  197. package/scripts/epic/epic-graph.ts +2 -0
  198. package/scripts/epic/epic-issue.ts +5 -1
  199. package/scripts/epic/epic-label-age.ts +1 -1
  200. package/scripts/epic/epic-lane-offer.ts +39 -4
  201. package/scripts/epic/epic-next-main.ts +24 -0
  202. package/scripts/epic/epic-next.ts +6 -24
  203. package/scripts/epic/epic-outside-blocker.ts +6 -2
  204. package/scripts/epic/epic-parse.ts +9 -3
  205. package/scripts/epic/epic-read.ts +1 -0
  206. package/scripts/epic/epic-reconcile.ts +39 -0
  207. package/scripts/epic/epic-run.ts +10 -1
  208. package/scripts/epic/epic-solo.ts +50 -14
  209. package/scripts/epic/epic.ts +41 -7
  210. package/scripts/exports/unused-members-cli.ts +2 -2
  211. package/scripts/followup/followup-checks-event.ts +8 -3
  212. package/scripts/followup/followup-coderabbit-wait.ts +82 -0
  213. package/scripts/followup/followup-review-gates.ts +81 -0
  214. package/scripts/followup/git-followup-stages.ts +13 -3
  215. package/scripts/followup/git-followup-workflow.ts +19 -66
  216. package/scripts/followup/git-pr-followup-wrapup.ts +9 -14
  217. package/scripts/followup/git-pr-followup.ts +36 -8
  218. package/scripts/fresh-machine/fresh-machine-cli.ts +1 -1
  219. package/scripts/fresh-machine/fresh-machine-run.ts +8 -8
  220. package/scripts/fresh-machine/specs/kit-test-backlogrun.json +1 -1
  221. package/scripts/gate/busy-average.ts +58 -0
  222. package/scripts/gate/check-cpu.ts +60 -0
  223. package/scripts/gate/check-inputs.ts +39 -95
  224. package/scripts/gate/check-reuse.ts +33 -54
  225. package/scripts/gate/command-memory.ts +192 -0
  226. package/scripts/gate/core-admission.ts +218 -28
  227. package/scripts/gate/core-budget-timing.ts +37 -0
  228. package/scripts/gate/core-budget.ts +80 -98
  229. package/scripts/gate/core-wait-record.ts +48 -0
  230. package/scripts/gate/core-wait.ts +37 -5
  231. package/scripts/gate/core-weights.ts +86 -0
  232. package/scripts/gate/free-cores.ts +27 -4
  233. package/scripts/gate/gate-ledger.ts +32 -4
  234. package/scripts/gate/gate-plan.ts +41 -34
  235. package/scripts/gate/gate-report.ts +14 -2
  236. package/scripts/gate/gate-run-steps.ts +53 -8
  237. package/scripts/gate/gate-skip.ts +12 -2
  238. package/scripts/gate/gate-steps.ts +12 -1
  239. package/scripts/gate/input-fingerprint.ts +42 -0
  240. package/scripts/gate/machine-capacity.ts +65 -31
  241. package/scripts/gate/moved-paths.ts +67 -0
  242. package/scripts/gate/project-checks.ts +5 -12
  243. package/scripts/gate/scoped-green.ts +12 -8
  244. package/scripts/gate/since-green.ts +62 -0
  245. package/scripts/gate/toolchain-inputs.ts +115 -0
  246. package/scripts/gate/verification-gate.ts +27 -24
  247. package/scripts/gate/verification-inputs.ts +250 -0
  248. package/scripts/gh/gh-author-association.ts +96 -9
  249. package/scripts/gh/git-ai-review-scan.ts +4 -2
  250. package/scripts/gh/git-gh-api-path.ts +15 -0
  251. package/scripts/gh/git-gh-branch-rules.ts +73 -0
  252. package/scripts/gh/git-gh-conditional.ts +5 -2
  253. package/scripts/gh/git-gh-issue-read.ts +5 -1
  254. package/scripts/gh/git-gh-issue-write.ts +67 -29
  255. package/scripts/gh/git-gh-issue.ts +7 -3
  256. package/scripts/gh/git-gh-poll-read.ts +89 -0
  257. package/scripts/gh/git-gh-pr-auto-merge.ts +8 -3
  258. package/scripts/gh/git-gh-pr-rest.ts +1 -1
  259. package/scripts/gh/git-gh-pr-snapshot.ts +33 -20
  260. package/scripts/gh/git-gh-pr.ts +27 -15
  261. package/scripts/gh/git-pr-checks-eval.ts +39 -7
  262. package/scripts/gh/git-pr-checks-parse.ts +39 -9
  263. package/scripts/gh/git-pr-merge-checked.ts +80 -0
  264. package/scripts/git/base-tree.ts +19 -2
  265. package/scripts/git/changed-file-scope.ts +6 -4
  266. package/scripts/git/changed-paths.ts +18 -1
  267. package/scripts/git/git-diff-reads.ts +27 -2
  268. package/scripts/git/git-grep-hits.ts +85 -0
  269. package/scripts/git/git-location-environment.ts +1 -1
  270. package/scripts/git/git-merge-conflicts.ts +83 -0
  271. package/scripts/git/git-preflight.ts +37 -12
  272. package/scripts/git/git-push-transport.ts +1 -2
  273. package/scripts/git/git-schemas.ts +17 -7
  274. package/scripts/git/git-spawn.ts +1 -2
  275. package/scripts/git/git-status.ts +4 -4
  276. package/scripts/git/main-merge-main.ts +12 -0
  277. package/scripts/git/main-merge-regenerate.ts +2 -2
  278. package/scripts/git/main-merge.ts +25 -9
  279. package/scripts/git/main-sync-main.ts +12 -0
  280. package/scripts/git/main-sync.ts +0 -9
  281. package/scripts/git/stash/git-stash.ts +27 -4
  282. package/scripts/git/stash/{stash-pop-args.ts → stash-args.ts} +13 -10
  283. package/scripts/git/stash/stash-pop-cli.ts +6 -12
  284. package/scripts/git/stash/stash-pop-main.ts +12 -0
  285. package/scripts/git/stash/stash-push-cli.ts +76 -0
  286. package/scripts/git/stash/stash-push-main.ts +12 -0
  287. package/scripts/hooks/batch-guard.ts +0 -8
  288. package/scripts/hooks/check-commit-message-main.ts +8 -0
  289. package/scripts/hooks/check-commit-message.ts +4 -7
  290. package/scripts/hooks/format-edited-file.ts +8 -24
  291. package/scripts/hooks/pre-commit-lint.ts +30 -3
  292. package/scripts/hooks/pre-push-unit.ts +4 -2
  293. package/scripts/hooks/pretool-guard-cli.ts +1 -8
  294. package/scripts/hooks/pretool-guard.ts +32 -19
  295. package/scripts/hooks/reserved-run.ts +67 -9
  296. package/scripts/hooks/run-hook.sh +13 -4
  297. package/scripts/hooks/shell-rules-notice.ts +37 -0
  298. package/scripts/hooks/stop-actions.ts +2 -21
  299. package/scripts/hooks/stop-guard.ts +13 -9
  300. package/scripts/init/hook-command-rewrite.ts +19 -5
  301. package/scripts/init/hook-launch.ts +15 -17
  302. package/scripts/init/init-actions.ts +0 -6
  303. package/scripts/init/init-ai-copy.ts +10 -36
  304. package/scripts/init/init-bootstrap.ts +9 -8
  305. package/scripts/init/init-dry-run-report.ts +1 -1
  306. package/scripts/init/init-dry-run.ts +1 -1
  307. package/scripts/init/init-file-action.ts +7 -9
  308. package/scripts/init/init-logic-json-merge.ts +2 -2
  309. package/scripts/init/init-logic-migrate.ts +9 -82
  310. package/scripts/init/init-logic.ts +3 -2
  311. package/scripts/init/init-main.ts +12 -0
  312. package/scripts/init/init.ts +5 -12
  313. package/scripts/init/kit-development-versions.ts +3 -7
  314. package/scripts/init/kit-written-paths.ts +2 -2
  315. package/scripts/init/project-profile.ts +5 -4
  316. package/scripts/init/tsconfig-preset-migration.ts +2 -1
  317. package/scripts/init/vscode-tasks.ts +1 -1
  318. package/scripts/issue/defect-origin-cli.ts +106 -0
  319. package/scripts/issue/defect-origin-line.ts +60 -0
  320. package/scripts/issue/defect-origin-main.ts +11 -0
  321. package/scripts/issue/defect-origin.ts +114 -0
  322. package/scripts/issue/defect-rate-cli.ts +34 -78
  323. package/scripts/issue/defect-rate.ts +0 -16
  324. package/scripts/issue/defect-report-cli.ts +128 -0
  325. package/scripts/issue/defect-report-format.ts +56 -0
  326. package/scripts/issue/defect-report-main.ts +11 -0
  327. package/scripts/issue/defect-report.ts +160 -0
  328. package/scripts/issue/expected-effect-lint.ts +1 -0
  329. package/scripts/issue/issue-already-done-cli.ts +62 -0
  330. package/scripts/issue/issue-body-or-comment.ts +40 -0
  331. package/scripts/issue/issue-cite-cli.ts +0 -9
  332. package/scripts/issue/issue-cite-main.ts +12 -0
  333. package/scripts/issue/issue-classification.ts +12 -7
  334. package/scripts/issue/issue-comment-cli.ts +10 -24
  335. package/scripts/issue/issue-comment-main.ts +12 -0
  336. package/scripts/issue/issue-evidence-exit.ts +100 -0
  337. package/scripts/issue/issue-file-cli.ts +29 -7
  338. package/scripts/issue/issue-file.ts +19 -19
  339. package/scripts/issue/issue-fold-cli.ts +2 -11
  340. package/scripts/issue/issue-fold-main.ts +12 -0
  341. package/scripts/issue/issue-labels.ts +81 -90
  342. package/scripts/issue/issue-lint-cli.ts +2 -10
  343. package/scripts/issue/issue-lint-main.ts +12 -0
  344. package/scripts/issue/issue-measured-cli.ts +56 -0
  345. package/scripts/issue/issue-merged.ts +19 -2
  346. package/scripts/issue/issue-not-before-label.ts +135 -0
  347. package/scripts/issue/issue-not-before.ts +111 -0
  348. package/scripts/issue/issue-number-shape.ts +15 -1
  349. package/scripts/issue/issue-park.ts +28 -0
  350. package/scripts/issue/issue-plan-cli.ts +151 -0
  351. package/scripts/issue/issue-priority.ts +151 -0
  352. package/scripts/issue/issue-rank.ts +7 -1
  353. package/scripts/issue/issue-read-cli.ts +3 -10
  354. package/scripts/issue/issue-read-main.ts +12 -0
  355. package/scripts/issue/issue-read.ts +29 -5
  356. package/scripts/issue/issue-release-cli.ts +0 -10
  357. package/scripts/issue/issue-release-main.ts +13 -0
  358. package/scripts/issue/issue-release.ts +7 -12
  359. package/scripts/issue/issue-sample-gate.ts +192 -0
  360. package/scripts/issue/issue-sample-source.ts +76 -0
  361. package/scripts/issue/issue-scout-cli.ts +0 -11
  362. package/scripts/issue/issue-scout-main.ts +14 -0
  363. package/scripts/issue/issue-state-cli.ts +0 -10
  364. package/scripts/issue/issue-state-main.ts +12 -0
  365. package/scripts/issue/issue-watch-diff.ts +56 -15
  366. package/scripts/issue/issue-watch.ts +2 -1
  367. package/scripts/issue/issue-wip.ts +2 -7
  368. package/scripts/issue/measure-rerun-cli.ts +13 -8
  369. package/scripts/issue/plan-consumers-cli.ts +39 -0
  370. package/scripts/issue/plan-consumers-main.ts +11 -0
  371. package/scripts/issue/plan-consumers-section.ts +55 -0
  372. package/scripts/issue/plan-consumers.ts +127 -0
  373. package/scripts/josh/agent-session-environment.ts +1 -1
  374. package/scripts/josh/command-usage.ts +15 -43
  375. package/scripts/josh/file-map-stamp.ts +49 -16
  376. package/scripts/josh/hook-decision.ts +32 -20
  377. package/scripts/josh/josh-command-map.ts +4 -1
  378. package/scripts/josh/josh-command-types.ts +12 -6
  379. package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
  380. package/scripts/josh/josh-commands-ai.ts +157 -158
  381. package/scripts/josh/josh-commands-backlog.ts +82 -16
  382. package/scripts/josh/josh-commands-clone.ts +1 -0
  383. package/scripts/josh/josh-commands-development.ts +111 -71
  384. package/scripts/josh/josh-commands-document.ts +43 -1
  385. package/scripts/josh/josh-commands-epic.ts +171 -0
  386. package/scripts/josh/josh-commands-hooks.ts +25 -2
  387. package/scripts/josh/josh-commands-issue-write.ts +181 -0
  388. package/scripts/josh/josh-commands-issue.ts +124 -24
  389. package/scripts/josh/josh-commands-lane.ts +103 -2
  390. package/scripts/josh/josh-commands-lint.ts +19 -8
  391. package/scripts/josh/josh-commands-maintenance.ts +112 -4
  392. package/scripts/josh/josh-commands-pause.ts +29 -0
  393. package/scripts/josh/josh-commands-progress.ts +87 -0
  394. package/scripts/josh/josh-commands-project.ts +138 -9
  395. package/scripts/josh/josh-commands-review.ts +124 -0
  396. package/scripts/josh/josh-commands-run.ts +211 -23
  397. package/scripts/josh/josh-commands-ship.ts +169 -0
  398. package/scripts/josh/josh-commands-split.ts +9 -0
  399. package/scripts/josh/josh-commands-versioning.ts +49 -2
  400. package/scripts/josh/josh-commands-workflow.ts +144 -6
  401. package/scripts/josh/josh-logic.ts +6 -13
  402. package/scripts/josh/package-directory.ts +2 -4
  403. package/scripts/josh/process-identity.ts +13 -4
  404. package/scripts/josh/session-language-cli.ts +4 -8
  405. package/scripts/josh/session-language-main.ts +13 -0
  406. package/scripts/josh/session-language.ts +6 -1
  407. package/scripts/josh/shared-cache.ts +90 -0
  408. package/scripts/josh/stamp-file.ts +9 -15
  409. package/scripts/lane/lane-await.ts +51 -12
  410. package/scripts/lane/lane-cache.ts +5 -30
  411. package/scripts/lane/lane-capacity.ts +14 -23
  412. package/scripts/lane/lane-check-stats.ts +62 -21
  413. package/scripts/lane/lane-child-invocation.ts +8 -0
  414. package/scripts/lane/lane-cli.ts +15 -5
  415. package/scripts/lane/lane-close.ts +86 -18
  416. package/scripts/lane/lane-core-wait-stats.ts +66 -0
  417. package/scripts/lane/lane-dispatch.ts +24 -3
  418. package/scripts/lane/lane-gap-stats.ts +156 -0
  419. package/scripts/lane/lane-handoff.ts +69 -1
  420. package/scripts/lane/lane-held-stats.ts +129 -0
  421. package/scripts/lane/lane-install.ts +4 -11
  422. package/scripts/lane/lane-launch-cli.ts +0 -9
  423. package/scripts/lane/lane-launch-main.ts +12 -0
  424. package/scripts/lane/lane-ledger-schema.ts +266 -0
  425. package/scripts/lane/lane-ledger.ts +92 -123
  426. package/scripts/lane/lane-limit-cli.ts +12 -1
  427. package/scripts/lane/lane-measure-cli.ts +57 -11
  428. package/scripts/lane/lane-open.ts +9 -1
  429. package/scripts/lane/lane-parked.ts +3 -3
  430. package/scripts/lane/lane-pause-cli.ts +130 -0
  431. package/scripts/lane/lane-pause.ts +158 -0
  432. package/scripts/lane/lane-process-table.ts +166 -0
  433. package/scripts/lane/lane-reap-settle.ts +124 -0
  434. package/scripts/lane/lane-reap.ts +50 -15
  435. package/scripts/lane/lane-registry.ts +24 -3
  436. package/scripts/lane/lane-residents.ts +162 -0
  437. package/scripts/lane/lane-restart.ts +22 -2
  438. package/scripts/lane/lane-round-two-stats.ts +49 -0
  439. package/scripts/lane/lane-sampler.ts +4 -0
  440. package/scripts/lane/lane-session-action.ts +19 -5
  441. package/scripts/lane/lane-session-broker.ts +102 -21
  442. package/scripts/lane/lane-snapshot-trace.ts +84 -0
  443. package/scripts/lane/lane-spans.ts +51 -0
  444. package/scripts/lane/lane-spent.ts +6 -3
  445. package/scripts/lane/lane-stage-stats.ts +7 -2
  446. package/scripts/lane/lane-state.ts +302 -0
  447. package/scripts/lane/lane-stats.ts +58 -4
  448. package/scripts/lane/lane-stop-stats.ts +113 -37
  449. package/scripts/lane/lane-test-related-stats.ts +127 -0
  450. package/scripts/lane/lane-transcript-calls.ts +145 -0
  451. package/scripts/lane/lane-transcript-stats.ts +168 -0
  452. package/scripts/lane/lane-vacant.ts +13 -3
  453. package/scripts/lane/lane-withdraw-cli.ts +5 -4
  454. package/scripts/lane/lane-withdraw.ts +50 -49
  455. package/scripts/lane/process-directories.ts +70 -0
  456. package/scripts/lane/process-lane-marks.ts +94 -0
  457. package/scripts/lib/atomic-write.ts +62 -0
  458. package/scripts/lib/buffered-process.ts +12 -5
  459. package/scripts/lib/cli-flags.ts +53 -0
  460. package/scripts/lib/figure-format.ts +63 -0
  461. package/scripts/lib/json-value.ts +9 -1
  462. package/scripts/lib/package-manifest.ts +35 -0
  463. package/scripts/lib/read-file.ts +3 -1
  464. package/scripts/lib/stamped-memo.ts +63 -0
  465. package/scripts/lib/stdout-on-stderr.ts +24 -0
  466. package/scripts/lib/timeouts.ts +9 -0
  467. package/scripts/lib/transcript-record.ts +91 -0
  468. package/scripts/lines/effective-limit.ts +1 -1
  469. package/scripts/lint/eslint-cache-dependencies.ts +145 -0
  470. package/scripts/lint/eslint-daemon.ts +265 -0
  471. package/scripts/lint/format.ts +11 -2
  472. package/scripts/lint/import-graph.ts +279 -0
  473. package/scripts/lint/lint-gate-scope.ts +102 -0
  474. package/scripts/lint/lint-parallel-main.ts +19 -0
  475. package/scripts/lint/lint-parallel.ts +62 -30
  476. package/scripts/lint/lint-related-scope.ts +30 -24
  477. package/scripts/lint/lint-related.ts +38 -6
  478. package/scripts/notify/confirmation-options.ts +1 -2
  479. package/scripts/notify/telegram-notify.ts +20 -20
  480. package/scripts/notify/telegram-test-logic.ts +0 -1
  481. package/scripts/notify/telegram-test-main.ts +8 -0
  482. package/scripts/notify/telegram-test.ts +2 -6
  483. package/scripts/observations/observation-ledger.ts +13 -0
  484. package/scripts/observations/observations-flush-landing.ts +5 -3
  485. package/scripts/observations/observations-flush.ts +6 -1
  486. package/scripts/overrides/overrides-check.ts +2 -5
  487. package/scripts/overrides/overrides-files.ts +2 -1
  488. package/scripts/overrides/overrides-logic.ts +3 -6
  489. package/scripts/package/verify-optional-eslint-install.ts +8 -6
  490. package/scripts/propagate/propagate-publish.ts +2 -7
  491. package/scripts/propagate/propagate-targets.ts +4 -12
  492. package/scripts/refactor/import-graph.ts +9 -7
  493. package/scripts/release/github-release-runs.ts +17 -6
  494. package/scripts/release/release-approval-prune.ts +18 -0
  495. package/scripts/release/release-history.ts +1 -3
  496. package/scripts/release/release-progress.ts +42 -22
  497. package/scripts/release/release-publish-run.ts +39 -0
  498. package/scripts/release/release-publish.ts +6 -6
  499. package/scripts/release/release-scope-cli.ts +0 -10
  500. package/scripts/release/release-scope-main.ts +12 -0
  501. package/scripts/repo/repo-setting.ts +3 -6
  502. package/scripts/repo/required-checks-logic.ts +6 -15
  503. package/scripts/report/report-format-reference.ts +2 -0
  504. package/scripts/report/report-labels.ts +155 -0
  505. package/scripts/report/report-lint-cli.ts +3 -0
  506. package/scripts/report/report-lint.ts +85 -110
  507. package/scripts/report/report-template-cli.ts +59 -0
  508. package/scripts/report/report-template.ts +112 -0
  509. package/scripts/review/acceptance-map.ts +1 -0
  510. package/scripts/review/removed-tests-check.ts +86 -0
  511. package/scripts/review/removed-tests.ts +149 -0
  512. package/scripts/review/review-brief-cli.ts +81 -15
  513. package/scripts/review/review-brief-main.ts +12 -0
  514. package/scripts/review/review-brief.ts +31 -3
  515. package/scripts/review/review-code-tree.ts +10 -6
  516. package/scripts/review/review-comment-round.ts +26 -8
  517. package/scripts/review/review-finding-ledger.ts +30 -15
  518. package/scripts/review/review-interaction.ts +94 -0
  519. package/scripts/review/review-readers-scan.ts +163 -0
  520. package/scripts/review/review-record-cli.ts +69 -30
  521. package/scripts/review/review-record-main.ts +12 -0
  522. package/scripts/review/review-round-one-blobs.ts +221 -0
  523. package/scripts/review/review-round2-cli.ts +49 -12
  524. package/scripts/review/review-round2.ts +80 -12
  525. package/scripts/review/review-stamps.ts +19 -1
  526. package/scripts/review/review-stop-log.ts +96 -0
  527. package/scripts/review/review-stops-cli.ts +85 -0
  528. package/scripts/review/review-tree.ts +6 -17
  529. package/scripts/review/review-untouched-readers.ts +146 -0
  530. package/scripts/review/test-titles.ts +118 -0
  531. package/scripts/rules/agent-model.ts +8 -0
  532. package/scripts/rules/bash-triggers.ts +46 -3
  533. package/scripts/rules/decision-oracle-batch.ts +9 -1
  534. package/scripts/rules/decision-oracle.ts +2 -2
  535. package/scripts/rules/delivered-rules.ts +80 -2
  536. package/scripts/rules/destructive-command.ts +8 -1
  537. package/scripts/rules/direct-filing.ts +10 -2
  538. package/scripts/rules/direct-issue-comment.ts +117 -0
  539. package/scripts/rules/direct-pr-create.ts +69 -3
  540. package/scripts/rules/early-heartbeat.ts +2 -1
  541. package/scripts/rules/file-body.ts +7 -0
  542. package/scripts/rules/filing-cap.ts +7 -0
  543. package/scripts/rules/git-argv.ts +72 -14
  544. package/scripts/rules/git-force.ts +12 -2
  545. package/scripts/rules/guard-remedy.ts +4 -0
  546. package/scripts/rules/implementation-cut-verdict.ts +1 -1
  547. package/scripts/rules/implementation-cut.ts +11 -3
  548. package/scripts/rules/index-guard.ts +8 -1
  549. package/scripts/rules/issue-comments.ts +9 -1
  550. package/scripts/rules/josh-git-bare.ts +7 -0
  551. package/scripts/rules/lane-background.ts +67 -25
  552. package/scripts/rules/lane-carry-conflict.ts +6 -0
  553. package/scripts/rules/lane-direct-tool.ts +74 -0
  554. package/scripts/rules/lane-interactive-ask.ts +9 -2
  555. package/scripts/rules/lane-park.ts +45 -23
  556. package/scripts/rules/lane-split-park.ts +10 -2
  557. package/scripts/rules/lane-switch-main.ts +7 -0
  558. package/scripts/rules/oracle-consulted.ts +10 -0
  559. package/scripts/rules/oracle-firing.ts +1 -0
  560. package/scripts/rules/permission-guards.ts +3 -0
  561. package/scripts/rules/piped-verification.ts +1 -1
  562. package/scripts/rules/poll-loop.ts +7 -0
  563. package/scripts/rules/pr-merge.ts +123 -0
  564. package/scripts/rules/protected-files.ts +32 -5
  565. package/scripts/rules/raw-field-body.ts +6 -0
  566. package/scripts/rules/rule-body-guard.ts +8 -0
  567. package/scripts/rules/rule-list.ts +9 -28
  568. package/scripts/rules/rule-value-cache.ts +4 -9
  569. package/scripts/rules/rule-value-cli.ts +51 -32
  570. package/scripts/rules/rule-value.ts +1 -1
  571. package/scripts/rules/shell-segments.ts +35 -0
  572. package/scripts/rules/stop-rule-rows.ts +64 -0
  573. package/scripts/rules/stop-rules.ts +3 -4
  574. package/scripts/rules/test-declared-commit.ts +11 -1
  575. package/scripts/rules/third-party-write.ts +7 -0
  576. package/scripts/rules/timed-rerun.ts +69 -0
  577. package/scripts/rules/worktree-guard.ts +13 -3
  578. package/scripts/run/board/run-board-app-name.ts +23 -0
  579. package/scripts/run/board/run-board-cli.ts +65 -32
  580. package/scripts/run/board/run-board-earlier.ts +94 -0
  581. package/scripts/run/board/run-board-ending-reason.ts +67 -0
  582. package/scripts/run/board/run-board-estimate-schedule.ts +103 -0
  583. package/scripts/run/board/run-board-estimate.ts +98 -0
  584. package/scripts/run/board/run-board-fit.ts +153 -36
  585. package/scripts/run/board/run-board-fold.ts +123 -0
  586. package/scripts/run/board/run-board-fresh.ts +2 -2
  587. package/scripts/run/board/run-board-gather-live.ts +29 -0
  588. package/scripts/run/board/run-board-gather-thread.ts +189 -0
  589. package/scripts/run/board/run-board-gather-worker.ts +29 -0
  590. package/scripts/run/board/run-board-gather.ts +187 -0
  591. package/scripts/run/board/run-board-github.ts +118 -38
  592. package/scripts/run/board/run-board-header.ts +82 -20
  593. package/scripts/run/board/run-board-keys.ts +58 -0
  594. package/scripts/run/board/run-board-kind.ts +20 -6
  595. package/scripts/run/board/run-board-labels.ts +116 -71
  596. package/scripts/run/board/run-board-lane-state.ts +109 -0
  597. package/scripts/run/board/run-board-lane-time.ts +122 -0
  598. package/scripts/run/board/run-board-layout.ts +239 -60
  599. package/scripts/run/board/run-board-length.ts +52 -0
  600. package/scripts/run/board/run-board-machine.ts +8 -4
  601. package/scripts/run/board/run-board-main.ts +12 -0
  602. package/scripts/run/board/run-board-notes.ts +52 -31
  603. package/scripts/run/board/run-board-now.ts +1 -1
  604. package/scripts/run/board/run-board-operation.ts +15 -33
  605. package/scripts/run/board/run-board-phase.ts +1 -1
  606. package/scripts/run/board/run-board-plan-shared.ts +115 -0
  607. package/scripts/run/board/run-board-plan.ts +55 -3
  608. package/scripts/run/board/run-board-planning.ts +45 -0
  609. package/scripts/run/board/run-board-priority.ts +44 -0
  610. package/scripts/run/board/run-board-process-groups.ts +195 -0
  611. package/scripts/run/board/run-board-read.ts +151 -27
  612. package/scripts/run/board/run-board-reason.ts +235 -51
  613. package/scripts/run/board/run-board-released.ts +35 -0
  614. package/scripts/run/board/run-board-render-checks.ts +39 -5
  615. package/scripts/run/board/run-board-render-condition.ts +96 -0
  616. package/scripts/run/board/run-board-render-drawn.ts +67 -0
  617. package/scripts/run/board/run-board-render-foot.ts +59 -0
  618. package/scripts/run/board/run-board-render-icon.ts +35 -0
  619. package/scripts/run/board/run-board-render-lanes.ts +145 -0
  620. package/scripts/run/board/run-board-render-lead.ts +80 -0
  621. package/scripts/run/board/run-board-render-legend.ts +117 -48
  622. package/scripts/run/board/run-board-render-notes.ts +156 -29
  623. package/scripts/run/board/run-board-render-processes.ts +196 -0
  624. package/scripts/run/board/run-board-render-section.ts +119 -0
  625. package/scripts/run/board/run-board-render-slot.ts +3 -36
  626. package/scripts/run/board/run-board-render-tail.ts +115 -48
  627. package/scripts/run/board/run-board-render-time.ts +56 -0
  628. package/scripts/run/board/run-board-render-title.ts +117 -24
  629. package/scripts/run/board/run-board-render-waits.ts +104 -20
  630. package/scripts/run/board/run-board-render.ts +207 -265
  631. package/scripts/run/board/run-board-roots.ts +54 -0
  632. package/scripts/run/board/run-board-row-yield.ts +9 -4
  633. package/scripts/run/board/run-board-setup.ts +1 -12
  634. package/scripts/run/board/run-board-snapshot.ts +111 -0
  635. package/scripts/run/board/run-board-spin.ts +2 -2
  636. package/scripts/run/board/run-board-state.ts +22 -33
  637. package/scripts/run/board/run-board-status.ts +147 -71
  638. package/scripts/run/board/run-board-thanks-read.ts +2 -2
  639. package/scripts/run/board/run-board-tick.ts +122 -107
  640. package/scripts/run/board/run-board-usage-board.ts +78 -0
  641. package/scripts/run/board/run-board-usage-lanes.ts +113 -0
  642. package/scripts/run/board/run-board-usage-listing.ts +93 -0
  643. package/scripts/run/board/run-board-usage-read.ts +120 -150
  644. package/scripts/run/board/run-board-usage-rusage.ts +19 -7
  645. package/scripts/run/board/run-board-usage-text.ts +139 -51
  646. package/scripts/run/board/run-board-usage-top.ts +102 -0
  647. package/scripts/run/board/run-board-usage.ts +89 -72
  648. package/scripts/run/board/run-board-usual.ts +20 -9
  649. package/scripts/run/carry/run-carry-args.ts +4 -7
  650. package/scripts/run/carry/run-carry-conversation.ts +1 -1
  651. package/scripts/run/carry/run-carry.ts +9 -4
  652. package/scripts/run/cut/run-cut-handoff.ts +2 -2
  653. package/scripts/run/event/run-event-cli.ts +1 -5
  654. package/scripts/run/event/run-event-filed.ts +12 -6
  655. package/scripts/run/event/run-event-follow.ts +2 -3
  656. package/scripts/run/event/run-event-render.ts +6 -10
  657. package/scripts/run/event/run-event-scope.ts +2 -2
  658. package/scripts/run/event/run-event-stream-emit.ts +82 -22
  659. package/scripts/run/event/run-event-stream.ts +34 -8
  660. package/scripts/run/hold/run-hold-adopt.ts +65 -0
  661. package/scripts/run/hold/run-hold-cli.ts +93 -22
  662. package/scripts/run/hold/run-hold-main.ts +12 -0
  663. package/scripts/run/hold/run-hold-member.ts +37 -0
  664. package/scripts/run/hold/run-stop-notify.ts +183 -0
  665. package/scripts/run/merge/run-merge-auth.ts +31 -0
  666. package/scripts/run/merge/run-merge-cli.ts +62 -48
  667. package/scripts/run/merge/run-merge-close.ts +74 -0
  668. package/scripts/run/merge/run-merge-collect.ts +6 -13
  669. package/scripts/run/merge/run-merge-driver.ts +71 -0
  670. package/scripts/run/merge/run-merge-main.ts +12 -0
  671. package/scripts/run/merge/run-merge-outcome.ts +23 -0
  672. package/scripts/run/merge/run-merge-restart.ts +39 -0
  673. package/scripts/run/merge/run-merge-ship.ts +20 -4
  674. package/scripts/run/merge/run-merge-signals.ts +33 -9
  675. package/scripts/run/merge/run-merge-steps.ts +120 -85
  676. package/scripts/run/merge/run-merge.ts +38 -37
  677. package/scripts/run/park/run-park-cli.ts +91 -0
  678. package/scripts/run/park/run-park.ts +88 -0
  679. package/scripts/run/park/run-stalled.ts +68 -0
  680. package/scripts/run/pause/run-pause-cli.ts +73 -0
  681. package/scripts/run/pause/run-pause.ts +251 -0
  682. package/scripts/run/progress/run-progress-cli.ts +4 -12
  683. package/scripts/run/progress/run-progress-clock.ts +1 -1
  684. package/scripts/run/progress/run-progress-config.ts +6 -14
  685. package/scripts/run/progress/run-progress-main.ts +12 -0
  686. package/scripts/run/progress/run-progress.ts +1 -4
  687. package/scripts/run/review/run-review.ts +2 -1
  688. package/scripts/run/run-ending.ts +1 -0
  689. package/scripts/run/run-invocation.ts +5 -6
  690. package/scripts/run/run-liveness-cli.ts +6 -8
  691. package/scripts/run/run-liveness.ts +60 -29
  692. package/scripts/run/run-next.ts +1 -1
  693. package/scripts/run/run-parent-cut-hook.ts +2 -2
  694. package/scripts/run/run-preflight.ts +18 -3
  695. package/scripts/run/run-prep-cli.ts +1 -10
  696. package/scripts/run/run-prep-locate.ts +7 -50
  697. package/scripts/run/run-prep-main.ts +12 -0
  698. package/scripts/run/run-prep.ts +6 -0
  699. package/scripts/run/run-report-cli.ts +101 -13
  700. package/scripts/run/run-report-handoff.ts +114 -0
  701. package/scripts/run/run-step.ts +1 -1
  702. package/scripts/run/run-stranded-detect.ts +13 -0
  703. package/scripts/run/run-watcher-guard-cli.ts +1 -1
  704. package/scripts/run/run-watcher-guard.ts +1 -1
  705. package/scripts/run/ship/run-ship-args.ts +121 -0
  706. package/scripts/run/ship/run-ship-body-draft.ts +110 -0
  707. package/scripts/run/ship/run-ship-cli.ts +63 -140
  708. package/scripts/run/ship/run-ship-detach.ts +19 -8
  709. package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
  710. package/scripts/run/ship/run-ship-next.ts +18 -2
  711. package/scripts/run/ship/run-ship-overlap.ts +42 -5
  712. package/scripts/run/ship/run-ship-place.ts +96 -0
  713. package/scripts/run/ship/run-ship-pre-detach-timed.ts +43 -0
  714. package/scripts/run/ship/run-ship-pre-detach.ts +81 -24
  715. package/scripts/run/ship/run-ship-preflight.ts +137 -32
  716. package/scripts/run/ship/run-ship-probe.ts +11 -3
  717. package/scripts/run/ship/run-ship-relaunch-cap.ts +70 -0
  718. package/scripts/run/ship/run-ship-removed-rows.ts +61 -0
  719. package/scripts/run/ship/run-ship-return.ts +107 -23
  720. package/scripts/run/ship/run-ship-review-steps.ts +105 -151
  721. package/scripts/run/ship/run-ship-review.ts +73 -6
  722. package/scripts/run/ship/run-ship-reviewer.ts +207 -0
  723. package/scripts/run/ship/run-ship-stage.ts +55 -6
  724. package/scripts/run/ship/run-ship-steps.ts +46 -15
  725. package/scripts/run/ship/run-ship-stop-cause.ts +135 -0
  726. package/scripts/run/ship/run-ship-stop-text.ts +11 -6
  727. package/scripts/run/ship/run-ship-sync.ts +43 -6
  728. package/scripts/run/ship/run-ship.ts +30 -2
  729. package/scripts/run/tidy/run-tidy-cli.ts +0 -4
  730. package/scripts/run/tidy/run-tidy-lanes.ts +3 -0
  731. package/scripts/run/tidy/run-tidy-main.ts +8 -0
  732. package/scripts/run/wake/run-wake-cli.ts +119 -100
  733. package/scripts/run/wake/run-wake-code.ts +83 -0
  734. package/scripts/run/wake/run-wake-driver.ts +19 -8
  735. package/scripts/run/wake/run-wake-loop.ts +34 -3
  736. package/scripts/run/wake/run-wake-main.ts +13 -0
  737. package/scripts/run/wake/run-wake-ports.ts +90 -0
  738. package/scripts/run/wake/run-wake-takeover.ts +66 -0
  739. package/scripts/run/wake/run-wake.ts +2 -1
  740. package/scripts/safe-chain/pack-hook.ts +2 -2
  741. package/scripts/safe-chain/preinstall-command.ts +2 -1
  742. package/scripts/safe-chain/project-config.ts +3 -9
  743. package/scripts/security/security-audit-main.ts +8 -0
  744. package/scripts/security/security-audit-provision-logic.ts +0 -11
  745. package/scripts/security/security-audit-provision-main.ts +12 -0
  746. package/scripts/security/security-audit-provision.ts +11 -26
  747. package/scripts/security/security-audit.ts +6 -7
  748. package/scripts/self-sync-guard/self-sync-guard-logic.ts +6 -13
  749. package/scripts/split/split-assess-cli.ts +2 -2
  750. package/scripts/split/split-assess.ts +15 -0
  751. package/scripts/split/split-measure.ts +65 -0
  752. package/scripts/sync/claude-settings-merge.ts +8 -15
  753. package/scripts/sync/directory-copy-guard.ts +4 -9
  754. package/scripts/sync/file-content.ts +78 -8
  755. package/scripts/sync/sync-ai-files.ts +3 -5
  756. package/scripts/sync/sync-configs.ts +11 -23
  757. package/scripts/sync/sync-hook-safety.ts +4 -10
  758. package/scripts/sync/sync-main.ts +11 -0
  759. package/scripts/sync/sync.ts +25 -37
  760. package/scripts/test/test-declared-changed.ts +2 -2
  761. package/scripts/test/test-declared.ts +1 -1
  762. package/scripts/test/test-e2e-guard.ts +25 -1
  763. package/scripts/test/test-e2e-stamp.ts +38 -0
  764. package/scripts/test/test-pinned-logic.ts +145 -0
  765. package/scripts/test/test-pinned-main.ts +78 -0
  766. package/scripts/test/test-pinned.ts +100 -0
  767. package/scripts/test/test-read-map.ts +264 -0
  768. package/scripts/test/test-read-recording.ts +91 -0
  769. package/scripts/test/test-read-trace.ts +148 -0
  770. package/scripts/test/test-red-main.ts +12 -0
  771. package/scripts/test/test-red.ts +12 -30
  772. package/scripts/test/test-related-main.ts +18 -0
  773. package/scripts/test/test-related-record.ts +119 -0
  774. package/scripts/test/test-related-scope.ts +229 -43
  775. package/scripts/test/test-related.ts +300 -22
  776. package/scripts/test/test-unit-guard-main.ts +15 -0
  777. package/scripts/test/test-unit-guard.ts +42 -24
  778. package/scripts/test/unit-count-file.ts +37 -0
  779. package/scripts/test/unit-run-marker.ts +162 -0
  780. package/scripts/test/unit-setup-files.ts +51 -0
  781. package/scripts/test/unit-worker-share.ts +61 -149
  782. package/scripts/test/whole-suite-files.ts +63 -0
  783. package/scripts/time-runtime/time-background.ts +20 -2
  784. package/scripts/time-runtime/time-bundles.ts +4 -3
  785. package/scripts/time-runtime/time-density-hook.ts +8 -6
  786. package/scripts/time-runtime/time-followup-stage.ts +1 -3
  787. package/scripts/time-runtime/time-format.ts +5 -28
  788. package/scripts/time-runtime/time-markers.ts +10 -1
  789. package/scripts/time-runtime/time-shell.ts +97 -10
  790. package/scripts/time-runtime/time-transcript-line.ts +49 -62
  791. package/scripts/uninstall/uninstall.ts +1 -1
  792. package/scripts/version/bump-version-main.ts +12 -0
  793. package/scripts/version/bump-version.ts +25 -25
  794. package/scripts/version/effective-upstream.ts +6 -12
  795. package/scripts/version/latest-corepack.ts +17 -32
  796. package/scripts/version/latest-if-required-cli.ts +93 -0
  797. package/scripts/version/latest-lane-guard-main.ts +8 -0
  798. package/scripts/version/latest-lane-guard.ts +0 -4
  799. package/scripts/version/latest-scope-cli.ts +0 -9
  800. package/scripts/version/latest-scope-main.ts +12 -0
  801. package/scripts/version/latest-update.ts +5 -5
  802. package/scripts/version/npm-registry.ts +44 -6
  803. package/scripts/version/publishable-range-check.ts +5 -16
  804. package/scripts/version/release-age.ts +1 -1
  805. package/scripts/version/release-hold.ts +1 -1
  806. package/scripts/version/release-window.ts +38 -0
  807. package/scripts/version/running-binary.ts +1 -1
  808. package/scripts/version/safe-chain-version-update.ts +3 -8
  809. package/scripts/version/version-targets.ts +6 -28
  810. package/templates/dependabot.yml +29 -0
  811. package/templates/gitignore +4 -1
  812. package/templates/pnpm-workspace.basic.yaml +1 -1
  813. package/templates/sonar-project.properties +3 -2
  814. package/templates/workflows/ci.yml +12 -4
  815. package/templates/workflows/github-release.yml +4 -0
  816. package/tsconfig.sonar.json +1 -1
  817. package/.ncurc.json +0 -3
  818. package/dist/hooks/batch-guard.js +0 -29
  819. package/dist/hooks/chunk-4KKD2UTK.js +0 -66
  820. package/dist/hooks/chunk-6TS2JD6D.js +0 -237
  821. package/dist/hooks/chunk-7DSBJVFH.js +0 -50
  822. package/dist/hooks/chunk-A65Y4YOR.js +0 -79
  823. package/dist/hooks/chunk-CDY4NFQG.js +0 -15
  824. package/dist/hooks/chunk-EFXE6C37.js +0 -81
  825. package/dist/hooks/chunk-GP4IEC4O.js +0 -20
  826. package/dist/hooks/chunk-JP45SOCJ.js +0 -56
  827. package/dist/hooks/chunk-LAOV7NLM.js +0 -45
  828. package/dist/hooks/chunk-M4HGZV7U.js +0 -83
  829. package/dist/hooks/chunk-PF2NZL2A.js +0 -131
  830. package/dist/hooks/chunk-PTICX4OL.js +0 -358
  831. package/dist/hooks/chunk-RT27QRJW.js +0 -6247
  832. package/dist/hooks/chunk-SYOTDYCI.js +0 -3533
  833. package/dist/hooks/chunk-UPUZF3AN.js +0 -279
  834. package/dist/hooks/chunk-WK6SMBIC.js +0 -3180
  835. package/dist/hooks/duplicate-read-guard.js +0 -30
  836. package/dist/hooks/investigation-guard.js +0 -29
  837. package/scripts/backlog/backlog-stalled-cli.ts +0 -30
  838. package/scripts/cost-runtime/cost-format.ts +0 -29
  839. package/scripts/init/basic-path-migration.ts +0 -24
  840. package/scripts/issue/issue-backlinks-cli.ts +0 -93
  841. package/scripts/josh/josh-commands-guard.ts +0 -38
  842. package/scripts/josh/josh-usage-automation.ts +0 -121
  843. package/scripts/josh/josh-usage-backlog.ts +0 -180
  844. package/scripts/josh/josh-usage-developer.ts +0 -230
  845. package/scripts/josh/josh-usage-hooks.ts +0 -38
  846. package/scripts/josh/josh-usage-issue.ts +0 -205
  847. package/scripts/josh/josh-usage-review.ts +0 -101
  848. package/scripts/josh/josh-usage-run.ts +0 -252
  849. package/scripts/josh/josh-usage-session.ts +0 -238
  850. package/scripts/josh/josh-usage-workflow.ts +0 -212
  851. package/scripts/lint/cross-file-recheck.ts +0 -155
  852. package/scripts/registry-migration/migrate-logic.ts +0 -237
  853. package/scripts/registry-migration/migrate.ts +0 -292
  854. package/scripts/registry-migration/user-npmrc.ts +0 -15
  855. package/scripts/rules/rule-guard.ts +0 -23
  856. package/scripts/rules/rule-registry-rows.ts +0 -292
  857. package/scripts/rules/rule-registry.ts +0 -112
  858. package/scripts/run/run-stranded-cli.ts +0 -27
@@ -0,0 +1,127 @@
1
+ import { MS_PER_SECOND } from '#scripts/lib/timeouts'
2
+ import { lane_ledger, type LedgerEntry, type TestRelatedEntry } from './lane-ledger'
3
+ import { lane_stage_stats } from './lane-stage-stats'
4
+ import { lane_stats, type StatsWindow } from './lane-stats'
5
+
6
+ // What widened a `josh test:related` run (joshuafolkken/kit#4465): one row per scope it settled on —
7
+ // `related`, `none` or the full-suite fallback kind — with the medians of its input (the change
8
+ // itself, what a main sync brought in, what the change since the test-read map's tree joined, the
9
+ // readers the map added), of the test files vitest
10
+ // ran and of its duration. A `related` row whose test files far outrun its input is vitest widening the
11
+ // run on its own.
12
+
13
+ const DECIMALS = 1
14
+ const RUNS_COLUMN = 'runs'
15
+ const SECONDS_COLUMN = 'median (s)'
16
+ const COLUMNS = [
17
+ 'test:related scope',
18
+ RUNS_COLUMN,
19
+ 'changed',
20
+ 'synced',
21
+ 'since map',
22
+ 'readers',
23
+ 'test files',
24
+ SECONDS_COLUMN,
25
+ ] as const
26
+ const TRIGGER_COLUMNS = ['test:related whole-suite trigger', RUNS_COLUMN, SECONDS_COLUMN] as const
27
+
28
+ type CountField = 'changed' | 'synced' | 'since_map' | 'readers'
29
+
30
+ function is_test_related(entry: LedgerEntry): entry is TestRelatedEntry {
31
+ return entry.kind === lane_ledger.KIND.TEST_RELATED
32
+ }
33
+
34
+ function count_cell(values: ReadonlyArray<number>): string {
35
+ const median = lane_stats.median(values)
36
+
37
+ return median === undefined ? lane_stage_stats.NOT_MEASURED : String(median)
38
+ }
39
+
40
+ function seconds_cell(values: ReadonlyArray<number>): string {
41
+ const median = lane_stats.median(values)
42
+
43
+ return median === undefined
44
+ ? lane_stage_stats.NOT_MEASURED
45
+ : (median / MS_PER_SECOND).toFixed(DECIMALS)
46
+ }
47
+
48
+ function median_of(runs: ReadonlyArray<TestRelatedEntry>, field: CountField): string {
49
+ return count_cell(runs.map((run) => run[field]))
50
+ }
51
+
52
+ function scope_row(scope: string, entries: ReadonlyArray<TestRelatedEntry>): string {
53
+ const runs = entries.filter((entry) => entry.scope === scope)
54
+ const test_files = runs.map((run) => run.test_files).filter((files) => files !== undefined)
55
+
56
+ return lane_stats.to_row([
57
+ scope,
58
+ String(runs.length),
59
+ median_of(runs, 'changed'),
60
+ median_of(runs, 'synced'),
61
+ median_of(runs, 'since_map'),
62
+ median_of(runs, 'readers'),
63
+ count_cell(test_files),
64
+ seconds_cell(runs.map((run) => run.elapsed_ms)),
65
+ ])
66
+ }
67
+
68
+ function rows_under(columns: ReadonlyArray<string>, rows: ReadonlyArray<string>): string {
69
+ return [lane_stats.to_row(columns), lane_stats.to_row(columns.map(() => '---')), ...rows].join(
70
+ '\n',
71
+ )
72
+ }
73
+
74
+ function runs_in(
75
+ entries: ReadonlyArray<LedgerEntry>,
76
+ window: StatsWindow,
77
+ ): Array<TestRelatedEntry> {
78
+ return lane_stats.in_window(entries, window).filter(is_test_related)
79
+ }
80
+
81
+ // The period's table: `entries` is the whole ledger, filtered here to `window`.
82
+ function table(entries: ReadonlyArray<LedgerEntry>, window: StatsWindow): string {
83
+ const runs = runs_in(entries, window)
84
+ const scopes = [...new Set(runs.map((run) => run.scope))]
85
+
86
+ return rows_under(
87
+ COLUMNS,
88
+ scopes.map((scope) => scope_row(scope, runs)),
89
+ )
90
+ }
91
+
92
+ interface TriggerRuns {
93
+ file: string
94
+ runs: ReadonlyArray<TestRelatedEntry>
95
+ }
96
+
97
+ function runs_sent_by(file: string, runs: ReadonlyArray<TestRelatedEntry>): TriggerRuns {
98
+ return { file, runs: runs.filter((run) => run.trigger_files?.includes(file) === true) }
99
+ }
100
+
101
+ function trigger_row({ file, runs }: TriggerRuns): string {
102
+ return lane_stats.to_row([
103
+ file,
104
+ String(runs.length),
105
+ seconds_cell(runs.map((run) => run.elapsed_ms)),
106
+ ])
107
+ }
108
+
109
+ // Which changed file sent a run to the whole suite, most runs first (joshuafolkken/kit#4510): the
110
+ // table `WHOLE_SUITE_FILES` and the test-read map are trimmed from. A row written before the files
111
+ // were recorded names none, and so counts under no file.
112
+ function trigger_table(entries: ReadonlyArray<LedgerEntry>, window: StatsWindow): string {
113
+ const runs = runs_in(entries, window)
114
+ const files = [...new Set(runs.flatMap((run) => run.trigger_files ?? []))]
115
+ const triggers = files
116
+ .map((file) => runs_sent_by(file, runs))
117
+ .toSorted((left, right) => right.runs.length - left.runs.length)
118
+
119
+ return rows_under(
120
+ TRIGGER_COLUMNS,
121
+ triggers.map((trigger) => trigger_row(trigger)),
122
+ )
123
+ }
124
+
125
+ const lane_test_related_stats = { table, trigger_table }
126
+
127
+ export { lane_test_related_stats }
@@ -0,0 +1,145 @@
1
+ import { json_value } from '#scripts/lib/json-value'
2
+ import { z } from 'zod'
3
+
4
+ // One lane session's transcript reduced to its tool calls: each `tool_use` an `assistant` line carries,
5
+ // joined by its id to the `tool_result` a later `user` line carries, so `josh lane:stats` can time a
6
+ // call as the gap between the two lines (joshuafolkken/kit#4418).
7
+ //
8
+ // **A backgrounded call is kept but not timed.** Its result line is the immediate "running in the
9
+ // background" notice, so the gap measures nothing the run waited on; `duration_ms` is `undefined` for
10
+ // it, as for a call whose result never arrived (an interrupted turn).
11
+
12
+ interface ToolCall {
13
+ session_id: string
14
+ started_ms: number
15
+ duration_ms: number | undefined
16
+ background: boolean
17
+ command: string | undefined
18
+ output: string
19
+ }
20
+
21
+ interface ToolUse {
22
+ started_ms: number
23
+ background: boolean
24
+ command: string | undefined
25
+ }
26
+
27
+ interface ToolResult {
28
+ ended_ms: number
29
+ output: string
30
+ }
31
+
32
+ interface TextPart {
33
+ text?: string | null | undefined
34
+ }
35
+
36
+ function join_parts(parts: ReadonlyArray<TextPart>): string {
37
+ return parts.map((part) => part.text ?? '').join('\n')
38
+ }
39
+
40
+ interface RawInput {
41
+ command?: unknown
42
+ run_in_background?: unknown
43
+ }
44
+
45
+ interface CallInput {
46
+ background: boolean
47
+ command: string | undefined
48
+ }
49
+
50
+ function to_input(input: RawInput | null | undefined): CallInput {
51
+ const command = input?.command
52
+
53
+ return {
54
+ background: input?.run_in_background === true,
55
+ command: typeof command === 'string' ? command : undefined,
56
+ }
57
+ }
58
+
59
+ const TEXT_PARTS_SCHEMA = z.array(z.object({ text: z.string().nullish() }))
60
+ // A result's text: a string, or the text parts of a block list; anything else reads as no output.
61
+ const RESULT_CONTENT_SCHEMA = z
62
+ .union([z.string(), TEXT_PARTS_SCHEMA.transform(join_parts)])
63
+ .catch('')
64
+ const INPUT_SCHEMA = z.object({ command: z.unknown(), run_in_background: z.unknown() }).partial()
65
+
66
+ const BLOCK_SCHEMA = z.object({
67
+ type: z.string(),
68
+ id: z.string().nullish(),
69
+ input: INPUT_SCHEMA.nullish().transform(to_input),
70
+ tool_use_id: z.string().nullish(),
71
+ content: RESULT_CONTENT_SCHEMA.optional(),
72
+ })
73
+
74
+ type Block = z.infer<typeof BLOCK_SCHEMA>
75
+
76
+ function blocks_of(message: { content: Array<Block> } | null | undefined): Array<Block> {
77
+ return message?.content ?? []
78
+ }
79
+
80
+ // A line that is not JSON, not a message, or carries no readable timestamp fails the parse.
81
+ const LINE_SCHEMA = z.object({
82
+ timestamp: z.string().transform(Date.parse).pipe(z.number()),
83
+ message: z
84
+ .object({ content: z.array(BLOCK_SCHEMA).catch([]) })
85
+ .nullish()
86
+ .transform(blocks_of),
87
+ })
88
+
89
+ interface Pairs {
90
+ uses: Map<string, ToolUse>
91
+ results: Map<string, ToolResult>
92
+ }
93
+
94
+ function record_use(pairs: Pairs, block: Block, started_ms: number): void {
95
+ if (block.type !== 'tool_use' || !block.id) return
96
+
97
+ pairs.uses.set(block.id, { started_ms, ...block.input })
98
+ }
99
+
100
+ function record_result(pairs: Pairs, block: Block, ended_ms: number): void {
101
+ if (block.type !== 'tool_result' || !block.tool_use_id) return
102
+
103
+ pairs.results.set(block.tool_use_id, { ended_ms, output: block.content ?? '' })
104
+ }
105
+
106
+ function record_line(pairs: Pairs, line: string): void {
107
+ const parsed = LINE_SCHEMA.safeParse(json_value.parse_or_undefined(line))
108
+
109
+ if (!parsed.success) return
110
+
111
+ const { timestamp, message } = parsed.data
112
+
113
+ for (const block of message) {
114
+ record_use(pairs, block, timestamp)
115
+ record_result(pairs, block, timestamp)
116
+ }
117
+ }
118
+
119
+ function to_call(session_id: string, use: ToolUse, result: ToolResult | undefined): ToolCall {
120
+ const is_timed = result !== undefined && !use.background
121
+
122
+ return {
123
+ session_id,
124
+ started_ms: use.started_ms,
125
+ duration_ms: is_timed ? result.ended_ms - use.started_ms : undefined,
126
+ background: use.background,
127
+ command: use.command,
128
+ output: result?.output ?? '',
129
+ }
130
+ }
131
+
132
+ // Every tool call `raw` — one transcript's text — records, in the order the calls were made.
133
+ function parse(session_id: string, raw: string): Array<ToolCall> {
134
+ const pairs: Pairs = { uses: new Map(), results: new Map() }
135
+ const lines = raw.split('\n')
136
+
137
+ for (const line of lines) record_line(pairs, line)
138
+
139
+ return [...pairs.uses].map(([id, use]) => to_call(session_id, use, pairs.results.get(id)))
140
+ }
141
+
142
+ const lane_transcript_calls = { parse }
143
+
144
+ export type { ToolCall }
145
+ export { lane_transcript_calls }
@@ -0,0 +1,168 @@
1
+ import { cost_transcript } from '#scripts/cost-runtime/cost-transcript'
2
+ import { MS_PER_SECOND } from '#scripts/lib/timeouts'
3
+ import { time_shell } from '#scripts/time-runtime/time-shell'
4
+ import { lane_stage_stats } from './lane-stage-stats'
5
+ import { lane_stats, type StatsWindow } from './lane-stats'
6
+ import { lane_transcript_calls, type ToolCall } from './lane-transcript-calls'
7
+
8
+ // The lane speed metrics only the lane sessions' transcripts hold, printed by `josh lane:stats` under the
9
+ // ledger's tables so a speed check needs no ad-hoc aggregation (joshuafolkken/kit#4418): tool time per
10
+ // session, the verification calls and the share that waited for the core budget, and the medians of
11
+ // `lint:related` / `test:related`.
12
+ //
13
+ // **A chained call is counted apart from a solo one.** One Bash call that runs two verification
14
+ // commands (`josh lint:related && josh test:related`) has one duration for both, so it would read as
15
+ // either command's time; the per-command medians take solo calls only. **Only a foreground call is
16
+ // timed** — `lane_transcript_calls` leaves a backgrounded one's duration out.
17
+ //
18
+ // **The period is cut at each call's own timestamp**, not a transcript's modification time, so a
19
+ // fractional `--period` (since a merge) counts the same calls whichever session they sit in.
20
+
21
+ const TIMED_COMMANDS: ReadonlyArray<string> = ['lint:related', 'test:related']
22
+ // **The verification calls split by what ran them** (joshuafolkken/kit#4442): the scoped checks of the
23
+ // implementation loop, a whole `gate` or `metrics` run by hand before the ship, and the `ship` call —
24
+ // whose own gate runs inside it and is the ledger's to count — so a hand-run gate is never hidden in the
25
+ // loop's volume. A call naming two classes counts in each.
26
+ const CALL_CLASSES: ReadonlyArray<readonly [string, ReadonlySet<string>]> = [
27
+ ['verification calls, scoped checks', new Set([...TIMED_COMMANDS, 'cspell:dot'])],
28
+ ['verification calls, gate / metrics by hand', new Set(['gate', 'metrics'])],
29
+ ['verification calls, ship', new Set(['ship'])],
30
+ ]
31
+ const VERIFICATION_COMMANDS: ReadonlySet<string> = new Set(
32
+ CALL_CLASSES.flatMap(([, names]) => [...names]),
33
+ )
34
+ // A command is `josh <name>` at the start of a shell command — after a separator and the shell
35
+ // keywords, then past what `time_shell` skips (env assignments, wrappers with their flags and operands,
36
+ // a `pnpm` / `npx` runner) — so `josh lint:related; josh test:related`, `out=$(pnpm josh gate)` and
37
+ // `CI=1 timeout 600 pnpm josh gate` name their commands. A heredoc body or a quoted string only
38
+ // mentions a command, so `time_shell.unquoted` cuts both, keeping a `"$(…)"` that runs
39
+ // (joshuafolkken/kit#4525).
40
+ const SEPARATOR_PATTERN = /[;&|()\n]/u
41
+ const WORD_PATTERN = /\s+/u
42
+ const KEYWORDS: ReadonlySet<string> = new Set([
43
+ 'if',
44
+ 'elif',
45
+ 'else',
46
+ 'then',
47
+ 'while',
48
+ 'until',
49
+ 'do',
50
+ '!',
51
+ '{',
52
+ ])
53
+ // `scripts/gate/core-wait.ts` writes this into every wait line it prints.
54
+ const CORE_WAIT_PHRASE = 'waits for the core budget'
55
+ const PERCENT = 100
56
+ const COLUMNS = ['transcript metric', 'value'] as const
57
+ const { NOT_MEASURED } = lane_stage_stats
58
+
59
+ // The josh command `segment` runs, or `''` when it runs none.
60
+ function segment_command(segment: string): string {
61
+ const words = segment.trim().split(WORD_PATTERN)
62
+ const start = words.findIndex((word) => !KEYWORDS.has(word))
63
+ const named = time_shell.josh_command_of_segment(words.slice(start).join(' '))
64
+
65
+ return named.slice(time_shell.JOSH_PREFIX.length)
66
+ }
67
+
68
+ function verification_commands(command = ''): Array<string> {
69
+ const spoken = time_shell.unquoted(command)
70
+ const named = spoken.split(SEPARATOR_PATTERN).map((segment) => segment_command(segment))
71
+
72
+ return named.filter((name) => VERIFICATION_COMMANDS.has(name))
73
+ }
74
+
75
+ function seconds_cell(ms: number | undefined): string {
76
+ return ms === undefined ? NOT_MEASURED : (ms / MS_PER_SECOND).toFixed(1)
77
+ }
78
+
79
+ function is_timed(ms: number | undefined): ms is number {
80
+ return ms !== undefined
81
+ }
82
+
83
+ function durations(calls: ReadonlyArray<ToolCall>): Array<number> {
84
+ return calls.map((call) => call.duration_ms).filter((ms) => is_timed(ms))
85
+ }
86
+
87
+ // Each session's summed foreground tool time, for the sessions that made a call in the period.
88
+ function session_times(calls: ReadonlyArray<ToolCall>): Array<number> {
89
+ const sessions = [...new Set(calls.map((call) => call.session_id))]
90
+
91
+ return sessions.map((session) =>
92
+ durations(calls.filter((call) => call.session_id === session)).reduce(
93
+ (sum, value) => sum + value,
94
+ 0,
95
+ ),
96
+ )
97
+ }
98
+
99
+ function share_cell(part: number, whole: number): string {
100
+ if (whole === 0) return NOT_MEASURED
101
+
102
+ return `${String(part)} of ${String(whole)} (${((part / whole) * PERCENT).toFixed(1)}%)`
103
+ }
104
+
105
+ function solo_median_row(verifying: ReadonlyArray<ToolCall>, name: string): Array<string> {
106
+ const solo = verifying.filter((call) => {
107
+ const named = verification_commands(call.command)
108
+
109
+ return named.length === 1 && named[0] === name
110
+ })
111
+
112
+ return [`${name} median, solo (s)`, seconds_cell(lane_stats.median(durations(solo)))]
113
+ }
114
+
115
+ function class_rows(verifying: ReadonlyArray<ToolCall>): Array<Array<string>> {
116
+ return CALL_CLASSES.map(([metric, names]) => {
117
+ const named = verifying.filter((call) =>
118
+ verification_commands(call.command).some((name) => names.has(name)),
119
+ )
120
+
121
+ return [metric, String(named.length)]
122
+ })
123
+ }
124
+
125
+ function rows_of(calls: ReadonlyArray<ToolCall>): Array<Array<string>> {
126
+ const times = session_times(calls)
127
+ const verifying = calls.filter((call) => verification_commands(call.command).length > 0)
128
+ const chained = verifying.filter((call) => verification_commands(call.command).length > 1)
129
+ const waited = verifying.filter((call) => call.output.includes(CORE_WAIT_PHRASE))
130
+
131
+ return [
132
+ ['lane sessions', String(times.length)],
133
+ ['tool time per session, median (min)', lane_stage_stats.cell(lane_stats.median(times))],
134
+ ['tool time per session, mean (min)', lane_stage_stats.cell(lane_stats.mean(times))],
135
+ ['verification calls, solo', String(verifying.length - chained.length)],
136
+ ['verification calls, chained', String(chained.length)],
137
+ ...class_rows(verifying),
138
+ ['waited for the core budget', share_cell(waited.length, verifying.length)],
139
+ ...TIMED_COMMANDS.map((name) => solo_median_row(verifying, name)),
140
+ ]
141
+ }
142
+
143
+ // The period's table: `calls` is every lane session's calls, filtered here to `window`.
144
+ function table(calls: ReadonlyArray<ToolCall>, window: StatsWindow): string {
145
+ const period = calls.filter(
146
+ (call) => call.started_ms >= window.since_ms && call.started_ms <= window.until_ms,
147
+ )
148
+
149
+ return [
150
+ lane_stats.to_row(COLUMNS),
151
+ lane_stats.to_row(COLUMNS.map(() => '---')),
152
+ ...rows_of(period).map((row) => lane_stats.to_row(row)),
153
+ ].join('\n')
154
+ }
155
+
156
+ // The tool calls of every lane session under `directories` that was still written to in `window` — a
157
+ // transcript last modified before the period holds no call in it, so it is never read. A delegated
158
+ // unit's transcript is not a lane session, and its time is already inside the parent's wait for it.
159
+ function read_calls(directories: ReadonlyArray<string>, window: StatsWindow): Array<ToolCall> {
160
+ return cost_transcript
161
+ .list_sessions_across(directories)
162
+ .filter((file) => !file.is_delegated && file.modified_ms >= window.since_ms)
163
+ .flatMap((file) => lane_transcript_calls.parse(file.session_id, cost_transcript.read_raw(file)))
164
+ }
165
+
166
+ const lane_transcript_stats = { read_calls, table, verification_commands }
167
+
168
+ export { lane_transcript_stats }
@@ -1,5 +1,6 @@
1
1
  import { git_command } from '#scripts/git/git-command'
2
2
  import { run_hold } from '#scripts/run/hold/run-hold'
3
+ import { PROCESS_NONE } from '#scripts/run/run-liveness'
3
4
  import { lane_await } from './lane-await'
4
5
  import type { LaneInfo } from './lane-registry'
5
6
 
@@ -9,7 +10,7 @@ import type { LaneInfo } from './lane-registry'
9
10
  // refuses it as `already-open` — so the next launch of that issue failed on a lane with nothing in it.
10
11
  //
11
12
  // **Every unreadable answer is "not vacant"**: `is_tree_dirty` already reads an unreadable status as
12
- // dirty, and a branch whose commits cannot be counted is kept rather than closed, because closing it
13
+ // dirty, a process probe that could not look reads as occupied, and a branch whose commits cannot be counted is kept rather than closed, because closing it
13
14
  // deletes the branch and anything on it.
14
15
  async function has_no_commits(lane: LaneInfo): Promise<boolean> {
15
16
  try {
@@ -21,8 +22,10 @@ async function has_no_commits(lane: LaneInfo): Promise<boolean> {
21
22
  }
22
23
  }
23
24
 
25
+ // Only pgrep's own "no match" clears a lane: a probe that failed or timed out never looked, and a
26
+ // freshly launched child with no commit yet must not read vacant on it (joshuafolkken/kit#4028).
24
27
  function is_occupied(lane: LaneInfo): boolean {
25
- return lane.is_stranded || lane_await.is_process_running_default(lane.issue)
28
+ return lane.is_stranded || lane_await.process_trace_default(lane.issue) !== PROCESS_NONE
26
29
  }
27
30
 
28
31
  async function is_vacant(lane: LaneInfo): Promise<boolean> {
@@ -31,6 +34,13 @@ async function is_vacant(lane: LaneInfo): Promise<boolean> {
31
34
  return await has_no_commits(lane)
32
35
  }
33
36
 
34
- const lane_vacant = { is_vacant }
37
+ // The issues of the lanes that hold nothing worth keeping, read in parallel.
38
+ async function vacant_issues(lanes: ReadonlyArray<LaneInfo>): Promise<Array<string>> {
39
+ const answers = await Promise.all(lanes.map(async (lane) => await is_vacant(lane)))
40
+
41
+ return lanes.filter((_lane, index) => answers[index] === true).map((lane) => lane.issue)
42
+ }
43
+
44
+ const lane_vacant = { is_vacant, vacant_issues }
35
45
 
36
46
  export { lane_vacant }
@@ -4,8 +4,9 @@ import { issue_number_shape } from '#scripts/issue/issue-number-shape'
4
4
  import { cli_flags } from '#scripts/lib/cli-flags'
5
5
  import { lane_withdraw, type WithdrawOutcome } from './lane-withdraw'
6
6
 
7
- // `josh lane:withdraw <issue> --reason <text>` — every explanation on standard error, and a withdrawal
8
- // that did not end with the Issue closed exits non-zero, so a caller never takes a half-done one as done.
7
+ // `josh lane:withdraw <issue> --reason <text>` — every explanation on standard error, and anything but a
8
+ // finished withdrawal exits non-zero, so a caller never takes a half-done one as done. The Issue stays
9
+ // open on success.
9
10
 
10
11
  const ARGV_OFFSET = 2
11
12
  const SUCCESS_EXIT_CODE = 0
@@ -24,7 +25,7 @@ function issue_of(positionals: ReadonlyArray<string>): string | undefined {
24
25
  return rest.length === 0 && issue_number_shape.is_issue_number(issue ?? '') ? issue : undefined
25
26
  }
26
27
 
27
- // A reason of only whitespace is no reason: the Issue would close with an empty `Why:` line.
28
+ // A reason of only whitespace is no reason: the Issue would carry an empty `Why:` line.
28
29
  function reason_of(value: unknown): string | undefined {
29
30
  const reason = cli_flags.string_of(value)?.trim()
30
31
 
@@ -41,7 +42,7 @@ function parse_request(argv: ReadonlyArray<string>): Request | undefined {
41
42
  }
42
43
 
43
44
  function exit_code_of(outcome: WithdrawOutcome): number {
44
- return outcome.kind === 'withdrawn' && outcome.is_closed ? SUCCESS_EXIT_CODE : FAILURE_EXIT_CODE
45
+ return outcome.kind === 'withdrawn' ? SUCCESS_EXIT_CODE : FAILURE_EXIT_CODE
45
46
  }
46
47
 
47
48
  async function run(argv: ReadonlyArray<string>): Promise<number> {
@@ -10,22 +10,21 @@ import { lane_close, type CloseKind } from './lane-close'
10
10
  import { lane_preserve, type KeptWork } from './lane-preserve'
11
11
  import { lane_reap } from './lane-reap'
12
12
  import { lane_registry, type LaneInfo } from './lane-registry'
13
+ import { lane_residents } from './lane-residents'
14
+ import { lane_state } from './lane-state'
13
15
 
14
- // `josh lane:withdraw <N> --reason <text>` — a person takes a running lane child's issue out of the run
15
- // for good: the child is stopped, its work stashed, the Issue closed as not planned and the lane closed.
16
+ // `josh lane:withdraw <N> --reason <text>` — a person takes a running lane child's issue out of the
17
+ // current run: the child is stopped, its work stashed and the lane closed. **The Issue stays open** —
18
+ // a withdrawal ends this run's attempt, not the work — so a later run offers it again; this run does
19
+ // not (`backlog-drive-restore.ts` → `offer_exclude`, and the drive's own exclusion).
16
20
  //
17
21
  // **The `withdraw` event is written first, before anything is stopped.** Killing the child alone would
18
22
  // let `lane:await` book it stopped and `run:merge` classify it from GitHub — an open issue resumed as an
19
- // `outage` or parked `needs-decision`. `run:merge` reads the event stream before GitHub, so a child whose
20
- // newest launch-or-withdraw event is a withdraw is booked `withdrawn` whatever the Issue's state reads
21
- // at that moment, and the race between the kill and the close cannot book it as anything else.
23
+ // `outage` or parked `run:stalled`. `run:merge` reads the event stream before GitHub, so a child whose
24
+ // newest launch-or-withdraw event is a withdraw is booked `withdrawn` whatever the Issue's state reads.
22
25
  //
23
- // **The issue is read again once the child is stopped.** It may merge between the first read and the
24
- // reap; the reap stopped it, so the second read is final, and an issue it already closed keeps
25
- // GitHub's close — `run:merge` books a merged close as merged whatever the event stream says.
26
- //
27
- // A tree that could not be stashed is left in place with the Issue open: closing the lane would delete
28
- // the work, and the person decides what to keep.
26
+ // A tree that could not be stashed is left in place: closing the lane would delete the work, and the
27
+ // person decides what to keep.
29
28
 
30
29
  const WITHDRAW_OCCASION = 'lane withdraw'
31
30
  const WITHDRAW_CAUSE = 'a person withdrew it with `lane:withdraw`'
@@ -41,22 +40,21 @@ interface Withdrawn {
41
40
  // How many of the child's processes the withdrawal stopped — 0 for a child that had already ended.
42
41
  reaped: number
43
42
  stash: string | undefined
44
- is_closed: boolean
45
- // The issue had closed on its own — merged — before the withdrawal reached it, so it was left as is.
46
- had_closed: boolean
43
+ // Whether the comment saying the issue stays open reached it.
44
+ is_noted: boolean
47
45
  lane: CloseKind
46
+ // What else the close ended from the checkout; `undefined` where it could not be read.
47
+ residents: ReadonlyArray<number> | undefined
48
48
  }
49
49
 
50
- type IssueSettled = Pick<Withdrawn, 'had_closed' | 'is_closed'>
51
-
52
50
  type Refused =
53
51
  { kind: typeof CLOSED_KIND } | { kind: typeof NO_LANE_KIND } | { kind: typeof UNREADABLE_KIND }
54
52
  type WithdrawOutcome = Withdrawn | Unsaved | Refused
55
53
 
56
- function close_comment(reason: string): string {
54
+ function withdraw_comment(reason: string): string {
57
55
  return [
58
- 'Withdrawn by a person with `pnpm josh lane:withdraw`.',
59
- 'Its lane child was stopped and the lane closed.',
56
+ 'Withdrawn from the current run by a person with `pnpm josh lane:withdraw`.',
57
+ 'Its lane child was stopped and the lane closed. The Issue stays open: this run does not resume it, and the next run offers it again.',
60
58
  `- Why: ${reason}`,
61
59
  ].join('\n')
62
60
  }
@@ -78,47 +76,45 @@ async function refusal_of(issue: string): Promise<Refused | undefined> {
78
76
  return undefined
79
77
  }
80
78
 
81
- async function close_open_issue(issue: string, reason: string): Promise<IssueSettled> {
82
- const refusal = await refusal_of(issue)
83
-
84
- // An unread issue may have merged during the reap, so it is left open for a person to close.
85
- if (refusal !== undefined) {
86
- const is_closed = refusal.kind === CLOSED_KIND
87
-
88
- return { is_closed, had_closed: is_closed }
89
- }
90
-
91
- const is_closed = await git_gh_issue_write.issue_close_not_planned(issue, close_comment(reason))
92
-
93
- return { is_closed, had_closed: false }
94
- }
95
-
96
- async function close_issue(
79
+ async function note_issue(
97
80
  issue: string,
98
81
  reason: string,
99
82
  stash: string | undefined,
100
- ): Promise<IssueSettled> {
101
- const settled = await close_open_issue(issue, reason)
83
+ ): Promise<boolean> {
84
+ const is_noted = await git_gh_issue_write.issue_try_comment(issue, withdraw_comment(reason))
102
85
 
103
86
  if (stash !== undefined) await lane_preserve.announce(issue, stash, WITHDRAW_CAUSE)
104
87
  await run_label.unmark(issue)
105
88
 
106
- return settled
89
+ return is_noted
107
90
  }
108
91
 
109
92
  async function stop_and_close(lane: LaneInfo, reason: string): Promise<WithdrawOutcome> {
110
93
  await record_withdraw(lane.issue, reason)
111
- const reaped = lane_reap.reap_child(lane.issue).length
94
+ const reaped = lane_reap.reap_child(lane).length
112
95
  const saved = await lane_preserve.keep_work(lane.issue, lane.directory, WITHDRAW_OCCASION)
113
96
 
114
97
  if (saved.kind === 'unsaved') return saved
115
- const settled = await close_issue(lane.issue, reason, saved.stash)
98
+ const is_noted = await note_issue(lane.issue, reason, saved.stash)
116
99
  const closed = await lane_close.close_lane(lane.issue)
117
100
 
118
- return { kind: 'withdrawn', reaped, stash: saved.stash, ...settled, lane: closed.kind }
101
+ // After the close, so the record names the withdrawal rather than the close it ran. An `incomplete`
102
+ // close is not `ended`: the supervisor closes the lane again until its last process is gone.
103
+ if (closed.kind !== 'incomplete') {
104
+ await lane_state.record_change({ issue: lane.issue, state: 'ended', command: 'lane:withdraw' })
105
+ }
106
+
107
+ return {
108
+ kind: 'withdrawn',
109
+ reaped,
110
+ stash: saved.stash,
111
+ is_noted,
112
+ lane: closed.kind,
113
+ residents: closed.residents,
114
+ }
119
115
  }
120
116
 
121
- /** Stop `#<N>`'s lane child, stash its work, close the Issue as not planned and close the lane. */
117
+ /** Stop `#<N>`'s lane child, stash its work and close the lane, leaving the Issue open. */
122
118
  async function withdraw(issue: string, reason: string): Promise<WithdrawOutcome> {
123
119
  issue_number_shape.require_issue_number(issue)
124
120
  const refusal = await refusal_of(issue)
@@ -137,21 +133,26 @@ function stash_sentence(stash: string | undefined): string {
137
133
  return `Its uncommitted work was stashed — recover with \`pnpm josh stash:pop "${stash}"\`.`
138
134
  }
139
135
 
136
+ // What the lane's close left or ended, as a suffix.
137
+ function lane_suffix(outcome: Withdrawn, cited: string): string {
138
+ const removed = outcome.lane === 'incomplete' ? ' The lane could not be fully removed.' : ''
139
+ const residents = lane_residents.residents_sentence(outcome.residents, cited)
140
+
141
+ return residents === undefined ? removed : `${removed} ${residents}`
142
+ }
143
+
140
144
  function withdrawn_text(outcome: Withdrawn, issue: string): string {
141
145
  const cited = session_cite.issue(issue)
142
146
  const stopped = outcome.reaped === 0 ? 'Its child had already ended.' : 'Stopped its child.'
143
147
  const head = `Withdrew ${cited}. ${stopped} ${stash_sentence(outcome.stash)}`
144
- const lane = outcome.lane === 'incomplete' ? ' The lane could not be fully removed.' : ''
145
-
146
- if (outcome.had_closed) return `${head} The Issue had already closed and was left as is.${lane}`
147
-
148
- if (outcome.is_closed) return `${head} The Issue is closed as not planned.${lane}`
148
+ const lane = lane_suffix(outcome, cited)
149
+ const noted = outcome.is_noted ? '' : ' The comment saying so could not be posted.'
149
150
 
150
- return `${head} The Issue could not be closed — close ${cited} by hand; \`run:merge\` books it withdrawn either way.${lane}`
151
+ return `${head} The Issue stays open: this run does not offer it again, the next run does.${noted}${lane}`
151
152
  }
152
153
 
153
154
  function unsaved_text(outcome: Unsaved, issue: string): string {
154
- return `The child for ${session_cite.issue(issue)} was stopped, but its uncommitted work could not be stashed (${outcome.reason}), so the Issue is left open and the lane at ${outcome.directory}; \`run:merge\` books it withdrawn.`
155
+ return `The child for ${session_cite.issue(issue)} was stopped, but its uncommitted work could not be stashed (${outcome.reason}), so the lane is left at ${outcome.directory}; \`run:merge\` books it withdrawn.`
155
156
  }
156
157
 
157
158
  function refused_text(outcome: Refused, issue: string): string {