@joshuafolkken/kit 1.1471.0 → 1.1784.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (895) hide show
  1. package/.claude/agents/investigator.md +1 -1
  2. package/.claude/settings.json +6 -6
  3. package/.claude/skills/epic-commands/SKILL.md +26 -77
  4. package/.claude/skills/epic-commands/epic-bundle.md +12 -6
  5. package/.claude/skills/epic-commands/execution-waves.md +1 -2
  6. package/.claude/skills/verify-ui/SKILL.md +1 -2
  7. package/.claude/skills/workflow-commands/SKILL.md +12 -14
  8. package/.claude/skills/workflow-commands/background-commands.md +8 -12
  9. package/.claude/skills/workflow-commands/backlogrun-child.md +13 -18
  10. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
  11. package/.claude/skills/workflow-commands/backlogrun-lanes.md +23 -28
  12. package/.claude/skills/workflow-commands/backlogrun-park.md +16 -31
  13. package/.claude/skills/workflow-commands/backlogrun-progress.md +12 -21
  14. package/.claude/skills/workflow-commands/backlogrun-recovery.md +12 -12
  15. package/.claude/skills/workflow-commands/backlogrun-steps.md +12 -20
  16. package/.claude/skills/workflow-commands/backlogrun.md +32 -51
  17. package/.claude/skills/workflow-commands/chain-rule.md +18 -11
  18. package/.claude/skills/workflow-commands/delegation.md +13 -8
  19. package/.claude/skills/workflow-commands/entry-sequence.md +10 -12
  20. package/.claude/skills/workflow-commands/followup.md +10 -35
  21. package/.claude/skills/workflow-commands/fullrun-steps.md +38 -49
  22. package/.claude/skills/workflow-commands/fullrun.md +6 -8
  23. package/.claude/skills/workflow-commands/halfrun.md +20 -32
  24. package/.claude/skills/workflow-commands/into-target.md +1 -2
  25. package/.claude/skills/workflow-commands/issue-comments.md +19 -15
  26. package/.claude/skills/workflow-commands/issue-scout.md +5 -4
  27. package/.claude/skills/workflow-commands/kickoff.md +24 -23
  28. package/.claude/skills/workflow-commands/latest-gate.md +9 -18
  29. package/.claude/skills/workflow-commands/needs-human-review.md +11 -19
  30. package/.claude/skills/workflow-commands/observation-filing.md +4 -50
  31. package/.claude/skills/workflow-commands/observation-ledger.md +5 -10
  32. package/.claude/skills/workflow-commands/pre-gate-cut.md +22 -44
  33. package/.claude/skills/workflow-commands/prerequisite.md +11 -18
  34. package/.claude/skills/workflow-commands/progress-watcher.md +3 -8
  35. package/.claude/skills/workflow-commands/prrun.md +6 -12
  36. package/.claude/skills/workflow-commands/retrospective.md +5 -5
  37. package/.claude/skills/workflow-commands/split-assessment.md +14 -4
  38. package/.claude/skills/workflow-commands/target-repository.md +1 -2
  39. package/.claude/skills/workflow-commands/working-tree-hold.md +11 -13
  40. package/.codex/hooks.json +6 -6
  41. package/.github/actions/setup-node/action.yml +10 -1
  42. package/.github/actions/setup-pnpm/action.yml +1 -1
  43. package/.github/dependabot.yml +16 -0
  44. package/.github/release.yml +0 -2
  45. package/.github/workflows/ci.yml +121 -11
  46. package/.github/workflows/publish.yml +10 -3
  47. package/.github/workflows/sonar-qube.yml +1 -0
  48. package/.prettierignore +2 -0
  49. package/.vscode/tasks.json +1 -2
  50. package/CLAUDE.md +4 -8
  51. package/README.md +4 -2
  52. package/SECURITY.md +1 -1
  53. package/cspell/index.yaml +7 -0
  54. package/dist/CLAUDE.md +4 -8
  55. package/dist/commands/document-read-cli.js +882 -0
  56. package/dist/commands/{document-section-cli.js → document-section-main.js} +137 -62
  57. package/dist/commands/read-set-cli.js +1867 -0
  58. package/dist/commands/run-prep-main.js +21653 -0
  59. package/dist/commands/run-step-cli.js +23880 -0
  60. package/dist/config-merge/index.js +5 -1
  61. package/dist/hooks/audit-provision.js +20 -35
  62. package/dist/hooks/{chunk-DGT54IH5.js → chunk-AZX4FGQ3.js} +63 -17
  63. package/dist/hooks/chunk-CWMBGKYW.js +6483 -0
  64. package/dist/hooks/chunk-O2YBIDSI.js +4306 -0
  65. package/dist/hooks/{chunk-AS74OU3D.js → chunk-PT5R6UJD.js} +4582 -2118
  66. package/dist/hooks/chunk-TUIFS5E7.js +72 -0
  67. package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
  68. package/dist/hooks/{chunk-E7OIKX5Z.js → chunk-WR2KQAYZ.js} +1863 -382
  69. package/dist/hooks/{chunk-KC5AK2GF.js → chunk-XGBNSWEI.js} +248 -46
  70. package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
  71. package/dist/hooks/codex-hook-adapter.js +10 -19
  72. package/dist/hooks/format-edited.js +5 -5
  73. package/dist/hooks/inputs.json +436 -257
  74. package/dist/hooks/pretool-guard.js +7 -22
  75. package/dist/hooks/session-lang.js +380 -42
  76. package/dist/hooks/stop-guard.js +8711 -782
  77. package/dist/josh.js +5263 -997
  78. package/dist/self-sync-guard/index.js +74 -10
  79. package/dist/version/index.js +115 -406
  80. package/eslint/base.js +1 -1
  81. package/lefthook/base.yml +8 -4
  82. package/package.json +17 -53
  83. package/pnpm-workspace.yaml +4 -2
  84. package/prompts/coding-standards.md +1 -1
  85. package/prompts/collaboration-workflow/file-edits.md +1 -9
  86. package/prompts/collaboration-workflow/gh-rest.md +1 -2
  87. package/prompts/collaboration-workflow/issue-citation.md +2 -4
  88. package/prompts/collaboration-workflow/issue-template.md +42 -17
  89. package/prompts/collaboration-workflow/lane-instructions.md +34 -0
  90. package/prompts/collaboration-workflow/measurement.md +37 -0
  91. package/prompts/collaboration-workflow/operating-rules.md +6 -12
  92. package/prompts/collaboration-workflow/output-bounds.md +4 -9
  93. package/prompts/collaboration-workflow/overview.md +1 -1
  94. package/prompts/collaboration-workflow/plan-comment.md +3 -42
  95. package/prompts/collaboration-workflow/principles.md +19 -8
  96. package/prompts/collaboration-workflow/report-format.md +37 -57
  97. package/prompts/collaboration-workflow/residency.md +12 -8
  98. package/prompts/collaboration-workflow/rule-delivery.md +3 -11
  99. package/prompts/collaboration-workflow/shell-body.md +8 -18
  100. package/prompts/collaboration-workflow/turn-batching.md +4 -6
  101. package/prompts/collaboration-workflow/upstream-interrupt.md +16 -6
  102. package/prompts/collaboration-workflow/wip-cap.md +7 -7
  103. package/prompts/collaboration-workflow.md +4 -7
  104. package/prompts/refactoring.md +1 -1
  105. package/prompts/review-rubric.md +1 -2
  106. package/prompts/review.md +45 -26
  107. package/prompts/testing-guide.md +10 -45
  108. package/scripts/agent/agent-argv.ts +20 -4
  109. package/scripts/agent/agent-event.ts +15 -15
  110. package/scripts/agent/agent-exit-record.ts +13 -1
  111. package/scripts/agent/agent-role-profile.ts +101 -45
  112. package/scripts/agent/agent-safe-text.ts +60 -0
  113. package/scripts/agent/api-auth.ts +41 -0
  114. package/scripts/agent/api-outage.ts +1 -1
  115. package/scripts/agent/claude-agent-argv.ts +14 -0
  116. package/scripts/agent/codex-agent-argv.ts +2 -0
  117. package/scripts/agent/lane-instructions.ts +144 -0
  118. package/scripts/auto-ok/auto-ok-cli.ts +14 -16
  119. package/scripts/auto-ok/auto-ok-judge-read.ts +12 -3
  120. package/scripts/auto-ok/auto-ok-judge-write.ts +46 -19
  121. package/scripts/auto-ok/auto-ok-judge.ts +13 -2
  122. package/scripts/auto-ok/auto-ok-main.ts +17 -0
  123. package/scripts/backlog/backlog-arrival.ts +14 -3
  124. package/scripts/backlog/backlog-budget-cli.ts +7 -33
  125. package/scripts/backlog/backlog-budget-main.ts +16 -0
  126. package/scripts/backlog/backlog-budget.ts +6 -7
  127. package/scripts/backlog/backlog-defect-priority.ts +4 -3
  128. package/scripts/backlog/backlog-drive-adopt.ts +67 -0
  129. package/scripts/backlog/backlog-drive-args.ts +4 -5
  130. package/scripts/backlog/backlog-drive-cli.ts +113 -28
  131. package/scripts/backlog/backlog-drive-hold.ts +162 -0
  132. package/scripts/backlog/backlog-drive-idle.ts +151 -0
  133. package/scripts/backlog/backlog-drive-judge.ts +25 -0
  134. package/scripts/backlog/backlog-drive-memory.ts +126 -0
  135. package/scripts/backlog/backlog-drive-named-offer.ts +5 -10
  136. package/scripts/backlog/backlog-drive-named.ts +54 -7
  137. package/scripts/backlog/backlog-drive-offer-argv.ts +3 -8
  138. package/scripts/backlog/backlog-drive-paused.ts +169 -0
  139. package/scripts/backlog/backlog-drive-restore.ts +39 -8
  140. package/scripts/backlog/backlog-drive-seats.ts +18 -8
  141. package/scripts/backlog/backlog-drive-token-handling.ts +38 -0
  142. package/scripts/backlog/backlog-drive.ts +79 -75
  143. package/scripts/backlog/backlog-next-main.ts +16 -0
  144. package/scripts/backlog/backlog-next-shared.ts +73 -0
  145. package/scripts/backlog/backlog-next.ts +48 -16
  146. package/scripts/backlog/backlog-occupied.ts +69 -0
  147. package/scripts/backlog/backlog-offer-cli.ts +6 -21
  148. package/scripts/backlog/backlog-offer-exclude.ts +15 -0
  149. package/scripts/backlog/backlog-offer-main.ts +12 -0
  150. package/scripts/backlog/backlog-offer.ts +36 -3
  151. package/scripts/backlog/backlog-overlap.ts +22 -4
  152. package/scripts/backlog/backlog-plan-read.ts +6 -2
  153. package/scripts/backlog/backlog-plan.ts +18 -4
  154. package/scripts/backlog/backlog-pool.ts +10 -10
  155. package/scripts/backlog/backlog-rank.ts +10 -2
  156. package/scripts/backlog/backlog-ready.ts +137 -18
  157. package/scripts/backlog/backlog-stalled-detect.ts +109 -36
  158. package/scripts/backlog/backlog-stalled.ts +52 -16
  159. package/scripts/backlog/backlog-wait-cause.ts +86 -0
  160. package/scripts/backlog/backlog-waves.ts +39 -13
  161. package/scripts/backlog/backlogrun-args.ts +19 -7
  162. package/scripts/backlog/backlogrun-cli.ts +19 -5
  163. package/scripts/backlog/backlogrun-launch.ts +6 -0
  164. package/scripts/backlog/backlogrun-restart.ts +97 -0
  165. package/scripts/backlog/backlogrun-stop.ts +79 -7
  166. package/scripts/behavior/behavior-cli.ts +2 -2
  167. package/scripts/behavior/behavior-rules.ts +47 -24
  168. package/scripts/build/build-bin.ts +2 -16
  169. package/scripts/build/build-claude-md.ts +0 -7
  170. package/scripts/build/build-commands.ts +0 -13
  171. package/scripts/build/build-hooks.ts +49 -48
  172. package/scripts/build/hook-bundle-stamp.ts +29 -11
  173. package/scripts/build/local-bin.ts +1 -1
  174. package/scripts/cases/cases-cli.ts +25 -13
  175. package/scripts/cases/cases-interaction-scan.ts +134 -0
  176. package/scripts/cases/cases-interaction.ts +183 -0
  177. package/scripts/cases/cases-logic.ts +39 -6
  178. package/scripts/ci/pr-classification-main.ts +18 -0
  179. package/scripts/ci/pr-classification.ts +10 -17
  180. package/scripts/clone/clone-scan.ts +1 -1
  181. package/scripts/cost-runtime/cost-blocks.ts +22 -37
  182. package/scripts/cost-runtime/cost-cli.ts +31 -14
  183. package/scripts/cost-runtime/cost-main.ts +12 -0
  184. package/scripts/cost-runtime/cost-transcript.ts +1 -0
  185. package/scripts/delegation/delegation-policy.ts +17 -4
  186. package/scripts/delegation/duplicate-read-guard.ts +2 -10
  187. package/scripts/delegation/investigation-guard.ts +15 -73
  188. package/scripts/delegation/investigation-reads.ts +3 -5
  189. package/scripts/dependabot/dependabot-cooldown.ts +194 -0
  190. package/scripts/discovery/repo-discovery.ts +24 -6
  191. package/scripts/doctor/doctor-consumer.ts +2 -5
  192. package/scripts/document/document-byte-budget.ts +9 -6
  193. package/scripts/document/document-scan.ts +1 -1
  194. package/scripts/document/document-section-cli.ts +17 -13
  195. package/scripts/document/document-section-main.ts +12 -0
  196. package/scripts/document/entry-read-budget.ts +2 -2
  197. package/scripts/document/read-set-cli.ts +4 -1
  198. package/scripts/epic/epic-audit-cli.ts +12 -6
  199. package/scripts/epic/epic-audit-orphans.ts +5 -8
  200. package/scripts/epic/epic-audit.ts +52 -1
  201. package/scripts/epic/epic-bundle-apply.ts +137 -0
  202. package/scripts/epic/epic-bundle-cli.ts +32 -121
  203. package/scripts/epic/epic-bundle-evidence.ts +49 -26
  204. package/scripts/epic/epic-bundle-format.ts +116 -0
  205. package/scripts/epic/epic-bundle-main.ts +17 -0
  206. package/scripts/epic/epic-bundle-referenced.ts +14 -3
  207. package/scripts/epic/epic-bundle.ts +17 -9
  208. package/scripts/epic/epic-busy.ts +5 -12
  209. package/scripts/epic/epic-classify.ts +24 -15
  210. package/scripts/epic/epic-cli-argv.ts +31 -0
  211. package/scripts/epic/epic-cli-decide.ts +42 -0
  212. package/scripts/epic/epic-cli.ts +6 -38
  213. package/scripts/epic/epic-close.ts +112 -55
  214. package/scripts/epic/epic-cross-repo.ts +4 -7
  215. package/scripts/epic/epic-decide.ts +119 -0
  216. package/scripts/epic/epic-decision.ts +9 -0
  217. package/scripts/epic/epic-fetch.ts +4 -0
  218. package/scripts/epic/epic-graph.ts +2 -0
  219. package/scripts/epic/epic-issue.ts +5 -1
  220. package/scripts/epic/epic-label-age.ts +1 -1
  221. package/scripts/epic/epic-lane-offer.ts +39 -4
  222. package/scripts/epic/epic-next-main.ts +24 -0
  223. package/scripts/epic/epic-next.ts +6 -24
  224. package/scripts/epic/epic-outside-blocker.ts +6 -2
  225. package/scripts/epic/epic-parse.ts +9 -3
  226. package/scripts/epic/epic-read.ts +1 -0
  227. package/scripts/epic/epic-reconcile.ts +39 -0
  228. package/scripts/epic/epic-run.ts +10 -1
  229. package/scripts/epic/epic-solo.ts +50 -14
  230. package/scripts/epic/epic.ts +41 -7
  231. package/scripts/exports/unused-members-cli.ts +2 -2
  232. package/scripts/followup/followup-checks-event.ts +8 -3
  233. package/scripts/followup/followup-coderabbit-wait.ts +82 -0
  234. package/scripts/followup/followup-review-gates.ts +81 -0
  235. package/scripts/followup/git-followup-stages.ts +13 -3
  236. package/scripts/followup/git-followup-workflow.ts +31 -60
  237. package/scripts/followup/git-pr-followup-wrapup.ts +9 -14
  238. package/scripts/followup/git-pr-followup.ts +36 -8
  239. package/scripts/fresh-machine/fresh-machine-cli.ts +1 -1
  240. package/scripts/fresh-machine/fresh-machine-run.ts +8 -8
  241. package/scripts/fresh-machine/specs/kit-test-backlogrun.json +1 -1
  242. package/scripts/gate/busy-average.ts +58 -0
  243. package/scripts/gate/check-cpu.ts +60 -0
  244. package/scripts/gate/check-inputs.ts +73 -0
  245. package/scripts/gate/check-reuse.ts +141 -0
  246. package/scripts/gate/command-memory.ts +192 -0
  247. package/scripts/gate/core-admission.ts +218 -28
  248. package/scripts/gate/core-budget-timing.ts +37 -0
  249. package/scripts/gate/core-budget.ts +150 -119
  250. package/scripts/gate/core-wait-record.ts +48 -0
  251. package/scripts/gate/core-wait.ts +162 -0
  252. package/scripts/gate/core-weights.ts +86 -0
  253. package/scripts/gate/free-cores.ts +72 -0
  254. package/scripts/gate/gate-ledger.ts +49 -7
  255. package/scripts/gate/gate-plan.ts +44 -15
  256. package/scripts/gate/gate-report.ts +29 -4
  257. package/scripts/gate/gate-run-steps.ts +195 -0
  258. package/scripts/gate/gate-skip.ts +12 -2
  259. package/scripts/gate/gate-steps.ts +12 -1
  260. package/scripts/gate/held-mark.ts +55 -0
  261. package/scripts/gate/input-fingerprint.ts +42 -0
  262. package/scripts/gate/machine-capacity.ts +124 -31
  263. package/scripts/gate/moved-paths.ts +67 -0
  264. package/scripts/gate/pre-commit-type-check.ts +14 -1
  265. package/scripts/gate/project-checks.ts +5 -12
  266. package/scripts/gate/scoped-green.ts +12 -8
  267. package/scripts/gate/since-green.ts +62 -0
  268. package/scripts/gate/toolchain-inputs.ts +115 -0
  269. package/scripts/gate/verification-gate.ts +65 -129
  270. package/scripts/gate/verification-inputs.ts +250 -0
  271. package/scripts/gh/gh-author-association.ts +96 -9
  272. package/scripts/gh/git-ai-review-scan.ts +4 -2
  273. package/scripts/gh/git-gh-api-path.ts +15 -0
  274. package/scripts/gh/git-gh-branch-rules.ts +73 -0
  275. package/scripts/gh/git-gh-conditional.ts +5 -2
  276. package/scripts/gh/git-gh-issue-read.ts +5 -1
  277. package/scripts/gh/git-gh-issue-rest.ts +1 -0
  278. package/scripts/gh/git-gh-issue-write.ts +77 -17
  279. package/scripts/gh/git-gh-issue.ts +7 -3
  280. package/scripts/gh/git-gh-poll-read.ts +89 -0
  281. package/scripts/gh/git-gh-pr-auto-merge.ts +8 -3
  282. package/scripts/gh/git-gh-pr-rest.ts +1 -1
  283. package/scripts/gh/git-gh-pr-snapshot.ts +33 -20
  284. package/scripts/gh/git-gh-pr.ts +27 -15
  285. package/scripts/gh/git-pr-checks-eval.ts +39 -7
  286. package/scripts/gh/git-pr-checks-parse.ts +39 -9
  287. package/scripts/gh/git-pr-merge-checked.ts +80 -0
  288. package/scripts/gh/git-pr.ts +13 -1
  289. package/scripts/git/base-tree.ts +19 -2
  290. package/scripts/git/changed-file-scope.ts +6 -4
  291. package/scripts/git/changed-paths.ts +18 -1
  292. package/scripts/git/git-diff-reads.ts +27 -2
  293. package/scripts/git/git-grep-hits.ts +85 -0
  294. package/scripts/git/git-location-environment.ts +1 -1
  295. package/scripts/git/git-merge-conflicts.ts +83 -0
  296. package/scripts/git/git-preflight.ts +37 -12
  297. package/scripts/git/git-push-transport.ts +1 -2
  298. package/scripts/git/git-schemas.ts +17 -7
  299. package/scripts/git/git-spawn.ts +1 -2
  300. package/scripts/git/git-status.ts +4 -4
  301. package/scripts/git/main-merge-main.ts +12 -0
  302. package/scripts/git/main-merge-regenerate.ts +78 -0
  303. package/scripts/git/main-merge.ts +39 -14
  304. package/scripts/git/main-sync-main.ts +12 -0
  305. package/scripts/git/main-sync.ts +0 -9
  306. package/scripts/git/stash/git-stash.ts +27 -4
  307. package/scripts/git/stash/{stash-pop-args.ts → stash-args.ts} +13 -10
  308. package/scripts/git/stash/stash-pop-cli.ts +6 -12
  309. package/scripts/git/stash/stash-pop-main.ts +12 -0
  310. package/scripts/git/stash/stash-push-cli.ts +76 -0
  311. package/scripts/git/stash/stash-push-main.ts +12 -0
  312. package/scripts/hooks/batch-guard.ts +5 -16
  313. package/scripts/hooks/check-commit-message-main.ts +8 -0
  314. package/scripts/hooks/check-commit-message.ts +4 -7
  315. package/scripts/hooks/format-edited-file.ts +8 -24
  316. package/scripts/hooks/pre-commit-lint.ts +118 -0
  317. package/scripts/hooks/pre-push-unit.ts +4 -2
  318. package/scripts/hooks/pretool-guard-cli.ts +1 -8
  319. package/scripts/hooks/pretool-guard.ts +57 -69
  320. package/scripts/hooks/reserved-run.ts +67 -8
  321. package/scripts/hooks/run-hook.sh +18 -11
  322. package/scripts/hooks/shell-rules-notice.ts +37 -0
  323. package/scripts/hooks/stop-actions.ts +185 -0
  324. package/scripts/hooks/stop-guard.ts +72 -27
  325. package/scripts/init/hook-command-rewrite.ts +19 -5
  326. package/scripts/init/hook-launch.ts +15 -12
  327. package/scripts/init/init-actions.ts +0 -6
  328. package/scripts/init/init-ai-copy.ts +10 -36
  329. package/scripts/init/init-bootstrap.ts +9 -8
  330. package/scripts/init/init-dry-run-report.ts +1 -1
  331. package/scripts/init/init-dry-run.ts +1 -1
  332. package/scripts/init/init-file-action.ts +7 -9
  333. package/scripts/init/init-logic-json-merge.ts +2 -2
  334. package/scripts/init/init-logic-migrate.ts +9 -82
  335. package/scripts/init/init-logic.ts +3 -2
  336. package/scripts/init/init-main.ts +12 -0
  337. package/scripts/init/init.ts +5 -12
  338. package/scripts/init/kit-development-versions.ts +3 -7
  339. package/scripts/init/kit-written-paths.ts +2 -2
  340. package/scripts/init/project-profile.ts +5 -4
  341. package/scripts/init/tsconfig-preset-migration.ts +2 -1
  342. package/scripts/init/vscode-tasks.ts +1 -1
  343. package/scripts/issue/defect-origin-cli.ts +106 -0
  344. package/scripts/issue/defect-origin-line.ts +60 -0
  345. package/scripts/issue/defect-origin-main.ts +11 -0
  346. package/scripts/issue/defect-origin.ts +114 -0
  347. package/scripts/issue/defect-rate-cli.ts +34 -78
  348. package/scripts/issue/defect-rate.ts +0 -16
  349. package/scripts/issue/defect-report-cli.ts +128 -0
  350. package/scripts/issue/defect-report-format.ts +56 -0
  351. package/scripts/issue/defect-report-main.ts +11 -0
  352. package/scripts/issue/defect-report.ts +160 -0
  353. package/scripts/issue/expected-effect-lint.ts +60 -0
  354. package/scripts/issue/issue-already-done-cli.ts +62 -0
  355. package/scripts/issue/issue-body-or-comment.ts +40 -0
  356. package/scripts/issue/issue-cite-cli.ts +33 -22
  357. package/scripts/issue/issue-cite-main.ts +12 -0
  358. package/scripts/issue/issue-classification.ts +13 -8
  359. package/scripts/issue/issue-comment-cli.ts +10 -24
  360. package/scripts/issue/issue-comment-main.ts +12 -0
  361. package/scripts/issue/issue-evidence-exit.ts +100 -0
  362. package/scripts/issue/issue-file-cli.ts +29 -7
  363. package/scripts/issue/issue-file.ts +19 -19
  364. package/scripts/issue/issue-fold-cli.ts +2 -11
  365. package/scripts/issue/issue-fold-main.ts +12 -0
  366. package/scripts/issue/issue-labels.ts +81 -90
  367. package/scripts/issue/issue-lint-cli.ts +7 -13
  368. package/scripts/issue/issue-lint-main.ts +12 -0
  369. package/scripts/issue/issue-measured-cli.ts +56 -0
  370. package/scripts/issue/issue-merged.ts +19 -2
  371. package/scripts/issue/issue-not-before-label.ts +135 -0
  372. package/scripts/issue/issue-not-before.ts +111 -0
  373. package/scripts/issue/issue-number-shape.ts +15 -1
  374. package/scripts/issue/issue-park.ts +28 -0
  375. package/scripts/issue/issue-plan-cli.ts +151 -0
  376. package/scripts/issue/issue-priority.ts +151 -0
  377. package/scripts/issue/issue-rank.ts +7 -1
  378. package/scripts/issue/issue-read-cli.ts +3 -10
  379. package/scripts/issue/issue-read-main.ts +12 -0
  380. package/scripts/issue/issue-read.ts +29 -5
  381. package/scripts/issue/issue-release-cli.ts +0 -10
  382. package/scripts/issue/issue-release-main.ts +13 -0
  383. package/scripts/issue/issue-release.ts +7 -12
  384. package/scripts/issue/issue-sample-gate.ts +192 -0
  385. package/scripts/issue/issue-sample-source.ts +76 -0
  386. package/scripts/issue/issue-scout-cli.ts +19 -25
  387. package/scripts/issue/issue-scout-main.ts +14 -0
  388. package/scripts/issue/issue-state-cli.ts +0 -10
  389. package/scripts/issue/issue-state-main.ts +12 -0
  390. package/scripts/issue/issue-watch-diff.ts +56 -15
  391. package/scripts/issue/issue-watch.ts +2 -1
  392. package/scripts/issue/issue-wip.ts +2 -7
  393. package/scripts/issue/markdown-section.ts +19 -5
  394. package/scripts/issue/measure-rerun-cli.ts +13 -8
  395. package/scripts/issue/plan-consumers-cli.ts +39 -0
  396. package/scripts/issue/plan-consumers-main.ts +11 -0
  397. package/scripts/issue/plan-consumers-section.ts +55 -0
  398. package/scripts/issue/plan-consumers.ts +127 -0
  399. package/scripts/josh/agent-session-environment.ts +1 -1
  400. package/scripts/josh/command-usage.ts +82 -0
  401. package/scripts/josh/file-map-stamp.ts +49 -16
  402. package/scripts/josh/hook-decision.ts +32 -20
  403. package/scripts/josh/josh-command-map.ts +6 -1
  404. package/scripts/josh/josh-command-types.ts +65 -13
  405. package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
  406. package/scripts/josh/josh-commands-ai.ts +169 -157
  407. package/scripts/josh/josh-commands-backlog.ts +82 -16
  408. package/scripts/josh/josh-commands-clone.ts +1 -0
  409. package/scripts/josh/josh-commands-development.ts +111 -71
  410. package/scripts/josh/josh-commands-document.ts +43 -1
  411. package/scripts/josh/josh-commands-epic.ts +171 -0
  412. package/scripts/josh/josh-commands-hooks.ts +31 -2
  413. package/scripts/josh/josh-commands-issue-write.ts +181 -0
  414. package/scripts/josh/josh-commands-issue.ts +124 -24
  415. package/scripts/josh/josh-commands-lane.ts +112 -2
  416. package/scripts/josh/josh-commands-lint.ts +19 -8
  417. package/scripts/josh/josh-commands-maintenance.ts +112 -4
  418. package/scripts/josh/josh-commands-pause.ts +29 -0
  419. package/scripts/josh/josh-commands-progress.ts +87 -0
  420. package/scripts/josh/josh-commands-project.ts +138 -9
  421. package/scripts/josh/josh-commands-review.ts +124 -0
  422. package/scripts/josh/josh-commands-run.ts +211 -23
  423. package/scripts/josh/josh-commands-ship.ts +169 -0
  424. package/scripts/josh/josh-commands-split.ts +9 -0
  425. package/scripts/josh/josh-commands-versioning.ts +49 -2
  426. package/scripts/josh/josh-commands-workflow.ts +149 -6
  427. package/scripts/josh/josh-logic.ts +11 -27
  428. package/scripts/josh/josh.ts +14 -5
  429. package/scripts/josh/package-directory.ts +18 -0
  430. package/scripts/josh/process-identity.ts +13 -4
  431. package/scripts/josh/session-language-cli.ts +4 -8
  432. package/scripts/josh/session-language-main.ts +13 -0
  433. package/scripts/josh/session-language.ts +6 -1
  434. package/scripts/josh/shared-cache.ts +90 -0
  435. package/scripts/josh/stamp-file.ts +9 -15
  436. package/scripts/lane/lane-await.ts +51 -12
  437. package/scripts/lane/lane-cache.ts +5 -30
  438. package/scripts/lane/lane-capacity.ts +19 -22
  439. package/scripts/lane/lane-check-stats.ts +97 -0
  440. package/scripts/lane/lane-child-invocation.ts +43 -4
  441. package/scripts/lane/lane-cli.ts +15 -5
  442. package/scripts/lane/lane-close.ts +86 -18
  443. package/scripts/lane/lane-core-wait-stats.ts +66 -0
  444. package/scripts/lane/lane-dispatch.ts +27 -6
  445. package/scripts/lane/lane-gap-stats.ts +156 -0
  446. package/scripts/lane/lane-guard-policy.ts +2 -2
  447. package/scripts/lane/lane-handoff.ts +76 -1
  448. package/scripts/lane/lane-held-stats.ts +129 -0
  449. package/scripts/lane/lane-install.ts +16 -15
  450. package/scripts/lane/lane-launch-cli.ts +0 -9
  451. package/scripts/lane/lane-launch-main.ts +12 -0
  452. package/scripts/lane/lane-ledger-schema.ts +266 -0
  453. package/scripts/lane/lane-ledger.ts +108 -97
  454. package/scripts/lane/lane-limit-cli.ts +19 -9
  455. package/scripts/lane/lane-measure-cli.ts +58 -10
  456. package/scripts/lane/lane-open.ts +9 -1
  457. package/scripts/lane/lane-parked.ts +3 -3
  458. package/scripts/lane/lane-pause-cli.ts +130 -0
  459. package/scripts/lane/lane-pause.ts +158 -0
  460. package/scripts/lane/lane-preserve.ts +29 -1
  461. package/scripts/lane/lane-process-table.ts +166 -0
  462. package/scripts/lane/lane-reap-settle.ts +124 -0
  463. package/scripts/lane/lane-reap.ts +50 -15
  464. package/scripts/lane/lane-registry.ts +33 -10
  465. package/scripts/lane/lane-residents.ts +162 -0
  466. package/scripts/lane/lane-restart.ts +26 -27
  467. package/scripts/lane/lane-round-two-stats.ts +49 -0
  468. package/scripts/lane/lane-sampler.ts +4 -0
  469. package/scripts/lane/lane-session-action.ts +160 -0
  470. package/scripts/lane/lane-session-broker.ts +134 -134
  471. package/scripts/lane/lane-snapshot-trace.ts +84 -0
  472. package/scripts/lane/lane-spans.ts +51 -0
  473. package/scripts/lane/lane-spent.ts +6 -3
  474. package/scripts/lane/lane-stage-stats.ts +7 -2
  475. package/scripts/lane/lane-state.ts +302 -0
  476. package/scripts/lane/lane-stats.ts +58 -4
  477. package/scripts/lane/lane-stop-stats.ts +113 -37
  478. package/scripts/lane/lane-test-related-stats.ts +127 -0
  479. package/scripts/lane/lane-transcript-calls.ts +145 -0
  480. package/scripts/lane/lane-transcript-stats.ts +168 -0
  481. package/scripts/lane/lane-vacant.ts +13 -3
  482. package/scripts/lane/lane-withdraw-cli.ts +72 -0
  483. package/scripts/lane/lane-withdraw.ts +183 -0
  484. package/scripts/lane/process-directories.ts +70 -0
  485. package/scripts/lane/process-lane-marks.ts +94 -0
  486. package/scripts/lib/atomic-write.ts +62 -0
  487. package/scripts/lib/buffered-process.ts +12 -5
  488. package/scripts/lib/cli-flags.ts +53 -0
  489. package/scripts/lib/figure-format.ts +63 -0
  490. package/scripts/lib/json-value.ts +9 -1
  491. package/scripts/lib/package-manifest.ts +35 -0
  492. package/scripts/lib/read-file.ts +3 -1
  493. package/scripts/lib/stamped-memo.ts +63 -0
  494. package/scripts/lib/stdout-on-stderr.ts +24 -0
  495. package/scripts/lib/timeouts.ts +9 -0
  496. package/scripts/lib/transcript-record.ts +91 -0
  497. package/scripts/lines/effective-limit.ts +1 -1
  498. package/scripts/lint/eslint-cache-dependencies.ts +145 -0
  499. package/scripts/lint/eslint-daemon.ts +265 -0
  500. package/scripts/lint/format.ts +14 -5
  501. package/scripts/lint/import-graph.ts +279 -0
  502. package/scripts/lint/lint-gate-scope.ts +102 -0
  503. package/scripts/lint/lint-parallel-main.ts +19 -0
  504. package/scripts/lint/lint-parallel.ts +72 -33
  505. package/scripts/lint/lint-related-scope.ts +33 -24
  506. package/scripts/lint/lint-related.ts +38 -6
  507. package/scripts/notify/confirmation-options.ts +1 -2
  508. package/scripts/notify/telegram-notify.ts +20 -20
  509. package/scripts/notify/telegram-test-logic.ts +0 -1
  510. package/scripts/notify/telegram-test-main.ts +8 -0
  511. package/scripts/notify/telegram-test.ts +12 -11
  512. package/scripts/observations/observation-ledger.ts +13 -0
  513. package/scripts/observations/observations-flush-landing.ts +5 -3
  514. package/scripts/observations/observations-flush.ts +6 -1
  515. package/scripts/overrides/overrides-check.ts +2 -5
  516. package/scripts/overrides/overrides-files.ts +2 -1
  517. package/scripts/overrides/overrides-logic.ts +3 -6
  518. package/scripts/package/verify-optional-eslint-install.ts +8 -6
  519. package/scripts/propagate/propagate-publish.ts +2 -7
  520. package/scripts/propagate/propagate-targets.ts +4 -12
  521. package/scripts/refactor/import-graph.ts +9 -7
  522. package/scripts/release/github-release-runs.ts +17 -6
  523. package/scripts/release/release-approval-prune.ts +18 -0
  524. package/scripts/release/release-history.ts +1 -3
  525. package/scripts/release/release-progress.ts +42 -22
  526. package/scripts/release/release-publish-run.ts +39 -0
  527. package/scripts/release/release-publish.ts +6 -6
  528. package/scripts/release/release-scope-cli.ts +0 -10
  529. package/scripts/release/release-scope-main.ts +12 -0
  530. package/scripts/repo/repo-setting.ts +3 -6
  531. package/scripts/repo/required-checks-logic.ts +6 -15
  532. package/scripts/report/report-format-reference.ts +4 -0
  533. package/scripts/report/report-labels.ts +155 -0
  534. package/scripts/report/report-lint-cli.ts +3 -0
  535. package/scripts/report/report-lint.ts +85 -110
  536. package/scripts/report/report-template-cli.ts +59 -0
  537. package/scripts/report/report-template.ts +112 -0
  538. package/scripts/review/acceptance-map-check.ts +61 -0
  539. package/scripts/review/acceptance-map.ts +206 -0
  540. package/scripts/review/removed-tests-check.ts +86 -0
  541. package/scripts/review/removed-tests.ts +149 -0
  542. package/scripts/review/review-brief-cli.ts +82 -16
  543. package/scripts/review/review-brief-main.ts +12 -0
  544. package/scripts/review/review-brief.ts +31 -3
  545. package/scripts/review/review-code-tree.ts +10 -6
  546. package/scripts/review/review-comment-round.ts +26 -8
  547. package/scripts/review/review-finding-ledger.ts +30 -15
  548. package/scripts/review/review-interaction.ts +94 -0
  549. package/scripts/review/review-readers-scan.ts +163 -0
  550. package/scripts/review/review-record-cli.ts +69 -30
  551. package/scripts/review/review-record-main.ts +12 -0
  552. package/scripts/review/review-round-one-blobs.ts +221 -0
  553. package/scripts/review/review-round2-cli.ts +49 -12
  554. package/scripts/review/review-round2.ts +80 -12
  555. package/scripts/review/review-stamps.ts +19 -1
  556. package/scripts/review/review-stop-log.ts +96 -0
  557. package/scripts/review/review-stops-cli.ts +85 -0
  558. package/scripts/review/review-tree.ts +6 -17
  559. package/scripts/review/review-untouched-readers.ts +146 -0
  560. package/scripts/review/test-titles.ts +118 -0
  561. package/scripts/rules/agent-model.ts +67 -0
  562. package/scripts/rules/bash-triggers.ts +46 -3
  563. package/scripts/rules/decision-oracle-batch.ts +9 -1
  564. package/scripts/rules/decision-oracle.ts +2 -2
  565. package/scripts/rules/delivered-rules.ts +90 -3
  566. package/scripts/rules/destructive-command.ts +8 -1
  567. package/scripts/rules/direct-filing.ts +10 -2
  568. package/scripts/rules/direct-issue-comment.ts +117 -0
  569. package/scripts/rules/direct-pr-create.ts +69 -3
  570. package/scripts/rules/early-heartbeat.ts +2 -1
  571. package/scripts/rules/file-body.ts +7 -0
  572. package/scripts/rules/filing-cap.ts +8 -0
  573. package/scripts/rules/firing-point.ts +6 -5
  574. package/scripts/rules/git-argv.ts +72 -14
  575. package/scripts/rules/git-force.ts +12 -2
  576. package/scripts/rules/guard-remedy.ts +121 -0
  577. package/scripts/rules/implementation-cut-verdict.ts +1 -1
  578. package/scripts/rules/implementation-cut.ts +11 -3
  579. package/scripts/rules/index-guard.ts +8 -1
  580. package/scripts/rules/issue-comments.ts +76 -7
  581. package/scripts/rules/josh-git-bare.ts +7 -0
  582. package/scripts/rules/lane-background.ts +67 -25
  583. package/scripts/rules/lane-carry-conflict.ts +6 -0
  584. package/scripts/rules/lane-direct-tool.ts +74 -0
  585. package/scripts/rules/lane-interactive-ask.ts +9 -2
  586. package/scripts/rules/lane-park.ts +45 -23
  587. package/scripts/rules/lane-split-park.ts +10 -2
  588. package/scripts/rules/lane-switch-main.ts +7 -0
  589. package/scripts/rules/last-prompt.ts +50 -5
  590. package/scripts/rules/oracle-consulted.ts +10 -0
  591. package/scripts/rules/oracle-firing.ts +1 -0
  592. package/scripts/rules/oracle-list-cli.ts +7 -0
  593. package/scripts/rules/permission-guards.ts +3 -0
  594. package/scripts/rules/piped-verification.ts +4 -2
  595. package/scripts/rules/poll-loop.ts +7 -0
  596. package/scripts/rules/pr-merge.ts +123 -0
  597. package/scripts/rules/protected-files.ts +32 -5
  598. package/scripts/rules/raw-field-body.ts +6 -0
  599. package/scripts/rules/rule-body-guard.ts +8 -0
  600. package/scripts/rules/rule-list.ts +12 -28
  601. package/scripts/rules/rule-rewrite.ts +114 -0
  602. package/scripts/rules/rule-value-cache.ts +4 -9
  603. package/scripts/rules/rule-value-cli.ts +51 -32
  604. package/scripts/rules/rule-value.ts +8 -2
  605. package/scripts/rules/shell-segments.ts +50 -0
  606. package/scripts/rules/stop-decision.ts +77 -0
  607. package/scripts/rules/stop-rule-rows.ts +64 -0
  608. package/scripts/rules/stop-rules.ts +150 -51
  609. package/scripts/rules/tail-commands.ts +15 -1
  610. package/scripts/rules/test-declared-commit.ts +11 -1
  611. package/scripts/rules/third-party-write.ts +7 -0
  612. package/scripts/rules/timed-rerun.ts +69 -0
  613. package/scripts/rules/worktree-guard.ts +13 -3
  614. package/scripts/run/board/run-board-app-name.ts +23 -0
  615. package/scripts/run/board/run-board-cli.ts +65 -30
  616. package/scripts/run/board/run-board-closed.ts +8 -2
  617. package/scripts/run/board/run-board-earlier.ts +94 -0
  618. package/scripts/run/board/run-board-ending-reason.ts +67 -0
  619. package/scripts/run/board/run-board-estimate-schedule.ts +103 -0
  620. package/scripts/run/board/run-board-estimate.ts +98 -0
  621. package/scripts/run/board/run-board-fit.ts +153 -36
  622. package/scripts/run/board/run-board-fold.ts +123 -0
  623. package/scripts/run/board/run-board-fresh.ts +2 -2
  624. package/scripts/run/board/run-board-gather-live.ts +29 -0
  625. package/scripts/run/board/run-board-gather-thread.ts +189 -0
  626. package/scripts/run/board/run-board-gather-worker.ts +29 -0
  627. package/scripts/run/board/run-board-gather.ts +187 -0
  628. package/scripts/run/board/run-board-github.ts +119 -31
  629. package/scripts/run/board/run-board-header.ts +86 -21
  630. package/scripts/run/board/run-board-keys.ts +58 -0
  631. package/scripts/run/board/run-board-kind.ts +20 -6
  632. package/scripts/run/board/run-board-labels.ts +118 -71
  633. package/scripts/run/board/run-board-lane-state.ts +109 -0
  634. package/scripts/run/board/run-board-lane-time.ts +122 -0
  635. package/scripts/run/board/run-board-layout.ts +240 -61
  636. package/scripts/run/board/run-board-length.ts +52 -0
  637. package/scripts/run/board/run-board-machine.ts +8 -4
  638. package/scripts/run/board/run-board-main.ts +12 -0
  639. package/scripts/run/board/run-board-notes.ts +52 -31
  640. package/scripts/run/board/run-board-now.ts +1 -1
  641. package/scripts/run/board/run-board-operation.ts +15 -33
  642. package/scripts/run/board/run-board-phase.ts +1 -1
  643. package/scripts/run/board/run-board-plan-shared.ts +115 -0
  644. package/scripts/run/board/run-board-plan.ts +55 -3
  645. package/scripts/run/board/run-board-planning.ts +45 -0
  646. package/scripts/run/board/run-board-priority.ts +44 -0
  647. package/scripts/run/board/run-board-process-groups.ts +195 -0
  648. package/scripts/run/board/run-board-read.ts +153 -13
  649. package/scripts/run/board/run-board-reason.ts +238 -45
  650. package/scripts/run/board/run-board-released.ts +35 -0
  651. package/scripts/run/board/run-board-render-checks.ts +39 -5
  652. package/scripts/run/board/run-board-render-condition.ts +96 -0
  653. package/scripts/run/board/run-board-render-drawn.ts +67 -0
  654. package/scripts/run/board/run-board-render-foot.ts +59 -0
  655. package/scripts/run/board/run-board-render-icon.ts +35 -0
  656. package/scripts/run/board/run-board-render-lanes.ts +145 -0
  657. package/scripts/run/board/run-board-render-lead.ts +80 -0
  658. package/scripts/run/board/run-board-render-legend.ts +117 -47
  659. package/scripts/run/board/run-board-render-notes.ts +156 -29
  660. package/scripts/run/board/run-board-render-processes.ts +196 -0
  661. package/scripts/run/board/run-board-render-section.ts +119 -0
  662. package/scripts/run/board/run-board-render-slot.ts +3 -36
  663. package/scripts/run/board/run-board-render-tail.ts +115 -48
  664. package/scripts/run/board/run-board-render-time.ts +56 -0
  665. package/scripts/run/board/run-board-render-title.ts +117 -24
  666. package/scripts/run/board/run-board-render-waits.ts +125 -0
  667. package/scripts/run/board/run-board-render.ts +206 -259
  668. package/scripts/run/board/run-board-roots.ts +54 -0
  669. package/scripts/run/board/run-board-row-yield.ts +10 -4
  670. package/scripts/run/board/run-board-setup.ts +1 -12
  671. package/scripts/run/board/run-board-snapshot.ts +111 -0
  672. package/scripts/run/board/run-board-spin.ts +2 -2
  673. package/scripts/run/board/run-board-state.ts +23 -29
  674. package/scripts/run/board/run-board-status.ts +206 -79
  675. package/scripts/run/board/run-board-thanks-read.ts +2 -2
  676. package/scripts/run/board/run-board-tick.ts +123 -104
  677. package/scripts/run/board/run-board-usage-board.ts +78 -0
  678. package/scripts/run/board/run-board-usage-lanes.ts +113 -0
  679. package/scripts/run/board/run-board-usage-listing.ts +93 -0
  680. package/scripts/run/board/run-board-usage-read.ts +120 -150
  681. package/scripts/run/board/run-board-usage-rusage.ts +19 -7
  682. package/scripts/run/board/run-board-usage-text.ts +139 -51
  683. package/scripts/run/board/run-board-usage-top.ts +102 -0
  684. package/scripts/run/board/run-board-usage.ts +89 -72
  685. package/scripts/run/board/run-board-usual.ts +20 -9
  686. package/scripts/run/carry/run-carry-args.ts +4 -7
  687. package/scripts/run/carry/run-carry-conversation.ts +1 -1
  688. package/scripts/run/carry/run-carry.ts +9 -4
  689. package/scripts/run/cut/run-cut-cli.ts +3 -2
  690. package/scripts/run/cut/run-cut-handoff.ts +2 -2
  691. package/scripts/run/cut/run-cut-report.ts +16 -0
  692. package/scripts/run/detached-launch.ts +23 -4
  693. package/scripts/run/entry/run-entry-cli.ts +8 -1
  694. package/scripts/run/event/run-event-cli.ts +1 -5
  695. package/scripts/run/event/run-event-filed.ts +12 -6
  696. package/scripts/run/event/run-event-follow.ts +2 -3
  697. package/scripts/run/event/run-event-render.ts +7 -10
  698. package/scripts/run/event/run-event-scope.ts +20 -2
  699. package/scripts/run/event/run-event-stream-emit.ts +78 -11
  700. package/scripts/run/event/run-event-stream.ts +37 -7
  701. package/scripts/run/hold/run-hold-adopt.ts +65 -0
  702. package/scripts/run/hold/run-hold-cli.ts +93 -22
  703. package/scripts/run/hold/run-hold-main.ts +12 -0
  704. package/scripts/run/hold/run-hold-member.ts +37 -0
  705. package/scripts/run/hold/run-hold-session.ts +46 -0
  706. package/scripts/run/hold/run-hold.ts +7 -1
  707. package/scripts/run/hold/run-stop-notify.ts +183 -0
  708. package/scripts/run/launch-priority.ts +32 -0
  709. package/scripts/run/merge/run-merge-auth.ts +31 -0
  710. package/scripts/run/merge/run-merge-cli.ts +72 -107
  711. package/scripts/run/merge/run-merge-close.ts +74 -0
  712. package/scripts/run/merge/run-merge-collect.ts +6 -13
  713. package/scripts/run/merge/run-merge-driver.ts +71 -0
  714. package/scripts/run/merge/run-merge-main.ts +12 -0
  715. package/scripts/run/merge/run-merge-outcome.ts +23 -0
  716. package/scripts/run/merge/run-merge-restart.ts +39 -0
  717. package/scripts/run/merge/run-merge-ship.ts +20 -4
  718. package/scripts/run/merge/run-merge-signals.ts +123 -0
  719. package/scripts/run/merge/run-merge-steps.ts +128 -83
  720. package/scripts/run/merge/run-merge.ts +53 -40
  721. package/scripts/run/park/run-park-cli.ts +91 -0
  722. package/scripts/run/park/run-park.ts +88 -0
  723. package/scripts/run/park/run-stalled.ts +68 -0
  724. package/scripts/run/pause/run-pause-cli.ts +73 -0
  725. package/scripts/run/pause/run-pause.ts +251 -0
  726. package/scripts/run/progress/run-progress-cli.ts +4 -12
  727. package/scripts/run/progress/run-progress-clock.ts +1 -1
  728. package/scripts/run/progress/run-progress-config.ts +6 -14
  729. package/scripts/run/progress/run-progress-main.ts +12 -0
  730. package/scripts/run/progress/run-progress.ts +1 -4
  731. package/scripts/run/review/run-review.ts +2 -1
  732. package/scripts/run/run-ending.ts +1 -0
  733. package/scripts/run/run-invocation.ts +5 -6
  734. package/scripts/run/run-liveness-cli.ts +6 -8
  735. package/scripts/run/run-liveness.ts +61 -30
  736. package/scripts/run/run-next.ts +1 -1
  737. package/scripts/run/run-parent-cut-hook.ts +2 -2
  738. package/scripts/run/run-poll-hook.ts +157 -0
  739. package/scripts/run/run-preflight.ts +18 -3
  740. package/scripts/run/run-prep-cli.ts +1 -10
  741. package/scripts/run/run-prep-locate.ts +7 -50
  742. package/scripts/run/run-prep-main.ts +12 -0
  743. package/scripts/run/run-prep.ts +6 -0
  744. package/scripts/run/run-report-cli.ts +101 -13
  745. package/scripts/run/run-report-handoff.ts +114 -0
  746. package/scripts/run/run-step-cli.ts +22 -15
  747. package/scripts/run/run-step-section.ts +85 -0
  748. package/scripts/run/run-step.ts +1 -1
  749. package/scripts/run/run-stranded-detect.ts +13 -0
  750. package/scripts/run/run-watcher-guard-cli.ts +1 -1
  751. package/scripts/run/run-watcher-guard.ts +1 -1
  752. package/scripts/run/ship/run-ship-args.ts +121 -0
  753. package/scripts/run/ship/run-ship-body-draft.ts +110 -0
  754. package/scripts/run/ship/run-ship-cli.ts +67 -151
  755. package/scripts/run/ship/run-ship-detach.ts +27 -7
  756. package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
  757. package/scripts/run/ship/run-ship-next.ts +27 -3
  758. package/scripts/run/ship/run-ship-overlap.ts +232 -0
  759. package/scripts/run/ship/run-ship-place.ts +96 -0
  760. package/scripts/run/ship/run-ship-pre-detach-timed.ts +43 -0
  761. package/scripts/run/ship/run-ship-pre-detach.ts +102 -27
  762. package/scripts/run/ship/run-ship-preflight.ts +161 -30
  763. package/scripts/run/ship/run-ship-probe.ts +11 -3
  764. package/scripts/run/ship/run-ship-relaunch-cap.ts +70 -0
  765. package/scripts/run/ship/run-ship-removed-rows.ts +61 -0
  766. package/scripts/run/ship/run-ship-return.ts +123 -15
  767. package/scripts/run/ship/run-ship-review-steps.ts +105 -149
  768. package/scripts/run/ship/run-ship-review.ts +73 -6
  769. package/scripts/run/ship/run-ship-reviewer.ts +207 -0
  770. package/scripts/run/ship/run-ship-stage.ts +55 -6
  771. package/scripts/run/ship/run-ship-steps.ts +46 -15
  772. package/scripts/run/ship/run-ship-stop-cause.ts +135 -0
  773. package/scripts/run/ship/run-ship-stop-context.ts +206 -0
  774. package/scripts/run/ship/run-ship-stop-text.ts +11 -6
  775. package/scripts/run/ship/run-ship-sync.ts +57 -12
  776. package/scripts/run/ship/run-ship.ts +30 -2
  777. package/scripts/run/tidy/run-tidy-cli.ts +0 -4
  778. package/scripts/run/tidy/run-tidy-lanes.ts +3 -0
  779. package/scripts/run/tidy/run-tidy-main.ts +8 -0
  780. package/scripts/run/wake/run-wake-cli.ts +119 -100
  781. package/scripts/run/wake/run-wake-code.ts +83 -0
  782. package/scripts/run/wake/run-wake-driver.ts +19 -8
  783. package/scripts/run/wake/run-wake-loop.ts +34 -3
  784. package/scripts/run/wake/run-wake-main.ts +13 -0
  785. package/scripts/run/wake/run-wake-ports.ts +90 -0
  786. package/scripts/run/wake/run-wake-takeover.ts +66 -0
  787. package/scripts/run/wake/run-wake.ts +2 -1
  788. package/scripts/safe-chain/pack-hook.ts +2 -2
  789. package/scripts/safe-chain/preinstall-command.ts +2 -1
  790. package/scripts/safe-chain/project-config.ts +3 -9
  791. package/scripts/security/security-audit-main.ts +8 -0
  792. package/scripts/security/security-audit-provision-logic.ts +0 -11
  793. package/scripts/security/security-audit-provision-main.ts +12 -0
  794. package/scripts/security/security-audit-provision.ts +11 -26
  795. package/scripts/security/security-audit.ts +6 -7
  796. package/scripts/self-sync-guard/self-sync-guard-logic.ts +6 -13
  797. package/scripts/split/split-assess-cli.ts +2 -2
  798. package/scripts/split/split-assess.ts +15 -0
  799. package/scripts/split/split-measure.ts +65 -0
  800. package/scripts/sync/claude-settings-merge.ts +8 -15
  801. package/scripts/sync/directory-copy-guard.ts +4 -9
  802. package/scripts/sync/file-content.ts +78 -8
  803. package/scripts/sync/sync-ai-files.ts +3 -5
  804. package/scripts/sync/sync-configs.ts +11 -23
  805. package/scripts/sync/sync-hook-safety.ts +4 -10
  806. package/scripts/sync/sync-main.ts +11 -0
  807. package/scripts/sync/sync.ts +25 -37
  808. package/scripts/test/test-declared-changed.ts +2 -2
  809. package/scripts/test/test-declared.ts +1 -1
  810. package/scripts/test/test-e2e-guard.ts +55 -6
  811. package/scripts/test/test-e2e-stamp.ts +38 -0
  812. package/scripts/test/test-pinned-logic.ts +145 -0
  813. package/scripts/test/test-pinned-main.ts +78 -0
  814. package/scripts/test/test-pinned.ts +100 -0
  815. package/scripts/test/test-read-map.ts +264 -0
  816. package/scripts/test/test-read-recording.ts +91 -0
  817. package/scripts/test/test-read-trace.ts +148 -0
  818. package/scripts/test/test-red-main.ts +12 -0
  819. package/scripts/test/test-red.ts +12 -30
  820. package/scripts/test/test-related-main.ts +18 -0
  821. package/scripts/test/test-related-record.ts +119 -0
  822. package/scripts/test/test-related-scope.ts +229 -43
  823. package/scripts/test/test-related.ts +300 -22
  824. package/scripts/test/test-unit-guard-main.ts +15 -0
  825. package/scripts/test/test-unit-guard.ts +54 -21
  826. package/scripts/test/unit-count-file.ts +37 -0
  827. package/scripts/test/unit-run-marker.ts +162 -0
  828. package/scripts/test/unit-setup-files.ts +51 -0
  829. package/scripts/test/unit-worker-share.ts +71 -137
  830. package/scripts/test/whole-suite-files.ts +63 -0
  831. package/scripts/time-runtime/time-background.ts +20 -2
  832. package/scripts/time-runtime/time-bundles.ts +4 -3
  833. package/scripts/time-runtime/time-density-hook.ts +8 -6
  834. package/scripts/time-runtime/time-followup-stage.ts +1 -3
  835. package/scripts/time-runtime/time-format.ts +5 -28
  836. package/scripts/time-runtime/time-markers.ts +10 -1
  837. package/scripts/time-runtime/time-shell.ts +126 -14
  838. package/scripts/time-runtime/time-spans.ts +1 -0
  839. package/scripts/time-runtime/time-tool-call.ts +7 -0
  840. package/scripts/time-runtime/time-transcript-line.ts +49 -62
  841. package/scripts/uninstall/uninstall.ts +1 -1
  842. package/scripts/version/bump-version-main.ts +12 -0
  843. package/scripts/version/bump-version.ts +25 -25
  844. package/scripts/version/effective-upstream.ts +6 -12
  845. package/scripts/version/latest-corepack.ts +17 -32
  846. package/scripts/version/latest-if-required-cli.ts +93 -0
  847. package/scripts/version/latest-lane-guard-main.ts +8 -0
  848. package/scripts/version/latest-lane-guard.ts +0 -4
  849. package/scripts/version/latest-scope-cli.ts +0 -9
  850. package/scripts/version/latest-scope-main.ts +12 -0
  851. package/scripts/version/latest-update.ts +5 -5
  852. package/scripts/version/npm-registry.ts +44 -6
  853. package/scripts/version/publishable-range-check.ts +5 -16
  854. package/scripts/version/release-age.ts +1 -1
  855. package/scripts/version/release-hold.ts +1 -1
  856. package/scripts/version/release-window.ts +38 -0
  857. package/scripts/version/running-binary.ts +1 -1
  858. package/scripts/version/safe-chain-version-update.ts +3 -8
  859. package/scripts/version/version-targets.ts +6 -28
  860. package/templates/dependabot.yml +29 -0
  861. package/templates/gitignore +10 -3
  862. package/templates/pnpm-workspace.basic.yaml +1 -1
  863. package/templates/sonar-project.properties +3 -2
  864. package/templates/workflows/ci.yml +12 -4
  865. package/templates/workflows/github-release.yml +4 -0
  866. package/tsconfig.sonar.json +1 -1
  867. package/.ncurc.json +0 -3
  868. package/dist/hooks/batch-guard.js +0 -29
  869. package/dist/hooks/chunk-43ZHT22P.js +0 -3495
  870. package/dist/hooks/chunk-CDY4NFQG.js +0 -15
  871. package/dist/hooks/chunk-EUMACUK2.js +0 -2038
  872. package/dist/hooks/chunk-H5HVWYXK.js +0 -359
  873. package/dist/hooks/chunk-IIGFYXKC.js +0 -7104
  874. package/dist/hooks/chunk-IX6TTTI6.js +0 -95
  875. package/dist/hooks/chunk-J47HU5H5.js +0 -237
  876. package/dist/hooks/chunk-K4EOONYM.js +0 -45
  877. package/dist/hooks/chunk-K4LMBQC2.js +0 -68
  878. package/dist/hooks/chunk-SHGPANFB.js +0 -56
  879. package/dist/hooks/chunk-YHBZAJSV.js +0 -79
  880. package/dist/hooks/chunk-YYPI7SJZ.js +0 -131
  881. package/dist/hooks/duplicate-read-guard.js +0 -30
  882. package/dist/hooks/investigation-guard.js +0 -32
  883. package/scripts/backlog/backlog-stalled-cli.ts +0 -30
  884. package/scripts/cost-runtime/cost-format.ts +0 -29
  885. package/scripts/init/basic-path-migration.ts +0 -24
  886. package/scripts/issue/issue-backlinks-cli.ts +0 -93
  887. package/scripts/josh/josh-commands-guard.ts +0 -38
  888. package/scripts/lint/cross-file-recheck.ts +0 -155
  889. package/scripts/registry-migration/migrate-logic.ts +0 -237
  890. package/scripts/registry-migration/migrate.ts +0 -292
  891. package/scripts/registry-migration/user-npmrc.ts +0 -15
  892. package/scripts/rules/rule-guard.ts +0 -23
  893. package/scripts/rules/rule-registry-rows.ts +0 -282
  894. package/scripts/rules/rule-registry.ts +0 -109
  895. package/scripts/run/run-stranded-cli.ts +0 -27
@@ -0,0 +1,158 @@
1
+ import { lane_reap, type LaneProcesses, type ReapProbes } from './lane-reap'
2
+ import { lane_registry } from './lane-registry'
3
+ import { lane_residents } from './lane-residents'
4
+
5
+ // Suspending a lane child in place, and letting it carry on from the same point.
6
+ //
7
+ // **Nothing but the processes is touched here.** The work tree, the branch and the issue stay as they
8
+ // are, so a paused lane is resumed rather than rebuilt — the one way to halt a lane that `lane:close`
9
+ // (which deletes it) and `lane:withdraw` (which takes its issue out of the run) are not. The command
10
+ // (`lane-pause-cli.ts`) records the change in the lane's state and on the run's event stream.
11
+ //
12
+ // **The tree is `lane_reap`'s** — the same match, the same descendants, the caller's own ancestry
13
+ // spared — so a pause and a reap never disagree on which processes are the lane's.
14
+ //
15
+ // **A pause reads the tree again until no new process turns up.** A parent signalled after it had
16
+ // already forked leaves a child that was not in the first read running; each round stops what the
17
+ // last one did not see, up to `PAUSE_ROUNDS`.
18
+ //
19
+ // **A process detached from the tree is stopped and continued with it** (joshuafolkken/kit#4300): the
20
+ // edit hook's `eslint_d`, a detached `ship`, found by its working directory or mark as `lane:close`
21
+ // finds it (`lane-residents.ts`), so a resume reaches every process the pause stopped. A pause with no
22
+ // child in the tree stops none of them: it pauses no lane and records nothing, so nothing would resume
23
+ // them. A read of them that failed is `is_unread`, never "none", so a caller can say they were missed.
24
+
25
+ const STOP_SIGNAL = 'SIGSTOP'
26
+ const CONTINUE_SIGNAL = 'SIGCONT'
27
+ const PAUSE_ROUNDS = 5
28
+
29
+ type LaneSignal = typeof STOP_SIGNAL | typeof CONTINUE_SIGNAL
30
+
31
+ interface PauseProbes extends ReapProbes {
32
+ signal: (pid: number, name: LaneSignal) => boolean
33
+ // What runs from the lane outside the tree (`lane-residents.ts`); `undefined` when unreadable.
34
+ residents: (lane: LaneProcesses) => ReadonlyArray<number> | undefined
35
+ }
36
+
37
+ // What a pause or a resume reached: the lane's processes signalled, and those of them in the child's
38
+ // tree. Only `child` says the lane is running — a resident outlives the child it served (`eslint_d`
39
+ // idles on), so signalling it alone pauses no lane. `is_unread`: the residents could not be read, so
40
+ // any of them may have been missed.
41
+ interface LaneSignalled {
42
+ signalled: Array<number>
43
+ child: Array<number>
44
+ is_unread: boolean
45
+ }
46
+
47
+ // One read of the lane: the child's tree, and the tree with what runs from the lane outside it.
48
+ interface LaneRead {
49
+ tree: Array<number>
50
+ all: Array<number>
51
+ is_unread: boolean
52
+ }
53
+
54
+ function signal(pid: number, name: LaneSignal): boolean {
55
+ try {
56
+ process.kill(pid, name)
57
+
58
+ return true
59
+ } catch {
60
+ return false
61
+ }
62
+ }
63
+
64
+ const SYSTEM_PROBES: PauseProbes = {
65
+ ...lane_reap.SYSTEM_PROBES,
66
+ signal,
67
+ residents: (lane) => lane_residents.residents(lane),
68
+ }
69
+
70
+ // The lane child's tree and what runs from the lane outside it, each once. The residents are read only
71
+ // beside a child, unless `is_resident_read_forced`.
72
+ function lane_processes(
73
+ lane: LaneProcesses,
74
+ probes: PauseProbes,
75
+ is_resident_read_forced: boolean,
76
+ ): LaneRead {
77
+ const tree = lane_reap.lane_tree(lane.issue, probes)
78
+ if (!is_resident_read_forced && tree.length === 0) return { tree, all: tree, is_unread: false }
79
+ const residents = probes.residents(lane)
80
+
81
+ return {
82
+ tree,
83
+ all: [...new Set([...tree, ...(residents ?? [])])],
84
+ is_unread: residents === undefined,
85
+ }
86
+ }
87
+
88
+ function signalled_of(
89
+ signalled: Array<number>,
90
+ tree: ReadonlySet<number>,
91
+ is_unread: boolean,
92
+ ): LaneSignalled {
93
+ return { signalled, child: signalled.filter((pid) => tree.has(pid)), is_unread }
94
+ }
95
+
96
+ // Every pid read is `seen`, so a process the signal could not reach is not retried each round; only the
97
+ // ones the signal reached are `stopped`. Every tree pid read is `tree`.
98
+ interface PauseProgress {
99
+ seen: Set<number>
100
+ tree: Set<number>
101
+ stopped: Array<number>
102
+ is_unread: boolean
103
+ }
104
+
105
+ function stop_unseen(lane: LaneProcesses, progress: PauseProgress, probes: PauseProbes): number {
106
+ const read = lane_processes(lane, probes, progress.tree.size > 0)
107
+ const unseen = read.all.filter((pid) => !progress.seen.has(pid))
108
+
109
+ for (const pid of read.tree) progress.tree.add(pid)
110
+ progress.is_unread ||= read.is_unread
111
+
112
+ for (const pid of unseen) {
113
+ progress.seen.add(pid)
114
+ if (probes.signal(pid, STOP_SIGNAL)) progress.stopped.push(pid)
115
+ }
116
+
117
+ return unseen.length
118
+ }
119
+
120
+ /** SIGSTOP every process of the lane; returns the pids stopped. */
121
+ function pause_lane(lane: LaneProcesses, probes: PauseProbes = SYSTEM_PROBES): LaneSignalled {
122
+ const progress: PauseProgress = {
123
+ seen: new Set(),
124
+ tree: new Set(),
125
+ stopped: [],
126
+ is_unread: false,
127
+ }
128
+
129
+ for (let round = 0; round < PAUSE_ROUNDS; round += 1) {
130
+ if (stop_unseen(lane, progress, probes) === 0) break
131
+ }
132
+
133
+ return signalled_of(progress.stopped, progress.tree, progress.is_unread)
134
+ }
135
+
136
+ /** SIGCONT every process of the lane; returns the pids continued. */
137
+ function resume_lane(lane: LaneProcesses, probes: PauseProbes = SYSTEM_PROBES): LaneSignalled {
138
+ const read = lane_processes(lane, probes, true)
139
+ const continued = read.all.filter((pid) => probes.signal(pid, CONTINUE_SIGNAL))
140
+
141
+ return signalled_of(continued, new Set(read.tree), read.is_unread)
142
+ }
143
+
144
+ // Only what a pause reads: a lane is matched by its issue and its directory, nothing else.
145
+ function processes_of(lane: LaneProcesses): LaneProcesses {
146
+ return { issue: lane.issue, directory: lane.directory }
147
+ }
148
+
149
+ async function open_lanes(): Promise<Array<LaneProcesses>> {
150
+ const lanes = await lane_registry.list_lanes()
151
+
152
+ return lanes.map((lane) => processes_of(lane))
153
+ }
154
+
155
+ const lane_pause = { PAUSE_ROUNDS, open_lanes, pause_lane, resume_lane }
156
+
157
+ export { lane_pause }
158
+ export type { LaneSignal, LaneSignalled, PauseProbes }
@@ -1,5 +1,6 @@
1
1
  import { git_gh_issue_write } from '#scripts/gh/git-gh-issue-write'
2
2
  import { git_stash } from '#scripts/git/stash/git-stash'
3
+ import { error_text } from '#scripts/lib/error-message'
3
4
 
4
5
  // Keeping a lane's uncommitted work before something discards or restarts it — `run:merge` closing a
5
6
  // lane, `lane:restart` handing it to a fresh session. The stash stack outlives the tree, so the push is
@@ -30,6 +31,32 @@ async function announce(issue: string, message: string, cause: string): Promise<
30
31
  await git_gh_issue_write.issue_try_comment(issue, preserved_comment(message, cause))
31
32
  }
32
33
 
34
+ // The tree's work kept before a stopped child's lane is reused or closed: `saved` with the stash, or
35
+ // none for a clean tree, and `unsaved` with the reason when the tree could not be read or pushed — the
36
+ // caller then leaves the tree as it is rather than handing it on or deleting it.
37
+ type KeptWork =
38
+ | { kind: 'saved'; stash: string | undefined }
39
+ | { kind: 'unsaved'; directory: string; reason: string }
40
+
41
+ async function stash_of(
42
+ issue: string,
43
+ directory: string,
44
+ occasion: string,
45
+ ): Promise<string | undefined> {
46
+ if (!(await git_stash.has_changes(directory))) return undefined
47
+
48
+ return await push_work(issue, directory, occasion)
49
+ }
50
+
51
+ /** Stash the tree's uncommitted work, if any, answering `unsaved` rather than throwing. */
52
+ async function keep_work(issue: string, directory: string, occasion: string): Promise<KeptWork> {
53
+ try {
54
+ return { kind: 'saved', stash: await stash_of(issue, directory, occasion) }
55
+ } catch (error) {
56
+ return { kind: 'unsaved', directory, reason: error_text.message_of(error) }
57
+ }
58
+ }
59
+
33
60
  /** `push_work`, then `announce` — for a caller with no reason to separate the two. */
34
61
  async function stash_work(
35
62
  issue: string,
@@ -44,6 +71,7 @@ async function stash_work(
44
71
  return message
45
72
  }
46
73
 
47
- const lane_preserve = { announce, push_work, stash_work }
74
+ const lane_preserve = { announce, keep_work, stash_work }
48
75
 
76
+ export type { KeptWork }
49
77
  export { lane_preserve }
@@ -0,0 +1,166 @@
1
+ import { process_identity } from '#scripts/josh/process-identity'
2
+ import { PROBE_TIMEOUT_MS } from '#scripts/lib/timeouts'
3
+ import { execa } from 'execa'
4
+ import { lane_reap, type TreeProbes } from './lane-reap'
5
+ import { process_tools } from './process-tools'
6
+
7
+ // Every process on the machine at one instant, read by one asynchronous `ps`, answering the probes a
8
+ // lane's tree is read through (joshuafolkken/kit#4241), and the listing `run:board`'s
9
+ // usage columns are read from (joshuafolkken/kit#4246).
10
+ //
11
+ // **Why one snapshot.** `lane_reap`'s probes start one synchronous `ps` / `pgrep` per ancestor and per
12
+ // descendant, so a reader that asks about every lane each few seconds — `run:board`, the backlogrun
13
+ // drive — blocked its event loop for over a second with seven lanes under load. The snapshot costs one
14
+ // spawn whatever the lane and process counts, and never blocks. `run:board` takes one per refresh and
15
+ // hands it to both the lane count and the usage columns (`shared`), so the two read the same instant.
16
+ //
17
+ // **The walk is not re-implemented.** `lane_reap` still walks the tree; the
18
+ // snapshot only answers the questions it asks. `matching` reads the full command line the way
19
+ // `pgrep -f` does, and `-ww` keeps `ps` from cutting it at a terminal width. The command is the full
20
+ // line rather than `comm`: `ps` cuts any column but the last, so the two cannot share one listing.
21
+ //
22
+ // **The start time is `process_identity`'s own reading.** A detached ship's record names its process by
23
+ // start time (`run-ship-detach.ts`), and the `lstart` column under `process_identity`'s environment
24
+ // prints it exactly as that module's own `ps` does, so a ship is told alive from these rows without
25
+ // starting another `ps` (joshuafolkken/kit#4245).
26
+
27
+ const COLUMNS = ['pid=', 'ppid=', 'time=', 'rss=', 'stat=', process_identity.START_TIME_FORMAT]
28
+ const PS_ARGUMENTS = ['-A', '-ww', '-o', [...COLUMNS, 'command='].join(',')]
29
+ // `ps` labels nothing locale-dependent here, and the C locale keeps its columns stable; the time zone
30
+ // fixes how the start time prints.
31
+ const PS_ENVIRONMENT = process_identity.PROBE_ENVIRONMENT
32
+ const FIELD_SEPARATOR = /\s+/u
33
+ // `lstart` prints `Tue Sep 8 08:39:04 2026`: five fields, the day of the month padded to two places.
34
+ const START_FIELDS = 5
35
+ const DAY_FIELD = 2
36
+ const DAY_WIDTH = 2
37
+
38
+ interface ProcessRow {
39
+ pid: number
40
+ parent: number
41
+ // `ps`'s cumulative CPU time as printed, `[DD-][HH:]MM:SS[.ss]`.
42
+ time: string
43
+ rss_kb: number
44
+ stat: string
45
+ // The start time as `process_identity`'s `ps` prints it.
46
+ start: string
47
+ command: string
48
+ }
49
+
50
+ // One snapshot's rows.
51
+ type ProcessTable = ReadonlyArray<ProcessRow>
52
+ // A snapshot read on demand, `undefined` where `ps` did not answer.
53
+ type TableRead = () => Promise<ProcessTable | undefined>
54
+
55
+ function is_row(row: ProcessRow): boolean {
56
+ const { pid, parent, rss_kb, command } = row
57
+
58
+ return Number.isSafeInteger(pid + parent) && Number.isFinite(rss_kb) && command !== ''
59
+ }
60
+
61
+ // The split fields put back with the day's padding the split dropped.
62
+ function start_of(fields: ReadonlyArray<string>): string {
63
+ return fields
64
+ .map((field, index) => (index === DAY_FIELD ? field.padStart(DAY_WIDTH) : field))
65
+ .join(' ')
66
+ }
67
+
68
+ // The command's own runs of white space read as one space, which no lane pattern tells apart.
69
+ function row_of(line: string): ProcessRow | undefined {
70
+ const [pid, parent, time = '', rss, stat = '', ...rest] = line.trim().split(FIELD_SEPARATOR)
71
+ const numbers = { pid: Number(pid), parent: Number(parent), rss_kb: Number(rss) }
72
+ const start = start_of(rest.slice(0, START_FIELDS))
73
+ const row = { ...numbers, time, stat, start, command: rest.slice(START_FIELDS).join(' ') }
74
+
75
+ return is_row(row) ? row : undefined
76
+ }
77
+
78
+ /** Each `ps` line as a row; a line that does not read as one is left out. */
79
+ function parse(printed: string): Array<ProcessRow> {
80
+ return printed
81
+ .split('\n')
82
+ .map((line) => row_of(line))
83
+ .filter((row) => row !== undefined)
84
+ }
85
+
86
+ function matching_in(rows: ProcessTable, pattern: string): Array<number> {
87
+ const expression = new RegExp(pattern, 'u')
88
+
89
+ return rows.filter((row) => expression.test(row.command)).map((row) => row.pid)
90
+ }
91
+
92
+ // Each parent's children, indexed once so a walk does not rescan every row per process.
93
+ function children_index(rows: ProcessTable): Map<number, Array<number>> {
94
+ const children = new Map<number, Array<number>>()
95
+
96
+ for (const { pid, parent } of rows) {
97
+ const siblings = children.get(parent) ?? []
98
+
99
+ siblings.push(pid)
100
+ children.set(parent, siblings)
101
+ }
102
+
103
+ return children
104
+ }
105
+
106
+ /** The probes a lane's tree is read through, answered from `rows` alone. */
107
+ function probes_of(rows: ProcessTable): TreeProbes {
108
+ const by_pid = new Map(rows.map((row) => [row.pid, row]))
109
+ const children = children_index(rows)
110
+
111
+ return {
112
+ matching: (pattern) => matching_in(rows, pattern),
113
+ children_of: (pid) => children.get(pid) ?? [],
114
+ parent_of: (pid) => by_pid.get(pid)?.parent,
115
+ }
116
+ }
117
+
118
+ /** `process_identity.read_start` with its `ps` answered from `rows`: `/proc` first, as there. */
119
+ function start_reader(rows: ProcessTable): (pid: number) => string | undefined {
120
+ const starts = new Map(rows.map((row) => [row.pid, row.start]))
121
+ const probes = {
122
+ ...process_identity.START_PROBES,
123
+ read_ps_start: (pid: number) => starts.get(pid),
124
+ }
125
+
126
+ return (pid) => process_identity.read_start(pid, probes)
127
+ }
128
+
129
+ /** The snapshot, `undefined` where `ps` did not answer; a missing `ps` is refused by name. */
130
+ async function read_table(): Promise<ProcessTable | undefined> {
131
+ try {
132
+ const { stdout } = await execa(lane_reap.PS_COMMAND, PS_ARGUMENTS, {
133
+ env: PS_ENVIRONMENT,
134
+ timeout: PROBE_TIMEOUT_MS,
135
+ })
136
+
137
+ return parse(stdout)
138
+ } catch (error) {
139
+ process_tools.throw_if_missing(lane_reap.PS_COMMAND, error)
140
+
141
+ return undefined
142
+ }
143
+ }
144
+
145
+ /** `read`, run on the first call alone; every later call answers that same snapshot. */
146
+ function shared(read: TableRead): TableRead {
147
+ const taken: { table?: ReturnType<TableRead> } = {}
148
+
149
+ return async function table() {
150
+ taken.table ??= read()
151
+
152
+ return await taken.table
153
+ }
154
+ }
155
+
156
+ const lane_process_table = {
157
+ PS_ARGUMENTS,
158
+ parse,
159
+ probes_of,
160
+ read_table,
161
+ shared,
162
+ start_reader,
163
+ }
164
+
165
+ export { lane_process_table }
166
+ export type { ProcessRow, ProcessTable, TableRead }
@@ -0,0 +1,124 @@
1
+ import { userInfo } from 'node:os'
2
+ import { lane_reap } from './lane-reap'
3
+ import { lane_residents, type ResidentLane } from './lane-residents'
4
+
5
+ // What a close does about the lane's processes once the SIGTERM went out (joshuafolkken/kit#4300).
6
+ //
7
+ // **A SIGTERM is a request, so the close looks again.** After a grace window the lane's directory is
8
+ // read again; whatever is still there gets a SIGKILL, and after a short wait the directory is read a
9
+ // last time. What survives that is reported, each with why it could — another account owns it, or it
10
+ // is stuck in the kernel — so `lane:close` answers `incomplete` and `run:board` can say what is wrong
11
+ // rather than only that something is left.
12
+
13
+ // Long enough for a node process to run its exit handlers.
14
+ const GRACE_MS = 3000
15
+ // A SIGKILL is not handled, so what still answers after this is not going to go.
16
+ const KILL_WAIT_MS = 1000
17
+ const KILL_SIGNAL = 'SIGKILL'
18
+ const STATE_FORMAT = ['-o', 'user=,stat=', '-p']
19
+ const FIELD_SEPARATOR = /\s+/u
20
+ const UNREADABLE_TEXT = "the lane's processes (lsof or ps failed)"
21
+
22
+ interface SettleProbes {
23
+ // `undefined` where the lane's processes could not be read (`lane_residents.residents`).
24
+ residents: (lane: ResidentLane) => Array<number> | undefined
25
+ kill: (pid: number) => boolean
26
+ wait: (milliseconds: number) => Promise<void>
27
+ // Why a process outlived the SIGKILL.
28
+ reason_of: (pid: number) => string
29
+ }
30
+
31
+ interface Survivor {
32
+ pid: number
33
+ reason: string
34
+ }
35
+
36
+ function kill(pid: number): boolean {
37
+ try {
38
+ process.kill(pid, KILL_SIGNAL)
39
+
40
+ return true
41
+ } catch {
42
+ return false
43
+ }
44
+ }
45
+
46
+ async function wait(milliseconds: number): Promise<void> {
47
+ await new Promise((resolve) => setTimeout(resolve, milliseconds))
48
+ }
49
+
50
+ // Another account's process is the usual survivor — a SIGKILL from this one is refused; otherwise
51
+ // `ps`'s state says it, `U` for an uninterruptible wait.
52
+ function reason_from(user: string, state: string): string {
53
+ if (user !== userInfo().username) return `owned by ${user}`
54
+
55
+ return `state ${state}`
56
+ }
57
+
58
+ function reason_of(pid: number): string {
59
+ const printed = lane_reap.run_probe(lane_reap.PS_COMMAND, [...STATE_FORMAT, String(pid)])
60
+ const [user = '', state = ''] = printed.trim().split(FIELD_SEPARATOR)
61
+
62
+ return user.length === 0 ? 'unreadable' : reason_from(user, state)
63
+ }
64
+
65
+ const SYSTEM_PROBES: SettleProbes = {
66
+ residents: (lane) => lane_residents.residents(lane),
67
+ kill,
68
+ wait,
69
+ reason_of,
70
+ }
71
+
72
+ // A reading that failed is not an empty one.
73
+ function is_empty(reading: ReadonlyArray<number> | undefined): boolean {
74
+ return reading?.length === 0
75
+ }
76
+
77
+ async function kill_all(
78
+ lingering: ReadonlyArray<number> | undefined,
79
+ probes: SettleProbes,
80
+ ): Promise<void> {
81
+ const targets = lingering ?? []
82
+
83
+ for (const pid of targets) probes.kill(pid)
84
+
85
+ await probes.wait(KILL_WAIT_MS)
86
+ }
87
+
88
+ function survivors(lane: ResidentLane, probes: SettleProbes): Array<Survivor> | undefined {
89
+ return probes.residents(lane)?.map((pid) => ({ pid, reason: probes.reason_of(pid) }))
90
+ }
91
+
92
+ /**
93
+ * Wait out the SIGTERM a reap sent, SIGKILL what is still in the lane's directory, and answer what
94
+ * outlived even that — the empty list is a lane with no process left, `undefined` a last reading that
95
+ * failed. A failed reading is never read as none: it is read again, and nothing is killed on it.
96
+ */
97
+ async function settle(
98
+ lane: ResidentLane,
99
+ probes: SettleProbes = SYSTEM_PROBES,
100
+ ): Promise<Array<Survivor> | undefined> {
101
+ if (is_empty(probes.residents(lane))) return []
102
+
103
+ await probes.wait(GRACE_MS)
104
+
105
+ const lingering = probes.residents(lane)
106
+
107
+ if (is_empty(lingering)) return []
108
+
109
+ await kill_all(lingering, probes)
110
+
111
+ return survivors(lane, probes)
112
+ }
113
+
114
+ /** How a close's `left_behind` names what `settle` answered; a failed reading is named as such. */
115
+ function survivor_texts(settled: ReadonlyArray<Survivor> | undefined): Array<string> {
116
+ if (settled === undefined) return [UNREADABLE_TEXT]
117
+
118
+ return settled.map((survivor) => `process ${String(survivor.pid)} (${survivor.reason})`)
119
+ }
120
+
121
+ const lane_reap_settle = { GRACE_MS, KILL_WAIT_MS, reason_from, settle, survivor_texts }
122
+
123
+ export type { SettleProbes, Survivor }
124
+ export { lane_reap_settle }
@@ -18,6 +18,9 @@ import { process_tools } from './process-tools'
18
18
  //
19
19
  // **The caller's own ancestry is never touched.** A `lane:close` issued from inside the lane it
20
20
  // closes would otherwise end the very session running it, before it could report.
21
+ //
22
+ // **What runs from the lane outside the tree is `lane-residents.ts`'s** (joshuafolkken/kit#4300): the
23
+ // edit hook's `eslint_d`, a `script` wrapper re-parented to pid 1, found by working directory or mark.
21
24
 
22
25
  const PGREP_COMMAND = 'pgrep'
23
26
  const MATCH_FULL_COMMAND_LINE = '-f'
@@ -26,13 +29,24 @@ const CHILDREN_OF_FLAG = '-P'
26
29
  const PS_COMMAND = '/bin/ps'
27
30
  const PARENT_FORMAT = ['-o', 'ppid=', '-p']
28
31
  const TERMINATE_SIGNAL = 'SIGTERM'
32
+ const CONTINUE_SIGNAL = 'SIGCONT'
29
33
  // `0` addresses the caller's own process group and `1` is init — neither is ever a lane child.
30
34
  const LOWEST_CHILD_PID = 2
31
35
 
32
- interface ReapProbes {
36
+ // The lane a reap or a pause acts on: the child by its issue, the rest by its directory.
37
+ interface LaneProcesses {
38
+ issue: string
39
+ directory: string
40
+ }
41
+
42
+ // What collecting a lane's process tree reads — shared with `lane:pause` (`lane-pause.ts`).
43
+ interface TreeProbes {
33
44
  matching: (pattern: string) => Array<number>
34
45
  children_of: (pid: number) => Array<number>
35
46
  parent_of: (pid: number) => number | undefined
47
+ }
48
+
49
+ interface ReapProbes extends TreeProbes {
36
50
  terminate: (pid: number) => boolean
37
51
  }
38
52
 
@@ -64,9 +78,9 @@ function parent_of(pid: number): number | undefined {
64
78
  return parse_pids(run_probe(PS_COMMAND, [...PARENT_FORMAT, String(pid)]))[0]
65
79
  }
66
80
 
67
- function terminate(pid: number): boolean {
81
+ function send(pid: number, name: NodeJS.Signals): boolean {
68
82
  try {
69
- process.kill(pid, TERMINATE_SIGNAL)
83
+ process.kill(pid, name)
70
84
 
71
85
  return true
72
86
  } catch {
@@ -74,6 +88,16 @@ function terminate(pid: number): boolean {
74
88
  }
75
89
  }
76
90
 
91
+ // A stopped process (`lane:pause`) holds a SIGTERM it handles pending until it is continued, so the
92
+ // terminate is followed by a SIGCONT; a running process ignores it.
93
+ function terminate(pid: number): boolean {
94
+ if (!send(pid, TERMINATE_SIGNAL)) return false
95
+
96
+ send(pid, CONTINUE_SIGNAL)
97
+
98
+ return true
99
+ }
100
+
77
101
  const SYSTEM_PROBES: ReapProbes = {
78
102
  matching: (pattern) => parse_pids(run_probe(PGREP_COMMAND, [MATCH_FULL_COMMAND_LINE, pattern])),
79
103
  children_of: (pid) => parse_pids(run_probe(PGREP_COMMAND, [CHILDREN_OF_FLAG, String(pid)])),
@@ -81,7 +105,7 @@ const SYSTEM_PROBES: ReapProbes = {
81
105
  terminate,
82
106
  }
83
107
 
84
- function ancestry_of(pid: number, probes: ReapProbes): Set<number> {
108
+ function ancestry_of(pid: number, probes: TreeProbes): Set<number> {
85
109
  const ancestry = new Set<number>([pid])
86
110
  let current = probes.parent_of(pid)
87
111
 
@@ -95,11 +119,11 @@ function ancestry_of(pid: number, probes: ReapProbes): Set<number> {
95
119
 
96
120
  // This process and every process above it. The Stop hook reads it to tell whether the session that
97
121
  // declared a carry record's `--owner "$PPID"` is the one it runs under.
98
- function own_ancestry(probes: ReapProbes = SYSTEM_PROBES): Set<number> {
122
+ function own_ancestry(probes: TreeProbes = SYSTEM_PROBES): Set<number> {
99
123
  return ancestry_of(process.pid, probes)
100
124
  }
101
125
 
102
- function tree_of(roots: ReadonlyArray<number>, probes: ReapProbes): Array<number> {
126
+ function tree_of(roots: ReadonlyArray<number>, probes: TreeProbes): Array<number> {
103
127
  const tree: Array<number> = []
104
128
  const pending = [...roots]
105
129
  let next = pending.shift()
@@ -116,35 +140,46 @@ function tree_of(roots: ReadonlyArray<number>, probes: ReapProbes): Array<number
116
140
  return tree
117
141
  }
118
142
 
119
- function roots_of(issue: string, own: Set<number>, probes: ReapProbes): Array<number> {
143
+ function roots_of(issue: string, own: Set<number>, probes: TreeProbes): Array<number> {
120
144
  const pattern = lane_child_invocation.process_pattern(issue)
121
145
 
122
146
  return probes.matching(pattern).filter((pid) => !own.has(pid))
123
147
  }
124
148
 
125
149
  /**
126
- * Terminate every process of the lane child for `issue` and everything under it, sparing the caller's
127
- * own ancestry. Returns the pids that were signalled — the empty list is the healthy case, a child
128
- * that had already ended by itself.
150
+ * Every process of the lane child for `issue` and everything under it, collected before anything is
151
+ * signalled, the caller's own ancestry left out.
129
152
  */
130
- function reap_child(issue: string, probes: ReapProbes = SYSTEM_PROBES): Array<number> {
153
+ function lane_tree(issue: string, probes: TreeProbes = SYSTEM_PROBES): Array<number> {
131
154
  const own = own_ancestry(probes)
132
- const doomed = tree_of(roots_of(issue, own, probes), probes).filter((pid) => !own.has(pid))
133
155
 
134
- return doomed.filter((pid) => probes.terminate(pid))
156
+ return tree_of(roots_of(issue, own, probes), probes).filter((pid) => !own.has(pid))
157
+ }
158
+
159
+ /**
160
+ * Terminate every process of the lane child for `lane.issue` and everything under it, sparing the
161
+ * caller's own ancestry. Returns the pids that were signalled — the empty list is the healthy case, a
162
+ * child that had already ended by itself.
163
+ */
164
+ function reap_child(lane: LaneProcesses, probes: ReapProbes = SYSTEM_PROBES): Array<number> {
165
+ return lane_tree(lane.issue, probes).filter((pid) => probes.terminate(pid))
135
166
  }
136
167
 
137
168
  /** Whether a lane child for `issue` is running, by the same match `reap_child` would end. */
138
- function is_child_running(issue: string, probes: ReapProbes = SYSTEM_PROBES): boolean {
169
+ function is_child_running(issue: string, probes: TreeProbes = SYSTEM_PROBES): boolean {
139
170
  return roots_of(issue, own_ancestry(probes), probes).length > 0
140
171
  }
141
172
 
142
173
  const lane_reap = {
143
174
  is_child_running,
175
+ lane_tree,
144
176
  own_ancestry,
145
177
  parse_pids,
178
+ PS_COMMAND,
146
179
  reap_child,
180
+ run_probe,
181
+ SYSTEM_PROBES,
147
182
  }
148
183
 
149
- export type { ReapProbes }
184
+ export type { LaneProcesses, ReapProbes, TreeProbes }
150
185
  export { lane_reap }