@joshuafolkken/kit 1.1166.0 → 1.1229.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 (437) hide show
  1. package/.claude/.claude-plugin/plugin.json +1 -1
  2. package/.claude/settings.json +2 -2
  3. package/.claude/skills/dependency-update/SKILL.md +4 -8
  4. package/.claude/skills/epic-commands/SKILL.md +2 -2
  5. package/.claude/skills/epic-commands/epic-bundle.md +1 -1
  6. package/.claude/skills/workflow-commands/SKILL.md +2 -4
  7. package/.claude/skills/workflow-commands/backlogrun-child.md +6 -4
  8. package/.claude/skills/workflow-commands/backlogrun-lanes.md +9 -5
  9. package/.claude/skills/workflow-commands/backlogrun-park.md +29 -9
  10. package/.claude/skills/workflow-commands/backlogrun-progress.md +7 -2
  11. package/.claude/skills/workflow-commands/backlogrun-recovery.md +4 -3
  12. package/.claude/skills/workflow-commands/backlogrun-steps.md +24 -15
  13. package/.claude/skills/workflow-commands/chain-rule.md +1 -1
  14. package/.claude/skills/workflow-commands/delegation.md +2 -2
  15. package/.claude/skills/workflow-commands/followup.md +5 -0
  16. package/.claude/skills/workflow-commands/fullrun-steps.md +1 -1
  17. package/.claude/skills/workflow-commands/halfrun.md +1 -1
  18. package/.claude/skills/workflow-commands/issue-scout.md +1 -1
  19. package/.claude/skills/workflow-commands/kickoff.md +1 -1
  20. package/.claude/skills/workflow-commands/observation-ledger.md +3 -3
  21. package/.claude/skills/workflow-commands/pre-gate-cut.md +10 -5
  22. package/.claude/skills/workflow-commands/prerequisite.md +2 -2
  23. package/.claude/skills/workflow-commands/progress-watcher.md +1 -1
  24. package/.claude/skills/workflow-commands/working-tree-hold.md +1 -1
  25. package/.codex/hooks.json +2 -2
  26. package/.cursorrules +6 -41
  27. package/.github/actions/setup-node/action.yml +1 -1
  28. package/.github/workflows/auto-tag.yml +3 -4
  29. package/.github/workflows/ci.yml +47 -33
  30. package/.github/workflows/dependabot-auto-merge.yml +13 -6
  31. package/.github/workflows/publish.yml +48 -4
  32. package/.github/workflows/sonar-qube.yml +3 -0
  33. package/.pnpmfile.mjs +4 -3
  34. package/.prettierignore +8 -2
  35. package/CLAUDE.md +18 -20
  36. package/README.md +26 -19
  37. package/SECURITY.md +15 -1
  38. package/dist/CLAUDE.md +18 -20
  39. package/dist/commands/document-section-cli.js +734 -0
  40. package/dist/hooks/audit-provision.js +346 -0
  41. package/dist/hooks/batch-guard.js +5 -4
  42. package/dist/hooks/{chunk-DYAVAM6S.js → chunk-55HHG5PX.js} +1405 -631
  43. package/dist/hooks/{chunk-A6P7PN7P.js → chunk-5VMKCCC4.js} +25 -10
  44. package/dist/hooks/chunk-5VNDSNG3.js +12 -0
  45. package/dist/hooks/{chunk-5KTCMCOT.js → chunk-6HJJXRBX.js} +4 -2
  46. package/dist/hooks/chunk-CDY4NFQG.js +15 -0
  47. package/dist/hooks/chunk-ELCN5LCH.js +135 -0
  48. package/dist/hooks/{chunk-ENA7P5FB.js → chunk-F56MFS4B.js} +3 -3
  49. package/dist/hooks/{chunk-ANJ2WGFD.js → chunk-FIVDHQGT.js} +7 -6
  50. package/dist/hooks/{chunk-3V37IID6.js → chunk-JBBMAPC4.js} +23 -14
  51. package/dist/hooks/{chunk-GU5MATVE.js → chunk-JUDKDCDP.js} +499 -389
  52. package/dist/hooks/{chunk-ZDZ555YH.js → chunk-NV2JRZZO.js} +743 -909
  53. package/dist/hooks/{chunk-V2BTOZHT.js → chunk-RNWHN5BP.js} +3 -3
  54. package/dist/hooks/{chunk-URJA6XY4.js → chunk-TQNPDZNH.js} +4 -4
  55. package/dist/hooks/{chunk-GYNGP7HI.js → chunk-VC3PZPZO.js} +1 -1
  56. package/dist/hooks/codex-hook-adapter.js +14 -12
  57. package/dist/hooks/duplicate-read-guard.js +6 -5
  58. package/dist/hooks/format-edited.js +4 -3
  59. package/dist/hooks/inputs.json +232 -210
  60. package/dist/hooks/investigation-guard.js +6 -5
  61. package/dist/hooks/pretool-guard.js +12 -10
  62. package/dist/hooks/session-lang.js +2 -4
  63. package/dist/hooks/stop-guard.js +81 -59
  64. package/dist/josh.js +872 -75
  65. package/dist/version/index.d.ts +7 -2
  66. package/dist/version/index.js +152 -75
  67. package/eslint/base.js +23 -1
  68. package/eslint/rules/code-quality.js +3 -0
  69. package/eslint/rules/early-return-one-liner.js +98 -0
  70. package/eslint/rules/unicorn.js +16 -1
  71. package/package.json +7 -6
  72. package/pnpm-workspace.yaml +9 -4
  73. package/prettier/basic.d.ts +3 -1
  74. package/prettier/index.d.ts +3 -1
  75. package/prettier/static.d.ts +3 -1
  76. package/prompts/coding-standards.md +1 -1
  77. package/prompts/collaboration-workflow/file-edits.md +4 -4
  78. package/prompts/collaboration-workflow/glossary.md +1 -1
  79. package/prompts/collaboration-workflow/operating-rules.md +17 -9
  80. package/prompts/collaboration-workflow/overview.md +2 -2
  81. package/prompts/collaboration-workflow/principles.md +14 -12
  82. package/prompts/collaboration-workflow/report-format.md +1 -1
  83. package/prompts/collaboration-workflow/residency.md +1 -1
  84. package/prompts/collaboration-workflow/rule-delivery.md +6 -6
  85. package/prompts/collaboration-workflow/shell-body.md +6 -6
  86. package/prompts/collaboration-workflow/turn-batching.md +1 -1
  87. package/prompts/collaboration-workflow/upstream-interrupt.md +12 -2
  88. package/prompts/collaboration-workflow/wip-cap.md +10 -10
  89. package/prompts/review-rubric.md +1 -2
  90. package/prompts/review.md +1 -1
  91. package/scripts/agent/agent-headless.ts +29 -0
  92. package/scripts/agent/agent-launch-environment.ts +6 -2
  93. package/scripts/agent/codex-agent-argv.ts +2 -1
  94. package/scripts/auto-ok/auto-ok-cli.ts +1 -1
  95. package/scripts/backlog/backlog-arrival.ts +3 -3
  96. package/scripts/backlog/backlog-budget.ts +1 -1
  97. package/scripts/backlog/backlog-drive-args.ts +135 -0
  98. package/scripts/backlog/backlog-drive-cli.ts +11 -137
  99. package/scripts/backlog/backlog-drive-launch.ts +39 -0
  100. package/scripts/backlog/backlog-drive-named-offer.ts +3 -5
  101. package/scripts/backlog/backlog-drive-named.ts +3 -3
  102. package/scripts/backlog/backlog-drive-offer-argv.ts +1 -1
  103. package/scripts/backlog/backlog-drive-owner.ts +1 -1
  104. package/scripts/backlog/backlog-drive-restore.ts +1 -1
  105. package/scripts/backlog/backlog-drive-retrospective.ts +1 -1
  106. package/scripts/backlog/backlog-drive.ts +1 -1
  107. package/scripts/backlog/backlog-next.ts +31 -9
  108. package/scripts/backlog/backlog-offer-cli.ts +6 -6
  109. package/scripts/backlog/backlog-offer.ts +1 -1
  110. package/scripts/backlog/backlog-plan-cli.ts +7 -6
  111. package/scripts/backlog/backlog-pool.ts +57 -11
  112. package/scripts/backlog/backlog-rank.ts +18 -9
  113. package/scripts/backlog/backlog-ready.ts +1 -1
  114. package/scripts/backlog/backlog-restructure.ts +152 -0
  115. package/scripts/backlog/backlog-scope.ts +1 -1
  116. package/scripts/backlog/backlog-stalled-detect.ts +2 -2
  117. package/scripts/backlog/backlog-stalled.ts +1 -1
  118. package/scripts/backlog/backlog-waves.ts +15 -17
  119. package/scripts/build/build-codex-hooks.ts +3 -1
  120. package/scripts/build/build-commands.ts +66 -0
  121. package/scripts/build/build-hooks.ts +2 -1
  122. package/scripts/build/build-library.ts +12 -3
  123. package/scripts/build/build.ts +70 -0
  124. package/scripts/build/local-bin.ts +3 -13
  125. package/scripts/cost-runtime/context-cut-threshold.ts +1 -9
  126. package/scripts/cost-runtime/cost-verdict.ts +15 -28
  127. package/scripts/delegation/investigation-reads.ts +3 -1
  128. package/scripts/discovery/repo-origin.ts +5 -5
  129. package/scripts/doctor/doctor-consumer.ts +2 -2
  130. package/scripts/doctor/doctor-io.ts +2 -3
  131. package/scripts/document/capped-print-part.ts +30 -0
  132. package/scripts/document/capped-print.ts +3 -4
  133. package/scripts/document/document-byte-budget.ts +11 -2
  134. package/scripts/document/document-scan.ts +117 -0
  135. package/scripts/document/document-section.ts +143 -16
  136. package/scripts/document/entry-read-budget.ts +5 -3
  137. package/scripts/document/entry-read-set.ts +10 -89
  138. package/scripts/document/read-set-cost.ts +98 -0
  139. package/scripts/epic/epic-add-body.ts +1 -0
  140. package/scripts/epic/epic-audit-checks.ts +1 -1
  141. package/scripts/epic/epic-audit-rationale.ts +4 -3
  142. package/scripts/epic/epic-bundle-cli.ts +14 -3
  143. package/scripts/epic/epic-bundle-poll.ts +41 -0
  144. package/scripts/epic/epic-busy.ts +1 -1
  145. package/scripts/epic/epic-candidate-confirm.ts +3 -2
  146. package/scripts/epic/epic-classify.ts +1 -1
  147. package/scripts/epic/epic-cli-argv.ts +78 -46
  148. package/scripts/epic/epic-cli-remove.ts +11 -19
  149. package/scripts/epic/epic-cli.ts +74 -73
  150. package/scripts/epic/epic-close-comment.ts +1 -1
  151. package/scripts/epic/epic-close.ts +1 -1
  152. package/scripts/epic/epic-cross-repo.ts +5 -5
  153. package/scripts/epic/epic-graph.ts +1 -1
  154. package/scripts/epic/epic-index.ts +1 -1
  155. package/scripts/epic/epic-issue.ts +2 -6
  156. package/scripts/epic/epic-lane-offer.ts +2 -2
  157. package/scripts/epic/epic-next.ts +29 -42
  158. package/scripts/epic/epic-solo-stale.ts +1 -1
  159. package/scripts/epic/epic-triage.ts +8 -4
  160. package/scripts/epic/epic-validate.ts +1 -1
  161. package/scripts/followup/git-followup-finish.ts +2 -2
  162. package/scripts/followup/git-followup-label.ts +2 -2
  163. package/scripts/followup/git-followup-merged.ts +2 -2
  164. package/scripts/followup/git-followup-stages.ts +9 -0
  165. package/scripts/followup/git-pr-followup-checks.ts +142 -0
  166. package/scripts/followup/git-pr-followup.ts +5 -130
  167. package/scripts/gate/core-budget.ts +69 -1
  168. package/scripts/gate/gate-plan.ts +47 -7
  169. package/scripts/gate/gate-skip.ts +38 -7
  170. package/scripts/gate/hook-gate-reuse.ts +12 -10
  171. package/scripts/gate/pre-commit-type-check.ts +4 -1
  172. package/scripts/gate/project-checks.ts +6 -9
  173. package/scripts/gate/type-check-step.ts +2 -3
  174. package/scripts/gate/verification-gate.ts +27 -8
  175. package/scripts/gh/git-gh-api-path.ts +2 -2
  176. package/scripts/gh/git-gh-issue-rest.ts +3 -3
  177. package/scripts/gh/git-gh-issue-write.ts +53 -7
  178. package/scripts/gh/git-gh-issue.ts +5 -3
  179. package/scripts/gh/git-gh-pr-read.ts +68 -19
  180. package/scripts/gh/git-gh-pr-rest.ts +1 -1
  181. package/scripts/gh/git-gh-pr.ts +5 -1
  182. package/scripts/gh/git-pr-ai-review.ts +1 -1
  183. package/scripts/gh/git-pr-checks-eval.ts +9 -3
  184. package/scripts/gh/git-pr-checks-parse.ts +1 -1
  185. package/scripts/gh/git-pr-checks-watch.ts +6 -5
  186. package/scripts/gh/git-pr-checks.ts +18 -6
  187. package/scripts/gh/git-pr-coderabbit.ts +1 -1
  188. package/scripts/gh/git-pr-error.ts +1 -3
  189. package/scripts/gh/git-pr.ts +9 -13
  190. package/scripts/gh/github-issue-url.ts +2 -2
  191. package/scripts/git/constants.ts +12 -6
  192. package/scripts/git/git-command.ts +20 -218
  193. package/scripts/git/git-diff-reads.ts +225 -0
  194. package/scripts/git/git-error.ts +4 -12
  195. package/scripts/git/git-pre-push-hook.ts +139 -0
  196. package/scripts/git/git-prompt.ts +2 -6
  197. package/scripts/git/{schemas.ts → git-schemas.ts} +2 -0
  198. package/scripts/git/git-spawn-sync.ts +3 -1
  199. package/scripts/git/git-spawn.ts +1 -1
  200. package/scripts/git/git-staging.ts +4 -6
  201. package/scripts/git/git-status.ts +3 -9
  202. package/scripts/git/main-merge.ts +57 -21
  203. package/scripts/hooks/codex-hook-adapter.ts +1 -1
  204. package/scripts/hooks/edited-cspell.ts +2 -4
  205. package/scripts/hooks/format-edited-file.ts +3 -12
  206. package/scripts/hooks/pre-push-unit.ts +31 -9
  207. package/scripts/hooks/reserved-run.ts +2 -2
  208. package/scripts/hooks/run-hook.sh +5 -4
  209. package/scripts/hooks/stop-guard.ts +5 -3
  210. package/scripts/init/init-actions.ts +0 -5
  211. package/scripts/init/init-ai-copy.ts +13 -2
  212. package/scripts/init/init-logic-json-merge.ts +19 -0
  213. package/scripts/init/init-logic-secretlint.ts +7 -7
  214. package/scripts/init/init-logic-workspace.ts +41 -2
  215. package/scripts/init/init-logic.ts +16 -26
  216. package/scripts/init/init.ts +5 -15
  217. package/scripts/init/initial-commit.ts +4 -4
  218. package/scripts/init/kit-development-versions.ts +40 -0
  219. package/scripts/init/kit-setup-state.ts +2 -2
  220. package/scripts/init/start-exec.ts +68 -19
  221. package/scripts/init/start-setup-pr.ts +9 -9
  222. package/scripts/init/start-steps.ts +6 -10
  223. package/scripts/issue/defect-rate-cli.ts +1 -1
  224. package/scripts/issue/git-next-issues.ts +1 -1
  225. package/scripts/issue/issue-auto-ok.ts +1 -1
  226. package/scripts/issue/issue-backlinks-cli.ts +2 -2
  227. package/scripts/issue/issue-backlinks.ts +9 -9
  228. package/scripts/issue/issue-comment-cli.ts +19 -13
  229. package/scripts/issue/issue-file-cli.ts +45 -18
  230. package/scripts/issue/issue-file.ts +24 -1
  231. package/scripts/issue/issue-scout-closed.ts +1 -1
  232. package/scripts/issue/issue-state-cli.ts +30 -74
  233. package/scripts/josh/josh-command-map.ts +2 -0
  234. package/scripts/josh/josh-command-types.ts +11 -0
  235. package/scripts/josh/josh-commands-ai.ts +4 -4
  236. package/scripts/josh/josh-commands-backlog.ts +4 -1
  237. package/scripts/josh/josh-commands-development.ts +11 -1
  238. package/scripts/josh/josh-commands-document.ts +1 -0
  239. package/scripts/josh/josh-commands-lane.ts +22 -0
  240. package/scripts/josh/josh-commands-maintenance.ts +4 -4
  241. package/scripts/josh/josh-commands-run.ts +12 -7
  242. package/scripts/josh/josh-in-process.ts +28 -9
  243. package/scripts/josh/josh-logic.ts +33 -15
  244. package/scripts/josh/process-identity.ts +1 -3
  245. package/scripts/josh/session-language-cli.ts +3 -4
  246. package/scripts/lane/lane-await.ts +5 -1
  247. package/scripts/lane/lane-child-invocation.ts +2 -2
  248. package/scripts/lane/lane-cli.ts +3 -3
  249. package/scripts/lane/lane-dispatch.ts +14 -10
  250. package/scripts/lane/lane-environment.ts +5 -1
  251. package/scripts/lane/lane-handoff.ts +1 -1
  252. package/scripts/lane/lane-install.ts +2 -13
  253. package/scripts/lane/lane-launch-cli.ts +35 -3
  254. package/scripts/lane/lane-ledger.ts +145 -0
  255. package/scripts/lane/lane-leftover.ts +1 -1
  256. package/scripts/lane/lane-load.ts +108 -0
  257. package/scripts/lane/lane-measure-cli.ts +149 -0
  258. package/scripts/lane/lane-occupancy.ts +3 -0
  259. package/scripts/lane/lane-reap.ts +1 -3
  260. package/scripts/lane/lane-relaunch.ts +1 -1
  261. package/scripts/lane/lane-stats.ts +224 -0
  262. package/scripts/lane/lane-vacant.ts +36 -0
  263. package/scripts/lane/openai-lane-ship.ts +2 -2
  264. package/scripts/lane/openai-lane-supervisor-owner.ts +180 -0
  265. package/scripts/lane/openai-lane-supervisor.ts +7 -165
  266. package/scripts/lane/openai-review-broker.ts +2 -4
  267. package/scripts/lib/ancestor-directories.ts +35 -0
  268. package/scripts/lib/animation-helpers.ts +2 -2
  269. package/scripts/lib/buffered-process.ts +3 -7
  270. package/scripts/lib/cli-flags.ts +71 -1
  271. package/scripts/lib/spawn-exit.ts +2 -2
  272. package/scripts/lib/timeouts.ts +35 -2
  273. package/scripts/lines/line-budget.ts +4 -6
  274. package/scripts/notify/telegram-notify.ts +26 -1
  275. package/scripts/notify/telegram-test.ts +6 -0
  276. package/scripts/observations/observation-ledger-line.ts +6 -6
  277. package/scripts/observations/observation-ledger-migrate.ts +55 -4
  278. package/scripts/observations/observation-ledger.ts +26 -7
  279. package/scripts/overrides/lockfile-overrides.ts +1 -1
  280. package/scripts/overrides/overrides-logic.ts +1 -1
  281. package/scripts/propagate/propagate-git.ts +1 -1
  282. package/scripts/propagate/propagate-publish.ts +2 -2
  283. package/scripts/propagate/propagate-steps.ts +20 -15
  284. package/scripts/propagate/propagate.ts +36 -27
  285. package/scripts/refactor/import-graph.ts +18 -1
  286. package/scripts/refactor/refactor-lint.ts +4 -4
  287. package/scripts/repo/repository-labels.ts +2 -2
  288. package/scripts/repo/required-checks-logic.ts +1 -3
  289. package/scripts/review/live-evidence.ts +2 -4
  290. package/scripts/review/review-brief-cli.ts +1 -1
  291. package/scripts/review/review-finding-ledger.ts +1 -1
  292. package/scripts/review/review-findings-cli.ts +1 -3
  293. package/scripts/rules/decision-oracle-batch.ts +128 -0
  294. package/scripts/rules/decision-oracle-tokens.ts +21 -0
  295. package/scripts/rules/decision-oracle.ts +8 -120
  296. package/scripts/rules/delivered-rules.ts +26 -182
  297. package/scripts/rules/direct-filing.ts +1 -1
  298. package/scripts/rules/early-heartbeat.ts +3 -3
  299. package/scripts/rules/git-argv.ts +1 -1
  300. package/scripts/rules/git-force.ts +1 -1
  301. package/scripts/rules/implementation-cut.ts +2 -2
  302. package/scripts/rules/index-guard.ts +1 -1
  303. package/scripts/rules/issue-comments.ts +118 -0
  304. package/scripts/rules/{issue-fold.ts → issue-fold-rule.ts} +2 -2
  305. package/scripts/rules/lane-background.ts +2 -2
  306. package/scripts/rules/lane-park.ts +18 -0
  307. package/scripts/rules/lane-split-park.ts +128 -0
  308. package/scripts/rules/oracle-firing.ts +1 -1
  309. package/scripts/rules/poll-loop.ts +1 -1
  310. package/scripts/rules/pre-gate-cut.ts +3 -3
  311. package/scripts/rules/protected-files.ts +59 -4
  312. package/scripts/rules/{run-tail.ts → run-tail-rule.ts} +2 -2
  313. package/scripts/rules/shell-body-trigger.ts +1 -1
  314. package/scripts/rules/stop-rules.ts +18 -7
  315. package/scripts/rules/test-declared-commit.ts +4 -4
  316. package/scripts/rules/wip-cap.ts +63 -0
  317. package/scripts/run/{run-carry-args.ts → carry/run-carry-args.ts} +37 -13
  318. package/scripts/run/{run-carry-change.ts → carry/run-carry-change.ts} +29 -7
  319. package/scripts/run/{run-carry-cli.ts → carry/run-carry-cli.ts} +4 -6
  320. package/scripts/run/{run-carry.ts → carry/run-carry.ts} +12 -6
  321. package/scripts/run/{run-cut-args.ts → cut/run-cut-args.ts} +1 -1
  322. package/scripts/run/{run-cut-cli.ts → cut/run-cut-cli.ts} +3 -3
  323. package/scripts/run/{run-cut-report.ts → cut/run-cut-report.ts} +2 -2
  324. package/scripts/run/{run-cut.ts → cut/run-cut.ts} +1 -1
  325. package/scripts/run/{run-entry-cli.ts → entry/run-entry-cli.ts} +11 -11
  326. package/scripts/run/{run-entry.ts → entry/run-entry.ts} +2 -2
  327. package/scripts/run/{run-event-scope.ts → event/run-event-scope.ts} +1 -1
  328. package/scripts/run/{run-event-stream-emit.ts → event/run-event-stream-emit.ts} +1 -1
  329. package/scripts/run/{run-event-stream.ts → event/run-event-stream.ts} +16 -2
  330. package/scripts/run/{run-hold-cli.ts → hold/run-hold-cli.ts} +5 -5
  331. package/scripts/run/{run-merge-cli.ts → merge/run-merge-cli.ts} +10 -5
  332. package/scripts/run/{run-merge-steps.ts → merge/run-merge-steps.ts} +53 -5
  333. package/scripts/run/{run-merge.ts → merge/run-merge.ts} +1 -1
  334. package/scripts/run/{run-progress-cli.ts → progress/run-progress-cli.ts} +1 -1
  335. package/scripts/run/{run-progress-config.ts → progress/run-progress-config.ts} +2 -17
  336. package/scripts/run/{run-progress-read.ts → progress/run-progress-read.ts} +5 -5
  337. package/scripts/run/{run-progress.ts → progress/run-progress.ts} +1 -1
  338. package/scripts/run/{run-review-steps.ts → review/run-review-steps.ts} +2 -3
  339. package/scripts/run/run-ending.ts +2 -2
  340. package/scripts/run/run-halfrun-resume.ts +6 -1
  341. package/scripts/run/run-headless.ts +1 -1
  342. package/scripts/run/run-invocation.ts +85 -84
  343. package/scripts/run/run-liveness.ts +1 -1
  344. package/scripts/run/run-parent-cut-hook.ts +1 -1
  345. package/scripts/run/run-preflight.ts +6 -6
  346. package/scripts/run/run-prep-cli.ts +1 -1
  347. package/scripts/run/run-prrun-resume.ts +1 -1
  348. package/scripts/run/run-report-cli.ts +4 -4
  349. package/scripts/run/run-report.ts +2 -2
  350. package/scripts/run/run-status-cli.ts +1 -1
  351. package/scripts/run/run-step-cli.ts +3 -3
  352. package/scripts/run/run-step.ts +2 -2
  353. package/scripts/run/run-stop-notify.ts +1 -1
  354. package/scripts/run/run-stranded-detect.ts +4 -4
  355. package/scripts/run/run-stranded.ts +2 -2
  356. package/scripts/run/run-watcher-guard-cli.ts +1 -1
  357. package/scripts/run/run-watcher-guard.ts +5 -3
  358. package/scripts/run/run-watcher-hook.ts +1 -1
  359. package/scripts/run/{run-ship-cli.ts → ship/run-ship-cli.ts} +29 -8
  360. package/scripts/run/{run-ship-detach.ts → ship/run-ship-detach.ts} +3 -3
  361. package/scripts/run/ship/run-ship-lock.ts +50 -0
  362. package/scripts/run/{run-ship-next.ts → ship/run-ship-next.ts} +13 -0
  363. package/scripts/run/ship/run-ship-pre-detach.ts +66 -0
  364. package/scripts/run/{run-ship-preflight.ts → ship/run-ship-preflight.ts} +6 -2
  365. package/scripts/run/{run-ship-probe.ts → ship/run-ship-probe.ts} +2 -2
  366. package/scripts/run/{run-ship-return.ts → ship/run-ship-return.ts} +10 -6
  367. package/scripts/run/{run-ship-review-steps.ts → ship/run-ship-review-steps.ts} +3 -3
  368. package/scripts/run/{run-ship-scoped.ts → ship/run-ship-scoped.ts} +10 -1
  369. package/scripts/run/{run-ship-stage.ts → ship/run-ship-stage.ts} +13 -0
  370. package/scripts/run/{run-ship-steps.ts → ship/run-ship-steps.ts} +15 -8
  371. package/scripts/run/ship/run-ship-stop-text.ts +13 -0
  372. package/scripts/run/ship/run-ship-sync.ts +128 -0
  373. package/scripts/run/{run-ship.ts → ship/run-ship.ts} +6 -0
  374. package/scripts/run/{run-tidy-lanes.ts → tidy/run-tidy-lanes.ts} +1 -1
  375. package/scripts/run/{run-wake-cli.ts → wake/run-wake-cli.ts} +31 -9
  376. package/scripts/run/{run-wake-describe.ts → wake/run-wake-describe.ts} +3 -3
  377. package/scripts/run/{run-wake-driver.ts → wake/run-wake-driver.ts} +99 -17
  378. package/scripts/run/{run-wake-handoff.ts → wake/run-wake-handoff.ts} +1 -1
  379. package/scripts/run/{run-wake-loop.ts → wake/run-wake-loop.ts} +8 -2
  380. package/scripts/run/wake/run-wake-restart.ts +58 -0
  381. package/scripts/run/{run-wake-session.ts → wake/run-wake-session.ts} +3 -3
  382. package/scripts/run/{run-wake.ts → wake/run-wake.ts} +1 -1
  383. package/scripts/safe-chain/preinstall-command.ts +20 -21
  384. package/scripts/safe-chain/project-config.ts +19 -15
  385. package/scripts/sync/sync-ai-files.ts +1 -1
  386. package/scripts/sync/sync-configs.ts +2 -1
  387. package/scripts/sync/sync.ts +15 -2
  388. package/scripts/test/test-red-logic.ts +17 -2
  389. package/scripts/test/test-red.ts +8 -7
  390. package/scripts/test/unit-worker-share.ts +1 -0
  391. package/scripts/time-runtime/time-background.ts +5 -1
  392. package/scripts/time-runtime/time-instant.ts +3 -1
  393. package/scripts/time-runtime/time-spans.ts +6 -139
  394. package/scripts/time-runtime/time-tool-call.ts +160 -0
  395. package/scripts/time-runtime/time-transcript-line.ts +27 -1
  396. package/scripts/version/effective-upstream.ts +2 -20
  397. package/scripts/version/latest-corepack.ts +17 -17
  398. package/scripts/version/latest-regression.ts +1 -1
  399. package/scripts/version/latest-update.ts +4 -4
  400. package/scripts/version/npm-registry.ts +20 -5
  401. package/scripts/version/publishable-range-check.ts +2 -2
  402. package/scripts/version/publishable-range.ts +1 -1
  403. package/scripts/version/release-age.ts +48 -38
  404. package/scripts/version/release-hold.ts +1 -1
  405. package/scripts/version/safe-chain-version-update.ts +40 -0
  406. package/scripts/version/upgrade-shell-command.ts +48 -8
  407. package/scripts/version/version-check-logic.ts +23 -14
  408. package/scripts/version/version-commands.ts +23 -11
  409. package/scripts/version/version-remote.ts +28 -13
  410. package/templates/pnpm-workspace.basic.yaml +4 -0
  411. package/templates/workflows/dependabot-auto-merge.yml +5 -5
  412. package/templates/workflows/github-release.yml +2 -0
  413. package/scripts/build/build-config-merge.ts +0 -27
  414. package/scripts/build/build-managed-marker.ts +0 -27
  415. package/scripts/build/build-self-sync-guard.ts +0 -27
  416. package/scripts/build/build-version.ts +0 -26
  417. package/scripts/version/preinstall-version-update.ts +0 -86
  418. /package/scripts/overrides/{schemas.ts → overrides-schemas.ts} +0 -0
  419. /package/scripts/run/{run-carry-conversation.ts → carry/run-carry-conversation.ts} +0 -0
  420. /package/scripts/run/{run-carry-reclaim.ts → carry/run-carry-reclaim.ts} +0 -0
  421. /package/scripts/run/{run-carry-stash.ts → carry/run-carry-stash.ts} +0 -0
  422. /package/scripts/run/{run-carry-streak.ts → carry/run-carry-streak.ts} +0 -0
  423. /package/scripts/run/{run-cut-handoff.ts → cut/run-cut-handoff.ts} +0 -0
  424. /package/scripts/run/{run-entry-stop.ts → entry/run-entry-stop.ts} +0 -0
  425. /package/scripts/run/{run-event-cli.ts → event/run-event-cli.ts} +0 -0
  426. /package/scripts/run/{run-event-follow.ts → event/run-event-follow.ts} +0 -0
  427. /package/scripts/run/{run-event-render.ts → event/run-event-render.ts} +0 -0
  428. /package/scripts/run/{run-event-watch.ts → event/run-event-watch.ts} +0 -0
  429. /package/scripts/run/{run-hold.ts → hold/run-hold.ts} +0 -0
  430. /package/scripts/run/{run-progress-args.ts → progress/run-progress-args.ts} +0 -0
  431. /package/scripts/run/{run-progress-clock.ts → progress/run-progress-clock.ts} +0 -0
  432. /package/scripts/run/{run-review-cli.ts → review/run-review-cli.ts} +0 -0
  433. /package/scripts/run/{run-review.ts → review/run-review.ts} +0 -0
  434. /package/scripts/run/{run-ship-review.ts → ship/run-ship-review.ts} +0 -0
  435. /package/scripts/run/{run-tidy-cli.ts → tidy/run-tidy-cli.ts} +0 -0
  436. /package/scripts/run/{run-tidy-stashes.ts → tidy/run-tidy-stashes.ts} +0 -0
  437. /package/scripts/run/{run-tidy.ts → tidy/run-tidy.ts} +0 -0
@@ -0,0 +1,734 @@
1
+ #!/usr/bin/env tsx
2
+
3
+ // scripts/document/document-section-cli.ts
4
+ import { existsSync as existsSync2 } from "node:fs";
5
+ import path6 from "node:path";
6
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
7
+
8
+ // scripts/document/capped-print.ts
9
+ import { mkdtempSync, writeFileSync } from "node:fs";
10
+ import path3 from "node:path";
11
+
12
+ // scripts/josh/platform-temporary.ts
13
+ import { accessSync, constants } from "node:fs";
14
+ import { tmpdir } from "node:os";
15
+ var POSIX_TEMP_ROOT = "/tmp";
16
+ var WINDOWS_PLATFORM = "win32";
17
+ function is_writable_directory(directory) {
18
+ try {
19
+ accessSync(directory, constants.W_OK);
20
+ return true;
21
+ } catch {
22
+ return false;
23
+ }
24
+ }
25
+ function resolve_temporary_root(platform, can_write = is_writable_directory) {
26
+ if (platform === WINDOWS_PLATFORM) return tmpdir();
27
+ return can_write(POSIX_TEMP_ROOT) ? POSIX_TEMP_ROOT : tmpdir();
28
+ }
29
+ var TEMP_ROOT_KEY = "JOSH_TEMP_ROOT";
30
+ function temporary_root(override, platform) {
31
+ return override === void 0 || override === "" ? resolve_temporary_root(platform) : override;
32
+ }
33
+ var PLATFORM_TEMP_ROOT = temporary_root(process.env[TEMP_ROOT_KEY], process.platform);
34
+
35
+ // scripts/review/review-diff-parts.ts
36
+ var LINE_BREAK = "\n";
37
+ function cut_line(line, budget) {
38
+ const pieces = [];
39
+ for (let start = 0; start < line.length; start += budget) {
40
+ pieces.push(line.slice(start, start + budget));
41
+ }
42
+ return pieces;
43
+ }
44
+ function pieces_of(text, budget) {
45
+ return text.split(/(?<=\n)/u).flatMap((line) => cut_line(line, budget));
46
+ }
47
+ function is_full(current, piece, budget) {
48
+ return current.length > 0 && current.length + piece.length > budget;
49
+ }
50
+ function split_text(text, budget) {
51
+ const parts = [];
52
+ let current = "";
53
+ for (const piece of pieces_of(text, budget)) {
54
+ if (is_full(current, piece, budget)) {
55
+ parts.push(current);
56
+ current = "";
57
+ }
58
+ current += piece;
59
+ }
60
+ return current.length > 0 ? [...parts, current] : parts;
61
+ }
62
+ function part_header(relative, index, count) {
63
+ return `# ${relative} \u2014 part ${String(index + 1)} of ${String(count)}${LINE_BREAK}`;
64
+ }
65
+ function part_texts(relative, diff, cap) {
66
+ const budget = Math.max(1, cap - part_header(relative, diff.length, diff.length).length);
67
+ const bodies = split_text(diff, budget);
68
+ return bodies.map((body, index) => `${part_header(relative, index, bodies.length)}${body}`);
69
+ }
70
+ function body_of(part) {
71
+ return part.slice(part.indexOf(LINE_BREAK) + 1);
72
+ }
73
+ function part_list(parts) {
74
+ return Object.entries(parts).flatMap(([relative, files]) => [` ${relative}`, ...files.map((file) => ` ${file}`)]).join(LINE_BREAK);
75
+ }
76
+ function reading_block(parts, cap) {
77
+ return [
78
+ `Reading the diff: Bash output is cut at ${String(cap)} characters, so the change is written below as one or more parts per path, each under that cap, and together exactly the diff. Read the parts of every path you review with the Read tool. Do not print the diff, or any file this brief names, through Bash (\`git diff\`, \`cat\`).`,
79
+ part_list(parts)
80
+ ].join(LINE_BREAK);
81
+ }
82
+ var review_diff_parts = { body_of, part_texts, reading_block, split_text };
83
+
84
+ // scripts/document/bash-output-cap.ts
85
+ import path from "node:path";
86
+
87
+ // scripts/lib/read-file.ts
88
+ import { readFileSync } from "node:fs";
89
+ var ABSENT_CODE = "ENOENT";
90
+ function is_absent(error) {
91
+ return error instanceof Error && "code" in error && error.code === ABSENT_CODE;
92
+ }
93
+ function read_optional(path7) {
94
+ try {
95
+ return readFileSync(path7, "utf8");
96
+ } catch (error) {
97
+ if (is_absent(error)) return void 0;
98
+ throw error;
99
+ }
100
+ }
101
+ function read_file_or_empty(path7) {
102
+ return read_optional(path7) ?? "";
103
+ }
104
+ function read_if_readable(path7) {
105
+ try {
106
+ return readFileSync(path7, "utf8");
107
+ } catch {
108
+ return void 0;
109
+ }
110
+ }
111
+ var file_reader = { read_optional, read_file_or_empty, read_if_readable };
112
+
113
+ // scripts/document/document-scan.ts
114
+ var COMMAND_PATTERN = /`(?:pnpm )?josh ([a-z][a-z0-9:-]+)/gu;
115
+ var LABEL_PATTERN = /(?:labels\[\]=|\/labels\/|labels -f name=)([a-z][a-z0-9:_-]*)/gu;
116
+ var SECTION_PATTERN = /(?<![\w./:`-])(?<tick>`?)(?<file>[\w./-]+\.md)\k<tick>\s*→\s*(?:§\w+,\s*)?["「](?<heading>[^"」]+)["」]/gu;
117
+ var LINK_TARGET_PATTERN = /\]\([^)\s]*\)/gu;
118
+ var LINK_PATTERN = /\]\(([\w./-]+\.md)(?:#[\w-]+)?\)/gu;
119
+ var PLACEHOLDER_FILES = /* @__PURE__ */ new Set(["x.md", "foo.md", "file.md", "path.md"]);
120
+ function matches(text, pattern) {
121
+ return [...text.matchAll(pattern)];
122
+ }
123
+ function command_references(text) {
124
+ return matches(text, COMMAND_PATTERN).map((match) => match[1] ?? "").filter((name) => !name.endsWith(":"));
125
+ }
126
+ function is_real_label(token) {
127
+ return token.length > 0 && !token.endsWith(":") && !token.includes("<");
128
+ }
129
+ function label_references(text) {
130
+ return matches(text, LABEL_PATTERN).map((match) => match[1] ?? "").filter((token) => is_real_label(token));
131
+ }
132
+ function base_name(path7) {
133
+ return path7.split("/").at(-1) ?? path7;
134
+ }
135
+ function is_placeholder_file(name) {
136
+ return name.includes("<") || PLACEHOLDER_FILES.has(base_name(name).toLowerCase());
137
+ }
138
+ function section_references(text) {
139
+ return matches(text.replaceAll(LINK_TARGET_PATTERN, ""), SECTION_PATTERN).map(({ groups }) => ({ file: groups?.["file"] ?? "", heading: groups?.["heading"] ?? "" })).filter((reference) => !is_placeholder_file(reference.file));
140
+ }
141
+ function link_targets(text) {
142
+ return matches(text, LINK_PATTERN).map((match) => match[1] ?? "").filter((file) => !is_placeholder_file(file));
143
+ }
144
+ function normalize_reference(heading) {
145
+ return heading.replaceAll("`", "").split(/\s+/u).filter((word) => word !== ">").join(" ");
146
+ }
147
+ function reference_forms(title) {
148
+ const normalized = normalize_reference(title);
149
+ return [normalized, normalized.replace(/^\d+[a-z]?\. /u, "")];
150
+ }
151
+ var document_scan = {
152
+ command_references,
153
+ label_references,
154
+ link_targets,
155
+ normalize_reference,
156
+ reference_forms,
157
+ section_references
158
+ };
159
+
160
+ // scripts/document/document-section.ts
161
+ var HEADING_PATTERN = /^(?<hashes>#{1,6}) (?<title>.*)$/u;
162
+ var FENCE = "```";
163
+ var SINGLE_MATCH = 1;
164
+ var BOLD_LABEL_PATTERN = /\*\*([^*]+?)\*\*/gu;
165
+ var BOLD_DELIMITER = "**";
166
+ var CODE_SPAN_PATTERN = /``[^\n]*?``|`[^`\n]*`/gu;
167
+ var LABEL_LEVEL = 7;
168
+ var LIST_ITEM_PATTERN = /^(?<indent>\s*)(?:[-*]|\d+\.) /u;
169
+ function to_heading(line, index) {
170
+ const groups = HEADING_PATTERN.exec(line)?.groups;
171
+ if (groups === void 0) return void 0;
172
+ const { hashes = "", title = "" } = groups;
173
+ return { level: hashes.length, title: title.trim(), line: index };
174
+ }
175
+ function push_heading(found, line, index) {
176
+ const heading = to_heading(line, index);
177
+ if (heading !== void 0) found.push(heading);
178
+ }
179
+ function fenced_flags(lines) {
180
+ let is_inside_fence = false;
181
+ return lines.map(function is_fenced(line) {
182
+ if (!line.startsWith(FENCE)) return is_inside_fence;
183
+ is_inside_fence = !is_inside_fence;
184
+ return true;
185
+ });
186
+ }
187
+ function headings(markdown) {
188
+ const lines = markdown.split("\n");
189
+ const fenced = fenced_flags(lines);
190
+ const found = [];
191
+ for (const [index, line] of lines.entries()) {
192
+ if (fenced[index] !== true) push_heading(found, line, index);
193
+ }
194
+ return found;
195
+ }
196
+ function titles(markdown) {
197
+ return headings(markdown).map((heading) => heading.title);
198
+ }
199
+ function line_starts(markdown) {
200
+ return [...markdown.matchAll(/\n/gu)].map((match) => match.index + SINGLE_MATCH);
201
+ }
202
+ function line_of(starts, offset) {
203
+ return starts.filter((start) => start <= offset).length;
204
+ }
205
+ function unfenced_text(markdown) {
206
+ const lines = markdown.split("\n");
207
+ const fenced = fenced_flags(lines);
208
+ return lines.map((line, index) => fenced[index] === true ? "" : line).join("\n");
209
+ }
210
+ function code_masked(text) {
211
+ return text.replaceAll(CODE_SPAN_PATTERN, (span) => span.replaceAll("*", " "));
212
+ }
213
+ function labels(markdown) {
214
+ const text = unfenced_text(markdown);
215
+ const starts = line_starts(text);
216
+ return [...code_masked(text).matchAll(BOLD_LABEL_PATTERN)].map((match) => ({
217
+ level: LABEL_LEVEL,
218
+ title: text.slice(
219
+ match.index + BOLD_DELIMITER.length,
220
+ match.index + match[0].length - BOLD_DELIMITER.length
221
+ ),
222
+ line: line_of(starts, match.index)
223
+ }));
224
+ }
225
+ function is_match(heading, wanted) {
226
+ return document_scan.reference_forms(heading.title).some((form) => form.startsWith(wanted));
227
+ }
228
+ function prefixed(found, wanted) {
229
+ const normalized = document_scan.normalize_reference(wanted);
230
+ return found.filter((heading) => is_match(heading, normalized));
231
+ }
232
+ function is_exact(heading, wanted) {
233
+ return document_scan.reference_forms(heading.title).includes(wanted);
234
+ }
235
+ function select(found, wanted) {
236
+ const normalized = document_scan.normalize_reference(wanted);
237
+ const exact = found.find((heading) => is_exact(heading, normalized));
238
+ if (exact !== void 0) return exact;
239
+ const near = prefixed(found, wanted);
240
+ return near.length === SINGLE_MATCH ? near[0] : void 0;
241
+ }
242
+ function last_line_of(found, chosen, total_lines) {
243
+ const next = found.find((heading) => heading.line > chosen.line && heading.level <= chosen.level);
244
+ return (next === void 0 ? total_lines : next.line) - SINGLE_MATCH;
245
+ }
246
+ function indent_of(line) {
247
+ return line.length - line.trimStart().length;
248
+ }
249
+ function is_sibling_item(line, depth) {
250
+ const { indent } = LIST_ITEM_PATTERN.exec(line)?.groups ?? {};
251
+ return indent !== void 0 && indent.length <= depth;
252
+ }
253
+ function ends_block(line, depth) {
254
+ if (line.trim() === "" || HEADING_PATTERN.test(line)) return true;
255
+ return is_sibling_item(line, depth);
256
+ }
257
+ function label_last_line(lines, label) {
258
+ const depth = indent_of(lines[label.line] ?? "");
259
+ const end = lines.findIndex((line, index) => index > label.line && ends_block(line, depth));
260
+ return (end === -1 ? lines.length : end) - SINGLE_MATCH;
261
+ }
262
+ function choose(markdown, wanted) {
263
+ const found = headings(markdown);
264
+ if (prefixed(found, wanted).length > 0) return select(found, wanted);
265
+ return select(labels(markdown), wanted);
266
+ }
267
+ function extent_of(markdown, chosen) {
268
+ const lines = markdown.split("\n");
269
+ if (chosen.level === LABEL_LEVEL) return label_last_line(lines, chosen);
270
+ return last_line_of(headings(markdown), chosen, lines.length);
271
+ }
272
+ function section(markdown, wanted) {
273
+ const chosen = choose(markdown, wanted);
274
+ if (chosen === void 0) return void 0;
275
+ const last_line = extent_of(markdown, chosen);
276
+ const lines = markdown.split("\n").slice(chosen.line, last_line + SINGLE_MATCH);
277
+ return {
278
+ title: chosen.title,
279
+ level: chosen.level,
280
+ first_line: chosen.line,
281
+ last_line,
282
+ text: lines.join("\n")
283
+ };
284
+ }
285
+ function candidates(markdown, wanted) {
286
+ const near = prefixed(headings(markdown), wanted);
287
+ const listed = near.length > 0 ? near : prefixed(labels(markdown), wanted);
288
+ return listed.map((heading) => heading.title);
289
+ }
290
+ function read_optional2(file_path) {
291
+ return file_reader.read_if_readable(file_path);
292
+ }
293
+ var document_section = {
294
+ candidates,
295
+ headings,
296
+ read_optional: read_optional2,
297
+ section,
298
+ titles
299
+ };
300
+
301
+ // scripts/document/bash-output-cap.ts
302
+ var SETTINGS_FILE = path.join(".claude", "settings.json");
303
+ var HARNESS_DEFAULT_CAP_CHARS = 3e4;
304
+ var ENV_KEY = "env";
305
+ var CAP_KEY = "BASH_MAX_OUTPUT_LENGTH";
306
+ var NONE = 0;
307
+ function property_of(value, key) {
308
+ if (typeof value !== "object" || value === null) return void 0;
309
+ return Reflect.get(value, key);
310
+ }
311
+ function declared_cap(text) {
312
+ try {
313
+ return property_of(property_of(JSON.parse(text), ENV_KEY), CAP_KEY);
314
+ } catch {
315
+ return void 0;
316
+ }
317
+ }
318
+ function bash_output_cap(root) {
319
+ const text = document_section.read_optional(path.join(root, SETTINGS_FILE)) ?? "";
320
+ const chars = Number(declared_cap(text));
321
+ return Number.isSafeInteger(chars) && chars > NONE ? chars : HARNESS_DEFAULT_CAP_CHARS;
322
+ }
323
+ var bash_output_cap_reader = { HARNESS_DEFAULT_CAP_CHARS, bash_output_cap };
324
+
325
+ // scripts/document/capped-print-part.ts
326
+ import path2 from "node:path";
327
+ var DIRECTORY_PREFIX = "josh-capped-print-";
328
+ var PART_PREFIX = "part-";
329
+ var PART_SUFFIX = ".md";
330
+ var PART_PATTERN = /^part-[1-9]\d*\.md$/u;
331
+ function part_name(index) {
332
+ return `${PART_PREFIX}${String(index + 1)}${PART_SUFFIX}`;
333
+ }
334
+ function is_part_file(absolute) {
335
+ const parent = path2.basename(path2.dirname(absolute));
336
+ return parent.startsWith(DIRECTORY_PREFIX) && PART_PATTERN.test(path2.basename(absolute));
337
+ }
338
+ var capped_print_part = { DIRECTORY_PREFIX, part_name, is_part_file };
339
+
340
+ // scripts/document/capped-print.ts
341
+ var FILE_MODE = 384;
342
+ var LINE_BREAK2 = "\n";
343
+ var HEADROOM_CHARS = 512;
344
+ function write_parts(label, text, cap) {
345
+ const directory = mkdtempSync(path3.join(PLATFORM_TEMP_ROOT, capped_print_part.DIRECTORY_PREFIX));
346
+ return review_diff_parts.part_texts(label, text, cap).map((part, index) => {
347
+ const file = path3.join(directory, capped_print_part.part_name(index));
348
+ writeFileSync(file, part, { flag: "wx", mode: FILE_MODE });
349
+ return file;
350
+ });
351
+ }
352
+ function part_count(count) {
353
+ return `written as ${String(count)} part file${count === 1 ? "" : "s"} under it`;
354
+ }
355
+ function listing(text, cap, files) {
356
+ const figures = `${text.length.toLocaleString("en-US")} > ${cap.toLocaleString("en-US")} characters`;
357
+ const lead = `Over the Bash cap (${figures}) \u2014 ${part_count(files.length)}, together exactly the output. Read every part with the Read tool, in one turn, not cat:`;
358
+ return [lead, ...files.map((file) => ` ${file}`)].join(LINE_BREAK2);
359
+ }
360
+ function output_budget(root) {
361
+ return Math.max(1, bash_output_cap_reader.bash_output_cap(root) - HEADROOM_CHARS);
362
+ }
363
+ function capped_print(text, label, root = process.cwd()) {
364
+ const budget = output_budget(root);
365
+ if (text.length < budget) {
366
+ console.info(text);
367
+ return;
368
+ }
369
+ console.info(listing(text, budget, write_parts(label, text, budget)));
370
+ }
371
+ var capped_output = { HEADROOM_CHARS, capped_print };
372
+
373
+ // scripts/document/entry-read-set.ts
374
+ import { existsSync } from "node:fs";
375
+ import path5 from "node:path";
376
+
377
+ // scripts/init/init-paths.ts
378
+ import path4 from "node:path";
379
+ import { fileURLToPath } from "node:url";
380
+ var PACKAGE_DIR = path4.join(path4.dirname(fileURLToPath(import.meta.url)), "..", "..");
381
+ var PROJECT_ROOT = process.cwd();
382
+
383
+ // scripts/cost-runtime/cost-tokens.ts
384
+ var ASCII_CHARS_PER_TOKEN = 3;
385
+ var WIDE_TOKENS_PER_CHAR = 1;
386
+ var ASCII_LIMIT = 128;
387
+ function count_chars(text) {
388
+ let ascii_chars = 0;
389
+ let wide_chars = 0;
390
+ for (const char of text) {
391
+ if ((char.codePointAt(0) ?? 0) < ASCII_LIMIT) ascii_chars += 1;
392
+ else wide_chars += 1;
393
+ }
394
+ return { ascii_chars, wide_chars };
395
+ }
396
+ function estimate(text) {
397
+ const { ascii_chars, wide_chars } = count_chars(text);
398
+ return Math.round(ascii_chars / ASCII_CHARS_PER_TOKEN) + wide_chars * WIDE_TOKENS_PER_CHAR;
399
+ }
400
+ function ascii_bytes_to_tokens(bytes) {
401
+ return Math.round(bytes / ASCII_CHARS_PER_TOKEN);
402
+ }
403
+ var cost_tokens = {
404
+ ASCII_CHARS_PER_TOKEN,
405
+ count_chars,
406
+ estimate,
407
+ ascii_bytes_to_tokens
408
+ };
409
+
410
+ // scripts/document/read-set-cost.ts
411
+ var NOTHING = 0;
412
+ var ONE_LINE = 1;
413
+ function cost_of(text) {
414
+ return { bytes: Buffer.byteLength(text, "utf8"), tokens: cost_tokens.estimate(text) };
415
+ }
416
+ function total(costs) {
417
+ const running = { bytes: NOTHING, tokens: NOTHING };
418
+ for (const cost of costs) {
419
+ running.bytes += cost.bytes;
420
+ running.tokens += cost.tokens;
421
+ }
422
+ return running;
423
+ }
424
+ function add_range(charged, found) {
425
+ for (let index = found.first_line; index <= found.last_line; index += ONE_LINE) charged.add(index);
426
+ }
427
+ function charged_lines(markdown, headings2) {
428
+ const charged = /* @__PURE__ */ new Set();
429
+ for (const heading of headings2) {
430
+ const found = document_section.section(markdown, heading);
431
+ if (found === void 0) return void 0;
432
+ add_range(charged, found);
433
+ }
434
+ return charged;
435
+ }
436
+ function extend_or_start(runs, index) {
437
+ const current = runs.at(-1);
438
+ if (current?.at(-1) === index - ONE_LINE) current.push(index);
439
+ else runs.push([index]);
440
+ }
441
+ function contiguous_runs(charged) {
442
+ const runs = [];
443
+ const ascending = [...charged].toSorted((left, right) => left - right);
444
+ for (const index of ascending) extend_or_start(runs, index);
445
+ return runs;
446
+ }
447
+ function run_text(lines, run2) {
448
+ return run2.map((index) => lines[index] ?? "").join("\n");
449
+ }
450
+ function scoped_file_cost(markdown, headings2) {
451
+ const charged = charged_lines(markdown, headings2);
452
+ if (charged === void 0) return cost_of(markdown);
453
+ const lines = markdown.split("\n");
454
+ return total(contiguous_runs(charged).map((run2) => cost_of(run_text(lines, run2))));
455
+ }
456
+ var read_set_cost = { cost_of, scoped_file_cost, total };
457
+
458
+ // scripts/document/read-set-point-of-use.ts
459
+ var POINT_OF_USE_FILES = /* @__PURE__ */ new Set([
460
+ "latest-gate.md",
461
+ "followup.md",
462
+ "chain-rule.md",
463
+ "background-commands.md",
464
+ "pre-gate-cut.md",
465
+ "progress-watcher.md",
466
+ "backlogrun-child.md",
467
+ "backlogrun-lanes.md",
468
+ "backlogrun-progress.md",
469
+ "backlogrun-park.md",
470
+ "backlogrun-steps.md",
471
+ // Read only when a delegated unit goes silent or a lane's pull request conflicts with `main` — a
472
+ // failure path, so a run in which nothing fails never reads it (joshuafolkken/kit#3175).
473
+ "backlogrun-recovery.md",
474
+ // Read only when `run:step` prints `pnpm josh retrospective` at a run's stop position — the very
475
+ // end of a run, never the entry (joshuafolkken/kit#2328). Kept out of every entry's read for the
476
+ // same reason the phase documents above are: no run that never drains its backlog reaches it.
477
+ "retrospective.md"
478
+ ]);
479
+ var DEFERRED_DECISIONS = /* @__PURE__ */ new Set(["delegation.md", "issue-scout.md"]);
480
+ var POINT_OF_USE_BY_ENTRY = /* @__PURE__ */ new Map([
481
+ ["kickoff", DEFERRED_DECISIONS],
482
+ ["fullrun", DEFERRED_DECISIONS],
483
+ ["halfrun", DEFERRED_DECISIONS],
484
+ ["prrun", DEFERRED_DECISIONS],
485
+ ["backlogrun", /* @__PURE__ */ new Set([...DEFERRED_DECISIONS, "fullrun.md", "split-assessment.md"])]
486
+ ]);
487
+ var NO_PER_ENTRY_FILES = /* @__PURE__ */ new Set();
488
+ function is_point_of_use(entry, file) {
489
+ if (POINT_OF_USE_FILES.has(file)) return true;
490
+ return (POINT_OF_USE_BY_ENTRY.get(entry) ?? NO_PER_ENTRY_FILES).has(file);
491
+ }
492
+ function point_of_use_files(entry, cited) {
493
+ const reached = [...POINT_OF_USE_FILES].filter((file) => cited.has(file));
494
+ return [...reached, ...POINT_OF_USE_BY_ENTRY.get(entry) ?? NO_PER_ENTRY_FILES];
495
+ }
496
+ var read_set_point_of_use = {
497
+ POINT_OF_USE_FILES,
498
+ POINT_OF_USE_BY_ENTRY,
499
+ is_point_of_use,
500
+ point_of_use_files
501
+ };
502
+
503
+ // scripts/document/entry-read-set.ts
504
+ var { POINT_OF_USE_FILES: POINT_OF_USE_FILES2, POINT_OF_USE_BY_ENTRY: POINT_OF_USE_BY_ENTRY2, is_point_of_use: is_point_of_use2, point_of_use_files: point_of_use_files2 } = read_set_point_of_use;
505
+ var { cost_of: cost_of2, scoped_file_cost: scoped_file_cost2, total: total2 } = read_set_cost;
506
+ var SKILL_DIRECTORY = path5.join(".claude", "skills", "workflow-commands");
507
+ var SKILL_FILE = "SKILL.md";
508
+ var TABLE_SECTION = "1. Which file to read";
509
+ var NOTHING2 = 0;
510
+ var SUBSECTION_PREFIX = "### ";
511
+ var TABLE_ROW = /^\|(?<entry>[^|]+)\|(?<files>[^|]+)\|\s*$/u;
512
+ var MARKDOWN_NAME = /`(?<name>[\w.-]+\.md)`/gu;
513
+ var ENTRY_KEYWORD = /`(?<keyword>[a-z]+)/u;
514
+ var SECTION_REFERENCE = /`(?<file>[\w.-]+\.md)` *→ *"(?<heading>[^"]+)"/gu;
515
+ var WHITESPACE_RUN = /\s+/gu;
516
+ function document_path(root, name) {
517
+ const in_project = path5.join(root, SKILL_DIRECTORY, name);
518
+ const in_package = path5.join(PACKAGE_DIR, SKILL_DIRECTORY, name);
519
+ const project_manifest = path5.join(root, "package.json");
520
+ if (root !== "" && existsSync(project_manifest) && existsSync(in_package)) return in_package;
521
+ return existsSync(in_project) ? in_project : in_package;
522
+ }
523
+ function read_document(root, name) {
524
+ return document_section.read_optional(document_path(root, name)) ?? "";
525
+ }
526
+ function unique(names) {
527
+ return [...new Set(names)];
528
+ }
529
+ function all_matches(text, pattern) {
530
+ const scanner = new RegExp(pattern.source, pattern.flags);
531
+ const found = [];
532
+ let match = scanner.exec(text);
533
+ while (match !== null) {
534
+ found.push(match);
535
+ match = scanner.exec(text);
536
+ }
537
+ return found;
538
+ }
539
+ function group_of(match, name) {
540
+ return match.groups?.[name] ?? "";
541
+ }
542
+ function names_in(text) {
543
+ return all_matches(text, MARKDOWN_NAME).map((match) => group_of(match, "name"));
544
+ }
545
+ function columns_of(line) {
546
+ const groups = TABLE_ROW.exec(line)?.groups;
547
+ if (groups === void 0) return void 0;
548
+ const { entry = "", files = "" } = groups;
549
+ return { entry, files };
550
+ }
551
+ function to_row(line) {
552
+ const columns = columns_of(line);
553
+ if (columns === void 0) return void 0;
554
+ const { keyword } = ENTRY_KEYWORD.exec(columns.entry)?.groups ?? {};
555
+ return keyword === void 0 ? void 0 : { keyword, files: names_in(columns.files) };
556
+ }
557
+ function push_row(rows, line) {
558
+ const row = to_row(line);
559
+ if (row !== void 0 && row.files.length > NOTHING2) rows.set(row.keyword, row.files);
560
+ }
561
+ function table_rows(root) {
562
+ const rows = /* @__PURE__ */ new Map();
563
+ const found = document_section.section(read_document(root, SKILL_FILE), TABLE_SECTION);
564
+ const lines = (found?.text ?? "").split("\n");
565
+ for (const line of lines) {
566
+ if (line.startsWith(SUBSECTION_PREFIX)) break;
567
+ push_row(rows, line);
568
+ }
569
+ return rows;
570
+ }
571
+ function files_for(root, entry) {
572
+ const declared = table_rows(root).get(entry) ?? [];
573
+ return unique([SKILL_FILE, ...declared]).filter((file) => !is_point_of_use2(entry, file));
574
+ }
575
+ function fold(text) {
576
+ return text.replaceAll(WHITESPACE_RUN, " ").trim();
577
+ }
578
+ function is_sibling_document(root, name) {
579
+ return document_section.read_optional(document_path(root, name)) !== void 0;
580
+ }
581
+ function is_counted(root, entry, reference, files) {
582
+ if (is_point_of_use2(entry, reference.file)) return false;
583
+ return !files.includes(reference.file) && is_sibling_document(root, reference.file);
584
+ }
585
+ function to_reference(match) {
586
+ return { file: group_of(match, "file"), heading: fold(group_of(match, "heading")) };
587
+ }
588
+ function references_from(root, entry, text, files) {
589
+ return all_matches(text, SECTION_REFERENCE).map((match) => to_reference(match)).filter((reference) => is_counted(root, entry, reference, files));
590
+ }
591
+ function sort_key(reference) {
592
+ return `${reference.file} ${reference.heading}`;
593
+ }
594
+ function dedupe(references) {
595
+ const seen = /* @__PURE__ */ new Map();
596
+ for (const reference of references) seen.set(sort_key(reference), reference);
597
+ return [...seen].map(([, reference]) => reference);
598
+ }
599
+ function sections_for(root, entry, files) {
600
+ const found = files.filter((file) => file !== SKILL_FILE).flatMap((file) => references_from(root, entry, read_document(root, file), files));
601
+ return dedupe(found).toSorted((left, right) => sort_key(left).localeCompare(sort_key(right)));
602
+ }
603
+ function read_set(root, entry) {
604
+ const files = files_for(root, entry);
605
+ return { entry, files, sections: sections_for(root, entry, files) };
606
+ }
607
+ function section_cost(root, reference) {
608
+ const found = document_section.section(read_document(root, reference.file), reference.heading);
609
+ return {
610
+ ...reference,
611
+ // **An unresolvable reference is charged at the whole file.** Reporting it at zero would let a
612
+ // broken pointer read as a saving, which is the one direction this measurement must not move.
613
+ cost: cost_of2(found?.text ?? read_document(root, reference.file)),
614
+ is_resolved: found !== void 0
615
+ };
616
+ }
617
+ function referenced_cost(root, sections) {
618
+ const files = unique(sections.map((reference) => reference.file));
619
+ return total2(files.map((file) => cost_of2(read_document(root, file))));
620
+ }
621
+ function headings_for(sections, file) {
622
+ return sections.filter((reference) => reference.file === file).map((one) => one.heading);
623
+ }
624
+ function scoped_cost(root, sections) {
625
+ const files = unique(sections.map((reference) => reference.file));
626
+ return total2(
627
+ files.map((file) => scoped_file_cost2(read_document(root, file), headings_for(sections, file)))
628
+ );
629
+ }
630
+ function file_costs(root, names) {
631
+ return names.map((file) => ({ file, cost: cost_of2(read_document(root, file)) }));
632
+ }
633
+ function point_of_use_cost(root, file, references) {
634
+ const reference = references.find((one) => one.file === file);
635
+ if (reference !== void 0) return section_cost(root, reference);
636
+ return { file, heading: "", cost: cost_of2(read_document(root, file)), is_resolved: true };
637
+ }
638
+ function cited_by(root, entry, table_text, also) {
639
+ const manifests = files_for(root, entry).filter((file) => file !== SKILL_FILE);
640
+ const rows = table_text.split("\n").filter((line) => line.startsWith("|") && line.includes(`\`${entry}\``));
641
+ const texts = [...manifests.map((file) => read_document(root, file)), ...rows];
642
+ return /* @__PURE__ */ new Set([...also, ...texts.flatMap((text) => names_in(text))]);
643
+ }
644
+ function point_of_use_costs(root, entry, also) {
645
+ const table_text = document_section.section(read_document(root, SKILL_FILE), TABLE_SECTION)?.text ?? "";
646
+ const references = all_matches(table_text, SECTION_REFERENCE).map((match) => to_reference(match));
647
+ const cited = cited_by(root, entry, table_text, also);
648
+ return point_of_use_files2(entry, cited).map((file) => point_of_use_cost(root, file, references));
649
+ }
650
+ function costed(root, entry, also = /* @__PURE__ */ new Set()) {
651
+ const { files, sections } = read_set(root, entry);
652
+ const own_costs = file_costs(root, files);
653
+ const section_costs = sections.map((reference) => section_cost(root, reference));
654
+ const own = total2(own_costs.map((row) => row.cost));
655
+ return {
656
+ entry,
657
+ files: own_costs,
658
+ sections: section_costs,
659
+ point_of_use: point_of_use_costs(root, entry, also),
660
+ bash_output_cap: bash_output_cap_reader.bash_output_cap(root),
661
+ whole: total2([own, referenced_cost(root, sections)]),
662
+ scoped: total2([own, scoped_cost(root, sections)])
663
+ };
664
+ }
665
+ function entries(root) {
666
+ return [...table_rows(root)].map(([keyword]) => keyword);
667
+ }
668
+ var entry_read_set = {
669
+ HARNESS_DEFAULT_CAP_CHARS: bash_output_cap_reader.HARNESS_DEFAULT_CAP_CHARS,
670
+ POINT_OF_USE_BY_ENTRY: POINT_OF_USE_BY_ENTRY2,
671
+ POINT_OF_USE_FILES: POINT_OF_USE_FILES2,
672
+ SECTION_REFERENCE,
673
+ SKILL_DIRECTORY,
674
+ SKILL_FILE,
675
+ TABLE_SECTION,
676
+ bash_output_cap: bash_output_cap_reader.bash_output_cap,
677
+ cost_of: cost_of2,
678
+ costed,
679
+ document_path,
680
+ entries,
681
+ read_set,
682
+ total: total2
683
+ };
684
+
685
+ // scripts/document/document-section-cli.ts
686
+ var ARGV_OFFSET = 2;
687
+ var FAILURE_EXIT_CODE = 1;
688
+ var FILE_ARGUMENT = 0;
689
+ var HEADING_ARGUMENT = 1;
690
+ var NO_CANDIDATE = 0;
691
+ var USAGE = 'Usage: josh doc:section <file.md> "<heading>"';
692
+ function resolve_document(name, root = process.cwd()) {
693
+ const named = path6.resolve(root, name);
694
+ if (existsSync2(named)) return named;
695
+ const in_skill = entry_read_set.document_path(root, name);
696
+ return existsSync2(in_skill) ? in_skill : named;
697
+ }
698
+ function report_missing(markdown, heading) {
699
+ const near = document_section.candidates(markdown, heading);
700
+ const listed = near.length > NO_CANDIDATE ? near : document_section.titles(markdown);
701
+ console.error(`No single section matches ${JSON.stringify(heading)}. Headings it could mean:`);
702
+ for (const title of listed) console.error(` ${title}`);
703
+ return FAILURE_EXIT_CODE;
704
+ }
705
+ function print_section(markdown, heading, root) {
706
+ const found = document_section.section(markdown, heading);
707
+ if (found === void 0) return report_missing(markdown, heading);
708
+ capped_output.capped_print(found.text, heading, root);
709
+ return 0;
710
+ }
711
+ function read_named(name, root) {
712
+ const file_path = resolve_document(name, root);
713
+ const markdown = document_section.read_optional(file_path);
714
+ if (markdown === void 0) console.error(`Cannot read ${file_path}`);
715
+ return markdown;
716
+ }
717
+ function run(argv, root = process.cwd()) {
718
+ const name = argv[FILE_ARGUMENT];
719
+ const heading = argv[HEADING_ARGUMENT];
720
+ if (name === void 0 || heading === void 0) {
721
+ console.error(USAGE);
722
+ return FAILURE_EXIT_CODE;
723
+ }
724
+ const markdown = read_named(name, root);
725
+ return markdown === void 0 ? FAILURE_EXIT_CODE : print_section(markdown, heading, root);
726
+ }
727
+ function main(argv) {
728
+ process.exitCode = run(argv);
729
+ }
730
+ var document_section_cli = { FAILURE_EXIT_CODE, USAGE, resolve_document, run };
731
+ if (process.argv[1] === fileURLToPath2(import.meta.url)) main(process.argv.slice(ARGV_OFFSET));
732
+ export {
733
+ document_section_cli
734
+ };