@joshuafolkken/kit 1.1050.0 → 1.1128.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 (630) hide show
  1. package/.claude/settings.json +9 -8
  2. package/.claude/skills/epic-commands/SKILL.md +5 -7
  3. package/.claude/skills/workflow-commands/SKILL.md +20 -12
  4. package/.claude/skills/workflow-commands/background-commands.md +36 -84
  5. package/.claude/skills/workflow-commands/backlogrun-child.md +1 -1
  6. package/.claude/skills/workflow-commands/backlogrun-lanes.md +8 -6
  7. package/.claude/skills/workflow-commands/backlogrun-progress.md +30 -33
  8. package/.claude/skills/workflow-commands/backlogrun-steps.md +12 -12
  9. package/.claude/skills/workflow-commands/backlogrun.md +2 -2
  10. package/.claude/skills/workflow-commands/chain-rule.md +4 -2
  11. package/.claude/skills/workflow-commands/delegation.md +3 -3
  12. package/.claude/skills/workflow-commands/followup-reference.md +1 -1
  13. package/.claude/skills/workflow-commands/followup.md +7 -3
  14. package/.claude/skills/workflow-commands/fullrun-steps.md +3 -2
  15. package/.claude/skills/workflow-commands/fullrun.md +8 -6
  16. package/.claude/skills/workflow-commands/halfrun.md +19 -21
  17. package/.claude/skills/workflow-commands/issue-comments.md +1 -1
  18. package/.claude/skills/workflow-commands/issue-fold-existing.md +10 -10
  19. package/.claude/skills/workflow-commands/issue-scout.md +1 -1
  20. package/.claude/skills/workflow-commands/kickoff.md +9 -4
  21. package/.claude/skills/workflow-commands/latest-gate.md +8 -16
  22. package/.claude/skills/workflow-commands/needs-human-review.md +1 -1
  23. package/.claude/skills/workflow-commands/observation-filing.md +3 -3
  24. package/.claude/skills/workflow-commands/pre-gate-cut.md +4 -8
  25. package/.claude/skills/workflow-commands/prerequisite.md +1 -1
  26. package/.claude/skills/workflow-commands/prrun.md +36 -0
  27. package/.claude/skills/workflow-commands/retrospective.md +1 -1
  28. package/.claude/skills/workflow-commands/split-assessment.md +4 -18
  29. package/.claude/skills/workflow-commands/working-tree-hold.md +22 -2
  30. package/.codex/hooks.json +16 -20
  31. package/.github/actions/setup-node/action.yml +33 -0
  32. package/.github/actions/setup-pnpm/action.yml +93 -0
  33. package/.github/dependabot.yml +5 -1
  34. package/.github/workflows/auto-tag.yml +2 -3
  35. package/.github/workflows/ci.yml +31 -134
  36. package/.github/workflows/dependabot-auto-merge.yml +1 -0
  37. package/.github/workflows/pr-classification.yml +6 -44
  38. package/.github/workflows/production.yml +1 -0
  39. package/.github/workflows/publish.yml +43 -47
  40. package/.github/workflows/sonar-qube.yml +41 -4
  41. package/.pnpmfile.mjs +29 -0
  42. package/AGENTS.md +5 -2
  43. package/CLAUDE.md +33 -27
  44. package/GEMINI.md +5 -2
  45. package/README.md +66 -20
  46. package/SECURITY.md +37 -6
  47. package/cspell/index.yaml +6 -1
  48. package/dist/CLAUDE.basic.md +6 -6
  49. package/dist/CLAUDE.md +33 -27
  50. package/dist/CLAUDE.static.md +6 -6
  51. package/dist/config-merge/index.js +48 -12
  52. package/dist/hooks/batch-guard.js +4 -4
  53. package/dist/hooks/{chunk-7VPDUBRN.js → chunk-4JZDP5X5.js} +152 -155
  54. package/dist/hooks/{chunk-HJIISEAC.js → chunk-5SD2YM7Z.js} +5 -13
  55. package/dist/hooks/{chunk-NAS4C7GP.js → chunk-77J7IEQM.js} +2 -2
  56. package/dist/hooks/{chunk-DMQN45FN.js → chunk-7HVB7SZG.js} +3 -3
  57. package/dist/hooks/{chunk-RLDX5SOC.js → chunk-AIOIOMPX.js} +4413 -1970
  58. package/dist/hooks/{chunk-5BK3K7V4.js → chunk-M7QKEKWO.js} +873 -2049
  59. package/dist/hooks/{chunk-WQ4OSBSS.js → chunk-MKVGBQPA.js} +2 -2
  60. package/dist/hooks/{chunk-EJDX2TOB.js → chunk-NXYMNPUQ.js} +7 -88
  61. package/dist/hooks/{chunk-NJQOBE6L.js → chunk-QVLT52OV.js} +2 -7
  62. package/dist/hooks/{chunk-GQ7KP45M.js → chunk-XYUIQOW3.js} +2 -2
  63. package/dist/hooks/codex-hook-adapter.js +12 -48
  64. package/dist/hooks/duplicate-read-guard.js +5 -5
  65. package/dist/hooks/format-edited.js +2 -2
  66. package/dist/hooks/inputs.json +280 -0
  67. package/dist/hooks/investigation-guard.js +5 -5
  68. package/dist/hooks/pretool-guard.js +9 -9
  69. package/dist/hooks/session-lang.js +0 -1
  70. package/dist/hooks/stop-guard.js +192 -333
  71. package/dist/josh.js +240 -148
  72. package/dist/managed-marker/index.js +2 -1
  73. package/dist/version/index.js +70 -78
  74. package/eslint/rules/promise.js +5 -0
  75. package/eslint/rules/unicorn.js +3 -2
  76. package/package.json +26 -5
  77. package/pnpm-workspace.yaml +5 -7
  78. package/prompts/collaboration-workflow/glossary.md +17 -0
  79. package/prompts/collaboration-workflow/issue-citation.md +5 -5
  80. package/prompts/collaboration-workflow/issue-template.md +1 -1
  81. package/prompts/collaboration-workflow/operating-rules.md +5 -5
  82. package/prompts/collaboration-workflow/overview.md +13 -1
  83. package/prompts/collaboration-workflow/principles.md +9 -0
  84. package/prompts/collaboration-workflow/report-format.md +1 -1
  85. package/prompts/collaboration-workflow/residency.md +3 -3
  86. package/prompts/collaboration-workflow/rule-delivery.md +1 -1
  87. package/prompts/collaboration-workflow/turn-batching.md +3 -3
  88. package/prompts/collaboration-workflow/upstream-interrupt.md +1 -1
  89. package/prompts/collaboration-workflow/wip-cap.md +25 -22
  90. package/prompts/collaboration-workflow.md +6 -8
  91. package/prompts/review-rubric.md +1 -1
  92. package/prompts/review.md +3 -3
  93. package/prompts/sonar-hotspot-handling.md +11 -3
  94. package/prompts/testing-guide.md +3 -3
  95. package/scripts/adopt/adopt-toolkits.ts +0 -2
  96. package/scripts/adopt/adopt.ts +0 -2
  97. package/scripts/agent/agent-argv.ts +0 -2
  98. package/scripts/agent/agent-diagnostics.ts +1 -1
  99. package/scripts/agent/agent-role-profile.ts +0 -7
  100. package/scripts/agent/claude-agent-argv.ts +0 -2
  101. package/scripts/agent/codex-agent-argv.ts +1 -1
  102. package/scripts/agent/codex-hooks.ts +92 -0
  103. package/scripts/agent/interactive-ask.ts +1 -1
  104. package/scripts/auto-ok/auto-ok-cli.ts +6 -16
  105. package/scripts/backlog/backlog-arrival.ts +30 -10
  106. package/scripts/backlog/backlog-budget-cli.ts +15 -16
  107. package/scripts/backlog/backlog-budget.ts +0 -2
  108. package/scripts/backlog/backlog-defect-priority.ts +2 -2
  109. package/scripts/backlog/backlog-drive-cli.ts +10 -8
  110. package/scripts/backlog/backlog-drive-named-offer.ts +16 -3
  111. package/scripts/backlog/backlog-drive-named.ts +2 -1
  112. package/scripts/backlog/backlog-drive.ts +76 -16
  113. package/scripts/backlog/backlog-named.ts +0 -3
  114. package/scripts/backlog/backlog-next.ts +9 -15
  115. package/scripts/backlog/backlog-offer-cli.ts +6 -19
  116. package/scripts/backlog/backlog-plan-cli.ts +1 -7
  117. package/scripts/backlog/backlog-plan.ts +30 -19
  118. package/scripts/backlog/backlog-pool.ts +3 -6
  119. package/scripts/backlog/backlog-rank.ts +2 -2
  120. package/scripts/backlog/backlog-ready.ts +39 -10
  121. package/scripts/backlog/backlog-scope.ts +1 -3
  122. package/scripts/backlog/backlog-stalled-detect.ts +2 -2
  123. package/scripts/backlog/backlog-stalled.ts +0 -1
  124. package/scripts/backlog/backlog-waves.ts +5 -2
  125. package/scripts/behavior/behavior-cli.ts +1 -1
  126. package/scripts/build/build-codex-hooks.ts +26 -0
  127. package/scripts/build/build-hooks.ts +85 -9
  128. package/scripts/build/hook-bundle-stamp.ts +111 -0
  129. package/scripts/cases/cases-cli.ts +1 -1
  130. package/scripts/cases/cases-logic.ts +1 -1
  131. package/scripts/ci/composite-actions.ts +30 -0
  132. package/scripts/ci/pr-classification.ts +3 -3
  133. package/scripts/claude/workflow-destination.ts +10 -1
  134. package/scripts/clone/clone-fingerprint.ts +0 -1
  135. package/scripts/clone/clone-scan-cli.ts +1 -1
  136. package/scripts/clone/clone-scan.ts +1 -1
  137. package/scripts/config-merge/json-format.ts +0 -1
  138. package/scripts/config-merge/parse-jsonc.ts +33 -3
  139. package/scripts/config-merge/patch-json-key.ts +13 -6
  140. package/scripts/config-merge/patch-yaml-list.ts +1 -1
  141. package/scripts/cost-runtime/codex-usage.ts +2 -9
  142. package/scripts/cost-runtime/cost-attribute.ts +0 -1
  143. package/scripts/cost-runtime/cost-cli.ts +3 -10
  144. package/scripts/cost-runtime/cost-corpus.ts +0 -2
  145. package/scripts/cost-runtime/cost-format.ts +0 -3
  146. package/scripts/cost-runtime/cost-pricing.ts +0 -1
  147. package/scripts/cost-runtime/cost-tokens.ts +0 -1
  148. package/scripts/delegation/delegation-cli.ts +1 -1
  149. package/scripts/delegation/delegation-policy.ts +0 -1
  150. package/scripts/delegation/duplicate-read-guard.ts +0 -8
  151. package/scripts/delegation/fanout-cli.ts +1 -1
  152. package/scripts/delegation/fanout.ts +0 -2
  153. package/scripts/delegation/investigation-reads.ts +1 -164
  154. package/scripts/discovery/repo-map-logic.ts +0 -1
  155. package/scripts/discovery/repo-party-cli.ts +1 -1
  156. package/scripts/doctor/doctor-consumer.ts +6 -10
  157. package/scripts/doctor/doctor-io.ts +9 -13
  158. package/scripts/doctor/doctor-logic.ts +0 -4
  159. package/scripts/doctor/doctor.ts +14 -9
  160. package/scripts/document/backlogrun-parent-read-set.ts +12 -1
  161. package/scripts/document/document-byte-budget.ts +5 -5
  162. package/scripts/document/document-byte-check.ts +0 -1
  163. package/scripts/document/document-read-cli.ts +0 -2
  164. package/scripts/document/document-section-cli.ts +1 -1
  165. package/scripts/document/document-section.ts +0 -3
  166. package/scripts/document/edit-files-cli.ts +0 -1
  167. package/scripts/document/entry-read-budget.ts +21 -7
  168. package/scripts/document/entry-read-set.ts +32 -8
  169. package/scripts/document/lane-child-read-set.ts +8 -6
  170. package/scripts/document/read-files-cli.ts +0 -4
  171. package/scripts/document/read-set-cli.ts +0 -2
  172. package/scripts/document/read-set-point-of-use.ts +9 -3
  173. package/scripts/document/read-set-pricing.ts +0 -1
  174. package/scripts/document/read-set-trim.ts +4 -2
  175. package/scripts/epic/epic-add.ts +1 -1
  176. package/scripts/epic/epic-audit-cli.ts +1 -4
  177. package/scripts/epic/epic-audit-orphans.ts +1 -3
  178. package/scripts/epic/epic-audit-rationale.ts +0 -1
  179. package/scripts/epic/epic-audit-report.ts +0 -2
  180. package/scripts/epic/epic-audit.ts +8 -22
  181. package/scripts/epic/epic-bundle-cli.ts +1 -1
  182. package/scripts/epic/epic-bundle-evidence.ts +0 -1
  183. package/scripts/epic/epic-bundle-referenced.ts +1 -5
  184. package/scripts/epic/epic-bundle.ts +0 -4
  185. package/scripts/epic/epic-busy.ts +4 -5
  186. package/scripts/epic/epic-candidate-confirm.ts +0 -5
  187. package/scripts/epic/epic-classify.ts +2 -2
  188. package/scripts/epic/epic-cli-argv.ts +0 -1
  189. package/scripts/epic/epic-close-comment.ts +1 -1
  190. package/scripts/epic/epic-close.ts +5 -2
  191. package/scripts/epic/epic-cross-repo.ts +2 -4
  192. package/scripts/epic/epic-decision.ts +0 -1
  193. package/scripts/epic/epic-fetch.ts +2 -2
  194. package/scripts/epic/epic-index.ts +2 -3
  195. package/scripts/epic/epic-issue.ts +1 -15
  196. package/scripts/epic/epic-lane-offer.ts +9 -8
  197. package/scripts/epic/epic-nested.ts +1 -1
  198. package/scripts/epic/epic-next-read.ts +1 -3
  199. package/scripts/epic/epic-next-views.ts +0 -1
  200. package/scripts/epic/epic-next.ts +1 -10
  201. package/scripts/epic/epic-parse.ts +0 -1
  202. package/scripts/epic/epic-promote.ts +0 -9
  203. package/scripts/epic/epic-rank.ts +2 -2
  204. package/scripts/epic/epic-read.ts +1 -2
  205. package/scripts/epic/epic-reconcile.ts +1 -1
  206. package/scripts/epic/epic-reference.ts +1 -13
  207. package/scripts/epic/epic-relation-recheck.ts +1 -1
  208. package/scripts/epic/epic-relations.ts +1 -1
  209. package/scripts/epic/epic-remove.ts +1 -1
  210. package/scripts/epic/epic-report.ts +0 -1
  211. package/scripts/epic/epic-run.ts +2 -3
  212. package/scripts/epic/epic-shape.ts +1 -1
  213. package/scripts/epic/epic-solo-stale.ts +107 -0
  214. package/scripts/epic/epic-solo.ts +3 -2
  215. package/scripts/epic/epic-triage.ts +1 -1
  216. package/scripts/epic/epic-validate.ts +1 -1
  217. package/scripts/epic/epic.ts +1 -1
  218. package/scripts/exports/unused-members-cli.ts +53 -0
  219. package/scripts/{git → followup}/followup-issue-number.ts +1 -6
  220. package/scripts/{git → followup}/git-followup-cleanup.ts +2 -1
  221. package/scripts/{git → followup}/git-followup-finish.ts +1 -3
  222. package/scripts/{git → followup}/git-followup-flush.ts +2 -2
  223. package/scripts/{git → followup}/git-followup-issue-close.ts +2 -2
  224. package/scripts/{git → followup}/git-followup-label.ts +4 -4
  225. package/scripts/followup/git-followup-merged.ts +112 -0
  226. package/scripts/{git → followup}/git-followup-pending.ts +1 -1
  227. package/scripts/{git → followup}/git-followup-workflow.ts +19 -11
  228. package/scripts/{git → followup}/git-pr-followup-wrapup.ts +9 -3
  229. package/scripts/{git → followup}/git-pr-followup.ts +53 -16
  230. package/scripts/gate/core-budget.ts +3 -9
  231. package/scripts/gate/gate-plan.ts +7 -4
  232. package/scripts/gate/gate-report.ts +0 -6
  233. package/scripts/gate/gate-tree.ts +1 -1
  234. package/scripts/gate/pre-commit-type-check.ts +0 -6
  235. package/scripts/gate/project-checks.ts +7 -8
  236. package/scripts/gate/scoped-green.ts +0 -1
  237. package/scripts/gate/type-check-step.ts +1 -1
  238. package/scripts/gate/verification-gate.ts +0 -2
  239. package/scripts/gh/fix-gh-packages.ts +15 -12
  240. package/scripts/gh/gh-spawn.ts +2 -2
  241. package/scripts/{git → gh}/git-ai-review-scan.ts +1 -5
  242. package/scripts/{git → gh}/git-gh-check.ts +2 -1
  243. package/scripts/{git → gh}/git-gh-exec.ts +1 -1
  244. package/scripts/{git → gh}/git-gh-failure.ts +1 -1
  245. package/scripts/{git → gh}/git-gh-helpers.ts +0 -1
  246. package/scripts/{git → gh}/git-gh-issue-list.ts +13 -10
  247. package/scripts/{git → gh}/git-gh-issue-read.ts +1 -1
  248. package/scripts/{git → gh}/git-gh-issue-rest.ts +6 -3
  249. package/scripts/{git → gh}/git-gh-issue-write.ts +4 -1
  250. package/scripts/{git → gh}/git-gh-pr-auto-merge.ts +4 -1
  251. package/scripts/{git → gh}/git-gh-pr-read.ts +24 -0
  252. package/scripts/{git → gh}/git-gh-pr-rest.ts +5 -2
  253. package/scripts/{git → gh}/git-gh-pr-review.ts +2 -2
  254. package/scripts/{git → gh}/git-gh-pr-rollup.ts +1 -3
  255. package/scripts/{git → gh}/git-gh-pr.ts +3 -1
  256. package/scripts/{git → gh}/git-pr-ai-review.ts +2 -5
  257. package/scripts/{git → gh}/git-pr-checks-eval.ts +0 -10
  258. package/scripts/{git → gh}/git-pr-checks-parse.ts +4 -20
  259. package/scripts/{git → gh}/git-pr-checks.ts +2 -1
  260. package/scripts/{git → gh}/git-pr-coderabbit.ts +2 -5
  261. package/scripts/{git → gh}/git-pr-confirmation.ts +1 -3
  262. package/scripts/{git → gh}/git-pr-managed-config.ts +2 -3
  263. package/scripts/{git → gh}/git-pr.ts +3 -3
  264. package/scripts/git/changed-file-scope.ts +0 -1
  265. package/scripts/git/git-branch.ts +3 -6
  266. package/scripts/git/git-command.ts +6 -1
  267. package/scripts/git/git-commit.ts +1 -1
  268. package/scripts/git/git-common-directory.ts +80 -24
  269. package/scripts/git/git-error.ts +66 -9
  270. package/scripts/git/git-issue.ts +1 -1
  271. package/scripts/git/git-preflight.ts +2 -2
  272. package/scripts/git/git-prompt.ts +6 -31
  273. package/scripts/git/git-push.ts +1 -1
  274. package/scripts/git/git-spawn-sync.ts +65 -0
  275. package/scripts/git/git-spawn.ts +5 -4
  276. package/scripts/git/git-staging.ts +1 -0
  277. package/scripts/git/git-status.ts +1 -1
  278. package/scripts/git/git-workflow.ts +1 -1
  279. package/scripts/git/gone-branch.ts +1 -0
  280. package/scripts/git/listing-cutoff.ts +1 -1
  281. package/scripts/git/main-merge.ts +1 -1
  282. package/scripts/git/main-sync.ts +19 -1
  283. package/scripts/git/parse-json-array.ts +0 -3
  284. package/scripts/git/repository-lock.ts +16 -16
  285. package/scripts/git/{git-stash.ts → stash/git-stash.ts} +1 -1
  286. package/scripts/git/{stash-pop-args.ts → stash/stash-pop-args.ts} +2 -7
  287. package/scripts/git/{stash-pop-cli.ts → stash/stash-pop-cli.ts} +0 -1
  288. package/scripts/git/{stash-sweep-lock.ts → stash/stash-sweep-lock.ts} +3 -3
  289. package/scripts/hooks/codex-hook-adapter.ts +0 -1
  290. package/scripts/hooks/edited-cspell.ts +1 -1
  291. package/scripts/hooks/format-edited-file.ts +2 -0
  292. package/scripts/hooks/pre-push-unit.ts +0 -4
  293. package/scripts/hooks/pretool-guard.ts +22 -4
  294. package/scripts/hooks/reserved-run.ts +1 -1
  295. package/scripts/hooks/step-zero-notice.ts +76 -0
  296. package/scripts/hooks/stop-guard.ts +47 -21
  297. package/scripts/init/claude-plugin-config.ts +4 -5
  298. package/scripts/init/hook-command-rewrite.ts +16 -8
  299. package/scripts/init/hook-launch.ts +41 -15
  300. package/scripts/init/init-basic.ts +2 -5
  301. package/scripts/init/init-file-action.ts +54 -0
  302. package/scripts/init/init-logic-migrate.ts +35 -17
  303. package/scripts/init/init-logic-secretlint.ts +1 -1
  304. package/scripts/init/init-logic.ts +10 -19
  305. package/scripts/init/init.ts +11 -71
  306. package/scripts/init/kit-written-paths.ts +2 -0
  307. package/scripts/init/project-profile.ts +9 -17
  308. package/scripts/init/start-exec.ts +1 -1
  309. package/scripts/init/start-setup-pr.ts +6 -6
  310. package/scripts/init/start-steps.ts +3 -1
  311. package/scripts/issue/behavior-change-lint.ts +0 -1
  312. package/scripts/issue/defect-rate-cli.ts +64 -23
  313. package/scripts/issue/defect-rate.ts +1 -2
  314. package/scripts/{git → issue}/git-next-issues.ts +3 -3
  315. package/scripts/issue/issue-backlinks-cli.ts +1 -5
  316. package/scripts/issue/issue-backlinks.ts +7 -14
  317. package/scripts/issue/issue-cite-cli.ts +2 -6
  318. package/scripts/issue/issue-cite.ts +12 -8
  319. package/scripts/issue/issue-classification.ts +1 -9
  320. package/scripts/issue/issue-closing-pr.ts +4 -4
  321. package/scripts/issue/issue-comment-cli.ts +2 -2
  322. package/scripts/issue/issue-file-cli.ts +5 -5
  323. package/scripts/issue/issue-file.ts +7 -14
  324. package/scripts/issue/issue-fold-cli.ts +1 -1
  325. package/scripts/issue/issue-fold-existing-cli.ts +1 -1
  326. package/scripts/{git → issue}/issue-labels.ts +8 -0
  327. package/scripts/issue/issue-lint-cli.ts +1 -1
  328. package/scripts/issue/issue-merged.ts +2 -2
  329. package/scripts/{git → issue}/issue-rank.ts +1 -1
  330. package/scripts/issue/issue-read-cli.ts +8 -47
  331. package/scripts/issue/issue-read.ts +0 -2
  332. package/scripts/issue/issue-report-failures.ts +80 -0
  333. package/scripts/issue/issue-scout-cli.ts +1 -7
  334. package/scripts/issue/issue-scout-closed.ts +2 -2
  335. package/scripts/issue/issue-scout.ts +0 -2
  336. package/scripts/issue/issue-state-cli.ts +5 -46
  337. package/scripts/issue/issue-state.ts +1 -5
  338. package/scripts/issue/markdown-section.ts +21 -6
  339. package/scripts/issue/measure-rerun-cli.ts +74 -15
  340. package/scripts/issue/reproduction-measure.ts +1 -1
  341. package/scripts/josh/cli-body.ts +1 -1
  342. package/scripts/josh/file-map-stamp.ts +0 -3
  343. package/scripts/josh/josh-command-map.ts +2 -0
  344. package/scripts/josh/josh-commands-ai.ts +9 -102
  345. package/scripts/josh/josh-commands-backlog.ts +5 -1
  346. package/scripts/josh/josh-commands-development.ts +8 -1
  347. package/scripts/josh/josh-commands-issue.ts +2 -2
  348. package/scripts/josh/josh-commands-maintenance.ts +7 -0
  349. package/scripts/josh/josh-commands-project.ts +7 -1
  350. package/scripts/josh/josh-commands-run.ts +114 -0
  351. package/scripts/josh/josh-commands-versioning.ts +8 -0
  352. package/scripts/josh/josh-commands-workflow.ts +3 -3
  353. package/scripts/josh/path-decision.ts +0 -3
  354. package/scripts/josh/process-owner.ts +16 -0
  355. package/scripts/josh/run-github-prerequisite.ts +3 -6
  356. package/scripts/josh/session-language-cli.ts +0 -1
  357. package/scripts/lane/lane-await.ts +46 -19
  358. package/scripts/lane/lane-capacity.ts +6 -3
  359. package/scripts/lane/lane-child-invocation.ts +20 -7
  360. package/scripts/lane/lane-cli.ts +1 -4
  361. package/scripts/lane/lane-close.ts +5 -4
  362. package/scripts/lane/lane-dispatch.ts +3 -4
  363. package/scripts/lane/lane-environment.ts +0 -9
  364. package/scripts/lane/lane-handoff.ts +38 -0
  365. package/scripts/lane/lane-launch-cli.ts +31 -27
  366. package/scripts/lane/lane-open.ts +0 -3
  367. package/scripts/lane/lane-output.ts +0 -1
  368. package/scripts/lane/lane-registry.ts +9 -0
  369. package/scripts/lane/openai-lane-ship.ts +2 -0
  370. package/scripts/lane/openai-lane-supervisor-decision.ts +2 -1
  371. package/scripts/lane/openai-lane-supervisor.ts +6 -4
  372. package/scripts/lane/openai-review-broker.ts +7 -1
  373. package/scripts/lib/bounded-pool.ts +1 -0
  374. package/scripts/lib/cli-flags.ts +31 -2
  375. package/scripts/lib/error-message.ts +12 -1
  376. package/scripts/lib/json-value.ts +5 -4
  377. package/scripts/lib/poll.ts +3 -1
  378. package/scripts/lib/timed-fetch.ts +15 -0
  379. package/scripts/lib/timeouts.ts +13 -0
  380. package/scripts/{yaml → lib}/yaml-document.ts +3 -1
  381. package/scripts/{bytes → lines}/bytes-command.ts +0 -2
  382. package/scripts/lines/line-targets.ts +0 -11
  383. package/scripts/lines/lines-command.ts +5 -4
  384. package/scripts/lint/lint-related-scope.ts +0 -1
  385. package/scripts/lint/lint-related.ts +1 -1
  386. package/scripts/{git → notify}/telegram-notify.ts +2 -2
  387. package/scripts/{git → notify}/telegram-test.ts +4 -4
  388. package/scripts/observations/observation-ledger-home.ts +0 -1
  389. package/scripts/observations/observation-ledger-line.ts +0 -1
  390. package/scripts/observations/observation-ledger-migrate.ts +1 -1
  391. package/scripts/observations/observations-flush-landing.ts +3 -3
  392. package/scripts/observations/observations-flush.ts +2 -2
  393. package/scripts/overrides/lockfile-overrides.ts +1 -1
  394. package/scripts/overrides/overrides-logic.ts +1 -1
  395. package/scripts/package/package-scout-cli.ts +2 -7
  396. package/scripts/package/package-scout.ts +0 -2
  397. package/scripts/propagate/propagate-git-failure.ts +0 -1
  398. package/scripts/propagate/propagate-git.ts +3 -10
  399. package/scripts/propagate/propagate-publish.ts +2 -3
  400. package/scripts/propagate/propagate-run.ts +0 -2
  401. package/scripts/propagate/propagate-steps.ts +3 -5
  402. package/scripts/propagate/propagate-targets.ts +0 -4
  403. package/scripts/propagate/propagate.ts +0 -4
  404. package/scripts/refactor/import-graph.ts +0 -1
  405. package/scripts/refactor/refactor-lint.ts +0 -2
  406. package/scripts/refactor/refactor-scan.ts +2 -2
  407. package/scripts/refactor/refactor-targets.ts +0 -1
  408. package/scripts/registry-migration/migrate-logic.ts +28 -21
  409. package/scripts/registry-migration/migrate.ts +25 -14
  410. package/scripts/release/github-release-cli.ts +19 -6
  411. package/scripts/release/github-release-environment.ts +46 -0
  412. package/scripts/release/github-release.ts +151 -94
  413. package/scripts/release/release-history.ts +0 -1
  414. package/scripts/release/release-plan.ts +0 -1
  415. package/scripts/release/release-publish.ts +38 -5
  416. package/scripts/release/release-scope-cli.ts +1 -2
  417. package/scripts/release/release-tag.ts +2 -4
  418. package/scripts/release/release-worktree.ts +97 -2
  419. package/scripts/repo/auto-merge-setting-logic.ts +1 -4
  420. package/scripts/repo/repo-setting.ts +1 -1
  421. package/scripts/repo/repository-labels.ts +3 -3
  422. package/scripts/repo/required-checks-logic.ts +206 -0
  423. package/scripts/repo/required-checks-report.ts +71 -0
  424. package/scripts/repo/ruleset-check-cli.ts +53 -0
  425. package/scripts/repo/ruleset-check.ts +147 -0
  426. package/scripts/report/report-lint-cli.ts +0 -4
  427. package/scripts/review/disposition-cli.ts +1 -1
  428. package/scripts/review/live-evidence.ts +1 -1
  429. package/scripts/review/review-attest-cli.ts +0 -6
  430. package/scripts/review/review-attest.ts +4 -16
  431. package/scripts/review/review-brief-cli.ts +23 -6
  432. package/scripts/review/review-brief.ts +21 -8
  433. package/scripts/review/review-checkout.ts +3 -2
  434. package/scripts/review/review-diff-parts.ts +89 -0
  435. package/scripts/review/review-diff-write.ts +97 -0
  436. package/scripts/review/review-finding-ledger.ts +0 -1
  437. package/scripts/review/review-record-cli.ts +10 -17
  438. package/scripts/review/review-record.ts +0 -1
  439. package/scripts/review/review-round2-cli.ts +1 -1
  440. package/scripts/review/review-stamps.ts +0 -3
  441. package/scripts/review/review-tree.ts +14 -2
  442. package/scripts/rules/decision-oracle-stage.ts +18 -0
  443. package/scripts/rules/decision-oracle.ts +10 -7
  444. package/scripts/rules/delivered-rules.ts +9 -1
  445. package/scripts/rules/destructive-command.ts +119 -0
  446. package/scripts/rules/direct-filing.ts +1 -1
  447. package/scripts/rules/early-heartbeat.ts +4 -3
  448. package/scripts/rules/file-body.ts +0 -3
  449. package/scripts/rules/filing-cap.ts +0 -2
  450. package/scripts/rules/gh-api.ts +7 -2
  451. package/scripts/rules/git-argv.ts +18 -7
  452. package/scripts/rules/git-force.ts +0 -2
  453. package/scripts/rules/implementation-cut.ts +0 -1
  454. package/scripts/rules/index-guard.ts +71 -0
  455. package/scripts/rules/issue-citation.ts +50 -25
  456. package/scripts/rules/lane-background.ts +15 -7
  457. package/scripts/rules/lane-park.ts +22 -6
  458. package/scripts/rules/last-prompt.ts +1 -0
  459. package/scripts/rules/oracle-consulted.ts +1 -1
  460. package/scripts/rules/oracle-firing.ts +1 -0
  461. package/scripts/rules/oracle-list-cli.ts +0 -3
  462. package/scripts/rules/permission-guards.ts +14 -0
  463. package/scripts/rules/protected-files.ts +74 -0
  464. package/scripts/rules/reply-language.ts +1 -1
  465. package/scripts/rules/rule-body-guard.ts +0 -3
  466. package/scripts/rules/rule-value-cli.ts +0 -1
  467. package/scripts/rules/shell-body-trigger.ts +0 -1
  468. package/scripts/rules/shell-segments.ts +0 -1
  469. package/scripts/rules/stop-rules.ts +20 -9
  470. package/scripts/rules/tail-commands.ts +1 -1
  471. package/scripts/rules/test-declared-commit.ts +1 -1
  472. package/scripts/rules/third-party-write.ts +0 -1
  473. package/scripts/rules/worktree-guard.ts +26 -9
  474. package/scripts/run/run-carry-args.ts +8 -12
  475. package/scripts/run/run-carry-cli.ts +0 -2
  476. package/scripts/run/run-carry-stash.ts +2 -2
  477. package/scripts/run/run-carry-streak.ts +1 -1
  478. package/scripts/run/run-cut-args.ts +1 -6
  479. package/scripts/run/run-cut-cli.ts +0 -7
  480. package/scripts/run/run-cut.ts +8 -54
  481. package/scripts/run/run-ending-cli.ts +2 -6
  482. package/scripts/run/run-ending.ts +1 -4
  483. package/scripts/run/run-entry-cli.ts +133 -25
  484. package/scripts/run/run-entry-stop.ts +104 -0
  485. package/scripts/run/run-entry.ts +0 -1
  486. package/scripts/run/run-event-cli.ts +0 -2
  487. package/scripts/run/run-event-follow.ts +1 -0
  488. package/scripts/run/run-event-render.ts +1 -1
  489. package/scripts/run/run-event-scope.ts +53 -4
  490. package/scripts/run/run-event-stream-emit.ts +7 -2
  491. package/scripts/run/run-event-stream.ts +0 -3
  492. package/scripts/run/run-event-watch.ts +1 -0
  493. package/scripts/run/run-halfrun-resume.ts +20 -7
  494. package/scripts/run/run-headless.ts +2 -2
  495. package/scripts/run/run-hold-cli.ts +33 -10
  496. package/scripts/run/run-hold.ts +29 -6
  497. package/scripts/run/run-issue-number.ts +1 -1
  498. package/scripts/run/run-liveness-cli.ts +2 -6
  499. package/scripts/run/run-liveness.ts +2 -3
  500. package/scripts/run/run-merge-cli.ts +7 -23
  501. package/scripts/run/run-merge-steps.ts +5 -5
  502. package/scripts/run/run-merge.ts +1 -1
  503. package/scripts/run/run-next-cli.ts +1 -1
  504. package/scripts/run/run-parent-cut-hook.ts +4 -2
  505. package/scripts/run/run-preflight.ts +2 -9
  506. package/scripts/run/run-prep-cli.ts +6 -3
  507. package/scripts/run/run-prep-locate.ts +1 -1
  508. package/scripts/run/run-progress-args.ts +20 -4
  509. package/scripts/run/run-progress-cli.ts +35 -36
  510. package/scripts/run/run-progress-clock.ts +10 -35
  511. package/scripts/run/run-progress-config.ts +0 -4
  512. package/scripts/run/run-progress-read.ts +1 -2
  513. package/scripts/run/run-progress.ts +1 -2
  514. package/scripts/run/run-prrun-resume.ts +117 -0
  515. package/scripts/run/run-report-cli.ts +1 -2
  516. package/scripts/run/run-report.ts +0 -1
  517. package/scripts/run/run-retrospective.ts +1 -1
  518. package/scripts/run/run-review-cli.ts +0 -3
  519. package/scripts/run/run-review-steps.ts +2 -0
  520. package/scripts/run/run-review.ts +0 -2
  521. package/scripts/run/run-ship-cli.ts +29 -19
  522. package/scripts/run/run-ship-detach.ts +1 -0
  523. package/scripts/run/run-ship-next.ts +106 -0
  524. package/scripts/run/run-ship-preflight.ts +1 -1
  525. package/scripts/run/run-ship-probe.ts +4 -1
  526. package/scripts/run/run-ship-return.ts +8 -3
  527. package/scripts/run/run-ship-review-steps.ts +18 -4
  528. package/scripts/run/run-ship-review.ts +11 -0
  529. package/scripts/run/run-ship-scoped.ts +1 -0
  530. package/scripts/run/run-ship-steps.ts +1 -1
  531. package/scripts/run/run-ship.ts +0 -1
  532. package/scripts/run/run-stage-read.ts +62 -0
  533. package/scripts/run/run-stage.ts +160 -0
  534. package/scripts/run/run-status-cli.ts +3 -16
  535. package/scripts/run/run-step-cli.ts +21 -14
  536. package/scripts/run/run-step.ts +1 -1
  537. package/scripts/run/run-stop-notify.ts +1 -3
  538. package/scripts/run/run-stranded-cli.ts +0 -4
  539. package/scripts/run/run-stranded-detect.ts +2 -2
  540. package/scripts/run/run-tail-cli.ts +17 -11
  541. package/scripts/run/run-tail.ts +2 -0
  542. package/scripts/run/run-tidy-lanes.ts +6 -2
  543. package/scripts/run/run-tidy-stashes.ts +12 -12
  544. package/scripts/run/run-wake-cli.ts +4 -13
  545. package/scripts/run/run-wake-loop.ts +2 -2
  546. package/scripts/run/run-wake.ts +2 -4
  547. package/scripts/run/run-watcher-guard-cli.ts +0 -4
  548. package/scripts/run/run-watcher-guard.ts +18 -12
  549. package/scripts/run/run-watcher-hook.ts +1 -1
  550. package/scripts/safe-chain/ci-installer-pin.ts +11 -5
  551. package/scripts/safe-chain/pack-hook.ts +92 -0
  552. package/scripts/safe-chain/project-config.ts +1 -1
  553. package/scripts/security/security-audit-provision-logic.ts +0 -1
  554. package/scripts/security/security-audit-provision.ts +3 -2
  555. package/scripts/security/security-audit.ts +0 -1
  556. package/scripts/security/security-updates-logic.ts +0 -1
  557. package/scripts/sonar/sonar-hotspots-cli.ts +10 -52
  558. package/scripts/sonar/sonar-hotspots.ts +0 -1
  559. package/scripts/sonar/sonar-new-code-cli.ts +150 -0
  560. package/scripts/sonar/sonar-new-code.ts +79 -0
  561. package/scripts/sonar/sonar-project.ts +97 -0
  562. package/scripts/split/split-assess-cli.ts +1 -1
  563. package/scripts/split/split-assess.ts +2 -5
  564. package/scripts/sync/managed-config-scope-cli.ts +1 -1
  565. package/scripts/sync/skill-migration.ts +0 -1
  566. package/scripts/sync/sync-ai-files.ts +4 -0
  567. package/scripts/sync/sync-hook-safety.ts +2 -3
  568. package/scripts/sync/sync.ts +1 -8
  569. package/scripts/sync/template-source-logic.ts +0 -1
  570. package/scripts/sync/workflow-pin-logic.ts +16 -28
  571. package/scripts/test/test-declared-changed.ts +13 -16
  572. package/scripts/test/test-declared-logic.ts +0 -1
  573. package/scripts/test/test-declared.ts +3 -9
  574. package/scripts/test/test-red-commit.ts +2 -2
  575. package/scripts/test/test-red.ts +14 -7
  576. package/scripts/test/test-type-logic.ts +1 -1
  577. package/scripts/test/unit-worker-share.ts +7 -16
  578. package/scripts/time-runtime/time-batch-guard.ts +1 -2
  579. package/scripts/time-runtime/time-bundle-call.ts +0 -1
  580. package/scripts/time-runtime/time-bundles.ts +0 -4
  581. package/scripts/time-runtime/time-density-hook.ts +0 -2
  582. package/scripts/time-runtime/time-followup-stage.ts +1 -1
  583. package/scripts/time-runtime/time-format.ts +0 -73
  584. package/scripts/time-runtime/time-round-trips.ts +0 -4
  585. package/scripts/time-runtime/time-single-check.ts +1 -1
  586. package/scripts/time-runtime/time-spans.ts +1 -1
  587. package/scripts/time-runtime/time-transcript-line.ts +1 -2
  588. package/scripts/ui/ui-routes-cli.ts +0 -5
  589. package/scripts/ui/ui-routes.ts +0 -5
  590. package/scripts/version/effective-upstream.ts +2 -2
  591. package/scripts/version/latest-corepack.ts +7 -9
  592. package/scripts/version/latest-scope-cli.ts +0 -2
  593. package/scripts/version/latest-update.ts +0 -2
  594. package/scripts/version/npm-registry.ts +2 -2
  595. package/scripts/version/publishable-range-check.ts +1 -1
  596. package/scripts/version/release-hold.ts +0 -4
  597. package/scripts/version/running-binary.ts +2 -2
  598. package/scripts/version/version-check-logic.ts +0 -2
  599. package/scripts/version/version-commands.ts +11 -1
  600. package/scripts/version/version-remote.ts +3 -3
  601. package/scripts/version/version-targets.ts +4 -4
  602. package/templates/CLAUDE.basic.md +6 -6
  603. package/templates/sonar-project.properties +28 -1
  604. package/templates/workflows/ci.yml +16 -82
  605. package/templates/workflows/dependabot-auto-merge.yml +6 -3
  606. package/templates/workflows/github-release.yml +79 -0
  607. package/tsconfig.sonar.json +4 -22
  608. package/prompts/collaboration-workflow/cross-repo-epic.md +0 -5
  609. package/prompts/collaboration-workflow/epic-audit.md +0 -5
  610. package/prompts/collaboration-workflow/epic-bundle.md +0 -5
  611. package/scripts/init/plugin-install-hint.ts +0 -47
  612. package/scripts/version/parse-json.ts +0 -13
  613. /package/scripts/{git → followup}/git-followup-stages.ts +0 -0
  614. /package/scripts/{git → gh}/git-gh-api-path.ts +0 -0
  615. /package/scripts/{git → gh}/git-gh-command.ts +0 -0
  616. /package/scripts/{git → gh}/git-gh-issue.ts +0 -0
  617. /package/scripts/{git → gh}/git-gh-pr-snapshot.ts +0 -0
  618. /package/scripts/{git → gh}/git-gh-reachability.ts +0 -0
  619. /package/scripts/{git → gh}/git-gh-repo.ts +0 -0
  620. /package/scripts/{git → gh}/git-gh-rest-state.ts +0 -0
  621. /package/scripts/{git → gh}/git-pr-checks-watch.ts +0 -0
  622. /package/scripts/{git → gh}/git-pr-error.ts +0 -0
  623. /package/scripts/{git → gh}/git-pr-messages.ts +0 -0
  624. /package/scripts/{git → gh}/github-issue-url.ts +0 -0
  625. /package/scripts/git/{stash-orphans.ts → stash/stash-orphans.ts} +0 -0
  626. /package/scripts/{git → issue}/issue-reference.ts +0 -0
  627. /package/scripts/{git → lib}/animation-helpers.ts +0 -0
  628. /package/scripts/{git → lib}/git-animation.ts +0 -0
  629. /package/scripts/{git → notify}/git-notify.ts +0 -0
  630. /package/scripts/{git → notify}/telegram-test-logic.ts +0 -0
@@ -0,0 +1,80 @@
1
+ // The failure report `issue:read` and `issue:state` share (joshuafolkken/kit#3046). Both read a batch
2
+ // of numbers, print a block for each one that answered, and name every one that did not; only the
3
+ // result kind that counts as an answer and what a gap must not be mistaken for differ between them.
4
+
5
+ const SUCCESS_EXIT_CODE = 0
6
+ const FAILURE_EXIT_CODE = 1
7
+
8
+ // The two failure kinds a read can end in, kept apart all the way to the report: `missing` is the
9
+ // number resolving to nothing and `unreadable` is a read that failed, and the documents ask a
10
+ // caller to report the two differently. Folding them together to simplify the batch would destroy
11
+ // exactly that distinction.
12
+ type ReadFailureKind = 'missing' | 'unreadable'
13
+
14
+ interface NumberReport<K extends string> {
15
+ issue_number: string
16
+ result: { kind: K | ReadFailureKind }
17
+ }
18
+
19
+ interface FailureTerms<K extends string> {
20
+ success_kind: K
21
+ // What a failed read would be misread as if it were printed silently — "the issue is empty".
22
+ misreading: string
23
+ }
24
+
25
+ function print_blocks(blocks: ReadonlyArray<string>, separator: string): void {
26
+ if (blocks.length === 0) return
27
+
28
+ console.info(blocks.join(separator))
29
+ }
30
+
31
+ // A number that resolves to nothing is an answer — a typo, or another repository's number quoted in
32
+ // prose — and it is reported as one. Everything else is a gap, and the message says so, because the
33
+ // caller's next move differs: a gap is retried, an answer is not.
34
+ function report_failure(kind: ReadFailureKind, issue_number: string, misreading: string): void {
35
+ if (kind === 'missing') {
36
+ console.error(`✖ issue #${issue_number} does not resolve — check the number and the repository`)
37
+ } else {
38
+ console.error(
39
+ `✖ could not read issue #${issue_number} — a rate limit, expired auth, or a dropped connection. This is not "${misreading}"`,
40
+ )
41
+ }
42
+ }
43
+
44
+ function is_failure_kind(kind: string): kind is ReadFailureKind {
45
+ return kind === 'missing' || kind === 'unreadable'
46
+ }
47
+
48
+ function report_one_failure<K extends string>(
49
+ report: NumberReport<K>,
50
+ terms: FailureTerms<K>,
51
+ ): boolean {
52
+ const { kind } = report.result
53
+
54
+ if (!is_failure_kind(kind)) return false
55
+
56
+ report_failure(kind, report.issue_number, terms.misreading)
57
+
58
+ return true
59
+ }
60
+
61
+ // Every number that produced no answer is named, so a caller is told which ones it has no answer for
62
+ // rather than being left to subtract the printed blocks from what it asked. A single failure makes
63
+ // the exit code non-zero.
64
+ function report_failures<K extends string>(
65
+ reports: ReadonlyArray<NumberReport<K>>,
66
+ terms: FailureTerms<K>,
67
+ ): number {
68
+ let has_failure = false
69
+
70
+ for (const report of reports) {
71
+ has_failure = report_one_failure(report, terms) || has_failure
72
+ }
73
+
74
+ return has_failure ? FAILURE_EXIT_CODE : SUCCESS_EXIT_CODE
75
+ }
76
+
77
+ const issue_report_failures = { print_blocks, report_failures }
78
+
79
+ export type { ReadFailureKind }
80
+ export { issue_report_failures }
@@ -5,7 +5,7 @@ import { epic_audit_logic } from '#scripts/epic/epic-audit'
5
5
  import { epic_bundle, type BacklogIssue, type BundleDecision } from '#scripts/epic/epic-bundle'
6
6
  import { epic_bundle_cli } from '#scripts/epic/epic-bundle-cli'
7
7
  import { epic_bundle_gaps } from '#scripts/epic/epic-bundle-gaps'
8
- import { git_gh_command } from '#scripts/git/git-gh-command'
8
+ import { git_gh_command } from '#scripts/gh/git-gh-command'
9
9
  import { cli_flags } from '#scripts/lib/cli-flags'
10
10
  import { issue_citation } from '#scripts/rules/issue-citation'
11
11
  import {
@@ -403,16 +403,10 @@ const issue_scout_cli = {
403
403
  NO_REFERENCE_LINE,
404
404
  CLOSED_UNREADABLE_LINE,
405
405
  CLOSED_CEILING_LINE,
406
- DRAFT_NUMBER,
407
406
  read_arguments,
408
407
  with_draft_body,
409
- draft_of,
410
- format_duplicates,
411
- format_epic_decision,
412
- format_report,
413
408
  scout,
414
409
  run,
415
- main,
416
410
  }
417
411
 
418
412
  if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
@@ -1,9 +1,9 @@
1
- import { git_gh_command } from '#scripts/git/git-gh-command'
2
- import { EPIC_LABEL, has_any_label } from '#scripts/git/issue-labels'
1
+ import { git_gh_command } from '#scripts/gh/git-gh-command'
3
2
  import { PAGE_CEILING_CAUSE } from '#scripts/git/listing-cutoff'
4
3
  import { parse_json_array_or_undefined } from '#scripts/git/parse-json-array'
5
4
  import { issue_label_schema } from '#scripts/git/schemas'
6
5
  import { z } from 'zod'
6
+ import { EPIC_LABEL, has_any_label } from './issue-labels'
7
7
  import type { ScoutIssue } from './issue-scout'
8
8
 
9
9
  // The closed half of `issue:scout`'s duplicate scan (joshuafolkken/kit#1679), held apart from the CLI
@@ -232,10 +232,8 @@ function find_duplicates(
232
232
 
233
233
  const issue_scout = {
234
234
  SIMILARITY_THRESHOLD,
235
- MIN_SHARED_TOKENS,
236
235
  MAX_CANDIDATES,
237
236
  tokenize,
238
- shared_tokens,
239
237
  dice_similarity,
240
238
  find_duplicates,
241
239
  }
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env tsx
2
2
  import { fileURLToPath } from 'node:url'
3
- import { git_gh_command } from '#scripts/git/git-gh-command'
3
+ import { git_gh_command } from '#scripts/gh/git-gh-command'
4
4
  import { bounded_pool } from '#scripts/lib/bounded-pool'
5
+ import { issue_report_failures, type ReadFailureKind } from './issue-report-failures'
5
6
  import { issue_state, type IssueState } from './issue-state'
6
7
 
7
8
  // `josh issue:state <N> [<N> ...]` — print each issue's state and labels, in the spelling the
@@ -25,7 +26,6 @@ import { issue_state, type IssueState } from './issue-state'
25
26
  // answer as "not CLOSED" would report a child as failed because nobody could reach GitHub. The two
26
27
  // are told apart here and neither is a state.
27
28
 
28
- const SUCCESS_EXIT_CODE = 0
29
29
  const FAILURE_EXIT_CODE = 1
30
30
  const ARGV_OFFSET = 2
31
31
  const REPO_FLAG = '--repo'
@@ -43,18 +43,13 @@ const READ_CONCURRENCY = 8
43
43
  // The two fields, under the names `gh issue view --json` gave them. `git-gh-issue-rest.ts` maps them
44
44
  // back from REST, which is what keeps `OPEN` / `CLOSED` / `MERGED` out of this file.
45
45
  const STATE_FIELDS = 'state,labels'
46
+ const FAILURE_TERMS = { success_kind: 'state', misreading: 'the issue is open' } as const
46
47
 
47
48
  interface StateRequest {
48
49
  issue_numbers: ReadonlyArray<string>
49
50
  repo?: string
50
51
  }
51
52
 
52
- // The two failure kinds a read can end in, kept apart all the way to the report: `missing` is the
53
- // number resolving to nothing and `unreadable` is a read that failed, and the documents ask a
54
- // caller to report the two differently. Folding them together to simplify the batch would destroy
55
- // exactly that distinction.
56
- type ReadFailureKind = 'missing' | 'unreadable'
57
-
58
53
  // One issue's state, or the failure kind. Named for export because `run:prep` reads the state beside
59
54
  // the body and the dependency-update scope (joshuafolkken/kit#1978), reusing this read rather than a
60
55
  // second one that would drift from the `human_review` decision `parse_issue_state` owns.
@@ -146,19 +141,6 @@ function parse_request(argv: ReadonlyArray<string>): StateRequest | undefined {
146
141
  return repo_flag.kind === 'named' ? { issue_numbers, repo: repo_flag.repo } : { issue_numbers }
147
142
  }
148
143
 
149
- // A number that resolves to nothing is an answer — a typo, or another repository's number quoted in
150
- // prose — and it is reported as one. Everything else is a gap, and the message says so, because the
151
- // caller's next move differs: a gap is retried, an answer is not.
152
- function report_failure(kind: ReadFailureKind, issue_number: string): void {
153
- if (kind === 'missing') {
154
- console.error(`✖ issue #${issue_number} does not resolve — check the number and the repository`)
155
- } else {
156
- console.error(
157
- `✖ could not read issue #${issue_number} — a rate limit, expired auth, or a dropped connection. This is not "the issue is open"`,
158
- )
159
- }
160
- }
161
-
162
144
  // One number's read, reduced to what the report needs and nothing printed yet. Separating the two
163
145
  // is what lets the whole batch be in flight at once: the numbers are independent, so reading them
164
146
  // one after the other spends a round trip per number for no reason.
@@ -206,30 +188,7 @@ function print_states(reports: ReadonlyArray<IssueReport>): void {
206
188
  const should_attribute = reports.length > 1
207
189
  const blocks = reports.flatMap((report) => state_blocks(report, should_attribute))
208
190
 
209
- if (blocks.length === 0) return
210
-
211
- console.info(blocks.join(BLOCK_SEPARATOR))
212
- }
213
-
214
- function report_one_failure(report: IssueReport): boolean {
215
- if (report.result.kind === 'state') return false
216
-
217
- report_failure(report.result.kind, report.issue_number)
218
-
219
- return true
220
- }
221
-
222
- // Every number that produced no state is named, so a caller is told which ones it has no answer for
223
- // rather than being left to subtract the printed blocks from what it asked. A single failure still
224
- // makes the exit code non-zero, exactly as it did when only one number could be passed.
225
- function report_failures(reports: ReadonlyArray<IssueReport>): number {
226
- let has_failure = false
227
-
228
- for (const report of reports) {
229
- has_failure = report_one_failure(report) || has_failure
230
- }
231
-
232
- return has_failure ? FAILURE_EXIT_CODE : SUCCESS_EXIT_CODE
191
+ issue_report_failures.print_blocks(blocks, BLOCK_SEPARATOR)
233
192
  }
234
193
 
235
194
  async function run(argv: ReadonlyArray<string>): Promise<number> {
@@ -245,7 +204,7 @@ async function run(argv: ReadonlyArray<string>): Promise<number> {
245
204
 
246
205
  print_states(reports)
247
206
 
248
- return report_failures(reports)
207
+ return issue_report_failures.report_failures(reports, FAILURE_TERMS)
249
208
  }
250
209
 
251
210
  async function main(argv: ReadonlyArray<string>): Promise<void> {
@@ -1,6 +1,6 @@
1
- import { has_any_label, NEEDS_HUMAN_REVIEW_LABEL } from '#scripts/git/issue-labels'
2
1
  import { parse_json_object_safe } from '#scripts/git/parse-json-array'
3
2
  import { z } from 'zod'
3
+ import { has_any_label, NEEDS_HUMAN_REVIEW_LABEL } from './issue-labels'
4
4
 
5
5
  // The answer `josh issue:state` prints, kept apart from the reading and the printing so the shape of
6
6
  // the report is decided by one pure function (joshuafolkken/kit#1054).
@@ -96,10 +96,6 @@ function format_attributed_issue_state(issue_number: string, state: IssueState):
96
96
 
97
97
  const issue_state = {
98
98
  NO_LABELS,
99
- STATE_LABEL,
100
- LABELS_LABEL,
101
- HUMAN_REVIEW_LABEL_LINE,
102
- ISSUE_LABEL,
103
99
  parse_issue_state,
104
100
  format_issue_state,
105
101
  format_attributed_issue_state,
@@ -52,13 +52,16 @@ function has_line(body: string, text: string): boolean {
52
52
  return has_unfenced_line(body, text)
53
53
  }
54
54
 
55
- // The lines between `heading` and the next `## ` heading, trimmed of the heading line itself; an empty
56
- // array when the heading is absent. A heading matched inside a sentence is not the section heading, so
57
- // only a line that is exactly the heading opens the section.
58
- function section_lines(body: string, heading: string): ReadonlyArray<string> {
55
+ // The lines between the first unfenced line `is_target` accepts and the next unfenced `## ` heading,
56
+ // trimmed of the heading line itself; an empty array when no line is accepted. A `## ` line inside a
57
+ // code fence is example text, so it neither opens nor closes a section (joshuafolkken/kit#3066).
58
+ function section_lines_matching(
59
+ body: string,
60
+ is_target: (line: string) => boolean,
61
+ ): ReadonlyArray<string> {
59
62
  const lines = body.split('\n')
60
63
  const visible = unfenced_lines(body)
61
- const start = visible.findIndex((line) => is_the_heading(line, heading))
64
+ const start = visible.findIndex((line) => is_target(line))
62
65
 
63
66
  if (start === -1) return []
64
67
 
@@ -68,6 +71,18 @@ function section_lines(body: string, heading: string): ReadonlyArray<string> {
68
71
  return end === -1 ? rest : rest.slice(0, end)
69
72
  }
70
73
 
71
- const markdown_section = { section_lines, is_heading, has_line, has_unfenced_line }
74
+ // A heading matched inside a sentence is not the section heading, so only a line that is exactly the
75
+ // heading opens the section.
76
+ function section_lines(body: string, heading: string): ReadonlyArray<string> {
77
+ return section_lines_matching(body, (line) => is_the_heading(line, heading))
78
+ }
79
+
80
+ const markdown_section = {
81
+ section_lines,
82
+ section_lines_matching,
83
+ unfenced_lines,
84
+ has_line,
85
+ has_unfenced_line,
86
+ }
72
87
 
73
88
  export { markdown_section }
@@ -1,26 +1,52 @@
1
1
  #!/usr/bin/env tsx
2
2
  import { execSync } from 'node:child_process'
3
- import { readFile } from 'node:fs/promises'
4
3
  import { fileURLToPath } from 'node:url'
4
+ import { git_gh_issue_read } from '#scripts/gh/git-gh-issue-read'
5
+ import { parse_json_object_safe } from '#scripts/git/parse-json-array'
5
6
  import { error_text } from '#scripts/lib/error-message'
6
7
  import { observation_ledger_home } from '#scripts/observations/observation-ledger-home'
8
+ import { z } from 'zod'
7
9
  import { baseline_measure, type Baseline } from './baseline-measure'
8
10
 
9
- // `josh measure:rerun <path>` — read a behavior-change Issue body after merge, re-run each baseline
11
+ // `josh measure:rerun <N>` — read a behavior-change Issue body after merge, re-run each baseline
10
12
  // command, and print the before/after pair (joshuafolkken/kit#2212). A value that did not move means
11
13
  // the premise the rule rested on is refuted, so a line is appended to the observation ledger — reusing
12
14
  // that append-only, same-key mechanism rather than a second one.
15
+ //
16
+ // **The baseline is shell, and the body is written by whoever filed the Issue** (joshuafolkken/kit#3064).
17
+ // A baseline needs pipes and loops (`git log … | wc -l`, `for d in $(ls …)`), so an allow-list of
18
+ // commands cannot make it safe; what can is who wrote it. The input is therefore the Issue number, not
19
+ // a file, so the author's `author_association` arrives with the body from the same REST read, and only
20
+ // a body written by someone with write access to the repository is run.
13
21
 
14
22
  const FAILURE_EXIT_CODE = 1
15
- const USAGE = 'Usage: josh measure:rerun <path-to-issue-body>'
23
+ const ARGV_OFFSET = 2
24
+ const ISSUE_NUMBER_PATTERN = /^[1-9]\d*$/u
25
+ const ISSUE_FIELDS = 'body,author_association'
26
+ const TRUSTED_ASSOCIATIONS: ReadonlySet<string> = new Set(['OWNER', 'MEMBER', 'COLLABORATOR'])
27
+ const TRUSTED_LIST = [...TRUSTED_ASSOCIATIONS].join(' / ')
28
+ const UNKNOWN_ASSOCIATION = 'unknown'
29
+ const USAGE = 'Usage: josh measure:rerun <issue-number>'
16
30
  const NO_BASELINE = 'no `command → value` baseline found in ## ベースライン — nothing to re-run'
17
31
  const DATE_END = 10
18
-
19
- // The command's stdout, trimmed to one value. A failing command yields its message so the pair still
20
- // prints rather than aborting the whole re-measurement.
32
+ // One baseline command's budget — the same minute `josh-harness.ts` gives one command it spawns. A
33
+ // baseline is a count or a digest that answers in seconds, so a command still running after a minute
34
+ // is stuck, and without a bound it would hold the whole re-measurement open with nothing printed.
35
+ const MEASURE_TIMEOUT_MS = 60_000
36
+ const issue_schema = z.object({
37
+ body: z.string().nullish(),
38
+ author_association: z.string().nullish(),
39
+ })
40
+
41
+ type IssueFields = z.infer<typeof issue_schema>
42
+ type BodyRead = { kind: 'trusted'; body: string } | { kind: 'refused'; reason: string }
43
+
44
+ // The command's stdout, trimmed to one value. A failing or timed-out command yields its message so the
45
+ // pair still prints and the remaining baselines still run, rather than aborting the whole
46
+ // re-measurement.
21
47
  function measure(command: string): string {
22
48
  try {
23
- return execSync(command, { encoding: 'utf8' }).trim()
49
+ return execSync(command, { encoding: 'utf8', timeout: MEASURE_TIMEOUT_MS }).trim()
24
50
  } catch (error) {
25
51
  return `(command failed: ${error_text.message_of(error)})`
26
52
  }
@@ -56,8 +82,35 @@ function today(now: Date): string {
56
82
  return now.toISOString().slice(0, DATE_END)
57
83
  }
58
84
 
59
- async function rerun(body_path: string, now: Date): Promise<number> {
60
- const baselines = baseline_measure.parse_baselines(await readFile(body_path, 'utf8'))
85
+ async function read_issue(issue_number: string): Promise<IssueFields | undefined> {
86
+ const json = await git_gh_issue_read.issue_view_json(issue_number, ISSUE_FIELDS)
87
+
88
+ return json === undefined ? undefined : parse_json_object_safe(json, issue_schema)
89
+ }
90
+
91
+ // The body, only when its author can write to the repository. A read that fails is refused as well:
92
+ // an unknown author is not a trusted one.
93
+ async function read_trusted_body(issue_number: string): Promise<BodyRead> {
94
+ const issue = await read_issue(issue_number)
95
+
96
+ if (issue === undefined) {
97
+ return { kind: 'refused', reason: `could not read issue #${issue_number}` }
98
+ }
99
+
100
+ const association = issue.author_association ?? UNKNOWN_ASSOCIATION
101
+
102
+ if (!TRUSTED_ASSOCIATIONS.has(association)) {
103
+ return {
104
+ kind: 'refused',
105
+ reason: `refusing to run the baseline of #${issue_number}: its author is ${association}, not ${TRUSTED_LIST}`,
106
+ }
107
+ }
108
+
109
+ return { kind: 'trusted', body: issue.body ?? '' }
110
+ }
111
+
112
+ async function rerun(body: string, now: Date): Promise<number> {
113
+ const baselines = baseline_measure.parse_baselines(body)
61
114
 
62
115
  if (baselines.length === 0) {
63
116
  console.error(NO_BASELINE)
@@ -76,23 +129,29 @@ async function rerun(body_path: string, now: Date): Promise<number> {
76
129
  return 0
77
130
  }
78
131
 
79
- async function run(body_path: string | undefined, now: Date): Promise<number> {
80
- if (body_path === undefined) {
132
+ async function run(issue_number: string | undefined, now: Date): Promise<number> {
133
+ if (issue_number === undefined || !ISSUE_NUMBER_PATTERN.test(issue_number)) {
81
134
  console.error(USAGE)
82
135
 
83
136
  return FAILURE_EXIT_CODE
84
137
  }
85
138
 
86
- return await rerun(body_path, now)
139
+ const read = await read_trusted_body(issue_number)
140
+
141
+ if (read.kind === 'refused') {
142
+ console.error(read.reason)
143
+
144
+ return FAILURE_EXIT_CODE
145
+ }
146
+
147
+ return await rerun(read.body, now)
87
148
  }
88
149
 
89
150
  async function main(argv: ReadonlyArray<string>): Promise<void> {
90
151
  process.exitCode = await run(argv[0], new Date())
91
152
  }
92
153
 
93
- const measure_rerun_cli = { run, rerun_one, USAGE, NO_BASELINE }
94
-
95
- const ARGV_OFFSET = 2
154
+ const measure_rerun_cli = { run }
96
155
 
97
156
  if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
98
157
 
@@ -53,7 +53,7 @@ function has_command_output(body: string, heading: string = REPRODUCTION_HEADING
53
53
  return reproduction.has_command && reproduction.has_output
54
54
  }
55
55
 
56
- const reproduction_measure = { REPRODUCTION_HEADING, has_command_output, parse_reproduction }
56
+ const reproduction_measure = { has_command_output }
57
57
 
58
58
  export type { Reproduction }
59
59
  export { reproduction_measure }
@@ -91,6 +91,6 @@ function resolve(input: {
91
91
  return read_file_or_stdin(file_path)
92
92
  }
93
93
 
94
- const cli_body = { read_file_or_stdin, expand_escaped_newlines, has_value, resolve }
94
+ const cli_body = { read_file_or_stdin, has_value, resolve }
95
95
 
96
96
  export { cli_body }
@@ -253,11 +253,8 @@ const file_map_stamp = {
253
253
  changed_since,
254
254
  create,
255
255
  describes_base,
256
- is_file_map,
257
- is_writer_gone,
258
256
  is_writer_running,
259
257
  parse_stamp,
260
- read_at,
261
258
  }
262
259
 
263
260
  export type { FileMapStamp, FileMapStampAccess }
@@ -40,6 +40,7 @@ const ALIASES: Record<string, string> = {
40
40
  f: 'format',
41
41
  sd: 'cspell:dot',
42
42
  bh: 'behavior',
43
+ eu: 'exports:unused',
43
44
  t: 'test',
44
45
  tu: 'test:unit',
45
46
  tr: 'test:related',
@@ -62,6 +63,7 @@ const ALIASES: Record<string, string> = {
62
63
  v: 'version',
63
64
  r: 'ranges',
64
65
  dr: 'doctor',
66
+ rc: 'ruleset:check',
65
67
  pg: 'propagate',
66
68
  ad: 'adopt',
67
69
  ov: 'overrides',
@@ -4,10 +4,9 @@ import { DOCUMENT_COMMANDS } from './josh-commands-document'
4
4
  import { GUARD_COMMANDS } from './josh-commands-guard'
5
5
  import { ISSUE_COMMANDS } from './josh-commands-issue'
6
6
  import { LANE_COMMANDS } from './josh-commands-lane'
7
+ import { RUN_COMMANDS } from './josh-commands-run'
7
8
  import { SPLIT_COMMANDS } from './josh-commands-split'
8
9
 
9
- // One script answers both `run:hold` and `run:release`; the flag below is what tells them apart.
10
- const RUN_HOLD_SCRIPT = 'scripts/run/run-hold-cli.ts'
11
10
  const ISSUE_WITH_OPTIONS = '<issue> [options]'
12
11
 
13
12
  /* eslint-disable @typescript-eslint/naming-convention */
@@ -21,7 +20,7 @@ const AI_COMMANDS: Record<string, CommandEntry> = {
21
20
  reference: ['<keywords> [--size <n>]', 'automation', ['network']],
22
21
  },
23
22
  'stash:pop': {
24
- script: 'scripts/git/stash-pop-cli.ts',
23
+ script: 'scripts/git/stash/stash-pop-cli.ts',
25
24
  description: 'Pop the stash matching this message, not whichever a shared stack has on top',
26
25
  category: 'AI tools',
27
26
  reference: ['<message>', 'automation', ['git']],
@@ -36,7 +35,7 @@ const AI_COMMANDS: Record<string, CommandEntry> = {
36
35
  script: 'scripts/epic/epic-next.ts',
37
36
  description: "List an epic's runnable children, bundled per repository",
38
37
  category: 'AI tools',
39
- reference: ['<epic>', 'automation', ['network']],
38
+ reference: ['<epic>... [--repo <owner/repo>] [--lanes]', 'automation', ['network']],
40
39
  },
41
40
  'epic:bundle': {
42
41
  script: 'scripts/epic/epic-bundle-cli.ts',
@@ -65,9 +64,10 @@ const AI_COMMANDS: Record<string, CommandEntry> = {
65
64
  ...BACKLOG_COMMANDS,
66
65
  cost: {
67
66
  script: 'scripts/cost-runtime/cost-cli.ts',
68
- description: "Report a run's token and credit cost from Claude Code's session transcripts",
67
+ description:
68
+ 'Say whether the next turn of a run crosses the context-cut threshold (--cut) or a given tokens-per-request figure (--over)',
69
69
  category: 'AI tools',
70
- reference: ['[--cut|--over]', 'automation', ['none']],
70
+ reference: ['(--cut | --over <tokens-per-request>) [--path <dir>]', 'automation', ['none']],
71
71
  },
72
72
  ...DOCUMENT_COMMANDS,
73
73
  time: {
@@ -134,100 +134,7 @@ const AI_COMMANDS: Record<string, CommandEntry> = {
134
134
  category: 'AI tools',
135
135
  reference: ['<unit-files> <unit-files> [<unit-files> …]', 'automation', ['none']],
136
136
  },
137
- 'run:hold': {
138
- script: RUN_HOLD_SCRIPT,
139
- description: 'Claim this working tree for a run, or say which run already holds it',
140
- category: 'AI tools',
141
- reference: ['[issue]', 'automation', ['files']],
142
- },
143
- 'run:release': {
144
- script: RUN_HOLD_SCRIPT,
145
- description: "Release this working tree's run record",
146
- category: 'AI tools',
147
- reference: ['[issue|--force]', 'automation', ['files']],
148
- default_script_arguments: ['--release'],
149
- },
150
- 'run:tidy': {
151
- script: 'scripts/run/run-tidy-cli.ts',
152
- description: 'Close merged lanes and drop stashes whose issues are all merged',
153
- category: 'AI tools',
154
- reference: ['', 'automation', ['git', 'network', 'files']],
155
- },
156
- 'run:carry': {
157
- script: 'scripts/run/run-carry-cli.ts',
158
- description: 'Carry one invocation’s budget across its own session cuts',
159
- category: 'AI tools',
160
- reference: ['<operation> [arguments...]', 'automation', ['files']],
161
- },
162
- 'run:wake': {
163
- script: 'scripts/run/run-wake-cli.ts',
164
- // `.env` rather than the ambient environment:
165
- // the failure warning needs the Telegram credentials, the same
166
- // reasons `notify` and `followup` carry these flags.
167
- tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
168
- description: 'Wake the next session of a cut backlogrun from outside the conversation',
169
- category: 'AI tools',
170
- reference: ['[options]', 'automation', ['processes', 'notifications']],
171
- },
172
- 'run:cut': {
173
- script: 'scripts/run/run-cut-cli.ts',
174
- description: 'Cut a lane child before the gate and resume a fresh process',
175
- category: 'AI tools',
176
- reference: ['[--resume] <issue> [--impl] [--handoff <path>]', 'automation', ['files']],
177
- },
178
- 'run:liveness': {
179
- script: 'scripts/run/run-liveness-cli.ts',
180
- description: 'Say whether a delegated unit is still working, or stopped without reporting',
181
- category: 'AI tools',
182
- reference: ['<issue> --output <path> [options]', 'automation', ['processes']],
183
- },
184
- 'run:ending': {
185
- script: 'scripts/run/run-ending-cli.ts',
186
- description: 'Classify how a dispatched lane child ended (merged, cut, abandoned, unreadable)',
187
- category: 'AI tools',
188
- reference: ['<issue> --output <path> [--repo <owner/repo>]', 'automation', ['network']],
189
- },
190
- 'run:progress': {
191
- script: 'scripts/run/run-progress-cli.ts',
192
- description: 'Report an unattended run’s progress once it has gone quiet for an interval',
193
- category: 'AI tools',
194
- reference: ['[--wait|--mark]', 'automation', ['files']],
195
- },
196
- 'run:prep': {
197
- script: 'scripts/run/run-prep-cli.ts',
198
- description: 'Bundle a run’s pre-edit reads: body, comments, state, dependency scope',
199
- category: 'AI tools',
200
- reference: ['<issue>', 'automation', ['network']],
201
- },
202
- // The entry sequence a lane opened on, folded into one call (joshuafolkken/kit#2372): claim the tree,
203
- // read the budget, gather the issue reads and decide the pre-implementation step. `run:hold`,
204
- // `cost --cut`, `run:prep` and `run:step` were four round trips re-billing a lane's full context each.
205
- 'run:entry': {
206
- script: 'scripts/run/run-entry-cli.ts',
207
- description:
208
- 'Open a run in one call: claim the tree, read the budget, bundle the reads, decide the pre-implementation step',
209
- category: 'AI tools',
210
- reference: ['<issue>', 'automation', ['git', 'network', 'files']],
211
- },
212
- 'run:status': {
213
- script: 'scripts/run/run-status-cli.ts',
214
- description: 'Bundle a run’s read-only status: issue state, cost verdict, carry counters',
215
- category: 'AI tools',
216
- reference: ['<issue> [--repo <owner/repo>]', 'automation', ['network']],
217
- },
218
- 'run:next': {
219
- script: 'scripts/run/run-next-cli.ts',
220
- description: 'Print the next step a fullrun takes, computed from the run’s state',
221
- category: 'AI tools',
222
- reference: ['<issue>', 'automation', ['network']],
223
- },
224
- 'run:step': {
225
- script: 'scripts/run/run-step-cli.ts',
226
- description:
227
- 'Print the run’s next single action, computed from the event stream, carry record and issue state',
228
- category: 'AI tools',
229
- reference: ['<issue>', 'automation', ['network', 'files']],
230
- },
137
+ ...RUN_COMMANDS,
231
138
  'repo:party': {
232
139
  script: 'scripts/discovery/repo-party-cli.ts',
233
140
  description:
@@ -255,7 +162,7 @@ const AI_COMMANDS: Record<string, CommandEntry> = {
255
162
  'run:tail': {
256
163
  script: 'scripts/run/run-tail-cli.ts',
257
164
  description:
258
- 'Close a run in one call: commit the observation ledger, read the citations, decide the release scope',
165
+ 'Close a run in one call: return to the default branch, commit the observation ledger, read the citations, decide the release scope',
259
166
  category: 'AI tools',
260
167
  reference: ['[<issue> ...]', 'automation', ['git', 'network']],
261
168
  },
@@ -269,7 +176,7 @@ const AI_COMMANDS: Record<string, CommandEntry> = {
269
176
  'Ship a change in one call: gate, commit/push/PR, the CI-wait merge and the report bookkeeping, stopping at the first failed step',
270
177
  category: 'AI tools',
271
178
  reference: [
272
- '"<title> #<N>" [<follow-up-N> ...] [--cite <N>] [--review] [--detach] [--notify-message <text> | --notify-message-file <path>] | --log <N>',
179
+ '"<title> #<N>" [<follow-up-N> ...] [--cite <N>] [--review] [--detach] [--body-file <path>] [--notify-message <text> | --notify-message-file <path>] | --log <N>',
273
180
  'automation',
274
181
  ['git', 'network'],
275
182
  ],
@@ -33,7 +33,11 @@ const BACKLOG_COMMANDS: Record<string, CommandEntry> = {
33
33
  description:
34
34
  'Print the whole backlog as a plan: ready now, waiting on what, waiting on a person, out of scope',
35
35
  category: 'AI tools',
36
- reference: ['[issue...] [--only]', 'automation', ['network']],
36
+ reference: [
37
+ '[issue...] [--only] [--waves] [--exclude <n>[,<n>...]]',
38
+ 'automation',
39
+ ['network'],
40
+ ],
37
41
  },
38
42
  'backlog:stalled': {
39
43
  script: 'scripts/backlog/backlog-stalled-cli.ts',