@joshuafolkken/kit 1.1229.0 → 1.1370.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 (939) hide show
  1. package/.claude/agents/investigator.md +1 -0
  2. package/.claude/settings.json +4 -0
  3. package/.claude/skills/dependency-update/SKILL.md +5 -3
  4. package/.claude/skills/epic-commands/SKILL.md +82 -113
  5. package/.claude/skills/epic-commands/epic-bundle.md +38 -63
  6. package/.claude/skills/epic-commands/execution-waves.md +30 -51
  7. package/.claude/skills/verify-ui/SKILL.md +13 -20
  8. package/.claude/skills/workflow-commands/SKILL.md +10 -10
  9. package/.claude/skills/workflow-commands/background-commands.md +4 -4
  10. package/.claude/skills/workflow-commands/backlogrun-child.md +30 -105
  11. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +29 -0
  12. package/.claude/skills/workflow-commands/backlogrun-lanes.md +45 -131
  13. package/.claude/skills/workflow-commands/backlogrun-park.md +36 -53
  14. package/.claude/skills/workflow-commands/backlogrun-progress.md +81 -331
  15. package/.claude/skills/workflow-commands/backlogrun-recovery.md +29 -83
  16. package/.claude/skills/workflow-commands/backlogrun-steps.md +105 -424
  17. package/.claude/skills/workflow-commands/backlogrun.md +50 -61
  18. package/.claude/skills/workflow-commands/chain-rule.md +36 -40
  19. package/.claude/skills/workflow-commands/entry-sequence.md +6 -6
  20. package/.claude/skills/workflow-commands/followup.md +24 -20
  21. package/.claude/skills/workflow-commands/fullrun-steps.md +23 -27
  22. package/.claude/skills/workflow-commands/fullrun.md +10 -10
  23. package/.claude/skills/workflow-commands/halfrun.md +9 -8
  24. package/.claude/skills/workflow-commands/into-target.md +12 -18
  25. package/.claude/skills/workflow-commands/issue-comments.md +11 -26
  26. package/.claude/skills/workflow-commands/kickoff.md +27 -16
  27. package/.claude/skills/workflow-commands/latest-gate.md +18 -29
  28. package/.claude/skills/workflow-commands/needs-human-review.md +13 -24
  29. package/.claude/skills/workflow-commands/observation-filing.md +37 -28
  30. package/.claude/skills/workflow-commands/observation-ledger.md +48 -38
  31. package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -9
  32. package/.claude/skills/workflow-commands/prerequisite.md +23 -15
  33. package/.claude/skills/workflow-commands/progress-watcher.md +17 -11
  34. package/.claude/skills/workflow-commands/prrun.md +3 -3
  35. package/.claude/skills/workflow-commands/retrospective.md +13 -18
  36. package/.claude/skills/workflow-commands/split-assessment.md +6 -4
  37. package/.claude/skills/workflow-commands/target-repository.md +25 -28
  38. package/.claude/skills/workflow-commands/working-tree-hold.md +11 -17
  39. package/.gitattributes +2 -1
  40. package/.github/workflows/ci.yml +14 -0
  41. package/.github/workflows/publish.yml +2 -0
  42. package/.vscode/tasks.json +14 -0
  43. package/CLAUDE.md +10 -61
  44. package/README.md +38 -57
  45. package/SECURITY.md +1 -1
  46. package/dist/CLAUDE.md +10 -61
  47. package/dist/commands/document-section-cli.js +42 -10
  48. package/dist/config-merge/index.js +11 -2
  49. package/dist/hooks/audit-provision.js +2 -2
  50. package/dist/hooks/batch-guard.js +7 -7
  51. package/dist/hooks/{chunk-FIVDHQGT.js → chunk-43G45XJF.js} +18 -20
  52. package/dist/hooks/{chunk-JUDKDCDP.js → chunk-4TW4MQUL.js} +284 -362
  53. package/dist/hooks/{chunk-5VMKCCC4.js → chunk-76RK6E3H.js} +13 -11
  54. package/dist/hooks/{chunk-RNWHN5BP.js → chunk-DZWZ3DKY.js} +4 -4
  55. package/dist/hooks/{chunk-5VNDSNG3.js → chunk-FZ6FUSBM.js} +1 -1
  56. package/dist/hooks/{chunk-VC3PZPZO.js → chunk-GG72ANKI.js} +1 -1
  57. package/dist/hooks/{chunk-6HJJXRBX.js → chunk-KPM4YIIX.js} +8 -44
  58. package/dist/hooks/chunk-MXVQMLDP.js +3705 -0
  59. package/dist/hooks/{chunk-ELCN5LCH.js → chunk-NEC4AT4Z.js} +34 -12
  60. package/dist/hooks/{chunk-TQNPDZNH.js → chunk-NZBHG6FW.js} +7 -5
  61. package/dist/hooks/chunk-NZN2UFI6.js +2409 -0
  62. package/dist/hooks/{chunk-F56MFS4B.js → chunk-R6CRQEAL.js} +4 -4
  63. package/dist/hooks/chunk-SYSRHRWU.js +1589 -0
  64. package/dist/hooks/{chunk-55HHG5PX.js → chunk-TLJYAGZK.js} +799 -903
  65. package/dist/hooks/chunk-Z5TMJIPW.js +45 -0
  66. package/dist/hooks/codex-hook-adapter.js +26 -21
  67. package/dist/hooks/duplicate-read-guard.js +8 -8
  68. package/dist/hooks/format-edited.js +4 -4
  69. package/dist/hooks/inputs.json +213 -197
  70. package/dist/hooks/investigation-guard.js +8 -8
  71. package/dist/hooks/pretool-guard.js +15 -15
  72. package/dist/hooks/session-lang.js +406 -8
  73. package/dist/hooks/stop-guard.js +122 -201
  74. package/dist/josh.js +540 -137
  75. package/dist/version/index.js +15 -13
  76. package/eslint/base.js +43 -5
  77. package/eslint/rules/english-only-prose.js +3 -3
  78. package/eslint/rules/import.js +12 -0
  79. package/eslint/rules/namespace-object-export.js +2 -2
  80. package/package.json +16 -10
  81. package/pnpm-workspace.yaml +2 -4
  82. package/prompts/coding-standards.md +14 -48
  83. package/prompts/collaboration-workflow/file-edits.md +1 -1
  84. package/prompts/collaboration-workflow/issue-citation.md +1 -1
  85. package/prompts/collaboration-workflow/issue-template.md +4 -10
  86. package/prompts/collaboration-workflow/operating-rules.md +7 -8
  87. package/prompts/collaboration-workflow/output-bounds.md +1 -1
  88. package/prompts/collaboration-workflow/overview.md +1 -1
  89. package/prompts/collaboration-workflow/plan-comment.md +2 -1
  90. package/prompts/collaboration-workflow/principles.md +21 -3
  91. package/prompts/collaboration-workflow/report-format.md +16 -29
  92. package/prompts/collaboration-workflow/residency.md +1 -1
  93. package/prompts/collaboration-workflow/rule-delivery.md +7 -95
  94. package/prompts/collaboration-workflow/shell-body.md +3 -23
  95. package/prompts/collaboration-workflow/turn-batching.md +4 -13
  96. package/prompts/collaboration-workflow/wip-cap.md +5 -11
  97. package/prompts/refactoring.md +1 -1
  98. package/prompts/review-rubric.md +3 -22
  99. package/prompts/review.md +15 -38
  100. package/prompts/testing-guide.md +2 -4
  101. package/scripts/adopt/adopt-logic.ts +5 -5
  102. package/scripts/adopt/adopt-toolkits.ts +4 -5
  103. package/scripts/adopt/adopt.ts +2 -3
  104. package/scripts/agent/agent-argv.ts +7 -7
  105. package/scripts/agent/agent-diagnostics.ts +2 -2
  106. package/scripts/agent/agent-exit-record.ts +1 -1
  107. package/scripts/agent/agent-headless.ts +1 -1
  108. package/scripts/agent/agent-launch-environment.ts +6 -1
  109. package/scripts/agent/agent-role-profile.ts +49 -22
  110. package/scripts/agent/agent-session-role.ts +32 -0
  111. package/scripts/agent/api-outage.ts +1 -1
  112. package/scripts/agent/claude-agent-argv.ts +4 -4
  113. package/scripts/agent/claude-result-event.ts +4 -4
  114. package/scripts/agent/codex-hooks.ts +2 -2
  115. package/scripts/agent/interactive-ask.ts +3 -6
  116. package/scripts/auto-ok/auto-ok-cli.ts +46 -60
  117. package/scripts/backlog/backlog-arrival-added.ts +34 -0
  118. package/scripts/backlog/backlog-arrival.ts +54 -17
  119. package/scripts/backlog/backlog-budget-cli.ts +34 -6
  120. package/scripts/backlog/backlog-budget.ts +17 -24
  121. package/scripts/backlog/backlog-defect-priority.ts +1 -1
  122. package/scripts/backlog/backlog-drive-args.ts +5 -4
  123. package/scripts/backlog/backlog-drive-cli.ts +14 -10
  124. package/scripts/backlog/backlog-drive-epic.ts +85 -0
  125. package/scripts/backlog/backlog-drive-launch.ts +1 -1
  126. package/scripts/backlog/backlog-drive-named-offer.ts +60 -9
  127. package/scripts/backlog/backlog-drive-named.ts +39 -9
  128. package/scripts/backlog/backlog-drive-offer-argv.ts +1 -1
  129. package/scripts/backlog/backlog-drive-restore.ts +1 -1
  130. package/scripts/backlog/backlog-drive-retrospective.ts +2 -2
  131. package/scripts/backlog/backlog-drive.ts +43 -28
  132. package/scripts/backlog/backlog-idle.ts +88 -0
  133. package/scripts/backlog/backlog-named.ts +11 -15
  134. package/scripts/backlog/backlog-next.ts +26 -30
  135. package/scripts/backlog/backlog-offer-cli.ts +28 -23
  136. package/scripts/backlog/backlog-offer.ts +7 -7
  137. package/scripts/backlog/backlog-overlap.ts +178 -0
  138. package/scripts/backlog/backlog-plan-cli.ts +14 -90
  139. package/scripts/backlog/backlog-plan-read.ts +111 -0
  140. package/scripts/backlog/backlog-plan.ts +11 -10
  141. package/scripts/backlog/backlog-pool.ts +13 -14
  142. package/scripts/backlog/backlog-rank.ts +11 -11
  143. package/scripts/backlog/backlog-ready.ts +15 -10
  144. package/scripts/backlog/backlog-scope.ts +14 -15
  145. package/scripts/backlog/backlog-stalled-cli.ts +2 -2
  146. package/scripts/backlog/backlog-stalled-detect.ts +4 -4
  147. package/scripts/backlog/backlog-stalled.ts +5 -6
  148. package/scripts/backlog/backlog-waves.ts +4 -4
  149. package/scripts/backlog/backlogrun-args.ts +74 -0
  150. package/scripts/backlog/backlogrun-cli.ts +113 -0
  151. package/scripts/backlog/backlogrun-launch.ts +178 -0
  152. package/scripts/behavior/behavior-assertion.ts +6 -8
  153. package/scripts/behavior/behavior-cli.ts +1 -1
  154. package/scripts/behavior/behavior-rules.ts +3 -3
  155. package/scripts/build/build-claude-md.ts +4 -4
  156. package/scripts/build/build-codex-hooks.ts +2 -2
  157. package/scripts/build/build-commands.ts +1 -1
  158. package/scripts/build/build-hooks.ts +5 -5
  159. package/scripts/build/build.ts +1 -1
  160. package/scripts/build/hook-bundle-stamp.ts +109 -7
  161. package/scripts/build/local-bin.ts +2 -2
  162. package/scripts/cases/cases-cli.ts +1 -1
  163. package/scripts/cases/cases-logic.ts +2 -2
  164. package/scripts/ci/composite-actions.ts +1 -2
  165. package/scripts/ci/pr-classification.ts +2 -2
  166. package/scripts/claude/workflow-destination.ts +1 -1
  167. package/scripts/clone/clone-aggregate.ts +1 -1
  168. package/scripts/clone/clone-fingerprint.ts +1 -1
  169. package/scripts/clone/clone-scan-cli.ts +1 -1
  170. package/scripts/clone/clone-scan.ts +1 -1
  171. package/scripts/config-merge/index.ts +1 -1
  172. package/scripts/config-merge/json-format.ts +1 -3
  173. package/scripts/config-merge/patch-json-array.ts +90 -0
  174. package/scripts/config-merge/patch-json-key.ts +6 -3
  175. package/scripts/config-merge/patch-json-list.ts +1 -1
  176. package/scripts/cost-runtime/codex-usage.ts +1 -1
  177. package/scripts/cost-runtime/context-cut-payback.ts +4 -5
  178. package/scripts/cost-runtime/context-cut-threshold.ts +4 -6
  179. package/scripts/cost-runtime/cost-attribute.ts +3 -3
  180. package/scripts/cost-runtime/cost-blocks.ts +3 -4
  181. package/scripts/cost-runtime/cost-cli.ts +14 -11
  182. package/scripts/cost-runtime/cost-corpus.ts +11 -11
  183. package/scripts/cost-runtime/cost-pricing.ts +4 -4
  184. package/scripts/cost-runtime/cost-tokens.ts +1 -2
  185. package/scripts/cost-runtime/cost-transcript.ts +29 -29
  186. package/scripts/cost-runtime/cost-usage.ts +6 -7
  187. package/scripts/cost-runtime/cost-verdict.ts +10 -11
  188. package/scripts/cost-runtime/own-session.ts +1 -1
  189. package/scripts/cost-runtime/transcript-cwd.ts +2 -2
  190. package/scripts/delegation/delegation-cli.ts +4 -4
  191. package/scripts/delegation/delegation-policy.ts +13 -15
  192. package/scripts/delegation/duplicate-read-guard.ts +9 -10
  193. package/scripts/delegation/fanout-cli.ts +1 -1
  194. package/scripts/delegation/fanout.ts +1 -1
  195. package/scripts/delegation/investigation-guard.ts +18 -22
  196. package/scripts/delegation/investigation-reads.ts +48 -238
  197. package/scripts/discovery/repo-discovery.ts +1 -1
  198. package/scripts/discovery/repo-map-logic.ts +1 -2
  199. package/scripts/discovery/repo-origin.ts +3 -3
  200. package/scripts/discovery/repo-party-cli.ts +2 -2
  201. package/scripts/discovery/repo-party.ts +2 -2
  202. package/scripts/doctor/doctor-consumer.ts +1 -1
  203. package/scripts/doctor/doctor-io.ts +6 -7
  204. package/scripts/doctor/doctor-logic.ts +1 -1
  205. package/scripts/doctor/doctor-ports.ts +1 -1
  206. package/scripts/doctor/doctor.ts +8 -9
  207. package/scripts/document/backlogrun-parent-read-set.ts +5 -6
  208. package/scripts/document/bash-output-cap.ts +5 -7
  209. package/scripts/document/capped-print-part.ts +1 -1
  210. package/scripts/document/capped-print.ts +1 -1
  211. package/scripts/document/document-byte-budget.ts +33 -64
  212. package/scripts/document/document-byte-check.ts +4 -4
  213. package/scripts/document/document-reachability.ts +7 -8
  214. package/scripts/document/document-read-cli.ts +2 -2
  215. package/scripts/document/document-scan.ts +26 -2
  216. package/scripts/document/document-section-cli.ts +6 -8
  217. package/scripts/document/document-section.ts +8 -12
  218. package/scripts/document/edit-files-cli.ts +3 -4
  219. package/scripts/document/entry-read-budget.ts +8 -70
  220. package/scripts/document/entry-read-set.ts +51 -34
  221. package/scripts/document/lane-child-read-set.ts +9 -9
  222. package/scripts/document/read-files-cli.ts +1 -2
  223. package/scripts/document/read-set-cli.ts +16 -19
  224. package/scripts/document/read-set-cost.ts +4 -4
  225. package/scripts/document/read-set-point-of-use.ts +28 -38
  226. package/scripts/document/read-set-pricing.ts +1 -1
  227. package/scripts/document/read-set-trim.ts +3 -3
  228. package/scripts/document/resident-budget.ts +8 -10
  229. package/scripts/epic/epic-add-body.ts +15 -18
  230. package/scripts/epic/epic-add-plan.ts +26 -28
  231. package/scripts/epic/epic-add.ts +32 -25
  232. package/scripts/epic/epic-audit-checks.ts +27 -37
  233. package/scripts/epic/epic-audit-cli.ts +21 -22
  234. package/scripts/epic/epic-audit-orphans.ts +16 -17
  235. package/scripts/epic/epic-audit-rationale.ts +10 -15
  236. package/scripts/epic/epic-audit-report.ts +2 -5
  237. package/scripts/epic/epic-audit.ts +18 -14
  238. package/scripts/epic/epic-body.ts +10 -10
  239. package/scripts/epic/epic-bundle-cli.ts +36 -34
  240. package/scripts/epic/epic-bundle-evidence.ts +5 -5
  241. package/scripts/epic/epic-bundle-gaps.ts +6 -9
  242. package/scripts/epic/epic-bundle-poll.ts +1 -1
  243. package/scripts/epic/epic-bundle-referenced.ts +11 -14
  244. package/scripts/epic/epic-bundle.ts +19 -20
  245. package/scripts/epic/epic-busy.ts +44 -21
  246. package/scripts/epic/epic-candidate-confirm.ts +15 -18
  247. package/scripts/epic/epic-chains.ts +18 -23
  248. package/scripts/epic/epic-classify.ts +11 -12
  249. package/scripts/epic/epic-cli-argv.ts +5 -6
  250. package/scripts/epic/epic-cli-remove.ts +9 -4
  251. package/scripts/epic/epic-cli.ts +38 -26
  252. package/scripts/epic/epic-close-comment.ts +14 -15
  253. package/scripts/epic/epic-close.ts +25 -29
  254. package/scripts/epic/epic-cross-repo.ts +18 -21
  255. package/scripts/epic/epic-decision.ts +14 -18
  256. package/scripts/epic/epic-fetch.ts +25 -31
  257. package/scripts/epic/epic-graph.ts +15 -17
  258. package/scripts/epic/epic-index.ts +14 -16
  259. package/scripts/epic/epic-issue.ts +9 -11
  260. package/scripts/epic/epic-label-age.ts +74 -0
  261. package/scripts/epic/epic-lane-offer.ts +35 -24
  262. package/scripts/epic/epic-nested.ts +1 -1
  263. package/scripts/epic/epic-next-read.ts +8 -8
  264. package/scripts/epic/epic-next-views.ts +12 -12
  265. package/scripts/epic/epic-next.ts +29 -33
  266. package/scripts/epic/epic-outside-blocker.ts +11 -10
  267. package/scripts/epic/epic-parse.ts +22 -24
  268. package/scripts/epic/epic-promote.ts +3 -2
  269. package/scripts/epic/epic-rank.ts +1 -1
  270. package/scripts/epic/epic-read.ts +10 -8
  271. package/scripts/epic/epic-reconcile.ts +8 -6
  272. package/scripts/epic/epic-reference.ts +5 -4
  273. package/scripts/epic/epic-relation-recheck.ts +10 -11
  274. package/scripts/epic/epic-relations.ts +9 -8
  275. package/scripts/epic/epic-remove-plan.ts +4 -5
  276. package/scripts/epic/epic-remove.ts +7 -5
  277. package/scripts/epic/epic-report.ts +18 -20
  278. package/scripts/epic/epic-run.ts +6 -5
  279. package/scripts/epic/epic-sections.ts +2 -2
  280. package/scripts/epic/epic-shape.ts +3 -3
  281. package/scripts/epic/epic-solo-stale.ts +3 -2
  282. package/scripts/epic/epic-solo.ts +8 -8
  283. package/scripts/epic/epic-triage.ts +5 -4
  284. package/scripts/epic/epic-validate.ts +8 -7
  285. package/scripts/epic/epic.ts +5 -5
  286. package/scripts/exports/unused-members-cli.ts +1 -1
  287. package/scripts/followup/followup-issue-number.ts +1 -2
  288. package/scripts/followup/git-followup-cleanup.ts +6 -7
  289. package/scripts/followup/git-followup-finish.ts +11 -13
  290. package/scripts/followup/git-followup-flush.ts +11 -7
  291. package/scripts/followup/git-followup-issue-close.ts +16 -13
  292. package/scripts/followup/git-followup-label.ts +9 -6
  293. package/scripts/followup/git-followup-merged.ts +1 -1
  294. package/scripts/followup/git-followup-pending.ts +7 -9
  295. package/scripts/followup/git-followup-stages.ts +28 -17
  296. package/scripts/followup/git-followup-workflow.ts +19 -21
  297. package/scripts/followup/git-pr-followup-checks.ts +13 -20
  298. package/scripts/followup/git-pr-followup-wrapup.ts +7 -7
  299. package/scripts/followup/git-pr-followup.ts +18 -17
  300. package/scripts/gate/core-admission.ts +162 -0
  301. package/scripts/gate/core-budget.ts +134 -91
  302. package/scripts/gate/gate-ledger.ts +114 -0
  303. package/scripts/gate/gate-log.ts +7 -9
  304. package/scripts/gate/gate-plan.ts +103 -35
  305. package/scripts/gate/gate-report.ts +39 -21
  306. package/scripts/gate/gate-skip.ts +11 -13
  307. package/scripts/gate/gate-steps.ts +5 -1
  308. package/scripts/gate/gate-tree.ts +3 -4
  309. package/scripts/gate/hook-gate-reuse.ts +9 -9
  310. package/scripts/gate/machine-capacity.ts +313 -0
  311. package/scripts/gate/pre-commit-type-check.ts +4 -4
  312. package/scripts/gate/project-checks.ts +12 -4
  313. package/scripts/gate/scoped-green.ts +11 -18
  314. package/scripts/gate/type-check-command.ts +2 -2
  315. package/scripts/gate/type-check-step.ts +4 -4
  316. package/scripts/gate/verification-gate.ts +60 -53
  317. package/scripts/gh/gh-spawn.ts +2 -2
  318. package/scripts/gh/git-ai-review-scan.ts +3 -2
  319. package/scripts/gh/git-gh-api-path.ts +10 -11
  320. package/scripts/gh/git-gh-exec.ts +43 -48
  321. package/scripts/gh/git-gh-failure.ts +6 -9
  322. package/scripts/gh/git-gh-helpers.ts +1 -1
  323. package/scripts/gh/git-gh-issue-list.ts +15 -19
  324. package/scripts/gh/git-gh-issue-read.ts +43 -60
  325. package/scripts/gh/git-gh-issue-rest.ts +14 -15
  326. package/scripts/gh/git-gh-issue-write.ts +52 -40
  327. package/scripts/gh/git-gh-issue.ts +23 -24
  328. package/scripts/gh/git-gh-pr-auto-merge.ts +3 -3
  329. package/scripts/gh/git-gh-pr-read.ts +46 -50
  330. package/scripts/gh/git-gh-pr-rest.ts +23 -26
  331. package/scripts/gh/git-gh-pr-review.ts +2 -2
  332. package/scripts/gh/git-gh-pr-rollup.ts +4 -4
  333. package/scripts/gh/git-gh-pr-snapshot.ts +8 -10
  334. package/scripts/gh/git-gh-pr.ts +16 -16
  335. package/scripts/gh/git-gh-reachability.ts +11 -12
  336. package/scripts/gh/git-gh-repo.ts +2 -3
  337. package/scripts/gh/git-gh-rest-state.ts +1 -1
  338. package/scripts/gh/git-pr-ai-review.ts +6 -5
  339. package/scripts/gh/git-pr-checks-eval.ts +28 -30
  340. package/scripts/gh/git-pr-checks-parse.ts +14 -16
  341. package/scripts/gh/git-pr-checks-watch.ts +17 -17
  342. package/scripts/gh/git-pr-checks.ts +20 -23
  343. package/scripts/gh/git-pr-coderabbit.ts +8 -6
  344. package/scripts/gh/git-pr-confirmation.ts +5 -5
  345. package/scripts/gh/git-pr-managed-config.ts +7 -9
  346. package/scripts/gh/git-pr-messages.ts +1 -1
  347. package/scripts/gh/git-pr.ts +15 -16
  348. package/scripts/gh/github-issue-url.ts +8 -9
  349. package/scripts/git/base-tree.ts +66 -0
  350. package/scripts/git/change-base.ts +42 -2
  351. package/scripts/git/changed-file-scope.ts +5 -5
  352. package/scripts/git/changed-paths.ts +1 -2
  353. package/scripts/git/constants.ts +2 -2
  354. package/scripts/git/git-branch.ts +1 -1
  355. package/scripts/git/git-closes-keyword.ts +3 -3
  356. package/scripts/git/git-command.ts +53 -41
  357. package/scripts/git/git-common-directory.ts +3 -3
  358. package/scripts/git/git-diff-reads.ts +14 -15
  359. package/scripts/git/git-error.ts +1 -1
  360. package/scripts/git/git-execa-error.ts +1 -2
  361. package/scripts/git/git-issue.ts +10 -8
  362. package/scripts/git/git-location-environment.ts +3 -4
  363. package/scripts/git/git-ls-remote.ts +6 -8
  364. package/scripts/git/git-pre-push-hook.ts +11 -10
  365. package/scripts/git/git-preflight.ts +5 -5
  366. package/scripts/git/git-push-transport.ts +2 -2
  367. package/scripts/git/git-remote-branch.ts +1 -2
  368. package/scripts/git/git-schemas.ts +16 -23
  369. package/scripts/git/git-spawn-sync.ts +1 -1
  370. package/scripts/git/git-spawn.ts +37 -14
  371. package/scripts/git/git-ssh-keepalive.ts +12 -5
  372. package/scripts/git/git-staging.ts +7 -8
  373. package/scripts/git/git-workflow.ts +1 -1
  374. package/scripts/git/git-worktree.ts +35 -27
  375. package/scripts/git/gone-branch.ts +2 -2
  376. package/scripts/git/listing-cutoff.ts +1 -2
  377. package/scripts/git/lockfile-sync.ts +65 -0
  378. package/scripts/git/main-merge-guard.ts +1 -2
  379. package/scripts/git/main-merge.ts +7 -7
  380. package/scripts/git/main-sync.ts +23 -8
  381. package/scripts/git/parse-json-array.ts +18 -23
  382. package/scripts/git/repository-lock.ts +34 -2
  383. package/scripts/git/stash/git-stash.ts +4 -5
  384. package/scripts/git/stash/stash-orphans.ts +5 -3
  385. package/scripts/git/stash/stash-pop-args.ts +1 -1
  386. package/scripts/git/stash/stash-pop-cli.ts +3 -3
  387. package/scripts/git/stash/stash-sweep-lock.ts +2 -2
  388. package/scripts/hooks/batch-guard.ts +11 -13
  389. package/scripts/hooks/check-commit-message.ts +12 -9
  390. package/scripts/hooks/codex-hook-adapter.ts +16 -10
  391. package/scripts/hooks/edited-cspell.ts +3 -4
  392. package/scripts/hooks/format-edited-cli.ts +1 -1
  393. package/scripts/hooks/format-edited-file.ts +11 -17
  394. package/scripts/hooks/format-rewrite-notice.ts +19 -17
  395. package/scripts/hooks/pre-push-unit.ts +10 -14
  396. package/scripts/hooks/pretool-guard-cli.ts +4 -4
  397. package/scripts/hooks/pretool-guard.ts +93 -18
  398. package/scripts/hooks/reserved-run.ts +2 -2
  399. package/scripts/hooks/step-zero-notice.ts +1 -1
  400. package/scripts/hooks/stop-guard.ts +21 -10
  401. package/scripts/init/basic-path-migration.ts +2 -2
  402. package/scripts/init/claude-kit-only-settings.ts +2 -2
  403. package/scripts/init/claude-plugin-config.ts +2 -2
  404. package/scripts/init/distributed-paths.ts +4 -4
  405. package/scripts/init/hook-command-rewrite.ts +3 -3
  406. package/scripts/init/hook-launch.ts +5 -5
  407. package/scripts/init/init-actions.ts +13 -0
  408. package/scripts/init/init-ai-copy.ts +11 -11
  409. package/scripts/init/init-bootstrap.ts +3 -3
  410. package/scripts/init/init-copy-content.ts +4 -4
  411. package/scripts/init/init-logic-json-merge.ts +7 -9
  412. package/scripts/init/init-logic-migrate.ts +1 -1
  413. package/scripts/init/init-logic-templates.ts +1 -1
  414. package/scripts/init/init-logic-workspace.ts +4 -4
  415. package/scripts/init/init-logic-yaml-merge.ts +2 -2
  416. package/scripts/init/init-logic.ts +19 -22
  417. package/scripts/init/init.ts +12 -8
  418. package/scripts/init/kit-base-preset.ts +1 -1
  419. package/scripts/init/kit-setup-state.ts +1 -1
  420. package/scripts/init/kit-written-paths.ts +1 -2
  421. package/scripts/init/package-manager-pin.ts +35 -0
  422. package/scripts/init/project-profile-cli.ts +1 -1
  423. package/scripts/init/project-profile.ts +3 -3
  424. package/scripts/init/session-language-environment.ts +1 -1
  425. package/scripts/init/start-exec.ts +3 -4
  426. package/scripts/init/start-plan.ts +2 -2
  427. package/scripts/init/start-setup-pr.ts +3 -2
  428. package/scripts/init/start-steps.ts +2 -2
  429. package/scripts/init/tsconfig-preset-migration.ts +1 -1
  430. package/scripts/init/vscode-tasks.ts +62 -0
  431. package/scripts/issue/baseline-measure.ts +2 -2
  432. package/scripts/issue/behavior-change-lint.ts +2 -2
  433. package/scripts/issue/defect-rate-cli.ts +6 -7
  434. package/scripts/issue/defect-rate.ts +37 -27
  435. package/scripts/issue/git-next-issues.ts +9 -8
  436. package/scripts/issue/issue-auto-ok.ts +49 -11
  437. package/scripts/issue/issue-backlinks-cli.ts +5 -5
  438. package/scripts/issue/issue-backlinks.ts +6 -6
  439. package/scripts/issue/issue-cite-cli.ts +20 -18
  440. package/scripts/issue/issue-cite.ts +18 -8
  441. package/scripts/issue/issue-closing-pr.ts +4 -4
  442. package/scripts/issue/issue-comment-cli.ts +6 -4
  443. package/scripts/issue/issue-file-cli.ts +75 -15
  444. package/scripts/issue/issue-file-fold.ts +155 -0
  445. package/scripts/issue/issue-file.ts +14 -6
  446. package/scripts/issue/issue-fold-cli.ts +14 -9
  447. package/scripts/issue/issue-fold.ts +23 -8
  448. package/scripts/issue/issue-labels.ts +46 -37
  449. package/scripts/issue/issue-lint-cli.ts +2 -2
  450. package/scripts/issue/issue-lint.ts +1 -1
  451. package/scripts/issue/issue-merged.ts +10 -4
  452. package/scripts/issue/issue-number-shape.ts +27 -0
  453. package/scripts/issue/issue-rank.ts +1 -1
  454. package/scripts/issue/issue-read-cli.ts +4 -5
  455. package/scripts/issue/issue-read.ts +4 -5
  456. package/scripts/issue/issue-reference.ts +5 -5
  457. package/scripts/issue/issue-release-cli.ts +165 -0
  458. package/scripts/issue/issue-release.ts +58 -0
  459. package/scripts/issue/issue-report-failures.ts +7 -4
  460. package/scripts/issue/issue-scout-cli.ts +11 -11
  461. package/scripts/issue/issue-scout-closed.ts +4 -4
  462. package/scripts/issue/issue-scout.ts +4 -5
  463. package/scripts/issue/issue-state-cli.ts +17 -10
  464. package/scripts/issue/issue-state.ts +12 -13
  465. package/scripts/issue/issue-wip.ts +7 -7
  466. package/scripts/issue/markdown-section.ts +3 -3
  467. package/scripts/issue/measure-rerun-cli.ts +10 -9
  468. package/scripts/issue/reproduction-measure.ts +3 -3
  469. package/scripts/issue/session-cite.ts +56 -0
  470. package/scripts/josh/agent-session-environment.ts +10 -8
  471. package/scripts/josh/cli-body.ts +2 -2
  472. package/scripts/josh/command-suggest.ts +1 -1
  473. package/scripts/josh/file-map-stamp.ts +20 -23
  474. package/scripts/josh/hook-decision.ts +24 -28
  475. package/scripts/josh/josh-command-map.ts +4 -1
  476. package/scripts/josh/josh-command-types.ts +32 -34
  477. package/scripts/josh/josh-commands-ai.ts +6 -6
  478. package/scripts/josh/josh-commands-backlog.ts +15 -3
  479. package/scripts/josh/josh-commands-clone.ts +1 -1
  480. package/scripts/josh/josh-commands-development.ts +33 -4
  481. package/scripts/josh/josh-commands-document.ts +3 -3
  482. package/scripts/josh/josh-commands-guard.ts +3 -3
  483. package/scripts/josh/josh-commands-issue.ts +11 -5
  484. package/scripts/josh/josh-commands-lane.ts +16 -5
  485. package/scripts/josh/josh-commands-lint.ts +1 -1
  486. package/scripts/josh/josh-commands-maintenance.ts +2 -2
  487. package/scripts/josh/josh-commands-run.ts +20 -6
  488. package/scripts/josh/josh-commands-split.ts +1 -2
  489. package/scripts/josh/josh-commands-versioning.ts +5 -5
  490. package/scripts/josh/josh-commands-workflow.ts +30 -22
  491. package/scripts/josh/josh-environment-file.ts +1 -1
  492. package/scripts/josh/josh-in-process.ts +3 -3
  493. package/scripts/josh/josh-logic.ts +10 -10
  494. package/scripts/josh/josh-run.ts +3 -3
  495. package/scripts/josh/josh-verdict.ts +9 -12
  496. package/scripts/josh/josh.ts +3 -3
  497. package/scripts/josh/kit-only.ts +2 -2
  498. package/scripts/josh/path-decision.ts +3 -3
  499. package/scripts/josh/platform-temporary.ts +7 -5
  500. package/scripts/josh/process-identity.ts +24 -6
  501. package/scripts/josh/process-owner.ts +4 -4
  502. package/scripts/josh/session-language-cli.ts +53 -11
  503. package/scripts/josh/session-language.ts +1 -1
  504. package/scripts/josh/stamp-file.ts +48 -29
  505. package/scripts/josh/stamp-record.ts +57 -0
  506. package/scripts/lane/lane-await.ts +35 -11
  507. package/scripts/lane/lane-cache.ts +6 -6
  508. package/scripts/lane/lane-capacity.ts +32 -17
  509. package/scripts/lane/lane-child-invocation.ts +17 -15
  510. package/scripts/lane/lane-child-marker.ts +12 -12
  511. package/scripts/lane/lane-cli.ts +20 -13
  512. package/scripts/lane/lane-close.ts +6 -6
  513. package/scripts/lane/lane-dispatch.ts +61 -72
  514. package/scripts/lane/lane-environment.ts +5 -5
  515. package/scripts/lane/lane-guard-policy.ts +7 -21
  516. package/scripts/lane/lane-handoff.ts +2 -2
  517. package/scripts/lane/lane-install.ts +9 -10
  518. package/scripts/lane/lane-launch-cli.ts +13 -8
  519. package/scripts/lane/lane-ledger.ts +73 -11
  520. package/scripts/lane/lane-leftover.ts +44 -30
  521. package/scripts/lane/lane-limit-cli.ts +160 -0
  522. package/scripts/lane/lane-limit-override.ts +74 -0
  523. package/scripts/lane/lane-load.ts +19 -68
  524. package/scripts/lane/lane-measure-cli.ts +15 -25
  525. package/scripts/lane/lane-occupancy.ts +6 -4
  526. package/scripts/lane/lane-open.ts +25 -24
  527. package/scripts/lane/lane-output.ts +4 -3
  528. package/scripts/lane/lane-paths.ts +22 -8
  529. package/scripts/lane/lane-phase.ts +33 -0
  530. package/scripts/lane/lane-reap.ts +2 -2
  531. package/scripts/lane/lane-registry.ts +27 -15
  532. package/scripts/lane/lane-relaunch.ts +9 -9
  533. package/scripts/lane/lane-report.ts +5 -4
  534. package/scripts/lane/lane-resume.ts +2 -2
  535. package/scripts/lane/lane-sampler.ts +55 -0
  536. package/scripts/lane/lane-seed.ts +7 -7
  537. package/scripts/lane/lane-stage-stats.ts +135 -0
  538. package/scripts/lane/lane-start-point.ts +8 -11
  539. package/scripts/lane/lane-stats.ts +60 -15
  540. package/scripts/lane/lane-stray.ts +140 -0
  541. package/scripts/lane/lane-vacant.ts +1 -1
  542. package/scripts/lane/openai-lane-supervisor-decision.ts +3 -7
  543. package/scripts/lane/openai-lane-supervisor-owner.ts +3 -9
  544. package/scripts/lane/openai-review-broker.ts +2 -4
  545. package/scripts/lib/ancestor-directories.ts +1 -1
  546. package/scripts/lib/bounded-pool.ts +2 -2
  547. package/scripts/lib/buffered-process.ts +4 -6
  548. package/scripts/lib/caddy-logs.sh +0 -0
  549. package/scripts/lib/cli-flags.ts +39 -6
  550. package/scripts/lib/error-message.ts +1 -1
  551. package/scripts/lib/json-value.ts +17 -3
  552. package/scripts/lib/poll.ts +1 -1
  553. package/scripts/lib/status-icons.ts +3 -3
  554. package/scripts/lib/timed-fetch.ts +1 -1
  555. package/scripts/lib/timeouts.ts +1 -1
  556. package/scripts/lines/bytes-command.ts +3 -4
  557. package/scripts/lines/effective-limit.ts +25 -12
  558. package/scripts/lines/line-budget.ts +47 -55
  559. package/scripts/lines/line-targets.ts +6 -2
  560. package/scripts/lines/lines-command.ts +3 -3
  561. package/scripts/lint/cspell-cached.ts +1 -1
  562. package/scripts/lint/cycle-recheck.ts +122 -0
  563. package/scripts/lint/format.ts +1 -2
  564. package/scripts/lint/lint-parallel.ts +34 -19
  565. package/scripts/lint/lint-related-scope.ts +25 -15
  566. package/scripts/lint/lint-related.ts +6 -7
  567. package/scripts/managed-marker/index.ts +1 -1
  568. package/scripts/managed-marker/managed-marker-logic.ts +1 -2
  569. package/scripts/notify/git-notify.ts +9 -7
  570. package/scripts/notify/telegram-notify.ts +53 -37
  571. package/scripts/notify/telegram-test-logic.ts +3 -3
  572. package/scripts/notify/telegram-test.ts +45 -30
  573. package/scripts/observations/observation-ledger-home.ts +14 -8
  574. package/scripts/observations/observation-ledger-line.ts +3 -2
  575. package/scripts/observations/observation-ledger-migrate.ts +3 -4
  576. package/scripts/observations/observation-ledger-prepare.ts +4 -4
  577. package/scripts/observations/observation-ledger.ts +14 -15
  578. package/scripts/observations/observation-record-cli.ts +83 -0
  579. package/scripts/observations/observation-record.ts +91 -0
  580. package/scripts/observations/observations-flush-cli.ts +1 -1
  581. package/scripts/observations/observations-flush-landing.ts +7 -6
  582. package/scripts/observations/observations-flush.ts +26 -27
  583. package/scripts/overrides/overrides-check.ts +18 -8
  584. package/scripts/package/package-scout-cli.ts +1 -1
  585. package/scripts/package/package-scout-format.ts +2 -2
  586. package/scripts/package/package-scout.ts +1 -1
  587. package/scripts/propagate/propagate-git-failure.ts +1 -1
  588. package/scripts/propagate/propagate-git.ts +7 -7
  589. package/scripts/propagate/propagate-plan.ts +2 -2
  590. package/scripts/propagate/propagate-publish.ts +2 -3
  591. package/scripts/propagate/propagate-run.ts +5 -7
  592. package/scripts/propagate/propagate-select.ts +1 -1
  593. package/scripts/propagate/propagate-steps.ts +19 -20
  594. package/scripts/propagate/propagate-targets.ts +6 -10
  595. package/scripts/propagate/propagate.ts +5 -5
  596. package/scripts/refactor/import-graph.ts +1 -1
  597. package/scripts/refactor/refactor-lint.ts +4 -10
  598. package/scripts/refactor/refactor-scan-cli.ts +1 -1
  599. package/scripts/refactor/refactor-scan.ts +2 -2
  600. package/scripts/refactor/refactor-targets.ts +1 -1
  601. package/scripts/release/github-release-cli.ts +25 -3
  602. package/scripts/release/github-release-environment.ts +1 -0
  603. package/scripts/release/github-release-runs.ts +115 -0
  604. package/scripts/release/github-release.ts +13 -67
  605. package/scripts/release/release-cli.ts +21 -4
  606. package/scripts/release/release-history.ts +6 -10
  607. package/scripts/release/release-plan.ts +3 -3
  608. package/scripts/release/release-progress.ts +3 -4
  609. package/scripts/release/release-publish.ts +8 -9
  610. package/scripts/release/release-scope-cli.ts +8 -10
  611. package/scripts/release/release-tag.ts +6 -8
  612. package/scripts/release/release-worktree.ts +5 -5
  613. package/scripts/repo/auto-merge-setting-logic.ts +7 -9
  614. package/scripts/repo/auto-merge-setting.ts +1 -1
  615. package/scripts/repo/repo-setting.ts +4 -4
  616. package/scripts/repo/repository-labels.ts +1 -1
  617. package/scripts/repo/required-checks-logic.ts +3 -3
  618. package/scripts/repo/required-checks-report.ts +1 -1
  619. package/scripts/repo/ruleset-check-cli.ts +1 -1
  620. package/scripts/repo/ruleset-check.ts +1 -1
  621. package/scripts/report/report-format-reference.ts +26 -0
  622. package/scripts/report/report-lint-cli.ts +2 -2
  623. package/scripts/report/report-lint.ts +16 -2
  624. package/scripts/review/disposition-cli.ts +2 -2
  625. package/scripts/review/disposition-logic.ts +1 -1
  626. package/scripts/review/live-evidence.ts +9 -6
  627. package/scripts/review/review-attest-cli.ts +1 -2
  628. package/scripts/review/review-attest.ts +3 -3
  629. package/scripts/review/review-brief-cli.ts +19 -20
  630. package/scripts/review/review-brief.ts +29 -32
  631. package/scripts/review/review-checkout.ts +2 -2
  632. package/scripts/review/review-diff-parts.ts +3 -5
  633. package/scripts/review/review-diff-write.ts +1 -1
  634. package/scripts/review/review-finding-ledger.ts +7 -4
  635. package/scripts/review/review-findings-cli.ts +2 -2
  636. package/scripts/review/review-level.ts +4 -7
  637. package/scripts/review/review-record-cli.ts +73 -16
  638. package/scripts/review/review-record.ts +5 -4
  639. package/scripts/review/review-round2-cli.ts +2 -3
  640. package/scripts/review/review-round2.ts +13 -21
  641. package/scripts/review/review-stamps.ts +9 -71
  642. package/scripts/review/review-tree.ts +4 -5
  643. package/scripts/rules/bash-triggers.ts +4 -4
  644. package/scripts/rules/decision-oracle-batch.ts +5 -6
  645. package/scripts/rules/decision-oracle-stage.ts +1 -1
  646. package/scripts/rules/decision-oracle-tokens.ts +1 -2
  647. package/scripts/rules/decision-oracle.ts +2 -2
  648. package/scripts/rules/delivered-rules.ts +61 -406
  649. package/scripts/rules/destructive-command.ts +2 -2
  650. package/scripts/rules/direct-filing.ts +4 -4
  651. package/scripts/rules/direct-pr-create.ts +2 -2
  652. package/scripts/rules/early-heartbeat.ts +15 -19
  653. package/scripts/rules/file-body.ts +5 -6
  654. package/scripts/rules/filing-cap.ts +6 -7
  655. package/scripts/rules/filing-offer.ts +1 -1
  656. package/scripts/rules/firing-point.ts +6 -6
  657. package/scripts/rules/gh-api.ts +2 -2
  658. package/scripts/rules/git-argv.ts +3 -3
  659. package/scripts/rules/git-force.ts +2 -2
  660. package/scripts/rules/hook-context-line.ts +31 -0
  661. package/scripts/rules/implementation-cut-verdict.ts +5 -8
  662. package/scripts/rules/implementation-cut.ts +35 -32
  663. package/scripts/rules/index-guard.ts +2 -2
  664. package/scripts/rules/issue-citation.ts +7 -7
  665. package/scripts/rules/issue-comments.ts +21 -13
  666. package/scripts/rules/josh-git-bare.ts +2 -2
  667. package/scripts/rules/lane-background.ts +14 -16
  668. package/scripts/rules/lane-carry-conflict.ts +41 -5
  669. package/scripts/rules/lane-interactive-ask.ts +6 -9
  670. package/scripts/rules/lane-park.ts +12 -16
  671. package/scripts/rules/lane-split-park.ts +1 -2
  672. package/scripts/rules/lane-switch-main.ts +10 -13
  673. package/scripts/rules/last-prompt.ts +1 -1
  674. package/scripts/rules/oracle-consulted.ts +5 -5
  675. package/scripts/rules/oracle-firing.ts +6 -9
  676. package/scripts/rules/oracle-list-cli.ts +2 -2
  677. package/scripts/rules/permission-guards.ts +2 -2
  678. package/scripts/rules/piped-verification.ts +79 -9
  679. package/scripts/rules/poll-loop.ts +9 -11
  680. package/scripts/rules/pre-gate-cut.ts +33 -30
  681. package/scripts/rules/prior-comment-read.ts +3 -3
  682. package/scripts/rules/protected-files.ts +25 -13
  683. package/scripts/rules/raw-field-body.ts +3 -4
  684. package/scripts/rules/reply-language.ts +1 -1
  685. package/scripts/rules/rule-body-guard.ts +10 -12
  686. package/scripts/rules/rule-guard.ts +1 -1
  687. package/scripts/rules/rule-list.ts +51 -0
  688. package/scripts/rules/rule-registry-rows.ts +282 -0
  689. package/scripts/rules/rule-registry.ts +109 -0
  690. package/scripts/rules/rule-value-cache.ts +2 -2
  691. package/scripts/rules/rule-value-cli.ts +6 -4
  692. package/scripts/rules/rule-value.ts +61 -22
  693. package/scripts/rules/run-tail-rule.ts +11 -15
  694. package/scripts/rules/shell-body-trigger.ts +7 -7
  695. package/scripts/rules/shell-segments.ts +2 -4
  696. package/scripts/rules/stop-rules.ts +54 -41
  697. package/scripts/rules/tail-commands.ts +1 -1
  698. package/scripts/rules/test-declared-commit.ts +2 -2
  699. package/scripts/rules/third-party-write.ts +3 -3
  700. package/scripts/rules/worktree-guard.ts +12 -5
  701. package/scripts/run/add/run-add-cli.ts +165 -0
  702. package/scripts/run/add/run-add.ts +124 -0
  703. package/scripts/run/board/run-board-cli.ts +207 -0
  704. package/scripts/run/board/run-board-closed.ts +95 -0
  705. package/scripts/run/board/run-board-every.ts +60 -0
  706. package/scripts/run/board/run-board-fetch.ts +38 -0
  707. package/scripts/run/board/run-board-fit.ts +219 -0
  708. package/scripts/run/board/run-board-github.ts +162 -0
  709. package/scripts/run/board/run-board-header.ts +275 -0
  710. package/scripts/run/board/run-board-kind.ts +35 -0
  711. package/scripts/run/board/run-board-labels.ts +299 -0
  712. package/scripts/run/board/run-board-layout.ts +222 -0
  713. package/scripts/run/board/run-board-link.ts +31 -0
  714. package/scripts/run/board/run-board-machine.ts +198 -0
  715. package/scripts/run/board/run-board-notes.ts +103 -0
  716. package/scripts/run/board/run-board-phase.ts +136 -0
  717. package/scripts/run/board/run-board-plan.ts +129 -0
  718. package/scripts/run/board/run-board-read.ts +62 -0
  719. package/scripts/run/board/run-board-render-legend.ts +82 -0
  720. package/scripts/run/board/run-board-render-notes.ts +77 -0
  721. package/scripts/run/board/run-board-render-slot.ts +50 -0
  722. package/scripts/run/board/run-board-render.ts +407 -0
  723. package/scripts/run/board/run-board-scope.ts +17 -0
  724. package/scripts/run/board/run-board-screen.ts +43 -0
  725. package/scripts/run/board/run-board-span.ts +66 -0
  726. package/scripts/run/board/run-board-spin.ts +115 -0
  727. package/scripts/run/board/run-board-state.ts +113 -0
  728. package/scripts/run/board/run-board-status.ts +279 -0
  729. package/scripts/run/board/run-board-tick.ts +210 -0
  730. package/scripts/run/board/run-board-track.ts +22 -0
  731. package/scripts/run/board/run-board-usage-read.ts +255 -0
  732. package/scripts/run/board/run-board-usage-rusage.ts +124 -0
  733. package/scripts/run/board/run-board-usage-text.ts +80 -0
  734. package/scripts/run/board/run-board-usage.ts +165 -0
  735. package/scripts/run/carry/run-carry-added.ts +62 -0
  736. package/scripts/run/carry/run-carry-args.ts +25 -22
  737. package/scripts/run/carry/run-carry-change.ts +1 -1
  738. package/scripts/run/carry/run-carry-cli.ts +71 -48
  739. package/scripts/run/carry/run-carry-conversation.ts +6 -7
  740. package/scripts/run/carry/run-carry-ended.ts +85 -0
  741. package/scripts/run/carry/run-carry-reclaim.ts +1 -1
  742. package/scripts/run/carry/run-carry-stash.ts +3 -2
  743. package/scripts/run/carry/run-carry-streak.ts +8 -10
  744. package/scripts/run/carry/run-carry.ts +85 -89
  745. package/scripts/run/cut/run-cut-args.ts +7 -7
  746. package/scripts/run/cut/run-cut-cli.ts +68 -37
  747. package/scripts/run/cut/run-cut-handoff.ts +15 -15
  748. package/scripts/run/cut/run-cut-report.ts +37 -16
  749. package/scripts/run/cut/run-cut.ts +63 -77
  750. package/scripts/run/detached-launch.ts +35 -50
  751. package/scripts/run/entry/run-entry-cli.ts +48 -27
  752. package/scripts/run/entry/run-entry-stop.ts +7 -9
  753. package/scripts/run/entry/run-entry.ts +5 -6
  754. package/scripts/run/event/run-event-cli.ts +5 -6
  755. package/scripts/run/event/run-event-filed.ts +69 -0
  756. package/scripts/run/event/run-event-follow.ts +3 -3
  757. package/scripts/run/event/run-event-plan.ts +38 -0
  758. package/scripts/run/event/run-event-render.ts +10 -4
  759. package/scripts/run/event/run-event-scope.ts +47 -18
  760. package/scripts/run/event/run-event-stream-emit.ts +64 -11
  761. package/scripts/run/event/run-event-stream.ts +172 -43
  762. package/scripts/run/event/run-event-watch.ts +4 -6
  763. package/scripts/run/hold/run-hold-cli.ts +65 -62
  764. package/scripts/run/hold/run-hold.ts +88 -46
  765. package/scripts/run/merge/run-merge-cli.ts +116 -77
  766. package/scripts/run/merge/run-merge-collect.ts +107 -0
  767. package/scripts/run/merge/run-merge-steps.ts +112 -65
  768. package/scripts/run/merge/run-merge-token.ts +30 -0
  769. package/scripts/run/merge/run-merge.ts +31 -22
  770. package/scripts/run/progress/run-progress-args.ts +4 -4
  771. package/scripts/run/progress/run-progress-cli.ts +39 -50
  772. package/scripts/run/progress/run-progress-clock.ts +25 -32
  773. package/scripts/run/progress/run-progress-config.ts +6 -9
  774. package/scripts/run/progress/run-progress-read.ts +9 -10
  775. package/scripts/run/progress/run-progress.ts +48 -53
  776. package/scripts/run/review/run-review-cli.ts +6 -6
  777. package/scripts/run/review/run-review-steps.ts +6 -6
  778. package/scripts/run/review/run-review.ts +9 -11
  779. package/scripts/run/run-cli-fault.ts +29 -0
  780. package/scripts/run/run-ending-cli.ts +3 -3
  781. package/scripts/run/run-ending.ts +10 -14
  782. package/scripts/run/run-halfrun-resume.ts +6 -8
  783. package/scripts/run/run-headless.ts +25 -12
  784. package/scripts/run/run-invocation.ts +17 -22
  785. package/scripts/run/run-label.ts +7 -5
  786. package/scripts/run/run-liveness-cli.ts +19 -6
  787. package/scripts/run/run-liveness.ts +27 -38
  788. package/scripts/run/run-next-cli.ts +5 -9
  789. package/scripts/run/run-next.ts +4 -5
  790. package/scripts/run/run-parent-cut-hook.ts +10 -12
  791. package/scripts/run/run-preflight.ts +25 -29
  792. package/scripts/run/run-prep-cli.ts +17 -13
  793. package/scripts/run/run-prep-locate.ts +4 -5
  794. package/scripts/run/run-prep.ts +7 -10
  795. package/scripts/run/run-prrun-resume.ts +2 -2
  796. package/scripts/run/run-report-cli.ts +4 -4
  797. package/scripts/run/run-report.ts +9 -14
  798. package/scripts/run/run-retrospective.ts +3 -3
  799. package/scripts/run/run-section.ts +42 -0
  800. package/scripts/run/run-stage-read.ts +2 -2
  801. package/scripts/run/run-stage.ts +6 -4
  802. package/scripts/run/run-status-cli.ts +7 -5
  803. package/scripts/run/run-status.ts +6 -7
  804. package/scripts/run/run-step-cli.ts +13 -15
  805. package/scripts/run/run-step.ts +62 -48
  806. package/scripts/run/run-stop-notify.ts +7 -8
  807. package/scripts/run/run-stranded-cli.ts +1 -1
  808. package/scripts/run/run-stranded-detect.ts +4 -4
  809. package/scripts/run/run-stranded.ts +11 -13
  810. package/scripts/run/run-tail-cli.ts +15 -16
  811. package/scripts/run/run-tail.ts +14 -33
  812. package/scripts/run/run-watcher-guard-cli.ts +3 -4
  813. package/scripts/run/run-watcher-guard.ts +11 -12
  814. package/scripts/run/run-watcher-hook.ts +6 -12
  815. package/scripts/run/ship/run-ship-cli.ts +67 -33
  816. package/scripts/run/ship/run-ship-detach.ts +15 -13
  817. package/scripts/run/ship/run-ship-lock.ts +1 -1
  818. package/scripts/run/ship/run-ship-next.ts +7 -8
  819. package/scripts/run/ship/run-ship-pre-detach.ts +27 -11
  820. package/scripts/run/ship/run-ship-preflight.ts +10 -11
  821. package/scripts/run/ship/run-ship-probe.ts +4 -4
  822. package/scripts/run/ship/run-ship-return.ts +1 -1
  823. package/scripts/run/ship/run-ship-review-steps.ts +43 -24
  824. package/scripts/run/ship/run-ship-review.ts +12 -14
  825. package/scripts/run/ship/run-ship-scoped.ts +15 -6
  826. package/scripts/run/ship/run-ship-stage.ts +80 -26
  827. package/scripts/run/ship/run-ship-steps.ts +26 -16
  828. package/scripts/run/ship/run-ship-stop-text.ts +4 -2
  829. package/scripts/run/ship/run-ship-sync.ts +9 -8
  830. package/scripts/run/ship/run-ship.ts +17 -32
  831. package/scripts/run/tidy/run-tidy-cli.ts +9 -5
  832. package/scripts/run/tidy/run-tidy-lanes.ts +18 -7
  833. package/scripts/run/tidy/run-tidy-stashes.ts +8 -8
  834. package/scripts/run/tidy/run-tidy.ts +4 -3
  835. package/scripts/run/wake/run-wake-cli.ts +27 -33
  836. package/scripts/run/wake/run-wake-describe.ts +76 -29
  837. package/scripts/run/wake/run-wake-driver.ts +14 -14
  838. package/scripts/run/wake/run-wake-handoff.ts +6 -6
  839. package/scripts/run/wake/run-wake-loop.ts +13 -21
  840. package/scripts/run/wake/run-wake-restart.ts +4 -5
  841. package/scripts/run/wake/run-wake-session.ts +23 -27
  842. package/scripts/run/wake/run-wake.ts +57 -328
  843. package/scripts/safe-chain/ci-installer-pin.ts +3 -3
  844. package/scripts/safe-chain/pack-hook.ts +2 -2
  845. package/scripts/safe-chain/preinstall-command.ts +2 -2
  846. package/scripts/security/security-audit-logic.ts +1 -1
  847. package/scripts/security/security-audit-provision-logic.ts +1 -1
  848. package/scripts/security/security-audit-provision.ts +2 -2
  849. package/scripts/security/security-audit.ts +5 -5
  850. package/scripts/security/security-updates-logic.ts +2 -3
  851. package/scripts/security/security-updates.ts +2 -4
  852. package/scripts/self-sync-guard/index.ts +1 -1
  853. package/scripts/self-sync-guard/self-sync-guard-logic.ts +2 -2
  854. package/scripts/self-sync-guard/self-sync-refusal.ts +1 -1
  855. package/scripts/sonar/sonar-hotspots-cli.ts +1 -1
  856. package/scripts/sonar/sonar-hotspots.ts +1 -1
  857. package/scripts/sonar/sonar-new-code-cli.ts +1 -1
  858. package/scripts/sonar/sonar-new-code.ts +1 -1
  859. package/scripts/sonar/sonar-project.ts +1 -1
  860. package/scripts/split/split-assess-cli.ts +1 -1
  861. package/scripts/split/split-assess.ts +3 -3
  862. package/scripts/sync/directory-copy-guard.ts +2 -3
  863. package/scripts/sync/managed-config-scope-cli.ts +1 -2
  864. package/scripts/sync/managed-config-scope.ts +4 -4
  865. package/scripts/sync/plugin-skill-directories.ts +2 -2
  866. package/scripts/sync/reconcile-templates.ts +17 -8
  867. package/scripts/sync/removed-skill-manifest.ts +2 -3
  868. package/scripts/sync/sync-ai-files.ts +7 -7
  869. package/scripts/sync/sync-configs.ts +30 -3
  870. package/scripts/sync/sync-hook-safety.ts +2 -2
  871. package/scripts/sync/sync.ts +23 -10
  872. package/scripts/sync/synced-paths.ts +2 -1
  873. package/scripts/sync/workflow-pin-logic.ts +1 -1
  874. package/scripts/test/test-declared-changed.ts +4 -4
  875. package/scripts/test/test-declared-logic.ts +2 -3
  876. package/scripts/test/test-declared-match.ts +25 -4
  877. package/scripts/test/test-declared.ts +26 -9
  878. package/scripts/test/test-red-commit.ts +3 -2
  879. package/scripts/test/test-red-logic.ts +7 -14
  880. package/scripts/test/test-red.ts +12 -47
  881. package/scripts/test/test-related-scope.ts +2 -3
  882. package/scripts/test/test-related.ts +3 -3
  883. package/scripts/test/test-type-logic.ts +1 -2
  884. package/scripts/test/test-unit-guard.ts +13 -17
  885. package/scripts/test/unit-worker-share.ts +7 -8
  886. package/scripts/time-runtime/time-agent-bundles.ts +2 -4
  887. package/scripts/time-runtime/time-background.ts +17 -21
  888. package/scripts/time-runtime/time-batch-guard.ts +67 -342
  889. package/scripts/time-runtime/time-bundle-call.ts +26 -28
  890. package/scripts/time-runtime/time-bundles.ts +11 -12
  891. package/scripts/time-runtime/time-call-identity.ts +1 -1
  892. package/scripts/time-runtime/time-command-key.ts +2 -2
  893. package/scripts/time-runtime/time-density-hook.ts +8 -11
  894. package/scripts/time-runtime/time-density.ts +5 -5
  895. package/scripts/time-runtime/time-followup-stage.ts +7 -7
  896. package/scripts/time-runtime/time-format.ts +5 -5
  897. package/scripts/time-runtime/time-hook-transcript.ts +3 -3
  898. package/scripts/time-runtime/time-instant.ts +1 -1
  899. package/scripts/time-runtime/time-markers.ts +15 -19
  900. package/scripts/time-runtime/time-phase-names.ts +3 -3
  901. package/scripts/time-runtime/time-reported-failure.ts +15 -19
  902. package/scripts/time-runtime/time-round-trips.ts +20 -23
  903. package/scripts/time-runtime/time-shell.ts +8 -8
  904. package/scripts/time-runtime/time-single-check.ts +1 -2
  905. package/scripts/time-runtime/time-spans.ts +35 -40
  906. package/scripts/time-runtime/time-tool-call.ts +15 -16
  907. package/scripts/time-runtime/time-transcript-line.ts +53 -34
  908. package/scripts/time-runtime/time-writes.ts +5 -5
  909. package/scripts/ui/ui-routes-cli.ts +1 -2
  910. package/scripts/ui/ui-routes.ts +1 -2
  911. package/scripts/version/bump-version.ts +1 -1
  912. package/scripts/version/fresh-metadata-cache.ts +2 -2
  913. package/scripts/version/latest-corepack.ts +129 -98
  914. package/scripts/version/latest-lane-guard.ts +1 -1
  915. package/scripts/version/latest-scope-cli.ts +2 -2
  916. package/scripts/version/latest-stamp.ts +1 -2
  917. package/scripts/version/latest-update.ts +2 -2
  918. package/scripts/version/npm-registry.ts +2 -2
  919. package/scripts/version/package-manager-version.ts +18 -0
  920. package/scripts/version/publishable-range-check.ts +2 -1
  921. package/scripts/version/publishable-range.ts +1 -1
  922. package/scripts/version/release-age.ts +11 -11
  923. package/scripts/version/release-hold.ts +2 -2
  924. package/scripts/version/safe-chain-version-update.ts +3 -3
  925. package/scripts/version/version-check-logic.ts +2 -3
  926. package/scripts/version/version-check.ts +1 -2
  927. package/scripts/version/version-command-config.ts +2 -2
  928. package/scripts/version/version-commands.ts +3 -3
  929. package/scripts/version/version-remote.ts +4 -4
  930. package/scripts/version/version-targets.ts +2 -2
  931. package/templates/gitignore +7 -0
  932. package/templates/workflows/github-release.yml +4 -0
  933. package/dist/hooks/chunk-NV2JRZZO.js +0 -6385
  934. package/dist/hooks/chunk-RKUAD3I6.js +0 -90
  935. package/dist/hooks/chunk-WPALEIRX.js +0 -18
  936. package/scripts/backlog/backlog-restructure.ts +0 -152
  937. package/scripts/rules/issue-fold-rule.ts +0 -72
  938. package/scripts/rules/wip-cap.ts +0 -63
  939. package/scripts/run/run-issue-number.ts +0 -19
@@ -0,0 +1,58 @@
1
+ import { DEPTH_0_LABEL, RELEASE_LABEL } from './issue-labels'
2
+
3
+ // The decisions behind `josh issue:release`, kept apart from the command
4
+ // that reads the network so each is a pure answer a test can pin. An Issue whose change reaches a
5
+ // consumer only once published is linked to the repository's release Issue, which it blocks until it
6
+ // merges.
7
+
8
+ interface ListingRow {
9
+ number: number
10
+ }
11
+
12
+ function is_listing_row(value: unknown): value is ListingRow {
13
+ if (typeof value !== 'object' || value === null) return false
14
+
15
+ return Number.isSafeInteger(Reflect.get(value, 'number'))
16
+ }
17
+
18
+ // The open release Issue a listing of `release`-labelled Issues names, or `undefined` when it names
19
+ // none or is unreadable. One release publishes every merge since the last, so a repository holds one
20
+ // release Issue at a time; were a person to open a second, the oldest is the one the next release
21
+ // closes, so it is the one every new blocker joins.
22
+ function open_release_of(json: string): number | undefined {
23
+ try {
24
+ const parsed: unknown = JSON.parse(json)
25
+ const rows = Array.isArray(parsed) ? parsed.filter((row) => is_listing_row(row)) : []
26
+
27
+ return rows.length === 0 ? undefined : Math.min(...rows.map((row) => row.number))
28
+ } catch {
29
+ return undefined
30
+ }
31
+ }
32
+
33
+ function title_of(repo: string): string {
34
+ return `Release ${repo} (next version)`
35
+ }
36
+
37
+ // Plain English with no classification declaration: the Issue is not filed through `issue:file`, and
38
+ // its labels are `RELEASE_LABELS` rather than read off the body.
39
+ function body_of(repo: string): string {
40
+ return [
41
+ `Tracks the next release of ${repo}.`,
42
+ '',
43
+ 'Every Issue this one is blocked by changes something a consumer can use only once it is published. Once they have merged, a person runs `pnpm josh release` in the primary checkout.',
44
+ '',
45
+ 'Close this Issue once that release is published: the next blocker files a new one, so an open release Issue names only unreleased work.',
46
+ '',
47
+ '`auto-ok` is never applied to this Issue by a run; a person may apply it.',
48
+ '',
49
+ ].join('\n')
50
+ }
51
+
52
+ // The release label and a depth: the subject of a release is what a consumer touches.
53
+ // Never `auto-ok`.
54
+ const RELEASE_LABELS: ReadonlyArray<string> = [RELEASE_LABEL, DEPTH_0_LABEL]
55
+
56
+ const issue_release = { RELEASE_LABELS, open_release_of, title_of, body_of }
57
+
58
+ export { issue_release }
@@ -1,6 +1,7 @@
1
1
  import { capped_output } from '#scripts/document/capped-print'
2
+ import { session_cite } from './session-cite'
2
3
 
3
- // The failure report `issue:read` and `issue:state` share (joshuafolkken/kit#3046). Both read a batch
4
+ // The failure report `issue:read` and `issue:state` share. Both read a batch
4
5
  // of numbers, print a block for each one that answered, and name every one that did not; only the
5
6
  // result kind that counts as an answer and what a gap must not be mistaken for differ between them.
6
7
 
@@ -25,7 +26,7 @@ interface FailureTerms<K extends string> {
25
26
  }
26
27
 
27
28
  // Under the Bash output cap, or as part files past it — a batch of long threads is the shape that
28
- // overflowed (joshuafolkken/kit#3143).
29
+ // overflowed.
29
30
  function print_blocks(blocks: ReadonlyArray<string>, separator: string, label: string): void {
30
31
  if (blocks.length === 0) return
31
32
 
@@ -37,10 +38,12 @@ function print_blocks(blocks: ReadonlyArray<string>, separator: string, label: s
37
38
  // caller's next move differs: a gap is retried, an answer is not.
38
39
  function report_failure(kind: ReadFailureKind, issue_number: string, misreading: string): void {
39
40
  if (kind === 'missing') {
40
- console.error(`✖ issue #${issue_number} does not resolve — check the number and the repository`)
41
+ console.error(
42
+ `✖ issue ${session_cite.issue(issue_number)} does not resolve — check the number and the repository`,
43
+ )
41
44
  } else {
42
45
  console.error(
43
- `✖ could not read issue #${issue_number} — a rate limit, expired auth, or a dropped connection. This is not "${misreading}"`,
46
+ `✖ could not read issue ${session_cite.issue(issue_number)} — a rate limit, expired auth, or a dropped connection. This is not "${misreading}"`,
44
47
  )
45
48
  }
46
49
  }
@@ -15,13 +15,14 @@ import {
15
15
  type ScoutIssue,
16
16
  } from './issue-scout'
17
17
  import { issue_scout_closed, type ClosedScan } from './issue-scout-closed'
18
+ import { session_cite } from './session-cite'
18
19
 
19
20
  const { CLOSED_CEILING_LINE, CLOSED_UNREADABLE_LINE, read_recently_closed, warn_about_closed } =
20
21
  issue_scout_closed
21
22
 
22
23
  // `josh issue:scout "<title>" [--body "<summary>"]` — before an issue is filed, answer the two
23
24
  // questions every `new` entry point asks first: has this already been filed, and which epic does it
24
- // belong to (joshuafolkken/kit#1252).
25
+ // belong to.
25
26
  //
26
27
  // Both were assembled by hand every time, differently every time: a measured `fullrun new` spent
27
28
  // 7 minutes 32 seconds — 22% of the run — listing epics, reading their children and searching for
@@ -104,13 +105,13 @@ function draft_of(args: ScoutArguments, repo: string): BacklogIssue {
104
105
  // below decides from prose references, and a title-only draft has none to give it.
105
106
  function format_duplicate(candidate: DuplicateCandidate): string {
106
107
  const score = candidate.is_referenced === true ? 'ref' : candidate.score.toFixed(SCORE_DIGITS)
107
- const epic = candidate.epic === undefined ? '' : ` (epic #${String(candidate.epic)})`
108
+ const epic = candidate.epic === undefined ? '' : ` (epic ${session_cite.issue(candidate.epic)})`
108
109
  // The reader does two different things with the two states, so the row has to say which it is: an
109
110
  // open candidate means somebody is already tracking this, a closed one means it may already be
110
111
  // done — and the second is the exit `issue-comments.md` names, not a second filing.
111
112
  const closed = candidate.is_closed === true ? ' (closed)' : ''
112
113
 
113
- return ` #${String(candidate.number)} ${score} ${candidate.title}${closed}${epic}`
114
+ return ` ${session_cite.issue(candidate.number)} ${score} ${candidate.title}${closed}${epic}`
114
115
  }
115
116
 
116
117
  // Weak matches are not padding for an empty answer: a list nobody trusts is read once and skipped
@@ -147,7 +148,7 @@ const NO_EPIC_LINE = 'Epic: none — file it standalone; nothing open shares a r
147
148
  function format_epic(decision: BundleDecision): Array<string> {
148
149
  const lines = [`Epic: ${epic_bundle_cli.ACTION_LINES[decision.action] ?? ''}`]
149
150
 
150
- if (decision.epic !== undefined) lines.push(` Target epic: #${String(decision.epic)}`)
151
+ if (decision.epic !== undefined) lines.push(` Target epic: ${session_cite.issue(decision.epic)}`)
151
152
 
152
153
  if (decision.candidates.length > 0) {
153
154
  lines.push(` Related: ${epic_bundle_cli.format_numbers(decision.candidates)}`)
@@ -168,9 +169,9 @@ const NO_REFERENCE_LINE =
168
169
  'Epic: not asked — no issue number in the summary. Pass --body "…#<N>…", or take the epic printed beside a duplicate above.'
169
170
 
170
171
  // Every placing verdict above asserts that no epic already tracks the draft's relatives, and a cut
171
- // epic listing cannot support that: `epic:bundle` withholds them for it (joshuafolkken/kit#1697),
172
+ // epic listing cannot support that: `epic:bundle` withholds them for it,
172
173
  // while this command drew the same lines out of `ACTION_LINES` and never passed through the gate that
173
- // does (joshuafolkken/kit#1703). The verdict is `epic:bundle`'s own, reused rather than restated, with
174
+ // does. The verdict is `epic:bundle`'s own, reused rather than restated, with
174
175
  // only the `Epic:` label the rest of this report is read by put in front of it.
175
176
  function format_unconfirmed_epic(decision: BundleDecision): string {
176
177
  const related = epic_bundle_cli.format_numbers(decision.candidates)
@@ -245,7 +246,7 @@ function format_epic_answer(
245
246
  // The closed rows reach the duplicate half only. `decide_bundle` places a draft among issues that
246
247
  // are still being worked on, and a closed one can neither gain a sibling nor be recommended as an
247
248
  // epic — so widening the placement pool with them would answer a different question from the one it
248
- // was asked (joshuafolkken/kit#1679).
249
+ // was asked.
249
250
  function duplicates_of(
250
251
  draft: BacklogIssue,
251
252
  issues: ReadonlyArray<BacklogIssue>,
@@ -292,8 +293,7 @@ function qualify_duplicate_report(report_text: string, is_incomplete: boolean):
292
293
  }
293
294
 
294
295
  // The report a run copies into its reply, with every `#N` in the `Related:` / `Target epic:` /
295
- // duplicate listings linkified so the references it carries are clickable rather than bare
296
- // (joshuafolkken/kit#2329).
296
+ // duplicate listings linkified so the references it carries are clickable rather than bare.
297
297
  function linkified_report(
298
298
  draft: BacklogIssue,
299
299
  widened: Widened,
@@ -315,7 +315,7 @@ function linkified_report(
315
315
  }
316
316
 
317
317
  // The scan's answer in both shapes it is read in: the report a person reads, and the candidate numbers
318
- // `issue:file` holds a filing to (joshuafolkken/kit#2808).
318
+ // `issue:file` holds a filing to.
319
319
  interface ScoutOutcome {
320
320
  report: string
321
321
  candidates: ReadonlyArray<number>
@@ -335,7 +335,7 @@ async function scout(args: ScoutArguments, repo: string): Promise<ScoutOutcome |
335
335
 
336
336
  const draft = draft_of(args, repo)
337
337
  // A reference the open listing cannot show — the parent that merged minutes ago — is read directly,
338
- // the same widening `epic:bundle` does and for the same reason (joshuafolkken/kit#947). The closed
338
+ // the same widening `epic:bundle` does and for the same reason. The closed
339
339
  // listing needs nothing from it, so the two requests go out together.
340
340
  const [widened, closed] = await Promise.all([
341
341
  epic_bundle_cli.widen_with_referenced(draft, backlog),
@@ -6,11 +6,11 @@ import { z } from 'zod'
6
6
  import { EPIC_LABEL, has_any_label } from './issue-labels'
7
7
  import type { ScoutIssue } from './issue-scout'
8
8
 
9
- // The closed half of `issue:scout`'s duplicate scan (joshuafolkken/kit#1679), held apart from the CLI
10
- // so the command that reports the scan and the one that files after it (`issue:file`,
11
- // joshuafolkken/kit#2808) read one listing rather than two.
9
+ // The closed half of `issue:scout`'s duplicate scan, held apart from the CLI
10
+ // so the command that reports the scan and the one that files after it (`issue:file`) read one
11
+ // listing rather than two.
12
12
 
13
- // How far back the closed half of the scan reaches (joshuafolkken/kit#1679). One page: the duplicate
13
+ // How far back the closed half of the scan reaches. One page: the duplicate
14
14
  // this half exists to catch closed hours ago, not months, and the listing is ordered by update so
15
15
  // the newest hundred already covers a run's own day several times over.
16
16
  //
@@ -4,7 +4,7 @@
4
4
  // strong signals: the two issues citing each other in prose, or a `blocked-by` recorded between them.
5
5
  // Neither reaches a draft — it has no number, so nothing can cite it and nothing can be recorded
6
6
  // against it — and the question a filing entry actually asks first is a different one: has somebody
7
- // already filed this? (joshuafolkken/kit#1252)
7
+ // already filed this?
8
8
  //
9
9
  // So this is a second signal rather than a change to that threshold. `epic:bundle` deliberately
10
10
  // refuses title resemblance as grounds for *bundling*, because "related" expands without limit; the
@@ -95,8 +95,8 @@ interface ScoutIssue {
95
95
  // already filed as #<E>", and the caller is sent to run an epic that has no implementation of its
96
96
  // own. `epic_bundle.is_strong_signal` excludes them from the other half for the same reason.
97
97
  is_epic?: boolean
98
- // A closed issue is a candidate, and the two are not interchangeable to whoever reads the list
99
- // (joshuafolkken/kit#1679): an open one says "somebody is already tracking this", a closed one
98
+ // A closed issue is a candidate, and the two are not interchangeable to whoever reads the list:
99
+ // an open one says "somebody is already tracking this", a closed one
100
100
  // says "this may already be done". So the state travels with the row rather than being inferred
101
101
  // from which listing it came out of, which the ranking mixes together.
102
102
  is_closed?: boolean
@@ -210,8 +210,7 @@ function compare_candidates(left: DuplicateCandidate, right: DuplicateCandidate)
210
210
  //
211
211
  // Every row is scored — no prefix, no early exit. The issue this search exists to catch is the one
212
212
  // another session filed minutes ago, and where that one sits in the listing is the single thing
213
- // nobody controls (joshuafolkken/kit#1252). Since joshuafolkken/kit#1679 the rows may be closed as
214
- // well as open, and the two rank together: a run about to file has to be shown the strongest match
213
+ // nobody controls. The rows may be closed as well as open, and the two rank together: a run about to file has to be shown the strongest match
215
214
  // there is, and which listing it came out of says nothing about how well it matches.
216
215
  function find_duplicates(
217
216
  title: string,
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env tsx
2
2
  import { fileURLToPath } from 'node:url'
3
3
  import { git_gh_command } from '#scripts/gh/git-gh-command'
4
+ import { issue_number_shape } from '#scripts/issue/issue-number-shape'
4
5
  import { bounded_pool } from '#scripts/lib/bounded-pool'
5
6
  import { cli_flags } from '#scripts/lib/cli-flags'
6
7
  import { issue_report_failures, type ReadFailureKind } from './issue-report-failures'
7
8
  import { issue_state, type IssueState } from './issue-state'
8
9
 
9
10
  // `josh issue:state <N> [<N> ...]` — print each issue's state and labels, in the spelling the
10
- // documents compare against (joshuafolkken/kit#1054; several numbers in one call,
11
- // joshuafolkken/kit#1302).
11
+ // documents compare against, several numbers in one call.
12
12
  //
13
13
  // The numbers are read concurrently and reported together because the callers that need more than
14
14
  // one need them all: `diag`'s ranking table reads a state per row, and one process start plus one
@@ -29,7 +29,6 @@ import { issue_state, type IssueState } from './issue-state'
29
29
 
30
30
  const FAILURE_EXIT_CODE = 1
31
31
  const ARGV_OFFSET = 2
32
- const ISSUE_NUMBER_PATTERN = /^[1-9]\d*$/u
33
32
  const USAGE = 'Usage: josh issue:state <issue-number> [<issue-number> ...] [--repo <owner/repo>]'
34
33
  // A blank line between the blocks of a multi-number report, so a person sees where one issue ends
35
34
  // while a reader matching `issue: ` still finds each block by its first line.
@@ -49,7 +48,7 @@ interface StateRequest {
49
48
  }
50
49
 
51
50
  // One issue's state, or the failure kind. Named for export because `run:prep` reads the state beside
52
- // the body and the dependency-update scope (joshuafolkken/kit#1978), reusing this read rather than a
51
+ // the body and the dependency-update scope, reusing this read rather than a
53
52
  // second one that would drift from the `human_review` decision `parse_issue_state` owns.
54
53
  type StateRead = { kind: 'state'; state: IssueState } | { kind: ReadFailureKind }
55
54
 
@@ -59,10 +58,9 @@ interface IssueReport {
59
58
  }
60
59
 
61
60
  // The read goes through `cli_flags`, both spellings gh itself accepts included (`--repo owner/repo`,
62
- // `--repo=owner/repo`), and is strict (joshuafolkken/kit#3261). An unrecognized flag refuses the
63
- // call: `--rep=owner/repo` used to be discarded for starting with a dash, so the call fell back to
64
- // the session's repository and printed a confident state for a *different* repository's issue of
65
- // that number (joshuafolkken/kit#1355).
61
+ // `--repo=owner/repo`), and is strict. An unrecognized flag refuses the
62
+ // call: discarding `--rep=owner/repo` for starting with a dash would fall back to the session's
63
+ // repository and print a confident state for a *different* repository's issue of that number.
66
64
  const OPTIONS = { repo: { type: 'string', multiple: true } } as const
67
65
 
68
66
  // `absent` and "given but with nothing usable" are different answers. Falling back to the session's
@@ -81,7 +79,8 @@ function read_repo(given: ReadonlyArray<string> | undefined): { repo?: string }
81
79
  // unanswered. `#1262` copied out of a `diag` table is exactly that token.
82
80
  function is_issue_numbers(positionals: ReadonlyArray<string>): boolean {
83
81
  return (
84
- positionals.length > 0 && positionals.every((argument) => ISSUE_NUMBER_PATTERN.test(argument))
82
+ positionals.length > 0 &&
83
+ positionals.every((argument) => issue_number_shape.is_issue_number(argument))
85
84
  )
86
85
  }
87
86
 
@@ -167,7 +166,15 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
167
166
  process.exitCode = await run(argv)
168
167
  }
169
168
 
170
- const issue_state_cli = { STATE_FIELDS, USAGE, main, parse_request, read_issue, run }
169
+ const issue_state_cli = {
170
+ READ_CONCURRENCY,
171
+ STATE_FIELDS,
172
+ USAGE,
173
+ main,
174
+ parse_request,
175
+ read_issue,
176
+ run,
177
+ }
171
178
 
172
179
  if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
173
180
 
@@ -1,24 +1,23 @@
1
- import { parse_json_object_safe } from '#scripts/git/parse-json-array'
1
+ import { parse_json_object_or_undefined } from '#scripts/git/parse-json-array'
2
2
  import { z } from 'zod'
3
3
  import { has_any_label, NEEDS_HUMAN_REVIEW_LABEL } from './issue-labels'
4
4
 
5
5
  // The answer `josh issue:state` prints, kept apart from the reading and the printing so the shape of
6
- // the report is decided by one pure function (joshuafolkken/kit#1054).
6
+ // the report is decided by one pure function.
7
7
  //
8
- // The command exists because the *instructions* needed one. `gh issue view <N> --json state` is what
9
- // an unattended epic run was told to type to confirm a delegated child, and gh answers that call
10
- // over GraphQL — which a cloud session is refused (403). The REST endpoint is served normally, but
11
- // it reports `open` / `closed` in lower case, so writing the REST call into the documents would have
12
- // copied the casing rule out of `git-gh-rest-state.ts` and into prose. Routing the instruction
13
- // through a command keeps that rule in the one place joshuafolkken/kit#1024 put it.
8
+ // The command exists because the *instructions* need one. `gh issue view <N> --json state` goes over
9
+ // GraphQL — which a cloud session is refused (403). The REST endpoint is served normally, but it
10
+ // reports `open` / `closed` in lower case, so writing the REST call into the documents would copy the
11
+ // casing rule out of `git-gh-rest-state.ts` and into prose. Routing the instruction through a command
12
+ // keeps that rule in one place.
14
13
 
15
14
  const NO_LABELS = '(none)'
16
15
  const LABEL_SEPARATOR = ', '
17
16
  const STATE_LABEL = 'state: '
18
17
  const LABELS_LABEL = 'labels: '
19
18
  // Whether this issue is one a run must stop on before committing. Printed as its own line rather than
20
- // left to a reader matching `needs-human-review` against the `labels:` line above
21
- // (joshuafolkken/kit#1132): GitHub keeps the spelling a label was created with and treats
19
+ // left to a reader matching `needs-human-review` against the `labels:` line above:
20
+ // GitHub keeps the spelling a label was created with and treats
22
21
  // `Needs-Human-Review` as the same label, so an eye comparing against the lowercase string misses it —
23
22
  // and a missed one is a run that does not stop and an artifact that ships, which is the whole thing
24
23
  // the label exists to prevent. Every other workflow label already reaches its decision through
@@ -26,8 +25,8 @@ const LABELS_LABEL = 'labels: '
26
25
  const HUMAN_REVIEW_LABEL_LINE = 'human_review: '
27
26
  const YES = 'yes'
28
27
  const NO = 'no'
29
- // The number a block belongs to, printed above it when several were asked for
30
- // (joshuafolkken/kit#1302). A block carries its own number rather than being matched by position,
28
+ // The number a block belongs to, printed above it when several were asked for.
29
+ // A block carries its own number rather than being matched by position,
31
30
  // because a batch read drops the numbers that resolve to nothing — a `diag` table mixes closed
32
31
  // issues and numbers that never existed — and a positional reading then attributes every block
33
32
  // after the gap to the wrong issue.
@@ -58,7 +57,7 @@ interface IssueState {
58
57
  // the same answer, because printing either as a state is what this command exists to prevent.
59
58
  function parse_issue_state(json: string): IssueState | undefined {
60
59
  try {
61
- const parsed = parse_json_object_safe(json, issue_state_schema)
60
+ const parsed = parse_json_object_or_undefined(json, issue_state_schema)
62
61
 
63
62
  if (parsed === undefined) return undefined
64
63
 
@@ -1,11 +1,11 @@
1
- import { delivered_rules } from '#scripts/rules/delivered-rules'
2
1
  import { INTERRUPT_ROUTE_LABEL, SPLIT_ROUTE_LABEL, TIER_A_ROUTE_LABEL } from './issue-labels'
3
2
 
4
- // The WIP cap at the call that files (joshuafolkken/kit#3181). The count used to be a hand-run
5
- // `gh api … | wc -l` the agent compared with the cap itself; `josh issue:file` now reads it and asks
6
- // the exemption question before anything is sent, the same hold `--distinct` places on a duplicate.
3
+ // The WIP cap at the call that files. `josh issue:file` reads the count and asks the exemption
4
+ // question before anything is sent, the same hold `--distinct` places on a duplicate.
7
5
  // What stays judgement — whether a filing is exempt — is declared by the route or by `--over-cap`.
8
6
 
7
+ // `WIP_CAP` is the number's single source; `wip-cap.md` states it once and a test pins the two equal.
8
+ const WIP_CAP = 30
9
9
  const WITHIN = 'within'
10
10
  const EXEMPT = 'exempt'
11
11
  const HELD = 'held' as const
@@ -43,13 +43,13 @@ function is_exempt(filing: WipFiling): boolean {
43
43
 
44
44
  // The cap is "more than `WIP_CAP` open", so exactly the cap is still within it.
45
45
  function verdict_of(count: number, filing: WipFiling): WipVerdict {
46
- if (count <= delivered_rules.WIP_CAP) return WITHIN
46
+ if (count <= WIP_CAP) return WITHIN
47
47
 
48
48
  return is_exempt(filing) ? EXEMPT : HELD
49
49
  }
50
50
 
51
51
  function count_line(count: number, repo: string, verdict: WipVerdict): string {
52
- return `wip: ${String(count)} open in ${repo} · cap ${String(delivered_rules.WIP_CAP)} · ${verdict}`
52
+ return `wip: ${String(count)} open in ${repo} · cap ${String(WIP_CAP)} · ${verdict}`
53
53
  }
54
54
 
55
55
  // The listing's JSON is an array of rows; anything else is unreadable rather than zero, because zero
@@ -64,7 +64,7 @@ function count_of(json: string): number | undefined {
64
64
  }
65
65
  }
66
66
 
67
- const issue_wip = { HELD, HELD_MESSAGE, UNREAD_MESSAGE, verdict_of, count_line, count_of }
67
+ const issue_wip = { WIP_CAP, HELD, HELD_MESSAGE, UNREAD_MESSAGE, verdict_of, count_line, count_of }
68
68
 
69
69
  export type { WipVerdict }
70
70
  export { issue_wip }
@@ -1,5 +1,5 @@
1
- // The body lines that sit under one `## heading`, up to the next `## heading` or the end
2
- // (joshuafolkken/kit#2212). Both the firing-point check and the baseline parser read a section this
1
+ // The body lines that sit under one `## heading`, up to the next `## heading` or the end.
2
+ // Both the firing-point check and the baseline parser read a section this
3
3
  // way, so the slicing lives in one place rather than being written twice.
4
4
 
5
5
  const HEADING_PREFIX = '## '
@@ -54,7 +54,7 @@ function has_line(body: string, text: string): boolean {
54
54
 
55
55
  // The lines between the first unfenced line `is_target` accepts and the next unfenced `## ` heading,
56
56
  // trimmed of the heading line itself; an empty array when no line is accepted. A `## ` line inside a
57
- // code fence is example text, so it neither opens nor closes a section (joshuafolkken/kit#3066).
57
+ // code fence is example text, so it neither opens nor closes a section.
58
58
  function section_lines_matching(
59
59
  body: string,
60
60
  is_target: (line: string) => boolean,
@@ -2,18 +2,20 @@
2
2
  import { execSync } from 'node:child_process'
3
3
  import { fileURLToPath } from 'node:url'
4
4
  import { git_gh_issue_read } from '#scripts/gh/git-gh-issue-read'
5
- import { parse_json_object_safe } from '#scripts/git/parse-json-array'
5
+ import { parse_json_object_or_undefined } from '#scripts/git/parse-json-array'
6
+ import { issue_number_shape } from '#scripts/issue/issue-number-shape'
6
7
  import { error_text } from '#scripts/lib/error-message'
7
8
  import { observation_ledger_home } from '#scripts/observations/observation-ledger-home'
8
9
  import { z } from 'zod'
9
10
  import { baseline_measure, type Baseline } from './baseline-measure'
11
+ import { session_cite } from './session-cite'
10
12
 
11
13
  // `josh measure:rerun <N>` — read a behavior-change Issue body after merge, re-run each baseline
12
- // command, and print the before/after pair (joshuafolkken/kit#2212). A value that did not move means
14
+ // command, and print the before/after pair. A value that did not move means
13
15
  // the premise the rule rested on is refuted, so a line is appended to the observation ledger — reusing
14
16
  // that append-only, same-key mechanism rather than a second one.
15
17
  //
16
- // **The baseline is shell, and the body is written by whoever filed the Issue** (joshuafolkken/kit#3064).
18
+ // **The baseline is shell, and the body is written by whoever filed the Issue**.
17
19
  // A baseline needs pipes and loops (`git log … | wc -l`, `for d in $(ls …)`), so an allow-list of
18
20
  // commands cannot make it safe; what can is who wrote it. The input is therefore the Issue number, not
19
21
  // a file, so the author's `author_association` arrives with the body from the same REST read, and only
@@ -21,7 +23,6 @@ import { baseline_measure, type Baseline } from './baseline-measure'
21
23
 
22
24
  const FAILURE_EXIT_CODE = 1
23
25
  const ARGV_OFFSET = 2
24
- const ISSUE_NUMBER_PATTERN = /^[1-9]\d*$/u
25
26
  const ISSUE_FIELDS = 'body,author_association'
26
27
  const TRUSTED_ASSOCIATIONS: ReadonlySet<string> = new Set(['OWNER', 'MEMBER', 'COLLABORATOR'])
27
28
  const TRUSTED_LIST = [...TRUSTED_ASSOCIATIONS].join(' / ')
@@ -71,7 +72,7 @@ async function append_ledger(lines: ReadonlyArray<string>, now: Date): Promise<v
71
72
  if (lines.length === 0) return
72
73
 
73
74
  // The running work tree's file for the checked-out issue, a lane's inside a lane — the run's own
74
- // commit carries it (joshuafolkken/kit#2919).
75
+ // commit carries it.
75
76
  const ledger_path = await observation_ledger_home.writer_path(now)
76
77
 
77
78
  await observation_ledger_home.append(ledger_path, lines)
@@ -85,7 +86,7 @@ function today(now: Date): string {
85
86
  async function read_issue(issue_number: string): Promise<IssueFields | undefined> {
86
87
  const json = await git_gh_issue_read.issue_view_json(issue_number, ISSUE_FIELDS)
87
88
 
88
- return json === undefined ? undefined : parse_json_object_safe(json, issue_schema)
89
+ return json === undefined ? undefined : parse_json_object_or_undefined(json, issue_schema)
89
90
  }
90
91
 
91
92
  // The body, only when its author can write to the repository. A read that fails is refused as well:
@@ -94,7 +95,7 @@ async function read_trusted_body(issue_number: string): Promise<BodyRead> {
94
95
  const issue = await read_issue(issue_number)
95
96
 
96
97
  if (issue === undefined) {
97
- return { kind: 'refused', reason: `could not read issue #${issue_number}` }
98
+ return { kind: 'refused', reason: `could not read issue ${session_cite.issue(issue_number)}` }
98
99
  }
99
100
 
100
101
  const association = issue.author_association ?? UNKNOWN_ASSOCIATION
@@ -102,7 +103,7 @@ async function read_trusted_body(issue_number: string): Promise<BodyRead> {
102
103
  if (!TRUSTED_ASSOCIATIONS.has(association)) {
103
104
  return {
104
105
  kind: 'refused',
105
- reason: `refusing to run the baseline of #${issue_number}: its author is ${association}, not ${TRUSTED_LIST}`,
106
+ reason: `refusing to run the baseline of ${session_cite.issue(issue_number)}: its author is ${association}, not ${TRUSTED_LIST}`,
106
107
  }
107
108
  }
108
109
 
@@ -130,7 +131,7 @@ async function rerun(body: string, now: Date): Promise<number> {
130
131
  }
131
132
 
132
133
  async function run(issue_number: string | undefined, now: Date): Promise<number> {
133
- if (issue_number === undefined || !ISSUE_NUMBER_PATTERN.test(issue_number)) {
134
+ if (issue_number === undefined || !issue_number_shape.ISSUE_NUMBER_PATTERN.test(issue_number)) {
134
135
  console.error(USAGE)
135
136
 
136
137
  return FAILURE_EXIT_CODE
@@ -1,8 +1,8 @@
1
1
  import { markdown_section } from './markdown-section'
2
2
 
3
3
  // A defect-claiming (behavior-change) Issue's reproduction section is written as `command + actual
4
- // output`, never prose, so the claim rests on a run that can be repeated rather than on a reading
5
- // (joshuafolkken/kit#2353). This is the counterpart of `baseline-measure.ts`: the baseline is a
4
+ // output`, never prose, so the claim rests on a run that can be repeated rather than on a reading.
5
+ // This is the counterpart of `baseline-measure.ts`: the baseline is a
6
6
  // distilled `command -> value`, the reproduction is the raw command *and* the output block it printed
7
7
  // — a prose "I checked it" is refused for the same reason a prose baseline is, it cannot be re-run.
8
8
 
@@ -38,7 +38,7 @@ function has_output_block(lines: ReadonlyArray<string>): boolean {
38
38
  }
39
39
 
40
40
  // The heading is a parameter so every `command + actual output` section is read by this one parser —
41
- // a pull request's live-execution evidence section is the same shape (joshuafolkken/kit#2446).
41
+ // a pull request's live-execution evidence section is the same shape.
42
42
  function parse_reproduction(body: string, heading: string = REPRODUCTION_HEADING): Reproduction {
43
43
  const lines = markdown_section.section_lines(body, heading)
44
44
 
@@ -0,0 +1,56 @@
1
+ import { repo_discovery } from '#scripts/discovery/repo-discovery'
2
+ import { repo_origin } from '#scripts/discovery/repo-origin'
3
+ import { issue_citation } from '#scripts/rules/issue-citation'
4
+ import { issue_cite } from './issue-cite'
5
+
6
+ // How a josh command names an Issue in what it prints to the session.
7
+ //
8
+ // **A line a command prints is a line a session copies.** A run quotes a progress line, a warning or a
9
+ // refusal into its reply verbatim, and a bare `#N` in that line reaches the reply as a bare `#N` — which
10
+ // the Stop guard then sends back for a second turn spent re-citing it. Printing the citation form at the
11
+ // source makes the cheap path and the correct path the same one, the reasoning `issue:cite` itself was
12
+ // built on.
13
+ //
14
+ // **The repository is read from the work tree's own `origin`, not asked of `gh`.** Most printing sites
15
+ // hold no `owner/repo`, and a network read per printed line would put a round trip — and a way to fail
16
+ // — into every warning. The config is a local file (`repo_discovery.read_origin_url`), and it is the
17
+ // same remote `gh` expands `{owner}/{repo}` from, so the link points at the repository the command acts
18
+ // on. A work tree with no GitHub origin falls back to the plain `#N`, the same fallback `reference` has.
19
+ //
20
+ // **The title is used when the caller already holds it, and never fetched.** A link without a title
21
+ // still resolves to the Issue in one click and passes the Stop guard as cited; fetching a title per line
22
+ // would cost the `gh` call this module exists to avoid.
23
+ //
24
+ // **A line assembled elsewhere is linked where it is printed.** A summary, a report or a list built by
25
+ // a helper that also feeds GitHub or a parser holds `issue_cite.plain`; `text` links every bare `#N` in
26
+ // it at the print boundary, the same `issue_citation.linkify` pass the listings already print through.
27
+
28
+ // `owner/repo` of the repository the command runs in, or `undefined` without a GitHub `origin`.
29
+ function session_repo(): string | undefined {
30
+ const url = repo_discovery.read_origin_url(process.cwd())
31
+ const identity = url === undefined ? undefined : repo_origin.parse_origin_url(url)
32
+
33
+ return identity === undefined ? undefined : `${identity.owner}/${identity.repo}`
34
+ }
35
+
36
+ // One Issue as a session reads it: `[#N](url) — title` with a title, `[#N](url)` without one. `repo`
37
+ // names another repository's Issue; it defaults to the one the command runs in.
38
+ function issue(number: number | string, title?: string, repo = session_repo()): string {
39
+ return issue_cite.reference(repo, String(number), title)
40
+ }
41
+
42
+ // `message` as a session reads it: every bare `#N` linked to the repository the command runs in, left
43
+ // as it is without a GitHub `origin`.
44
+ function text(message: string): string {
45
+ const repo = session_repo()
46
+
47
+ return repo === undefined ? message : issue_citation.linkify(message, repo)
48
+ }
49
+
50
+ const session_cite = {
51
+ issue,
52
+ session_repo,
53
+ text,
54
+ }
55
+
56
+ export { session_cite }
@@ -1,24 +1,25 @@
1
1
  // The environment variables that name the **parent** agent session, and which a child session must
2
2
  // not inherit.
3
3
  //
4
- // It lived inside `scripts/eval/eval-session.ts` until `josh run:wake` became a second launcher of a
5
- // headless session (joshuafolkken/kit#1719). Two copies of this list is the clone `CLAUDE.md`
4
+ // `scripts/eval/eval-session.ts` and `josh run:wake` both launch a headless session. Two copies of
5
+ // this list is the clone `CLAUDE.md`
6
6
  // prohibits, and this is the shape of clone that fails silently: the copy that drifts does not throw
7
7
  // or lint — the child dials the parent's private socket, is refused, and the session dies as
8
8
  // `API Error: Unable to connect to API (ConnectionRefused)` with nothing anywhere naming the cause.
9
9
  //
10
10
  // `CLAUDE_CODE_MESSAGING_SOCKET` is a UNIX socket only the parent listens on,
11
11
  // `CLAUDE_CODE_MESSAGING_TOKEN` is that socket's credential, and the two session identifiers claim
12
- // the parent's session as the child's own. Measured under joshuafolkken/kit#1158: removing them
13
- // restored 5/5 held in 54 seconds, and lowering the concurrency — the suspected cause before this one
14
- // was found — made it worse.
12
+ // the parent's session as the child's own.
15
13
  //
16
14
  // **`SESSION_ID_KEY` is the name Claude Code exports for the running session's own id** — the base
17
15
  // name of that session's transcript file. It is single-sourced here rather than spelled a second time
18
- // where the cost reader identifies its own transcript by it (joshuafolkken/kit#2403): one env var,
16
+ // where the cost reader identifies its own transcript by it: one env var,
19
17
  // one literal, so the list a child must not inherit and the selection that reads it cannot drift.
20
18
  const SESSION_ID_KEY = 'CLAUDE_CODE_SESSION_ID'
21
19
 
20
+ // The pid of the agent session's own process, which a run hold records as its owner.
21
+ const AGENT_PID_KEY = 'CLAUDE_PID'
22
+
22
23
  const PARENT_SESSION_KEYS: ReadonlyArray<string> = [
23
24
  'CLAUDE_CODE_MESSAGING_SOCKET',
24
25
  'CLAUDE_CODE_MESSAGING_TOKEN',
@@ -27,7 +28,7 @@ const PARENT_SESSION_KEYS: ReadonlyArray<string> = [
27
28
  ]
28
29
 
29
30
  // **The second thing a child must not inherit is a proxy that belongs to the invocation which
30
- // launched it** (joshuafolkken/kit#1760). `pnpm josh run:wake --start` runs under whatever wraps this
31
+ // launched it**. `pnpm josh run:wake --start` runs under whatever wraps this
31
32
  // machine's package manager — here a supply-chain scanner, which stands a proxy up on a loopback port
32
33
  // and writes `HTTPS_PROXY=http://localhost:<ephemeral>` plus its own CA into the environment of
33
34
  // everything that invocation spawns. The supervisor is **detached**, so it outlives that proxy and
@@ -158,7 +159,7 @@ function is_scanner_proxy(source: EnvironmentSource): (value: string | undefined
158
159
  }
159
160
  }
160
161
 
161
- // **The proxy half alone, for a spawn that is not a session** (joshuafolkken/kit#2436). kit's `gh`
162
+ // **The proxy half alone, for a spawn that is not a session**. kit's `gh`
162
163
  // requests inherited the same loopback proxy, and the scanner behind it tunnels api.github.com
163
164
  // without inspecting it — so routing GitHub through it protected nothing and added a failure point:
164
165
  // the scanner release installed here marked a host it had once timed out on as dead for the rest of
@@ -176,6 +177,7 @@ function removed_proxy_environment(source: EnvironmentSource = process.env): Rem
176
177
  }
177
178
 
178
179
  const agent_session_environment = {
180
+ AGENT_PID_KEY,
179
181
  LOOPBACK_HOSTS,
180
182
  PARENT_SESSION_KEYS,
181
183
  PROXY_CERTIFICATE_KEY,