@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
@@ -24,8 +24,4 @@ async function main(): Promise<void> {
24
24
  process.exitCode = SUCCESS_EXIT_CODE
25
25
  }
26
26
 
27
- const run_stranded_cli = { main }
28
-
29
27
  if (process.argv[1] === fileURLToPath(import.meta.url)) await main()
30
-
31
- export { run_stranded_cli }
@@ -1,4 +1,4 @@
1
- import { telegram_notify } from '#scripts/git/telegram-notify'
1
+ import { telegram_notify } from '#scripts/notify/telegram-notify'
2
2
  import { run_carry, type CarryRead, type RunCarry } from './run-carry'
3
3
  import { run_event_stream } from './run-event-stream'
4
4
  import { run_event_stream_emit } from './run-event-stream-emit'
@@ -128,7 +128,7 @@ async function run_stranded_check(): Promise<void> {
128
128
  }
129
129
  }
130
130
 
131
- const run_stranded_detect = { DEFAULT_PORTS, detect_and_report, gather, report, run_stranded_check }
131
+ const run_stranded_detect = { detect_and_report, run_stranded_check }
132
132
 
133
133
  export { run_stranded_detect }
134
134
  export type { DetectPorts, RecordTargets }
@@ -22,7 +22,6 @@ import { run_tail, type TailSection } from './run-tail'
22
22
  // step for a line written on the default branch outside any issue's run.
23
23
 
24
24
  const ARGV_OFFSET = 2
25
- const SUCCESS_EXIT_CODE = 0
26
25
  const FAILURE_EXIT_CODE = 1
27
26
  const ISSUE_NUMBER_PATTERN = /^[1-9]\d*$/u
28
27
  const USAGE = 'Usage: josh run:tail [<issue-number> ...]'
@@ -33,21 +32,27 @@ interface Step {
33
32
  argv: (issues: ReadonlyArray<string>) => ReadonlyArray<string>
34
33
  }
35
34
 
36
- // The steps in the order a run closes on: any ledger line the run's own commit did not carry
37
- // (joshuafolkken/kit#2763) is committed first so the recurrence count is on main — on most runs the
38
- // flush answers `clean` — the citations are read for the completion report, and the release scope is
39
- // decided last.
40
- const FLUSH_STEP: Step = {
41
- header: run_tail.OBSERVATIONS_HEADER,
42
- argv: () => ['observations:flush'],
43
- }
35
+ // The steps in the order a run closes on: the checkout returns to the default branch, any ledger line
36
+ // the run's own commit did not carry (joshuafolkken/kit#2763) is committed so the recurrence count is on
37
+ // main — on most runs the flush answers `clean` — the citations are read for the completion report, and
38
+ // the release scope is decided last.
39
+ //
40
+ // **The return comes first because the flush refuses anywhere else** (joshuafolkken/kit#2979). A run
41
+ // closes right after its merge, still on the feature branch it shipped from, and `josh ship` reaches
42
+ // this report with nothing in between — so the flush stopped a merged run as failed. `main:sync` is the
43
+ // step a person used to type after the fact; it fast-forwards the local default branch before the
44
+ // checkout, so a ledger line appended after the merge is carried along rather than refused.
45
+ const LEDGER_STEPS: ReadonlyArray<Step> = [
46
+ { header: run_tail.SYNC_HEADER, argv: () => ['main:sync'] },
47
+ { header: run_tail.OBSERVATIONS_HEADER, argv: () => ['observations:flush'] },
48
+ ]
44
49
  const REPORT_STEPS: ReadonlyArray<Step> = [
45
50
  { header: run_tail.CITATIONS_HEADER, argv: (issues) => ['issue:cite', ...issues] },
46
51
  { header: run_tail.RELEASE_HEADER, argv: () => ['release:scope'] },
47
52
  ]
48
53
 
49
54
  function steps_for(is_lane_child: boolean): ReadonlyArray<Step> {
50
- return is_lane_child ? REPORT_STEPS : [FLUSH_STEP, ...REPORT_STEPS]
55
+ return is_lane_child ? REPORT_STEPS : [...LEDGER_STEPS, ...REPORT_STEPS]
51
56
  }
52
57
 
53
58
  // Numbers only — a target `issue:cite` reads as an issue, so a stray flag is refused rather than
@@ -75,6 +80,7 @@ async function close_run(issues: ReadonlyArray<string>): Promise<ReadonlyArray<T
75
80
 
76
81
  const is_lane_child = lane_child_marker.is_child_of(process.cwd())
77
82
 
83
+ // eslint-disable-next-line no-await-in-loop -- the tail steps run in their declared order
78
84
  for (const step of steps_for(is_lane_child)) sections.push(await run_step(step, issues))
79
85
 
80
86
  return sections
@@ -100,7 +106,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
100
106
  process.exitCode = await run(argv)
101
107
  }
102
108
 
103
- const run_tail_cli = { SUCCESS_EXIT_CODE, USAGE, close_run, main, parse_issues, run }
109
+ const run_tail_cli = { run }
104
110
 
105
111
  if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
106
112
 
@@ -9,6 +9,7 @@
9
9
  // each step's output under a header and answers the exit code from the collected codes, so a test pins
10
10
  // the composite without a ledger ever being committed or a release ever read.
11
11
 
12
+ const SYNC_HEADER = '=== sync ==='
12
13
  const OBSERVATIONS_HEADER = '=== observations ==='
13
14
  const CITATIONS_HEADER = '=== citations ==='
14
15
  const RELEASE_HEADER = '=== release ==='
@@ -52,6 +53,7 @@ const run_tail = {
52
53
  CITATIONS_HEADER,
53
54
  OBSERVATIONS_HEADER,
54
55
  RELEASE_HEADER,
56
+ SYNC_HEADER,
55
57
  exit_code,
56
58
  format_report,
57
59
  section_body,
@@ -1,5 +1,5 @@
1
1
  import { git_spawn } from '#scripts/git/git-spawn'
2
- import { git_stash } from '#scripts/git/git-stash'
2
+ import { git_stash } from '#scripts/git/stash/git-stash'
3
3
  import { lane_close } from '#scripts/lane/lane-close'
4
4
  import { lane_registry, type LaneInfo } from '#scripts/lane/lane-registry'
5
5
  import { run_hold } from './run-hold'
@@ -96,6 +96,7 @@ async function tidy_lanes(is_merged: IsMerged): Promise<Array<Outcome>> {
96
96
  const lanes = await lane_registry.list_lanes()
97
97
 
98
98
  for (const lane of lanes) {
99
+ // eslint-disable-next-line no-await-in-loop -- a close prunes the worktree list the next one reads
99
100
  const outcome = await tidy_lane(lane, is_merged)
100
101
 
101
102
  if (outcome !== undefined) outcomes.push(outcome)
@@ -1,6 +1,6 @@
1
- import { git_stash, type StashEntry } from '#scripts/git/git-stash'
2
- import { stash_orphans } from '#scripts/git/stash-orphans'
3
- import { stash_sweep_lock } from '#scripts/git/stash-sweep-lock'
1
+ import { git_stash, type StashEntry } from '#scripts/git/stash/git-stash'
2
+ import { stash_orphans } from '#scripts/git/stash/stash-orphans'
3
+ import { stash_sweep_lock } from '#scripts/git/stash/stash-sweep-lock'
4
4
  import { bounded_pool } from '#scripts/lib/bounded-pool'
5
5
  import { observation_ledger } from '#scripts/observations/observation-ledger'
6
6
  import { observation_ledger_home } from '#scripts/observations/observation-ledger-home'
@@ -18,20 +18,19 @@ const GONE_REASON = 'already dropped by another run'
18
18
  const BUSY_REASON = 'another run held the stash sweep lock'
19
19
 
20
20
  // An entry cut before joshuafolkken/kit#2919 holds its lines at an old single-file path, so the lines
21
- // of every ledger path it touches are carried to the current ledger.
21
+ // of every ledger path it touches are carried to the current ledger. The reads are independent, and the
22
+ // lines come back in path order however the reads finish.
22
23
  async function added_ledger_lines(
23
24
  hash: string,
24
25
  ledger_paths: ReadonlyArray<string>,
25
26
  ): Promise<Array<string>> {
26
- const added: Array<string> = []
27
-
28
- for (const ledger_path of ledger_paths) {
29
- const lines = await git_stash.added_lines(hash, ledger_path)
30
-
31
- added.push(...lines)
32
- }
27
+ const added = await bounded_pool.bounded_map(
28
+ ledger_paths,
29
+ READ_CONCURRENCY,
30
+ async (ledger_path) => await git_stash.added_lines(hash, ledger_path),
31
+ )
33
32
 
34
- return added
33
+ return added.flat()
35
34
  }
36
35
 
37
36
  // How many ledger lines went into the running work tree's ledger before the drop. The duplicate check
@@ -107,6 +106,7 @@ async function tidy_entries(
107
106
  const outcomes: Array<Outcome> = []
108
107
 
109
108
  for (const entry of entries) {
109
+ // eslint-disable-next-line no-await-in-loop -- drops shift the stash stack and append to the same ledger
110
110
  const outcome = await tidy_entry(entry, merged)
111
111
 
112
112
  if (outcome !== undefined) outcomes.push(outcome)
@@ -3,8 +3,8 @@ import { randomUUID } from 'node:crypto'
3
3
  import path from 'node:path'
4
4
  import { fileURLToPath } from 'node:url'
5
5
  import type { AgentProfile } from '#scripts/agent/agent-role-profile'
6
- import { telegram_notify } from '#scripts/git/telegram-notify'
7
6
  import { cli_flags } from '#scripts/lib/cli-flags'
7
+ import { telegram_notify } from '#scripts/notify/telegram-notify'
8
8
  import { run_carry, type CarryRead } from './run-carry'
9
9
  import { run_event_stream } from './run-event-stream'
10
10
  import { run_headless } from './run-headless'
@@ -226,7 +226,7 @@ async function warn_of_stop(stop: LoopStop, body: string, context: WakeContext):
226
226
  }
227
227
 
228
228
  // **Only a failed wake exits non-zero, and the two reasons that newly warn do not**
229
- // (joshuafolkken/kit#1746). The verdict-and-exit-code table in `docs/josh-commands.md` is a contract
229
+ // (joshuafolkken/kit#1746). The verdict-and-exit-code table in `docs/josh-commands-automation.md` is a contract
230
230
  // callers branch on; what `expired` and `unreadable` were missing is the notification, not a different
231
231
  // exit code, and changing both at once would break a caller to fix a silence.
232
232
  function exit_code_of(reason: WakeStopReason): number {
@@ -290,7 +290,7 @@ function start(context: WakeContext, interval: string | undefined): number {
290
290
  const existing = run_wake.read_wake(context.wake_target)
291
291
 
292
292
  if (existing !== undefined && run_wake.is_supervisor_live(existing)) {
293
- console.error(run_wake_describe.describe_wake(existing, context))
293
+ console.error(run_wake_describe.describe_wake_cited(existing, context))
294
294
 
295
295
  return report(RUNNING_VERDICT)
296
296
  }
@@ -342,7 +342,7 @@ function list(context: WakeContext): number {
342
342
 
343
343
  if (wake === undefined) return report(NONE_VERDICT)
344
344
 
345
- console.error(run_wake_describe.describe_wake(wake, context))
345
+ console.error(run_wake_describe.describe_wake_cited(wake, context))
346
346
 
347
347
  return report(run_wake.is_supervisor_live(wake) ? SUPERVISING_VERDICT : STALE_VERDICT)
348
348
  }
@@ -410,7 +410,6 @@ const run_wake_cli = {
410
410
  NONE_VERDICT,
411
411
  RUNNING_VERDICT,
412
412
  STALE_VERDICT,
413
- STARTED_VERDICT,
414
413
  STOPPED_VERDICT,
415
414
  SUPERVISING_VERDICT,
416
415
  UNKNOWN_VERDICT,
@@ -1,4 +1,6 @@
1
1
  import { agent_role_profile } from '#scripts/agent/agent-role-profile'
2
+ import { gh_spawn } from '#scripts/gh/gh-spawn'
3
+ import { issue_citation } from '#scripts/rules/issue-citation'
2
4
  import { run_carry, type CarryRead } from './run-carry'
3
5
  import { run_event_stream } from './run-event-stream'
4
6
  import { run_liveness } from './run-liveness'
@@ -9,6 +11,7 @@ import { run_wake, type RunWake } from './run-wake'
9
11
  // record reads back to a person lives here, one cohesive block.
10
12
 
11
13
  const UNKNOWN_CUTS = 'an unreadable number of'
14
+ const REPO_LOOKUP_TIMEOUT_MS = 10_000
12
15
  const STOP_COMMAND = 'pnpm josh run:wake --stop'
13
16
 
14
17
  // The three paths every verb needs: the carry record it reads, its own record, and the work tree a
@@ -91,7 +94,22 @@ function describe_wake(wake: RunWake, context: WakeContext): string {
91
94
  .join('\n')
92
95
  }
93
96
 
94
- const run_wake_describe = { STOP_COMMAND, describe_wake }
97
+ // The description as a person reads it, every issue on it a number-link (joshuafolkken/kit#2943). The
98
+ // invocation and the newest event both name issues (`backlogrun #1 #2`, `#1904 merged`), and a report
99
+ // that copies them bare is what the Stop guard sends back. The repository is asked here, bounded, rather
100
+ // than in the context every verb resolves: only the two describing verbs print it, and a lookup that
101
+ // does not answer leaves the description as it was rather than withholding it.
102
+ function cite_description(description: string, repo: string | undefined): string {
103
+ return repo === undefined ? description : issue_citation.linkify(description, repo)
104
+ }
105
+
106
+ function describe_wake_cited(wake: RunWake, context: WakeContext): string {
107
+ const repo = gh_spawn.get_repo_name_with_owner_within(REPO_LOOKUP_TIMEOUT_MS)
108
+
109
+ return cite_description(describe_wake(wake, context), repo)
110
+ }
111
+
112
+ const run_wake_describe = { STOP_COMMAND, cite_description, describe_wake, describe_wake_cited }
95
113
 
96
114
  export type { WakeContext }
97
115
  export { run_wake_describe }
@@ -199,10 +199,12 @@ async function run_loop(target: string, ports: LoopPorts, interval_ms: number):
199
199
  let wake = run_wake.read_own_wake(target)
200
200
 
201
201
  while (wake !== undefined) {
202
+ // eslint-disable-next-line no-await-in-loop -- polling: each read waits on the state the previous one saw
202
203
  const stop = await run_pass(target, wake, ports)
203
204
 
204
205
  if (stop !== undefined) return stop
205
206
 
207
+ // eslint-disable-next-line no-await-in-loop -- polling: each read waits on the state the previous one saw
206
208
  await ports.sleep(next_interval(run_wake.read_own_wake(target), interval_ms, ports.now()))
207
209
  wake = run_wake.read_own_wake(target)
208
210
  }
@@ -213,10 +215,8 @@ async function run_loop(target: string, ports: LoopPorts, interval_ms: number):
213
215
  const run_wake_loop = {
214
216
  FAILED_REASON,
215
217
  MAX_BACKOFF_FACTOR,
216
- STOPPED_REASON,
217
218
  next_interval,
218
219
  run_loop,
219
- step,
220
220
  }
221
221
 
222
222
  export type { DriveResult, LoopPorts, LoopStop }
@@ -1,6 +1,7 @@
1
1
  import { agent_role_profile, type AgentProfile } from '#scripts/agent/agent-role-profile'
2
2
  import { backlog_budget } from '#scripts/backlog/backlog-budget'
3
3
  import { process_identity } from '#scripts/josh/process-identity'
4
+ import { process_owner_schema } from '#scripts/josh/process-owner'
4
5
  import { stamp_file } from '#scripts/josh/stamp-file'
5
6
  import { z } from 'zod'
6
7
  import type { CarryRead } from './run-carry'
@@ -209,11 +210,9 @@ const STOP_REASONS: Record<'none' | 'expired' | 'unreadable', WakeStopReason> =
209
210
  unreadable: 'unreadable',
210
211
  }
211
212
 
212
- const run_wake_schema = z.object({
213
+ const run_wake_schema = process_owner_schema.extend({
213
214
  invocation: z.string(),
214
215
  started_at: z.string(),
215
- pid: z.number(),
216
- process_start: z.string().optional(),
217
216
  woke: z.number(),
218
217
  woke_at: z.string().optional(),
219
218
  // **Every optional field of `RunWake` has to be listed here.** `z.object` strips what it does not
@@ -583,7 +582,6 @@ const run_wake = {
583
582
  IDLE_CEILING_MS,
584
583
  MAX_WAKE_ATTEMPTS,
585
584
  WAKE_GRACE_MS,
586
- WAKE_PREFIX,
587
585
  claim,
588
586
  count_claim,
589
587
  count_wake,
@@ -30,8 +30,4 @@ async function main(): Promise<void> {
30
30
  process.exitCode = await run()
31
31
  }
32
32
 
33
- const run_watcher_guard_cli = { run }
34
-
35
33
  if (process.argv[1] === fileURLToPath(import.meta.url)) await main()
36
-
37
- export { run_watcher_guard_cli }
@@ -1,4 +1,5 @@
1
1
  import { lane_registry } from '#scripts/lane/lane-registry'
2
+ import { run_headless } from './run-headless'
2
3
  import { run_progress_clock } from './run-progress-clock'
3
4
 
4
5
  // A watcher that stopped while children are still in-flight leaves the parent blind to completions
@@ -29,19 +30,21 @@ type GuardResult = { kind: 'ok' } | { kind: 'stale'; note: string }
29
30
 
30
31
  const OK_RESULT: GuardResult = { kind: 'ok' }
31
32
 
32
- // The lanes a parent is still waiting on. A stranded lane has no child working in it, so it is not
33
- // in-flight — the one definition both this guard and the headless stop rule read (`run-headless.ts`).
34
- async function has_lanes_in_flight(): Promise<boolean> {
35
- const all_lanes = await lane_registry.list_lanes()
33
+ // **Only the run that opened the lanes owes them a watcher** (joshuafolkken/kit#2965). The lane listing
34
+ // is machine-wide, so a session with no run of its own — an investigation, a `fullrun` beside a batch —
35
+ // used to be refused for another run's lanes. The session that drives the live `backlogrun` carry
36
+ // record is the one that dispatched them; every other session passes.
37
+ async function owes_watcher(): Promise<boolean> {
38
+ if (!(await run_headless.is_backlog_parent())) return false
36
39
 
37
- return all_lanes.some((lane) => !lane.is_stranded)
40
+ return await lane_registry.has_lanes_in_flight()
38
41
  }
39
42
 
40
43
  // `life_target` is the path returned by `run_progress_read.stamp_target()` or
41
44
  // `run_progress_clock.life_target_of(git_directory)`. Passed in rather than resolved here so the
42
45
  // caller can use whichever resolution fits its sync/async context.
43
46
  async function check(life_target: string): Promise<GuardResult> {
44
- if (!(await has_lanes_in_flight())) return OK_RESULT
47
+ if (!(await owes_watcher())) return OK_RESULT
45
48
 
46
49
  if (run_progress_clock.is_life_fresh(life_target, STALE_THRESHOLD_MS)) return OK_RESULT
47
50
 
@@ -52,7 +55,6 @@ const run_watcher_guard = {
52
55
  STALE_NOTE,
53
56
  STALE_THRESHOLD_MS,
54
57
  check,
55
- has_lanes_in_flight,
56
58
  }
57
59
 
58
60
  export type { GuardResult }
@@ -81,6 +81,6 @@ async function watcher_hook_reason(
81
81
  return await stale_reason(transcript, now_ms)
82
82
  }
83
83
 
84
- const run_watcher_hook = { SWITCH_ENV_KEY, STAMP_PREFIX, watcher_hook_reason }
84
+ const run_watcher_hook = { transcript_of, watcher_hook_reason }
85
85
 
86
86
  export { run_watcher_hook }
@@ -1,5 +1,6 @@
1
1
  import { createHash } from 'node:crypto'
2
2
  import { existsSync, readdirSync, readFileSync, writeFileSync } from 'node:fs'
3
+ import { composite_actions } from '#scripts/ci/composite-actions'
3
4
  import { execaSync } from 'execa'
4
5
 
5
6
  // Where the workflows that install safe-chain on the runner live. Each carries the release and the
@@ -25,13 +26,18 @@ function installer_url(version: string): string {
25
26
  return `https://github.com/AikidoSec/safe-chain/releases/download/${version}/install-safe-chain.sh`
26
27
  }
27
28
 
29
+ // The local composite actions follow the workflows: kit's own pin lives in
30
+ // `.github/actions/setup-pnpm`, which every kit workflow installs through (joshuafolkken/kit#2982).
28
31
  function list_workflows(): Array<string> {
29
- return WORKFLOW_DIRECTORIES.filter((directory) => existsSync(directory)).flatMap((directory) =>
30
- readdirSync(directory)
31
- .filter((file_name) => WORKFLOW_FILE_RE.test(file_name))
32
- .toSorted((left, right) => left.localeCompare(right))
33
- .map((file_name) => `${directory}/${file_name}`),
32
+ const workflows = WORKFLOW_DIRECTORIES.filter((directory) => existsSync(directory)).flatMap(
33
+ (directory) =>
34
+ readdirSync(directory)
35
+ .filter((file_name) => WORKFLOW_FILE_RE.test(file_name))
36
+ .toSorted((left, right) => left.localeCompare(right))
37
+ .map((file_name) => `${directory}/${file_name}`),
34
38
  )
39
+
40
+ return [...workflows, ...composite_actions.list()]
35
41
  }
36
42
 
37
43
  function extract_pinned_version(content: string): string | undefined {
@@ -1,8 +1,8 @@
1
1
  import { existsSync, readFileSync, writeFileSync } from 'node:fs'
2
2
  import path from 'node:path'
3
3
  import { file_reader } from '#scripts/lib/read-file'
4
+ import { yaml_document } from '#scripts/lib/yaml-document'
4
5
  import { release_age } from '#scripts/version/release-age'
5
- import { yaml_document } from '#scripts/yaml/yaml-document'
6
6
  import { dump } from 'js-yaml'
7
7
  import { z } from 'zod'
8
8
 
@@ -191,7 +191,6 @@ function format_below_floor(version: string): string {
191
191
  }
192
192
 
193
193
  const security_audit_provision_logic = {
194
- FORCED_DOWNLOAD_TIMEOUT_MS,
195
194
  RETRY_INTERVAL_MS,
196
195
  SESSION_DOWNLOAD_TIMEOUT_MS,
197
196
  SCANNER_VERSION,
@@ -5,6 +5,7 @@ import { fileURLToPath } from 'node:url'
5
5
  import { PROJECT_ROOT } from '#scripts/init/init-paths'
6
6
  import { stamp_file } from '#scripts/josh/stamp-file'
7
7
  import { error_text } from '#scripts/lib/error-message'
8
+ import { timed_fetch } from '#scripts/lib/timed-fetch'
8
9
  import { security_audit } from './security-audit'
9
10
  import { security_audit_logic } from './security-audit-logic'
10
11
  import { security_audit_provision_logic, type ScannerAsset } from './security-audit-provision-logic'
@@ -33,7 +34,7 @@ interface ProvisionOutcome {
33
34
  // catch-all would drop the release URL out of the message that names where the fetch went.
34
35
  async function download(url: string, timeout_ms: number): Promise<DownloadOutcome> {
35
36
  try {
36
- const response = await fetch(url, { signal: AbortSignal.timeout(timeout_ms) })
37
+ const response = await timed_fetch(url, {}, timeout_ms)
37
38
  if (!response.ok) return { reason: `HTTP ${String(response.status)}` }
38
39
 
39
40
  return { content: Buffer.from(await response.arrayBuffer()), reason: '' }
@@ -180,6 +181,6 @@ async function main(): Promise<void> {
180
181
 
181
182
  if (process.argv[1] === fileURLToPath(import.meta.url)) await main()
182
183
 
183
- const security_audit_provision = { attempt, download, install, main, provision, report }
184
+ const security_audit_provision = { attempt, provision, report }
184
185
 
185
186
  export { security_audit_provision }
@@ -137,7 +137,6 @@ const security_audit = {
137
137
  meets_floor,
138
138
  resolve_scanner,
139
139
  run_scanner,
140
- scanner_version,
141
140
  }
142
141
 
143
142
  export { security_audit }
@@ -120,7 +120,6 @@ function format_security_updates_report(
120
120
  }
121
121
 
122
122
  const security_updates_logic = {
123
- SETTING_LABEL,
124
123
  enable_command,
125
124
  classify_security_updates,
126
125
  is_exposed,
@@ -1,9 +1,5 @@
1
1
  #!/usr/bin/env tsx
2
- import { existsSync, readFileSync } from 'node:fs'
3
- import path from 'node:path'
4
2
  import { fileURLToPath } from 'node:url'
5
- import { git_command } from '#scripts/git/git-command'
6
- import { error_text } from '#scripts/lib/error-message'
7
3
  import { managed_config_scope } from '#scripts/sync/managed-config-scope'
8
4
  import { z } from 'zod'
9
5
  import {
@@ -12,6 +8,7 @@ import {
12
8
  type HotspotDisposition,
13
9
  type HotspotFetch,
14
10
  } from './sonar-hotspots'
11
+ import { sonar_project } from './sonar-project'
15
12
 
16
13
  // `josh sonar:hotspots <PR>` — fetch the SonarCloud hotspots on a pull request and print the Step B
17
14
  // disposition of each (joshuafolkken/kit#2182).
@@ -24,11 +21,7 @@ import {
24
21
 
25
22
  const ARGV_OFFSET = 2
26
23
  const USAGE = 'Usage: josh sonar:hotspots <PR>'
27
- const SONAR_HOST = 'https://sonarcloud.io'
28
24
  const HOTSPOTS_PATH = '/api/hotspots/search'
29
- const PROPERTIES_FILE = 'sonar-project.properties'
30
- const PROJECT_KEY_PREFIX = 'sonar.projectKey='
31
- const FETCH_TIMEOUT_MS = 10_000
32
25
  const FAILURE_EXIT_CODE = 1
33
26
  const UNKNOWN_LINE = '?'
34
27
 
@@ -44,34 +37,17 @@ const hotspot_schema = z.looseObject({
44
37
  })
45
38
  const response_schema = z.looseObject({ hotspots: z.array(hotspot_schema).optional() })
46
39
 
47
- function read_project_key(root: string): string | undefined {
48
- const file = path.join(root, PROPERTIES_FILE)
49
- if (!existsSync(file)) return undefined
50
-
51
- const line = readFileSync(file, 'utf8')
52
- .split('\n')
53
- .find((entry) => entry.startsWith(PROJECT_KEY_PREFIX))
54
-
55
- return line?.slice(PROJECT_KEY_PREFIX.length).trim()
56
- }
57
-
58
40
  function hotspots_url(project_key: string, pull_request: string): string {
59
- const query = new URLSearchParams({ projectKey: project_key, pullRequest: pull_request })
60
-
61
- return `${SONAR_HOST}${HOTSPOTS_PATH}?${query.toString()}`
41
+ return sonar_project.api_url(HOTSPOTS_PATH, {
42
+ projectKey: project_key,
43
+ pullRequest: pull_request,
44
+ })
62
45
  }
63
46
 
64
47
  async function fetch_hotspots(url: string): Promise<HotspotFetch> {
65
- try {
66
- const response = await fetch(url, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS) })
67
- if (!response.ok) return { error: `HTTP ${String(response.status)}` }
68
-
69
- const parsed = response_schema.parse(await response.json())
48
+ const read = await sonar_project.fetch_json(url, response_schema)
70
49
 
71
- return { hotspots: parsed.hotspots ?? [] }
72
- } catch (error) {
73
- return { error: error_text.message_of(error) }
74
- }
50
+ return 'error' in read ? read : { hotspots: read.data.hotspots ?? [] }
75
51
  }
76
52
 
77
53
  function is_managed(component: string): boolean {
@@ -108,23 +84,10 @@ async function fetch_and_print(project_key: string, pull_request: string): Promi
108
84
  }
109
85
 
110
86
  async function run(argv: ReadonlyArray<string>): Promise<number> {
111
- const [pull_request] = argv
112
-
113
- if (pull_request === undefined || pull_request.startsWith('-')) {
114
- console.error(USAGE)
115
-
116
- return FAILURE_EXIT_CODE
117
- }
118
-
119
- const project_key = read_project_key(await git_command.repository_root())
120
-
121
- if (project_key === undefined) {
122
- console.error(`no ${PROJECT_KEY_PREFIX} found in ${PROPERTIES_FILE}`)
123
-
124
- return FAILURE_EXIT_CODE
125
- }
87
+ const target = await sonar_project.resolve_target(argv, USAGE)
88
+ if (target === undefined) return FAILURE_EXIT_CODE
126
89
 
127
- await fetch_and_print(project_key, pull_request)
90
+ await fetch_and_print(target.project_key, target.pull_request)
128
91
 
129
92
  return 0
130
93
  }
@@ -136,12 +99,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
136
99
  const sonar_hotspots_cli = {
137
100
  fetch_hotspots,
138
101
  format_hotspot,
139
- hotspots_url,
140
- is_managed,
141
- main,
142
102
  print_disposition,
143
- read_project_key,
144
- run,
145
103
  USAGE,
146
104
  }
147
105
 
@@ -95,7 +95,6 @@ const sonar_hotspots = {
95
95
  classify_fetch,
96
96
  classify_hotspot,
97
97
  component_path,
98
- HOTSPOT_BRANCHES,
99
98
  UNREADABLE,
100
99
  }
101
100