@joshuafolkken/kit 1.1514.0 → 1.1784.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (858) hide show
  1. package/.claude/agents/investigator.md +1 -1
  2. package/.claude/settings.json +5 -5
  3. package/.claude/skills/epic-commands/SKILL.md +26 -65
  4. package/.claude/skills/epic-commands/epic-bundle.md +3 -1
  5. package/.claude/skills/workflow-commands/SKILL.md +5 -5
  6. package/.claude/skills/workflow-commands/background-commands.md +5 -5
  7. package/.claude/skills/workflow-commands/backlogrun-child.md +10 -8
  8. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
  9. package/.claude/skills/workflow-commands/backlogrun-lanes.md +17 -13
  10. package/.claude/skills/workflow-commands/backlogrun-park.md +14 -23
  11. package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -2
  12. package/.claude/skills/workflow-commands/backlogrun-recovery.md +5 -5
  13. package/.claude/skills/workflow-commands/backlogrun-steps.md +10 -10
  14. package/.claude/skills/workflow-commands/backlogrun.md +1 -1
  15. package/.claude/skills/workflow-commands/chain-rule.md +13 -7
  16. package/.claude/skills/workflow-commands/delegation.md +6 -5
  17. package/.claude/skills/workflow-commands/entry-sequence.md +9 -9
  18. package/.claude/skills/workflow-commands/followup.md +9 -31
  19. package/.claude/skills/workflow-commands/fullrun-steps.md +36 -45
  20. package/.claude/skills/workflow-commands/fullrun.md +2 -2
  21. package/.claude/skills/workflow-commands/halfrun.md +17 -25
  22. package/.claude/skills/workflow-commands/issue-comments.md +16 -12
  23. package/.claude/skills/workflow-commands/issue-scout.md +2 -2
  24. package/.claude/skills/workflow-commands/kickoff.md +24 -23
  25. package/.claude/skills/workflow-commands/latest-gate.md +7 -12
  26. package/.claude/skills/workflow-commands/needs-human-review.md +9 -14
  27. package/.claude/skills/workflow-commands/observation-filing.md +4 -36
  28. package/.claude/skills/workflow-commands/observation-ledger.md +1 -1
  29. package/.claude/skills/workflow-commands/pre-gate-cut.md +13 -30
  30. package/.claude/skills/workflow-commands/prerequisite.md +10 -16
  31. package/.claude/skills/workflow-commands/progress-watcher.md +1 -1
  32. package/.claude/skills/workflow-commands/prrun.md +3 -7
  33. package/.claude/skills/workflow-commands/retrospective.md +1 -1
  34. package/.claude/skills/workflow-commands/split-assessment.md +13 -1
  35. package/.claude/skills/workflow-commands/working-tree-hold.md +9 -9
  36. package/.codex/hooks.json +5 -5
  37. package/.github/actions/setup-node/action.yml +9 -0
  38. package/.github/actions/setup-pnpm/action.yml +1 -1
  39. package/.github/dependabot.yml +16 -0
  40. package/.github/release.yml +0 -2
  41. package/.github/workflows/ci.yml +120 -10
  42. package/.github/workflows/publish.yml +8 -1
  43. package/.github/workflows/sonar-qube.yml +1 -0
  44. package/.prettierignore +2 -0
  45. package/.vscode/tasks.json +1 -2
  46. package/CLAUDE.md +3 -7
  47. package/README.md +4 -2
  48. package/SECURITY.md +1 -1
  49. package/dist/CLAUDE.md +3 -7
  50. package/dist/commands/document-read-cli.js +882 -0
  51. package/dist/commands/{document-section-cli.js → document-section-main.js} +79 -37
  52. package/dist/commands/read-set-cli.js +1867 -0
  53. package/dist/commands/run-prep-main.js +21653 -0
  54. package/dist/commands/run-step-cli.js +23880 -0
  55. package/dist/config-merge/index.js +5 -1
  56. package/dist/hooks/audit-provision.js +20 -35
  57. package/dist/hooks/{chunk-DGT54IH5.js → chunk-AZX4FGQ3.js} +63 -17
  58. package/dist/hooks/chunk-CWMBGKYW.js +6483 -0
  59. package/dist/hooks/chunk-O2YBIDSI.js +4306 -0
  60. package/dist/hooks/{chunk-TNUMY6NL.js → chunk-PT5R6UJD.js} +4193 -1900
  61. package/dist/hooks/chunk-TUIFS5E7.js +72 -0
  62. package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
  63. package/dist/hooks/{chunk-APUO6U4J.js → chunk-WR2KQAYZ.js} +1843 -440
  64. package/dist/hooks/{chunk-O6GDRNJB.js → chunk-XGBNSWEI.js} +248 -46
  65. package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
  66. package/dist/hooks/codex-hook-adapter.js +10 -22
  67. package/dist/hooks/format-edited.js +5 -6
  68. package/dist/hooks/inputs.json +443 -317
  69. package/dist/hooks/pretool-guard.js +7 -25
  70. package/dist/hooks/session-lang.js +44 -51
  71. package/dist/hooks/stop-guard.js +7716 -2187
  72. package/dist/josh.js +6002 -3583
  73. package/dist/self-sync-guard/index.js +74 -10
  74. package/dist/version/index.js +115 -406
  75. package/eslint/base.js +1 -1
  76. package/lefthook/base.yml +3 -1
  77. package/package.json +10 -48
  78. package/pnpm-workspace.yaml +4 -2
  79. package/prompts/coding-standards.md +1 -1
  80. package/prompts/collaboration-workflow/file-edits.md +1 -7
  81. package/prompts/collaboration-workflow/issue-citation.md +1 -1
  82. package/prompts/collaboration-workflow/issue-template.md +33 -16
  83. package/prompts/collaboration-workflow/lane-instructions.md +1 -2
  84. package/prompts/collaboration-workflow/measurement.md +37 -0
  85. package/prompts/collaboration-workflow/operating-rules.md +4 -6
  86. package/prompts/collaboration-workflow/output-bounds.md +2 -7
  87. package/prompts/collaboration-workflow/plan-comment.md +3 -42
  88. package/prompts/collaboration-workflow/principles.md +5 -0
  89. package/prompts/collaboration-workflow/report-format.md +31 -60
  90. package/prompts/collaboration-workflow/residency.md +2 -2
  91. package/prompts/collaboration-workflow/shell-body.md +6 -16
  92. package/prompts/collaboration-workflow/turn-batching.md +0 -2
  93. package/prompts/collaboration-workflow/upstream-interrupt.md +14 -4
  94. package/prompts/collaboration-workflow/wip-cap.md +1 -1
  95. package/prompts/collaboration-workflow.md +3 -7
  96. package/prompts/refactoring.md +1 -1
  97. package/prompts/review-rubric.md +1 -2
  98. package/prompts/review.md +41 -21
  99. package/prompts/testing-guide.md +8 -43
  100. package/scripts/agent/agent-event.ts +15 -15
  101. package/scripts/agent/agent-exit-record.ts +13 -1
  102. package/scripts/agent/api-auth.ts +41 -0
  103. package/scripts/agent/api-outage.ts +1 -1
  104. package/scripts/auto-ok/auto-ok-cli.ts +14 -16
  105. package/scripts/auto-ok/auto-ok-judge-read.ts +12 -3
  106. package/scripts/auto-ok/auto-ok-judge-write.ts +46 -19
  107. package/scripts/auto-ok/auto-ok-judge.ts +13 -2
  108. package/scripts/auto-ok/auto-ok-main.ts +17 -0
  109. package/scripts/backlog/backlog-arrival.ts +14 -3
  110. package/scripts/backlog/backlog-budget-cli.ts +7 -33
  111. package/scripts/backlog/backlog-budget-main.ts +16 -0
  112. package/scripts/backlog/backlog-budget.ts +2 -3
  113. package/scripts/backlog/backlog-defect-priority.ts +4 -3
  114. package/scripts/backlog/backlog-drive-adopt.ts +67 -0
  115. package/scripts/backlog/backlog-drive-args.ts +4 -5
  116. package/scripts/backlog/backlog-drive-cli.ts +113 -28
  117. package/scripts/backlog/backlog-drive-hold.ts +162 -0
  118. package/scripts/backlog/backlog-drive-idle.ts +151 -0
  119. package/scripts/backlog/backlog-drive-judge.ts +25 -0
  120. package/scripts/backlog/backlog-drive-memory.ts +126 -0
  121. package/scripts/backlog/backlog-drive-named-offer.ts +5 -10
  122. package/scripts/backlog/backlog-drive-named.ts +53 -6
  123. package/scripts/backlog/backlog-drive-offer-argv.ts +3 -8
  124. package/scripts/backlog/backlog-drive-paused.ts +169 -0
  125. package/scripts/backlog/backlog-drive-restore.ts +30 -7
  126. package/scripts/backlog/backlog-drive-seats.ts +18 -8
  127. package/scripts/backlog/backlog-drive-token-handling.ts +38 -0
  128. package/scripts/backlog/backlog-drive.ts +79 -75
  129. package/scripts/backlog/backlog-next-main.ts +16 -0
  130. package/scripts/backlog/backlog-next-shared.ts +73 -0
  131. package/scripts/backlog/backlog-next.ts +48 -16
  132. package/scripts/backlog/backlog-occupied.ts +52 -39
  133. package/scripts/backlog/backlog-offer-cli.ts +6 -21
  134. package/scripts/backlog/backlog-offer-exclude.ts +15 -0
  135. package/scripts/backlog/backlog-offer-main.ts +12 -0
  136. package/scripts/backlog/backlog-offer.ts +36 -3
  137. package/scripts/backlog/backlog-overlap.ts +22 -4
  138. package/scripts/backlog/backlog-plan-read.ts +6 -2
  139. package/scripts/backlog/backlog-plan.ts +18 -4
  140. package/scripts/backlog/backlog-pool.ts +10 -10
  141. package/scripts/backlog/backlog-rank.ts +10 -2
  142. package/scripts/backlog/backlog-ready.ts +112 -30
  143. package/scripts/backlog/backlog-stalled-detect.ts +109 -36
  144. package/scripts/backlog/backlog-stalled.ts +52 -16
  145. package/scripts/backlog/backlog-wait-cause.ts +86 -0
  146. package/scripts/backlog/backlog-waves.ts +39 -13
  147. package/scripts/backlog/backlogrun-args.ts +19 -7
  148. package/scripts/backlog/backlogrun-cli.ts +19 -5
  149. package/scripts/backlog/backlogrun-launch.ts +6 -0
  150. package/scripts/backlog/backlogrun-restart.ts +97 -0
  151. package/scripts/backlog/backlogrun-stop.ts +79 -7
  152. package/scripts/behavior/behavior-cli.ts +2 -2
  153. package/scripts/behavior/behavior-rules.ts +47 -24
  154. package/scripts/build/build-bin.ts +2 -16
  155. package/scripts/build/build-claude-md.ts +0 -7
  156. package/scripts/build/build-commands.ts +0 -13
  157. package/scripts/build/build-hooks.ts +49 -48
  158. package/scripts/build/hook-bundle-stamp.ts +29 -11
  159. package/scripts/build/local-bin.ts +1 -1
  160. package/scripts/cases/cases-cli.ts +25 -13
  161. package/scripts/cases/cases-interaction-scan.ts +134 -0
  162. package/scripts/cases/cases-interaction.ts +183 -0
  163. package/scripts/cases/cases-logic.ts +39 -6
  164. package/scripts/ci/pr-classification-main.ts +18 -0
  165. package/scripts/ci/pr-classification.ts +10 -17
  166. package/scripts/clone/clone-scan.ts +1 -1
  167. package/scripts/cost-runtime/cost-blocks.ts +22 -37
  168. package/scripts/cost-runtime/cost-cli.ts +31 -14
  169. package/scripts/cost-runtime/cost-main.ts +12 -0
  170. package/scripts/cost-runtime/cost-transcript.ts +1 -0
  171. package/scripts/delegation/delegation-policy.ts +17 -4
  172. package/scripts/delegation/duplicate-read-guard.ts +0 -8
  173. package/scripts/delegation/investigation-guard.ts +0 -8
  174. package/scripts/delegation/investigation-reads.ts +3 -4
  175. package/scripts/dependabot/dependabot-cooldown.ts +194 -0
  176. package/scripts/discovery/repo-discovery.ts +24 -6
  177. package/scripts/doctor/doctor-consumer.ts +2 -5
  178. package/scripts/document/document-byte-budget.ts +8 -6
  179. package/scripts/document/document-scan.ts +1 -1
  180. package/scripts/document/document-section-cli.ts +0 -8
  181. package/scripts/document/document-section-main.ts +12 -0
  182. package/scripts/epic/epic-audit-cli.ts +12 -6
  183. package/scripts/epic/epic-bundle-apply.ts +137 -0
  184. package/scripts/epic/epic-bundle-cli.ts +32 -121
  185. package/scripts/epic/epic-bundle-format.ts +116 -0
  186. package/scripts/epic/epic-bundle-main.ts +17 -0
  187. package/scripts/epic/epic-busy.ts +5 -12
  188. package/scripts/epic/epic-classify.ts +24 -15
  189. package/scripts/epic/epic-cli-argv.ts +31 -0
  190. package/scripts/epic/epic-cli-decide.ts +42 -0
  191. package/scripts/epic/epic-cli.ts +6 -38
  192. package/scripts/epic/epic-close.ts +112 -55
  193. package/scripts/epic/epic-cross-repo.ts +4 -7
  194. package/scripts/epic/epic-decide.ts +119 -0
  195. package/scripts/epic/epic-decision.ts +9 -0
  196. package/scripts/epic/epic-fetch.ts +4 -0
  197. package/scripts/epic/epic-graph.ts +2 -0
  198. package/scripts/epic/epic-issue.ts +5 -1
  199. package/scripts/epic/epic-label-age.ts +1 -1
  200. package/scripts/epic/epic-lane-offer.ts +39 -4
  201. package/scripts/epic/epic-next-main.ts +24 -0
  202. package/scripts/epic/epic-next.ts +6 -24
  203. package/scripts/epic/epic-outside-blocker.ts +6 -2
  204. package/scripts/epic/epic-parse.ts +9 -3
  205. package/scripts/epic/epic-read.ts +1 -0
  206. package/scripts/epic/epic-reconcile.ts +39 -0
  207. package/scripts/epic/epic-run.ts +10 -1
  208. package/scripts/epic/epic-solo.ts +50 -14
  209. package/scripts/epic/epic.ts +41 -7
  210. package/scripts/exports/unused-members-cli.ts +2 -2
  211. package/scripts/followup/followup-checks-event.ts +8 -3
  212. package/scripts/followup/followup-coderabbit-wait.ts +82 -0
  213. package/scripts/followup/followup-review-gates.ts +81 -0
  214. package/scripts/followup/git-followup-stages.ts +13 -3
  215. package/scripts/followup/git-followup-workflow.ts +19 -66
  216. package/scripts/followup/git-pr-followup-wrapup.ts +9 -14
  217. package/scripts/followup/git-pr-followup.ts +36 -8
  218. package/scripts/fresh-machine/fresh-machine-cli.ts +1 -1
  219. package/scripts/fresh-machine/fresh-machine-run.ts +8 -8
  220. package/scripts/fresh-machine/specs/kit-test-backlogrun.json +1 -1
  221. package/scripts/gate/busy-average.ts +58 -0
  222. package/scripts/gate/check-cpu.ts +60 -0
  223. package/scripts/gate/check-inputs.ts +39 -95
  224. package/scripts/gate/check-reuse.ts +33 -54
  225. package/scripts/gate/command-memory.ts +192 -0
  226. package/scripts/gate/core-admission.ts +218 -28
  227. package/scripts/gate/core-budget-timing.ts +37 -0
  228. package/scripts/gate/core-budget.ts +80 -98
  229. package/scripts/gate/core-wait-record.ts +48 -0
  230. package/scripts/gate/core-wait.ts +37 -5
  231. package/scripts/gate/core-weights.ts +86 -0
  232. package/scripts/gate/free-cores.ts +27 -4
  233. package/scripts/gate/gate-ledger.ts +32 -4
  234. package/scripts/gate/gate-plan.ts +41 -34
  235. package/scripts/gate/gate-report.ts +14 -2
  236. package/scripts/gate/gate-run-steps.ts +53 -8
  237. package/scripts/gate/gate-skip.ts +12 -2
  238. package/scripts/gate/gate-steps.ts +12 -1
  239. package/scripts/gate/input-fingerprint.ts +42 -0
  240. package/scripts/gate/machine-capacity.ts +65 -31
  241. package/scripts/gate/moved-paths.ts +67 -0
  242. package/scripts/gate/project-checks.ts +5 -12
  243. package/scripts/gate/scoped-green.ts +12 -8
  244. package/scripts/gate/since-green.ts +62 -0
  245. package/scripts/gate/toolchain-inputs.ts +115 -0
  246. package/scripts/gate/verification-gate.ts +27 -24
  247. package/scripts/gate/verification-inputs.ts +250 -0
  248. package/scripts/gh/gh-author-association.ts +96 -9
  249. package/scripts/gh/git-ai-review-scan.ts +4 -2
  250. package/scripts/gh/git-gh-api-path.ts +15 -0
  251. package/scripts/gh/git-gh-branch-rules.ts +73 -0
  252. package/scripts/gh/git-gh-conditional.ts +5 -2
  253. package/scripts/gh/git-gh-issue-read.ts +5 -1
  254. package/scripts/gh/git-gh-issue-write.ts +67 -29
  255. package/scripts/gh/git-gh-issue.ts +7 -3
  256. package/scripts/gh/git-gh-poll-read.ts +89 -0
  257. package/scripts/gh/git-gh-pr-auto-merge.ts +8 -3
  258. package/scripts/gh/git-gh-pr-rest.ts +1 -1
  259. package/scripts/gh/git-gh-pr-snapshot.ts +33 -20
  260. package/scripts/gh/git-gh-pr.ts +27 -15
  261. package/scripts/gh/git-pr-checks-eval.ts +39 -7
  262. package/scripts/gh/git-pr-checks-parse.ts +39 -9
  263. package/scripts/gh/git-pr-merge-checked.ts +80 -0
  264. package/scripts/git/base-tree.ts +19 -2
  265. package/scripts/git/changed-file-scope.ts +6 -4
  266. package/scripts/git/changed-paths.ts +18 -1
  267. package/scripts/git/git-diff-reads.ts +27 -2
  268. package/scripts/git/git-grep-hits.ts +85 -0
  269. package/scripts/git/git-location-environment.ts +1 -1
  270. package/scripts/git/git-merge-conflicts.ts +83 -0
  271. package/scripts/git/git-preflight.ts +37 -12
  272. package/scripts/git/git-push-transport.ts +1 -2
  273. package/scripts/git/git-schemas.ts +17 -7
  274. package/scripts/git/git-spawn.ts +1 -2
  275. package/scripts/git/git-status.ts +4 -4
  276. package/scripts/git/main-merge-main.ts +12 -0
  277. package/scripts/git/main-merge-regenerate.ts +2 -2
  278. package/scripts/git/main-merge.ts +25 -9
  279. package/scripts/git/main-sync-main.ts +12 -0
  280. package/scripts/git/main-sync.ts +0 -9
  281. package/scripts/git/stash/git-stash.ts +27 -4
  282. package/scripts/git/stash/{stash-pop-args.ts → stash-args.ts} +13 -10
  283. package/scripts/git/stash/stash-pop-cli.ts +6 -12
  284. package/scripts/git/stash/stash-pop-main.ts +12 -0
  285. package/scripts/git/stash/stash-push-cli.ts +76 -0
  286. package/scripts/git/stash/stash-push-main.ts +12 -0
  287. package/scripts/hooks/batch-guard.ts +0 -8
  288. package/scripts/hooks/check-commit-message-main.ts +8 -0
  289. package/scripts/hooks/check-commit-message.ts +4 -7
  290. package/scripts/hooks/format-edited-file.ts +8 -24
  291. package/scripts/hooks/pre-commit-lint.ts +30 -3
  292. package/scripts/hooks/pre-push-unit.ts +4 -2
  293. package/scripts/hooks/pretool-guard-cli.ts +1 -8
  294. package/scripts/hooks/pretool-guard.ts +32 -19
  295. package/scripts/hooks/reserved-run.ts +67 -9
  296. package/scripts/hooks/run-hook.sh +13 -4
  297. package/scripts/hooks/shell-rules-notice.ts +37 -0
  298. package/scripts/hooks/stop-actions.ts +2 -21
  299. package/scripts/hooks/stop-guard.ts +13 -9
  300. package/scripts/init/hook-command-rewrite.ts +19 -5
  301. package/scripts/init/hook-launch.ts +15 -17
  302. package/scripts/init/init-actions.ts +0 -6
  303. package/scripts/init/init-ai-copy.ts +10 -36
  304. package/scripts/init/init-bootstrap.ts +9 -8
  305. package/scripts/init/init-dry-run-report.ts +1 -1
  306. package/scripts/init/init-dry-run.ts +1 -1
  307. package/scripts/init/init-file-action.ts +7 -9
  308. package/scripts/init/init-logic-json-merge.ts +2 -2
  309. package/scripts/init/init-logic-migrate.ts +9 -82
  310. package/scripts/init/init-logic.ts +3 -2
  311. package/scripts/init/init-main.ts +12 -0
  312. package/scripts/init/init.ts +5 -12
  313. package/scripts/init/kit-development-versions.ts +3 -7
  314. package/scripts/init/kit-written-paths.ts +2 -2
  315. package/scripts/init/project-profile.ts +5 -4
  316. package/scripts/init/tsconfig-preset-migration.ts +2 -1
  317. package/scripts/init/vscode-tasks.ts +1 -1
  318. package/scripts/issue/defect-origin-cli.ts +106 -0
  319. package/scripts/issue/defect-origin-line.ts +60 -0
  320. package/scripts/issue/defect-origin-main.ts +11 -0
  321. package/scripts/issue/defect-origin.ts +114 -0
  322. package/scripts/issue/defect-rate-cli.ts +34 -78
  323. package/scripts/issue/defect-rate.ts +0 -16
  324. package/scripts/issue/defect-report-cli.ts +128 -0
  325. package/scripts/issue/defect-report-format.ts +56 -0
  326. package/scripts/issue/defect-report-main.ts +11 -0
  327. package/scripts/issue/defect-report.ts +160 -0
  328. package/scripts/issue/expected-effect-lint.ts +1 -0
  329. package/scripts/issue/issue-already-done-cli.ts +62 -0
  330. package/scripts/issue/issue-body-or-comment.ts +40 -0
  331. package/scripts/issue/issue-cite-cli.ts +0 -9
  332. package/scripts/issue/issue-cite-main.ts +12 -0
  333. package/scripts/issue/issue-classification.ts +12 -7
  334. package/scripts/issue/issue-comment-cli.ts +10 -24
  335. package/scripts/issue/issue-comment-main.ts +12 -0
  336. package/scripts/issue/issue-evidence-exit.ts +100 -0
  337. package/scripts/issue/issue-file-cli.ts +29 -7
  338. package/scripts/issue/issue-file.ts +19 -19
  339. package/scripts/issue/issue-fold-cli.ts +2 -11
  340. package/scripts/issue/issue-fold-main.ts +12 -0
  341. package/scripts/issue/issue-labels.ts +81 -90
  342. package/scripts/issue/issue-lint-cli.ts +2 -10
  343. package/scripts/issue/issue-lint-main.ts +12 -0
  344. package/scripts/issue/issue-measured-cli.ts +56 -0
  345. package/scripts/issue/issue-merged.ts +19 -2
  346. package/scripts/issue/issue-not-before-label.ts +135 -0
  347. package/scripts/issue/issue-not-before.ts +111 -0
  348. package/scripts/issue/issue-number-shape.ts +15 -1
  349. package/scripts/issue/issue-park.ts +28 -0
  350. package/scripts/issue/issue-plan-cli.ts +151 -0
  351. package/scripts/issue/issue-priority.ts +151 -0
  352. package/scripts/issue/issue-rank.ts +7 -1
  353. package/scripts/issue/issue-read-cli.ts +3 -10
  354. package/scripts/issue/issue-read-main.ts +12 -0
  355. package/scripts/issue/issue-read.ts +29 -5
  356. package/scripts/issue/issue-release-cli.ts +0 -10
  357. package/scripts/issue/issue-release-main.ts +13 -0
  358. package/scripts/issue/issue-release.ts +7 -12
  359. package/scripts/issue/issue-sample-gate.ts +192 -0
  360. package/scripts/issue/issue-sample-source.ts +76 -0
  361. package/scripts/issue/issue-scout-cli.ts +0 -11
  362. package/scripts/issue/issue-scout-main.ts +14 -0
  363. package/scripts/issue/issue-state-cli.ts +0 -10
  364. package/scripts/issue/issue-state-main.ts +12 -0
  365. package/scripts/issue/issue-watch-diff.ts +56 -15
  366. package/scripts/issue/issue-watch.ts +2 -1
  367. package/scripts/issue/issue-wip.ts +2 -7
  368. package/scripts/issue/measure-rerun-cli.ts +13 -8
  369. package/scripts/issue/plan-consumers-cli.ts +39 -0
  370. package/scripts/issue/plan-consumers-main.ts +11 -0
  371. package/scripts/issue/plan-consumers-section.ts +55 -0
  372. package/scripts/issue/plan-consumers.ts +127 -0
  373. package/scripts/josh/agent-session-environment.ts +1 -1
  374. package/scripts/josh/command-usage.ts +15 -43
  375. package/scripts/josh/file-map-stamp.ts +49 -16
  376. package/scripts/josh/hook-decision.ts +32 -20
  377. package/scripts/josh/josh-command-map.ts +4 -1
  378. package/scripts/josh/josh-command-types.ts +12 -6
  379. package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
  380. package/scripts/josh/josh-commands-ai.ts +157 -158
  381. package/scripts/josh/josh-commands-backlog.ts +82 -16
  382. package/scripts/josh/josh-commands-clone.ts +1 -0
  383. package/scripts/josh/josh-commands-development.ts +111 -71
  384. package/scripts/josh/josh-commands-document.ts +43 -1
  385. package/scripts/josh/josh-commands-epic.ts +171 -0
  386. package/scripts/josh/josh-commands-hooks.ts +25 -2
  387. package/scripts/josh/josh-commands-issue-write.ts +181 -0
  388. package/scripts/josh/josh-commands-issue.ts +124 -24
  389. package/scripts/josh/josh-commands-lane.ts +103 -2
  390. package/scripts/josh/josh-commands-lint.ts +19 -8
  391. package/scripts/josh/josh-commands-maintenance.ts +112 -4
  392. package/scripts/josh/josh-commands-pause.ts +29 -0
  393. package/scripts/josh/josh-commands-progress.ts +87 -0
  394. package/scripts/josh/josh-commands-project.ts +138 -9
  395. package/scripts/josh/josh-commands-review.ts +124 -0
  396. package/scripts/josh/josh-commands-run.ts +211 -23
  397. package/scripts/josh/josh-commands-ship.ts +169 -0
  398. package/scripts/josh/josh-commands-split.ts +9 -0
  399. package/scripts/josh/josh-commands-versioning.ts +49 -2
  400. package/scripts/josh/josh-commands-workflow.ts +144 -6
  401. package/scripts/josh/josh-logic.ts +6 -13
  402. package/scripts/josh/package-directory.ts +2 -4
  403. package/scripts/josh/process-identity.ts +13 -4
  404. package/scripts/josh/session-language-cli.ts +4 -8
  405. package/scripts/josh/session-language-main.ts +13 -0
  406. package/scripts/josh/session-language.ts +6 -1
  407. package/scripts/josh/shared-cache.ts +90 -0
  408. package/scripts/josh/stamp-file.ts +9 -15
  409. package/scripts/lane/lane-await.ts +51 -12
  410. package/scripts/lane/lane-cache.ts +5 -30
  411. package/scripts/lane/lane-capacity.ts +14 -23
  412. package/scripts/lane/lane-check-stats.ts +62 -21
  413. package/scripts/lane/lane-child-invocation.ts +8 -0
  414. package/scripts/lane/lane-cli.ts +15 -5
  415. package/scripts/lane/lane-close.ts +86 -18
  416. package/scripts/lane/lane-core-wait-stats.ts +66 -0
  417. package/scripts/lane/lane-dispatch.ts +24 -3
  418. package/scripts/lane/lane-gap-stats.ts +156 -0
  419. package/scripts/lane/lane-handoff.ts +69 -1
  420. package/scripts/lane/lane-held-stats.ts +129 -0
  421. package/scripts/lane/lane-install.ts +4 -11
  422. package/scripts/lane/lane-launch-cli.ts +0 -9
  423. package/scripts/lane/lane-launch-main.ts +12 -0
  424. package/scripts/lane/lane-ledger-schema.ts +266 -0
  425. package/scripts/lane/lane-ledger.ts +92 -123
  426. package/scripts/lane/lane-limit-cli.ts +12 -1
  427. package/scripts/lane/lane-measure-cli.ts +57 -11
  428. package/scripts/lane/lane-open.ts +9 -1
  429. package/scripts/lane/lane-parked.ts +3 -3
  430. package/scripts/lane/lane-pause-cli.ts +130 -0
  431. package/scripts/lane/lane-pause.ts +158 -0
  432. package/scripts/lane/lane-process-table.ts +166 -0
  433. package/scripts/lane/lane-reap-settle.ts +124 -0
  434. package/scripts/lane/lane-reap.ts +50 -15
  435. package/scripts/lane/lane-registry.ts +24 -3
  436. package/scripts/lane/lane-residents.ts +162 -0
  437. package/scripts/lane/lane-restart.ts +22 -2
  438. package/scripts/lane/lane-round-two-stats.ts +49 -0
  439. package/scripts/lane/lane-sampler.ts +4 -0
  440. package/scripts/lane/lane-session-action.ts +19 -5
  441. package/scripts/lane/lane-session-broker.ts +102 -21
  442. package/scripts/lane/lane-snapshot-trace.ts +84 -0
  443. package/scripts/lane/lane-spans.ts +51 -0
  444. package/scripts/lane/lane-spent.ts +6 -3
  445. package/scripts/lane/lane-stage-stats.ts +7 -2
  446. package/scripts/lane/lane-state.ts +302 -0
  447. package/scripts/lane/lane-stats.ts +58 -4
  448. package/scripts/lane/lane-stop-stats.ts +113 -37
  449. package/scripts/lane/lane-test-related-stats.ts +127 -0
  450. package/scripts/lane/lane-transcript-calls.ts +145 -0
  451. package/scripts/lane/lane-transcript-stats.ts +168 -0
  452. package/scripts/lane/lane-vacant.ts +13 -3
  453. package/scripts/lane/lane-withdraw-cli.ts +5 -4
  454. package/scripts/lane/lane-withdraw.ts +50 -49
  455. package/scripts/lane/process-directories.ts +70 -0
  456. package/scripts/lane/process-lane-marks.ts +94 -0
  457. package/scripts/lib/atomic-write.ts +62 -0
  458. package/scripts/lib/buffered-process.ts +12 -5
  459. package/scripts/lib/cli-flags.ts +53 -0
  460. package/scripts/lib/figure-format.ts +63 -0
  461. package/scripts/lib/json-value.ts +9 -1
  462. package/scripts/lib/package-manifest.ts +35 -0
  463. package/scripts/lib/read-file.ts +3 -1
  464. package/scripts/lib/stamped-memo.ts +63 -0
  465. package/scripts/lib/stdout-on-stderr.ts +24 -0
  466. package/scripts/lib/timeouts.ts +9 -0
  467. package/scripts/lib/transcript-record.ts +91 -0
  468. package/scripts/lines/effective-limit.ts +1 -1
  469. package/scripts/lint/eslint-cache-dependencies.ts +145 -0
  470. package/scripts/lint/eslint-daemon.ts +265 -0
  471. package/scripts/lint/format.ts +11 -2
  472. package/scripts/lint/import-graph.ts +279 -0
  473. package/scripts/lint/lint-gate-scope.ts +102 -0
  474. package/scripts/lint/lint-parallel-main.ts +19 -0
  475. package/scripts/lint/lint-parallel.ts +62 -30
  476. package/scripts/lint/lint-related-scope.ts +30 -24
  477. package/scripts/lint/lint-related.ts +38 -6
  478. package/scripts/notify/confirmation-options.ts +1 -2
  479. package/scripts/notify/telegram-notify.ts +20 -20
  480. package/scripts/notify/telegram-test-logic.ts +0 -1
  481. package/scripts/notify/telegram-test-main.ts +8 -0
  482. package/scripts/notify/telegram-test.ts +2 -6
  483. package/scripts/observations/observation-ledger.ts +13 -0
  484. package/scripts/observations/observations-flush-landing.ts +5 -3
  485. package/scripts/observations/observations-flush.ts +6 -1
  486. package/scripts/overrides/overrides-check.ts +2 -5
  487. package/scripts/overrides/overrides-files.ts +2 -1
  488. package/scripts/overrides/overrides-logic.ts +3 -6
  489. package/scripts/package/verify-optional-eslint-install.ts +8 -6
  490. package/scripts/propagate/propagate-publish.ts +2 -7
  491. package/scripts/propagate/propagate-targets.ts +4 -12
  492. package/scripts/refactor/import-graph.ts +9 -7
  493. package/scripts/release/github-release-runs.ts +17 -6
  494. package/scripts/release/release-approval-prune.ts +18 -0
  495. package/scripts/release/release-history.ts +1 -3
  496. package/scripts/release/release-progress.ts +42 -22
  497. package/scripts/release/release-publish-run.ts +39 -0
  498. package/scripts/release/release-publish.ts +6 -6
  499. package/scripts/release/release-scope-cli.ts +0 -10
  500. package/scripts/release/release-scope-main.ts +12 -0
  501. package/scripts/repo/repo-setting.ts +3 -6
  502. package/scripts/repo/required-checks-logic.ts +6 -15
  503. package/scripts/report/report-format-reference.ts +2 -0
  504. package/scripts/report/report-labels.ts +155 -0
  505. package/scripts/report/report-lint-cli.ts +3 -0
  506. package/scripts/report/report-lint.ts +85 -110
  507. package/scripts/report/report-template-cli.ts +59 -0
  508. package/scripts/report/report-template.ts +112 -0
  509. package/scripts/review/acceptance-map.ts +1 -0
  510. package/scripts/review/removed-tests-check.ts +86 -0
  511. package/scripts/review/removed-tests.ts +149 -0
  512. package/scripts/review/review-brief-cli.ts +81 -15
  513. package/scripts/review/review-brief-main.ts +12 -0
  514. package/scripts/review/review-brief.ts +31 -3
  515. package/scripts/review/review-code-tree.ts +10 -6
  516. package/scripts/review/review-comment-round.ts +26 -8
  517. package/scripts/review/review-finding-ledger.ts +30 -15
  518. package/scripts/review/review-interaction.ts +94 -0
  519. package/scripts/review/review-readers-scan.ts +163 -0
  520. package/scripts/review/review-record-cli.ts +69 -30
  521. package/scripts/review/review-record-main.ts +12 -0
  522. package/scripts/review/review-round-one-blobs.ts +221 -0
  523. package/scripts/review/review-round2-cli.ts +49 -12
  524. package/scripts/review/review-round2.ts +80 -12
  525. package/scripts/review/review-stamps.ts +19 -1
  526. package/scripts/review/review-stop-log.ts +96 -0
  527. package/scripts/review/review-stops-cli.ts +85 -0
  528. package/scripts/review/review-tree.ts +6 -17
  529. package/scripts/review/review-untouched-readers.ts +146 -0
  530. package/scripts/review/test-titles.ts +118 -0
  531. package/scripts/rules/agent-model.ts +8 -0
  532. package/scripts/rules/bash-triggers.ts +46 -3
  533. package/scripts/rules/decision-oracle-batch.ts +9 -1
  534. package/scripts/rules/decision-oracle.ts +2 -2
  535. package/scripts/rules/delivered-rules.ts +80 -2
  536. package/scripts/rules/destructive-command.ts +8 -1
  537. package/scripts/rules/direct-filing.ts +10 -2
  538. package/scripts/rules/direct-issue-comment.ts +117 -0
  539. package/scripts/rules/direct-pr-create.ts +69 -3
  540. package/scripts/rules/early-heartbeat.ts +2 -1
  541. package/scripts/rules/file-body.ts +7 -0
  542. package/scripts/rules/filing-cap.ts +7 -0
  543. package/scripts/rules/git-argv.ts +72 -14
  544. package/scripts/rules/git-force.ts +12 -2
  545. package/scripts/rules/guard-remedy.ts +4 -0
  546. package/scripts/rules/implementation-cut-verdict.ts +1 -1
  547. package/scripts/rules/implementation-cut.ts +11 -3
  548. package/scripts/rules/index-guard.ts +8 -1
  549. package/scripts/rules/issue-comments.ts +9 -1
  550. package/scripts/rules/josh-git-bare.ts +7 -0
  551. package/scripts/rules/lane-background.ts +67 -25
  552. package/scripts/rules/lane-carry-conflict.ts +6 -0
  553. package/scripts/rules/lane-direct-tool.ts +74 -0
  554. package/scripts/rules/lane-interactive-ask.ts +9 -2
  555. package/scripts/rules/lane-park.ts +45 -23
  556. package/scripts/rules/lane-split-park.ts +10 -2
  557. package/scripts/rules/lane-switch-main.ts +7 -0
  558. package/scripts/rules/oracle-consulted.ts +10 -0
  559. package/scripts/rules/oracle-firing.ts +1 -0
  560. package/scripts/rules/permission-guards.ts +3 -0
  561. package/scripts/rules/piped-verification.ts +1 -1
  562. package/scripts/rules/poll-loop.ts +7 -0
  563. package/scripts/rules/pr-merge.ts +123 -0
  564. package/scripts/rules/protected-files.ts +32 -5
  565. package/scripts/rules/raw-field-body.ts +6 -0
  566. package/scripts/rules/rule-body-guard.ts +8 -0
  567. package/scripts/rules/rule-list.ts +9 -28
  568. package/scripts/rules/rule-value-cache.ts +4 -9
  569. package/scripts/rules/rule-value-cli.ts +51 -32
  570. package/scripts/rules/rule-value.ts +1 -1
  571. package/scripts/rules/shell-segments.ts +35 -0
  572. package/scripts/rules/stop-rule-rows.ts +64 -0
  573. package/scripts/rules/stop-rules.ts +3 -4
  574. package/scripts/rules/test-declared-commit.ts +11 -1
  575. package/scripts/rules/third-party-write.ts +7 -0
  576. package/scripts/rules/timed-rerun.ts +69 -0
  577. package/scripts/rules/worktree-guard.ts +13 -3
  578. package/scripts/run/board/run-board-app-name.ts +23 -0
  579. package/scripts/run/board/run-board-cli.ts +65 -32
  580. package/scripts/run/board/run-board-earlier.ts +94 -0
  581. package/scripts/run/board/run-board-ending-reason.ts +67 -0
  582. package/scripts/run/board/run-board-estimate-schedule.ts +103 -0
  583. package/scripts/run/board/run-board-estimate.ts +98 -0
  584. package/scripts/run/board/run-board-fit.ts +153 -36
  585. package/scripts/run/board/run-board-fold.ts +123 -0
  586. package/scripts/run/board/run-board-fresh.ts +2 -2
  587. package/scripts/run/board/run-board-gather-live.ts +29 -0
  588. package/scripts/run/board/run-board-gather-thread.ts +189 -0
  589. package/scripts/run/board/run-board-gather-worker.ts +29 -0
  590. package/scripts/run/board/run-board-gather.ts +187 -0
  591. package/scripts/run/board/run-board-github.ts +118 -38
  592. package/scripts/run/board/run-board-header.ts +82 -20
  593. package/scripts/run/board/run-board-keys.ts +58 -0
  594. package/scripts/run/board/run-board-kind.ts +20 -6
  595. package/scripts/run/board/run-board-labels.ts +116 -71
  596. package/scripts/run/board/run-board-lane-state.ts +109 -0
  597. package/scripts/run/board/run-board-lane-time.ts +122 -0
  598. package/scripts/run/board/run-board-layout.ts +239 -60
  599. package/scripts/run/board/run-board-length.ts +52 -0
  600. package/scripts/run/board/run-board-machine.ts +8 -4
  601. package/scripts/run/board/run-board-main.ts +12 -0
  602. package/scripts/run/board/run-board-notes.ts +52 -31
  603. package/scripts/run/board/run-board-now.ts +1 -1
  604. package/scripts/run/board/run-board-operation.ts +15 -33
  605. package/scripts/run/board/run-board-phase.ts +1 -1
  606. package/scripts/run/board/run-board-plan-shared.ts +115 -0
  607. package/scripts/run/board/run-board-plan.ts +55 -3
  608. package/scripts/run/board/run-board-planning.ts +45 -0
  609. package/scripts/run/board/run-board-priority.ts +44 -0
  610. package/scripts/run/board/run-board-process-groups.ts +195 -0
  611. package/scripts/run/board/run-board-read.ts +151 -27
  612. package/scripts/run/board/run-board-reason.ts +235 -51
  613. package/scripts/run/board/run-board-released.ts +35 -0
  614. package/scripts/run/board/run-board-render-checks.ts +39 -5
  615. package/scripts/run/board/run-board-render-condition.ts +96 -0
  616. package/scripts/run/board/run-board-render-drawn.ts +67 -0
  617. package/scripts/run/board/run-board-render-foot.ts +59 -0
  618. package/scripts/run/board/run-board-render-icon.ts +35 -0
  619. package/scripts/run/board/run-board-render-lanes.ts +145 -0
  620. package/scripts/run/board/run-board-render-lead.ts +80 -0
  621. package/scripts/run/board/run-board-render-legend.ts +117 -48
  622. package/scripts/run/board/run-board-render-notes.ts +156 -29
  623. package/scripts/run/board/run-board-render-processes.ts +196 -0
  624. package/scripts/run/board/run-board-render-section.ts +119 -0
  625. package/scripts/run/board/run-board-render-slot.ts +3 -36
  626. package/scripts/run/board/run-board-render-tail.ts +115 -48
  627. package/scripts/run/board/run-board-render-time.ts +56 -0
  628. package/scripts/run/board/run-board-render-title.ts +117 -24
  629. package/scripts/run/board/run-board-render-waits.ts +104 -20
  630. package/scripts/run/board/run-board-render.ts +207 -265
  631. package/scripts/run/board/run-board-roots.ts +54 -0
  632. package/scripts/run/board/run-board-row-yield.ts +9 -4
  633. package/scripts/run/board/run-board-setup.ts +1 -12
  634. package/scripts/run/board/run-board-snapshot.ts +111 -0
  635. package/scripts/run/board/run-board-spin.ts +2 -2
  636. package/scripts/run/board/run-board-state.ts +22 -33
  637. package/scripts/run/board/run-board-status.ts +147 -71
  638. package/scripts/run/board/run-board-thanks-read.ts +2 -2
  639. package/scripts/run/board/run-board-tick.ts +122 -107
  640. package/scripts/run/board/run-board-usage-board.ts +78 -0
  641. package/scripts/run/board/run-board-usage-lanes.ts +113 -0
  642. package/scripts/run/board/run-board-usage-listing.ts +93 -0
  643. package/scripts/run/board/run-board-usage-read.ts +120 -150
  644. package/scripts/run/board/run-board-usage-rusage.ts +19 -7
  645. package/scripts/run/board/run-board-usage-text.ts +139 -51
  646. package/scripts/run/board/run-board-usage-top.ts +102 -0
  647. package/scripts/run/board/run-board-usage.ts +89 -72
  648. package/scripts/run/board/run-board-usual.ts +20 -9
  649. package/scripts/run/carry/run-carry-args.ts +4 -7
  650. package/scripts/run/carry/run-carry-conversation.ts +1 -1
  651. package/scripts/run/carry/run-carry.ts +9 -4
  652. package/scripts/run/cut/run-cut-handoff.ts +2 -2
  653. package/scripts/run/event/run-event-cli.ts +1 -5
  654. package/scripts/run/event/run-event-filed.ts +12 -6
  655. package/scripts/run/event/run-event-follow.ts +2 -3
  656. package/scripts/run/event/run-event-render.ts +6 -10
  657. package/scripts/run/event/run-event-scope.ts +2 -2
  658. package/scripts/run/event/run-event-stream-emit.ts +82 -22
  659. package/scripts/run/event/run-event-stream.ts +34 -8
  660. package/scripts/run/hold/run-hold-adopt.ts +65 -0
  661. package/scripts/run/hold/run-hold-cli.ts +93 -22
  662. package/scripts/run/hold/run-hold-main.ts +12 -0
  663. package/scripts/run/hold/run-hold-member.ts +37 -0
  664. package/scripts/run/hold/run-stop-notify.ts +183 -0
  665. package/scripts/run/merge/run-merge-auth.ts +31 -0
  666. package/scripts/run/merge/run-merge-cli.ts +62 -48
  667. package/scripts/run/merge/run-merge-close.ts +74 -0
  668. package/scripts/run/merge/run-merge-collect.ts +6 -13
  669. package/scripts/run/merge/run-merge-driver.ts +71 -0
  670. package/scripts/run/merge/run-merge-main.ts +12 -0
  671. package/scripts/run/merge/run-merge-outcome.ts +23 -0
  672. package/scripts/run/merge/run-merge-restart.ts +39 -0
  673. package/scripts/run/merge/run-merge-ship.ts +20 -4
  674. package/scripts/run/merge/run-merge-signals.ts +33 -9
  675. package/scripts/run/merge/run-merge-steps.ts +120 -85
  676. package/scripts/run/merge/run-merge.ts +38 -37
  677. package/scripts/run/park/run-park-cli.ts +91 -0
  678. package/scripts/run/park/run-park.ts +88 -0
  679. package/scripts/run/park/run-stalled.ts +68 -0
  680. package/scripts/run/pause/run-pause-cli.ts +73 -0
  681. package/scripts/run/pause/run-pause.ts +251 -0
  682. package/scripts/run/progress/run-progress-cli.ts +4 -12
  683. package/scripts/run/progress/run-progress-clock.ts +1 -1
  684. package/scripts/run/progress/run-progress-config.ts +6 -14
  685. package/scripts/run/progress/run-progress-main.ts +12 -0
  686. package/scripts/run/progress/run-progress.ts +1 -4
  687. package/scripts/run/review/run-review.ts +2 -1
  688. package/scripts/run/run-ending.ts +1 -0
  689. package/scripts/run/run-invocation.ts +5 -6
  690. package/scripts/run/run-liveness-cli.ts +6 -8
  691. package/scripts/run/run-liveness.ts +60 -29
  692. package/scripts/run/run-next.ts +1 -1
  693. package/scripts/run/run-parent-cut-hook.ts +2 -2
  694. package/scripts/run/run-preflight.ts +18 -3
  695. package/scripts/run/run-prep-cli.ts +1 -10
  696. package/scripts/run/run-prep-locate.ts +7 -50
  697. package/scripts/run/run-prep-main.ts +12 -0
  698. package/scripts/run/run-prep.ts +6 -0
  699. package/scripts/run/run-report-cli.ts +101 -13
  700. package/scripts/run/run-report-handoff.ts +114 -0
  701. package/scripts/run/run-step.ts +1 -1
  702. package/scripts/run/run-stranded-detect.ts +13 -0
  703. package/scripts/run/run-watcher-guard-cli.ts +1 -1
  704. package/scripts/run/run-watcher-guard.ts +1 -1
  705. package/scripts/run/ship/run-ship-args.ts +121 -0
  706. package/scripts/run/ship/run-ship-body-draft.ts +110 -0
  707. package/scripts/run/ship/run-ship-cli.ts +63 -140
  708. package/scripts/run/ship/run-ship-detach.ts +19 -8
  709. package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
  710. package/scripts/run/ship/run-ship-next.ts +18 -2
  711. package/scripts/run/ship/run-ship-overlap.ts +42 -5
  712. package/scripts/run/ship/run-ship-place.ts +96 -0
  713. package/scripts/run/ship/run-ship-pre-detach-timed.ts +43 -0
  714. package/scripts/run/ship/run-ship-pre-detach.ts +81 -24
  715. package/scripts/run/ship/run-ship-preflight.ts +137 -32
  716. package/scripts/run/ship/run-ship-probe.ts +11 -3
  717. package/scripts/run/ship/run-ship-relaunch-cap.ts +70 -0
  718. package/scripts/run/ship/run-ship-removed-rows.ts +61 -0
  719. package/scripts/run/ship/run-ship-return.ts +107 -23
  720. package/scripts/run/ship/run-ship-review-steps.ts +105 -151
  721. package/scripts/run/ship/run-ship-review.ts +73 -6
  722. package/scripts/run/ship/run-ship-reviewer.ts +207 -0
  723. package/scripts/run/ship/run-ship-stage.ts +55 -6
  724. package/scripts/run/ship/run-ship-steps.ts +46 -15
  725. package/scripts/run/ship/run-ship-stop-cause.ts +135 -0
  726. package/scripts/run/ship/run-ship-stop-text.ts +11 -6
  727. package/scripts/run/ship/run-ship-sync.ts +43 -6
  728. package/scripts/run/ship/run-ship.ts +30 -2
  729. package/scripts/run/tidy/run-tidy-cli.ts +0 -4
  730. package/scripts/run/tidy/run-tidy-lanes.ts +3 -0
  731. package/scripts/run/tidy/run-tidy-main.ts +8 -0
  732. package/scripts/run/wake/run-wake-cli.ts +119 -100
  733. package/scripts/run/wake/run-wake-code.ts +83 -0
  734. package/scripts/run/wake/run-wake-driver.ts +19 -8
  735. package/scripts/run/wake/run-wake-loop.ts +34 -3
  736. package/scripts/run/wake/run-wake-main.ts +13 -0
  737. package/scripts/run/wake/run-wake-ports.ts +90 -0
  738. package/scripts/run/wake/run-wake-takeover.ts +66 -0
  739. package/scripts/run/wake/run-wake.ts +2 -1
  740. package/scripts/safe-chain/pack-hook.ts +2 -2
  741. package/scripts/safe-chain/preinstall-command.ts +2 -1
  742. package/scripts/safe-chain/project-config.ts +3 -9
  743. package/scripts/security/security-audit-main.ts +8 -0
  744. package/scripts/security/security-audit-provision-logic.ts +0 -11
  745. package/scripts/security/security-audit-provision-main.ts +12 -0
  746. package/scripts/security/security-audit-provision.ts +11 -26
  747. package/scripts/security/security-audit.ts +6 -7
  748. package/scripts/self-sync-guard/self-sync-guard-logic.ts +6 -13
  749. package/scripts/split/split-assess-cli.ts +2 -2
  750. package/scripts/split/split-assess.ts +15 -0
  751. package/scripts/split/split-measure.ts +65 -0
  752. package/scripts/sync/claude-settings-merge.ts +8 -15
  753. package/scripts/sync/directory-copy-guard.ts +4 -9
  754. package/scripts/sync/file-content.ts +78 -8
  755. package/scripts/sync/sync-ai-files.ts +3 -5
  756. package/scripts/sync/sync-configs.ts +11 -23
  757. package/scripts/sync/sync-hook-safety.ts +4 -10
  758. package/scripts/sync/sync-main.ts +11 -0
  759. package/scripts/sync/sync.ts +25 -37
  760. package/scripts/test/test-declared-changed.ts +2 -2
  761. package/scripts/test/test-declared.ts +1 -1
  762. package/scripts/test/test-e2e-guard.ts +25 -1
  763. package/scripts/test/test-e2e-stamp.ts +38 -0
  764. package/scripts/test/test-pinned-logic.ts +145 -0
  765. package/scripts/test/test-pinned-main.ts +78 -0
  766. package/scripts/test/test-pinned.ts +100 -0
  767. package/scripts/test/test-read-map.ts +264 -0
  768. package/scripts/test/test-read-recording.ts +91 -0
  769. package/scripts/test/test-read-trace.ts +148 -0
  770. package/scripts/test/test-red-main.ts +12 -0
  771. package/scripts/test/test-red.ts +12 -30
  772. package/scripts/test/test-related-main.ts +18 -0
  773. package/scripts/test/test-related-record.ts +119 -0
  774. package/scripts/test/test-related-scope.ts +229 -43
  775. package/scripts/test/test-related.ts +300 -22
  776. package/scripts/test/test-unit-guard-main.ts +15 -0
  777. package/scripts/test/test-unit-guard.ts +42 -24
  778. package/scripts/test/unit-count-file.ts +37 -0
  779. package/scripts/test/unit-run-marker.ts +162 -0
  780. package/scripts/test/unit-setup-files.ts +51 -0
  781. package/scripts/test/unit-worker-share.ts +61 -149
  782. package/scripts/test/whole-suite-files.ts +63 -0
  783. package/scripts/time-runtime/time-background.ts +20 -2
  784. package/scripts/time-runtime/time-bundles.ts +4 -3
  785. package/scripts/time-runtime/time-density-hook.ts +8 -6
  786. package/scripts/time-runtime/time-followup-stage.ts +1 -3
  787. package/scripts/time-runtime/time-format.ts +5 -28
  788. package/scripts/time-runtime/time-markers.ts +10 -1
  789. package/scripts/time-runtime/time-shell.ts +97 -10
  790. package/scripts/time-runtime/time-transcript-line.ts +49 -62
  791. package/scripts/uninstall/uninstall.ts +1 -1
  792. package/scripts/version/bump-version-main.ts +12 -0
  793. package/scripts/version/bump-version.ts +25 -25
  794. package/scripts/version/effective-upstream.ts +6 -12
  795. package/scripts/version/latest-corepack.ts +17 -32
  796. package/scripts/version/latest-if-required-cli.ts +93 -0
  797. package/scripts/version/latest-lane-guard-main.ts +8 -0
  798. package/scripts/version/latest-lane-guard.ts +0 -4
  799. package/scripts/version/latest-scope-cli.ts +0 -9
  800. package/scripts/version/latest-scope-main.ts +12 -0
  801. package/scripts/version/latest-update.ts +5 -5
  802. package/scripts/version/npm-registry.ts +44 -6
  803. package/scripts/version/publishable-range-check.ts +5 -16
  804. package/scripts/version/release-age.ts +1 -1
  805. package/scripts/version/release-hold.ts +1 -1
  806. package/scripts/version/release-window.ts +38 -0
  807. package/scripts/version/running-binary.ts +1 -1
  808. package/scripts/version/safe-chain-version-update.ts +3 -8
  809. package/scripts/version/version-targets.ts +6 -28
  810. package/templates/dependabot.yml +29 -0
  811. package/templates/gitignore +4 -1
  812. package/templates/pnpm-workspace.basic.yaml +1 -1
  813. package/templates/sonar-project.properties +3 -2
  814. package/templates/workflows/ci.yml +12 -4
  815. package/templates/workflows/github-release.yml +4 -0
  816. package/tsconfig.sonar.json +1 -1
  817. package/.ncurc.json +0 -3
  818. package/dist/hooks/batch-guard.js +0 -29
  819. package/dist/hooks/chunk-4KKD2UTK.js +0 -66
  820. package/dist/hooks/chunk-6TS2JD6D.js +0 -237
  821. package/dist/hooks/chunk-7DSBJVFH.js +0 -50
  822. package/dist/hooks/chunk-A65Y4YOR.js +0 -79
  823. package/dist/hooks/chunk-CDY4NFQG.js +0 -15
  824. package/dist/hooks/chunk-EFXE6C37.js +0 -81
  825. package/dist/hooks/chunk-GP4IEC4O.js +0 -20
  826. package/dist/hooks/chunk-JP45SOCJ.js +0 -56
  827. package/dist/hooks/chunk-LAOV7NLM.js +0 -45
  828. package/dist/hooks/chunk-M4HGZV7U.js +0 -83
  829. package/dist/hooks/chunk-PF2NZL2A.js +0 -131
  830. package/dist/hooks/chunk-PTICX4OL.js +0 -358
  831. package/dist/hooks/chunk-RT27QRJW.js +0 -6247
  832. package/dist/hooks/chunk-SYOTDYCI.js +0 -3533
  833. package/dist/hooks/chunk-UPUZF3AN.js +0 -279
  834. package/dist/hooks/chunk-WK6SMBIC.js +0 -3180
  835. package/dist/hooks/duplicate-read-guard.js +0 -30
  836. package/dist/hooks/investigation-guard.js +0 -29
  837. package/scripts/backlog/backlog-stalled-cli.ts +0 -30
  838. package/scripts/cost-runtime/cost-format.ts +0 -29
  839. package/scripts/init/basic-path-migration.ts +0 -24
  840. package/scripts/issue/issue-backlinks-cli.ts +0 -93
  841. package/scripts/josh/josh-commands-guard.ts +0 -38
  842. package/scripts/josh/josh-usage-automation.ts +0 -121
  843. package/scripts/josh/josh-usage-backlog.ts +0 -180
  844. package/scripts/josh/josh-usage-developer.ts +0 -230
  845. package/scripts/josh/josh-usage-hooks.ts +0 -38
  846. package/scripts/josh/josh-usage-issue.ts +0 -205
  847. package/scripts/josh/josh-usage-review.ts +0 -101
  848. package/scripts/josh/josh-usage-run.ts +0 -252
  849. package/scripts/josh/josh-usage-session.ts +0 -238
  850. package/scripts/josh/josh-usage-workflow.ts +0 -212
  851. package/scripts/lint/cross-file-recheck.ts +0 -155
  852. package/scripts/registry-migration/migrate-logic.ts +0 -237
  853. package/scripts/registry-migration/migrate.ts +0 -292
  854. package/scripts/registry-migration/user-npmrc.ts +0 -15
  855. package/scripts/rules/rule-guard.ts +0 -23
  856. package/scripts/rules/rule-registry-rows.ts +0 -292
  857. package/scripts/rules/rule-registry.ts +0 -112
  858. package/scripts/run/run-stranded-cli.ts +0 -27
@@ -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 }
@@ -0,0 +1,82 @@
1
+ import type { SnapshotObserver } from '#scripts/gh/git-pr-checks'
2
+ import type { PrStateSnapshot } from '#scripts/gh/git-pr-checks-parse'
3
+ import { lane_ledger } from '#scripts/lane/lane-ledger'
4
+ import type { CodeRabbitState } from '#scripts/run/event/run-event-checks'
5
+ import { followup_checks_event } from './followup-checks-event'
6
+
7
+ // How long `followup`'s check waits spent with CodeRabbit still running or rate-limited
8
+ // (joshuafolkken/kit#4574). CodeRabbit does not gate the merge, so the wait never names it; without
9
+ // this, a followup that sat for half an hour beside a rate-limited CodeRabbit leaves nothing in the
10
+ // lane ledger but a long `ci-wait`.
11
+ //
12
+ // **The time between two polls is the state the earlier poll saw** — the observer sees snapshots, not
13
+ // transitions, so the clock is read at each one and the interval since the last is charged to the
14
+ // state that held over it. The clock is `performance.now()`'s, monotonic for the reason
15
+ // `git-followup-stages.ts` states.
16
+
17
+ const NO_TIME = 0
18
+ const RATE_LIMITED: CodeRabbitState = 'rate-limited'
19
+ const WAITING_STATES: ReadonlySet<CodeRabbitState> = new Set(['running', RATE_LIMITED])
20
+
21
+ interface Poll {
22
+ state: CodeRabbitState
23
+ at_ms: number
24
+ }
25
+
26
+ // Mutable for the reason `StageLog` is: the observer adds to it as the wait polls.
27
+ interface CodeRabbitWait {
28
+ wait_ms: number
29
+ rate_limited_ms: number
30
+ last?: Poll
31
+ }
32
+
33
+ function new_wait(): CodeRabbitWait {
34
+ return { wait_ms: NO_TIME, rate_limited_ms: NO_TIME }
35
+ }
36
+
37
+ function charge(wait: CodeRabbitWait, last: Poll, now_ms: number): void {
38
+ const elapsed_ms = now_ms - last.at_ms
39
+
40
+ if (WAITING_STATES.has(last.state)) wait.wait_ms += elapsed_ms
41
+ if (last.state === RATE_LIMITED) wait.rate_limited_ms += elapsed_ms
42
+ }
43
+
44
+ function observe(wait: CodeRabbitWait, snapshot: PrStateSnapshot, now_ms: number): void {
45
+ if (wait.last !== undefined) charge(wait, wait.last, now_ms)
46
+
47
+ wait.last = { state: followup_checks_event.coderabbit_of(snapshot), at_ms: now_ms }
48
+ }
49
+
50
+ // **Each check wait is timed from its own first poll**: the time between two waits — the comment scans,
51
+ // the merge that found the head moved — is not CodeRabbit's, whatever the earlier wait last saw.
52
+ function observer_of(wait: CodeRabbitWait): SnapshotObserver {
53
+ delete wait.last
54
+
55
+ return async function time_snapshot(snapshot: PrStateSnapshot): Promise<void> {
56
+ observe(wait, snapshot, performance.now())
57
+ }
58
+ }
59
+
60
+ // Both observers on every poll — the board's event line and this timer.
61
+ function both(first: SnapshotObserver, second: SnapshotObserver): SnapshotObserver {
62
+ return async function observe_both(snapshot: PrStateSnapshot): Promise<void> {
63
+ await first(snapshot)
64
+ await second(snapshot)
65
+ }
66
+ }
67
+
68
+ async function record_part(stage: string, elapsed_ms: number): Promise<void> {
69
+ if (elapsed_ms > NO_TIME) await lane_ledger.record_stage({ stage, elapsed_ms })
70
+ }
71
+
72
+ // **A run that never saw CodeRabbit waiting records nothing**, so a row's run count is how many
73
+ // followups CodeRabbit held up, and its median is over those.
74
+ async function record(wait: CodeRabbitWait): Promise<void> {
75
+ await record_part(lane_ledger.CODERABBIT_WAIT_STAGE, wait.wait_ms)
76
+ await record_part(lane_ledger.CODERABBIT_RATE_LIMIT_STAGE, wait.rate_limited_ms)
77
+ }
78
+
79
+ const followup_coderabbit_wait = { both, new_wait, observe, observer_of, record }
80
+
81
+ export type { CodeRabbitWait }
82
+ export { followup_coderabbit_wait }
@@ -0,0 +1,81 @@
1
+ import { issue_number_shape } from '#scripts/issue/issue-number-shape'
2
+ import { issue_watch_gate } from '#scripts/issue/issue-watch-gate'
3
+ import { review_attest } from '#scripts/review/review-attest'
4
+ import { review_interaction } from '#scripts/review/review-interaction'
5
+ import { review_record } from '#scripts/review/review-record'
6
+
7
+ // The merge gates over the review rounds — that the review read its own checkout, and that each round
8
+ // the change owes left its ledger line. `git-followup-workflow.ts` runs them first, before the gates over
9
+ // the pull request body.
10
+
11
+ // `/code-review` is forked by the harness and inherits the *session's* working directory, so a run
12
+ // implementing in a lane can be reviewed against a different tree entirely — one holding the
13
+ // previous child's already-merged code. That review finds nothing wrong and says so, and the run
14
+ // would read the silence as a clean round. **This is the seam where that is caught**: a merge is
15
+ // refused unless the review attested the checkout it was briefed on.
16
+ //
17
+ // **Absence is a refusal, not a pass.** The defect produces *no* signal, so a check that only
18
+ // compared two present records would answer `ok` in exactly the state it exists to catch.
19
+ //
20
+ // **Scoped to a checkout that actually briefed a review.** `review_attest.check` answers
21
+ // `not-required` where no `josh review:brief` was run here inside a run's lifetime, so a project or
22
+ // a flow that does not use the brief merges exactly as it did before.
23
+ //
24
+ // The direction is deliberate: a wrongly-refused merge costs one re-run of the review, and a wrongly
25
+ // allowed one ships a diff nobody read. Thrown rather than reported, so no `completion` Telegram is
26
+ // sent and nothing merges — `git_pr_followup.run` is never reached.
27
+ // `ok` means the guard was satisfied and `not-required` means it never applied to this checkout —
28
+ // both let the merge proceed, so the two gates below read the verdict through one predicate rather
29
+ // than repeating the pair of statuses.
30
+ function is_merge_permitted(status: string): boolean {
31
+ return status === 'ok' || status === 'not-required'
32
+ }
33
+
34
+ function is_valid_issue(issue_number: string | undefined): issue_number is string {
35
+ return issue_number !== undefined && issue_number_shape.ISSUE_NUMBER_PATTERN.test(issue_number)
36
+ }
37
+
38
+ async function assert_review_attested(should_merge: boolean): Promise<void> {
39
+ if (!should_merge) return
40
+
41
+ const verdict = await review_attest.check_here()
42
+
43
+ if (!is_merge_permitted(verdict.status)) throw new Error(review_attest.refusal_message(verdict))
44
+
45
+ const refusal = await issue_watch_gate.review_refusal_here()
46
+
47
+ if (refusal !== undefined) throw new Error(refusal)
48
+ }
49
+
50
+ // Recording a review round as a prose request leaves the recurrence ledger blind whenever it is
51
+ // skipped. **This is the seam where it is a gate instead**: a merge is refused unless the round left
52
+ // a `- rf:` line for its issue, a zero-finding `none` line included — and, for a change to the run
53
+ // tooling, unless the interaction review left its `- ri:` line too (joshuafolkken/kit#4276).
54
+ //
55
+ // **Absence is a refusal, `missing` exactly as `assert_review_attested`'s is** — the defect this
56
+ // exists for produces *no* line, so silence must not read as success. A checkout that keeps no ledger
57
+ // answers `not-required` and merges as before, and a run whose issue the followup cannot identify has
58
+ // no key to check, so it carries on rather than blocking on missing information.
59
+ async function assert_review_recorded(
60
+ should_merge: boolean,
61
+ issue_number: string | undefined,
62
+ ): Promise<void> {
63
+ if (!should_merge || !is_valid_issue(issue_number)) return
64
+
65
+ const issue = Number(issue_number)
66
+ const verdict = await review_record.check(issue)
67
+
68
+ if (!is_merge_permitted(verdict.status)) throw new Error(review_record.refusal_message(issue))
69
+
70
+ const refusal = await review_interaction.refusal(issue)
71
+
72
+ if (refusal !== undefined) throw new Error(refusal)
73
+ }
74
+
75
+ const followup_review_gates = {
76
+ assert_review_attested,
77
+ assert_review_recorded,
78
+ is_valid_issue,
79
+ }
80
+
81
+ export { followup_review_gates }
@@ -1,6 +1,7 @@
1
1
  import { PrConflictError } from '#scripts/gh/git-pr-checks-eval'
2
2
  import { lane_ledger } from '#scripts/lane/lane-ledger'
3
3
  import { time_format } from '#scripts/time-runtime/time-format'
4
+ import { followup_coderabbit_wait, type CodeRabbitWait } from './followup-coderabbit-wait'
4
5
 
5
6
  // Where `pnpm josh followup` spends its own wall clock.
6
7
  //
@@ -90,13 +91,17 @@ interface FollowupStage {
90
91
  // `last_ms` is `performance.now()`'s clock rather than `Date.now()`'s, for the reason
91
92
  // `buffered-process.ts` states: it is monotonic, so a system clock adjusted mid-wait cannot produce a
92
93
  // negative lap.
94
+ //
95
+ // `coderabbit` rides on the log because every check wait of the run — the merge gate's and the one the
96
+ // merge goes back to (#4036) — adds to the same CodeRabbit time.
93
97
  interface StageLog {
94
98
  stages: Array<FollowupStage>
95
99
  last_ms: number
100
+ coderabbit: CodeRabbitWait
96
101
  }
97
102
 
98
103
  function new_log(): StageLog {
99
- return { stages: [], last_ms: performance.now() }
104
+ return { stages: [], last_ms: performance.now(), coderabbit: followup_coderabbit_wait.new_wait() }
100
105
  }
101
106
 
102
107
  function lap(log: StageLog, name: string): void {
@@ -140,7 +145,7 @@ function print_stages(log: StageLog): void {
140
145
 
141
146
  // The wait for CI goes to the lane ledger as well, where `josh lane:stats` reads it beside the review
142
147
  // round it would overlap: the printed block reaches only this run's reader. A wait that threw is the
143
- // `interrupted` lap and records nothing here.
148
+ // `interrupted` lap and records nothing here. CodeRabbit's part of the waits goes beside it.
144
149
  async function record_ci_wait(log: StageLog): Promise<void> {
145
150
  const wait = log.stages.find((stage) => stage.name === STAGE.checks_wait)
146
151
 
@@ -152,6 +157,11 @@ async function record_ci_wait(log: StageLog): Promise<void> {
152
157
  })
153
158
  }
154
159
 
160
+ async function record_waits(log: StageLog): Promise<void> {
161
+ await record_ci_wait(log)
162
+ await followup_coderabbit_wait.record(log.coderabbit)
163
+ }
164
+
155
165
  const git_followup_stages = {
156
166
  STAGE,
157
167
  STAGE_LINE_PREFIX,
@@ -161,7 +171,7 @@ const git_followup_stages = {
161
171
  total_ms,
162
172
  format_stages,
163
173
  print_stages,
164
- record_ci_wait,
174
+ record_waits,
165
175
  stopped_lap,
166
176
  }
167
177