@joshuafolkken/kit 1.1514.0 → 1.1784.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (858) hide show
  1. package/.claude/agents/investigator.md +1 -1
  2. package/.claude/settings.json +5 -5
  3. package/.claude/skills/epic-commands/SKILL.md +26 -65
  4. package/.claude/skills/epic-commands/epic-bundle.md +3 -1
  5. package/.claude/skills/workflow-commands/SKILL.md +5 -5
  6. package/.claude/skills/workflow-commands/background-commands.md +5 -5
  7. package/.claude/skills/workflow-commands/backlogrun-child.md +10 -8
  8. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
  9. package/.claude/skills/workflow-commands/backlogrun-lanes.md +17 -13
  10. package/.claude/skills/workflow-commands/backlogrun-park.md +14 -23
  11. package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -2
  12. package/.claude/skills/workflow-commands/backlogrun-recovery.md +5 -5
  13. package/.claude/skills/workflow-commands/backlogrun-steps.md +10 -10
  14. package/.claude/skills/workflow-commands/backlogrun.md +1 -1
  15. package/.claude/skills/workflow-commands/chain-rule.md +13 -7
  16. package/.claude/skills/workflow-commands/delegation.md +6 -5
  17. package/.claude/skills/workflow-commands/entry-sequence.md +9 -9
  18. package/.claude/skills/workflow-commands/followup.md +9 -31
  19. package/.claude/skills/workflow-commands/fullrun-steps.md +36 -45
  20. package/.claude/skills/workflow-commands/fullrun.md +2 -2
  21. package/.claude/skills/workflow-commands/halfrun.md +17 -25
  22. package/.claude/skills/workflow-commands/issue-comments.md +16 -12
  23. package/.claude/skills/workflow-commands/issue-scout.md +2 -2
  24. package/.claude/skills/workflow-commands/kickoff.md +24 -23
  25. package/.claude/skills/workflow-commands/latest-gate.md +7 -12
  26. package/.claude/skills/workflow-commands/needs-human-review.md +9 -14
  27. package/.claude/skills/workflow-commands/observation-filing.md +4 -36
  28. package/.claude/skills/workflow-commands/observation-ledger.md +1 -1
  29. package/.claude/skills/workflow-commands/pre-gate-cut.md +13 -30
  30. package/.claude/skills/workflow-commands/prerequisite.md +10 -16
  31. package/.claude/skills/workflow-commands/progress-watcher.md +1 -1
  32. package/.claude/skills/workflow-commands/prrun.md +3 -7
  33. package/.claude/skills/workflow-commands/retrospective.md +1 -1
  34. package/.claude/skills/workflow-commands/split-assessment.md +13 -1
  35. package/.claude/skills/workflow-commands/working-tree-hold.md +9 -9
  36. package/.codex/hooks.json +5 -5
  37. package/.github/actions/setup-node/action.yml +9 -0
  38. package/.github/actions/setup-pnpm/action.yml +1 -1
  39. package/.github/dependabot.yml +16 -0
  40. package/.github/release.yml +0 -2
  41. package/.github/workflows/ci.yml +120 -10
  42. package/.github/workflows/publish.yml +8 -1
  43. package/.github/workflows/sonar-qube.yml +1 -0
  44. package/.prettierignore +2 -0
  45. package/.vscode/tasks.json +1 -2
  46. package/CLAUDE.md +3 -7
  47. package/README.md +4 -2
  48. package/SECURITY.md +1 -1
  49. package/dist/CLAUDE.md +3 -7
  50. package/dist/commands/document-read-cli.js +882 -0
  51. package/dist/commands/{document-section-cli.js → document-section-main.js} +79 -37
  52. package/dist/commands/read-set-cli.js +1867 -0
  53. package/dist/commands/run-prep-main.js +21653 -0
  54. package/dist/commands/run-step-cli.js +23880 -0
  55. package/dist/config-merge/index.js +5 -1
  56. package/dist/hooks/audit-provision.js +20 -35
  57. package/dist/hooks/{chunk-DGT54IH5.js → chunk-AZX4FGQ3.js} +63 -17
  58. package/dist/hooks/chunk-CWMBGKYW.js +6483 -0
  59. package/dist/hooks/chunk-O2YBIDSI.js +4306 -0
  60. package/dist/hooks/{chunk-TNUMY6NL.js → chunk-PT5R6UJD.js} +4193 -1900
  61. package/dist/hooks/chunk-TUIFS5E7.js +72 -0
  62. package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
  63. package/dist/hooks/{chunk-APUO6U4J.js → chunk-WR2KQAYZ.js} +1843 -440
  64. package/dist/hooks/{chunk-O6GDRNJB.js → chunk-XGBNSWEI.js} +248 -46
  65. package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
  66. package/dist/hooks/codex-hook-adapter.js +10 -22
  67. package/dist/hooks/format-edited.js +5 -6
  68. package/dist/hooks/inputs.json +443 -317
  69. package/dist/hooks/pretool-guard.js +7 -25
  70. package/dist/hooks/session-lang.js +44 -51
  71. package/dist/hooks/stop-guard.js +7716 -2187
  72. package/dist/josh.js +6002 -3583
  73. package/dist/self-sync-guard/index.js +74 -10
  74. package/dist/version/index.js +115 -406
  75. package/eslint/base.js +1 -1
  76. package/lefthook/base.yml +3 -1
  77. package/package.json +10 -48
  78. package/pnpm-workspace.yaml +4 -2
  79. package/prompts/coding-standards.md +1 -1
  80. package/prompts/collaboration-workflow/file-edits.md +1 -7
  81. package/prompts/collaboration-workflow/issue-citation.md +1 -1
  82. package/prompts/collaboration-workflow/issue-template.md +33 -16
  83. package/prompts/collaboration-workflow/lane-instructions.md +1 -2
  84. package/prompts/collaboration-workflow/measurement.md +37 -0
  85. package/prompts/collaboration-workflow/operating-rules.md +4 -6
  86. package/prompts/collaboration-workflow/output-bounds.md +2 -7
  87. package/prompts/collaboration-workflow/plan-comment.md +3 -42
  88. package/prompts/collaboration-workflow/principles.md +5 -0
  89. package/prompts/collaboration-workflow/report-format.md +31 -60
  90. package/prompts/collaboration-workflow/residency.md +2 -2
  91. package/prompts/collaboration-workflow/shell-body.md +6 -16
  92. package/prompts/collaboration-workflow/turn-batching.md +0 -2
  93. package/prompts/collaboration-workflow/upstream-interrupt.md +14 -4
  94. package/prompts/collaboration-workflow/wip-cap.md +1 -1
  95. package/prompts/collaboration-workflow.md +3 -7
  96. package/prompts/refactoring.md +1 -1
  97. package/prompts/review-rubric.md +1 -2
  98. package/prompts/review.md +41 -21
  99. package/prompts/testing-guide.md +8 -43
  100. package/scripts/agent/agent-event.ts +15 -15
  101. package/scripts/agent/agent-exit-record.ts +13 -1
  102. package/scripts/agent/api-auth.ts +41 -0
  103. package/scripts/agent/api-outage.ts +1 -1
  104. package/scripts/auto-ok/auto-ok-cli.ts +14 -16
  105. package/scripts/auto-ok/auto-ok-judge-read.ts +12 -3
  106. package/scripts/auto-ok/auto-ok-judge-write.ts +46 -19
  107. package/scripts/auto-ok/auto-ok-judge.ts +13 -2
  108. package/scripts/auto-ok/auto-ok-main.ts +17 -0
  109. package/scripts/backlog/backlog-arrival.ts +14 -3
  110. package/scripts/backlog/backlog-budget-cli.ts +7 -33
  111. package/scripts/backlog/backlog-budget-main.ts +16 -0
  112. package/scripts/backlog/backlog-budget.ts +2 -3
  113. package/scripts/backlog/backlog-defect-priority.ts +4 -3
  114. package/scripts/backlog/backlog-drive-adopt.ts +67 -0
  115. package/scripts/backlog/backlog-drive-args.ts +4 -5
  116. package/scripts/backlog/backlog-drive-cli.ts +113 -28
  117. package/scripts/backlog/backlog-drive-hold.ts +162 -0
  118. package/scripts/backlog/backlog-drive-idle.ts +151 -0
  119. package/scripts/backlog/backlog-drive-judge.ts +25 -0
  120. package/scripts/backlog/backlog-drive-memory.ts +126 -0
  121. package/scripts/backlog/backlog-drive-named-offer.ts +5 -10
  122. package/scripts/backlog/backlog-drive-named.ts +53 -6
  123. package/scripts/backlog/backlog-drive-offer-argv.ts +3 -8
  124. package/scripts/backlog/backlog-drive-paused.ts +169 -0
  125. package/scripts/backlog/backlog-drive-restore.ts +30 -7
  126. package/scripts/backlog/backlog-drive-seats.ts +18 -8
  127. package/scripts/backlog/backlog-drive-token-handling.ts +38 -0
  128. package/scripts/backlog/backlog-drive.ts +79 -75
  129. package/scripts/backlog/backlog-next-main.ts +16 -0
  130. package/scripts/backlog/backlog-next-shared.ts +73 -0
  131. package/scripts/backlog/backlog-next.ts +48 -16
  132. package/scripts/backlog/backlog-occupied.ts +52 -39
  133. package/scripts/backlog/backlog-offer-cli.ts +6 -21
  134. package/scripts/backlog/backlog-offer-exclude.ts +15 -0
  135. package/scripts/backlog/backlog-offer-main.ts +12 -0
  136. package/scripts/backlog/backlog-offer.ts +36 -3
  137. package/scripts/backlog/backlog-overlap.ts +22 -4
  138. package/scripts/backlog/backlog-plan-read.ts +6 -2
  139. package/scripts/backlog/backlog-plan.ts +18 -4
  140. package/scripts/backlog/backlog-pool.ts +10 -10
  141. package/scripts/backlog/backlog-rank.ts +10 -2
  142. package/scripts/backlog/backlog-ready.ts +112 -30
  143. package/scripts/backlog/backlog-stalled-detect.ts +109 -36
  144. package/scripts/backlog/backlog-stalled.ts +52 -16
  145. package/scripts/backlog/backlog-wait-cause.ts +86 -0
  146. package/scripts/backlog/backlog-waves.ts +39 -13
  147. package/scripts/backlog/backlogrun-args.ts +19 -7
  148. package/scripts/backlog/backlogrun-cli.ts +19 -5
  149. package/scripts/backlog/backlogrun-launch.ts +6 -0
  150. package/scripts/backlog/backlogrun-restart.ts +97 -0
  151. package/scripts/backlog/backlogrun-stop.ts +79 -7
  152. package/scripts/behavior/behavior-cli.ts +2 -2
  153. package/scripts/behavior/behavior-rules.ts +47 -24
  154. package/scripts/build/build-bin.ts +2 -16
  155. package/scripts/build/build-claude-md.ts +0 -7
  156. package/scripts/build/build-commands.ts +0 -13
  157. package/scripts/build/build-hooks.ts +49 -48
  158. package/scripts/build/hook-bundle-stamp.ts +29 -11
  159. package/scripts/build/local-bin.ts +1 -1
  160. package/scripts/cases/cases-cli.ts +25 -13
  161. package/scripts/cases/cases-interaction-scan.ts +134 -0
  162. package/scripts/cases/cases-interaction.ts +183 -0
  163. package/scripts/cases/cases-logic.ts +39 -6
  164. package/scripts/ci/pr-classification-main.ts +18 -0
  165. package/scripts/ci/pr-classification.ts +10 -17
  166. package/scripts/clone/clone-scan.ts +1 -1
  167. package/scripts/cost-runtime/cost-blocks.ts +22 -37
  168. package/scripts/cost-runtime/cost-cli.ts +31 -14
  169. package/scripts/cost-runtime/cost-main.ts +12 -0
  170. package/scripts/cost-runtime/cost-transcript.ts +1 -0
  171. package/scripts/delegation/delegation-policy.ts +17 -4
  172. package/scripts/delegation/duplicate-read-guard.ts +0 -8
  173. package/scripts/delegation/investigation-guard.ts +0 -8
  174. package/scripts/delegation/investigation-reads.ts +3 -4
  175. package/scripts/dependabot/dependabot-cooldown.ts +194 -0
  176. package/scripts/discovery/repo-discovery.ts +24 -6
  177. package/scripts/doctor/doctor-consumer.ts +2 -5
  178. package/scripts/document/document-byte-budget.ts +8 -6
  179. package/scripts/document/document-scan.ts +1 -1
  180. package/scripts/document/document-section-cli.ts +0 -8
  181. package/scripts/document/document-section-main.ts +12 -0
  182. package/scripts/epic/epic-audit-cli.ts +12 -6
  183. package/scripts/epic/epic-bundle-apply.ts +137 -0
  184. package/scripts/epic/epic-bundle-cli.ts +32 -121
  185. package/scripts/epic/epic-bundle-format.ts +116 -0
  186. package/scripts/epic/epic-bundle-main.ts +17 -0
  187. package/scripts/epic/epic-busy.ts +5 -12
  188. package/scripts/epic/epic-classify.ts +24 -15
  189. package/scripts/epic/epic-cli-argv.ts +31 -0
  190. package/scripts/epic/epic-cli-decide.ts +42 -0
  191. package/scripts/epic/epic-cli.ts +6 -38
  192. package/scripts/epic/epic-close.ts +112 -55
  193. package/scripts/epic/epic-cross-repo.ts +4 -7
  194. package/scripts/epic/epic-decide.ts +119 -0
  195. package/scripts/epic/epic-decision.ts +9 -0
  196. package/scripts/epic/epic-fetch.ts +4 -0
  197. package/scripts/epic/epic-graph.ts +2 -0
  198. package/scripts/epic/epic-issue.ts +5 -1
  199. package/scripts/epic/epic-label-age.ts +1 -1
  200. package/scripts/epic/epic-lane-offer.ts +39 -4
  201. package/scripts/epic/epic-next-main.ts +24 -0
  202. package/scripts/epic/epic-next.ts +6 -24
  203. package/scripts/epic/epic-outside-blocker.ts +6 -2
  204. package/scripts/epic/epic-parse.ts +9 -3
  205. package/scripts/epic/epic-read.ts +1 -0
  206. package/scripts/epic/epic-reconcile.ts +39 -0
  207. package/scripts/epic/epic-run.ts +10 -1
  208. package/scripts/epic/epic-solo.ts +50 -14
  209. package/scripts/epic/epic.ts +41 -7
  210. package/scripts/exports/unused-members-cli.ts +2 -2
  211. package/scripts/followup/followup-checks-event.ts +8 -3
  212. package/scripts/followup/followup-coderabbit-wait.ts +82 -0
  213. package/scripts/followup/followup-review-gates.ts +81 -0
  214. package/scripts/followup/git-followup-stages.ts +13 -3
  215. package/scripts/followup/git-followup-workflow.ts +19 -66
  216. package/scripts/followup/git-pr-followup-wrapup.ts +9 -14
  217. package/scripts/followup/git-pr-followup.ts +36 -8
  218. package/scripts/fresh-machine/fresh-machine-cli.ts +1 -1
  219. package/scripts/fresh-machine/fresh-machine-run.ts +8 -8
  220. package/scripts/fresh-machine/specs/kit-test-backlogrun.json +1 -1
  221. package/scripts/gate/busy-average.ts +58 -0
  222. package/scripts/gate/check-cpu.ts +60 -0
  223. package/scripts/gate/check-inputs.ts +39 -95
  224. package/scripts/gate/check-reuse.ts +33 -54
  225. package/scripts/gate/command-memory.ts +192 -0
  226. package/scripts/gate/core-admission.ts +218 -28
  227. package/scripts/gate/core-budget-timing.ts +37 -0
  228. package/scripts/gate/core-budget.ts +80 -98
  229. package/scripts/gate/core-wait-record.ts +48 -0
  230. package/scripts/gate/core-wait.ts +37 -5
  231. package/scripts/gate/core-weights.ts +86 -0
  232. package/scripts/gate/free-cores.ts +27 -4
  233. package/scripts/gate/gate-ledger.ts +32 -4
  234. package/scripts/gate/gate-plan.ts +41 -34
  235. package/scripts/gate/gate-report.ts +14 -2
  236. package/scripts/gate/gate-run-steps.ts +53 -8
  237. package/scripts/gate/gate-skip.ts +12 -2
  238. package/scripts/gate/gate-steps.ts +12 -1
  239. package/scripts/gate/input-fingerprint.ts +42 -0
  240. package/scripts/gate/machine-capacity.ts +65 -31
  241. package/scripts/gate/moved-paths.ts +67 -0
  242. package/scripts/gate/project-checks.ts +5 -12
  243. package/scripts/gate/scoped-green.ts +12 -8
  244. package/scripts/gate/since-green.ts +62 -0
  245. package/scripts/gate/toolchain-inputs.ts +115 -0
  246. package/scripts/gate/verification-gate.ts +27 -24
  247. package/scripts/gate/verification-inputs.ts +250 -0
  248. package/scripts/gh/gh-author-association.ts +96 -9
  249. package/scripts/gh/git-ai-review-scan.ts +4 -2
  250. package/scripts/gh/git-gh-api-path.ts +15 -0
  251. package/scripts/gh/git-gh-branch-rules.ts +73 -0
  252. package/scripts/gh/git-gh-conditional.ts +5 -2
  253. package/scripts/gh/git-gh-issue-read.ts +5 -1
  254. package/scripts/gh/git-gh-issue-write.ts +67 -29
  255. package/scripts/gh/git-gh-issue.ts +7 -3
  256. package/scripts/gh/git-gh-poll-read.ts +89 -0
  257. package/scripts/gh/git-gh-pr-auto-merge.ts +8 -3
  258. package/scripts/gh/git-gh-pr-rest.ts +1 -1
  259. package/scripts/gh/git-gh-pr-snapshot.ts +33 -20
  260. package/scripts/gh/git-gh-pr.ts +27 -15
  261. package/scripts/gh/git-pr-checks-eval.ts +39 -7
  262. package/scripts/gh/git-pr-checks-parse.ts +39 -9
  263. package/scripts/gh/git-pr-merge-checked.ts +80 -0
  264. package/scripts/git/base-tree.ts +19 -2
  265. package/scripts/git/changed-file-scope.ts +6 -4
  266. package/scripts/git/changed-paths.ts +18 -1
  267. package/scripts/git/git-diff-reads.ts +27 -2
  268. package/scripts/git/git-grep-hits.ts +85 -0
  269. package/scripts/git/git-location-environment.ts +1 -1
  270. package/scripts/git/git-merge-conflicts.ts +83 -0
  271. package/scripts/git/git-preflight.ts +37 -12
  272. package/scripts/git/git-push-transport.ts +1 -2
  273. package/scripts/git/git-schemas.ts +17 -7
  274. package/scripts/git/git-spawn.ts +1 -2
  275. package/scripts/git/git-status.ts +4 -4
  276. package/scripts/git/main-merge-main.ts +12 -0
  277. package/scripts/git/main-merge-regenerate.ts +2 -2
  278. package/scripts/git/main-merge.ts +25 -9
  279. package/scripts/git/main-sync-main.ts +12 -0
  280. package/scripts/git/main-sync.ts +0 -9
  281. package/scripts/git/stash/git-stash.ts +27 -4
  282. package/scripts/git/stash/{stash-pop-args.ts → stash-args.ts} +13 -10
  283. package/scripts/git/stash/stash-pop-cli.ts +6 -12
  284. package/scripts/git/stash/stash-pop-main.ts +12 -0
  285. package/scripts/git/stash/stash-push-cli.ts +76 -0
  286. package/scripts/git/stash/stash-push-main.ts +12 -0
  287. package/scripts/hooks/batch-guard.ts +0 -8
  288. package/scripts/hooks/check-commit-message-main.ts +8 -0
  289. package/scripts/hooks/check-commit-message.ts +4 -7
  290. package/scripts/hooks/format-edited-file.ts +8 -24
  291. package/scripts/hooks/pre-commit-lint.ts +30 -3
  292. package/scripts/hooks/pre-push-unit.ts +4 -2
  293. package/scripts/hooks/pretool-guard-cli.ts +1 -8
  294. package/scripts/hooks/pretool-guard.ts +32 -19
  295. package/scripts/hooks/reserved-run.ts +67 -9
  296. package/scripts/hooks/run-hook.sh +13 -4
  297. package/scripts/hooks/shell-rules-notice.ts +37 -0
  298. package/scripts/hooks/stop-actions.ts +2 -21
  299. package/scripts/hooks/stop-guard.ts +13 -9
  300. package/scripts/init/hook-command-rewrite.ts +19 -5
  301. package/scripts/init/hook-launch.ts +15 -17
  302. package/scripts/init/init-actions.ts +0 -6
  303. package/scripts/init/init-ai-copy.ts +10 -36
  304. package/scripts/init/init-bootstrap.ts +9 -8
  305. package/scripts/init/init-dry-run-report.ts +1 -1
  306. package/scripts/init/init-dry-run.ts +1 -1
  307. package/scripts/init/init-file-action.ts +7 -9
  308. package/scripts/init/init-logic-json-merge.ts +2 -2
  309. package/scripts/init/init-logic-migrate.ts +9 -82
  310. package/scripts/init/init-logic.ts +3 -2
  311. package/scripts/init/init-main.ts +12 -0
  312. package/scripts/init/init.ts +5 -12
  313. package/scripts/init/kit-development-versions.ts +3 -7
  314. package/scripts/init/kit-written-paths.ts +2 -2
  315. package/scripts/init/project-profile.ts +5 -4
  316. package/scripts/init/tsconfig-preset-migration.ts +2 -1
  317. package/scripts/init/vscode-tasks.ts +1 -1
  318. package/scripts/issue/defect-origin-cli.ts +106 -0
  319. package/scripts/issue/defect-origin-line.ts +60 -0
  320. package/scripts/issue/defect-origin-main.ts +11 -0
  321. package/scripts/issue/defect-origin.ts +114 -0
  322. package/scripts/issue/defect-rate-cli.ts +34 -78
  323. package/scripts/issue/defect-rate.ts +0 -16
  324. package/scripts/issue/defect-report-cli.ts +128 -0
  325. package/scripts/issue/defect-report-format.ts +56 -0
  326. package/scripts/issue/defect-report-main.ts +11 -0
  327. package/scripts/issue/defect-report.ts +160 -0
  328. package/scripts/issue/expected-effect-lint.ts +1 -0
  329. package/scripts/issue/issue-already-done-cli.ts +62 -0
  330. package/scripts/issue/issue-body-or-comment.ts +40 -0
  331. package/scripts/issue/issue-cite-cli.ts +0 -9
  332. package/scripts/issue/issue-cite-main.ts +12 -0
  333. package/scripts/issue/issue-classification.ts +12 -7
  334. package/scripts/issue/issue-comment-cli.ts +10 -24
  335. package/scripts/issue/issue-comment-main.ts +12 -0
  336. package/scripts/issue/issue-evidence-exit.ts +100 -0
  337. package/scripts/issue/issue-file-cli.ts +29 -7
  338. package/scripts/issue/issue-file.ts +19 -19
  339. package/scripts/issue/issue-fold-cli.ts +2 -11
  340. package/scripts/issue/issue-fold-main.ts +12 -0
  341. package/scripts/issue/issue-labels.ts +81 -90
  342. package/scripts/issue/issue-lint-cli.ts +2 -10
  343. package/scripts/issue/issue-lint-main.ts +12 -0
  344. package/scripts/issue/issue-measured-cli.ts +56 -0
  345. package/scripts/issue/issue-merged.ts +19 -2
  346. package/scripts/issue/issue-not-before-label.ts +135 -0
  347. package/scripts/issue/issue-not-before.ts +111 -0
  348. package/scripts/issue/issue-number-shape.ts +15 -1
  349. package/scripts/issue/issue-park.ts +28 -0
  350. package/scripts/issue/issue-plan-cli.ts +151 -0
  351. package/scripts/issue/issue-priority.ts +151 -0
  352. package/scripts/issue/issue-rank.ts +7 -1
  353. package/scripts/issue/issue-read-cli.ts +3 -10
  354. package/scripts/issue/issue-read-main.ts +12 -0
  355. package/scripts/issue/issue-read.ts +29 -5
  356. package/scripts/issue/issue-release-cli.ts +0 -10
  357. package/scripts/issue/issue-release-main.ts +13 -0
  358. package/scripts/issue/issue-release.ts +7 -12
  359. package/scripts/issue/issue-sample-gate.ts +192 -0
  360. package/scripts/issue/issue-sample-source.ts +76 -0
  361. package/scripts/issue/issue-scout-cli.ts +0 -11
  362. package/scripts/issue/issue-scout-main.ts +14 -0
  363. package/scripts/issue/issue-state-cli.ts +0 -10
  364. package/scripts/issue/issue-state-main.ts +12 -0
  365. package/scripts/issue/issue-watch-diff.ts +56 -15
  366. package/scripts/issue/issue-watch.ts +2 -1
  367. package/scripts/issue/issue-wip.ts +2 -7
  368. package/scripts/issue/measure-rerun-cli.ts +13 -8
  369. package/scripts/issue/plan-consumers-cli.ts +39 -0
  370. package/scripts/issue/plan-consumers-main.ts +11 -0
  371. package/scripts/issue/plan-consumers-section.ts +55 -0
  372. package/scripts/issue/plan-consumers.ts +127 -0
  373. package/scripts/josh/agent-session-environment.ts +1 -1
  374. package/scripts/josh/command-usage.ts +15 -43
  375. package/scripts/josh/file-map-stamp.ts +49 -16
  376. package/scripts/josh/hook-decision.ts +32 -20
  377. package/scripts/josh/josh-command-map.ts +4 -1
  378. package/scripts/josh/josh-command-types.ts +12 -6
  379. package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
  380. package/scripts/josh/josh-commands-ai.ts +157 -158
  381. package/scripts/josh/josh-commands-backlog.ts +82 -16
  382. package/scripts/josh/josh-commands-clone.ts +1 -0
  383. package/scripts/josh/josh-commands-development.ts +111 -71
  384. package/scripts/josh/josh-commands-document.ts +43 -1
  385. package/scripts/josh/josh-commands-epic.ts +171 -0
  386. package/scripts/josh/josh-commands-hooks.ts +25 -2
  387. package/scripts/josh/josh-commands-issue-write.ts +181 -0
  388. package/scripts/josh/josh-commands-issue.ts +124 -24
  389. package/scripts/josh/josh-commands-lane.ts +103 -2
  390. package/scripts/josh/josh-commands-lint.ts +19 -8
  391. package/scripts/josh/josh-commands-maintenance.ts +112 -4
  392. package/scripts/josh/josh-commands-pause.ts +29 -0
  393. package/scripts/josh/josh-commands-progress.ts +87 -0
  394. package/scripts/josh/josh-commands-project.ts +138 -9
  395. package/scripts/josh/josh-commands-review.ts +124 -0
  396. package/scripts/josh/josh-commands-run.ts +211 -23
  397. package/scripts/josh/josh-commands-ship.ts +169 -0
  398. package/scripts/josh/josh-commands-split.ts +9 -0
  399. package/scripts/josh/josh-commands-versioning.ts +49 -2
  400. package/scripts/josh/josh-commands-workflow.ts +144 -6
  401. package/scripts/josh/josh-logic.ts +6 -13
  402. package/scripts/josh/package-directory.ts +2 -4
  403. package/scripts/josh/process-identity.ts +13 -4
  404. package/scripts/josh/session-language-cli.ts +4 -8
  405. package/scripts/josh/session-language-main.ts +13 -0
  406. package/scripts/josh/session-language.ts +6 -1
  407. package/scripts/josh/shared-cache.ts +90 -0
  408. package/scripts/josh/stamp-file.ts +9 -15
  409. package/scripts/lane/lane-await.ts +51 -12
  410. package/scripts/lane/lane-cache.ts +5 -30
  411. package/scripts/lane/lane-capacity.ts +14 -23
  412. package/scripts/lane/lane-check-stats.ts +62 -21
  413. package/scripts/lane/lane-child-invocation.ts +8 -0
  414. package/scripts/lane/lane-cli.ts +15 -5
  415. package/scripts/lane/lane-close.ts +86 -18
  416. package/scripts/lane/lane-core-wait-stats.ts +66 -0
  417. package/scripts/lane/lane-dispatch.ts +24 -3
  418. package/scripts/lane/lane-gap-stats.ts +156 -0
  419. package/scripts/lane/lane-handoff.ts +69 -1
  420. package/scripts/lane/lane-held-stats.ts +129 -0
  421. package/scripts/lane/lane-install.ts +4 -11
  422. package/scripts/lane/lane-launch-cli.ts +0 -9
  423. package/scripts/lane/lane-launch-main.ts +12 -0
  424. package/scripts/lane/lane-ledger-schema.ts +266 -0
  425. package/scripts/lane/lane-ledger.ts +92 -123
  426. package/scripts/lane/lane-limit-cli.ts +12 -1
  427. package/scripts/lane/lane-measure-cli.ts +57 -11
  428. package/scripts/lane/lane-open.ts +9 -1
  429. package/scripts/lane/lane-parked.ts +3 -3
  430. package/scripts/lane/lane-pause-cli.ts +130 -0
  431. package/scripts/lane/lane-pause.ts +158 -0
  432. package/scripts/lane/lane-process-table.ts +166 -0
  433. package/scripts/lane/lane-reap-settle.ts +124 -0
  434. package/scripts/lane/lane-reap.ts +50 -15
  435. package/scripts/lane/lane-registry.ts +24 -3
  436. package/scripts/lane/lane-residents.ts +162 -0
  437. package/scripts/lane/lane-restart.ts +22 -2
  438. package/scripts/lane/lane-round-two-stats.ts +49 -0
  439. package/scripts/lane/lane-sampler.ts +4 -0
  440. package/scripts/lane/lane-session-action.ts +19 -5
  441. package/scripts/lane/lane-session-broker.ts +102 -21
  442. package/scripts/lane/lane-snapshot-trace.ts +84 -0
  443. package/scripts/lane/lane-spans.ts +51 -0
  444. package/scripts/lane/lane-spent.ts +6 -3
  445. package/scripts/lane/lane-stage-stats.ts +7 -2
  446. package/scripts/lane/lane-state.ts +302 -0
  447. package/scripts/lane/lane-stats.ts +58 -4
  448. package/scripts/lane/lane-stop-stats.ts +113 -37
  449. package/scripts/lane/lane-test-related-stats.ts +127 -0
  450. package/scripts/lane/lane-transcript-calls.ts +145 -0
  451. package/scripts/lane/lane-transcript-stats.ts +168 -0
  452. package/scripts/lane/lane-vacant.ts +13 -3
  453. package/scripts/lane/lane-withdraw-cli.ts +5 -4
  454. package/scripts/lane/lane-withdraw.ts +50 -49
  455. package/scripts/lane/process-directories.ts +70 -0
  456. package/scripts/lane/process-lane-marks.ts +94 -0
  457. package/scripts/lib/atomic-write.ts +62 -0
  458. package/scripts/lib/buffered-process.ts +12 -5
  459. package/scripts/lib/cli-flags.ts +53 -0
  460. package/scripts/lib/figure-format.ts +63 -0
  461. package/scripts/lib/json-value.ts +9 -1
  462. package/scripts/lib/package-manifest.ts +35 -0
  463. package/scripts/lib/read-file.ts +3 -1
  464. package/scripts/lib/stamped-memo.ts +63 -0
  465. package/scripts/lib/stdout-on-stderr.ts +24 -0
  466. package/scripts/lib/timeouts.ts +9 -0
  467. package/scripts/lib/transcript-record.ts +91 -0
  468. package/scripts/lines/effective-limit.ts +1 -1
  469. package/scripts/lint/eslint-cache-dependencies.ts +145 -0
  470. package/scripts/lint/eslint-daemon.ts +265 -0
  471. package/scripts/lint/format.ts +11 -2
  472. package/scripts/lint/import-graph.ts +279 -0
  473. package/scripts/lint/lint-gate-scope.ts +102 -0
  474. package/scripts/lint/lint-parallel-main.ts +19 -0
  475. package/scripts/lint/lint-parallel.ts +62 -30
  476. package/scripts/lint/lint-related-scope.ts +30 -24
  477. package/scripts/lint/lint-related.ts +38 -6
  478. package/scripts/notify/confirmation-options.ts +1 -2
  479. package/scripts/notify/telegram-notify.ts +20 -20
  480. package/scripts/notify/telegram-test-logic.ts +0 -1
  481. package/scripts/notify/telegram-test-main.ts +8 -0
  482. package/scripts/notify/telegram-test.ts +2 -6
  483. package/scripts/observations/observation-ledger.ts +13 -0
  484. package/scripts/observations/observations-flush-landing.ts +5 -3
  485. package/scripts/observations/observations-flush.ts +6 -1
  486. package/scripts/overrides/overrides-check.ts +2 -5
  487. package/scripts/overrides/overrides-files.ts +2 -1
  488. package/scripts/overrides/overrides-logic.ts +3 -6
  489. package/scripts/package/verify-optional-eslint-install.ts +8 -6
  490. package/scripts/propagate/propagate-publish.ts +2 -7
  491. package/scripts/propagate/propagate-targets.ts +4 -12
  492. package/scripts/refactor/import-graph.ts +9 -7
  493. package/scripts/release/github-release-runs.ts +17 -6
  494. package/scripts/release/release-approval-prune.ts +18 -0
  495. package/scripts/release/release-history.ts +1 -3
  496. package/scripts/release/release-progress.ts +42 -22
  497. package/scripts/release/release-publish-run.ts +39 -0
  498. package/scripts/release/release-publish.ts +6 -6
  499. package/scripts/release/release-scope-cli.ts +0 -10
  500. package/scripts/release/release-scope-main.ts +12 -0
  501. package/scripts/repo/repo-setting.ts +3 -6
  502. package/scripts/repo/required-checks-logic.ts +6 -15
  503. package/scripts/report/report-format-reference.ts +2 -0
  504. package/scripts/report/report-labels.ts +155 -0
  505. package/scripts/report/report-lint-cli.ts +3 -0
  506. package/scripts/report/report-lint.ts +85 -110
  507. package/scripts/report/report-template-cli.ts +59 -0
  508. package/scripts/report/report-template.ts +112 -0
  509. package/scripts/review/acceptance-map.ts +1 -0
  510. package/scripts/review/removed-tests-check.ts +86 -0
  511. package/scripts/review/removed-tests.ts +149 -0
  512. package/scripts/review/review-brief-cli.ts +81 -15
  513. package/scripts/review/review-brief-main.ts +12 -0
  514. package/scripts/review/review-brief.ts +31 -3
  515. package/scripts/review/review-code-tree.ts +10 -6
  516. package/scripts/review/review-comment-round.ts +26 -8
  517. package/scripts/review/review-finding-ledger.ts +30 -15
  518. package/scripts/review/review-interaction.ts +94 -0
  519. package/scripts/review/review-readers-scan.ts +163 -0
  520. package/scripts/review/review-record-cli.ts +69 -30
  521. package/scripts/review/review-record-main.ts +12 -0
  522. package/scripts/review/review-round-one-blobs.ts +221 -0
  523. package/scripts/review/review-round2-cli.ts +49 -12
  524. package/scripts/review/review-round2.ts +80 -12
  525. package/scripts/review/review-stamps.ts +19 -1
  526. package/scripts/review/review-stop-log.ts +96 -0
  527. package/scripts/review/review-stops-cli.ts +85 -0
  528. package/scripts/review/review-tree.ts +6 -17
  529. package/scripts/review/review-untouched-readers.ts +146 -0
  530. package/scripts/review/test-titles.ts +118 -0
  531. package/scripts/rules/agent-model.ts +8 -0
  532. package/scripts/rules/bash-triggers.ts +46 -3
  533. package/scripts/rules/decision-oracle-batch.ts +9 -1
  534. package/scripts/rules/decision-oracle.ts +2 -2
  535. package/scripts/rules/delivered-rules.ts +80 -2
  536. package/scripts/rules/destructive-command.ts +8 -1
  537. package/scripts/rules/direct-filing.ts +10 -2
  538. package/scripts/rules/direct-issue-comment.ts +117 -0
  539. package/scripts/rules/direct-pr-create.ts +69 -3
  540. package/scripts/rules/early-heartbeat.ts +2 -1
  541. package/scripts/rules/file-body.ts +7 -0
  542. package/scripts/rules/filing-cap.ts +7 -0
  543. package/scripts/rules/git-argv.ts +72 -14
  544. package/scripts/rules/git-force.ts +12 -2
  545. package/scripts/rules/guard-remedy.ts +4 -0
  546. package/scripts/rules/implementation-cut-verdict.ts +1 -1
  547. package/scripts/rules/implementation-cut.ts +11 -3
  548. package/scripts/rules/index-guard.ts +8 -1
  549. package/scripts/rules/issue-comments.ts +9 -1
  550. package/scripts/rules/josh-git-bare.ts +7 -0
  551. package/scripts/rules/lane-background.ts +67 -25
  552. package/scripts/rules/lane-carry-conflict.ts +6 -0
  553. package/scripts/rules/lane-direct-tool.ts +74 -0
  554. package/scripts/rules/lane-interactive-ask.ts +9 -2
  555. package/scripts/rules/lane-park.ts +45 -23
  556. package/scripts/rules/lane-split-park.ts +10 -2
  557. package/scripts/rules/lane-switch-main.ts +7 -0
  558. package/scripts/rules/oracle-consulted.ts +10 -0
  559. package/scripts/rules/oracle-firing.ts +1 -0
  560. package/scripts/rules/permission-guards.ts +3 -0
  561. package/scripts/rules/piped-verification.ts +1 -1
  562. package/scripts/rules/poll-loop.ts +7 -0
  563. package/scripts/rules/pr-merge.ts +123 -0
  564. package/scripts/rules/protected-files.ts +32 -5
  565. package/scripts/rules/raw-field-body.ts +6 -0
  566. package/scripts/rules/rule-body-guard.ts +8 -0
  567. package/scripts/rules/rule-list.ts +9 -28
  568. package/scripts/rules/rule-value-cache.ts +4 -9
  569. package/scripts/rules/rule-value-cli.ts +51 -32
  570. package/scripts/rules/rule-value.ts +1 -1
  571. package/scripts/rules/shell-segments.ts +35 -0
  572. package/scripts/rules/stop-rule-rows.ts +64 -0
  573. package/scripts/rules/stop-rules.ts +3 -4
  574. package/scripts/rules/test-declared-commit.ts +11 -1
  575. package/scripts/rules/third-party-write.ts +7 -0
  576. package/scripts/rules/timed-rerun.ts +69 -0
  577. package/scripts/rules/worktree-guard.ts +13 -3
  578. package/scripts/run/board/run-board-app-name.ts +23 -0
  579. package/scripts/run/board/run-board-cli.ts +65 -32
  580. package/scripts/run/board/run-board-earlier.ts +94 -0
  581. package/scripts/run/board/run-board-ending-reason.ts +67 -0
  582. package/scripts/run/board/run-board-estimate-schedule.ts +103 -0
  583. package/scripts/run/board/run-board-estimate.ts +98 -0
  584. package/scripts/run/board/run-board-fit.ts +153 -36
  585. package/scripts/run/board/run-board-fold.ts +123 -0
  586. package/scripts/run/board/run-board-fresh.ts +2 -2
  587. package/scripts/run/board/run-board-gather-live.ts +29 -0
  588. package/scripts/run/board/run-board-gather-thread.ts +189 -0
  589. package/scripts/run/board/run-board-gather-worker.ts +29 -0
  590. package/scripts/run/board/run-board-gather.ts +187 -0
  591. package/scripts/run/board/run-board-github.ts +118 -38
  592. package/scripts/run/board/run-board-header.ts +82 -20
  593. package/scripts/run/board/run-board-keys.ts +58 -0
  594. package/scripts/run/board/run-board-kind.ts +20 -6
  595. package/scripts/run/board/run-board-labels.ts +116 -71
  596. package/scripts/run/board/run-board-lane-state.ts +109 -0
  597. package/scripts/run/board/run-board-lane-time.ts +122 -0
  598. package/scripts/run/board/run-board-layout.ts +239 -60
  599. package/scripts/run/board/run-board-length.ts +52 -0
  600. package/scripts/run/board/run-board-machine.ts +8 -4
  601. package/scripts/run/board/run-board-main.ts +12 -0
  602. package/scripts/run/board/run-board-notes.ts +52 -31
  603. package/scripts/run/board/run-board-now.ts +1 -1
  604. package/scripts/run/board/run-board-operation.ts +15 -33
  605. package/scripts/run/board/run-board-phase.ts +1 -1
  606. package/scripts/run/board/run-board-plan-shared.ts +115 -0
  607. package/scripts/run/board/run-board-plan.ts +55 -3
  608. package/scripts/run/board/run-board-planning.ts +45 -0
  609. package/scripts/run/board/run-board-priority.ts +44 -0
  610. package/scripts/run/board/run-board-process-groups.ts +195 -0
  611. package/scripts/run/board/run-board-read.ts +151 -27
  612. package/scripts/run/board/run-board-reason.ts +235 -51
  613. package/scripts/run/board/run-board-released.ts +35 -0
  614. package/scripts/run/board/run-board-render-checks.ts +39 -5
  615. package/scripts/run/board/run-board-render-condition.ts +96 -0
  616. package/scripts/run/board/run-board-render-drawn.ts +67 -0
  617. package/scripts/run/board/run-board-render-foot.ts +59 -0
  618. package/scripts/run/board/run-board-render-icon.ts +35 -0
  619. package/scripts/run/board/run-board-render-lanes.ts +145 -0
  620. package/scripts/run/board/run-board-render-lead.ts +80 -0
  621. package/scripts/run/board/run-board-render-legend.ts +117 -48
  622. package/scripts/run/board/run-board-render-notes.ts +156 -29
  623. package/scripts/run/board/run-board-render-processes.ts +196 -0
  624. package/scripts/run/board/run-board-render-section.ts +119 -0
  625. package/scripts/run/board/run-board-render-slot.ts +3 -36
  626. package/scripts/run/board/run-board-render-tail.ts +115 -48
  627. package/scripts/run/board/run-board-render-time.ts +56 -0
  628. package/scripts/run/board/run-board-render-title.ts +117 -24
  629. package/scripts/run/board/run-board-render-waits.ts +104 -20
  630. package/scripts/run/board/run-board-render.ts +207 -265
  631. package/scripts/run/board/run-board-roots.ts +54 -0
  632. package/scripts/run/board/run-board-row-yield.ts +9 -4
  633. package/scripts/run/board/run-board-setup.ts +1 -12
  634. package/scripts/run/board/run-board-snapshot.ts +111 -0
  635. package/scripts/run/board/run-board-spin.ts +2 -2
  636. package/scripts/run/board/run-board-state.ts +22 -33
  637. package/scripts/run/board/run-board-status.ts +147 -71
  638. package/scripts/run/board/run-board-thanks-read.ts +2 -2
  639. package/scripts/run/board/run-board-tick.ts +122 -107
  640. package/scripts/run/board/run-board-usage-board.ts +78 -0
  641. package/scripts/run/board/run-board-usage-lanes.ts +113 -0
  642. package/scripts/run/board/run-board-usage-listing.ts +93 -0
  643. package/scripts/run/board/run-board-usage-read.ts +120 -150
  644. package/scripts/run/board/run-board-usage-rusage.ts +19 -7
  645. package/scripts/run/board/run-board-usage-text.ts +139 -51
  646. package/scripts/run/board/run-board-usage-top.ts +102 -0
  647. package/scripts/run/board/run-board-usage.ts +89 -72
  648. package/scripts/run/board/run-board-usual.ts +20 -9
  649. package/scripts/run/carry/run-carry-args.ts +4 -7
  650. package/scripts/run/carry/run-carry-conversation.ts +1 -1
  651. package/scripts/run/carry/run-carry.ts +9 -4
  652. package/scripts/run/cut/run-cut-handoff.ts +2 -2
  653. package/scripts/run/event/run-event-cli.ts +1 -5
  654. package/scripts/run/event/run-event-filed.ts +12 -6
  655. package/scripts/run/event/run-event-follow.ts +2 -3
  656. package/scripts/run/event/run-event-render.ts +6 -10
  657. package/scripts/run/event/run-event-scope.ts +2 -2
  658. package/scripts/run/event/run-event-stream-emit.ts +82 -22
  659. package/scripts/run/event/run-event-stream.ts +34 -8
  660. package/scripts/run/hold/run-hold-adopt.ts +65 -0
  661. package/scripts/run/hold/run-hold-cli.ts +93 -22
  662. package/scripts/run/hold/run-hold-main.ts +12 -0
  663. package/scripts/run/hold/run-hold-member.ts +37 -0
  664. package/scripts/run/hold/run-stop-notify.ts +183 -0
  665. package/scripts/run/merge/run-merge-auth.ts +31 -0
  666. package/scripts/run/merge/run-merge-cli.ts +62 -48
  667. package/scripts/run/merge/run-merge-close.ts +74 -0
  668. package/scripts/run/merge/run-merge-collect.ts +6 -13
  669. package/scripts/run/merge/run-merge-driver.ts +71 -0
  670. package/scripts/run/merge/run-merge-main.ts +12 -0
  671. package/scripts/run/merge/run-merge-outcome.ts +23 -0
  672. package/scripts/run/merge/run-merge-restart.ts +39 -0
  673. package/scripts/run/merge/run-merge-ship.ts +20 -4
  674. package/scripts/run/merge/run-merge-signals.ts +33 -9
  675. package/scripts/run/merge/run-merge-steps.ts +120 -85
  676. package/scripts/run/merge/run-merge.ts +38 -37
  677. package/scripts/run/park/run-park-cli.ts +91 -0
  678. package/scripts/run/park/run-park.ts +88 -0
  679. package/scripts/run/park/run-stalled.ts +68 -0
  680. package/scripts/run/pause/run-pause-cli.ts +73 -0
  681. package/scripts/run/pause/run-pause.ts +251 -0
  682. package/scripts/run/progress/run-progress-cli.ts +4 -12
  683. package/scripts/run/progress/run-progress-clock.ts +1 -1
  684. package/scripts/run/progress/run-progress-config.ts +6 -14
  685. package/scripts/run/progress/run-progress-main.ts +12 -0
  686. package/scripts/run/progress/run-progress.ts +1 -4
  687. package/scripts/run/review/run-review.ts +2 -1
  688. package/scripts/run/run-ending.ts +1 -0
  689. package/scripts/run/run-invocation.ts +5 -6
  690. package/scripts/run/run-liveness-cli.ts +6 -8
  691. package/scripts/run/run-liveness.ts +60 -29
  692. package/scripts/run/run-next.ts +1 -1
  693. package/scripts/run/run-parent-cut-hook.ts +2 -2
  694. package/scripts/run/run-preflight.ts +18 -3
  695. package/scripts/run/run-prep-cli.ts +1 -10
  696. package/scripts/run/run-prep-locate.ts +7 -50
  697. package/scripts/run/run-prep-main.ts +12 -0
  698. package/scripts/run/run-prep.ts +6 -0
  699. package/scripts/run/run-report-cli.ts +101 -13
  700. package/scripts/run/run-report-handoff.ts +114 -0
  701. package/scripts/run/run-step.ts +1 -1
  702. package/scripts/run/run-stranded-detect.ts +13 -0
  703. package/scripts/run/run-watcher-guard-cli.ts +1 -1
  704. package/scripts/run/run-watcher-guard.ts +1 -1
  705. package/scripts/run/ship/run-ship-args.ts +121 -0
  706. package/scripts/run/ship/run-ship-body-draft.ts +110 -0
  707. package/scripts/run/ship/run-ship-cli.ts +63 -140
  708. package/scripts/run/ship/run-ship-detach.ts +19 -8
  709. package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
  710. package/scripts/run/ship/run-ship-next.ts +18 -2
  711. package/scripts/run/ship/run-ship-overlap.ts +42 -5
  712. package/scripts/run/ship/run-ship-place.ts +96 -0
  713. package/scripts/run/ship/run-ship-pre-detach-timed.ts +43 -0
  714. package/scripts/run/ship/run-ship-pre-detach.ts +81 -24
  715. package/scripts/run/ship/run-ship-preflight.ts +137 -32
  716. package/scripts/run/ship/run-ship-probe.ts +11 -3
  717. package/scripts/run/ship/run-ship-relaunch-cap.ts +70 -0
  718. package/scripts/run/ship/run-ship-removed-rows.ts +61 -0
  719. package/scripts/run/ship/run-ship-return.ts +107 -23
  720. package/scripts/run/ship/run-ship-review-steps.ts +105 -151
  721. package/scripts/run/ship/run-ship-review.ts +73 -6
  722. package/scripts/run/ship/run-ship-reviewer.ts +207 -0
  723. package/scripts/run/ship/run-ship-stage.ts +55 -6
  724. package/scripts/run/ship/run-ship-steps.ts +46 -15
  725. package/scripts/run/ship/run-ship-stop-cause.ts +135 -0
  726. package/scripts/run/ship/run-ship-stop-text.ts +11 -6
  727. package/scripts/run/ship/run-ship-sync.ts +43 -6
  728. package/scripts/run/ship/run-ship.ts +30 -2
  729. package/scripts/run/tidy/run-tidy-cli.ts +0 -4
  730. package/scripts/run/tidy/run-tidy-lanes.ts +3 -0
  731. package/scripts/run/tidy/run-tidy-main.ts +8 -0
  732. package/scripts/run/wake/run-wake-cli.ts +119 -100
  733. package/scripts/run/wake/run-wake-code.ts +83 -0
  734. package/scripts/run/wake/run-wake-driver.ts +19 -8
  735. package/scripts/run/wake/run-wake-loop.ts +34 -3
  736. package/scripts/run/wake/run-wake-main.ts +13 -0
  737. package/scripts/run/wake/run-wake-ports.ts +90 -0
  738. package/scripts/run/wake/run-wake-takeover.ts +66 -0
  739. package/scripts/run/wake/run-wake.ts +2 -1
  740. package/scripts/safe-chain/pack-hook.ts +2 -2
  741. package/scripts/safe-chain/preinstall-command.ts +2 -1
  742. package/scripts/safe-chain/project-config.ts +3 -9
  743. package/scripts/security/security-audit-main.ts +8 -0
  744. package/scripts/security/security-audit-provision-logic.ts +0 -11
  745. package/scripts/security/security-audit-provision-main.ts +12 -0
  746. package/scripts/security/security-audit-provision.ts +11 -26
  747. package/scripts/security/security-audit.ts +6 -7
  748. package/scripts/self-sync-guard/self-sync-guard-logic.ts +6 -13
  749. package/scripts/split/split-assess-cli.ts +2 -2
  750. package/scripts/split/split-assess.ts +15 -0
  751. package/scripts/split/split-measure.ts +65 -0
  752. package/scripts/sync/claude-settings-merge.ts +8 -15
  753. package/scripts/sync/directory-copy-guard.ts +4 -9
  754. package/scripts/sync/file-content.ts +78 -8
  755. package/scripts/sync/sync-ai-files.ts +3 -5
  756. package/scripts/sync/sync-configs.ts +11 -23
  757. package/scripts/sync/sync-hook-safety.ts +4 -10
  758. package/scripts/sync/sync-main.ts +11 -0
  759. package/scripts/sync/sync.ts +25 -37
  760. package/scripts/test/test-declared-changed.ts +2 -2
  761. package/scripts/test/test-declared.ts +1 -1
  762. package/scripts/test/test-e2e-guard.ts +25 -1
  763. package/scripts/test/test-e2e-stamp.ts +38 -0
  764. package/scripts/test/test-pinned-logic.ts +145 -0
  765. package/scripts/test/test-pinned-main.ts +78 -0
  766. package/scripts/test/test-pinned.ts +100 -0
  767. package/scripts/test/test-read-map.ts +264 -0
  768. package/scripts/test/test-read-recording.ts +91 -0
  769. package/scripts/test/test-read-trace.ts +148 -0
  770. package/scripts/test/test-red-main.ts +12 -0
  771. package/scripts/test/test-red.ts +12 -30
  772. package/scripts/test/test-related-main.ts +18 -0
  773. package/scripts/test/test-related-record.ts +119 -0
  774. package/scripts/test/test-related-scope.ts +229 -43
  775. package/scripts/test/test-related.ts +300 -22
  776. package/scripts/test/test-unit-guard-main.ts +15 -0
  777. package/scripts/test/test-unit-guard.ts +42 -24
  778. package/scripts/test/unit-count-file.ts +37 -0
  779. package/scripts/test/unit-run-marker.ts +162 -0
  780. package/scripts/test/unit-setup-files.ts +51 -0
  781. package/scripts/test/unit-worker-share.ts +61 -149
  782. package/scripts/test/whole-suite-files.ts +63 -0
  783. package/scripts/time-runtime/time-background.ts +20 -2
  784. package/scripts/time-runtime/time-bundles.ts +4 -3
  785. package/scripts/time-runtime/time-density-hook.ts +8 -6
  786. package/scripts/time-runtime/time-followup-stage.ts +1 -3
  787. package/scripts/time-runtime/time-format.ts +5 -28
  788. package/scripts/time-runtime/time-markers.ts +10 -1
  789. package/scripts/time-runtime/time-shell.ts +97 -10
  790. package/scripts/time-runtime/time-transcript-line.ts +49 -62
  791. package/scripts/uninstall/uninstall.ts +1 -1
  792. package/scripts/version/bump-version-main.ts +12 -0
  793. package/scripts/version/bump-version.ts +25 -25
  794. package/scripts/version/effective-upstream.ts +6 -12
  795. package/scripts/version/latest-corepack.ts +17 -32
  796. package/scripts/version/latest-if-required-cli.ts +93 -0
  797. package/scripts/version/latest-lane-guard-main.ts +8 -0
  798. package/scripts/version/latest-lane-guard.ts +0 -4
  799. package/scripts/version/latest-scope-cli.ts +0 -9
  800. package/scripts/version/latest-scope-main.ts +12 -0
  801. package/scripts/version/latest-update.ts +5 -5
  802. package/scripts/version/npm-registry.ts +44 -6
  803. package/scripts/version/publishable-range-check.ts +5 -16
  804. package/scripts/version/release-age.ts +1 -1
  805. package/scripts/version/release-hold.ts +1 -1
  806. package/scripts/version/release-window.ts +38 -0
  807. package/scripts/version/running-binary.ts +1 -1
  808. package/scripts/version/safe-chain-version-update.ts +3 -8
  809. package/scripts/version/version-targets.ts +6 -28
  810. package/templates/dependabot.yml +29 -0
  811. package/templates/gitignore +4 -1
  812. package/templates/pnpm-workspace.basic.yaml +1 -1
  813. package/templates/sonar-project.properties +3 -2
  814. package/templates/workflows/ci.yml +12 -4
  815. package/templates/workflows/github-release.yml +4 -0
  816. package/tsconfig.sonar.json +1 -1
  817. package/.ncurc.json +0 -3
  818. package/dist/hooks/batch-guard.js +0 -29
  819. package/dist/hooks/chunk-4KKD2UTK.js +0 -66
  820. package/dist/hooks/chunk-6TS2JD6D.js +0 -237
  821. package/dist/hooks/chunk-7DSBJVFH.js +0 -50
  822. package/dist/hooks/chunk-A65Y4YOR.js +0 -79
  823. package/dist/hooks/chunk-CDY4NFQG.js +0 -15
  824. package/dist/hooks/chunk-EFXE6C37.js +0 -81
  825. package/dist/hooks/chunk-GP4IEC4O.js +0 -20
  826. package/dist/hooks/chunk-JP45SOCJ.js +0 -56
  827. package/dist/hooks/chunk-LAOV7NLM.js +0 -45
  828. package/dist/hooks/chunk-M4HGZV7U.js +0 -83
  829. package/dist/hooks/chunk-PF2NZL2A.js +0 -131
  830. package/dist/hooks/chunk-PTICX4OL.js +0 -358
  831. package/dist/hooks/chunk-RT27QRJW.js +0 -6247
  832. package/dist/hooks/chunk-SYOTDYCI.js +0 -3533
  833. package/dist/hooks/chunk-UPUZF3AN.js +0 -279
  834. package/dist/hooks/chunk-WK6SMBIC.js +0 -3180
  835. package/dist/hooks/duplicate-read-guard.js +0 -30
  836. package/dist/hooks/investigation-guard.js +0 -29
  837. package/scripts/backlog/backlog-stalled-cli.ts +0 -30
  838. package/scripts/cost-runtime/cost-format.ts +0 -29
  839. package/scripts/init/basic-path-migration.ts +0 -24
  840. package/scripts/issue/issue-backlinks-cli.ts +0 -93
  841. package/scripts/josh/josh-commands-guard.ts +0 -38
  842. package/scripts/josh/josh-usage-automation.ts +0 -121
  843. package/scripts/josh/josh-usage-backlog.ts +0 -180
  844. package/scripts/josh/josh-usage-developer.ts +0 -230
  845. package/scripts/josh/josh-usage-hooks.ts +0 -38
  846. package/scripts/josh/josh-usage-issue.ts +0 -205
  847. package/scripts/josh/josh-usage-review.ts +0 -101
  848. package/scripts/josh/josh-usage-run.ts +0 -252
  849. package/scripts/josh/josh-usage-session.ts +0 -238
  850. package/scripts/josh/josh-usage-workflow.ts +0 -212
  851. package/scripts/lint/cross-file-recheck.ts +0 -155
  852. package/scripts/registry-migration/migrate-logic.ts +0 -237
  853. package/scripts/registry-migration/migrate.ts +0 -292
  854. package/scripts/registry-migration/user-npmrc.ts +0 -15
  855. package/scripts/rules/rule-guard.ts +0 -23
  856. package/scripts/rules/rule-registry-rows.ts +0 -292
  857. package/scripts/rules/rule-registry.ts +0 -112
  858. package/scripts/run/run-stranded-cli.ts +0 -27
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env tsx
2
+ import { fileURLToPath } from 'node:url'
3
+ import { git_gh_issue_write } from '#scripts/gh/git-gh-issue-write'
4
+ import { issue_comment_cli, type CommentRequest } from '#scripts/issue/issue-comment-cli'
5
+ import { NEEDS_DECISION_LABEL } from '#scripts/issue/issue-labels'
6
+ import { issue_number_shape } from '#scripts/issue/issue-number-shape'
7
+ import { issue_park } from '#scripts/issue/issue-park'
8
+ import { session_cite } from '#scripts/issue/session-cite'
9
+ import { cli_flags } from '#scripts/lib/cli-flags'
10
+ import { run_park } from './run-park'
11
+
12
+ // `josh run:park <N> --body-file <path>` — park a lane child for a person's decision in one call: the
13
+ // question as a comment, `needs-decision`, and the local record the `lane-park` guard reads.
14
+ // `josh run:park <N> --clear` takes the park back off once the decision is recorded.
15
+ //
16
+ // **The park was two hand-typed commands, and a child could stop after either one**
17
+ // (joshuafolkken/kit#4132). One call writes both, and only a park that has both is recorded, so the
18
+ // guard falls silent on exactly the child that left a question behind.
19
+ //
20
+ // **`in-progress` and the hold are not this command's.** A parked child keeps `in-progress`, and every
21
+ // parked ending still owes `pnpm josh run:release <N>` (`backlogrun-park.md` → "park and continue").
22
+
23
+ const SUCCESS_EXIT_CODE = 0
24
+ const FAILURE_EXIT_CODE = 1
25
+ const ARGV_OFFSET = 2
26
+ const CLEAR_FLAG = '--clear'
27
+ const USAGE = `Usage: josh run:park <issue-number> --body-file <path> | <issue-number> ${CLEAR_FLAG}`
28
+ const CLEAR_OPTIONS = { clear: { type: 'boolean' } } as const
29
+
30
+ function clear_issue(argv: ReadonlyArray<string>): string | undefined {
31
+ const parsed = cli_flags.arguments_of(argv, CLEAR_OPTIONS)
32
+
33
+ if (parsed === undefined) return undefined
34
+
35
+ return issue_number_shape.single_of(parsed.positionals)
36
+ }
37
+
38
+ async function park(request: CommentRequest, directory: string): Promise<number> {
39
+ const { issue_number, body } = request
40
+ const write = await issue_park.apply(issue_number, NEEDS_DECISION_LABEL, body)
41
+ const is_parked = write.is_labelled && write.is_commented
42
+ const is_recorded = is_parked && run_park.record(issue_number, directory)
43
+
44
+ console.info(
45
+ `park ${session_cite.issue(issue_number)} — label: ${String(write.is_labelled)} · comment: ${String(write.is_commented)} · recorded: ${String(is_recorded)}`,
46
+ )
47
+
48
+ return is_parked ? SUCCESS_EXIT_CODE : FAILURE_EXIT_CODE
49
+ }
50
+
51
+ // **The record goes whatever the label answers**: the decision is a person's and already made, so a
52
+ // guard reading a stale park would only stay silent on the child's next stop.
53
+ async function clear(issue_number: string, directory: string): Promise<number> {
54
+ run_park.clear(issue_number, directory)
55
+ const is_cleared = await git_gh_issue_write.issue_clear_label(issue_number, NEEDS_DECISION_LABEL)
56
+
57
+ console.info(`park ${session_cite.issue(issue_number)} — cleared: ${String(is_cleared)}`)
58
+
59
+ return is_cleared ? SUCCESS_EXIT_CODE : FAILURE_EXIT_CODE
60
+ }
61
+
62
+ async function run_clear(argv: ReadonlyArray<string>, directory: string): Promise<number> {
63
+ const issue_number = clear_issue(argv)
64
+
65
+ if (issue_number !== undefined) return await clear(issue_number, directory)
66
+
67
+ console.error(USAGE)
68
+
69
+ return FAILURE_EXIT_CODE
70
+ }
71
+
72
+ async function run(
73
+ argv: ReadonlyArray<string>,
74
+ directory: string = process.cwd(),
75
+ ): Promise<number> {
76
+ if (argv.includes(CLEAR_FLAG)) return await run_clear(argv, directory)
77
+
78
+ const request = issue_comment_cli.resolve_request(argv, USAGE)
79
+
80
+ return request === undefined ? FAILURE_EXIT_CODE : await park(request, directory)
81
+ }
82
+
83
+ async function main(argv: ReadonlyArray<string>): Promise<void> {
84
+ process.exitCode = await run(argv)
85
+ }
86
+
87
+ const run_park_cli = { USAGE, run }
88
+
89
+ if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
90
+
91
+ export { run_park_cli }
@@ -0,0 +1,88 @@
1
+ import { backlog_budget } from '#scripts/backlog/backlog-budget'
2
+ import { git_common_directory } from '#scripts/git/git-common-directory'
3
+ import { stamp_file } from '#scripts/josh/stamp-file'
4
+ import { stamp_record, type StampRecordSpec } from '#scripts/josh/stamp-record'
5
+ import { json_value } from '#scripts/lib/json-value'
6
+ import { z } from 'zod'
7
+
8
+ // The local record of a lane child's park — the half of `run:park` a `PreToolUse` guard can read.
9
+ //
10
+ // **The park itself is a GitHub label, which a synchronous guard cannot read**, so `lane-park` used to
11
+ // fire on every lane-child stop, parked or not (joshuafolkken/kit#4132). `run:park` writes this record
12
+ // once the comment and the label are both on the issue, and the guard reads it back synchronously, the
13
+ // way the pre-gate cut guard reads `run-cut.ts`'s record.
14
+ //
15
+ // **Keyed to the repository and the issue, not the work tree.** The child parks from its lane, and the
16
+ // parent clears the park from the main checkout once a person has decided; both resolve the same
17
+ // common git directory, so `run:park --clear` removes the record wherever it runs.
18
+ //
19
+ // **Bounded like the cut record, and taken back by the next dispatch.** The guard asks within the run
20
+ // that parked, seconds after the park; a label a person removed by hand, without `--clear`, must not
21
+ // leave the guard silent on that issue's next dispatch, so `lane:dispatch` clears the record before it
22
+ // starts the child, and a record past the lane child's idle bound reads as no park.
23
+
24
+ const PARK_PREFIX = 'josh-run-park-'
25
+ const PARK_MAX_AGE_MS = backlog_budget.DEFAULT_IDLE_MS
26
+
27
+ const run_park_schema = z.object({
28
+ issue: z.string(),
29
+ parked_at: z.string(),
30
+ })
31
+
32
+ type RunPark = z.infer<typeof run_park_schema>
33
+
34
+ function parse_park(raw: string): RunPark | undefined {
35
+ return json_value.parse_with(raw, run_park_schema)
36
+ }
37
+
38
+ function parked_at_of(park: RunPark): string {
39
+ return park.parked_at
40
+ }
41
+
42
+ const PARK_SPEC: StampRecordSpec<RunPark> = {
43
+ parse: parse_park,
44
+ timestamp_of: parked_at_of,
45
+ max_age_ms: PARK_MAX_AGE_MS,
46
+ }
47
+
48
+ function park_path(repository: string, issue: string): string {
49
+ return stamp_file.stamp_path(`${PARK_PREFIX}${issue}-`, repository)
50
+ }
51
+
52
+ // **The directory is injectable so a test never writes the live record** — the same reason
53
+ // `run_cut.carried_cut_sync` takes one.
54
+ function record(issue: string, directory: string, now: Date = new Date()): boolean {
55
+ const repository = git_common_directory.repository(directory)
56
+
57
+ if (repository === undefined) return false
58
+
59
+ stamp_file.replace_stamp(park_path(repository, issue), { issue, parked_at: now.toISOString() })
60
+
61
+ return true
62
+ }
63
+
64
+ function clear(issue: string, directory: string): void {
65
+ const repository = git_common_directory.repository(directory)
66
+
67
+ if (repository !== undefined) stamp_file.remove_stamp(park_path(repository, issue))
68
+ }
69
+
70
+ // **A fault reads as "not parked"**, the direction `carried_cut_sync` takes: the guard then speaks once,
71
+ // which a child answers by reissuing, rather than falling silent on a run that never parked.
72
+ function is_parked_sync(issue: string, directory: string, now: Date = new Date()): boolean {
73
+ const repository = git_common_directory.repository(directory)
74
+
75
+ if (repository === undefined) return false
76
+
77
+ const read = stamp_record.classify(
78
+ stamp_file.read_stamp_text(park_path(repository, issue)),
79
+ PARK_SPEC,
80
+ now,
81
+ )
82
+
83
+ return read.kind === 'carried' && read.record.issue === issue
84
+ }
85
+
86
+ const run_park = { PARK_MAX_AGE_MS, clear, is_parked_sync, record }
87
+
88
+ export { run_park }
@@ -0,0 +1,68 @@
1
+ import { issue_cite } from '#scripts/issue/issue-cite'
2
+ import { RUN_STALLED_LABEL } from '#scripts/issue/issue-labels'
3
+
4
+ // What a `run:stalled` park says, written and read in one place (joshuafolkken/kit#4215): the park
5
+ // event carries the cause's short name after the label, the park comment its whole `Why:`, and the
6
+ // park comments, `backlog:plan --waves` and `run:board` name the one next action.
7
+
8
+ // Why a child was parked: `short` rides on the park event and the board row, `why` on the comment.
9
+ interface StallCause {
10
+ short: string
11
+ why: string
12
+ }
13
+
14
+ // What `run:merge` judged when it parks a child with no ship stop to name.
15
+ const SESSION_UNFINISHED: StallCause = {
16
+ short: 'session unfinished',
17
+ why: 'the child’s session ended with its issue still open and unfinished.',
18
+ }
19
+ const CUT_NOT_RELAUNCHED: StallCause = {
20
+ short: 'cut not relaunched',
21
+ why: 'its lane held a declared cut, but no successor could be relaunched from it (or it already was once).',
22
+ }
23
+
24
+ const RESUME_COMMAND = 'fullrun'
25
+ const CAUSE_LEAD = `${RUN_STALLED_LABEL}: `
26
+ const NEXT_ARROW = ' → '
27
+
28
+ function resume_of(child: number | string): string {
29
+ return `${RESUME_COMMAND} ${issue_cite.plain(child)}`
30
+ }
31
+
32
+ // The next action as a clause, which a park comment's `Next:` and the plan's note end with.
33
+ function next_step(child: number | string): string {
34
+ return `fix the cause, then resume it with \`${resume_of(child)}\` or remove \`${RUN_STALLED_LABEL}\` to offer it again`
35
+ }
36
+
37
+ function park_event(child: number | string, cause: string): string {
38
+ return `${issue_cite.plain(child)} parked (${CAUSE_LEAD}${cause})`
39
+ }
40
+
41
+ // The cause a park event's reason carries: `''` for a bare `run:stalled` (written before the event
42
+ // carried one), `undefined` for a reason that is no `run:stalled` park.
43
+ function cause_of(reason: string): string | undefined {
44
+ if (reason === RUN_STALLED_LABEL) return ''
45
+
46
+ return reason.startsWith(CAUSE_LEAD) ? reason.slice(CAUSE_LEAD.length) : undefined
47
+ }
48
+
49
+ // A stalled row's right end: its cause, then the action that resumes it — the action alone where no
50
+ // cause was recorded.
51
+ function row_text(child: number | string, cause = ''): string {
52
+ const resume = resume_of(child)
53
+
54
+ return cause === '' ? resume : `${cause}${NEXT_ARROW}${resume}`
55
+ }
56
+
57
+ const run_stalled = {
58
+ CUT_NOT_RELAUNCHED,
59
+ SESSION_UNFINISHED,
60
+ cause_of,
61
+ next_step,
62
+ park_event,
63
+ resume_of,
64
+ row_text,
65
+ }
66
+
67
+ export { run_stalled }
68
+ export type { StallCause }
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env tsx
2
+ import { fileURLToPath } from 'node:url'
3
+ import { issue_number_shape } from '#scripts/issue/issue-number-shape'
4
+ import { cli_flags } from '#scripts/lib/cli-flags'
5
+ import { run_pause, type PauseRequest, type PauseResult, type StepReport } from './run-pause'
6
+
7
+ // `josh run:pause <M> --for <N>` — the argument parsing and the report around `run-pause.ts`. One
8
+ // line per step that landed; a failure names its step, what was already done, and the rerun that
9
+ // continues from there.
10
+
11
+ const SUCCESS_EXIT_CODE = 0
12
+ const FAILURE_EXIT_CODE = 1
13
+ const ARGV_OFFSET = 2
14
+ const USAGE = 'Usage: josh run:pause <issue> --for <prerequisite>'
15
+ const OPTIONS = { for: { type: 'string' } } as const
16
+
17
+ // The prerequisite has to be another issue: `#M` blocked by itself is no order at all.
18
+ function prerequisite_of(value: string | undefined, issue: string): string | undefined {
19
+ if (value === undefined || value === issue) return undefined
20
+
21
+ return issue_number_shape.is_issue_number(value) ? value : undefined
22
+ }
23
+
24
+ function parse_request(argv: ReadonlyArray<string>): PauseRequest | undefined {
25
+ const parsed = cli_flags.arguments_of(argv, OPTIONS)
26
+ if (parsed === undefined) return undefined
27
+ const issue = issue_number_shape.single_of(parsed.positionals)
28
+ const prerequisite = issue === undefined ? undefined : prerequisite_of(parsed.values.for, issue)
29
+
30
+ return issue === undefined || prerequisite === undefined ? undefined : { issue, prerequisite }
31
+ }
32
+
33
+ function report_done(done: ReadonlyArray<StepReport>): void {
34
+ for (const { step, detail } of done) console.info(`${step}: ${detail}`)
35
+ }
36
+
37
+ function report_failure(request: PauseRequest, result: PauseResult & { kind: 'failed' }): void {
38
+ const steps = result.done.map(({ step }) => step).join(', ')
39
+
40
+ console.error(`✖ ${result.step} failed: ${result.reason}`)
41
+ console.error(`Done: ${steps.length === 0 ? 'nothing' : steps}.`)
42
+ console.error(
43
+ `Rerun \`pnpm josh run:pause ${request.issue} --for ${request.prerequisite}\` to continue from ${result.step}.`,
44
+ )
45
+ }
46
+
47
+ async function run(argv: ReadonlyArray<string>): Promise<number> {
48
+ const request = parse_request(argv)
49
+
50
+ if (request === undefined) {
51
+ console.error(USAGE)
52
+
53
+ return FAILURE_EXIT_CODE
54
+ }
55
+
56
+ const result = await run_pause.pause(request)
57
+
58
+ report_done(result.done)
59
+ if (result.kind === 'paused') return SUCCESS_EXIT_CODE
60
+ report_failure(request, result)
61
+
62
+ return FAILURE_EXIT_CODE
63
+ }
64
+
65
+ async function main(argv: ReadonlyArray<string>): Promise<void> {
66
+ process.exitCode = await run(argv)
67
+ }
68
+
69
+ const run_pause_cli = { USAGE, run }
70
+
71
+ if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
72
+
73
+ export { run_pause_cli }
@@ -0,0 +1,251 @@
1
+ import { epic_add } from '#scripts/epic/epic-add'
2
+ import { epic_bundle_gaps } from '#scripts/epic/epic-bundle-gaps'
3
+ import { epic_index } from '#scripts/epic/epic-index'
4
+ import { epic_reconcile } from '#scripts/epic/epic-reconcile'
5
+ import { git_gh_issue_read } from '#scripts/gh/git-gh-issue-read'
6
+ import { git_gh_issue_write } from '#scripts/gh/git-gh-issue-write'
7
+ import { parse_json_array_or_undefined } from '#scripts/git/parse-json-array'
8
+ import { git_stash } from '#scripts/git/stash/git-stash'
9
+ import { stash_push_cli } from '#scripts/git/stash/stash-push-cli'
10
+ import { issue_cite } from '#scripts/issue/issue-cite'
11
+ import { session_cite } from '#scripts/issue/session-cite'
12
+ import { error_text } from '#scripts/lib/error-message'
13
+ import { run_hold_cli } from '#scripts/run/hold/run-hold-cli'
14
+ import { z } from 'zod'
15
+
16
+ // `josh run:pause <M> --for <N>` — set a run aside while its prerequisite `#N` lands first
17
+ // (`prerequisite.md`): the work in progress stashed under a fixed name, a comment on `#M` naming the
18
+ // pop, `#M` blocked by `#N` and the hold released, in that order.
19
+ //
20
+ // **Every step asks whether it is already done before it acts**, so a rerun after a failure carries on
21
+ // from the step that failed rather than stashing, commenting or recording twice. The state lives where
22
+ // each write lands — the stash stack, the Issue's comments and its `blocked_by` relations — so no
23
+ // record of its own is kept. Each write is the existing command's implementation, not a copy of it.
24
+
25
+ // `epic:bundle`'s own listing limit, so both commands see the same epics.
26
+ const EPIC_LIMIT = 200
27
+ const SUCCESS_EXIT_CODE = 0
28
+ const ALREADY = 'already'
29
+ const comment_schema = z.object({ body: z.string().nullish() })
30
+
31
+ interface PauseRequest {
32
+ issue: string
33
+ prerequisite: string
34
+ }
35
+
36
+ type StepName = 'stash' | 'comment' | 'blocked-by' | 'release'
37
+
38
+ interface StepReport {
39
+ step: StepName
40
+ detail: string
41
+ }
42
+
43
+ type PauseResult =
44
+ | { kind: 'paused'; done: ReadonlyArray<StepReport> }
45
+ | { kind: 'failed'; step: StepName; reason: string; done: ReadonlyArray<StepReport> }
46
+
47
+ function stash_message(request: PauseRequest): string {
48
+ return `run:pause: ${issue_cite.plain(request.issue)} waits on ${issue_cite.plain(request.prerequisite)}`
49
+ }
50
+
51
+ function comment_marker(request: PauseRequest): string {
52
+ return `<!-- josh:run-pause ${issue_cite.plain(request.issue)} for ${issue_cite.plain(request.prerequisite)} -->`
53
+ }
54
+
55
+ async function is_stashed(request: PauseRequest): Promise<boolean> {
56
+ return git_stash.select(await git_stash.list(), stash_message(request)).kind !== 'none'
57
+ }
58
+
59
+ async function stash_step(request: PauseRequest): Promise<string> {
60
+ if (await is_stashed(request)) return ALREADY
61
+
62
+ return await stash_push_cli.set_aside({ message: stash_message(request), dir: undefined })
63
+ }
64
+
65
+ function pause_comment(request: PauseRequest, is_work_stashed: boolean): string {
66
+ const work = is_work_stashed
67
+ ? `- The work in progress was stashed. After \`pnpm josh ms\`, recover it with \`pnpm josh stash:pop "${stash_message(request)}"\` (expect conflicts).`
68
+ : '- The tree held no uncommitted work, so nothing was stashed.'
69
+
70
+ return [
71
+ `Paused: ${issue_cite.plain(request.prerequisite)} has to land first.`,
72
+ work,
73
+ comment_marker(request),
74
+ ].join('\n')
75
+ }
76
+
77
+ async function has_pause_comment(request: PauseRequest): Promise<boolean> {
78
+ const json = await git_gh_issue_read.issue_list_comments(request.issue)
79
+ const rows = json === undefined ? undefined : parse_json_array_or_undefined(json, comment_schema)
80
+
81
+ if (rows === undefined) {
82
+ throw new Error(`the comments on ${session_cite.issue(request.issue)} could not be read`)
83
+ }
84
+
85
+ return rows.some((row) => row.body?.includes(comment_marker(request)) === true)
86
+ }
87
+
88
+ async function comment_step(request: PauseRequest): Promise<string> {
89
+ if (await has_pause_comment(request)) return ALREADY
90
+
91
+ const body = pause_comment(request, await is_stashed(request))
92
+
93
+ return await git_gh_issue_write.issue_comment(request.issue, body)
94
+ }
95
+
96
+ async function is_blocked(request: PauseRequest): Promise<boolean> {
97
+ const blockers = await git_gh_issue_read.issue_blocked_by_numbers(request.issue)
98
+
99
+ return blockers.includes(Number(request.prerequisite))
100
+ }
101
+
102
+ interface Tracking {
103
+ epic: number
104
+ // Whether the same epic already tracks the prerequisite as a row of its own.
105
+ is_prerequisite_child: boolean
106
+ }
107
+
108
+ // Every epic listing the child, not the one `build_epic_index` keeps: a child a second epic also
109
+ // lists is still a row of this one.
110
+ function is_listed_by(
111
+ epics: ReadonlyArray<{ number: number; body: string }>,
112
+ child: string,
113
+ epic: number,
114
+ ): boolean {
115
+ return epic_index.build_tracking_index(epics).get(Number(child))?.includes(epic) === true
116
+ }
117
+
118
+ // A listing cut short is no answer about absence: an epic past the cut tracks `#M` invisibly, and a
119
+ // direct relation written then leaves that epic recording an order its body never declares.
120
+ async function tracking_epic(request: PauseRequest): Promise<Tracking | undefined> {
121
+ const fetched = await epic_index.fetch_epics(EPIC_LIMIT)
122
+ if (fetched === undefined) throw new Error('the open epics could not be read')
123
+ const index = epic_index.build_epic_index(fetched.epics)
124
+ const epic = index.get(Number(request.issue))
125
+
126
+ if (epic === undefined && !epic_bundle_gaps.is_membership_established(fetched.cutoff)) {
127
+ throw new Error('the open epics were not read in full, so an epic tracking it may be unseen')
128
+ }
129
+
130
+ if (epic === undefined) return undefined
131
+
132
+ return { epic, is_prerequisite_child: is_listed_by(fetched.epics, request.prerequisite, epic) }
133
+ }
134
+
135
+ async function add_to_epic(epic: number, request: PauseRequest): Promise<void> {
136
+ const code = await epic_add.add_children({
137
+ epic_number: epic,
138
+ children: [Number(request.prerequisite)],
139
+ position: { kind: 'before', target: Number(request.issue) },
140
+ })
141
+
142
+ if (code !== SUCCESS_EXIT_CODE) {
143
+ throw new Error(`\`epic --add\` into ${session_cite.issue(epic)} failed`)
144
+ }
145
+ }
146
+
147
+ async function record_relation(request: PauseRequest): Promise<void> {
148
+ if (await git_gh_issue_write.issue_add_blocked_by(request.issue, request.prerequisite)) return
149
+
150
+ throw new Error('the blocked-by relation was not recorded')
151
+ }
152
+
153
+ async function refuse_unreconcilable(epic: number, request: PauseRequest): Promise<void> {
154
+ const link = { blocker: Number(request.prerequisite), blocked: Number(request.issue) }
155
+ const refusal = await epic_reconcile.refusal_after(epic, link)
156
+ if (refusal === undefined) return
157
+
158
+ throw new Error(
159
+ `\`pnpm josh epic --reconcile ${String(epic)}\` would refuse the relation, so none was recorded: ${refusal}`,
160
+ )
161
+ }
162
+
163
+ async function reconcile_epic(epic: number): Promise<void> {
164
+ if ((await epic_reconcile.reconcile_epic(epic)) === SUCCESS_EXIT_CODE) return
165
+
166
+ throw new Error(
167
+ `the relation was recorded, but \`pnpm josh epic --reconcile ${String(epic)}\` failed to declare it`,
168
+ )
169
+ }
170
+
171
+ // A prerequisite outside the epic gains its row, declaration and relation from `epic --add --before`.
172
+ // One the epic already tracks does not: `epic --add` reads it as a move and drops every order it
173
+ // already had, where a pause only adds one — so the relation is recorded directly and
174
+ // `epic --reconcile` copies it into the declaration beside the others, once a dry plan shows the
175
+ // reconcile accepts it: a refusal after the write would leave the relation undeclared. `epic --add`
176
+ // exits 0 on a relation it failed to post, so the relation is read back after the insertion.
177
+ async function record_in_epic(tracking: Tracking, request: PauseRequest): Promise<string> {
178
+ if (tracking.is_prerequisite_child) {
179
+ await refuse_unreconcilable(tracking.epic, request)
180
+ await record_relation(request)
181
+ await reconcile_epic(tracking.epic)
182
+ } else {
183
+ await add_to_epic(tracking.epic, request)
184
+ if (!(await is_blocked(request))) await record_relation(request)
185
+ }
186
+
187
+ return `recorded in epic ${session_cite.issue(tracking.epic)}`
188
+ }
189
+
190
+ // A relation recorded inside an epic tracking both issues is only done once it is declared, so a
191
+ // rerun past a failed reconcile reconciles again — a no-op on an epic that already declares it.
192
+ async function settle_recorded(request: PauseRequest): Promise<string> {
193
+ const tracking = await tracking_epic(request)
194
+ if (tracking?.is_prerequisite_child === true) await reconcile_epic(tracking.epic)
195
+
196
+ return ALREADY
197
+ }
198
+
199
+ async function blocked_by_step(request: PauseRequest): Promise<string> {
200
+ if (await is_blocked(request)) return await settle_recorded(request)
201
+
202
+ const tracking = await tracking_epic(request)
203
+ if (tracking !== undefined) return await record_in_epic(tracking, request)
204
+ await record_relation(request)
205
+
206
+ return 'recorded'
207
+ }
208
+
209
+ // Releasing a free record is a success, so a rerun past this step answers `released` again.
210
+ async function release_step(request: PauseRequest): Promise<string> {
211
+ const code = await run_hold_cli.run(['--release', request.issue])
212
+ if (code !== SUCCESS_EXIT_CODE) throw new Error('`run:release` refused')
213
+
214
+ return 'released'
215
+ }
216
+
217
+ const STEPS: ReadonlyArray<[StepName, (request: PauseRequest) => Promise<string>]> = [
218
+ ['stash', stash_step],
219
+ ['comment', comment_step],
220
+ ['blocked-by', blocked_by_step],
221
+ ['release', release_step],
222
+ ]
223
+
224
+ async function attempt(
225
+ act: (request: PauseRequest) => Promise<string>,
226
+ request: PauseRequest,
227
+ ): Promise<{ detail: string } | { reason: string }> {
228
+ try {
229
+ return { detail: await act(request) }
230
+ } catch (error) {
231
+ return { reason: error_text.message_of(error) }
232
+ }
233
+ }
234
+
235
+ async function pause(request: PauseRequest): Promise<PauseResult> {
236
+ const done: Array<StepReport> = []
237
+
238
+ for (const [step, act] of STEPS) {
239
+ // eslint-disable-next-line no-await-in-loop -- each step runs only once the one before it landed
240
+ const outcome = await attempt(act, request)
241
+ if ('reason' in outcome) return { kind: 'failed', step, reason: outcome.reason, done }
242
+ done.push({ step, detail: outcome.detail })
243
+ }
244
+
245
+ return { kind: 'paused', done }
246
+ }
247
+
248
+ const run_pause = { pause }
249
+
250
+ export type { PauseRequest, PauseResult, StepReport }
251
+ export { run_pause }
@@ -1,11 +1,10 @@
1
- #!/usr/bin/env tsx
2
1
  import { setTimeout as sleep } from 'node:timers/promises'
3
- import { fileURLToPath } from 'node:url'
4
2
  import { backlog_arrival, type ArrivalProbe } from '#scripts/backlog/backlog-arrival'
5
3
  import { backlog_ready } from '#scripts/backlog/backlog-ready'
6
4
  import { gh_spawn } from '#scripts/gh/gh-spawn'
7
5
  import { lane_child_marker } from '#scripts/lane/lane-child-marker'
8
6
  import { error_text } from '#scripts/lib/error-message'
7
+ import { MS_PER_SECOND } from '#scripts/lib/timeouts'
9
8
  import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
10
9
  import { run_progress, type ProgressState } from './run-progress'
11
10
  import { run_progress_args, type ParsedValues } from './run-progress-args'
@@ -34,7 +33,6 @@ import { run_progress_read, type ObservationRead } from './run-progress-read'
34
33
 
35
34
  const SUCCESS_EXIT_CODE = 0
36
35
  const FAILURE_EXIT_CODE = 1
37
- const ARGV_OFFSET = 2
38
36
  // How often the loop wakes to look at the clock — not how often it reports. It is short relative to
39
37
  // the interval so that a `--mark` written by the run is noticed promptly, and long enough that a
40
38
  // watcher left running overnight costs nothing measurable.
@@ -78,7 +76,7 @@ const WAIT_EXPIRED_NOTICE = `The watch bound (\`--hours\`, ${String(DEFAULT_WAIT
78
76
  // one: a `gh` call that hangs would otherwise block the synchronous read at startup and leave the
79
77
  // watcher neither running nor saying so.
80
78
  const REPO_LOOKUP_TIMEOUT_SECONDS = 10
81
- const REPO_LOOKUP_TIMEOUT_MS = REPO_LOOKUP_TIMEOUT_SECONDS * run_progress.MS_PER_SECOND
79
+ const REPO_LOOKUP_TIMEOUT_MS = REPO_LOOKUP_TIMEOUT_SECONDS * MS_PER_SECOND
82
80
  // A lookup that timed out or failed is not an argument the caller got wrong, so it is told apart from
83
81
  // the usage error — read as one, it would send a person to fix arguments that were correct.
84
82
  const REPO_UNRESOLVED_NOTICE = `The repository could not be resolved (\`gh\` did not answer within ${String(REPO_LOOKUP_TIMEOUT_SECONDS)}s or failed), so the progress watcher did not start. Pass \`--repo <owner/repo>\` and start it again.`
@@ -215,7 +213,7 @@ async function emit(options: WatchOptions, context: EmitContext): Promise<EmitRe
215
213
  function decline(loop: WatchLoop, now_ms: number, notice: string): WatchLoop {
216
214
  if (loop.said !== notice) console.error(notice)
217
215
 
218
- const cooldown_ms = DECLINE_RETRY_SECONDS * run_progress.MS_PER_SECOND
216
+ const cooldown_ms = DECLINE_RETRY_SECONDS * MS_PER_SECOND
219
217
 
220
218
  return { ...loop, retry_at_ms: now_ms + cooldown_ms, said: notice }
221
219
  }
@@ -442,7 +440,7 @@ function to_options(values: ParsedValues): WatchOptions | undefined {
442
440
  max_ms: run_progress_args.to_max_ms(values.hours, values.wait === true),
443
441
  output_paths: values.output ?? [],
444
442
  repo,
445
- tick_ms: TICK_SECONDS * run_progress.MS_PER_SECOND,
443
+ tick_ms: TICK_SECONDS * MS_PER_SECOND,
446
444
  }
447
445
  }
448
446
 
@@ -480,10 +478,6 @@ async function run(argv: ReadonlyArray<string>): Promise<number> {
480
478
  return await run_watch(values)
481
479
  }
482
480
 
483
- async function main(argv: ReadonlyArray<string>): Promise<void> {
484
- process.exitCode = await run(argv)
485
- }
486
-
487
481
  const run_progress_cli = {
488
482
  DECLINE_RETRY_SECONDS,
489
483
  DEFAULT_WAIT_MAX_HOURS,
@@ -503,7 +497,5 @@ const run_progress_cli = {
503
497
  wait_once,
504
498
  }
505
499
 
506
- if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
507
-
508
500
  export type { WatchLoop, WatchOptions }
509
501
  export { run_progress_cli }
@@ -2,6 +2,7 @@ import { git_common_directory } from '#scripts/git/git-common-directory'
2
2
  import { stamp_file } from '#scripts/josh/stamp-file'
3
3
  import { error_text } from '#scripts/lib/error-message'
4
4
  import { json_value } from '#scripts/lib/json-value'
5
+ import { MS_PER_MINUTE } from '#scripts/lib/timeouts'
5
6
  import { z } from 'zod'
6
7
 
7
8
  // The report clock `josh run:progress` keeps, in the one form both of its readers can use.
@@ -48,7 +49,6 @@ const LOG_SUFFIX = '.log'
48
49
  // A few hours of heartbeats at the twenty-minute interval — enough to read the run's recent shape, and
49
50
  // bounded so an unattended run cannot grow the file without limit.
50
51
  const LOG_KEEP = 12
51
- const MS_PER_MINUTE = 60_000
52
52
  // Longer than any heartbeat interval and shorter than any gap between two runs. Heartbeats land at most
53
53
  // one interval apart while a run is live (twenty minutes by default, well under this), so a newest block
54
54
  // older than this belongs to a previous run: past it the log is reset rather than extended, and a fresh