@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
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env tsx
2
2
  import {
3
+ FETCH_TIMEOUT_MS,
3
4
  RUN_LANE_LABEL,
4
5
  RUN_SOLO_LABEL,
5
6
  agent_role_profile,
@@ -8,25 +9,29 @@ import {
8
9
  git_gh_api_path,
9
10
  git_gh_exec,
10
11
  has_label_name,
12
+ issue_cite,
11
13
  lane_background,
12
- lane_child_invocation,
14
+ lane_handoff,
13
15
  lane_park,
14
16
  lane_registry,
15
17
  process_identity,
18
+ process_owner_schema,
16
19
  repo_party,
17
20
  run_carry,
18
21
  run_cut,
22
+ run_event_stream,
23
+ run_event_stream_emit,
24
+ run_headless,
19
25
  run_hold,
20
- run_invocation,
21
- run_watcher_guard
22
- } from "./chunk-EIFCAJRB.js";
26
+ run_invocation
27
+ } from "./chunk-UD24EAIL.js";
23
28
  import {
24
29
  session_language
25
30
  } from "./chunk-6V5OPIUU.js";
26
31
  import {
27
32
  hook_decision,
28
33
  lane_child_marker
29
- } from "./chunk-HOYJU5RM.js";
34
+ } from "./chunk-E54KGFEQ.js";
30
35
  import {
31
36
  PROJECT_ROOT,
32
37
  json_value,
@@ -34,7 +39,7 @@ import {
34
39
  time_density_hook,
35
40
  time_hook_transcript,
36
41
  time_reported_failure
37
- } from "./chunk-GLBDBJOK.js";
42
+ } from "./chunk-NKOG3XAV.js";
38
43
  import "./chunk-WPALEIRX.js";
39
44
  import "./chunk-RKUAD3I6.js";
40
45
 
@@ -62,6 +67,23 @@ async function josh_run(args, should_forward_stderr = false, timeout_ms) {
62
67
  }
63
68
  var josh_command = { josh_run };
64
69
 
70
+ // scripts/lane/lane-seed.ts
71
+ var FIRST_LANE_SEAT = 1;
72
+ var LAST_LANE_SEAT = 9;
73
+ function free_seats(used) {
74
+ const taken = new Set(used);
75
+ const free = [];
76
+ for (let seat = FIRST_LANE_SEAT; seat <= LAST_LANE_SEAT; seat += 1) {
77
+ if (!taken.has(seat)) free.push(seat);
78
+ }
79
+ return free;
80
+ }
81
+ var lane_seed_policy = {
82
+ FIRST_LANE_SEAT,
83
+ LAST_LANE_SEAT,
84
+ free_seats
85
+ };
86
+
65
87
  // scripts/lane/lane-capacity.ts
66
88
  var DEFAULT_LANE_LIMIT = 6;
67
89
  var LANE_LIMIT_KEY = "JOSH_LANE_LIMIT";
@@ -78,219 +100,47 @@ function read_limit(raw) {
78
100
  }
79
101
  return { kind: "limit", limit: Number(trimmed) };
80
102
  }
81
- function lane_limit(environment2 = process.env) {
82
- return read_limit(environment2[LANE_LIMIT_KEY]);
103
+ function lane_limit(environment = process.env) {
104
+ return read_limit(environment[LANE_LIMIT_KEY]);
83
105
  }
84
106
  function free_lanes(limit, occupied) {
85
- return Math.max(NO_LANES, limit - occupied);
107
+ return Math.max(NO_LANES, Math.min(limit, lane_seed_policy.LAST_LANE_SEAT) - occupied);
86
108
  }
87
109
  var lane_capacity = {
88
- DEFAULT_LANE_LIMIT,
89
110
  LANE_LIMIT_KEY,
90
- read_limit,
91
111
  lane_limit,
92
112
  free_lanes
93
113
  };
94
114
 
95
- // scripts/lane/lane-reap.ts
96
- import { execFileSync } from "node:child_process";
97
- var PGREP_COMMAND = "pgrep";
98
- var MATCH_FULL_COMMAND_LINE = "-f";
99
- var CHILDREN_OF_FLAG = "-P";
100
- var PS_COMMAND = "/bin/ps";
101
- var PARENT_FORMAT = ["-o", "ppid=", "-p"];
102
- var TERMINATE_SIGNAL = "SIGTERM";
103
- var PROBE_TIMEOUT_MS = 2e3;
104
- var LOWEST_CHILD_PID = 2;
105
- function parse_pids(printed) {
106
- return printed.split("\n").map((line) => Number(line.trim())).filter((pid) => Number.isSafeInteger(pid) && pid >= LOWEST_CHILD_PID);
107
- }
108
- function run_probe(command, args) {
109
- try {
110
- return execFileSync(command, [...args], {
111
- encoding: "utf8",
112
- timeout: PROBE_TIMEOUT_MS,
113
- stdio: ["ignore", "pipe", "ignore"]
114
- });
115
- } catch {
116
- return "";
117
- }
118
- }
119
- function parent_of(pid) {
120
- return parse_pids(run_probe(PS_COMMAND, [...PARENT_FORMAT, String(pid)]))[0];
121
- }
122
- function terminate(pid) {
123
- try {
124
- process.kill(pid, TERMINATE_SIGNAL);
125
- return true;
126
- } catch {
127
- return false;
128
- }
129
- }
130
- var SYSTEM_PROBES = {
131
- matching: (pattern) => parse_pids(run_probe(PGREP_COMMAND, [MATCH_FULL_COMMAND_LINE, pattern])),
132
- children_of: (pid) => parse_pids(run_probe(PGREP_COMMAND, [CHILDREN_OF_FLAG, String(pid)])),
133
- parent_of,
134
- terminate
135
- };
136
- function ancestry_of(pid, probes) {
137
- const ancestry = /* @__PURE__ */ new Set([pid]);
138
- let current = probes.parent_of(pid);
139
- while (current !== void 0 && !ancestry.has(current)) {
140
- ancestry.add(current);
141
- current = probes.parent_of(current);
142
- }
143
- return ancestry;
144
- }
145
- function own_ancestry(probes = SYSTEM_PROBES) {
146
- return ancestry_of(process.pid, probes);
147
- }
148
- function tree_of(roots, probes) {
149
- const tree = [];
150
- const pending = [...roots];
151
- let next = pending.shift();
152
- while (next !== void 0) {
153
- if (!tree.includes(next)) {
154
- tree.push(next);
155
- pending.push(...probes.children_of(next));
156
- }
157
- next = pending.shift();
158
- }
159
- return tree;
160
- }
161
- function reap_child(issue, probes = SYSTEM_PROBES) {
162
- const own = own_ancestry(probes);
163
- const pattern = lane_child_invocation.process_pattern(issue);
164
- const roots = probes.matching(pattern).filter((pid) => !own.has(pid));
165
- const doomed = tree_of(roots, probes).filter((pid) => !own.has(pid));
166
- return doomed.filter((pid) => probes.terminate(pid));
167
- }
168
- var lane_reap = {
169
- own_ancestry,
170
- parse_pids,
171
- reap_child
172
- };
173
-
174
- // scripts/run/run-headless.ts
175
- var HEADLESS_ENV_KEY = "JOSH_RUN_HEADLESS";
176
- var HEADLESS_VALUE = "1";
177
- function environment() {
178
- return { [HEADLESS_ENV_KEY]: HEADLESS_VALUE };
179
- }
180
- function is_headless(source = process.env) {
181
- return source[HEADLESS_ENV_KEY] === HEADLESS_VALUE;
182
- }
183
- function is_driving(read) {
184
- return read?.kind === "carried" && read.carry.is_handed_off !== true;
185
- }
186
- async function read_carry_here() {
187
- const repository = await run_carry.repository_directory();
188
- return repository === void 0 ? void 0 : run_carry.read_carry(run_carry.carry_path(repository));
189
- }
190
- async function must_keep_waiting(source = process.env) {
191
- const is_candidate = is_headless(source) && lane_child_marker.marked_issue(source) === void 0;
192
- if (!is_candidate || !await run_watcher_guard.has_lanes_in_flight()) return false;
193
- return is_driving(await read_carry_here());
194
- }
195
- async function current_carry() {
196
- const read = await read_carry_here();
197
- return read?.kind === "carried" ? read.carry : void 0;
198
- }
199
- function is_owned_here(carry, ancestry) {
200
- return carry.owner_pid !== void 0 && ancestry().has(carry.owner_pid);
201
- }
202
- function is_driven_here(read, ancestry) {
203
- if (read?.kind !== "carried" || !is_driving(read)) return false;
204
- return is_owned_here(read.carry, ancestry);
205
- }
206
- async function is_backlog_parent(source = process.env, ancestry = lane_reap.own_ancestry) {
207
- if (lane_child_marker.marked_issue(source) !== void 0) return false;
208
- return is_driven_here(await read_carry_here(), ancestry);
209
- }
210
- var run_headless = {
211
- HEADLESS_ENV_KEY,
212
- current_carry,
213
- environment,
214
- is_backlog_parent,
215
- is_headless,
216
- is_owned_here,
217
- must_keep_waiting
218
- };
219
-
220
- // scripts/issue/issue-cite.ts
221
- var GITHUB_URL_PREFIX = "https://github.com/";
222
- var ISSUE_PATH = "/issues/";
223
- var SUMMARY_SEPARATOR = " \u2014 ";
224
- var REPO_QUALIFIED = /^([^\s/#]+\/[^\s/#]+)#(\d+)$/u;
225
- var BARE_NUMBER = /^#?(\d+)$/u;
226
- function issue_url(slug, number) {
227
- return `${GITHUB_URL_PREFIX}${slug}${ISSUE_PATH}${number}`;
228
- }
229
- function citation_line(slug, number, summary) {
230
- return `[#${number}](${issue_url(slug, number)})${SUMMARY_SEPARATOR}${summary}`;
231
- }
232
- function qualified_target(token) {
233
- const match = REPO_QUALIFIED.exec(token);
234
- if (match === null) return void 0;
235
- const [, repo = "", number = ""] = match;
236
- return { number, repo };
237
- }
238
- function bare_target(token, default_repo) {
239
- const match = BARE_NUMBER.exec(token);
240
- if (match === null) return void 0;
241
- const [, number = ""] = match;
242
- return { number, repo: default_repo };
243
- }
244
- function parse_target(token, default_repo) {
245
- return qualified_target(token) ?? bare_target(token, default_repo);
246
- }
247
- function label(target) {
248
- return target.repo === void 0 ? `#${target.number}` : `${target.repo}#${target.number}`;
249
- }
250
- function missing_line(target) {
251
- return `\u2716 ${label(target)}: issue does not resolve \u2014 check the number and the repository`;
252
- }
253
- function unreadable_line(target) {
254
- return `\u2716 ${label(target)}: could not be read \u2014 a rate limit, expired auth, or a dropped connection`;
255
- }
256
- function no_repo_line(target) {
257
- return `\u2716 ${label(target)}: could not read this repository \u2014 check gh auth and the origin remote`;
258
- }
259
- var issue_cite = {
260
- SUMMARY_SEPARATOR,
261
- citation_line,
262
- issue_url,
263
- label,
264
- missing_line,
265
- no_repo_line,
266
- parse_target,
267
- unreadable_line
268
- };
269
-
270
115
  // scripts/rules/issue-citation.ts
271
116
  var ISSUE_NUMBER = /#\d+/gu;
272
117
  var REFERENCE_BOUNDARY = /[\s#()[\]<>|]/u;
273
118
  var OWNER_REPO = /^[^\s/#]+\/[^\s/#]+$/u;
274
- var MARKDOWN_LINK = /\[([^[\]]*)\]\([^()]*\)/gu;
119
+ var MARKDOWN_LINK = /\[[^[\]]*\]\([^()]*\)/gu;
120
+ var NUMBER_CONTINUATION = /^(?:\w|-[a-z])/iu;
121
+ var CONTINUATION_WIDTH = 2;
122
+ var GLUED_LEAD = /[&./]/u;
275
123
  var FENCE_MARKER = /^\s*(?:`{3,}|~{3,})/u;
276
124
  var QUOTE_LINE = /^\s*>/u;
277
125
  var PR_PREFIX = /\b(?:pr|pull request)\s*$/iu;
278
126
  var BACKTICK_PAIR = 2;
279
- function text_span_covers(link, index) {
280
- const start = (link.index ?? 0) + 1;
281
- const end = start + (link[1] ?? "").length;
282
- return index >= start && index < end;
127
+ function link_covers(link, index) {
128
+ const start = link.index ?? 0;
129
+ return index >= start && index < start + link[0].length;
283
130
  }
284
131
  function is_linked_at(line, index) {
285
132
  for (const link of line.matchAll(MARKDOWN_LINK)) {
286
- if (text_span_covers(link, index)) return true;
133
+ if (link_covers(link, index)) return true;
287
134
  }
288
135
  return false;
289
136
  }
290
- function repo_prefix(message2, hash_index) {
137
+ function lead_token(message2, hash_index) {
291
138
  let start = hash_index;
292
139
  while (start > 0 && !REFERENCE_BOUNDARY.test(message2.charAt(start - 1))) start -= 1;
293
- const token = message2.slice(start, hash_index);
140
+ return message2.slice(start, hash_index);
141
+ }
142
+ function repo_prefix(message2, hash_index) {
143
+ const token = lead_token(message2, hash_index);
294
144
  return OWNER_REPO.test(token) ? token : "";
295
145
  }
296
146
  function is_inline_code_at(line, index) {
@@ -301,13 +151,16 @@ function is_bare_at(line, index) {
301
151
  if (is_linked_at(line, index) || is_inline_code_at(line, index)) return false;
302
152
  return !PR_PREFIX.test(line.slice(0, index));
303
153
  }
154
+ function is_glued(line, reference) {
155
+ const end = reference.index + reference.text.length;
156
+ if (NUMBER_CONTINUATION.test(line.slice(end, end + CONTINUATION_WIDTH))) return true;
157
+ return reference.prefix === "" && GLUED_LEAD.test(lead_token(line, reference.index));
158
+ }
304
159
  function line_references(line) {
305
160
  const references = [];
306
161
  for (const match of line.matchAll(ISSUE_NUMBER)) {
307
- const { index } = match;
308
- if (is_bare_at(line, index)) {
309
- references.push({ index, prefix: repo_prefix(line, index), text: match[0] });
310
- }
162
+ const reference = { index: match.index, prefix: repo_prefix(line, match.index), text: match[0] };
163
+ if (!is_glued(line, reference) && is_bare_at(line, match.index)) references.push(reference);
311
164
  }
312
165
  return references;
313
166
  }
@@ -406,144 +259,6 @@ function message(children, repo) {
406
259
  }
407
260
  var epic_triage = { TRIAGE_VERDICT, is_triaged, message, untriaged };
408
261
 
409
- // scripts/run/run-event-stream.ts
410
- import { z } from "zod";
411
- var EVENT_PREFIX = "josh-run-events-";
412
- var EVENT_SUFFIX = ".jsonl";
413
- var EVENT_CAP = 500;
414
- var FIRST_POSITION = 0;
415
- var POSITION_INCREMENT = 1;
416
- var LINE_SEPARATOR = "\n";
417
- var EVENT_KIND = {
418
- PLAN: "plan",
419
- CHILD_LAUNCH: "child-launch",
420
- MERGE: "merge",
421
- PARK: "park",
422
- SPLIT: "split",
423
- OUTAGE: "outage",
424
- CUT: "cut",
425
- // The backlog emptied while nothing of the run's own was in flight — the drain
426
- // (joshuafolkken/kit#2335). It marks the position at which the end-of-run retrospective is owed,
427
- // *before* the idle watch opens, so `run:step` fires the retrospective at the drain rather than after
428
- // the watch runs its course. It is not itself a stop: the run watches on once the retrospective has
429
- // run, and the real `STOP` follows when the watch expires.
430
- DRAIN: "drain",
431
- STOP: "stop",
432
- PR_OPENED: "pr-opened",
433
- REVIEW_ROUND: "review-round",
434
- // The end-of-run retrospective's result, recorded when the run marks the retrospective done
435
- // (joshuafolkken/kit#2342). A retrospective that files zero improvements and one that never ran look
436
- // the same from outside — no new Issue either way — so the result is put on the stream the report is
437
- // generated from: the issues filed (or that none were), and the candidates dropped with why. It is
438
- // emitted from the `run:carry --retrospective` close, so marking the retrospective done and recording
439
- // what it found are one action rather than two the run could do only one of.
440
- RETROSPECTIVE: "retrospective",
441
- // Ready backlog work is sitting undispatched while a lane is free and nothing has dispatched for a
442
- // while (joshuafolkken/kit#2359). Emitted once per stall episode by the stop-time detector, it is
443
- // both the dedup marker — `emit_once_since` refuses a second until a `CHILD_LAUNCH` intervenes
444
- // (joshuafolkken/kit#2464) — and the line a
445
- // terminal reader following the stream sees. `run:step` reads it as `backlog:next`, so a run that
446
- // stalled is pointed straight at dispatching the work rather than left waiting.
447
- STALL: "stall",
448
- // The run's own driver is gone: the cut handed the budget off, the owner has died, and no supervisor
449
- // is watching (joshuafolkken/kit#2375). Emitted once per strand episode by the stop-time detector,
450
- // exactly as `STALL` is — the newest-event dedup keeps a run polled every stop from notifying more
451
- // than once, and a terminal reader following the stream sees the line. The strand is the step before
452
- // the stall: a stalled run still has a driver that could dispatch, a stranded one has none.
453
- STRANDED: "stranded",
454
- // One `josh ship` stage starting, succeeding or failing (joshuafolkken/kit#2426). It is a trace of the
455
- // composite's progress rather than a position the run is at — the positions a ship leaves behind are
456
- // the closed issue its `followup` merges, or a detached supervisor's `SHIP_LAUNCH` / `SHIP_STOP` below
457
- // — so it is one of the `TRACE_KINDS` the last-event read skips.
458
- SHIP_STAGE: "ship-stage",
459
- // One progress watcher line — the `at … / next …` heartbeat `run:progress` prints
460
- // (joshuafolkken/kit#2437). Printed only to the watcher's own output, a headless successor's heartbeat
461
- // was buried in its log after a cut; on the stream it reaches the attached session's relay. It says
462
- // the run is alive rather than where it is, so it is a trace kind like `SHIP_STAGE`.
463
- HEARTBEAT: "heartbeat",
464
- // The post-implementation region handed to a detached `josh ship --detach` supervisor
465
- // (joshuafolkken/kit#2428). Unlike a stage trace it is a position: the agent has ended and the
466
- // supervisor carries the run, so `run:step` answers `wait` until it stops or the issue closes.
467
- SHIP_LAUNCH: "ship-launch",
468
- // The supervisor stopped at a failed stage — a red gate, a High/Medium review, a failed push, red CI
469
- // (joshuafolkken/kit#2428). The position that hands control back: `run:step` prints the command that
470
- // shows the stopped report, so the agent fixes it and relaunches rather than rebuilding the context.
471
- SHIP_STOP: "ship-stop"
472
- };
473
- var EVENT_KINDS = Object.values(EVENT_KIND);
474
- var TRACE_KINDS = /* @__PURE__ */ new Set([EVENT_KIND.SHIP_STAGE, EVENT_KIND.HEARTBEAT]);
475
- var event_schema = z.object({
476
- pos: z.number(),
477
- at: z.string(),
478
- kind: z.string(),
479
- text: z.string()
480
- });
481
- function is_event_kind(value) {
482
- return EVENT_KINDS.includes(value);
483
- }
484
- function target_of(repository) {
485
- return stamp_file.stamp_path(EVENT_PREFIX, repository, EVENT_SUFFIX);
486
- }
487
- function is_present(event) {
488
- return event !== void 0;
489
- }
490
- function parse_line(line) {
491
- return event_schema.safeParse(json_value.parse_or_undefined(line)).data;
492
- }
493
- function read_events(target) {
494
- const raw = stamp_file.read_stamp_text(target);
495
- if (raw === void 0) return [];
496
- return raw.split(LINE_SEPARATOR).map((line) => line.trim()).filter((line) => line.length > 0).map((line) => parse_line(line)).filter(is_present);
497
- }
498
- function last_position(events) {
499
- return events[events.length - POSITION_INCREMENT]?.pos ?? FIRST_POSITION;
500
- }
501
- function serialize(events) {
502
- return `${events.map((event) => JSON.stringify(event)).join(LINE_SEPARATOR)}${LINE_SEPARATOR}`;
503
- }
504
- function append(target, kind, text2, at) {
505
- if (!is_event_kind(kind)) return { appended: false, position: FIRST_POSITION };
506
- const existing = read_events(target);
507
- const position = last_position(existing) + POSITION_INCREMENT;
508
- const bounded = [...existing, { pos: position, at, kind, text: text2 }].slice(-EVENT_CAP);
509
- stamp_file.write_text_stamp(target, serialize(bounded));
510
- return { appended: true, position };
511
- }
512
- function read_from(target, position) {
513
- const events = read_events(target);
514
- return {
515
- events: events.filter((event) => event.pos > position),
516
- next_position: last_position(events)
517
- };
518
- }
519
- function read_last(target) {
520
- return read_events(target).findLast((event) => !TRACE_KINDS.has(event.kind));
521
- }
522
- function has_since(events, kind, reset_kind) {
523
- const reset_at = events.findLastIndex((event) => event.kind === reset_kind);
524
- return events.slice(reset_at + POSITION_INCREMENT).some((event) => event.kind === kind);
525
- }
526
- var FIELD_SEPARATOR = " \xB7 ";
527
- function format_event(event) {
528
- return [event.at, event.kind, event.text].join(FIELD_SEPARATOR);
529
- }
530
- var run_event_stream = {
531
- EVENT_CAP,
532
- EVENT_KIND,
533
- EVENT_KINDS,
534
- EVENT_PREFIX,
535
- EVENT_SUFFIX,
536
- TRACE_KINDS,
537
- append,
538
- format_event,
539
- has_since,
540
- is_event_kind,
541
- read_events,
542
- read_from,
543
- read_last,
544
- target_of
545
- };
546
-
547
262
  // scripts/backlog/backlog-stalled.ts
548
263
  var STALL_THRESHOLD_MINUTES = 10;
549
264
  var MS_PER_MINUTE = 6e4;
@@ -595,7 +310,6 @@ var backlog_stalled = {
595
310
  count_ready_tokens,
596
311
  describe,
597
312
  dispatch_age_ms,
598
- is_stalled,
599
313
  needs_triage,
600
314
  ready_tokens
601
315
  };
@@ -603,12 +317,20 @@ var backlog_stalled = {
603
317
  // scripts/backlog/backlog-ready.ts
604
318
  var NO_FREE = 0;
605
319
  var NONE2 = 0;
320
+ async function free_under(limit) {
321
+ const lanes = await lane_registry.list_lanes();
322
+ const live = lanes.filter((lane) => !lane.is_stranded).length;
323
+ return lane_capacity.free_lanes(limit, live);
324
+ }
606
325
  async function free_lane_count() {
607
326
  const limit = lane_capacity.lane_limit();
608
327
  if (limit.kind !== "limit") return NO_FREE;
609
- const lanes = await lane_registry.list_lanes();
610
- const live = lanes.filter((lane) => !lane.is_stranded).length;
611
- return lane_capacity.free_lanes(limit.limit, live);
328
+ return await free_under(limit.limit);
329
+ }
330
+ async function drive_free_lane_count() {
331
+ const limit = lane_capacity.lane_limit();
332
+ if (limit.kind !== "limit") throw new Error(limit.problem);
333
+ return await free_under(limit.limit);
612
334
  }
613
335
  function drains_pool(carry) {
614
336
  return carry === void 0 || !run_invocation.has_only(carry.invocation);
@@ -656,6 +378,7 @@ var backlog_ready = {
656
378
  read_backlog_next,
657
379
  print_offer_hint,
658
380
  free_lane_count,
381
+ drive_free_lane_count,
659
382
  drains_pool,
660
383
  print_ready_line,
661
384
  read_ready,
@@ -683,12 +406,17 @@ function get_repo_name_with_owner_within(timeout_ms) {
683
406
  }
684
407
  var gh_spawn = { get_repo_name_with_owner, get_repo_name_with_owner_within };
685
408
 
686
- // scripts/git/telegram-notify.ts
687
- import { z as z2 } from "zod";
409
+ // scripts/lib/timed-fetch.ts
410
+ async function timed_fetch(url, init = {}, timeout_ms = FETCH_TIMEOUT_MS) {
411
+ return await fetch(url, { ...init, signal: AbortSignal.timeout(timeout_ms) });
412
+ }
413
+
414
+ // scripts/notify/telegram-notify.ts
415
+ import { z } from "zod";
688
416
  var TELEGRAM_API_BASE = "https://api.telegram.org";
689
- var telegram_environment_schema = z2.object({
690
- telegram_bot_token: z2.string().min(1, { message: "TELEGRAM_BOT_TOKEN is required" }),
691
- telegram_chat_id: z2.string().min(1, { message: "TELEGRAM_CHAT_ID is required" })
417
+ var telegram_environment_schema = z.object({
418
+ telegram_bot_token: z.string().min(1, { message: "TELEGRAM_BOT_TOKEN is required" }),
419
+ telegram_chat_id: z.string().min(1, { message: "TELEGRAM_CHAT_ID is required" })
692
420
  });
693
421
  var TASK_DEFINITIONS = {
694
422
  planning: { icon: "\u{1F4CB}", label: "Planning" },
@@ -742,9 +470,9 @@ function is_notify_disabled() {
742
470
  return parse_environment_string(process.env[NOTIFY_SWITCH_KEY]).toLowerCase() === NOTIFY_OFF_VALUE;
743
471
  }
744
472
  function build_header(task_type, repo_name) {
745
- const { icon, label: label2 } = TASK_DEFINITIONS[task_type];
746
- if (repo_name === void 0 || repo_name.length === 0) return `${icon} ${label2}`;
747
- return `${icon} ${repo_name}: ${label2}`;
473
+ const { icon, label } = TASK_DEFINITIONS[task_type];
474
+ if (repo_name === void 0 || repo_name.length === 0) return `${icon} ${label}`;
475
+ return `${icon} ${repo_name}: ${label}`;
748
476
  }
749
477
  function push_if_present(target, value) {
750
478
  if (value !== void 0 && value.length > 0) target.push(value);
@@ -754,8 +482,8 @@ function build_title_block(input) {
754
482
  push_if_present(lines, input.issue_title);
755
483
  return lines.join("\n");
756
484
  }
757
- function append_url(parts, label2, value) {
758
- if (value !== void 0 && value.length > 0) parts.push(`${label2}: ${value}`);
485
+ function append_url(parts, label, value) {
486
+ if (value !== void 0 && value.length > 0) parts.push(`${label}: ${value}`);
759
487
  }
760
488
  function build_url_parts(input) {
761
489
  const parts = [];
@@ -774,7 +502,7 @@ function build_text(input) {
774
502
  }
775
503
  async function post_message(config, text2) {
776
504
  const url = `${TELEGRAM_API_BASE}/bot${config.bot_token}/sendMessage`;
777
- const response = await fetch(url, {
505
+ const response = await timed_fetch(url, {
778
506
  method: "POST",
779
507
  headers: { "Content-Type": "application/json" },
780
508
  body: JSON.stringify({ chat_id: config.chat_id, text: text2 })
@@ -873,7 +601,6 @@ async function stranded(input) {
873
601
  );
874
602
  }
875
603
  var telegram_notify = {
876
- REPO_LOOKUP_TIMEOUT_MS,
877
604
  confirm,
878
605
  send,
879
606
  send_or_report,
@@ -882,125 +609,6 @@ var telegram_notify = {
882
609
  warn
883
610
  };
884
611
 
885
- // scripts/run/run-event-scope.ts
886
- var SINCE_SCOPE = "since";
887
- var UNKNOWN_SCOPE = "unknown";
888
- var UNKNOWN_EVENT_SCOPE = { kind: UNKNOWN_SCOPE };
889
- function moment_of(at) {
890
- const parsed = Date.parse(at);
891
- return Number.isNaN(parsed) ? void 0 : parsed;
892
- }
893
- function is_within(event, floor) {
894
- const at = moment_of(event.at);
895
- return at !== void 0 && at >= floor;
896
- }
897
- function scoped_events(events, scope) {
898
- if (scope.kind === UNKNOWN_SCOPE) return void 0;
899
- const floor = moment_of(scope.started_at);
900
- if (floor === void 0) return void 0;
901
- return events.filter((event) => is_within(event, floor));
902
- }
903
- function scope_of(read) {
904
- if (read.kind === "carried" || read.kind === "expired") {
905
- return { kind: SINCE_SCOPE, started_at: read.carry.started_at };
906
- }
907
- return UNKNOWN_EVENT_SCOPE;
908
- }
909
- function last_scoped_event(events, scope) {
910
- return scoped_events(events, scope)?.findLast(
911
- (event) => !run_event_stream.TRACE_KINDS.has(event.kind)
912
- );
913
- }
914
- var SHIP_POSITION_KINDS = /* @__PURE__ */ new Set([
915
- run_event_stream.EVENT_KIND.SHIP_LAUNCH,
916
- run_event_stream.EVENT_KIND.SHIP_STOP
917
- ]);
918
- function is_foreign_ship_event(event, issue) {
919
- return SHIP_POSITION_KINDS.has(event.kind) && !event.text.startsWith(`#${issue} `);
920
- }
921
- function is_own_ship_event(event, issue) {
922
- return SHIP_POSITION_KINDS.has(event.kind) && !is_foreign_ship_event(event, issue);
923
- }
924
- function last_issue_event(events, scope, issue) {
925
- const own = events.filter((event) => !is_foreign_ship_event(event, issue));
926
- if (scope.kind === SINCE_SCOPE) return last_scoped_event(own, scope);
927
- return own.findLast((event) => is_own_ship_event(event, issue));
928
- }
929
- var run_event_scope = {
930
- UNKNOWN_EVENT_SCOPE,
931
- last_issue_event,
932
- last_scoped_event,
933
- scope_of,
934
- scoped_events
935
- };
936
-
937
- // scripts/run/run-event-stream-emit.ts
938
- function now_iso() {
939
- return (/* @__PURE__ */ new Date()).toISOString();
940
- }
941
- async function stream_target() {
942
- const repository = await run_carry.repository_directory();
943
- return repository === void 0 ? void 0 : run_event_stream.target_of(repository);
944
- }
945
- async function emit(kind, text2) {
946
- try {
947
- const target = await stream_target();
948
- if (target === void 0) return;
949
- run_event_stream.append(target, kind, text2, now_iso());
950
- } catch {
951
- }
952
- }
953
- async function emit_once(kind, text2) {
954
- try {
955
- const target = await stream_target();
956
- if (target === void 0 || run_event_stream.read_last(target)?.kind === kind) return false;
957
- return run_event_stream.append(target, kind, text2, now_iso()).appended;
958
- } catch {
959
- return false;
960
- }
961
- }
962
- function invocation_events(repository, target) {
963
- const events = run_event_stream.read_events(target);
964
- const scope = run_event_scope.scope_of(run_carry.read_carry(run_carry.carry_path(repository)));
965
- return run_event_scope.scoped_events(events, scope) ?? events;
966
- }
967
- async function emit_once_since(kind, text2, reset_kind) {
968
- try {
969
- const repository = await run_carry.repository_directory();
970
- if (repository === void 0) return false;
971
- const target = run_event_stream.target_of(repository);
972
- if (run_event_stream.has_since(invocation_events(repository, target), kind, reset_kind)) {
973
- return false;
974
- }
975
- return run_event_stream.append(target, kind, text2, now_iso()).appended;
976
- } catch {
977
- return false;
978
- }
979
- }
980
- async function emit_heartbeat(line) {
981
- await emit(run_event_stream.EVENT_KIND.HEARTBEAT, line);
982
- }
983
- async function current_events() {
984
- try {
985
- const repository = await run_carry.repository_directory();
986
- if (repository === void 0) return [];
987
- const read = run_carry.read_carry(run_carry.carry_path(repository));
988
- const scope = run_event_scope.scope_of(read);
989
- const events = run_event_stream.read_events(run_event_stream.target_of(repository));
990
- return run_event_scope.scoped_events(events, scope) ?? [];
991
- } catch {
992
- return [];
993
- }
994
- }
995
- var run_event_stream_emit = {
996
- current_events,
997
- emit,
998
- emit_heartbeat,
999
- emit_once,
1000
- emit_once_since,
1001
- stream_target
1002
- };
1003
-
1004
612
  // scripts/backlog/backlog-stalled-detect.ts
1005
613
  var NO_FREE2 = 0;
1006
614
  var NO_READY = 0;
@@ -1063,23 +671,24 @@ async function run_stall_check(ready = backlog_ready.DEFAULT_PORTS) {
1063
671
  } catch {
1064
672
  }
1065
673
  }
1066
- var backlog_stalled_detect = { DEFAULT_PORTS: DEFAULT_PORTS2, detect_and_report, gather, report, run_stall_check };
674
+ var backlog_stalled_detect = { detect_and_report, run_stall_check };
1067
675
 
1068
676
  // scripts/rules/last-prompt.ts
1069
- import { z as z3 } from "zod";
677
+ import { z as z2 } from "zod";
1070
678
  var WORKFLOW_KEYWORDS = /* @__PURE__ */ new Set([
1071
679
  "kickoff",
1072
680
  "fullrun",
1073
681
  "halfrun",
682
+ "prrun",
1074
683
  "backlogrun"
1075
684
  ]);
1076
685
  var NO_PROMPT = "";
1077
686
  var HUMAN_ORIGIN = "human";
1078
687
  var KEYWORD_BEFORE_ARGUMENT = -2;
1079
- var PROMPT_LINE_SCHEMA = z3.object({
1080
- isMeta: z3.boolean().nullish(),
1081
- origin: z3.object({ kind: z3.string().nullish() }).nullish(),
1082
- message: z3.object({ content: z3.unknown() })
688
+ var PROMPT_LINE_SCHEMA = z2.object({
689
+ isMeta: z2.boolean().nullish(),
690
+ origin: z2.object({ kind: z2.string().nullish() }).nullish(),
691
+ message: z2.object({ content: z2.unknown() })
1083
692
  });
1084
693
  function is_person(line) {
1085
694
  if (line.isMeta === true) return false;
@@ -1106,7 +715,7 @@ function prompt_text(tail) {
1106
715
  var last_prompt = { prompt_text };
1107
716
 
1108
717
  // scripts/rules/stop-rules.ts
1109
- import { z as z4 } from "zod";
718
+ import { z as z3 } from "zod";
1110
719
 
1111
720
  // scripts/rules/filing-offer.ts
1112
721
  var OFFER_PATTERNS = [
@@ -1209,19 +818,19 @@ function is_mismatch(message2, lang) {
1209
818
  if (letter_count(prose) < MIN_PROSE_LETTERS) return false;
1210
819
  return matches_share(prose, script, pattern) < MATCH_SHARE_FLOOR;
1211
820
  }
1212
- var reply_language = { MIN_PROSE_LETTERS, is_mismatch, script_of };
821
+ var reply_language = { is_mismatch, script_of };
1213
822
 
1214
823
  // scripts/rules/stop-rules.ts
1215
824
  var SWITCH_ENV_KEY = "JOSH_STOP_GUARD";
1216
825
  var BLOCK_DECISION = "block";
1217
- var stop_payload_schema = z4.object({
1218
- transcript_path: z4.string().min(1),
1219
- stop_hook_active: z4.boolean().nullish(),
1220
- last_assistant_message: z4.string().nullish()
826
+ var stop_payload_schema = z3.object({
827
+ transcript_path: z3.string().min(1),
828
+ stop_hook_active: z3.boolean().nullish(),
829
+ last_assistant_message: z3.string().nullish()
1221
830
  });
1222
831
  var NO_OUTCOME = { reason: void 0 };
1223
832
  var STOP_NOTIFY_REASON = '\u26D4 mid-workflow stop notification: this working tree is still held by a run and no `confirmation` Telegram was sent this turn, so a person is being left to wait off-screen without knowing the run paused. `CLAUDE.md` \u2192 "Mid-workflow stop notification" requires `pnpm josh notify --task-type confirmation --issue-url "<url>" --body=$\'<reason>\'` before any mid-workflow pause. Send it, then end with a one-line confirmation that it was sent \u2014 do not repeat your previous reply. This fires only while the hold is held and no notify is on the transcript, and `stop_hook_active` lets a second stop through so a run is never wedged.';
1224
- var HOLD_RELEASE_REASON = "\u26D4 working-tree hold not released: this working tree is clean but its `run:hold` record is still in place, so the next run here runs `git switch main && git pull` believing the tree is free while you hold it. `.claude/skills/workflow-commands/SKILL.md` \u2192 \xA72f: a stop that leaves the tree clean releases the hold with `pnpm josh run:release <N>` (bare for a `new` entry). A `halfrun` pre-commit stop and a `needs-human-review` stop keep the hold because their tree is dirty \u2014 this row is silent there. Release it, then end with a one-line confirmation that it was released \u2014 do not repeat your previous reply.";
833
+ var HOLD_RELEASE_REASON = "\u26D4 working-tree hold not released: this working tree is clean but its `run:hold` record is still in place, so the next run here runs `git switch main && git pull` believing the tree is free while you hold it. `.claude/skills/workflow-commands/SKILL.md` \u2192 \xA72f: a stop that leaves the tree clean releases the hold with `pnpm josh run:release <N>` (bare for a `new` entry). A `halfrun` pre-commit stop and a `needs-human-review` stop keep the hold because their tree is dirty, and a `prrun` stop keeps it by its stop mark \u2014 this row is silent there. Release it, then end with a one-line confirmation that it was released \u2014 do not repeat your previous reply.";
1225
834
  var ISSUE_CITATION_REASON = "Session-facing output cites an Issue as a number-link so the reader can click through and see which repository it is (`CLAUDE.md`, `prompts/collaboration-workflow/issue-citation.md`).";
1226
835
  function build_citation_reason(references) {
1227
836
  const numbers = references.join(", ");
@@ -1258,13 +867,13 @@ function needs_filing(context) {
1258
867
  return filing_offer.is_first_party_target(context.message, context.session_owner);
1259
868
  }
1260
869
  function is_held_idle(context) {
1261
- return context.hold_present && !context.agent_pending;
870
+ return context.hold_present && !context.agent_pending && !context.handed_off;
1262
871
  }
1263
872
  function needs_notify(context) {
1264
873
  return is_held_idle(context) && !context.notified;
1265
874
  }
1266
875
  function needs_release(context) {
1267
- return is_held_idle(context) && context.tree_clean;
876
+ return is_held_idle(context) && context.tree_clean && !context.prrun_stopped;
1268
877
  }
1269
878
  function citation_reason(context) {
1270
879
  const references = issue_citation.unquoted_references(context.message, context.prompt);
@@ -1322,7 +931,6 @@ var stop_rules = {
1322
931
  STOP_NOTIFY_REASON,
1323
932
  SWITCH_ENV_KEY,
1324
933
  block_envelope,
1325
- block_reason,
1326
934
  build_language_reason,
1327
935
  count_headless_refusals,
1328
936
  is_enabled,
@@ -1330,6 +938,67 @@ var stop_rules = {
1330
938
  stop_outcome
1331
939
  };
1332
940
 
941
+ // scripts/run/run-halfrun-resume.ts
942
+ var MARKED = "marked";
943
+ var FOREIGN = "foreign";
944
+ var UNREADABLE2 = "unreadable";
945
+ function hold_of(read) {
946
+ return read.kind === "held" || read.kind === "stale" ? read.hold : void 0;
947
+ }
948
+ function is_halfrun_stop(read, issue, is_dirty) {
949
+ const hold = hold_of(read);
950
+ return is_dirty && hold?.issue === issue && hold.is_halfrun_stop === true;
951
+ }
952
+ function is_own_record(read, issue) {
953
+ const hold = hold_of(read);
954
+ return hold === void 0 || hold.issue === issue || hold.issue === run_hold.UNNUMBERED_ISSUE;
955
+ }
956
+ function mark_stop_at(target, issue, mark = run_hold.HALFRUN_STOP_FIELDS) {
957
+ const read = run_hold.read_hold(target);
958
+ if (read.kind === "unreadable") return UNREADABLE2;
959
+ if (!is_own_record(read, issue)) return FOREIGN;
960
+ run_hold.release_hold(target);
961
+ return run_hold.create_stop_hold(target, issue, mark) ? MARKED : FOREIGN;
962
+ }
963
+ function take_over(target, issue) {
964
+ run_hold.release_hold(target);
965
+ return run_hold.create_hold(target, issue, /* @__PURE__ */ new Date(), true);
966
+ }
967
+ function adopt_at(target, issue, is_dirty) {
968
+ if (!is_halfrun_stop(run_hold.read_hold(target), issue, is_dirty)) return false;
969
+ return take_over(target, issue);
970
+ }
971
+ async function hold_target() {
972
+ try {
973
+ const directory = await run_hold.worktree_directory();
974
+ return directory === void 0 ? void 0 : run_hold.hold_path(directory);
975
+ } catch {
976
+ return void 0;
977
+ }
978
+ }
979
+ async function is_pending(issue) {
980
+ const target = await hold_target();
981
+ if (target === void 0) return false;
982
+ return is_halfrun_stop(run_hold.read_hold(target), issue, await run_hold.is_tree_dirty());
983
+ }
984
+ async function adopt(issue) {
985
+ const target = await hold_target();
986
+ if (target === void 0) return false;
987
+ return adopt_at(target, issue, await run_hold.is_tree_dirty());
988
+ }
989
+ var run_halfrun_resume = {
990
+ FOREIGN,
991
+ MARKED,
992
+ UNREADABLE: UNREADABLE2,
993
+ adopt,
994
+ adopt_at,
995
+ hold_of,
996
+ hold_target,
997
+ is_pending,
998
+ mark_stop_at,
999
+ take_over
1000
+ };
1001
+
1333
1002
  // scripts/run/run-stranded.ts
1334
1003
  var RECOVERY_COMMAND = "pnpm josh run:wake --start";
1335
1004
  var LIVE = "live";
@@ -1369,7 +1038,7 @@ var run_stranded = {
1369
1038
  };
1370
1039
 
1371
1040
  // scripts/run/run-wake.ts
1372
- import { z as z5 } from "zod";
1041
+ import { z as z4 } from "zod";
1373
1042
  var WAKE_PREFIX = "josh-run-wake-";
1374
1043
  var WAKE_LOG_PREFIX = "josh-run-wake-log-";
1375
1044
  var WAKE_LOG_SUFFIX = ".log";
@@ -1389,21 +1058,19 @@ var STOP_REASONS = {
1389
1058
  expired: "expired",
1390
1059
  unreadable: "unreadable"
1391
1060
  };
1392
- var run_wake_schema = z5.object({
1393
- invocation: z5.string(),
1394
- started_at: z5.string(),
1395
- pid: z5.number(),
1396
- process_start: z5.string().optional(),
1397
- woke: z5.number(),
1398
- woke_at: z5.string().optional(),
1061
+ var run_wake_schema = process_owner_schema.extend({
1062
+ invocation: z4.string(),
1063
+ started_at: z4.string(),
1064
+ woke: z4.number(),
1065
+ woke_at: z4.string().optional(),
1399
1066
  // **Every optional field of `RunWake` has to be listed here.** `z.object` strips what it does not
1400
1067
  // declare, so a field added to the interface alone round-trips through disk as `undefined` — which
1401
1068
  // reads as "no attempt has been made yet" and would restart the retry count on every pass.
1402
- attempts: z5.number().optional(),
1403
- woke_pid: z5.number().optional(),
1404
- held_at: z5.string().optional(),
1405
- spawned: z5.array(z5.string()).optional(),
1406
- idle_since: z5.string().optional(),
1069
+ attempts: z4.number().optional(),
1070
+ woke_pid: z4.number().optional(),
1071
+ held_at: z4.string().optional(),
1072
+ spawned: z4.array(z4.string()).optional(),
1073
+ idle_since: z4.string().optional(),
1407
1074
  profile: agent_role_profile.PROFILE_SCHEMA.optional()
1408
1075
  });
1409
1076
  function is_overdue(marked_at, now, limit_ms = WAKE_GRACE_MS) {
@@ -1555,7 +1222,6 @@ var run_wake = {
1555
1222
  IDLE_CEILING_MS,
1556
1223
  MAX_WAKE_ATTEMPTS,
1557
1224
  WAKE_GRACE_MS,
1558
- WAKE_PREFIX,
1559
1225
  claim,
1560
1226
  count_claim,
1561
1227
  count_wake,
@@ -1626,14 +1292,13 @@ async function run_stranded_check() {
1626
1292
  } catch {
1627
1293
  }
1628
1294
  }
1629
- var run_stranded_detect = { DEFAULT_PORTS: DEFAULT_PORTS3, detect_and_report: detect_and_report2, gather: gather2, report: report2, run_stranded_check };
1295
+ var run_stranded_detect = { detect_and_report: detect_and_report2, run_stranded_check };
1630
1296
 
1631
1297
  // scripts/hooks/stop-guard.ts
1632
- async function is_hold_present() {
1298
+ async function hold_facts() {
1633
1299
  const directory = await run_hold.worktree_directory();
1634
- if (directory === void 0) return false;
1635
- const read = run_hold.read_hold(run_hold.hold_path(directory));
1636
- return read.kind === "held" || read.kind === "stale";
1300
+ const hold = directory === void 0 ? void 0 : run_halfrun_resume.hold_of(run_hold.read_hold(run_hold.hold_path(directory)));
1301
+ return { hold_present: hold !== void 0, prrun_stopped: hold?.prrun_stop_head !== void 0 };
1637
1302
  }
1638
1303
  function transcript_tail(transcript_path) {
1639
1304
  const transcript = time_hook_transcript.transcript_of(transcript_path, void 0);
@@ -1648,7 +1313,7 @@ function session_lang() {
1648
1313
  async function build_context(transcript_path, payload_tail) {
1649
1314
  const tail = transcript_tail(transcript_path);
1650
1315
  return {
1651
- hold_present: await is_hold_present(),
1316
+ ...await hold_facts(),
1652
1317
  tree_clean: !await run_hold.is_tree_dirty(),
1653
1318
  notified: lane_park.mentions_confirmation_notify(tail),
1654
1319
  message: payload_tail.message,
@@ -1662,6 +1327,7 @@ async function build_context(transcript_path, payload_tail) {
1662
1327
  lane_child: lane_child_marker.is_child_of(process.cwd()),
1663
1328
  background_pending: lane_background.pending_background_ids(tail).length > 0,
1664
1329
  agent_pending: lane_background.pending_agent_ids(tail).length > 0,
1330
+ handed_off: lane_handoff.is_handed_off(process.cwd()),
1665
1331
  session_lang: session_lang()
1666
1332
  };
1667
1333
  }
@@ -1681,10 +1347,23 @@ async function outcome_of(raw_payload) {
1681
1347
  return stop_rules.NO_OUTCOME;
1682
1348
  }
1683
1349
  }
1684
- async function write_stop_decision(raw_payload) {
1685
- hook_decision.load_environment_file();
1350
+ async function has_run_record() {
1351
+ try {
1352
+ const directory = await run_carry.repository_directory();
1353
+ if (directory === void 0) return false;
1354
+ return run_carry.read_carry(run_carry.carry_path(directory)).kind === "carried";
1355
+ } catch {
1356
+ return false;
1357
+ }
1358
+ }
1359
+ async function run_report_checks() {
1360
+ if (!await has_run_record()) return;
1686
1361
  await backlog_stalled_detect.run_stall_check(backlog_ready.DEFAULT_PORTS);
1687
1362
  await run_stranded_detect.run_stranded_check();
1363
+ }
1364
+ async function write_stop_decision(raw_payload) {
1365
+ hook_decision.load_environment_file();
1366
+ await run_report_checks();
1688
1367
  const { reason } = await outcome_of(raw_payload);
1689
1368
  if (reason === void 0) return;
1690
1369
  process.stdout.write(`${stop_rules.block_envelope(reason, session_lang())}