@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
@@ -1,5 +1,6 @@
1
1
  import { git_gh_command } from '#scripts/gh/git-gh-command'
2
2
  import type { IssueReadFailure } from '#scripts/gh/git-gh-issue-read'
3
+ import { issue_sample_gate } from '#scripts/issue/issue-sample-gate'
3
4
  import { epic_cross_repo } from './epic-cross-repo'
4
5
  import type { EpicChild, IssueReference } from './epic-graph'
5
6
  import { epic_issue, type EpicIssue } from './epic-issue'
@@ -21,6 +22,7 @@ function to_child(parsed: EpicIssue, repo: string): EpicChild {
21
22
  state: epic_issue.normalize_state(parsed.state),
22
23
  labels: epic_issue.label_names(parsed),
23
24
  blocked_by: epic_issue.blocker_references_of(parsed, repo),
25
+ body: parsed.body,
24
26
  }
25
27
  }
26
28
 
@@ -132,6 +134,8 @@ async function fetch_child_read(
132
134
 
133
135
  const parsed = epic_issue.parse_epic_issue(read.json)
134
136
 
137
+ await issue_sample_gate.prime([parsed?.body])
138
+
135
139
  return { child: parsed === undefined ? undefined : to_child(parsed, repo), is_unreachable: false }
136
140
  }
137
141
 
@@ -29,6 +29,8 @@ interface EpicChild {
29
29
  state: 'OPEN' | 'CLOSED'
30
30
  labels: ReadonlyArray<string>
31
31
  blocked_by: ReadonlyArray<IssueReference>
32
+ // Read only to hold a child until its declared start time; absent on rows built without a read.
33
+ body?: string | undefined
32
34
  }
33
35
 
34
36
  // What is wrong with the graph. Both stop the run — neither is something to pick a winner for.
@@ -2,6 +2,7 @@ import { git_gh_issue_rest } from '#scripts/gh/git-gh-issue-rest'
2
2
  import { blocked_by_schema } from '#scripts/git/git-schemas'
3
3
  import { parse_json_object_or_undefined } from '#scripts/git/parse-json-array'
4
4
  import { z } from 'zod'
5
+ import { REPOSITORY_SEGMENT_SOURCE } from './epic-parse'
5
6
  import type { IssueReference } from './epic-reference'
6
7
 
7
8
  // The shapes one issue is read as, and the argument every epic command takes.
@@ -116,7 +117,10 @@ interface EpicReference {
116
117
  number: number
117
118
  }
118
119
 
119
- const QUALIFIED_REFERENCE = /^([\w.-]+\/[\w.-]+)#(\d+)$/u
120
+ const QUALIFIED_REFERENCE = new RegExp(
121
+ String.raw`^(${REPOSITORY_SEGMENT_SOURCE}\/${REPOSITORY_SEGMENT_SOURCE})#(\d+)$`,
122
+ 'u',
123
+ )
120
124
  const QUALIFIED_REPO_GROUP = 1
121
125
  const QUALIFIED_NUMBER_GROUP = 2
122
126
 
@@ -1,6 +1,7 @@
1
1
  import { git_gh_api_path } from '#scripts/gh/git-gh-api-path'
2
2
  import { git_gh_exec } from '#scripts/gh/git-gh-exec'
3
3
  import { IN_PROGRESS_LABEL } from '#scripts/issue/issue-labels'
4
+ import { MS_PER_MINUTE } from '#scripts/lib/timeouts'
4
5
 
5
6
  // How long each lane holder has carried `in-progress`. The stale-label rule
6
7
  // in `backlogrun-progress.md` is applied by age, and until this read the age was a hand-written
@@ -12,7 +13,6 @@ import { IN_PROGRESS_LABEL } from '#scripts/issue/issue-labels'
12
13
 
13
14
  // Matches the `Stale \`in-progress\`` row of the table in `backlogrun-progress.md`.
14
15
  const STALE_MINUTES = 90
15
- const MS_PER_MINUTE = 60_000
16
16
  const TIMELINE_PAGE = 100
17
17
 
18
18
  const LABELED_FILTER = `.[] | select(.event == "labeled" and (.label.name | ascii_downcase) == "${IN_PROGRESS_LABEL}") | .created_at`
@@ -1,4 +1,5 @@
1
1
  import { lane_capacity } from '#scripts/lane/lane-capacity'
2
+ import { lane_snapshot_trace } from '#scripts/lane/lane-snapshot-trace'
2
3
  import { epic_busy, type BusyRead } from './epic-busy'
3
4
  import {
4
5
  epic_candidate_confirm,
@@ -39,11 +40,13 @@ interface RepoPool {
39
40
 
40
41
  // What is being asked of one repository. `is_all_lanes` is the caller's appetite rather than the
41
42
  // repository's capacity: `epic:next --repo` prints a single token unless `--lanes` was passed, so a
42
- // caller written against the one-child contract keeps getting exactly one child.
43
+ // caller written against the one-child contract keeps getting exactly one child. `is_this_checkout`
44
+ // says whether `repo` is the repository this command runs in, whose ship records are the ones read.
43
45
  interface LaneRequest {
44
46
  repo: string
45
47
  limit: number
46
48
  is_all_lanes: boolean
49
+ is_this_checkout: boolean
47
50
  }
48
51
 
49
52
  // The answer for one repository: the children to start, the verdict standing in their place when
@@ -62,8 +65,27 @@ function is_held(read: BusyRead): boolean {
62
65
  return read.kind === 'unreadable' || read.kind === 'truncated'
63
66
  }
64
67
 
65
- function free_lanes(read: BusyRead, limit: number): number {
66
- return is_held(read) ? NO_LANES : lane_capacity.free_lanes(limit, epic_busy.occupied_lanes(read))
68
+ function free_lanes(read: BusyRead, limit: number, merge_waiting: number): number {
69
+ if (is_held(read)) return NO_LANES
70
+
71
+ const holders = epic_busy.occupied_lanes(read)
72
+
73
+ // A merge-waiting holder frees its place under the limit but keeps its port seat
74
+ // (`lane_capacity.free_lanes`).
75
+ return lane_capacity.free_lanes(limit, holders - merge_waiting, holders)
76
+ }
77
+
78
+ // **A holder whose detached ship waits on its merge holds no lane** — the count `backlog:drive` makes
79
+ // for the pool (`backlog-occupied.ts`), so a named epic's lanes are offered the place too
80
+ // (joshuafolkken/kit#4466). It keeps `in-progress` until the merge. The ship records read are this
81
+ // checkout's, so a `--repo` naming another repository is discounted nothing: its holder numbers
82
+ // would be matched against this repository's unrelated ships.
83
+ async function merge_waiting_holders(read: BusyRead, request: LaneRequest): Promise<number> {
84
+ if (read.kind !== 'busy' || !request.is_this_checkout) return NO_LANES
85
+
86
+ return await lane_snapshot_trace.count_merge_waiting(
87
+ read.issues.map((issue) => String(issue.number)),
88
+ )
67
89
  }
68
90
 
69
91
  function wanted_of(request: LaneRequest, free: number): number {
@@ -247,7 +269,7 @@ async function offer_for_repo(
247
269
 
248
270
  if (notice !== undefined) console.error(notice)
249
271
 
250
- const free = free_lanes(read, request.limit)
272
+ const free = free_lanes(read, request.limit, await merge_waiting_holders(read, request))
251
273
  const ages = await holder_ages(read, request.repo)
252
274
 
253
275
  if (free === NO_LANES) {
@@ -263,9 +285,22 @@ async function offer_for_repo(
263
285
  return solo_offer(await collect(for_repo, wanted_of(request, free)), read, request, ages)
264
286
  }
265
287
 
288
+ // A `--repo` compared against the repository this command runs in, case-insensitively as GitHub
289
+ // names it.
290
+ function lane_request(
291
+ asked: Pick<LaneRequest, 'repo' | 'is_all_lanes'>,
292
+ limit: number,
293
+ current_repo: string,
294
+ ): LaneRequest {
295
+ const is_this_checkout = asked.repo.toLowerCase() === current_repo.toLowerCase()
296
+
297
+ return { ...asked, limit, is_this_checkout }
298
+ }
299
+
266
300
  const epic_lane_offer = {
267
301
  combine_verdicts,
268
302
  dedupe_pools,
303
+ lane_request,
269
304
  offer_for_repo,
270
305
  }
271
306
 
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env tsx
2
+ import { fileURLToPath } from 'node:url'
3
+ import { josh_environment_file } from '#scripts/josh/josh-environment-file'
4
+ import { epic_next } from './epic-next'
5
+
6
+ // The `josh epic:next` entry, kept apart from `epic-next.ts` because other modules import that one: a
7
+ // bundle is one file, so a main guard there would fire for every command that carries it
8
+ // (joshuafolkken/kit#4186).
9
+ //
10
+ // `.env` is read here rather than through the dispatcher's `tsx_arguments`: declaring any would
11
+ // disqualify this command from in-process dispatch, and an unattended `epicrun` asks it every sixty
12
+ // seconds for the whole life of a run (`josh-environment-file.ts` records the measurement). Inside the
13
+ // guard, so a developer's own `.env` cannot decide what the unit tests see.
14
+ //
15
+ // `process.exitCode` rather than `process.exit()`, for the reason `scripts/cost-runtime/cost-main.ts`
16
+ // records: the answer goes to standard output and a write to a pipe is asynchronous on macOS, so
17
+ // exiting can tear the process down before it drains. This command's contract is
18
+ // `answer=$(pnpm josh epic:next <E>)`, which is exactly that pipe.
19
+ if (process.argv[1] === fileURLToPath(import.meta.url)) {
20
+ const ARGV_OFFSET = 2
21
+
22
+ josh_environment_file.load_environment_file()
23
+ process.exitCode = await epic_next.run(process.argv.slice(ARGV_OFFSET))
24
+ }
@@ -1,9 +1,6 @@
1
- #!/usr/bin/env tsx
2
- import { fileURLToPath } from 'node:url'
3
1
  import { repo_discovery } from '#scripts/discovery/repo-discovery'
4
2
  import { git_gh_command } from '#scripts/gh/git-gh-command'
5
3
  import { PROJECT_ROOT } from '#scripts/init/init-paths'
6
- import { josh_environment_file } from '#scripts/josh/josh-environment-file'
7
4
  import { lane_capacity } from '#scripts/lane/lane-capacity'
8
5
  import { cli_flags } from '#scripts/lib/cli-flags'
9
6
  import { issue_citation } from '#scripts/rules/issue-citation'
@@ -31,7 +28,6 @@ import { epic_report, type EpicNextResult } from './epic-report'
31
28
 
32
29
  const SUCCESS_EXIT_CODE = 0
33
30
  const FAILURE_EXIT_CODE = 1
34
- const ARGV_OFFSET = 2
35
31
  // Asking for every free lane (`--lanes`) is opt-in, so the answer stays one token for a caller that
36
32
  // has not been changed. `--repo` alone prints exactly one number.
37
33
  const OPTIONS = { repo: { type: 'string' }, lanes: { type: 'boolean' } } as const
@@ -351,11 +347,13 @@ async function report_epics(
351
347
  const choice = await lane_capacity.lane_limit()
352
348
  if (choice.kind === 'problem') return refuse(choice.problem)
353
349
 
354
- return await report(
355
- views,
356
- { repo: options.repo, limit: choice.limit, is_all_lanes: options.is_all_lanes ?? false },
350
+ const request = epic_lane_offer.lane_request(
351
+ { repo: options.repo, is_all_lanes: options.is_all_lanes ?? false },
352
+ choice.limit,
357
353
  current_repo,
358
354
  )
355
+
356
+ return await report(views, request, current_repo)
359
357
  }
360
358
 
361
359
  // One view per named epic, classified against one shared registry read. `running` is every named
@@ -416,14 +414,6 @@ async function run(argv: ReadonlyArray<string>): Promise<number> {
416
414
  return await run_epics(options)
417
415
  }
418
416
 
419
- // `process.exitCode` rather than `process.exit()`, for the reason `scripts/cost-runtime/cost-cli.ts` records:
420
- // the answer goes to standard output and a write to a pipe is asynchronous on macOS, so exiting can
421
- // tear the process down before it drains. This command's contract is `answer=$(pnpm josh epic:next
422
- // <E>)`, which is exactly that pipe.
423
- async function main(argv: ReadonlyArray<string>): Promise<void> {
424
- process.exitCode = await run(argv)
425
- }
426
-
427
417
  const epic_next = {
428
418
  EXTERNAL_NOTICE,
429
419
  FOREIGN_EPIC,
@@ -433,19 +423,11 @@ const epic_next = {
433
423
  parse_options,
434
424
  refuse_reads,
435
425
  views_of,
426
+ run,
436
427
  run_epics,
437
428
  decide,
438
429
  report,
439
430
  }
440
431
 
441
- // `.env` is read here rather than through the dispatcher's `tsx_arguments`: declaring any would
442
- // disqualify this command from in-process dispatch, and an unattended `epicrun` asks it every sixty
443
- // seconds for the whole life of a run (`josh-environment-file.ts` records the measurement). Inside the guard
444
- // rather than in `main`, so a developer's own `.env` cannot decide what the unit tests see.
445
- if (process.argv[1] === fileURLToPath(import.meta.url)) {
446
- josh_environment_file.load_environment_file()
447
- await main(process.argv.slice(ARGV_OFFSET))
448
- }
449
-
450
432
  export type { NextOptions }
451
433
  export { epic_next }
@@ -24,6 +24,10 @@ type DependencyVerdict = 'resolved' | 'time' | 'human' | 'inherit'
24
24
  // a closed blocker is a finished one.
25
25
  type ResolveDependency = (blocker: EpicChild, blocked: EpicChild) => DependencyVerdict
26
26
 
27
+ // A notice's mark on `run:board`: ❗ rather than ⚠, a text symbol drawn two columns wide over the
28
+ // blank after it.
29
+ const NOTICE_ICON = '❗'
30
+
27
31
  type OutsideCategory = 'time' | 'human'
28
32
 
29
33
  // A line to announce once per invocation, keyed so the classifier's de-duplication can drop repeats.
@@ -62,7 +66,7 @@ function unread_answer(child: EpicChild, reference: IssueReference): OutsideAnsw
62
66
  category: 'time',
63
67
  notice: {
64
68
  key: `unread:${epic_graph.key_of(child)}:${blocker}`,
65
- message: `⚠ ${name_of(child)} is blocked by ${blocker}, whose state could not be read — it waits rather than runs`,
69
+ message: `${NOTICE_ICON} ${name_of(child)} is blocked by ${blocker}, whose state could not be read — it waits rather than runs`,
66
70
  },
67
71
  }
68
72
  }
@@ -80,7 +84,7 @@ function open_answer(
80
84
  category: 'human',
81
85
  notice: {
82
86
  key: `outside:${epic_graph.key_of(child)}:${blocker}`,
83
- message: `⚠ ${name_of(child)} waits on ${blocker}, which this run will not finish — withheld for a person`,
87
+ message: `${NOTICE_ICON} ${name_of(child)} waits on ${blocker}, which this run will not finish — withheld for a person`,
84
88
  },
85
89
  }
86
90
  }
@@ -16,7 +16,10 @@ const TASK_LIST_LINE_PATTERN = new RegExp(TASK_LIST_ISSUE_SOURCE, 'u')
16
16
  // `owner/repo#101` on its own. The row patterns below are built from this source, so what counts as
17
17
  // a cross-repository reference has one definition — a second copy would let a form the task list
18
18
  // accepts be refused where a person types it, or the reverse.
19
- const EXTERNAL_REFERENCE_SOURCE = String.raw`([\w.-]+)\/([\w.-]+)#(\d+)`
19
+ // A segment starts with a word character, so `.`, `..` and a leading `-` never become an owner or a
20
+ // repository — `../..#1` would otherwise be read as one and walk the API path out of `repos/`.
21
+ const REPOSITORY_SEGMENT_SOURCE = String.raw`\w[\w.-]*`
22
+ const EXTERNAL_REFERENCE_SOURCE = String.raw`(${REPOSITORY_SEGMENT_SOURCE})\/(${REPOSITORY_SEGMENT_SOURCE})#(\d+)`
20
23
  const EXTERNAL_REFERENCE_PATTERN = new RegExp(`^${EXTERNAL_REFERENCE_SOURCE}$`, 'u')
21
24
  const TASK_LIST_ROW_SOURCE = String.raw`^[ \t]*[-*+][ \t]+\[[ xX]\][ \t]+`
22
25
  const EXTERNAL_TASK_LIST_PATTERN = new RegExp(
@@ -29,8 +32,10 @@ const EXTERNAL_SHORTHAND_PATTERN = new RegExp(
29
32
  'gmu',
30
33
  )
31
34
  // `- [ ] https://github.com/owner/repo/issues/101`
32
- const EXTERNAL_URL_PATTERN =
33
- /^[ \t]*[-*+][ \t]+\[[ xX]\][ \t]+https?:\/\/github\.com\/([\w.-]+)\/([\w.-]+)\/issues\/(\d+)\b/gmu
35
+ const EXTERNAL_URL_PATTERN = new RegExp(
36
+ String.raw`${TASK_LIST_ROW_SOURCE}https?:\/\/github\.com\/(${REPOSITORY_SEGMENT_SOURCE})\/(${REPOSITORY_SEGMENT_SOURCE})\/issues\/(\d+)\b`,
37
+ 'gmu',
38
+ )
34
39
 
35
40
  // Fenced blocks are stripped before matching. An epic body may quote the body template itself, and
36
41
  // its sample rows (`- [ ] #101 <title>`) are illustrations, not tracked children — counting them
@@ -345,4 +350,5 @@ export {
345
350
  is_state_closed,
346
351
  UNORDERED_DEPENDENCIES,
347
352
  DECLARED_CHAIN_LINE,
353
+ REPOSITORY_SEGMENT_SOURCE,
348
354
  }
@@ -67,6 +67,7 @@ async function read_epic(epic_number: number): Promise<EpicReading | { error: st
67
67
  }
68
68
 
69
69
  const epic_read = {
70
+ read_subject,
70
71
  read_epic,
71
72
  }
72
73
 
@@ -235,11 +235,50 @@ async function reconcile_epic(epic_number: number): Promise<number> {
235
235
  return await apply_plan(epic_number, plan)
236
236
  }
237
237
 
238
+ function with_recorded(
239
+ recorded: ReadonlyArray<EpicChild>,
240
+ link: DependencyLink,
241
+ repo: string,
242
+ ): Array<EpicChild> {
243
+ return recorded.map((child) =>
244
+ child.number === link.blocked && child.repo === repo
245
+ ? { ...child, blocked_by: [...child.blocked_by, to_blocker(link, repo)] }
246
+ : child,
247
+ )
248
+ }
249
+
250
+ // The plan the epic would reconcile to once `link` is recorded, so a caller about to record it can
251
+ // refuse first — a relation recorded and then refused leaves an order the declaration never carries.
252
+ function build_plan_after(input: ReconcilePlanInput, link: DependencyLink): ReconcilePlan {
253
+ return build_reconcile_plan({
254
+ ...input,
255
+ recorded: with_recorded(input.recorded, link, input.repo),
256
+ })
257
+ }
258
+
259
+ // Why reconciling after recording `link` would refuse, read before anything is written. An epic that
260
+ // cannot be read throws: a failed read is no answer about whether the reconcile would refuse.
261
+ async function refusal_after(
262
+ epic_number: number,
263
+ link: DependencyLink,
264
+ ): Promise<string | undefined> {
265
+ const epic = await epic_read.read_epic(epic_number)
266
+ if ('error' in epic) throw new Error(epic.error)
267
+
268
+ const input = { body: epic.subject.body, recorded: epic.recorded, repo: epic.repo }
269
+ const plan = build_plan_after(input, link)
270
+ if (plan.kind === 'cycle') return plan.message
271
+
272
+ return plan.kind === 'error' ? plan.error : undefined
273
+ }
274
+
238
275
  const epic_reconcile = {
239
276
  NOTHING_TO_RECONCILE,
240
277
  RECONCILED,
278
+ build_plan_after,
241
279
  build_reconcile_plan,
242
280
  reconcile_epic,
281
+ refusal_after,
243
282
  }
244
283
 
245
284
  export { epic_reconcile }
@@ -84,7 +84,9 @@ async function fill_run_command(
84
84
  }
85
85
  }
86
86
 
87
- async function create_epic(input: CreateEpicInput): Promise<number> {
87
+ // The created epic's number, or `undefined` when its URL could not be read — for a caller that writes
88
+ // to the epic next (`epic:bundle --apply` reconciling a recorded order).
89
+ async function create_epic_number(input: CreateEpicInput): Promise<number | undefined> {
88
90
  await git_gh_command.label_ensure({
89
91
  name: EPIC_LABEL,
90
92
  color: EPIC_LABEL_COLOR,
@@ -110,6 +112,12 @@ async function create_epic(input: CreateEpicInput): Promise<number> {
110
112
  await fill_run_command(epic_number, input)
111
113
  console.info(`▶ Run the children with: ${epic_body.format_run_command(epic_number)}`)
112
114
 
115
+ return epic_number
116
+ }
117
+
118
+ async function create_epic(input: CreateEpicInput): Promise<number> {
119
+ await create_epic_number(input)
120
+
113
121
  return SUCCESS_EXIT_CODE
114
122
  }
115
123
 
@@ -215,6 +223,7 @@ async function check_epic(epic_number: number): Promise<number> {
215
223
 
216
224
  const epic_run = {
217
225
  create_epic,
226
+ create_epic_number,
218
227
  promote_epic,
219
228
  check_epic,
220
229
  }
@@ -1,5 +1,5 @@
1
1
  import { issue_cite } from '#scripts/issue/issue-cite'
2
- import { has_any_label, has_label_name, RUN_SOLO_LABEL } from '#scripts/issue/issue-labels'
2
+ import { has_label_name, RUN_SOLO_LABEL } from '#scripts/issue/issue-labels'
3
3
  import { issue_citation } from '#scripts/rules/issue-citation'
4
4
  import { epic_busy, type BusyRead } from './epic-busy'
5
5
  import type { EpicChild } from './epic-graph'
@@ -28,8 +28,6 @@ import { epic_report, type EpicNextResult } from './epic-report'
28
28
  // them goes first is the ranking's question — `issue-rank.ts` puts a verification-path defect at the head — so an idle
29
29
  // repository takes the candidates in rank order like any other.
30
30
 
31
- const SOLO_LABELS: ReadonlySet<string> = new Set([RUN_SOLO_LABEL])
32
-
33
31
  // Which of the ordered candidates may start, which are held back, and why when a reason is worth
34
32
  // saying. `offered` keeps the candidates' own order.
35
33
  interface SoloSelection {
@@ -38,35 +36,65 @@ interface SoloSelection {
38
36
  notice?: string
39
37
  }
40
38
 
39
+ interface SoloQueue {
40
+ solo: EpicChild
41
+ index: number
42
+ behind: ReadonlyArray<EpicChild>
43
+ }
44
+
41
45
  interface SoloGate {
42
46
  result: EpicNextResult
43
47
  notice?: string
44
48
  }
45
49
 
46
- function is_solo(child: EpicChild): boolean {
50
+ // An issue as its number and its label names — a candidate, or a running issue `run:board` reads.
51
+ type Labelled = Pick<EpicChild, 'number' | 'labels'>
52
+
53
+ function is_solo(child: Labelled): boolean {
47
54
  return has_label_name(child.labels, RUN_SOLO_LABEL)
48
55
  }
49
56
 
57
+ // The running `run:solo` issue that lets nothing new start, if any — the one reading `select` and
58
+ // `run:board`'s 🔒 rows share (joshuafolkken/kit#4391).
59
+ function holder_of(running: ReadonlyArray<Labelled>): number | undefined {
60
+ return running.find((issue) => is_solo(issue))?.number
61
+ }
62
+
50
63
  function solo_holder(read: BusyRead): number | undefined {
51
64
  if (read.kind !== 'busy') return undefined
65
+ const running = read.issues.map((issue) => ({
66
+ number: issue.number,
67
+ labels: (issue.labels ?? []).map((label) => label.name),
68
+ }))
52
69
 
53
- return read.issues.find((issue) => has_any_label(issue.labels, SOLO_LABELS))?.number
70
+ return holder_of(running)
54
71
  }
55
72
 
73
+ // The words each of the gate's wait notices carries, so `backlog:offer` tells a `run:solo` wait from any
74
+ // other `wait` off the notice `backlog:next` printed (joshuafolkken/kit#4396). Each names its verb:
75
+ // `epic_solo_stale`'s release notice also opens "carries `run:solo` and", and is no wait.
76
+ const HELD_MARK = `carries \`${RUN_SOLO_LABEL}\` and is running in`
77
+ const WAITING_MARK = `carries \`${RUN_SOLO_LABEL}\` and waits for`
78
+
56
79
  function held_message(holder: number, repo: string): string {
57
80
  return issue_citation.linkify(
58
- `${issue_cite.plain(holder)} carries \`${RUN_SOLO_LABEL}\` and is running in ${repo}; nothing else starts until it merges or is parked.`,
81
+ `${issue_cite.plain(holder)} ${HELD_MARK} ${repo}; nothing else starts until it merges or is parked.`,
59
82
  repo,
60
83
  )
61
84
  }
62
85
 
63
86
  function waiting_message(solo: number, repo: string): string {
64
87
  return issue_citation.linkify(
65
- `${issue_cite.plain(solo)} carries \`${RUN_SOLO_LABEL}\` and waits for ${repo}'s running lanes to finish; nothing ranked below it is offered past it.`,
88
+ `${issue_cite.plain(solo)} ${WAITING_MARK} ${repo}'s running lanes to finish; nothing ranked below it is offered past it.`,
66
89
  repo,
67
90
  )
68
91
  }
69
92
 
93
+ // Whether `text` — what an offer printed on stderr — says the `run:solo` gate held the candidates.
94
+ function is_solo_wait(text: string): boolean {
95
+ return text.includes(HELD_MARK) || text.includes(WAITING_MARK)
96
+ }
97
+
70
98
  function first_of(children: ReadonlyArray<EpicChild>, keep: number): SoloSelection {
71
99
  return { offered: children.slice(0, keep), withheld: children.slice(keep) }
72
100
  }
@@ -75,6 +103,15 @@ function none_of(children: ReadonlyArray<EpicChild>, notice: string): SoloSelect
75
103
  return { offered: [], withheld: [...children], notice }
76
104
  }
77
105
 
106
+ // The first `run:solo` candidate, where it sits, and the candidates ranked behind it, which nothing
107
+ // offers past it. `run:board` draws the same reading on its queued rows (joshuafolkken/kit#4294).
108
+ function queue_of(children: ReadonlyArray<EpicChild>): SoloQueue | undefined {
109
+ const index = children.findIndex((child) => is_solo(child))
110
+ const solo = children[index]
111
+
112
+ return solo === undefined ? undefined : { solo, index, behind: children.slice(index + 1) }
113
+ }
114
+
78
115
  // Where the first `run:solo` candidate sits decides what starts: everything when there is none, the
79
116
  // candidates ahead of it when it is not first, and it alone once it heads an idle repository's ranking.
80
117
  function select_candidates(
@@ -82,14 +119,13 @@ function select_candidates(
82
119
  read: BusyRead,
83
120
  repo: string,
84
121
  ): SoloSelection {
85
- const index = children.findIndex((child) => is_solo(child))
86
- const solo = children[index]
122
+ const queue = queue_of(children)
87
123
 
88
- if (solo === undefined) return first_of(children, children.length)
89
- if (index > 0) return first_of(children, index)
124
+ if (queue === undefined) return first_of(children, children.length)
125
+ if (queue.index > 0) return first_of(children, queue.index)
90
126
  if (read.kind === 'idle') return first_of(children, 1)
91
127
 
92
- return none_of(children, waiting_message(solo.number, repo))
128
+ return none_of(children, waiting_message(queue.solo.number, repo))
93
129
  }
94
130
 
95
131
  // An unreadable or truncated listing keeps nothing: without it a running `run:solo` issue cannot be
@@ -143,7 +179,7 @@ function gate(
143
179
  : { result: gated, notice: selection.notice }
144
180
  }
145
181
 
146
- const epic_solo = { gate, is_solo, select }
182
+ const epic_solo = { gate, holder_of, is_solo, is_solo_wait, queue_of, select }
147
183
 
148
- export type { SoloGate, SoloSelection, SoloSelector }
184
+ export type { Labelled, SoloGate, SoloQueue, SoloSelection, SoloSelector }
149
185
  export { epic_solo }
@@ -8,11 +8,13 @@
8
8
  * tsx scripts/epic/epic.ts --add <E> <N1> <N2> ... [--before <M> | --after <M>]
9
9
  * [--decision-file <path|->]
10
10
  * tsx scripts/epic/epic.ts --remove <E> <M> <N> ... [--decision-file <path|->]
11
+ * tsx scripts/epic/epic.ts --decide <E> <N1> <N2> ... --decision-file <path|->
11
12
  */
12
13
  import { git_gh_command } from '#scripts/gh/git-gh-command'
13
14
  import { error_text } from '#scripts/lib/error-message'
14
15
  import { epic_add, type AddChildrenInput } from './epic-add'
15
16
  import { epic_cli, type AddArguments, type CrossRepoAddTarget } from './epic-cli'
17
+ import { epic_decide } from './epic-decide'
16
18
  import { epic_reconcile } from './epic-reconcile'
17
19
  import { epic_remove } from './epic-remove'
18
20
  import { epic_run } from './epic-run'
@@ -26,6 +28,7 @@ const USAGE = [
26
28
  ' josh epic --add <E> <N1> <N2> ... [--order-before <M> | --order-after <M>] [--decision-file <path|->]',
27
29
  ' josh epic --remove <E> <M> <N> ... [--decision-file <path|->]',
28
30
  ' josh epic --reconcile <E>',
31
+ ' josh epic --decide <E> <N1> <N2> ... --decision-file <path|->',
29
32
  ].join('\n')
30
33
  const FAILURE_EXIT_CODE = 1
31
34
 
@@ -134,6 +137,26 @@ async function run_removal(argv: ReadonlyArray<string>): Promise<number> {
134
137
  })
135
138
  }
136
139
 
140
+ // A decision about children the epic already tracks — the half `--add --decision-file` cannot write,
141
+ // since an insertion with nothing to add is refused.
142
+ async function run_decision(argv: ReadonlyArray<string>): Promise<number> {
143
+ const parsed = epic_cli.parse_decide_arguments(argv)
144
+
145
+ if (parsed === undefined) {
146
+ console.error(
147
+ `✖ An epic number, at least one child issue number, and exactly one readable \`--decision-file\` path (\`-\` reads stdin) are required.\n${USAGE}`,
148
+ )
149
+
150
+ return FAILURE_EXIT_CODE
151
+ }
152
+
153
+ return await epic_decide.decide({
154
+ epic_number: parsed.epic_number,
155
+ children: parsed.children,
156
+ decision: epic_cli.read_decision(parsed.decision_path) ?? '',
157
+ })
158
+ }
159
+
137
160
  // Reconcile an epic's declaration with its recorded relations. No decision file and no children: the
138
161
  // repair reads what the epic already records rather than being told an order.
139
162
  async function run_reconciliation(argv: ReadonlyArray<string>): Promise<number> {
@@ -166,15 +189,26 @@ async function run_creation(argv: ReadonlyArray<string>): Promise<number> {
166
189
  })
167
190
  }
168
191
 
169
- // `--add` is checked before `--promote`: both name an existing issue first, and only the flag
170
- // distinguishes "insert into this epic" from "turn this issue into one".
192
+ type EpicForm = readonly [
193
+ (argv: ReadonlyArray<string>) => boolean,
194
+ (argv: ReadonlyArray<string>) => Promise<number>,
195
+ ]
196
+
197
+ // Checked in this order. `--add` comes before `--promote`: both name an existing issue first, and only
198
+ // the flag distinguishes "insert into this epic" from "turn this issue into one".
199
+ const FLAGGED_FORMS: ReadonlyArray<EpicForm> = [
200
+ [epic_cli.is_reconciliation, run_reconciliation],
201
+ [epic_cli.is_removal, run_removal],
202
+ [epic_cli.is_decision_entry, run_decision],
203
+ [epic_cli.is_addition, run_addition],
204
+ [epic_cli.is_promotion, run_promotion],
205
+ ]
206
+
171
207
  async function run(argv: ReadonlyArray<string>): Promise<number> {
172
- if (epic_cli.is_reconciliation(argv)) return await run_reconciliation(argv)
173
- if (epic_cli.is_removal(argv)) return await run_removal(argv)
174
- if (epic_cli.is_addition(argv)) return await run_addition(argv)
175
- if (epic_cli.is_promotion(argv)) return await run_promotion(argv)
208
+ const form = FLAGGED_FORMS.find(([is_form]) => is_form(argv))
209
+ const run_form = form === undefined ? run_creation : form[1]
176
210
 
177
- return await run_creation(argv)
211
+ return await run_form(argv)
178
212
  }
179
213
 
180
214
  async function main(): Promise<void> {
@@ -4,7 +4,7 @@ import { fileURLToPath } from 'node:url'
4
4
  import { doctor_consumer } from '#scripts/doctor/doctor-consumer'
5
5
  import { project_checks } from '#scripts/gate/project-checks'
6
6
  import { NOTHING_TO_CHECK_MARKER } from '#scripts/test/skip-marker'
7
- import type { NamespaceMember } from './namespace-members'
7
+ import type { NamespaceMember } from '#tools/exports/namespace-members'
8
8
 
9
9
  const CHECK = 'exports'
10
10
  const FAIL_EXIT_CODE = 1
@@ -39,7 +39,7 @@ async function run_unused_members(root: string): Promise<number> {
39
39
  // Loaded only past the skip: the scanner pulls in `typescript`, an optional peer a basic-profile
40
40
  // consumer may not have, and this check runs in every consumer's gate. For the same reason the
41
41
  // scanner is left out of the published package (`package.json` `files`); only this entry ships.
42
- const { unused_members } = await import('./unused-members')
42
+ const { unused_members } = await import('#tools/exports/unused-members')
43
43
  const members = unused_members.find_unused_members(root)
44
44
  const output = report(root, members)
45
45
 
@@ -35,16 +35,21 @@ function coderabbit_state_of(check: RollupCheck | undefined): CodeRabbitState {
35
35
  return is_coderabbit_rate_limited(check) ? 'rate-limited' : 'done'
36
36
  }
37
37
 
38
+ // CodeRabbit's state on one poll — the reading `run:board` draws and `followup` times
39
+ // (`followup-coderabbit-wait.ts`).
40
+ function coderabbit_of(snapshot: PrStateSnapshot): CodeRabbitState {
41
+ return coderabbit_state_of(snapshot.rollup.find((check) => is_coderabbit_check(check.name)))
42
+ }
43
+
38
44
  function summary_of(snapshot: PrStateSnapshot, pr: number): PrChecks {
39
45
  const ci = snapshot.rollup.filter((check) => !is_coderabbit_check(check.name))
40
- const coderabbit = snapshot.rollup.find((check) => is_coderabbit_check(check.name))
41
46
 
42
47
  return {
43
48
  pr,
44
49
  pass: count_of(ci, CHECK_STATUS_PASS),
45
50
  pending: count_of(ci, CHECK_STATUS_PENDING),
46
51
  fail: count_of(ci, CHECK_STATUS_FAIL),
47
- coderabbit: coderabbit_state_of(coderabbit),
52
+ coderabbit: coderabbit_of(snapshot),
48
53
  }
49
54
  }
50
55
 
@@ -77,6 +82,6 @@ function observer_of(issue: string | undefined, pr_url: string | undefined): Sna
77
82
  }
78
83
  }
79
84
 
80
- const followup_checks_event = { observer_of, summary_of }
85
+ const followup_checks_event = { coderabbit_of, observer_of, summary_of }
81
86
 
82
87
  export { followup_checks_event }