@joshuafolkken/kit 1.1035.0 → 1.1094.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 (605) hide show
  1. package/.claude/settings.json +9 -8
  2. package/.claude/skills/epic-commands/SKILL.md +5 -7
  3. package/.claude/skills/verify-ui/SKILL.md +1 -1
  4. package/.claude/skills/workflow-commands/SKILL.md +21 -13
  5. package/.claude/skills/workflow-commands/background-commands.md +5 -4
  6. package/.claude/skills/workflow-commands/backlogrun-child.md +3 -3
  7. package/.claude/skills/workflow-commands/backlogrun-lanes.md +9 -7
  8. package/.claude/skills/workflow-commands/backlogrun-park.md +6 -0
  9. package/.claude/skills/workflow-commands/backlogrun-progress.md +31 -37
  10. package/.claude/skills/workflow-commands/backlogrun-steps.md +25 -25
  11. package/.claude/skills/workflow-commands/backlogrun.md +2 -2
  12. package/.claude/skills/workflow-commands/chain-rule.md +6 -4
  13. package/.claude/skills/workflow-commands/delegation.md +3 -3
  14. package/.claude/skills/workflow-commands/followup-reference.md +3 -3
  15. package/.claude/skills/workflow-commands/followup.md +7 -3
  16. package/.claude/skills/workflow-commands/fullrun-steps.md +3 -2
  17. package/.claude/skills/workflow-commands/fullrun.md +3 -2
  18. package/.claude/skills/workflow-commands/halfrun.md +16 -19
  19. package/.claude/skills/workflow-commands/issue-comments.md +2 -2
  20. package/.claude/skills/workflow-commands/issue-fold-existing.md +10 -10
  21. package/.claude/skills/workflow-commands/issue-scout.md +1 -1
  22. package/.claude/skills/workflow-commands/kickoff.md +9 -4
  23. package/.claude/skills/workflow-commands/latest-gate.md +1 -1
  24. package/.claude/skills/workflow-commands/needs-human-review.md +1 -1
  25. package/.claude/skills/workflow-commands/observation-filing.md +44 -89
  26. package/.claude/skills/workflow-commands/pre-gate-cut.md +33 -36
  27. package/.claude/skills/workflow-commands/prerequisite.md +1 -1
  28. package/.claude/skills/workflow-commands/prrun.md +36 -0
  29. package/.claude/skills/workflow-commands/retrospective.md +1 -1
  30. package/.claude/skills/workflow-commands/working-tree-hold.md +24 -4
  31. package/.codex/hooks.json +16 -20
  32. package/.github/actions/setup-pnpm/action.yml +93 -0
  33. package/.github/dependabot.yml +5 -1
  34. package/.github/workflows/auto-tag.yml +21 -0
  35. package/.github/workflows/ci.yml +26 -128
  36. package/.github/workflows/pr-classification.yml +5 -41
  37. package/.github/workflows/publish.yml +42 -48
  38. package/.github/workflows/sonar-qube.yml +37 -4
  39. package/AGENTS.md +12 -2
  40. package/CLAUDE.md +15 -16
  41. package/GEMINI.md +14 -2
  42. package/README.md +59 -18
  43. package/SECURITY.md +36 -6
  44. package/cspell/index.yaml +2 -1
  45. package/dist/CLAUDE.md +15 -16
  46. package/dist/config-merge/index.js +15 -3
  47. package/dist/hooks/batch-guard.js +4 -4
  48. package/dist/hooks/{chunk-Y27M6A7X.js → chunk-3C4YCCEF.js} +5 -13
  49. package/dist/hooks/{chunk-D67KVGGY.js → chunk-7ZPFAVR7.js} +17 -88
  50. package/dist/hooks/{chunk-HOYJU5RM.js → chunk-E54KGFEQ.js} +11 -4
  51. package/dist/hooks/{chunk-KG6PZD72.js → chunk-IL27YTPH.js} +2 -2
  52. package/dist/hooks/{chunk-GJT4BNVE.js → chunk-KHWHKJOM.js} +3 -3
  53. package/dist/hooks/{chunk-HU66PWWL.js → chunk-M2XDCUKD.js} +1076 -509
  54. package/dist/hooks/{chunk-GLBDBJOK.js → chunk-NKOG3XAV.js} +199 -304
  55. package/dist/hooks/{chunk-ZXNE6NY3.js → chunk-O4LL4HTI.js} +2 -7
  56. package/dist/hooks/{chunk-XPLP27WA.js → chunk-OIZUHPJI.js} +5 -27
  57. package/dist/hooks/{chunk-EIFCAJRB.js → chunk-UD24EAIL.js} +2546 -1636
  58. package/dist/hooks/codex-hook-adapter.js +10 -11
  59. package/dist/hooks/duplicate-read-guard.js +5 -5
  60. package/dist/hooks/format-edited.js +15 -34
  61. package/dist/hooks/inputs.json +279 -0
  62. package/dist/hooks/investigation-guard.js +5 -5
  63. package/dist/hooks/pretool-guard.js +23 -16
  64. package/dist/hooks/session-lang.js +0 -1
  65. package/dist/hooks/stop-guard.js +188 -509
  66. package/dist/josh.js +166 -225
  67. package/dist/managed-marker/index.js +2 -1
  68. package/dist/version/index.js +412 -64
  69. package/eslint/rules/promise.js +5 -0
  70. package/package.json +13 -8
  71. package/prompts/collaboration-workflow/file-edits.md +6 -53
  72. package/prompts/collaboration-workflow/issue-citation.md +5 -5
  73. package/prompts/collaboration-workflow/operating-rules.md +4 -4
  74. package/prompts/collaboration-workflow/overview.md +13 -1
  75. package/prompts/collaboration-workflow/report-format.md +1 -1
  76. package/prompts/collaboration-workflow/residency.md +4 -4
  77. package/prompts/collaboration-workflow/rule-delivery.md +5 -36
  78. package/prompts/collaboration-workflow/shell-body.md +7 -9
  79. package/prompts/collaboration-workflow/turn-batching.md +21 -37
  80. package/prompts/collaboration-workflow/upstream-interrupt.md +1 -1
  81. package/prompts/collaboration-workflow/wip-cap.md +36 -36
  82. package/prompts/collaboration-workflow.md +5 -8
  83. package/prompts/review-rubric.md +1 -1
  84. package/prompts/review.md +3 -3
  85. package/prompts/sonar-hotspot-handling.md +12 -4
  86. package/prompts/testing-guide.md +3 -3
  87. package/scripts/adopt/adopt-toolkits.ts +2 -2
  88. package/scripts/adopt/adopt.ts +0 -2
  89. package/scripts/agent/agent-argv.ts +0 -2
  90. package/scripts/agent/agent-diagnostics.ts +1 -1
  91. package/scripts/agent/agent-role-profile.ts +0 -7
  92. package/scripts/agent/claude-agent-argv.ts +0 -2
  93. package/scripts/agent/codex-agent-argv.ts +1 -1
  94. package/scripts/agent/codex-hooks.ts +92 -0
  95. package/scripts/agent/interactive-ask.ts +1 -1
  96. package/scripts/auto-ok/auto-ok-cli.ts +15 -25
  97. package/scripts/backlog/backlog-budget.ts +0 -2
  98. package/scripts/backlog/backlog-defect-priority.ts +2 -2
  99. package/scripts/backlog/backlog-drive-cli.ts +10 -8
  100. package/scripts/backlog/backlog-drive-named-offer.ts +16 -3
  101. package/scripts/backlog/backlog-drive-named.ts +2 -1
  102. package/scripts/backlog/backlog-drive.ts +76 -16
  103. package/scripts/backlog/backlog-named.ts +0 -3
  104. package/scripts/backlog/backlog-next.ts +32 -22
  105. package/scripts/backlog/backlog-offer-cli.ts +0 -5
  106. package/scripts/backlog/backlog-plan-cli.ts +6 -8
  107. package/scripts/backlog/backlog-plan.ts +1 -1
  108. package/scripts/backlog/backlog-pool.ts +34 -17
  109. package/scripts/backlog/backlog-rank.ts +106 -0
  110. package/scripts/backlog/backlog-ready.ts +19 -3
  111. package/scripts/backlog/backlog-scope.ts +1 -3
  112. package/scripts/backlog/backlog-stalled-detect.ts +2 -2
  113. package/scripts/backlog/backlog-stalled.ts +0 -1
  114. package/scripts/backlog/backlog-waves.ts +47 -31
  115. package/scripts/behavior/behavior-cli.ts +1 -1
  116. package/scripts/build/build-codex-hooks.ts +26 -0
  117. package/scripts/build/build-hooks.ts +92 -11
  118. package/scripts/build/hook-bundle-stamp.ts +111 -0
  119. package/scripts/cases/cases-cli.ts +1 -1
  120. package/scripts/cases/cases-logic.ts +1 -1
  121. package/scripts/ci/composite-actions.ts +30 -0
  122. package/scripts/ci/pr-classification.ts +3 -3
  123. package/scripts/claude/workflow-destination.ts +10 -1
  124. package/scripts/clone/clone-fingerprint.ts +0 -1
  125. package/scripts/clone/clone-scan-cli.ts +1 -1
  126. package/scripts/clone/clone-scan.ts +1 -1
  127. package/scripts/config-merge/json-format.ts +0 -1
  128. package/scripts/config-merge/patch-yaml-list.ts +1 -1
  129. package/scripts/cost-runtime/codex-usage.ts +2 -9
  130. package/scripts/cost-runtime/cost-attribute.ts +0 -1
  131. package/scripts/cost-runtime/cost-cli.ts +0 -3
  132. package/scripts/cost-runtime/cost-corpus.ts +0 -2
  133. package/scripts/cost-runtime/cost-format.ts +0 -3
  134. package/scripts/cost-runtime/cost-pricing.ts +0 -1
  135. package/scripts/cost-runtime/cost-tokens.ts +0 -1
  136. package/scripts/delegation/delegation-cli.ts +1 -1
  137. package/scripts/delegation/delegation-policy.ts +11 -1
  138. package/scripts/delegation/duplicate-read-guard.ts +0 -8
  139. package/scripts/delegation/fanout-cli.ts +1 -1
  140. package/scripts/delegation/fanout.ts +0 -2
  141. package/scripts/delegation/investigation-reads.ts +1 -164
  142. package/scripts/discovery/repo-map-logic.ts +0 -1
  143. package/scripts/discovery/repo-party-cli.ts +1 -1
  144. package/scripts/doctor/doctor-consumer.ts +4 -6
  145. package/scripts/doctor/doctor-logic.ts +0 -4
  146. package/scripts/doctor/doctor.ts +14 -9
  147. package/scripts/document/document-byte-budget.ts +8 -9
  148. package/scripts/document/document-byte-check.ts +0 -1
  149. package/scripts/document/document-read-cli.ts +0 -2
  150. package/scripts/document/document-section-cli.ts +1 -1
  151. package/scripts/document/document-section.ts +0 -3
  152. package/scripts/document/edit-files-cli.ts +0 -1
  153. package/scripts/document/entry-read-budget.ts +13 -4
  154. package/scripts/document/lane-child-read-set.ts +1 -6
  155. package/scripts/document/read-files-cli.ts +0 -4
  156. package/scripts/document/read-set-cli.ts +0 -2
  157. package/scripts/document/read-set-point-of-use.ts +1 -0
  158. package/scripts/document/read-set-pricing.ts +0 -1
  159. package/scripts/document/read-set-trim.ts +1 -1
  160. package/scripts/epic/epic-add.ts +1 -1
  161. package/scripts/epic/epic-audit-cli.ts +1 -4
  162. package/scripts/epic/epic-audit-orphans.ts +1 -3
  163. package/scripts/epic/epic-audit-rationale.ts +0 -1
  164. package/scripts/epic/epic-audit-report.ts +0 -2
  165. package/scripts/epic/epic-audit.ts +5 -4
  166. package/scripts/epic/epic-bundle-cli.ts +1 -1
  167. package/scripts/epic/epic-bundle-evidence.ts +0 -1
  168. package/scripts/epic/epic-bundle-referenced.ts +1 -5
  169. package/scripts/epic/epic-bundle.ts +0 -4
  170. package/scripts/epic/epic-busy.ts +4 -5
  171. package/scripts/epic/epic-candidate-confirm.ts +0 -5
  172. package/scripts/epic/epic-classify.ts +2 -2
  173. package/scripts/epic/epic-cli-argv.ts +0 -1
  174. package/scripts/epic/epic-close-comment.ts +1 -1
  175. package/scripts/epic/epic-close.ts +5 -2
  176. package/scripts/epic/epic-cross-repo.ts +2 -4
  177. package/scripts/epic/epic-decision.ts +0 -1
  178. package/scripts/epic/epic-fetch.ts +2 -2
  179. package/scripts/epic/epic-index.ts +2 -3
  180. package/scripts/epic/epic-issue.ts +1 -15
  181. package/scripts/epic/epic-lane-offer.ts +20 -30
  182. package/scripts/epic/epic-nested.ts +1 -1
  183. package/scripts/epic/epic-next-read.ts +1 -3
  184. package/scripts/epic/epic-next-views.ts +0 -1
  185. package/scripts/epic/epic-next.ts +1 -10
  186. package/scripts/epic/epic-parse.ts +0 -1
  187. package/scripts/epic/epic-promote.ts +0 -9
  188. package/scripts/epic/epic-rank.ts +37 -0
  189. package/scripts/epic/epic-read.ts +1 -2
  190. package/scripts/epic/epic-reconcile.ts +1 -1
  191. package/scripts/epic/epic-reference.ts +1 -13
  192. package/scripts/epic/epic-relation-recheck.ts +1 -1
  193. package/scripts/epic/epic-relations.ts +1 -1
  194. package/scripts/epic/epic-remove.ts +1 -1
  195. package/scripts/epic/epic-report.ts +0 -1
  196. package/scripts/epic/epic-run.ts +2 -3
  197. package/scripts/epic/epic-shape.ts +1 -1
  198. package/scripts/epic/epic-solo-stale.ts +107 -0
  199. package/scripts/epic/epic-solo.ts +32 -30
  200. package/scripts/epic/epic-triage.ts +1 -1
  201. package/scripts/epic/epic-validate.ts +1 -1
  202. package/scripts/epic/epic.ts +1 -1
  203. package/scripts/exports/unused-members-cli.ts +53 -0
  204. package/scripts/{git → followup}/followup-issue-number.ts +1 -6
  205. package/scripts/{git → followup}/git-followup-cleanup.ts +2 -1
  206. package/scripts/{git → followup}/git-followup-finish.ts +1 -3
  207. package/scripts/{git → followup}/git-followup-flush.ts +2 -2
  208. package/scripts/{git → followup}/git-followup-issue-close.ts +2 -2
  209. package/scripts/{git → followup}/git-followup-label.ts +4 -4
  210. package/scripts/followup/git-followup-merged.ts +112 -0
  211. package/scripts/{git → followup}/git-followup-pending.ts +1 -1
  212. package/scripts/{git → followup}/git-followup-workflow.ts +19 -11
  213. package/scripts/{git → followup}/git-pr-followup-wrapup.ts +9 -3
  214. package/scripts/{git → followup}/git-pr-followup.ts +53 -16
  215. package/scripts/gate/core-budget.ts +3 -9
  216. package/scripts/gate/gate-plan.ts +7 -4
  217. package/scripts/gate/gate-report.ts +0 -6
  218. package/scripts/gate/gate-tree.ts +1 -1
  219. package/scripts/gate/pre-commit-type-check.ts +0 -6
  220. package/scripts/gate/project-checks.ts +7 -8
  221. package/scripts/gate/scoped-green.ts +0 -1
  222. package/scripts/gate/type-check-step.ts +1 -1
  223. package/scripts/gate/verification-gate.ts +0 -2
  224. package/scripts/gh/fix-gh-packages.ts +15 -12
  225. package/scripts/gh/gh-spawn.ts +2 -2
  226. package/scripts/{git → gh}/git-ai-review-scan.ts +1 -5
  227. package/scripts/{git → gh}/git-gh-check.ts +2 -1
  228. package/scripts/{git → gh}/git-gh-exec.ts +1 -1
  229. package/scripts/{git → gh}/git-gh-failure.ts +1 -1
  230. package/scripts/{git → gh}/git-gh-helpers.ts +0 -1
  231. package/scripts/{git → gh}/git-gh-issue-list.ts +2 -0
  232. package/scripts/{git → gh}/git-gh-issue-read.ts +1 -1
  233. package/scripts/{git → gh}/git-gh-issue-rest.ts +6 -3
  234. package/scripts/{git → gh}/git-gh-pr-read.ts +24 -0
  235. package/scripts/{git → gh}/git-gh-pr-rest.ts +5 -2
  236. package/scripts/{git → gh}/git-gh-pr-review.ts +2 -2
  237. package/scripts/{git → gh}/git-gh-pr-rollup.ts +1 -3
  238. package/scripts/{git → gh}/git-gh-pr.ts +3 -1
  239. package/scripts/{git → gh}/git-pr-ai-review.ts +2 -5
  240. package/scripts/{git → gh}/git-pr-checks-eval.ts +0 -10
  241. package/scripts/{git → gh}/git-pr-checks-parse.ts +4 -20
  242. package/scripts/{git → gh}/git-pr-checks.ts +2 -1
  243. package/scripts/{git → gh}/git-pr-coderabbit.ts +2 -5
  244. package/scripts/{git → gh}/git-pr-confirmation.ts +1 -3
  245. package/scripts/{git → gh}/git-pr-managed-config.ts +2 -3
  246. package/scripts/{git → gh}/git-pr.ts +3 -3
  247. package/scripts/git/changed-file-scope.ts +0 -1
  248. package/scripts/git/git-branch.ts +3 -6
  249. package/scripts/git/git-command.ts +1 -1
  250. package/scripts/git/git-commit.ts +1 -1
  251. package/scripts/git/git-common-directory.ts +80 -24
  252. package/scripts/git/git-error.ts +66 -9
  253. package/scripts/git/git-execa-error.ts +6 -1
  254. package/scripts/git/git-issue.ts +1 -1
  255. package/scripts/git/git-preflight.ts +24 -6
  256. package/scripts/git/git-prompt.ts +6 -31
  257. package/scripts/git/git-push-transport.ts +12 -69
  258. package/scripts/git/git-push.ts +1 -1
  259. package/scripts/git/git-spawn.ts +79 -3
  260. package/scripts/git/git-ssh-keepalive.ts +74 -0
  261. package/scripts/git/git-staging.ts +1 -0
  262. package/scripts/git/git-status.ts +1 -1
  263. package/scripts/git/git-workflow.ts +1 -1
  264. package/scripts/git/gone-branch.ts +4 -2
  265. package/scripts/git/listing-cutoff.ts +1 -1
  266. package/scripts/git/main-merge.ts +1 -1
  267. package/scripts/git/main-sync.ts +19 -1
  268. package/scripts/git/parse-json-array.ts +0 -3
  269. package/scripts/git/repository-lock.ts +16 -16
  270. package/scripts/git/{git-stash.ts → stash/git-stash.ts} +1 -1
  271. package/scripts/git/{stash-pop-args.ts → stash/stash-pop-args.ts} +1 -1
  272. package/scripts/git/{stash-pop-cli.ts → stash/stash-pop-cli.ts} +0 -1
  273. package/scripts/git/{stash-sweep-lock.ts → stash/stash-sweep-lock.ts} +3 -3
  274. package/scripts/hooks/codex-hook-adapter.ts +0 -1
  275. package/scripts/hooks/edited-cspell.ts +1 -1
  276. package/scripts/hooks/format-edited-cli.ts +15 -0
  277. package/scripts/hooks/format-edited-file.ts +4 -9
  278. package/scripts/hooks/pre-push-unit.ts +0 -4
  279. package/scripts/hooks/pretool-guard-cli.ts +21 -0
  280. package/scripts/hooks/pretool-guard.ts +36 -19
  281. package/scripts/hooks/reserved-run.ts +1 -1
  282. package/scripts/hooks/step-zero-notice.ts +76 -0
  283. package/scripts/hooks/stop-guard.ts +47 -21
  284. package/scripts/init/claude-plugin-config.ts +4 -5
  285. package/scripts/init/hook-command-rewrite.ts +16 -8
  286. package/scripts/init/hook-launch.ts +41 -15
  287. package/scripts/init/init-basic.ts +2 -5
  288. package/scripts/init/init-logic.ts +7 -0
  289. package/scripts/init/init.ts +0 -3
  290. package/scripts/init/project-profile.ts +6 -11
  291. package/scripts/init/start-exec.ts +8 -2
  292. package/scripts/init/start-plan.ts +18 -5
  293. package/scripts/init/start-setup-pr.ts +52 -25
  294. package/scripts/init/start-steps.ts +42 -9
  295. package/scripts/init/start.ts +40 -10
  296. package/scripts/issue/behavior-change-lint.ts +0 -1
  297. package/scripts/issue/defect-rate-cli.ts +3 -3
  298. package/scripts/issue/defect-rate.ts +1 -2
  299. package/scripts/{git → issue}/git-next-issues.ts +37 -8
  300. package/scripts/issue/issue-backlinks-cli.ts +1 -5
  301. package/scripts/issue/issue-cite-cli.ts +2 -6
  302. package/scripts/issue/issue-cite.ts +19 -3
  303. package/scripts/issue/issue-classification.ts +1 -9
  304. package/scripts/issue/issue-closing-pr.ts +4 -4
  305. package/scripts/issue/issue-comment-cli.ts +2 -2
  306. package/scripts/issue/issue-file-cli.ts +5 -5
  307. package/scripts/issue/issue-file.ts +2 -2
  308. package/scripts/issue/issue-fold-cli.ts +1 -1
  309. package/scripts/issue/issue-fold-existing-cli.ts +1 -1
  310. package/scripts/{git → issue}/issue-labels.ts +20 -0
  311. package/scripts/issue/issue-lint-cli.ts +1 -1
  312. package/scripts/issue/issue-merged.ts +2 -2
  313. package/scripts/issue/issue-rank.ts +89 -0
  314. package/scripts/issue/issue-read-cli.ts +8 -47
  315. package/scripts/issue/issue-read.ts +0 -2
  316. package/scripts/issue/issue-report-failures.ts +80 -0
  317. package/scripts/issue/issue-scout-cli.ts +1 -7
  318. package/scripts/issue/issue-scout-closed.ts +2 -2
  319. package/scripts/issue/issue-scout.ts +0 -2
  320. package/scripts/issue/issue-state-cli.ts +5 -46
  321. package/scripts/issue/issue-state.ts +1 -5
  322. package/scripts/issue/markdown-section.ts +1 -1
  323. package/scripts/issue/measure-rerun-cli.ts +1 -1
  324. package/scripts/issue/reproduction-measure.ts +1 -1
  325. package/scripts/josh/cli-body.ts +1 -1
  326. package/scripts/josh/file-map-stamp.ts +0 -3
  327. package/scripts/josh/josh-command-map.ts +2 -102
  328. package/scripts/josh/josh-commands-ai.ts +9 -102
  329. package/scripts/josh/josh-commands-backlog.ts +5 -1
  330. package/scripts/josh/josh-commands-development.ts +10 -3
  331. package/scripts/josh/josh-commands-issue.ts +2 -2
  332. package/scripts/josh/josh-commands-maintenance.ts +7 -0
  333. package/scripts/josh/josh-commands-project.ts +7 -1
  334. package/scripts/josh/josh-commands-run.ts +114 -0
  335. package/scripts/josh/josh-commands-versioning.ts +8 -0
  336. package/scripts/josh/josh-commands-workflow.ts +2 -2
  337. package/scripts/josh/path-decision.ts +0 -3
  338. package/scripts/josh/process-owner.ts +16 -0
  339. package/scripts/josh/session-language-cli.ts +0 -1
  340. package/scripts/lane/lane-await.ts +3 -6
  341. package/scripts/lane/lane-capacity.ts +6 -3
  342. package/scripts/lane/lane-child-invocation.ts +20 -7
  343. package/scripts/lane/lane-child-marker.ts +16 -2
  344. package/scripts/lane/lane-cli.ts +33 -18
  345. package/scripts/lane/lane-close.ts +1 -3
  346. package/scripts/lane/lane-dispatch.ts +3 -4
  347. package/scripts/lane/lane-environment.ts +0 -9
  348. package/scripts/lane/lane-handoff.ts +38 -0
  349. package/scripts/lane/lane-launch-cli.ts +21 -11
  350. package/scripts/lane/lane-open.ts +0 -3
  351. package/scripts/lane/lane-output.ts +0 -1
  352. package/scripts/lane/lane-registry.ts +9 -0
  353. package/scripts/lane/lane-report.ts +10 -4
  354. package/scripts/lane/openai-lane-ship.ts +2 -0
  355. package/scripts/lane/openai-lane-supervisor-decision.ts +2 -1
  356. package/scripts/lane/openai-lane-supervisor.ts +6 -4
  357. package/scripts/lane/openai-review-broker.ts +3 -0
  358. package/scripts/lib/bounded-pool.ts +1 -0
  359. package/scripts/lib/json-value.ts +5 -4
  360. package/scripts/lib/poll.ts +3 -1
  361. package/scripts/lib/timed-fetch.ts +15 -0
  362. package/scripts/lib/timeouts.ts +13 -0
  363. package/scripts/{yaml → lib}/yaml-document.ts +3 -1
  364. package/scripts/{bytes → lines}/bytes-command.ts +0 -2
  365. package/scripts/lines/lines-command.ts +0 -1
  366. package/scripts/lint/lint-related-scope.ts +0 -1
  367. package/scripts/lint/lint-related.ts +1 -1
  368. package/scripts/{git → notify}/telegram-notify.ts +2 -2
  369. package/scripts/{git → notify}/telegram-test.ts +4 -4
  370. package/scripts/observations/observation-ledger-home.ts +0 -1
  371. package/scripts/observations/observation-ledger-line.ts +0 -1
  372. package/scripts/observations/observation-ledger-migrate.ts +1 -1
  373. package/scripts/observations/observations-flush-landing.ts +3 -3
  374. package/scripts/observations/observations-flush.ts +2 -2
  375. package/scripts/overrides/lockfile-overrides.ts +1 -1
  376. package/scripts/overrides/overrides-logic.ts +1 -1
  377. package/scripts/package/package-scout-cli.ts +2 -7
  378. package/scripts/package/package-scout.ts +0 -2
  379. package/scripts/propagate/propagate-git-failure.ts +0 -1
  380. package/scripts/propagate/propagate-git.ts +0 -2
  381. package/scripts/propagate/propagate-plan.ts +185 -0
  382. package/scripts/propagate/propagate-publish.ts +2 -3
  383. package/scripts/propagate/propagate-run.ts +5 -3
  384. package/scripts/propagate/propagate-steps.ts +19 -6
  385. package/scripts/propagate/propagate-targets.ts +13 -6
  386. package/scripts/propagate/propagate.ts +60 -46
  387. package/scripts/refactor/import-graph.ts +0 -1
  388. package/scripts/refactor/refactor-lint.ts +0 -2
  389. package/scripts/refactor/refactor-scan.ts +0 -1
  390. package/scripts/refactor/refactor-targets.ts +0 -1
  391. package/scripts/registry-migration/migrate-logic.ts +1 -2
  392. package/scripts/registry-migration/migrate.ts +19 -9
  393. package/scripts/release/github-release-cli.ts +8 -6
  394. package/scripts/release/github-release-environment.ts +46 -0
  395. package/scripts/release/github-release.ts +151 -94
  396. package/scripts/release/release-history.ts +0 -1
  397. package/scripts/release/release-plan.ts +0 -1
  398. package/scripts/release/release-publish.ts +2 -3
  399. package/scripts/release/release-scope-cli.ts +1 -2
  400. package/scripts/release/release-tag.ts +2 -4
  401. package/scripts/repo/auto-merge-setting-logic.ts +1 -4
  402. package/scripts/repo/repo-setting.ts +1 -1
  403. package/scripts/repo/repository-labels.ts +3 -3
  404. package/scripts/repo/required-checks-logic.ts +206 -0
  405. package/scripts/repo/required-checks-report.ts +71 -0
  406. package/scripts/repo/ruleset-check-cli.ts +53 -0
  407. package/scripts/repo/ruleset-check.ts +147 -0
  408. package/scripts/report/report-lint-cli.ts +0 -4
  409. package/scripts/review/disposition-cli.ts +1 -1
  410. package/scripts/review/live-evidence.ts +1 -1
  411. package/scripts/review/review-attest-cli.ts +0 -6
  412. package/scripts/review/review-attest.ts +48 -16
  413. package/scripts/review/review-brief-cli.ts +72 -8
  414. package/scripts/review/review-brief.ts +67 -9
  415. package/scripts/review/review-diff-parts.ts +89 -0
  416. package/scripts/review/review-diff-write.ts +97 -0
  417. package/scripts/review/review-finding-ledger.ts +0 -1
  418. package/scripts/review/review-record-cli.ts +1 -1
  419. package/scripts/review/review-record.ts +0 -1
  420. package/scripts/review/review-round2-cli.ts +1 -1
  421. package/scripts/review/review-stamps.ts +6 -2
  422. package/scripts/review/review-tree.ts +14 -2
  423. package/scripts/rules/decision-oracle-stage.ts +18 -0
  424. package/scripts/rules/decision-oracle.ts +10 -7
  425. package/scripts/rules/delivered-rules.ts +9 -1
  426. package/scripts/rules/destructive-command.ts +119 -0
  427. package/scripts/rules/direct-filing.ts +1 -1
  428. package/scripts/rules/file-body.ts +0 -3
  429. package/scripts/rules/filing-cap.ts +0 -2
  430. package/scripts/rules/gh-api.ts +7 -2
  431. package/scripts/rules/git-argv.ts +18 -7
  432. package/scripts/rules/git-force.ts +0 -2
  433. package/scripts/rules/implementation-cut.ts +1 -2
  434. package/scripts/rules/index-guard.ts +71 -0
  435. package/scripts/rules/issue-citation.ts +50 -25
  436. package/scripts/rules/issue-fold.ts +1 -2
  437. package/scripts/rules/lane-background.ts +15 -7
  438. package/scripts/rules/lane-carry-conflict.ts +1 -2
  439. package/scripts/rules/lane-park.ts +14 -8
  440. package/scripts/rules/last-prompt.ts +1 -0
  441. package/scripts/rules/oracle-consulted.ts +1 -1
  442. package/scripts/rules/oracle-firing.ts +1 -0
  443. package/scripts/rules/oracle-list-cli.ts +0 -3
  444. package/scripts/rules/permission-guards.ts +14 -0
  445. package/scripts/rules/pre-gate-cut.ts +2 -2
  446. package/scripts/rules/protected-files.ts +74 -0
  447. package/scripts/rules/reply-language.ts +1 -1
  448. package/scripts/rules/rule-body-guard.ts +0 -3
  449. package/scripts/rules/rule-value-cli.ts +0 -1
  450. package/scripts/rules/shell-body-trigger.ts +0 -1
  451. package/scripts/rules/shell-segments.ts +0 -1
  452. package/scripts/rules/stop-rules.ts +13 -5
  453. package/scripts/rules/tail-commands.ts +1 -1
  454. package/scripts/rules/test-declared-commit.ts +1 -1
  455. package/scripts/rules/third-party-write.ts +0 -1
  456. package/scripts/rules/worktree-guard.ts +26 -9
  457. package/scripts/run/run-carry-cli.ts +0 -2
  458. package/scripts/run/run-carry-stash.ts +2 -2
  459. package/scripts/run/run-carry-streak.ts +1 -1
  460. package/scripts/run/run-cut-cli.ts +0 -7
  461. package/scripts/run/run-cut.ts +8 -54
  462. package/scripts/run/run-ending-cli.ts +1 -1
  463. package/scripts/run/run-ending.ts +1 -4
  464. package/scripts/run/run-entry-cli.ts +101 -24
  465. package/scripts/run/run-entry.ts +0 -1
  466. package/scripts/run/run-event-cli.ts +0 -2
  467. package/scripts/run/run-event-follow.ts +1 -0
  468. package/scripts/run/run-event-render.ts +1 -1
  469. package/scripts/run/run-event-scope.ts +53 -4
  470. package/scripts/run/run-event-stream.ts +0 -3
  471. package/scripts/run/run-event-watch.ts +1 -0
  472. package/scripts/run/run-halfrun-resume.ts +20 -7
  473. package/scripts/run/run-headless.ts +24 -8
  474. package/scripts/run/run-hold-cli.ts +33 -10
  475. package/scripts/run/run-hold.ts +25 -5
  476. package/scripts/run/run-issue-number.ts +1 -1
  477. package/scripts/run/run-liveness-cli.ts +1 -1
  478. package/scripts/run/run-liveness.ts +2 -3
  479. package/scripts/run/run-merge-cli.ts +5 -13
  480. package/scripts/run/run-merge-steps.ts +5 -5
  481. package/scripts/run/run-merge.ts +1 -1
  482. package/scripts/run/run-next-cli.ts +1 -1
  483. package/scripts/run/run-parent-cut-hook.ts +143 -0
  484. package/scripts/run/run-preflight.ts +2 -9
  485. package/scripts/run/run-prep-cli.ts +2 -2
  486. package/scripts/run/run-prep-locate.ts +1 -1
  487. package/scripts/run/run-progress-cli.ts +4 -7
  488. package/scripts/run/run-progress-clock.ts +6 -34
  489. package/scripts/run/run-progress-config.ts +0 -4
  490. package/scripts/run/run-progress-read.ts +3 -3
  491. package/scripts/run/run-progress.ts +22 -10
  492. package/scripts/run/run-prrun-resume.ts +117 -0
  493. package/scripts/run/run-report-cli.ts +1 -2
  494. package/scripts/run/run-report.ts +0 -1
  495. package/scripts/run/run-retrospective.ts +1 -1
  496. package/scripts/run/run-review-cli.ts +0 -3
  497. package/scripts/run/run-review-steps.ts +2 -0
  498. package/scripts/run/run-review.ts +0 -2
  499. package/scripts/run/run-ship-cli.ts +27 -77
  500. package/scripts/run/run-ship-detach.ts +1 -0
  501. package/scripts/run/run-ship-next.ts +106 -0
  502. package/scripts/run/run-ship-preflight.ts +87 -0
  503. package/scripts/run/run-ship-return.ts +8 -3
  504. package/scripts/run/run-ship-review-steps.ts +23 -30
  505. package/scripts/run/run-ship-review.ts +20 -0
  506. package/scripts/run/run-ship-scoped.ts +45 -0
  507. package/scripts/run/run-ship-stage.ts +5 -1
  508. package/scripts/run/run-ship-steps.ts +105 -0
  509. package/scripts/run/run-ship.ts +2 -1
  510. package/scripts/run/run-stage-read.ts +62 -0
  511. package/scripts/run/run-stage.ts +160 -0
  512. package/scripts/run/run-status-cli.ts +1 -1
  513. package/scripts/run/run-step-cli.ts +21 -14
  514. package/scripts/run/run-step.ts +1 -1
  515. package/scripts/run/run-stop-notify.ts +1 -3
  516. package/scripts/run/run-stranded-cli.ts +0 -4
  517. package/scripts/run/run-stranded-detect.ts +2 -2
  518. package/scripts/run/run-tail-cli.ts +17 -11
  519. package/scripts/run/run-tail.ts +2 -0
  520. package/scripts/run/run-tidy-lanes.ts +2 -1
  521. package/scripts/run/run-tidy-stashes.ts +12 -12
  522. package/scripts/run/run-wake-cli.ts +4 -5
  523. package/scripts/run/run-wake-describe.ts +19 -1
  524. package/scripts/run/run-wake-loop.ts +2 -2
  525. package/scripts/run/run-wake.ts +2 -4
  526. package/scripts/run/run-watcher-guard-cli.ts +0 -4
  527. package/scripts/run/run-watcher-guard.ts +9 -7
  528. package/scripts/run/run-watcher-hook.ts +1 -1
  529. package/scripts/safe-chain/ci-installer-pin.ts +11 -5
  530. package/scripts/safe-chain/project-config.ts +1 -1
  531. package/scripts/security/security-audit-provision-logic.ts +0 -1
  532. package/scripts/security/security-audit-provision.ts +3 -2
  533. package/scripts/security/security-audit.ts +0 -1
  534. package/scripts/security/security-updates-logic.ts +0 -1
  535. package/scripts/sonar/sonar-hotspots-cli.ts +10 -52
  536. package/scripts/sonar/sonar-hotspots.ts +0 -1
  537. package/scripts/sonar/sonar-new-code-cli.ts +150 -0
  538. package/scripts/sonar/sonar-new-code.ts +79 -0
  539. package/scripts/sonar/sonar-project.ts +97 -0
  540. package/scripts/split/split-assess-cli.ts +1 -1
  541. package/scripts/split/split-assess.ts +2 -5
  542. package/scripts/sync/managed-config-scope-cli.ts +1 -1
  543. package/scripts/sync/skill-migration.ts +0 -1
  544. package/scripts/sync/sync-hook-safety.ts +2 -3
  545. package/scripts/sync/sync.ts +1 -8
  546. package/scripts/sync/template-source-logic.ts +0 -1
  547. package/scripts/sync/workflow-pin-logic.ts +16 -28
  548. package/scripts/test/test-declared-logic.ts +0 -1
  549. package/scripts/test/test-declared.ts +0 -2
  550. package/scripts/test/test-red-commit.ts +2 -2
  551. package/scripts/test/test-red.ts +14 -7
  552. package/scripts/test/test-type-logic.ts +1 -1
  553. package/scripts/test/unit-worker-share.ts +7 -16
  554. package/scripts/time-runtime/time-batch-guard.ts +1 -2
  555. package/scripts/time-runtime/time-bundle-call.ts +2 -3
  556. package/scripts/time-runtime/time-bundles.ts +0 -4
  557. package/scripts/time-runtime/time-density-hook.ts +0 -2
  558. package/scripts/time-runtime/time-followup-stage.ts +1 -1
  559. package/scripts/time-runtime/time-format.ts +0 -73
  560. package/scripts/time-runtime/time-round-trips.ts +0 -4
  561. package/scripts/time-runtime/time-single-check.ts +1 -1
  562. package/scripts/time-runtime/time-spans.ts +1 -1
  563. package/scripts/time-runtime/time-transcript-line.ts +1 -2
  564. package/scripts/ui/ui-routes-cli.ts +0 -5
  565. package/scripts/ui/ui-routes.ts +0 -5
  566. package/scripts/version/effective-upstream.ts +2 -2
  567. package/scripts/version/latest-corepack.ts +7 -9
  568. package/scripts/version/latest-scope-cli.ts +0 -2
  569. package/scripts/version/latest-update.ts +0 -2
  570. package/scripts/version/npm-registry.ts +97 -0
  571. package/scripts/version/publishable-range-check.ts +1 -1
  572. package/scripts/version/release-hold.ts +0 -4
  573. package/scripts/version/running-binary.ts +2 -2
  574. package/scripts/version/version-check-logic.ts +0 -2
  575. package/scripts/version/version-commands.ts +5 -4
  576. package/scripts/version/version-remote.ts +28 -14
  577. package/scripts/version/version-targets.ts +4 -4
  578. package/templates/sonar-project.properties +28 -1
  579. package/templates/workflows/dependabot-auto-merge.yml +5 -3
  580. package/templates/workflows/github-release.yml +81 -0
  581. package/prompts/collaboration-workflow/cross-repo-epic.md +0 -5
  582. package/prompts/collaboration-workflow/epic-audit.md +0 -5
  583. package/prompts/collaboration-workflow/epic-bundle.md +0 -5
  584. package/scripts/init/plugin-install-hint.ts +0 -47
  585. package/scripts/version/parse-json.ts +0 -13
  586. /package/scripts/{git → followup}/git-followup-stages.ts +0 -0
  587. /package/scripts/{git → gh}/git-gh-api-path.ts +0 -0
  588. /package/scripts/{git → gh}/git-gh-command.ts +0 -0
  589. /package/scripts/{git → gh}/git-gh-issue-write.ts +0 -0
  590. /package/scripts/{git → gh}/git-gh-issue.ts +0 -0
  591. /package/scripts/{git → gh}/git-gh-pr-auto-merge.ts +0 -0
  592. /package/scripts/{git → gh}/git-gh-pr-snapshot.ts +0 -0
  593. /package/scripts/{git → gh}/git-gh-reachability.ts +0 -0
  594. /package/scripts/{git → gh}/git-gh-repo.ts +0 -0
  595. /package/scripts/{git → gh}/git-gh-rest-state.ts +0 -0
  596. /package/scripts/{git → gh}/git-pr-checks-watch.ts +0 -0
  597. /package/scripts/{git → gh}/git-pr-error.ts +0 -0
  598. /package/scripts/{git → gh}/git-pr-messages.ts +0 -0
  599. /package/scripts/{git → gh}/github-issue-url.ts +0 -0
  600. /package/scripts/git/{stash-orphans.ts → stash/stash-orphans.ts} +0 -0
  601. /package/scripts/{git → issue}/issue-reference.ts +0 -0
  602. /package/scripts/{git → lib}/animation-helpers.ts +0 -0
  603. /package/scripts/{git → lib}/git-animation.ts +0 -0
  604. /package/scripts/{git → notify}/git-notify.ts +0 -0
  605. /package/scripts/{git → notify}/telegram-test-logic.ts +0 -0
@@ -9,6 +9,9 @@ import { run_hold_cli } from './run-hold-cli'
9
9
  import { run_next } from './run-next'
10
10
  import { run_prep } from './run-prep'
11
11
  import { run_prep_cli } from './run-prep-cli'
12
+ import { run_prrun_resume } from './run-prrun-resume'
13
+ import { run_stage, type StageCommand, type StageDecision } from './run-stage'
14
+ import { run_stage_read, type StageRead } from './run-stage-read'
12
15
  import { run_step } from './run-step'
13
16
 
14
17
  // `josh run:entry <N>` — one call for the fixed entry sequence a lane opens on (joshuafolkken/kit#2372).
@@ -27,7 +30,10 @@ const ARGV_OFFSET = 2
27
30
  const SUCCESS_EXIT_CODE = 0
28
31
  const FAILURE_EXIT_CODE = 1
29
32
  const ISSUE_NUMBER_PATTERN = /^[1-9]\d*$/u
30
- const USAGE = 'Usage: josh run:entry <issue-number>'
33
+ const USAGE = 'Usage: josh run:entry <issue-number> [--to kickoff|halfrun|prrun|fullrun]'
34
+ const TO_FLAG = '--to'
35
+ // The flag and its command.
36
+ const TO_ARGUMENT_COUNT = 2
31
37
  const should_forward_stderr = true
32
38
  const NEWLINE = '\n'
33
39
 
@@ -48,16 +54,42 @@ function parse_number(argv: ReadonlyArray<string>): string | undefined {
48
54
  return first
49
55
  }
50
56
 
57
+ interface EntryRequest {
58
+ issue_number: string
59
+ command: StageCommand
60
+ }
61
+
62
+ // `--to <command>` names how far the run goes (joshuafolkken/kit#3042); absent, it is `fullrun`.
63
+ // Anything else is refused.
64
+ function parse_command(rest: ReadonlyArray<string>): StageCommand | undefined {
65
+ if (rest.length === 0) return run_stage.DEFAULT_COMMAND
66
+
67
+ const [flag, value] = rest
68
+
69
+ if (flag !== TO_FLAG || rest.length !== TO_ARGUMENT_COUNT) return undefined
70
+
71
+ return run_stage.to_command(value)
72
+ }
73
+
74
+ function parse_request(argv: ReadonlyArray<string>): EntryRequest | undefined {
75
+ const issue_number = parse_number(argv.slice(0, 1))
76
+ const command = parse_command(argv.slice(1))
77
+
78
+ return issue_number === undefined || command === undefined ? undefined : { issue_number, command }
79
+ }
80
+
51
81
  function first_line(out: string): string {
52
82
  return out.split(NEWLINE)[0] ?? ''
53
83
  }
54
84
 
55
85
  // `run:hold <N>` prints one token — `hold`, `busy` or `unknown` — and forwards its explanation to
56
86
  // stderr, so the composite branches on the token and the reader still sees why. `--fullrun` marks the
57
- // hold as this entry's, since `run:entry` is `fullrun #N`'s alone (joshuafolkken/kit#2760).
58
- async function claim_hold(issue_number: string): Promise<string> {
87
+ // hold as a run whose implementation cut resumes as `fullrun #N` (joshuafolkken/kit#2760) — a
88
+ // `fullrun`'s, and a `prrun`'s, which runs `fullrun`'s steps; a `halfrun`'s hold is never marked.
89
+ async function claim_hold(issue_number: string, command: StageCommand): Promise<string> {
90
+ const mark = command === run_stage.HALFRUN ? [] : ['--fullrun']
59
91
  const held = await josh_command.josh_run(
60
- ['run:hold', issue_number, '--fullrun'],
92
+ ['run:hold', issue_number, ...mark],
61
93
  should_forward_stderr,
62
94
  )
63
95
 
@@ -131,31 +163,51 @@ function resume_report(issue_number: string, resume: Resume): number {
131
163
  // **A `halfrun` stopped before its commit is resumed, not claimed** (joshuafolkken/kit#2796): its hold
132
164
  // is kept over the verified diff, so the claim below would answer `busy` against it. The budget is asked
133
165
  // first, as for any run; then the hold is adopted and the run goes to the gate, skipping everything up
134
- // to and including implementation.
135
- async function resume_halfrun(issue_number: string): Promise<number> {
166
+ // to and including implementation. **A `prrun` stopped before its merge is resumed the same way**
167
+ // (joshuafolkken/kit#3023), under the token that says what is left of it.
168
+ async function resume_stopped(
169
+ issue_number: string,
170
+ token: string,
171
+ stopped_run: { adopt: (issue: string) => Promise<boolean> },
172
+ ): Promise<number> {
136
173
  const cost = await check_cost()
137
174
 
138
- if (cost === run_entry.COST_OVER) {
139
- return stop_report(issue_number, HALFRUN_RESUME_TOKEN, cost, COST_STOP_NOTE)
140
- }
175
+ if (cost === run_entry.COST_OVER) return stop_report(issue_number, token, cost, COST_STOP_NOTE)
141
176
 
142
- if (!(await run_halfrun_resume.adopt(issue_number))) {
177
+ if (!(await stopped_run.adopt(issue_number))) {
143
178
  return stop_report(issue_number, run_hold_cli.BUSY_VERDICT, cost, HOLD_STOP_NOTE)
144
179
  }
145
180
 
146
- console.info(`entry #${issue_number} — resume: ${HALFRUN_RESUME_TOKEN}`)
181
+ console.info(`entry #${issue_number} — resume: ${token}`)
147
182
 
148
183
  return SUCCESS_EXIT_CODE
149
184
  }
150
185
 
151
- async function open_run(issue_number: string): Promise<number> {
152
- const resume = await ask_resume(issue_number)
186
+ // The stopped run a decision picks up: a `halfrun` stop resumes at the gate, a `prrun` stop at
187
+ // `followup` under its own token. `undefined` for any other start, so the ordinary claim decides.
188
+ async function resume_any(
189
+ issue_number: string,
190
+ decision: StageDecision,
191
+ stage: StageRead,
192
+ ): Promise<number | undefined> {
193
+ if (decision.state === run_stage.HALFRUN_STOPPED) {
194
+ return await resume_stopped(issue_number, HALFRUN_RESUME_TOKEN, run_halfrun_resume)
195
+ }
153
196
 
154
- if (resume.token !== run_cut_report.FRESH_VERDICT) return resume_report(issue_number, resume)
197
+ return stage.prrun_token === undefined
198
+ ? undefined
199
+ : await resume_stopped(issue_number, stage.prrun_token, run_prrun_resume)
200
+ }
155
201
 
156
- if (await run_halfrun_resume.is_pending(issue_number)) return await resume_halfrun(issue_number)
202
+ // **A command whose stopping point the issue has already reached redoes nothing** (joshuafolkken/kit#3042)
203
+ // — the stage line is the whole report. A merged issue is the exception: the ordinary entry already
204
+ // answers it (`already-done`, or `keep-work` over a lane's uncommitted work), so it is left to that.
205
+ function is_settled(decision: StageDecision): boolean {
206
+ return decision.is_reached && decision.state !== run_stage.MERGED
207
+ }
157
208
 
158
- const hold = await claim_hold(issue_number)
209
+ async function claim_run({ issue_number, command }: EntryRequest): Promise<number> {
210
+ const hold = await claim_hold(issue_number, command)
159
211
 
160
212
  if (hold !== run_hold_cli.HOLD_VERDICT) {
161
213
  return stop_report(issue_number, hold, run_entry.COST_SKIPPED, HOLD_STOP_NOTE)
@@ -170,16 +222,45 @@ async function open_run(issue_number: string): Promise<number> {
170
222
  return emit({ issue_number, hold, cost, verdict: reads.verdict, report: reads.report })
171
223
  }
172
224
 
225
+ // A carried cut is asked first, before anything is read (`run:cut --resume`); `kickoff` claims and cuts
226
+ // nothing, so it never asks. `undefined` when no cut is waiting.
227
+ async function resume_cut(request: EntryRequest): Promise<number | undefined> {
228
+ if (request.command === run_stage.KICKOFF) return undefined
229
+
230
+ const resume = await ask_resume(request.issue_number)
231
+
232
+ return resume.token === run_cut_report.FRESH_VERDICT
233
+ ? undefined
234
+ : resume_report(request.issue_number, resume)
235
+ }
236
+
237
+ // `kickoff` stops at the stage line whatever it says — it plans, and claims nothing.
238
+ async function open_run(request: EntryRequest): Promise<number> {
239
+ const { issue_number, command } = request
240
+ const cut = await resume_cut(request)
241
+
242
+ if (cut !== undefined) return cut
243
+
244
+ const stage = await run_stage_read.read_stage(issue_number)
245
+ const decision = run_stage.decide(stage.state, command)
246
+
247
+ console.info(run_stage.format_decision(issue_number, decision))
248
+
249
+ if (command === run_stage.KICKOFF || is_settled(decision)) return SUCCESS_EXIT_CODE
250
+
251
+ return (await resume_any(issue_number, decision, stage)) ?? (await claim_run(request))
252
+ }
253
+
173
254
  async function run(argv: ReadonlyArray<string>): Promise<number> {
174
- const issue_number = parse_number(argv)
255
+ const request = parse_request(argv)
175
256
 
176
- if (issue_number === undefined) {
257
+ if (request === undefined) {
177
258
  console.error(USAGE)
178
259
 
179
260
  return FAILURE_EXIT_CODE
180
261
  }
181
262
 
182
- return await open_run(issue_number)
263
+ return await open_run(request)
183
264
  }
184
265
 
185
266
  async function main(argv: ReadonlyArray<string>): Promise<void> {
@@ -188,12 +269,8 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
188
269
 
189
270
  const run_entry_cli = {
190
271
  HALFRUN_RESUME_TOKEN,
191
- SUCCESS_EXIT_CODE,
192
- USAGE,
193
- check_cost,
194
- claim_hold,
195
- main,
196
272
  parse_number,
273
+ parse_request,
197
274
  run,
198
275
  }
199
276
 
@@ -84,7 +84,6 @@ const run_entry = {
84
84
  COST_SKIPPED,
85
85
  COST_UNDER,
86
86
  NO_VERDICT,
87
- SUMMARY_PREFIX,
88
87
  exit_code,
89
88
  format_report,
90
89
  can_proceed,
@@ -193,8 +193,6 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
193
193
  }
194
194
 
195
195
  const run_event_cli = {
196
- USAGE,
197
- main,
198
196
  run,
199
197
  watch_start,
200
198
  }
@@ -52,6 +52,7 @@ async function follow(
52
52
  let read = ports.read(position)
53
53
 
54
54
  while (read.events.length === 0 && ports.now() < deadline) {
55
+ // eslint-disable-next-line no-await-in-loop -- polling: each read waits on the state the previous one saw
55
56
  await ports.sleep(options.tick_ms)
56
57
  read = ports.read(position)
57
58
  }
@@ -69,7 +69,7 @@ function render(event: RunEvent, lang: string): string {
69
69
  return [clock_of(event.at), label_of(event.kind, lang), event.text].join(FIELD_SEPARATOR)
70
70
  }
71
71
 
72
- const run_event_render = { KIND_LABELS, clock_of, label_of, render }
72
+ const run_event_render = { clock_of, label_of, render }
73
73
 
74
74
  export type { KindLabel }
75
75
  export { run_event_render }
@@ -91,6 +91,22 @@ const SHIP_POSITION_KINDS: ReadonlySet<string> = new Set([
91
91
  run_event_stream.EVENT_KIND.SHIP_STOP,
92
92
  ])
93
93
 
94
+ const KIND = run_event_stream.EVENT_KIND
95
+
96
+ // The parent's record of the batch around a child — its dispatch, park and split, the retrospective
97
+ // whose summary may name an issue it filed, and the strand whose text carries the whole invocation
98
+ // (`backlogrun #<N1> #<N2> …`). Each can name the child, yet none is a position the child itself is at,
99
+ // so a lane child never reads one as its own.
100
+ const BATCH_RECORD_KINDS: ReadonlySet<string> = new Set([
101
+ KIND.CHILD_LAUNCH,
102
+ KIND.PARK,
103
+ KIND.SPLIT,
104
+ KIND.RETROSPECTIVE,
105
+ KIND.STRANDED,
106
+ ])
107
+
108
+ const ISSUE_REFERENCE = /#(\d+)/u
109
+
94
110
  function is_foreign_ship_event(event: RunEvent, issue: string): boolean {
95
111
  return SHIP_POSITION_KINDS.has(event.kind) && !event.text.startsWith(`#${issue} `)
96
112
  }
@@ -99,16 +115,49 @@ function is_own_ship_event(event: RunEvent, issue: string): boolean {
99
115
  return SHIP_POSITION_KINDS.has(event.kind) && !is_foreign_ship_event(event, issue)
100
116
  }
101
117
 
118
+ // **A lane child's position is read only from events that name its own issue** (joshuafolkken/kit#3039).
119
+ // The parent and every lane append to one stream under one carry scope, so anything else on it is another
120
+ // run's: another lane's merge told a planned child to stop, the parent's stall (which names no issue)
121
+ // pointed it at `backlog:next`, and another lane's cut at `run:cut --resume`. The child's own merge and
122
+ // outage stay, so the parent-only stop in `run-step.ts` still holds; the parent keeps reading everything.
123
+ function names_issue(event: RunEvent, issue: string): boolean {
124
+ return ISSUE_REFERENCE.exec(event.text)?.[1] === issue
125
+ }
126
+
127
+ function is_lane_position(event: RunEvent, issue: string): boolean {
128
+ return !BATCH_RECORD_KINDS.has(event.kind) && names_issue(event, issue)
129
+ }
130
+
131
+ // A lane child's attempt begins at its own newest launch. A child re-dispatched after an outage — or
132
+ // relaunched after a cut, whose resume `run:cut --resume` answers at the entry — shares the scope with
133
+ // its previous attempt, and that attempt's outage would otherwise stop the new one at its entry `run:step`.
134
+ function since_own_launch(events: ReadonlyArray<RunEvent>, issue: string): ReadonlyArray<RunEvent> {
135
+ const launch = events.findLastIndex(
136
+ (event) => event.kind === KIND.CHILD_LAUNCH && names_issue(event, issue),
137
+ )
138
+
139
+ return events.slice(launch + 1)
140
+ }
141
+
142
+ function is_foreign_event(event: RunEvent, issue: string, is_lane_child: boolean): boolean {
143
+ if (is_lane_child) return !is_lane_position(event, issue)
144
+
145
+ return is_foreign_ship_event(event, issue)
146
+ }
147
+
102
148
  // The newest position for one issue's run: the scoped last event with other issues' ship positions left
103
- // out, and — where no scope applies, as in an interactive `fullrun` with no carry record — the issue's own
104
- // newest ship position, which its issue number already scopes. A determined scope with nothing in it yet
105
- // reads nothing: an earlier invocation's stop for the same issue is not this invocation's position.
149
+ // out — and, for a lane child, every event not naming its issue — and, where no scope applies, as in
150
+ // an interactive `fullrun` with no carry record, the issue's own newest ship position, which its issue
151
+ // number already scopes. A determined scope with nothing in it yet reads nothing: an earlier invocation's
152
+ // stop for the same issue is not this invocation's position.
106
153
  function last_issue_event(
107
154
  events: ReadonlyArray<RunEvent>,
108
155
  scope: EventScope,
109
156
  issue: string,
157
+ is_lane_child: boolean,
110
158
  ): RunEvent | undefined {
111
- const own = events.filter((event) => !is_foreign_ship_event(event, issue))
159
+ const attempt = is_lane_child ? since_own_launch(events, issue) : events
160
+ const own = attempt.filter((event) => !is_foreign_event(event, issue, is_lane_child))
112
161
 
113
162
  if (scope.kind === SINCE_SCOPE) return last_scoped_event(own, scope)
114
163
 
@@ -238,13 +238,10 @@ const run_event_stream = {
238
238
  EVENT_CAP,
239
239
  EVENT_KIND,
240
240
  EVENT_KINDS,
241
- EVENT_PREFIX,
242
- EVENT_SUFFIX,
243
241
  TRACE_KINDS,
244
242
  append,
245
243
  format_event,
246
244
  has_since,
247
- is_event_kind,
248
245
  read_events,
249
246
  read_from,
250
247
  read_last,
@@ -22,6 +22,7 @@ async function watch(ports: WatchPorts, position: number): Promise<number> {
22
22
  let next = position
23
23
 
24
24
  while (ports.should_continue()) {
25
+ // eslint-disable-next-line no-await-in-loop -- polling: each read waits on the state the previous one saw
25
26
  const read = await ports.pass(next)
26
27
 
27
28
  for (const event of read.events) ports.write(ports.render(event))
@@ -1,4 +1,4 @@
1
- import { run_hold, type HoldRead, type RunHold } from './run-hold'
1
+ import { run_hold, type HoldRead, type RunHold, type StopMarkFields } from './run-hold'
2
2
 
3
3
  // joshuafolkken/kit#2796: a `halfrun` stops before its commit and **keeps** its hold, because the
4
4
  // uncommitted, hand-verified work is exactly what a second run would trample. The person then types
@@ -38,7 +38,13 @@ function is_own_record(read: HoldRead, issue: string): boolean {
38
38
  return hold === undefined || hold.issue === issue || hold.issue === run_hold.UNNUMBERED_ISSUE
39
39
  }
40
40
 
41
- function mark_stop_at(target: string, issue: string): StopMark {
41
+ // `mark` is the `halfrun` stop's by default; a `prrun` stop passes its own (joshuafolkken/kit#3023), so
42
+ // the own-record check is one check whichever run is stopping.
43
+ function mark_stop_at(
44
+ target: string,
45
+ issue: string,
46
+ mark: StopMarkFields = run_hold.HALFRUN_STOP_FIELDS,
47
+ ): StopMark {
42
48
  const read = run_hold.read_hold(target)
43
49
 
44
50
  if (read.kind === 'unreadable') return UNREADABLE
@@ -47,7 +53,14 @@ function mark_stop_at(target: string, issue: string): StopMark {
47
53
 
48
54
  run_hold.release_hold(target)
49
55
 
50
- return run_hold.create_halfrun_stop_hold(target, issue) ? MARKED : FOREIGN
56
+ return run_hold.create_stop_hold(target, issue, mark) ? MARKED : FOREIGN
57
+ }
58
+
59
+ // The stopped run's record is replaced by this `fullrun`'s, shared with the `prrun` resume.
60
+ function take_over(target: string, issue: string): boolean {
61
+ run_hold.release_hold(target)
62
+
63
+ return run_hold.create_hold(target, issue, new Date(), true)
51
64
  }
52
65
 
53
66
  // `false` leaves the record untouched, so the ordinary claim that follows decides the tree exactly as
@@ -55,9 +68,7 @@ function mark_stop_at(target: string, issue: string): StopMark {
55
68
  function adopt_at(target: string, issue: string, is_dirty: boolean): boolean {
56
69
  if (!is_halfrun_stop(run_hold.read_hold(target), issue, is_dirty)) return false
57
70
 
58
- run_hold.release_hold(target)
59
-
60
- return run_hold.create_hold(target, issue, new Date(), true)
71
+ return take_over(target, issue)
61
72
  }
62
73
 
63
74
  // **An unreadable git directory is no resume**, never a crash: `run:entry` must still print its one
@@ -95,9 +106,11 @@ const run_halfrun_resume = {
95
106
  UNREADABLE,
96
107
  adopt,
97
108
  adopt_at,
98
- is_halfrun_stop,
109
+ hold_of,
110
+ hold_target,
99
111
  is_pending,
100
112
  mark_stop_at,
113
+ take_over,
101
114
  }
102
115
 
103
116
  export type { StopMark }
@@ -1,7 +1,7 @@
1
1
  import { lane_child_marker } from '#scripts/lane/lane-child-marker'
2
2
  import { lane_reap } from '#scripts/lane/lane-reap'
3
+ import { lane_registry } from '#scripts/lane/lane-registry'
3
4
  import { run_carry, type CarryRead, type RunCarry } from './run-carry'
4
- import { run_watcher_guard } from './run-watcher-guard'
5
5
 
6
6
  // The headless `backlogrun` parent (joshuafolkken/kit#2437). `run:wake` starts a cut's successor as
7
7
  // `claude -p`, and there a turn that ends is the process that ends: its background `lane:await` and
@@ -51,7 +51,7 @@ async function read_carry_here(): Promise<CarryRead | undefined> {
51
51
  async function must_keep_waiting(source: EnvironmentSource = process.env): Promise<boolean> {
52
52
  const is_candidate = is_headless(source) && lane_child_marker.marked_issue(source) === undefined
53
53
 
54
- if (!is_candidate || !(await run_watcher_guard.has_lanes_in_flight())) return false
54
+ if (!is_candidate || !(await lane_registry.has_lanes_in_flight())) return false
55
55
 
56
56
  return is_driving(await read_carry_here())
57
57
  }
@@ -73,10 +73,27 @@ function is_owned_here(carry: RunCarry, ancestry: () => ReadonlySet<number>): bo
73
73
  return carry.owner_pid !== undefined && ancestry().has(carry.owner_pid)
74
74
  }
75
75
 
76
- function is_driven_here(read: CarryRead | undefined, ancestry: () => ReadonlySet<number>): boolean {
77
- if (read?.kind !== 'carried' || !is_driving(read)) return false
76
+ function driven_here(
77
+ read: CarryRead | undefined,
78
+ ancestry: () => ReadonlySet<number>,
79
+ ): RunCarry | undefined {
80
+ if (read?.kind !== 'carried' || !is_driving(read)) return undefined
78
81
 
79
- return is_owned_here(read.carry, ancestry)
82
+ return is_owned_here(read.carry, ancestry) ? read.carry : undefined
83
+ }
84
+
85
+ /**
86
+ * The live, un-handed-off carry record this session drives as the `backlogrun` parent, or `undefined`
87
+ * for a lane child or any session that does not own one. Returned rather than tested so a caller that
88
+ * also needs the record's counters (the parent cut's cap, joshuafolkken/kit#2947) reads it once.
89
+ */
90
+ async function driving_carry(
91
+ source: EnvironmentSource = process.env,
92
+ ancestry: () => ReadonlySet<number> = lane_reap.own_ancestry,
93
+ ): Promise<RunCarry | undefined> {
94
+ if (lane_child_marker.marked_issue(source) !== undefined) return undefined
95
+
96
+ return driven_here(await read_carry_here(), ancestry)
80
97
  }
81
98
 
82
99
  /**
@@ -88,14 +105,13 @@ async function is_backlog_parent(
88
105
  source: EnvironmentSource = process.env,
89
106
  ancestry: () => ReadonlySet<number> = lane_reap.own_ancestry,
90
107
  ): Promise<boolean> {
91
- if (lane_child_marker.marked_issue(source) !== undefined) return false
92
-
93
- return is_driven_here(await read_carry_here(), ancestry)
108
+ return (await driving_carry(source, ancestry)) !== undefined
94
109
  }
95
110
 
96
111
  const run_headless = {
97
112
  HEADLESS_ENV_KEY,
98
113
  current_carry,
114
+ driving_carry,
99
115
  environment,
100
116
  is_backlog_parent,
101
117
  is_headless,
@@ -3,6 +3,7 @@ import { fileURLToPath } from 'node:url'
3
3
  import { run_halfrun_resume } from './run-halfrun-resume'
4
4
  import { run_hold, type HoldRead, type RunHold } from './run-hold'
5
5
  import { run_preflight, type PreflightDecision } from './run-preflight'
6
+ import { run_prrun_resume } from './run-prrun-resume'
6
7
  import { run_tidy_cli } from './run-tidy-cli'
7
8
 
8
9
  // `josh run:hold [<N>]` and `josh run:release [<N> | --force]` — the working-tree guard the typed
@@ -48,11 +49,13 @@ const FORCE_FLAG = '--force'
48
49
  // implementation cut outside a lane resumes as `fullrun #N` (joshuafolkken/kit#2760).
49
50
  const FULLRUN_FLAG = '--fullrun'
50
51
  const HALFRUN_STOP_FLAG = '--halfrun-stop'
52
+ // A `prrun`'s stop before merge (joshuafolkken/kit#3023): its record keeps the commit it stopped on.
53
+ const PRRUN_STOP_FLAG = '--prrun-stop'
51
54
  // The most a claim reads: the issue number and the one flag after it.
52
55
  const MAX_CLAIM_ARGUMENTS = 2
53
56
  const ISSUE_NUMBER_PATTERN = /^[1-9]\d*$/u
54
57
  const USAGE =
55
- 'Usage: josh run:hold [<issue-number> [--fullrun | --halfrun-stop]] | josh run:release [<issue-number> | --force]'
58
+ 'Usage: josh run:hold [<issue-number> [--fullrun | --halfrun-stop | --prrun-stop]] | josh run:release [<issue-number> | --force]'
56
59
 
57
60
  const HOLD_VERDICT = 'hold'
58
61
  const BUSY_VERDICT = 'busy'
@@ -65,6 +68,7 @@ const HELD_VERDICT = 'held'
65
68
 
66
69
  const FORCE_RELEASE_KIND = 'force-release'
67
70
  const HALFRUN_STOP_KIND = 'halfrun-stop'
71
+ const PRRUN_STOP_KIND = 'prrun-stop'
68
72
 
69
73
  interface ClaimRequest {
70
74
  kind: 'claim'
@@ -72,11 +76,20 @@ interface ClaimRequest {
72
76
  is_fullrun?: boolean
73
77
  }
74
78
 
79
+ interface StopRequest {
80
+ kind: typeof HALFRUN_STOP_KIND | typeof PRRUN_STOP_KIND
81
+ issue: string
82
+ }
83
+
75
84
  type HoldRequest =
76
85
  | ClaimRequest
86
+ | StopRequest
77
87
  | { kind: 'release'; claimant: string }
78
88
  | { kind: typeof FORCE_RELEASE_KIND }
79
- | { kind: typeof HALFRUN_STOP_KIND; issue: string }
89
+
90
+ function is_stop_request(request: HoldRequest): request is StopRequest {
91
+ return request.kind === HALFRUN_STOP_KIND || request.kind === PRRUN_STOP_KIND
92
+ }
80
93
 
81
94
  const FORCE_RELEASE_REQUEST: HoldRequest = { kind: FORCE_RELEASE_KIND }
82
95
 
@@ -84,12 +97,20 @@ function release_request(claimant: string): HoldRequest {
84
97
  return { kind: 'release', claimant }
85
98
  }
86
99
 
87
- // The flag after a numbered claim: absent, `--fullrun` or `--halfrun-stop`. Anything else is a usage
88
- // error.
100
+ const STOP_KIND_BY_FLAG: ReadonlyMap<string, typeof HALFRUN_STOP_KIND | typeof PRRUN_STOP_KIND> =
101
+ new Map([
102
+ [HALFRUN_STOP_FLAG, HALFRUN_STOP_KIND],
103
+ [PRRUN_STOP_FLAG, PRRUN_STOP_KIND],
104
+ ])
105
+
106
+ // The flag after a numbered claim: absent, `--fullrun`, `--halfrun-stop` or `--prrun-stop`. Anything
107
+ // else is a usage error.
89
108
  function numbered_claim(issue: string, flag: string | undefined): HoldRequest | undefined {
90
109
  if (flag === undefined) return { kind: 'claim', issue }
91
110
 
92
- if (flag === HALFRUN_STOP_FLAG) return { kind: HALFRUN_STOP_KIND, issue }
111
+ const stop_kind = STOP_KIND_BY_FLAG.get(flag)
112
+
113
+ if (stop_kind !== undefined) return { kind: stop_kind, issue }
93
114
 
94
115
  return flag === FULLRUN_FLAG ? { kind: 'claim', issue, is_fullrun: true } : undefined
95
116
  }
@@ -293,8 +314,12 @@ async function read_worktree(): Promise<string | undefined> {
293
314
 
294
315
  // **A `halfrun` stop marks its own record** (joshuafolkken/kit#2796) — the positive "this run has ended
295
316
  // over its verified diff" that `run:entry` adopts on `fullrun #N`. Another run's record is left alone.
296
- function mark_halfrun_stop(target: string, issue: string): number {
297
- const mark = run_halfrun_resume.mark_stop_at(target, issue)
317
+ // A `prrun` stop marks its record the same way, with the commit it stopped on (joshuafolkken/kit#3023).
318
+ async function mark_stop(target: string, request: StopRequest): Promise<number> {
319
+ const mark =
320
+ request.kind === PRRUN_STOP_KIND
321
+ ? await run_prrun_resume.mark_stop_at(target, request.issue)
322
+ : run_halfrun_resume.mark_stop_at(target, request.issue)
298
323
 
299
324
  if (mark === run_halfrun_resume.MARKED) return report_hold()
300
325
 
@@ -306,7 +331,7 @@ function mark_halfrun_stop(target: string, issue: string): number {
306
331
  async function dispatch(request: HoldRequest, target: string, is_linked: boolean): Promise<number> {
307
332
  if (request.kind === 'claim') return await claim(target, request, is_linked)
308
333
 
309
- if (request.kind === HALFRUN_STOP_KIND) return mark_halfrun_stop(target, request.issue)
334
+ if (is_stop_request(request)) return await mark_stop(target, request)
310
335
 
311
336
  if (request.kind === FORCE_RELEASE_KIND) return force_release(target)
312
337
 
@@ -351,8 +376,6 @@ const run_hold_cli = {
351
376
  RELEASED_VERDICT,
352
377
  UNKNOWN_VERDICT,
353
378
  USAGE,
354
- blocking_message,
355
- main,
356
379
  parse_request,
357
380
  run,
358
381
  }
@@ -52,6 +52,10 @@ interface RunHold {
52
52
  // the positive record that the run has *ended* over its verified diff, which is what lets
53
53
  // `fullrun #N` adopt the hold. A running `halfrun` or a `backlogrun` child never carries it.
54
54
  is_halfrun_stop?: boolean | undefined
55
+ // Set only at a `prrun`'s stop before merge (`run:hold <N> --prrun-stop`, joshuafolkken/kit#3023): the
56
+ // commit the green pull request stood on, so `fullrun #N` can tell an untouched branch — merge it —
57
+ // from one that moved since and has to pass the gate and the review again.
58
+ prrun_stop_head?: string | undefined
55
59
  }
56
60
 
57
61
  type HoldRead =
@@ -92,6 +96,7 @@ const run_hold_schema = z.object({
92
96
  pid: z.number(),
93
97
  is_fullrun: z.boolean().optional(),
94
98
  is_halfrun_stop: z.boolean().optional(),
99
+ prrun_stop_head: z.string().optional(),
95
100
  })
96
101
 
97
102
  // `undefined` for anything that is not a well-formed record, so the caller decides what a broken one
@@ -161,9 +166,24 @@ function create_hold(
161
166
  return stamp_file.create_stamp(target, build_hold(issue, now, is_fullrun))
162
167
  }
163
168
 
164
- // The claim a `halfrun` stop leaves behind: the same exclusive create, carrying the stop mark.
169
+ // What a stopped run's record carries on top of the claim: the `halfrun` stop's flag, or the commit a
170
+ // `prrun` stop stood on (joshuafolkken/kit#3023).
171
+ type StopMarkFields = Pick<RunHold, 'is_halfrun_stop' | 'prrun_stop_head'>
172
+
173
+ const HALFRUN_STOP_FIELDS: StopMarkFields = { is_halfrun_stop: true }
174
+
175
+ // The claim a stop leaves behind: the same exclusive create, carrying the stop mark.
176
+ function create_stop_hold(
177
+ target: string,
178
+ issue: string,
179
+ mark: StopMarkFields,
180
+ now: Date = new Date(),
181
+ ): boolean {
182
+ return stamp_file.create_stamp(target, { ...build_hold(issue, now), ...mark })
183
+ }
184
+
165
185
  function create_halfrun_stop_hold(target: string, issue: string, now: Date = new Date()): boolean {
166
- return stamp_file.create_stamp(target, { ...build_hold(issue, now), is_halfrun_stop: true })
186
+ return create_stop_hold(target, issue, HALFRUN_STOP_FIELDS, now)
167
187
  }
168
188
 
169
189
  // **A tree with uncommitted work in it is never handed over, however old its record is.** No age can
@@ -260,8 +280,9 @@ const run_hold = {
260
280
  UNNUMBERED_ISSUE,
261
281
  classify,
262
282
  create_halfrun_stop_hold,
283
+ create_stop_hold,
284
+ HALFRUN_STOP_FIELDS,
263
285
  create_hold,
264
- describe_holder,
265
286
  foreign_release_message,
266
287
  forced_release_message,
267
288
  held_message,
@@ -270,7 +291,6 @@ const run_hold = {
270
291
  is_own_hold,
271
292
  is_tree_dirty,
272
293
  own_release_command,
273
- parse_hold,
274
294
  race_message,
275
295
  read_hold,
276
296
  release_hold,
@@ -282,5 +302,5 @@ const run_hold = {
282
302
  write_hold,
283
303
  }
284
304
 
285
- export type { HoldRead, RunHold }
305
+ export type { HoldRead, RunHold, StopMarkFields }
286
306
  export { run_hold }
@@ -14,6 +14,6 @@ function require_issue_number(issue: string): void {
14
14
  if (!ISSUE_NUMBER_PATTERN.test(issue)) throw new Error(`${BAD_ISSUE_MESSAGE}${issue}`)
15
15
  }
16
16
 
17
- const run_issue_number = { BAD_ISSUE_MESSAGE, ISSUE_NUMBER_PATTERN, require_issue_number }
17
+ const run_issue_number = { ISSUE_NUMBER_PATTERN, require_issue_number }
18
18
 
19
19
  export { run_issue_number }
@@ -159,7 +159,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
159
159
  process.exitCode = await run(argv)
160
160
  }
161
161
 
162
- const run_liveness_cli = { USAGE, main, parse_request, run }
162
+ const run_liveness_cli = { USAGE, parse_request, run }
163
163
 
164
164
  if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
165
165