@joshuafolkken/kit 1.1784.0 → 1.2114.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 (690) hide show
  1. package/.claude/agents/reviewer-verification.md +19 -0
  2. package/.claude/agents/reviewer.md +19 -0
  3. package/.claude/settings.json +5 -6
  4. package/.claude/skills/dependency-update/SKILL.md +9 -10
  5. package/.claude/skills/workflow-commands/SKILL.md +6 -6
  6. package/.claude/skills/workflow-commands/background-commands.md +8 -5
  7. package/.claude/skills/workflow-commands/backlogrun-child.md +3 -1
  8. package/.claude/skills/workflow-commands/backlogrun-lanes.md +1 -1
  9. package/.claude/skills/workflow-commands/backlogrun-park.md +5 -2
  10. package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -3
  11. package/.claude/skills/workflow-commands/backlogrun-recovery.md +1 -1
  12. package/.claude/skills/workflow-commands/backlogrun-steps.md +3 -2
  13. package/.claude/skills/workflow-commands/backlogrun.md +1 -1
  14. package/.claude/skills/workflow-commands/chain-rule.md +41 -32
  15. package/.claude/skills/workflow-commands/delegation.md +6 -6
  16. package/.claude/skills/workflow-commands/entry-sequence.md +2 -2
  17. package/.claude/skills/workflow-commands/followup.md +7 -5
  18. package/.claude/skills/workflow-commands/fullrun-steps.md +6 -6
  19. package/.claude/skills/workflow-commands/fullrun.md +1 -1
  20. package/.claude/skills/workflow-commands/issue-comments.md +9 -4
  21. package/.claude/skills/workflow-commands/issue-fold-existing.md +2 -1
  22. package/.claude/skills/workflow-commands/kickoff.md +2 -2
  23. package/.claude/skills/workflow-commands/observation-filing.md +1 -1
  24. package/.claude/skills/workflow-commands/observation-ledger.md +6 -4
  25. package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -7
  26. package/.claude/skills/workflow-commands/prerequisite.md +3 -2
  27. package/.claude/skills/workflow-commands/retrospective.md +2 -2
  28. package/.claude/skills/workflow-commands/split-assessment.md +7 -5
  29. package/.codex/hooks.json +5 -5
  30. package/.github/actions/setup-pnpm/action.yml +9 -16
  31. package/.github/dependabot.yml +16 -0
  32. package/.github/workflows/auto-tag.yml +45 -0
  33. package/.github/workflows/ci.yml +155 -15
  34. package/.github/workflows/dependabot-auto-merge.yml +63 -4
  35. package/.github/workflows/production.yml +8 -0
  36. package/.github/workflows/publish.yml +59 -45
  37. package/.vscode/settings.json +19 -0
  38. package/CLAUDE.md +5 -12
  39. package/SECURITY.md +2 -2
  40. package/dist/CLAUDE.md +5 -12
  41. package/dist/commands/document-read-cli.js +2 -1
  42. package/dist/commands/document-section-main.js +2 -1
  43. package/dist/commands/read-set-cli.js +194 -134
  44. package/dist/commands/run-prep-main.js +9694 -10173
  45. package/dist/commands/run-step-cli.js +22138 -18285
  46. package/dist/hooks/audit-provision.js +23 -5
  47. package/dist/hooks/chunk-3GKE653K.js +6204 -0
  48. package/dist/hooks/chunk-45CJJOO7.js +1243 -0
  49. package/dist/hooks/{chunk-CWMBGKYW.js → chunk-5PM2JRGV.js} +2153 -856
  50. package/dist/hooks/{chunk-WR2KQAYZ.js → chunk-7SIUNQXK.js} +1207 -1470
  51. package/dist/hooks/{chunk-O2YBIDSI.js → chunk-CQD4LJE6.js} +1682 -1130
  52. package/dist/hooks/{chunk-VWWCFGWK.js → chunk-OPSRGWFU.js} +1 -1
  53. package/dist/hooks/{chunk-XGBNSWEI.js → chunk-UJ3FPMMM.js} +132 -49
  54. package/dist/hooks/chunk-VVNYJWEI.js +30 -0
  55. package/dist/hooks/chunk-Z6DQJKH3.js +2806 -0
  56. package/dist/hooks/codex-hook-adapter.js +8 -8
  57. package/dist/hooks/format-edited.js +4 -5
  58. package/dist/hooks/inputs.json +415 -389
  59. package/dist/hooks/pretool-guard.js +7 -6
  60. package/dist/hooks/session-lang.js +101 -258
  61. package/dist/hooks/stop-guard.js +1744 -2576
  62. package/dist/josh.js +7133 -6368
  63. package/dist/version/index.js +161 -1
  64. package/eslint/rules/comment-why-only.js +108 -0
  65. package/package.json +15 -8
  66. package/prompts/coding-standards.md +1 -1
  67. package/prompts/collaboration-workflow/file-edits.md +14 -11
  68. package/prompts/collaboration-workflow/issue-citation.md +0 -4
  69. package/prompts/collaboration-workflow/issue-template.md +40 -21
  70. package/prompts/collaboration-workflow/lane-instructions.md +3 -1
  71. package/prompts/collaboration-workflow/measurement.md +8 -1
  72. package/prompts/collaboration-workflow/operating-rules.md +11 -2
  73. package/prompts/collaboration-workflow/output-bounds.md +6 -2
  74. package/prompts/collaboration-workflow/plan-comment.md +1 -1
  75. package/prompts/collaboration-workflow/principles.md +9 -0
  76. package/prompts/collaboration-workflow/residency.md +3 -2
  77. package/prompts/collaboration-workflow/rule-delivery.md +13 -1
  78. package/prompts/collaboration-workflow/upstream-interrupt.md +2 -2
  79. package/prompts/collaboration-workflow/wip-cap.md +3 -1
  80. package/prompts/review-rubric.md +8 -0
  81. package/prompts/review.md +31 -22
  82. package/prompts/testing-guide.md +1 -0
  83. package/scripts/agent/agent-argv.ts +14 -16
  84. package/scripts/agent/agent-provider.ts +138 -0
  85. package/scripts/agent/agent-role-profile.ts +108 -156
  86. package/scripts/agent/agent-safe-text.ts +20 -5
  87. package/scripts/agent/api-usage-limit.ts +65 -0
  88. package/scripts/agent/claude-agent-argv.ts +19 -9
  89. package/scripts/agent/codex-agent-argv.ts +118 -22
  90. package/scripts/agent/usage-limit-reset.ts +179 -0
  91. package/scripts/auth/claude-token-output.ts +2 -2
  92. package/scripts/auto-ok/auto-ok-author.ts +53 -0
  93. package/scripts/auto-ok/auto-ok-cli.ts +20 -9
  94. package/scripts/backlog/backlog-defect-priority.ts +1 -1
  95. package/scripts/backlog/backlog-drive-cli.ts +6 -1
  96. package/scripts/backlog/backlog-drive-hold.ts +3 -3
  97. package/scripts/backlog/backlog-drive-idle.ts +10 -0
  98. package/scripts/backlog/backlog-drive-launch-pass.ts +90 -0
  99. package/scripts/backlog/backlog-drive-launch.ts +8 -2
  100. package/scripts/backlog/backlog-drive-named-offer.ts +73 -30
  101. package/scripts/backlog/backlog-drive-named.ts +28 -7
  102. package/scripts/backlog/backlog-drive-paused.ts +5 -4
  103. package/scripts/backlog/backlog-drive-restore.ts +11 -3
  104. package/scripts/backlog/backlog-drive.ts +21 -60
  105. package/scripts/backlog/backlog-gate-scope.ts +61 -0
  106. package/scripts/backlog/backlog-measure-close.ts +112 -0
  107. package/scripts/backlog/backlog-next.ts +39 -49
  108. package/scripts/backlog/backlog-occupied.ts +2 -2
  109. package/scripts/backlog/backlog-overlap.ts +42 -8
  110. package/scripts/backlog/backlog-plan-cli.ts +4 -1
  111. package/scripts/backlog/backlog-plan-comment.ts +81 -0
  112. package/scripts/backlog/backlog-plan-read.ts +19 -6
  113. package/scripts/backlog/backlog-pool.ts +50 -12
  114. package/scripts/backlog/backlog-rank.ts +60 -13
  115. package/scripts/backlog/backlog-stalled-detect.ts +2 -1
  116. package/scripts/backlog/backlog-waves.ts +17 -2
  117. package/scripts/backlog/backlogrun-launch.ts +7 -4
  118. package/scripts/cost-runtime/context-cut-payback.ts +27 -25
  119. package/scripts/cost-runtime/cost-cli.ts +37 -16
  120. package/scripts/cost-runtime/cost-pricing.ts +9 -0
  121. package/scripts/cost-runtime/cost-verdict.ts +4 -1
  122. package/scripts/delegation/delegation-policy.ts +2 -2
  123. package/scripts/delegation/duplicate-read-guard.ts +1 -0
  124. package/scripts/delegation/investigation-guard.ts +14 -2
  125. package/scripts/delegation/investigation-reads.ts +45 -23
  126. package/scripts/dependabot/dependabot-cooldown.ts +3 -2
  127. package/scripts/discovery/repo-party.ts +80 -20
  128. package/scripts/discovery/session-owner-pin.ts +51 -0
  129. package/scripts/document/capped-print.ts +1 -1
  130. package/scripts/document/command-reference-line-budget.ts +42 -0
  131. package/scripts/document/document-byte-budget.ts +17 -7
  132. package/scripts/document/document-checks.ts +20 -0
  133. package/scripts/document/document-ratchet-check.ts +101 -0
  134. package/scripts/document/document-section.ts +1 -0
  135. package/scripts/document/entry-read-budget.ts +7 -3
  136. package/scripts/document/issue-citation-budget.ts +94 -0
  137. package/scripts/epic/epic-cli-argv.ts +2 -2
  138. package/scripts/epic/epic-fetch.ts +4 -2
  139. package/scripts/epic/epic-graph.ts +7 -2
  140. package/scripts/epic/epic-issue.ts +3 -1
  141. package/scripts/epic/epic-rank.ts +5 -0
  142. package/scripts/exports/unused-members-check.ts +62 -0
  143. package/scripts/exports/unused-members-cli.ts +6 -51
  144. package/scripts/followup/followup-ci-path.ts +67 -0
  145. package/scripts/followup/followup-coderabbit-retrigger.ts +261 -0
  146. package/scripts/followup/followup-coderabbit-wait.ts +13 -10
  147. package/scripts/followup/followup-failed-tests.ts +160 -0
  148. package/scripts/followup/followup-job-needs.ts +100 -0
  149. package/scripts/followup/followup-job-rerun.ts +303 -0
  150. package/scripts/followup/followup-main-move.ts +113 -0
  151. package/scripts/followup/git-followup-finish.ts +43 -11
  152. package/scripts/followup/git-followup-pending.ts +3 -3
  153. package/scripts/followup/git-followup-stages.ts +41 -11
  154. package/scripts/followup/git-pr-followup-checks.ts +55 -16
  155. package/scripts/followup/git-pr-followup-wrapup.ts +24 -5
  156. package/scripts/followup/git-pr-followup.ts +62 -27
  157. package/scripts/fresh-machine/fresh-machine-script.ts +5 -9
  158. package/scripts/fresh-machine/specs/kit-test-backlogrun-python.json +2 -2
  159. package/scripts/fresh-machine/specs/kit-test-backlogrun.json +2 -2
  160. package/scripts/gate/busy-average.ts +34 -2
  161. package/scripts/gate/check-related-pinned.ts +43 -0
  162. package/scripts/gate/check-related-reuse.ts +64 -0
  163. package/scripts/gate/check-related-section.ts +57 -0
  164. package/scripts/gate/check-related-unplanned.ts +34 -0
  165. package/scripts/gate/check-related.ts +265 -0
  166. package/scripts/gate/command-memory.ts +1 -1
  167. package/scripts/gate/core-admission.ts +24 -6
  168. package/scripts/gate/core-budget-timing.ts +20 -6
  169. package/scripts/gate/core-budget.ts +40 -11
  170. package/scripts/gate/core-wait-record.ts +3 -2
  171. package/scripts/gate/core-wait.ts +25 -2
  172. package/scripts/gate/core-weights.ts +15 -7
  173. package/scripts/gate/gate-labels.ts +46 -0
  174. package/scripts/gate/gate-ledger.ts +14 -6
  175. package/scripts/gate/gate-plan.ts +103 -58
  176. package/scripts/gate/gate-report.ts +9 -7
  177. package/scripts/gate/gate-run-steps.ts +26 -3
  178. package/scripts/gate/gate-skip.ts +45 -6
  179. package/scripts/gate/gate-static-group.ts +60 -0
  180. package/scripts/gate/gate-steps.ts +2 -1
  181. package/scripts/gate/gate-tree.ts +4 -2
  182. package/scripts/gate/hook-gate-reuse.ts +19 -2
  183. package/scripts/gate/metrics-totals.ts +59 -0
  184. package/scripts/gate/scoped-green.ts +68 -15
  185. package/scripts/gate/since-green.ts +14 -6
  186. package/scripts/gate/structural-checks.ts +96 -0
  187. package/scripts/gate/verification-gate.ts +51 -16
  188. package/scripts/gate/verification-inputs.ts +21 -6
  189. package/scripts/gate/verification-tail.ts +52 -0
  190. package/scripts/gh/gh-author-association.ts +23 -2
  191. package/scripts/gh/git-ai-review-scan.ts +1 -1
  192. package/scripts/gh/git-gh-api-path.ts +12 -3
  193. package/scripts/gh/git-gh-comments-unreadable.ts +36 -0
  194. package/scripts/gh/git-gh-exec.ts +32 -2
  195. package/scripts/gh/git-gh-issue-read.ts +4 -2
  196. package/scripts/gh/git-gh-issue-rest.ts +1 -0
  197. package/scripts/gh/git-gh-issue-write.ts +8 -2
  198. package/scripts/gh/git-gh-issue.ts +12 -5
  199. package/scripts/gh/git-gh-pr-auto-merge.ts +13 -6
  200. package/scripts/gh/git-gh-pr-graphql-state.ts +56 -0
  201. package/scripts/gh/git-gh-pr-read.ts +74 -13
  202. package/scripts/gh/git-gh-pr-rest.ts +3 -1
  203. package/scripts/gh/git-gh-pr-snapshot.ts +22 -7
  204. package/scripts/gh/git-gh-pr-too-large.ts +20 -0
  205. package/scripts/gh/git-gh-pr.ts +21 -7
  206. package/scripts/gh/git-gh-retry.ts +141 -0
  207. package/scripts/gh/git-pr-ai-review.ts +15 -6
  208. package/scripts/gh/git-pr-checks-eval.ts +3 -0
  209. package/scripts/gh/git-pr-checks.ts +5 -5
  210. package/scripts/git/base-tree.ts +30 -0
  211. package/scripts/git/change-base.ts +4 -10
  212. package/scripts/git/changed-paths-sync.ts +63 -0
  213. package/scripts/git/changed-paths.ts +16 -1
  214. package/scripts/git/git-common-directory.ts +11 -1
  215. package/scripts/git/git-diff-reads.ts +66 -20
  216. package/scripts/git/git-error.ts +9 -2
  217. package/scripts/git/git-schemas.ts +13 -0
  218. package/scripts/git/git-worktree.ts +13 -0
  219. package/scripts/git/gone-branch.ts +4 -1
  220. package/scripts/git/main-merge-budget-conflict.ts +89 -0
  221. package/scripts/git/main-merge-guard.ts +55 -18
  222. package/scripts/git/main-merge-regenerate.ts +59 -25
  223. package/scripts/git/main-merge.ts +53 -5
  224. package/scripts/git/no-base-checkout.ts +127 -0
  225. package/scripts/git/stash/git-stash.ts +11 -2
  226. package/scripts/git/stash/stash-push-cli.ts +10 -0
  227. package/scripts/hooks/batch-guard.ts +40 -21
  228. package/scripts/hooks/edited-cspell.ts +37 -11
  229. package/scripts/hooks/format-edited-file.ts +22 -2
  230. package/scripts/hooks/lane-plan-guard.ts +50 -0
  231. package/scripts/hooks/pre-commit-lint-switch.ts +9 -0
  232. package/scripts/hooks/pre-commit-lint.ts +14 -1
  233. package/scripts/hooks/pre-push-related-switch.ts +10 -0
  234. package/scripts/hooks/pre-push-unit.ts +76 -10
  235. package/scripts/hooks/pretool-guard.ts +2 -0
  236. package/scripts/hooks/reserved-run.ts +14 -1
  237. package/scripts/hooks/run-hook.sh +23 -8
  238. package/scripts/hooks/step-zero-notice.ts +6 -1
  239. package/scripts/hooks/stop-actions.ts +3 -15
  240. package/scripts/hooks/stop-guard.ts +7 -6
  241. package/scripts/init/distributed-paths.ts +1 -0
  242. package/scripts/init/hook-command-rewrite.ts +5 -1
  243. package/scripts/init/hook-launch.ts +4 -2
  244. package/scripts/issue/aggregation-split.ts +52 -0
  245. package/scripts/issue/defect-origin-line.ts +19 -1
  246. package/scripts/issue/defect-rate-cli.ts +5 -102
  247. package/scripts/issue/defect-report.ts +4 -4
  248. package/scripts/issue/effect-audit-cli.ts +178 -0
  249. package/scripts/issue/effect-audit.ts +185 -0
  250. package/scripts/issue/expected-effect-lint.ts +64 -9
  251. package/scripts/issue/git-next-issues.ts +5 -0
  252. package/scripts/issue/issue-body-or-comment.ts +38 -4
  253. package/scripts/issue/issue-cite-cli.ts +1 -3
  254. package/scripts/issue/issue-classification.ts +1 -0
  255. package/scripts/issue/issue-closing-pr.ts +8 -1
  256. package/scripts/issue/issue-evidence-exit.ts +4 -2
  257. package/scripts/issue/issue-file-cap.ts +58 -0
  258. package/scripts/issue/issue-file-cli.ts +111 -38
  259. package/scripts/issue/issue-file-deferral.ts +52 -0
  260. package/scripts/issue/issue-file-fold.ts +29 -10
  261. package/scripts/issue/issue-file-interrupt.ts +85 -0
  262. package/scripts/issue/issue-file-lane-hint.ts +30 -0
  263. package/scripts/issue/issue-file.ts +43 -6
  264. package/scripts/issue/issue-labels.ts +19 -2
  265. package/scripts/issue/issue-lint-cli.ts +27 -2
  266. package/scripts/issue/issue-measured-cli.ts +13 -35
  267. package/scripts/issue/issue-measured-close.ts +58 -0
  268. package/scripts/issue/issue-not-before-label.ts +2 -2
  269. package/scripts/issue/issue-not-before.ts +4 -1
  270. package/scripts/issue/issue-priority-cli.ts +60 -0
  271. package/scripts/issue/issue-priority-raise.ts +55 -0
  272. package/scripts/issue/issue-priority.ts +174 -43
  273. package/scripts/issue/issue-rank.ts +21 -4
  274. package/scripts/issue/issue-read-cli.ts +32 -6
  275. package/scripts/issue/issue-read.ts +37 -12
  276. package/scripts/issue/issue-sample-gate.ts +95 -74
  277. package/scripts/issue/issue-sample-prime.ts +127 -0
  278. package/scripts/issue/issue-sample-required.ts +57 -0
  279. package/scripts/issue/issue-sample-source.ts +12 -11
  280. package/scripts/issue/issue-search.ts +124 -0
  281. package/scripts/issue/issue-state.ts +13 -1
  282. package/scripts/issue/issue-template-section.ts +43 -0
  283. package/scripts/issue/issue-watch-diff.ts +31 -1
  284. package/scripts/issue/issue-watch-hook.ts +11 -2
  285. package/scripts/issue/issue-watch.ts +55 -12
  286. package/scripts/issue/markdown-section.ts +1 -0
  287. package/scripts/issue/measure-declaration.ts +121 -0
  288. package/scripts/issue/measure-rerun-cli.ts +7 -70
  289. package/scripts/issue/plan-consumers-section.ts +22 -1
  290. package/scripts/issue/reproduction-measure.ts +3 -1
  291. package/scripts/issue/size-estimate.ts +90 -0
  292. package/scripts/issue/trusted-measure.ts +84 -0
  293. package/scripts/josh/command-usage.ts +3 -2
  294. package/scripts/josh/durable-state-migrate.ts +105 -0
  295. package/scripts/josh/durable-state.ts +112 -0
  296. package/scripts/josh/josh-aliases.ts +95 -0
  297. package/scripts/josh/josh-command-map.ts +1 -82
  298. package/scripts/josh/josh-commands-agent-hooks.ts +6 -6
  299. package/scripts/josh/josh-commands-ai.ts +5 -5
  300. package/scripts/josh/josh-commands-development.ts +59 -58
  301. package/scripts/josh/josh-commands-issue-write.ts +23 -4
  302. package/scripts/josh/josh-commands-issue.ts +32 -0
  303. package/scripts/josh/josh-commands-lane.ts +87 -4
  304. package/scripts/josh/josh-commands-lint.ts +16 -3
  305. package/scripts/josh/josh-commands-maintenance.ts +15 -0
  306. package/scripts/josh/josh-commands-review.ts +41 -6
  307. package/scripts/josh/josh-commands-ship.ts +56 -8
  308. package/scripts/josh/josh-commands-test-check.ts +80 -0
  309. package/scripts/josh/josh-commands-workflow.ts +1 -1
  310. package/scripts/josh/josh-environment-file.ts +43 -3
  311. package/scripts/josh/josh-in-process.ts +2 -2
  312. package/scripts/josh/josh-logic.ts +5 -3
  313. package/scripts/josh/josh-run.ts +19 -1
  314. package/scripts/josh/run-record-path.ts +15 -0
  315. package/scripts/josh/stamp-file.ts +11 -2
  316. package/scripts/lane/lane-adopt-cli.ts +98 -0
  317. package/scripts/lane/lane-adopt.ts +208 -0
  318. package/scripts/lane/lane-await.ts +5 -8
  319. package/scripts/lane/lane-baseline.ts +123 -0
  320. package/scripts/lane/lane-breakdown-cli.ts +64 -0
  321. package/scripts/lane/lane-breakdown-implement.ts +170 -0
  322. package/scripts/lane/lane-breakdown-laps.ts +107 -0
  323. package/scripts/lane/lane-breakdown-pinned.ts +76 -0
  324. package/scripts/lane/lane-breakdown-text.ts +145 -0
  325. package/scripts/lane/lane-breakdown.ts +239 -0
  326. package/scripts/lane/lane-check-stats.ts +29 -8
  327. package/scripts/lane/lane-child-invocation.ts +9 -2
  328. package/scripts/lane/lane-child-mark-keys.ts +12 -0
  329. package/scripts/lane/lane-child-marker.ts +20 -1
  330. package/scripts/lane/lane-ci-path-stats.ts +73 -0
  331. package/scripts/lane/lane-claim-stats.ts +84 -0
  332. package/scripts/lane/lane-close.ts +8 -3
  333. package/scripts/lane/lane-dispatch-log.ts +3 -3
  334. package/scripts/lane/lane-dispatch.ts +2 -2
  335. package/scripts/lane/lane-gap-stats.ts +7 -6
  336. package/scripts/lane/lane-guard-policy.ts +7 -1
  337. package/scripts/lane/lane-implement-stats.ts +207 -0
  338. package/scripts/lane/lane-implement-subagents.ts +90 -0
  339. package/scripts/lane/lane-investigation-switch.ts +16 -0
  340. package/scripts/lane/lane-ledger-kind.ts +31 -0
  341. package/scripts/lane/lane-ledger-schema-ship.ts +49 -0
  342. package/scripts/lane/lane-ledger-schema.ts +119 -36
  343. package/scripts/lane/lane-ledger-write.ts +257 -0
  344. package/scripts/lane/lane-ledger.ts +31 -177
  345. package/scripts/lane/lane-load.ts +1 -1
  346. package/scripts/lane/lane-measure-cli.ts +176 -59
  347. package/scripts/lane/lane-net-read.ts +44 -0
  348. package/scripts/lane/lane-net-time.ts +212 -0
  349. package/scripts/lane/lane-open.ts +16 -7
  350. package/scripts/lane/lane-output.ts +2 -4
  351. package/scripts/lane/lane-overrun-prompt.ts +147 -0
  352. package/scripts/lane/lane-overrun.ts +274 -0
  353. package/scripts/lane/lane-paths.ts +24 -1
  354. package/scripts/lane/lane-pause-cli.ts +4 -1
  355. package/scripts/lane/lane-paused-spans.ts +97 -0
  356. package/scripts/lane/lane-plan-check.ts +207 -0
  357. package/scripts/lane/lane-plan-cli.ts +41 -0
  358. package/scripts/lane/lane-plan.ts +144 -0
  359. package/scripts/lane/lane-registry.ts +14 -1
  360. package/scripts/lane/lane-relaunch.ts +1 -1
  361. package/scripts/lane/lane-round-one-stats.ts +51 -0
  362. package/scripts/lane/lane-sampler.ts +23 -4
  363. package/scripts/lane/lane-session-action.ts +93 -18
  364. package/scripts/lane/lane-session-broker.ts +49 -21
  365. package/scripts/lane/lane-session-reread-main.ts +14 -0
  366. package/scripts/lane/lane-session-reread.ts +51 -0
  367. package/scripts/lane/lane-ship-lap-stats.ts +74 -0
  368. package/scripts/lane/lane-sleep.ts +58 -0
  369. package/scripts/lane/lane-spent.ts +1 -1
  370. package/scripts/lane/lane-split-stats.ts +28 -0
  371. package/scripts/lane/lane-stage-stats.ts +13 -1
  372. package/scripts/lane/lane-state.ts +41 -9
  373. package/scripts/lane/lane-stats-tables.ts +58 -0
  374. package/scripts/lane/lane-stats.ts +21 -5
  375. package/scripts/lane/lane-stop-stats.ts +51 -19
  376. package/scripts/lane/lane-tail-stats.ts +32 -0
  377. package/scripts/lane/lane-transcript-calls.ts +67 -10
  378. package/scripts/lane/lane-transcript-stats.ts +44 -12
  379. package/scripts/lane/lane-value-cell.ts +72 -0
  380. package/scripts/lane/lane-value.ts +118 -0
  381. package/scripts/lane/lane-withdraw-closed.ts +124 -0
  382. package/scripts/lane/lane-withdraw.ts +108 -31
  383. package/scripts/lane/lane-yield.ts +85 -0
  384. package/scripts/lane/openai-lane-ship.ts +12 -11
  385. package/scripts/lane/openai-lane-supervisor-decision.ts +6 -8
  386. package/scripts/lane/openai-lane-supervisor-owner.ts +5 -8
  387. package/scripts/lane/openai-lane-supervisor.ts +5 -4
  388. package/scripts/lib/poll.ts +38 -9
  389. package/scripts/lib/settled-together.ts +10 -0
  390. package/scripts/lib/shell-quote.ts +21 -0
  391. package/scripts/lib/token-shape.ts +111 -0
  392. package/scripts/lint/eslint-daemon-sources.ts +79 -0
  393. package/scripts/lint/eslint-daemon.ts +45 -6
  394. package/scripts/lint/eslint-warm-cli.ts +7 -0
  395. package/scripts/lint/eslint-warm.ts +66 -0
  396. package/scripts/lint/import-graph.ts +141 -11
  397. package/scripts/lint/lint-gate-scope.ts +2 -2
  398. package/scripts/lint/lint-parallel.ts +54 -6
  399. package/scripts/lint/lint-related.ts +154 -33
  400. package/scripts/lint/rename-cli.ts +179 -0
  401. package/scripts/lint/rename-identifier.ts +192 -0
  402. package/scripts/lint/type-only-imports.ts +58 -0
  403. package/scripts/notify/telegram-notify.ts +12 -3
  404. package/scripts/observations/observation-record.ts +42 -16
  405. package/scripts/observations/observations-flush.ts +32 -9
  406. package/scripts/overrides/overrides-check.ts +9 -1
  407. package/scripts/release/release-approval-prune.ts +7 -1
  408. package/scripts/repo/required-checks-logic.ts +4 -1
  409. package/scripts/repo/ruleset-check.ts +4 -3
  410. package/scripts/report/markdown-shape.ts +28 -0
  411. package/scripts/report/report-format-reference.ts +15 -1
  412. package/scripts/report/report-labels.ts +12 -1
  413. package/scripts/report/report-lint-child-summary.ts +94 -0
  414. package/scripts/report/report-lint-cli.ts +26 -7
  415. package/scripts/report/report-lint.ts +2 -20
  416. package/scripts/review/prose-stale-cli.ts +88 -0
  417. package/scripts/review/prose-stale-scan.ts +152 -0
  418. package/scripts/review/review-attest.ts +73 -23
  419. package/scripts/review/review-brief-cli.ts +68 -19
  420. package/scripts/review/review-brief-paths.ts +22 -0
  421. package/scripts/review/review-brief.ts +14 -7
  422. package/scripts/review/review-comment-carry.ts +47 -0
  423. package/scripts/review/review-comment-round.ts +85 -22
  424. package/scripts/review/review-finding-ledger.ts +109 -7
  425. package/scripts/review/review-finding-text.ts +43 -0
  426. package/scripts/review/review-interaction.ts +11 -0
  427. package/scripts/review/review-lane-handover.ts +68 -0
  428. package/scripts/review/review-lint-cli.ts +57 -0
  429. package/scripts/review/review-lint-findings.ts +92 -0
  430. package/scripts/review/review-lint-sections.ts +80 -0
  431. package/scripts/review/review-lint.ts +221 -0
  432. package/scripts/review/review-prior-findings.ts +102 -0
  433. package/scripts/review/review-readers-scan.ts +4 -2
  434. package/scripts/review/review-record-cli.ts +177 -54
  435. package/scripts/review/review-record-code-round.ts +55 -0
  436. package/scripts/review/review-record-comment.ts +60 -0
  437. package/scripts/review/review-record-interaction.ts +35 -0
  438. package/scripts/review/review-record-pinned.ts +108 -0
  439. package/scripts/review/review-record.ts +25 -1
  440. package/scripts/review/review-reviewed-tree.ts +307 -0
  441. package/scripts/review/review-round-one-closure.ts +62 -0
  442. package/scripts/review/review-round-reuse.ts +106 -0
  443. package/scripts/review/review-round2-cli.ts +91 -29
  444. package/scripts/review/review-round2-skip-comment.ts +55 -0
  445. package/scripts/review/review-round2.ts +24 -8
  446. package/scripts/review/review-stamps.ts +7 -3
  447. package/scripts/review/review-stop-log.ts +20 -6
  448. package/scripts/review/review-stops-cli.ts +2 -1
  449. package/scripts/review/review-submit-cli.ts +101 -0
  450. package/scripts/rules/agent-model.ts +1 -1
  451. package/scripts/rules/bash-triggers.ts +3 -3
  452. package/scripts/rules/concise-reply.ts +88 -0
  453. package/scripts/rules/credential-body.ts +77 -0
  454. package/scripts/rules/decision-oracle.ts +1 -1
  455. package/scripts/rules/delivered-rules.ts +36 -17
  456. package/scripts/rules/destructive-command.ts +3 -11
  457. package/scripts/rules/direct-issue-comment.ts +34 -12
  458. package/scripts/rules/direct-issue-read.ts +191 -0
  459. package/scripts/rules/direct-pr-create.ts +4 -24
  460. package/scripts/rules/early-heartbeat.ts +2 -0
  461. package/scripts/rules/edit-tool.ts +27 -0
  462. package/scripts/rules/file-edit-rows.ts +17 -0
  463. package/scripts/rules/file-rewrite.ts +146 -0
  464. package/scripts/rules/firing-point.ts +3 -2
  465. package/scripts/rules/gh-api.ts +128 -7
  466. package/scripts/rules/gh-repo-selector.ts +84 -0
  467. package/scripts/rules/git-force.ts +2 -2
  468. package/scripts/rules/guard-remedy.ts +14 -5
  469. package/scripts/rules/implementation-cut.ts +61 -28
  470. package/scripts/rules/investigator-foreground.ts +231 -0
  471. package/scripts/rules/issue-citation.ts +15 -60
  472. package/scripts/rules/issue-comments.ts +9 -4
  473. package/scripts/rules/josh-git-bare.ts +1 -1
  474. package/scripts/rules/lane-background.ts +41 -13
  475. package/scripts/rules/lane-direct-tool.ts +107 -9
  476. package/scripts/rules/lane-interactive-ask.ts +4 -1
  477. package/scripts/rules/lane-park.ts +4 -2
  478. package/scripts/rules/lane-spilled-read.ts +90 -0
  479. package/scripts/rules/lane-split-park.ts +1 -1
  480. package/scripts/rules/lane-switch-main.ts +4 -4
  481. package/scripts/rules/last-prompt.ts +20 -47
  482. package/scripts/rules/oracle-consulted.ts +1 -1
  483. package/scripts/rules/permission-guards.ts +5 -1
  484. package/scripts/rules/piped-verification-shapes.ts +110 -0
  485. package/scripts/rules/piped-verification.ts +67 -17
  486. package/scripts/rules/poll-loop.ts +72 -9
  487. package/scripts/rules/pr-merge.ts +5 -5
  488. package/scripts/rules/pre-gate-cut.ts +3 -3
  489. package/scripts/rules/protected-files.ts +88 -24
  490. package/scripts/rules/reply-language.ts +3 -17
  491. package/scripts/rules/reply-prose.ts +34 -0
  492. package/scripts/rules/repo-admin.ts +132 -0
  493. package/scripts/rules/reviewer-foreground.ts +88 -0
  494. package/scripts/rules/round-one-check-related.ts +120 -0
  495. package/scripts/rules/rule-body-guard.ts +5 -15
  496. package/scripts/rules/rule-value-cache.ts +53 -5
  497. package/scripts/rules/rule-value-candidates.ts +84 -0
  498. package/scripts/rules/rule-value-cli.ts +59 -11
  499. package/scripts/rules/rule-value.ts +17 -4
  500. package/scripts/rules/run-tail-rule.ts +1 -1
  501. package/scripts/rules/sed-in-place.ts +196 -0
  502. package/scripts/rules/shell-segments.ts +10 -2
  503. package/scripts/rules/stop-rule-rows.ts +1 -13
  504. package/scripts/rules/stop-rules.ts +33 -58
  505. package/scripts/rules/test-declared-commit.ts +1 -1
  506. package/scripts/rules/third-party-write.ts +110 -23
  507. package/scripts/rules/timed-rerun.ts +1 -1
  508. package/scripts/rules/turn-filings.ts +90 -0
  509. package/scripts/rules/worktree-guard.ts +22 -7
  510. package/scripts/run/board/run-board-ending-reason.ts +6 -2
  511. package/scripts/run/board/run-board-fit.ts +24 -1
  512. package/scripts/run/board/run-board-found.ts +134 -0
  513. package/scripts/run/board/run-board-header.ts +8 -0
  514. package/scripts/run/board/run-board-labels.ts +11 -1
  515. package/scripts/run/board/run-board-lane-time.ts +1 -0
  516. package/scripts/run/board/run-board-link.ts +15 -2
  517. package/scripts/run/board/run-board-notes.ts +7 -1
  518. package/scripts/run/board/run-board-operation.ts +4 -2
  519. package/scripts/run/board/run-board-phase.ts +2 -5
  520. package/scripts/run/board/run-board-plan.ts +1 -1
  521. package/scripts/run/board/run-board-read.ts +46 -1
  522. package/scripts/run/board/run-board-reason.ts +20 -8
  523. package/scripts/run/board/run-board-render-checks.ts +3 -2
  524. package/scripts/run/board/run-board-render-drawn.ts +11 -0
  525. package/scripts/run/board/run-board-render-found.ts +157 -0
  526. package/scripts/run/board/run-board-render-lead.ts +9 -0
  527. package/scripts/run/board/run-board-render-legend.ts +19 -0
  528. package/scripts/run/board/run-board-render-tail.ts +1 -1
  529. package/scripts/run/board/run-board-render.ts +82 -18
  530. package/scripts/run/board/run-board-spin.ts +1 -3
  531. package/scripts/run/board/run-board-status.ts +2 -0
  532. package/scripts/run/board/run-board-tick.ts +39 -10
  533. package/scripts/run/carry/run-carry-ended.ts +3 -2
  534. package/scripts/run/carry/run-carry.ts +3 -2
  535. package/scripts/run/cut/run-cut-cli.ts +33 -133
  536. package/scripts/run/cut/run-cut-digest.ts +152 -0
  537. package/scripts/run/cut/run-cut-handoff.ts +52 -8
  538. package/scripts/run/cut/run-cut-report.ts +24 -3
  539. package/scripts/run/cut/run-cut-resume.ts +129 -0
  540. package/scripts/run/cut/run-cut-review.ts +105 -0
  541. package/scripts/run/cut/run-cut.ts +18 -7
  542. package/scripts/run/detached-launch.ts +1 -1
  543. package/scripts/run/entry/run-entry-cli.ts +88 -19
  544. package/scripts/run/entry/run-entry-spill.ts +83 -0
  545. package/scripts/run/entry/run-entry-stop.ts +5 -1
  546. package/scripts/run/entry/run-entry-trust.ts +91 -0
  547. package/scripts/run/event/run-event-baseline.ts +56 -0
  548. package/scripts/run/event/run-event-filed.ts +9 -3
  549. package/scripts/run/event/run-event-overrun.ts +197 -0
  550. package/scripts/run/event/run-event-render.ts +4 -0
  551. package/scripts/run/event/run-event-stream.ts +25 -3
  552. package/scripts/run/hold/run-stop-notify.ts +3 -8
  553. package/scripts/run/merge/run-merge-cap.ts +57 -0
  554. package/scripts/run/merge/run-merge-cli.ts +66 -23
  555. package/scripts/run/merge/run-merge-outcome.ts +2 -0
  556. package/scripts/run/merge/run-merge-ship.ts +13 -3
  557. package/scripts/run/merge/run-merge-signals.ts +40 -23
  558. package/scripts/run/merge/run-merge-steps.ts +56 -36
  559. package/scripts/run/merge/run-merge-usage-limit.ts +53 -0
  560. package/scripts/run/merge/run-merge-withdrawn.ts +53 -0
  561. package/scripts/run/merge/run-merge.ts +41 -14
  562. package/scripts/run/review/run-review-cli.ts +306 -20
  563. package/scripts/run/review/run-review-early-push.ts +121 -0
  564. package/scripts/run/review/run-review-join-read.ts +94 -0
  565. package/scripts/run/review/run-review-pinned-accepted.ts +126 -0
  566. package/scripts/run/review/run-review-pinned-join.ts +216 -0
  567. package/scripts/run/review/run-review-pinned-steps.ts +383 -0
  568. package/scripts/run/review/run-review-pinned-tree.ts +37 -0
  569. package/scripts/run/review/run-review-pinned.ts +53 -0
  570. package/scripts/run/review/run-review-steps.ts +70 -34
  571. package/scripts/run/review/run-review.ts +26 -6
  572. package/scripts/run/run-parent-cut-hook.ts +3 -4
  573. package/scripts/run/run-prep.ts +1 -0
  574. package/scripts/run/run-stage-read.ts +2 -6
  575. package/scripts/run/run-step-cli.ts +17 -5
  576. package/scripts/run/run-step-lane-plan.ts +27 -0
  577. package/scripts/run/run-step-section.ts +26 -7
  578. package/scripts/run/run-step.ts +5 -2
  579. package/scripts/run/ship/run-ship-args.ts +19 -0
  580. package/scripts/run/ship/run-ship-brokered-review.ts +106 -0
  581. package/scripts/run/ship/run-ship-cli.ts +131 -39
  582. package/scripts/run/ship/run-ship-conflict-probe.ts +59 -0
  583. package/scripts/run/ship/run-ship-detach.ts +10 -4
  584. package/scripts/run/ship/run-ship-handover.ts +106 -0
  585. package/scripts/run/ship/run-ship-infra-retry.ts +16 -1
  586. package/scripts/run/ship/run-ship-lap.ts +63 -0
  587. package/scripts/run/ship/run-ship-next.ts +27 -26
  588. package/scripts/run/ship/run-ship-overlap.ts +8 -3
  589. package/scripts/run/ship/run-ship-place.ts +9 -2
  590. package/scripts/run/ship/run-ship-planned.ts +92 -0
  591. package/scripts/run/ship/run-ship-pre-detach-pinned.ts +197 -0
  592. package/scripts/run/ship/run-ship-pre-detach-timed.ts +7 -8
  593. package/scripts/run/ship/run-ship-pre-detach.ts +77 -23
  594. package/scripts/run/ship/run-ship-preflight.ts +16 -4
  595. package/scripts/run/ship/run-ship-probe.ts +23 -9
  596. package/scripts/run/ship/run-ship-relaunch-cap.ts +43 -7
  597. package/scripts/run/ship/run-ship-relaunch.ts +51 -0
  598. package/scripts/run/ship/run-ship-return.ts +103 -29
  599. package/scripts/run/ship/run-ship-review-reason.ts +24 -0
  600. package/scripts/run/ship/run-ship-review-steps.ts +230 -59
  601. package/scripts/run/ship/run-ship-review.ts +171 -51
  602. package/scripts/run/ship/run-ship-reviewer.ts +138 -42
  603. package/scripts/run/ship/run-ship-scoped.ts +39 -10
  604. package/scripts/run/ship/run-ship-stage.ts +49 -13
  605. package/scripts/run/ship/run-ship-steps.ts +24 -4
  606. package/scripts/run/ship/run-ship-stop-cause.ts +43 -2
  607. package/scripts/run/ship/run-ship-stop-context.ts +50 -13
  608. package/scripts/run/ship/run-ship-sync.ts +171 -30
  609. package/scripts/run/ship/run-ship-synced-scope.ts +178 -0
  610. package/scripts/run/ship/run-ship-wait-cli.ts +145 -0
  611. package/scripts/run/ship/run-ship-waiter.ts +114 -0
  612. package/scripts/run/ship/run-ship.ts +16 -2
  613. package/scripts/run/wake/run-wake-caffeinate.ts +48 -0
  614. package/scripts/run/wake/run-wake-cli.ts +6 -113
  615. package/scripts/run/wake/run-wake-code.ts +53 -11
  616. package/scripts/run/wake/run-wake-driver.ts +5 -3
  617. package/scripts/run/wake/run-wake-finish.ts +137 -0
  618. package/scripts/run/wake/run-wake-loop.ts +5 -3
  619. package/scripts/run/wake/run-wake-ports.ts +11 -3
  620. package/scripts/run/wake/run-wake-session.ts +2 -0
  621. package/scripts/run/wake/run-wake.ts +3 -2
  622. package/scripts/safe-chain/ci-installer-pin.ts +49 -8
  623. package/scripts/safe-chain/project-config.ts +3 -2
  624. package/scripts/security/secretlint-scan.ts +42 -9
  625. package/scripts/security/security-audit-provision-main.ts +9 -1
  626. package/scripts/security/security-audit-provision.ts +1 -1
  627. package/scripts/security/security-audit.ts +21 -1
  628. package/scripts/security/sonar-file.ts +10 -5
  629. package/scripts/split/split-assess.ts +12 -3
  630. package/scripts/split/split-early-notice.ts +116 -0
  631. package/scripts/split/split-measure.ts +20 -2
  632. package/scripts/split/split-resolution.ts +107 -0
  633. package/scripts/test/direct-importers.ts +185 -0
  634. package/scripts/test/pure-files-entries.ts +83 -0
  635. package/scripts/test/related-heavy-tests.ts +81 -0
  636. package/scripts/test/test-no-base.ts +88 -0
  637. package/scripts/test/test-pinned-cache-logic.ts +363 -0
  638. package/scripts/test/test-pinned-cache.ts +337 -0
  639. package/scripts/test/test-pinned-emit.ts +49 -0
  640. package/scripts/test/test-pinned-functions.ts +116 -0
  641. package/scripts/test/test-pinned-ledger.ts +80 -0
  642. package/scripts/test/test-pinned-logic.ts +208 -20
  643. package/scripts/test/test-pinned-main.ts +84 -18
  644. package/scripts/test/test-pinned-pool.ts +73 -0
  645. package/scripts/test/test-pinned-probe.ts +254 -0
  646. package/scripts/test/test-pinned-prune-logic.ts +118 -0
  647. package/scripts/test/test-pinned-reach.ts +194 -0
  648. package/scripts/test/test-pinned-record.ts +196 -0
  649. package/scripts/test/test-pinned-rewire.ts +148 -0
  650. package/scripts/test/test-pinned-spawn.ts +81 -0
  651. package/scripts/test/test-pinned-stage.ts +70 -0
  652. package/scripts/test/test-pinned.ts +258 -47
  653. package/scripts/test/test-reach-cli.ts +61 -0
  654. package/scripts/test/test-read-map.ts +35 -11
  655. package/scripts/test/test-read-recording.ts +17 -5
  656. package/scripts/test/test-read-trace.ts +26 -8
  657. package/scripts/test/test-red-logic.ts +46 -7
  658. package/scripts/test/test-red.ts +34 -14
  659. package/scripts/test/test-related-claim.ts +37 -0
  660. package/scripts/test/test-related-main.ts +4 -1
  661. package/scripts/test/test-related-moved.ts +91 -0
  662. package/scripts/test/test-related-record.ts +43 -23
  663. package/scripts/test/test-related-scope.ts +99 -34
  664. package/scripts/test/test-related-synced.ts +135 -0
  665. package/scripts/test/test-related-touched.ts +84 -0
  666. package/scripts/test/test-related.ts +167 -83
  667. package/scripts/test/test-unit-guard.ts +28 -5
  668. package/scripts/test/unit-durations.ts +41 -0
  669. package/scripts/test/unit-worker-share.ts +5 -4
  670. package/scripts/test/vitest-cache-directory.ts +19 -0
  671. package/scripts/test/vitest-cli-excludes.ts +14 -0
  672. package/scripts/test/vitest-failure-summary.ts +111 -0
  673. package/scripts/test/whole-suite-files.ts +12 -1
  674. package/scripts/time-runtime/time-batch-guard.ts +42 -4
  675. package/scripts/time-runtime/time-bundle-call.ts +1 -1
  676. package/scripts/time-runtime/time-bundles.ts +36 -5
  677. package/scripts/time-runtime/time-markers.ts +2 -2
  678. package/scripts/time-runtime/time-search-call.ts +38 -0
  679. package/scripts/time-runtime/time-shell.ts +1 -1
  680. package/scripts/time-runtime/time-transcript-line.ts +17 -5
  681. package/scripts/version/development-engines-verdict.ts +124 -0
  682. package/scripts/version/latest-corepack.ts +2 -0
  683. package/templates/gitignore +2 -0
  684. package/templates/workflows/ci.yml +41 -0
  685. package/dist/hooks/chunk-AZX4FGQ3.js +0 -207
  686. package/dist/hooks/chunk-PT5R6UJD.js +0 -7131
  687. package/dist/hooks/chunk-TUIFS5E7.js +0 -72
  688. package/dist/hooks/chunk-YCDOIR3I.js +0 -3456
  689. package/scripts/cost-runtime/context-cut-threshold.ts +0 -11
  690. package/scripts/rules/filing-cap.ts +0 -139
@@ -0,0 +1,192 @@
1
+ import type ts from 'typescript'
2
+
3
+ // The rewrite behind `josh rename` (joshuafolkken/kit#5236): one identifier and, optionally, one import
4
+ // specifier, renamed through the TypeScript parse tree rather than a pattern.
5
+ //
6
+ // **Only a binding is renamed, never a key.** `obj.old`, `{ old: 1 }` and `{ old: x } = obj` name a
7
+ // property of some other value, so they stay; a shorthand `{ old }` keeps its key and becomes
8
+ // `{ old: new }`. Strings and comments are not identifiers to the parser, so the walk never reaches
9
+ // them — a specifier is rewritten only where the module system reads it.
10
+
11
+ type TypeScriptApi = typeof ts
12
+
13
+ interface RenameRequest {
14
+ old_name: string
15
+ new_name: string
16
+ specifier?: readonly [string, string] | undefined
17
+ }
18
+
19
+ interface Replacement {
20
+ start: number
21
+ end: number
22
+ text: string
23
+ }
24
+
25
+ // `is_taken`: the new name is already a binding here, so the rename could shadow or merge with it —
26
+ // the rename matches by spelling, not by scope.
27
+ interface RenameResult {
28
+ text: string
29
+ count: number
30
+ is_taken: boolean
31
+ }
32
+
33
+ // Calls whose first argument is a module specifier the test runner resolves like an import.
34
+ const MODULE_CALLS: ReadonlySet<string> = new Set([
35
+ 'vi.mock',
36
+ 'vi.doMock',
37
+ 'vi.importActual',
38
+ 'vi.importMock',
39
+ ])
40
+ const NAME_KEY = 'name'
41
+
42
+ // The parents whose `name` is a property key rather than a binding.
43
+ function key_parent_kinds(api: TypeScriptApi): ReadonlySet<ts.SyntaxKind> {
44
+ const kind = api.SyntaxKind
45
+
46
+ return new Set([
47
+ kind.PropertyAccessExpression,
48
+ kind.PropertyAssignment,
49
+ kind.PropertyDeclaration,
50
+ kind.PropertySignature,
51
+ kind.MethodDeclaration,
52
+ kind.MethodSignature,
53
+ kind.GetAccessor,
54
+ kind.SetAccessor,
55
+ kind.EnumMember,
56
+ kind.JsxAttribute,
57
+ ])
58
+ }
59
+
60
+ function is_key_position(api: TypeScriptApi, node: ts.Identifier): boolean {
61
+ const { parent } = node
62
+
63
+ if (api.isQualifiedName(parent)) return parent.right === node
64
+ if (api.isBindingElement(parent)) return parent.propertyName === node
65
+
66
+ return key_parent_kinds(api).has(parent.kind) && Reflect.get(parent, NAME_KEY) === node
67
+ }
68
+
69
+ // A shorthand key is also the property's name, so the key is spelled out to keep it.
70
+ function keeps_key(api: TypeScriptApi, node: ts.Identifier): boolean {
71
+ const { parent } = node
72
+
73
+ if (api.isShorthandPropertyAssignment(parent)) return true
74
+
75
+ return (
76
+ api.isBindingElement(parent) &&
77
+ parent.propertyName === undefined &&
78
+ parent.dotDotDotToken === undefined &&
79
+ api.isObjectBindingPattern(parent.parent)
80
+ )
81
+ }
82
+
83
+ function identifier_replacement(
84
+ api: TypeScriptApi,
85
+ node: ts.Identifier,
86
+ request: RenameRequest,
87
+ ): Replacement | undefined {
88
+ if (node.text !== request.old_name || is_key_position(api, node)) return undefined
89
+ const text = keeps_key(api, node) ? `${node.text}: ${request.new_name}` : request.new_name
90
+
91
+ return { start: node.getStart(), end: node.getEnd(), text }
92
+ }
93
+
94
+ function is_module_call(
95
+ api: TypeScriptApi,
96
+ call: ts.CallExpression,
97
+ node: ts.StringLiteral,
98
+ ): boolean {
99
+ if (call.arguments.indexOf(node) !== 0) return false
100
+
101
+ return (
102
+ call.expression.kind === api.SyntaxKind.ImportKeyword ||
103
+ MODULE_CALLS.has(call.expression.getText())
104
+ )
105
+ }
106
+
107
+ function is_module_specifier(api: TypeScriptApi, node: ts.StringLiteral): boolean {
108
+ const { parent } = node
109
+
110
+ if (api.isImportDeclaration(parent) || api.isExportDeclaration(parent)) {
111
+ return parent.moduleSpecifier === node
112
+ }
113
+
114
+ if (api.isCallExpression(parent)) return is_module_call(api, parent, node)
115
+
116
+ return api.isLiteralTypeNode(parent) && api.isImportTypeNode(parent.parent)
117
+ }
118
+
119
+ function specifier_replacement(
120
+ api: TypeScriptApi,
121
+ node: ts.StringLiteral,
122
+ specifier: RenameRequest['specifier'],
123
+ ): Replacement | undefined {
124
+ if (specifier?.[0] !== node.text || !is_module_specifier(api, node)) return undefined
125
+ const start = node.getStart()
126
+ const quote = node.getSourceFile().text.charAt(start)
127
+
128
+ return { start, end: node.getEnd(), text: `${quote}${specifier[1]}${quote}` }
129
+ }
130
+
131
+ function replacement_at(
132
+ api: TypeScriptApi,
133
+ node: ts.Node,
134
+ request: RenameRequest,
135
+ ): Replacement | undefined {
136
+ if (api.isIdentifier(node)) return identifier_replacement(api, node, request)
137
+ if (api.isStringLiteral(node)) return specifier_replacement(api, node, request.specifier)
138
+
139
+ return undefined
140
+ }
141
+
142
+ // `forEachChild` never descends into JSDoc, so a name inside a doc comment stays as written.
143
+ function collect(
144
+ api: TypeScriptApi,
145
+ node: ts.Node,
146
+ request: RenameRequest,
147
+ into: Array<Replacement>,
148
+ ): void {
149
+ const replacement = replacement_at(api, node, request)
150
+
151
+ if (replacement !== undefined) into.push(replacement)
152
+ api.forEachChild(node, (child) => {
153
+ collect(api, child, request, into)
154
+ })
155
+ }
156
+
157
+ // Applied from the end of the file backwards, so an earlier offset is never moved by a later edit.
158
+ function apply(text: string, replacements: ReadonlyArray<Replacement>): string {
159
+ const backwards = replacements.toSorted((first, second) => second.start - first.start)
160
+ let result = text
161
+
162
+ for (const edit of backwards) {
163
+ result = `${result.slice(0, edit.start)}${edit.text}${result.slice(edit.end)}`
164
+ }
165
+
166
+ return result
167
+ }
168
+
169
+ function rewrite(
170
+ api: TypeScriptApi,
171
+ file_name: string,
172
+ text: string,
173
+ request: RenameRequest,
174
+ ): RenameResult {
175
+ const source = api.createSourceFile(file_name, text, api.ScriptTarget.Latest, true)
176
+ const replacements: Array<Replacement> = []
177
+ const existing: Array<Replacement> = []
178
+
179
+ collect(api, source, request, replacements)
180
+ collect(api, source, { old_name: request.new_name, new_name: request.new_name }, existing)
181
+
182
+ return {
183
+ text: apply(text, replacements),
184
+ count: replacements.length,
185
+ is_taken: existing.length > 0,
186
+ }
187
+ }
188
+
189
+ const rename_identifier = { rewrite }
190
+
191
+ export type { RenameRequest, RenameResult, TypeScriptApi }
192
+ export { rename_identifier }
@@ -0,0 +1,58 @@
1
+ import type ts from 'typescript'
2
+
3
+ // The module specifiers a file names only for their types: an `import type` or an
4
+ // `export type … from` declaration, which the transpiler drops whole, so the test runner's module graph
5
+ // never holds the edge (joshuafolkken/kit#5368). An `import { type A }` is left out: under
6
+ // `verbatimModuleSyntax` it stays as a side-effect import. A declaration is matched to the reference
7
+ // `preProcessFile` reports by where its specifier sits, never by its text, so a value import of the
8
+ // same module keeps its edge whichever declarations `preProcessFile` lists.
9
+ type TypeScript = typeof ts
10
+ type ModuleDeclaration = ts.ImportDeclaration | ts.ExportDeclaration
11
+
12
+ function declaration_of(
13
+ typescript: TypeScript,
14
+ statement: ts.Statement,
15
+ ): ModuleDeclaration | undefined {
16
+ if (typescript.isImportDeclaration(statement)) return statement
17
+ if (typescript.isExportDeclaration(statement)) return statement
18
+
19
+ return undefined
20
+ }
21
+
22
+ function is_type_only(typescript: TypeScript, declaration: ModuleDeclaration): boolean {
23
+ if (typescript.isExportDeclaration(declaration)) return declaration.isTypeOnly
24
+
25
+ return declaration.importClause?.phaseModifier === typescript.SyntaxKind.TypeKeyword
26
+ }
27
+
28
+ // Where the specifier's literal starts, its opening quote — the `pos` `preProcessFile` reports.
29
+ function type_only_position(
30
+ typescript: TypeScript,
31
+ source: ts.SourceFile,
32
+ statement: ts.Statement,
33
+ ): number | undefined {
34
+ const declaration = declaration_of(typescript, statement)
35
+ if (declaration === undefined || !is_type_only(typescript, declaration)) return undefined
36
+ const specifier = declaration.moduleSpecifier
37
+ if (specifier === undefined || !typescript.isStringLiteral(specifier)) return undefined
38
+
39
+ return specifier.getStart(source)
40
+ }
41
+
42
+ // The specifiers `preProcessFile` finds less the type-only declarations': the edges the test runner
43
+ // follows.
44
+ function runtime_specifiers(typescript: TypeScript, file: string, content: string): Array<string> {
45
+ const source = typescript.createSourceFile(file, content, typescript.ScriptTarget.Latest)
46
+ const type_only = new Set(
47
+ source.statements.map((statement) => type_only_position(typescript, source, statement)),
48
+ )
49
+
50
+ return typescript
51
+ .preProcessFile(content, true, true)
52
+ .importedFiles.filter((reference) => !type_only.has(reference.pos))
53
+ .map((reference) => reference.fileName)
54
+ }
55
+
56
+ const type_only_imports = { runtime_specifiers }
57
+
58
+ export { type_only_imports }
@@ -1,5 +1,6 @@
1
1
  import { gh_spawn } from '#scripts/gh/gh-spawn'
2
2
  import { timed_fetch } from '#scripts/lib/timed-fetch'
3
+ import { token_shape } from '#scripts/lib/token-shape'
3
4
  import { z } from 'zod'
4
5
  import { confirmation_options, type ConfirmationOptions } from './confirmation-options'
5
6
  import { notify_opt_in } from './notify-opt-in'
@@ -230,6 +231,14 @@ function build_text(input: TelegramSendInput): string {
230
231
  return join_blocks({ ...input, body: `${head_of(input.body, kept)}${BODY_TRUNCATION_MARK}` })
231
232
  }
232
233
 
234
+ // The text to send, refused when it holds a credential: the whole text is read, before the cut could
235
+ // leave a head no shape matches.
236
+ function outbound_text(input: TelegramSendInput): string {
237
+ token_shape.refuse(join_blocks(input), 'The Telegram message')
238
+
239
+ return build_text(input)
240
+ }
241
+
233
242
  async function post_message(config: TelegramConfig, text: string): Promise<void> {
234
243
  const url = `${TELEGRAM_API_BASE}/bot${config.bot_token}/sendMessage`
235
244
  const response = await timed_fetch(url, {
@@ -271,7 +280,7 @@ async function send(input: TelegramSendInput): Promise<void> {
271
280
  }
272
281
 
273
282
  const config = load_config()
274
- const text = build_text(input)
283
+ const text = outbound_text(input)
275
284
 
276
285
  try {
277
286
  await post_message(config, text)
@@ -283,7 +292,7 @@ async function send(input: TelegramSendInput): Promise<void> {
283
292
  }
284
293
 
285
294
  // **The tolerant form**, for a caller whose job is something other than the notification.
286
- // `followup` sends the completion message on its way to the merge, and a gateway timeout at
295
+ // `followup` sends the completion message beside the merge, and a gateway timeout at
287
296
  // Telegram is not a reason to leave a reviewed, green pull request unmerged. So the failure is
288
297
  // reported and the run carries on.
289
298
  //
@@ -298,7 +307,7 @@ async function send(input: TelegramSendInput): Promise<void> {
298
307
  //
299
308
  // **Not routed through `git_followup_cleanup`**, which is that Issue's mechanism: it guards the
300
309
  // steps a merge has already earned and says "failed after the merge" in its own wording, while this
301
- // send happens *before* the merge. Borrowing it would print a sentence that is not true.
310
+ // send never happens *after* the merge. Borrowing it would print a sentence that is not true.
302
311
  function report_send_failure(error: unknown, recovery: string | undefined): void {
303
312
  console.error('')
304
313
  console.error(`❗ ${describe_symptom(error)}`)
@@ -31,17 +31,32 @@ interface RecordRequest {
31
31
  now: Date
32
32
  }
33
33
 
34
- type RecordResult =
35
- | { verdict: typeof REFUSED_VERDICT; reason: string }
36
- | {
37
- verdict: typeof FILE_VERDICT | typeof LEDGER_VERDICT
38
- earlier: ReadonlyArray<string>
39
- line: string
40
- target: string
41
- }
34
+ interface Refusal {
35
+ verdict: typeof REFUSED_VERDICT
36
+ reason: string
37
+ }
38
+
39
+ interface Assessment {
40
+ verdict: typeof FILE_VERDICT | typeof LEDGER_VERDICT
41
+ earlier: ReadonlyArray<string>
42
+ line: string
43
+ }
44
+
45
+ type AssessResult = Refusal | Assessment
46
+
47
+ type RecordResult = Refusal | (Assessment & { target: string })
48
+
49
+ // Prettier's markdown pass collapses a whitespace run in a list item (only the whitespace is settled
50
+ // here; emphasis markers in a field are not), so a line keeping one (vitest's
51
+ // padded test names, joshuafolkken/kit#5303) fails a later gate's style check on a file it never wrote.
52
+ // Collapsed before the grammar check, so whitespace around a `|` that Prettier would turn into a
53
+ // separator is refused like a `|` already standing as one.
54
+ function collapsed(field: string): string {
55
+ return field.replaceAll(/\s+/gu, ' ').trim()
56
+ }
42
57
 
43
58
  function entry_line(entry: ObservationEntry, date: string): string {
44
- return `- k:${entry.slug} | ${entry.depth} | ${date} | ${entry.where} | ${entry.what}`
59
+ return `- k:${entry.slug} | ${entry.depth} | ${date} | ${collapsed(entry.where)} | ${collapsed(entry.what)}`
45
60
  }
46
61
 
47
62
  function refusal_of(entry: ObservationEntry, line: string): string | undefined {
@@ -58,8 +73,9 @@ function sightings(ledger: string | undefined, slug: string): ReadonlyArray<stri
58
73
  return (ledger ?? '').split('\n').filter((line) => line.startsWith(prefix))
59
74
  }
60
75
 
61
- // The count is read before the append, so it is the sightings *before* this one.
62
- async function record(request: RecordRequest): Promise<RecordResult> {
76
+ // The line, the earlier sightings and the verdict, with nothing appended — for a caller that keeps the
77
+ // line somewhere other than the tree (`followup-failed-tests.ts` posts it on the issue).
78
+ async function assess(request: RecordRequest): Promise<AssessResult> {
63
79
  const date = observation_ledger_home.ledger_date(request.now)
64
80
  const line = entry_line(request.entry, date)
65
81
  const reason = refusal_of(request.entry, line)
@@ -70,22 +86,32 @@ async function record(request: RecordRequest): Promise<RecordResult> {
70
86
  await observation_ledger_home.read(request.checkout),
71
87
  request.entry.slug,
72
88
  )
73
- const target = await observation_ledger_home.writer_path(request.now, request.checkout)
89
+ const verdict = earlier.length === PROMOTING_COUNT ? FILE_VERDICT : LEDGER_VERDICT
74
90
 
75
- await observation_ledger_home.append(target, [line])
91
+ return { verdict, earlier, line }
92
+ }
76
93
 
77
- const verdict = earlier.length === PROMOTING_COUNT ? FILE_VERDICT : LEDGER_VERDICT
94
+ // The count is read before the append, so it is the sightings *before* this one.
95
+ async function record(request: RecordRequest): Promise<RecordResult> {
96
+ const assessment = await assess(request)
97
+
98
+ if (assessment.verdict === REFUSED_VERDICT) return assessment
99
+
100
+ const target = await observation_ledger_home.writer_path(request.now, request.checkout)
101
+
102
+ await observation_ledger_home.append(target, [assessment.line])
78
103
 
79
- return { verdict, earlier, line, target }
104
+ return { ...assessment, target }
80
105
  }
81
106
 
82
- const observation_record = { record }
107
+ const observation_record = { assess, record }
83
108
 
84
109
  export {
85
110
  FILE_VERDICT,
86
111
  LEDGER_VERDICT,
87
112
  observation_record,
88
113
  REFUSED_VERDICT,
114
+ type AssessResult,
89
115
  type ObservationEntry,
90
116
  type RecordResult,
91
117
  }
@@ -3,6 +3,7 @@ import { git_command } from '#scripts/git/git-command'
3
3
  import { main_sync } from '#scripts/git/main-sync'
4
4
  import { IGNORE_FOR_RELEASE_LABEL } from '#scripts/issue/issue-labels'
5
5
  import { error_text } from '#scripts/lib/error-message'
6
+ import { review_comment_carry } from '#scripts/review/review-comment-carry'
6
7
  import { observation_ledger, OBSERVATION_LEDGER_DIRECTORY } from './observation-ledger'
7
8
  import type { BrokenLine } from './observation-ledger-line'
8
9
  import { observation_ledger_prepare } from './observation-ledger-prepare'
@@ -12,7 +13,8 @@ import { observations_flush_landing } from './observations-flush-landing'
12
13
  // a lane's included — commits its appended lines with its own pull request (`scripts/git/
13
14
  // git-staging.ts`), and `pnpm josh followup` commits a
14
15
  // line appended after that commit before it merges, so what is left here is a line written on the
15
- // default branch outside any issue's run — the date-named file `observation-ledger-home.ts` resolves.
16
+ // default branch outside any issue's run — the date-named file `observation-ledger-home.ts` resolves —
17
+ // and the closed issues' comment rounds no lane carries (`flush` below).
16
18
  //
17
19
  // **The shape is `scripts/release/release-publish.ts`'s, deliberately.** Both open a pull request of
18
20
  // their own over one path, wait on the same required checks every other pull request waits on, and
@@ -393,6 +395,27 @@ async function prepare_ledger(): Promise<void> {
393
395
  if (broken.length > 0) throw new Error(broken_lines_message(broken))
394
396
  }
395
397
 
398
+ // The checkout made safe and caught up: a carried file an earlier flush left uncommitted is discarded
399
+ // first, since it would make git refuse the fast-forward (`review-comment-carry.ts`).
400
+ async function ready_default_branch(status_output: string): Promise<string> {
401
+ const default_branch = await refuse_unsafe_flush(status_output)
402
+
403
+ review_comment_carry.discard_uncommitted(status_output, process.cwd())
404
+ await catch_up_default(default_branch)
405
+
406
+ return default_branch
407
+ }
408
+
409
+ // **The closed issues' comment rounds are carried only once a flush will go ahead**
410
+ // (joshuafolkken/kit#5326): a lane child leaves them to this flush, so the carried files ride its pull
411
+ // request, and the status is read again so a carry alone is a change to flush. A carry left behind by
412
+ // a later stop is discarded by the next flush's `ready_default_branch`.
413
+ async function carried_status(): Promise<string> {
414
+ await review_comment_carry.carry_reported(process.cwd())
415
+
416
+ return await git_command.status()
417
+ }
418
+
396
419
  // **Nothing pulls in front of the branch, and that is deliberate.** The ledger is dirty by
397
420
  // definition at this point, so `git pull --ff-only` aborts on it in exactly the case a pull would
398
421
  // have been for — an upstream flush that already advanced the ledger — and reports a failure about
@@ -401,19 +424,19 @@ async function prepare_ledger(): Promise<void> {
401
424
  // only where git can do it without touching the ledger: a default branch
402
425
  // that predates another merged flush still stops here — before a branch is cut — rather than opening
403
426
  // a pull request that cannot merge. An earlier flush pull request still open is checked for the same
404
- // reason: a branch cut beside it conflicts with it at the ledger's tail.
427
+ // reason: a branch cut beside it conflicts with it at the ledger's tail. So the order is: ready the
428
+ // default branch, defer to an open flush, carry, then check, prepare and land.
405
429
  async function flush(now: Date): Promise<string> {
406
- const status_output = await git_command.status()
407
- const default_branch = await refuse_unsafe_flush(status_output)
408
-
409
- if (!has_ledger_change(status_output)) return CLEAN_MESSAGE
410
-
411
- await prepare_ledger()
430
+ const default_branch = await ready_default_branch(await git_command.status())
412
431
 
413
432
  const deferred = await observations_flush_landing.refuse_open_flush(BRANCH_PREFIX)
414
433
  if (deferred !== undefined) return deferred
415
434
 
416
- await catch_up_default(default_branch)
435
+ const status_output = await carried_status()
436
+
437
+ if (!has_ledger_change(status_output)) return CLEAN_MESSAGE
438
+
439
+ await prepare_ledger()
417
440
 
418
441
  const branch_name = branch_name_for(timestamp_for(now))
419
442
 
@@ -13,6 +13,7 @@ import { fileURLToPath } from 'node:url'
13
13
  import { cli_flags } from '#scripts/lib/cli-flags'
14
14
  import { file_reader } from '#scripts/lib/read-file'
15
15
  import { overrides_snapshot_schema } from '#scripts/lib/schemas'
16
+ import { development_engines_verdict } from '#scripts/version/development-engines-verdict'
16
17
  import { overrides_files } from './overrides-files'
17
18
  import { overrides_check, type OverridesDiff } from './overrides-logic'
18
19
 
@@ -71,6 +72,13 @@ function run_overrides_check(should_save: boolean): void {
71
72
  console.info(`✔ overrides unchanged (${summary}).`)
72
73
  }
73
74
 
75
+ // The `devEngines` verdict rides on every check, whatever the overrides answer, so it is printed
76
+ // before the overrides comparison can exit.
77
+ function run_check(should_save: boolean): void {
78
+ development_engines_verdict.report()
79
+ run_overrides_check(should_save)
80
+ }
81
+
74
82
  // A line nobody can read is refused before the snapshot is read or written: a misspelled `--save` that
75
83
  // fell through would compare against the record the caller meant to replace.
76
84
  function refuse_usage(): never {
@@ -83,7 +91,7 @@ function main(argv: ReadonlyArray<string>): void {
83
91
  const values = cli_flags.values_of(argv, OPTIONS)
84
92
 
85
93
  if (values === undefined) refuse_usage()
86
- run_overrides_check(values.save)
94
+ run_check(values.save)
87
95
  }
88
96
 
89
97
  if (process.argv[1] === fileURLToPath(import.meta.url)) main(process.argv.slice(ARGV_OFFSET))
@@ -8,11 +8,17 @@ import { git_spawn } from '#scripts/git/git-spawn'
8
8
  // no verdict. `--ignore-unmatch` makes a repository with no approvals a no-op.
9
9
 
10
10
  const APPROVAL_DIRECTORY = '.josh/metrics-accepted'
11
+ const APPROVAL_PREFIX = `${APPROVAL_DIRECTORY}/`
11
12
 
12
13
  async function prune(): Promise<void> {
13
14
  await git_spawn.read(['rm', '-r', '-q', '--ignore-unmatch', '--', APPROVAL_DIRECTORY])
14
15
  }
15
16
 
16
- const release_approval_prune = { APPROVAL_DIRECTORY, prune }
17
+ // A repository-relative path under the approval directory.
18
+ function is_approval(file: string): boolean {
19
+ return file.startsWith(APPROVAL_PREFIX)
20
+ }
21
+
22
+ const release_approval_prune = { APPROVAL_DIRECTORY, is_approval, prune }
17
23
 
18
24
  export { release_approval_prune }
@@ -22,7 +22,10 @@ const REQUIRED_STATUS_CHECKS = 'required_status_checks'
22
22
  const NOT_FOUND_STATUS = 404
23
23
 
24
24
  const DISTRIBUTED_CHECKS: ReadonlyArray<WorkflowChecks> = [
25
- { workflow: CI_WORKFLOW, checks: ['Checks', 'Detect E2E', 'E2E', 'Security Audit'] },
25
+ {
26
+ workflow: CI_WORKFLOW,
27
+ checks: ['Checks', 'Detect E2E', 'E2E', 'Secret Scan', 'Security Audit'],
28
+ },
26
29
  { workflow: SONAR_WORKFLOW, checks: ['SonarQube'] },
27
30
  { workflow: CLASSIFICATION_WORKFLOW, checks: ['Release classification'] },
28
31
  ]
@@ -1,4 +1,5 @@
1
1
  import path from 'node:path'
2
+ import { git_gh_api_path } from '#scripts/gh/git-gh-api-path'
2
3
  import { git_gh_exec } from '#scripts/gh/git-gh-exec'
3
4
  import { gh_failure } from '#scripts/gh/git-gh-failure'
4
5
  import { PROJECT_ROOT } from '#scripts/init/init-paths'
@@ -37,7 +38,7 @@ function read_default_branch(repo: string): string | undefined {
37
38
  function read_protection(repo: string, branch: string): ApiRead {
38
39
  try {
39
40
  const stdout = git_gh_exec.exec_gh_api_sync({
40
- path: `repos/${repo}/branches/${branch}/protection/required_status_checks`,
41
+ path: git_gh_api_path.branch_protection_checks_api_path(branch, repo),
41
42
  cwd: PROJECT_ROOT,
42
43
  timeout_ms: repo_setting.GH_TIMEOUT_MS,
43
44
  })
@@ -52,7 +53,7 @@ function read_protection(repo: string, branch: string): ApiRead {
52
53
  // there rather than letting protection alone pass for the whole answer.
53
54
  function read_source(repo: string, branch: string): RequiredSource {
54
55
  const from_rules = required_checks_logic.parse_branch_rules(
55
- read_api(`repos/${repo}/rules/branches/${branch}`),
56
+ read_api(git_gh_api_path.branch_rules_api_path(branch, repo)),
56
57
  )
57
58
  if (from_rules.kind === 'unreadable') return from_rules
58
59
  const from_protection = required_checks_logic.parse_protection(read_protection(repo, branch))
@@ -95,7 +96,7 @@ function apply_to_ruleset(repo: string, ruleset_id: number, missing: ReadonlyArr
95
96
 
96
97
  function apply_to_protection(repo: string, branch: string, missing: ReadonlyArray<string>): void {
97
98
  git_gh_exec.exec_gh_api_sync({
98
- path: `repos/${repo}/branches/${branch}/protection/required_status_checks/contexts`,
99
+ path: `${git_gh_api_path.branch_protection_checks_api_path(branch, repo)}/contexts`,
99
100
  method: 'POST',
100
101
  body: required_checks_logic.protection_update_body(missing),
101
102
  cwd: PROJECT_ROOT,
@@ -0,0 +1,28 @@
1
+ // The shape checks the fixed-shape linters share — `report:lint`, its `--child-summary` mode and
2
+ // `review:lint` — kept in one place so the fence rule and the line count read the same in all three.
3
+
4
+ const FENCE_MARKER = '```'
5
+
6
+ // The non-blank lines: what a line bound counts and what the first-line checks read.
7
+ function content_lines(text: string): ReadonlyArray<string> {
8
+ return text.split('\n').filter((line) => line.trim().length > 0)
9
+ }
10
+
11
+ function first_content_line(text: string): string {
12
+ return content_lines(text)[0]?.trim() ?? ''
13
+ }
14
+
15
+ function is_fenced(text: string): boolean {
16
+ return first_content_line(text).startsWith(FENCE_MARKER)
17
+ }
18
+
19
+ // `subject` names the artifact in the message: `summary`, `review`.
20
+ function fence_violation(text: string, subject: string): ReadonlyArray<string> {
21
+ return is_fenced(text)
22
+ ? [`✖ the ${subject} is wrapped in a code fence — write it as plain markdown`]
23
+ : []
24
+ }
25
+
26
+ const markdown_shape = { content_lines, first_content_line, fence_violation }
27
+
28
+ export { markdown_shape }
@@ -10,15 +10,29 @@ const SUMMARY_TEMPLATE_HEADING = '作業前サマリ(セッション向け・`
10
10
  const COMPLETION_REPORT_HEADING = '完了報告(セッション向け)'
11
11
  const ACCEPTANCE_MAP_HEADING = 'PR 本文の受け入れ条件の対応表'
12
12
  const REMOVED_TESTS_HEADING = 'PR 本文の消えたテストの処置'
13
+ // The lane child's summary is shaped in the backlogrun child's document, not in `report-format.md`.
14
+ const CHILD_SUMMARY_PATH = '.claude/skills/workflow-commands/backlogrun-child.md'
15
+ const CHILD_SUMMARY_HEADING = 'What the summary carries, and how long it may be'
13
16
 
14
17
  // The heading goes in single quotes in the runnable form: the template heading carries backticks,
15
18
  // which a double-quoted shell argument would run as a command substitution.
19
+ function section_pointer(path: string, heading: string): string {
20
+ return `${path} → "${heading}" (read it: pnpm josh doc:section ${path} '${heading}')`
21
+ }
22
+
16
23
  function pointer(heading: string): string {
17
- return `${REPORT_FORMAT_PATH} → "${heading}" (read it: pnpm josh doc:section ${REPORT_FORMAT_PATH} '${heading}')`
24
+ return section_pointer(REPORT_FORMAT_PATH, heading)
25
+ }
26
+
27
+ function child_summary_pointer(): string {
28
+ return section_pointer(CHILD_SUMMARY_PATH, CHILD_SUMMARY_HEADING)
18
29
  }
19
30
 
20
31
  const report_format_reference = {
21
32
  ACCEPTANCE_MAP_HEADING,
33
+ CHILD_SUMMARY_HEADING,
34
+ CHILD_SUMMARY_PATH,
35
+ child_summary_pointer,
22
36
  COMPLETION_REPORT_HEADING,
23
37
  pointer,
24
38
  REMOVED_TESTS_HEADING,
@@ -141,6 +141,11 @@ const ENGLISH_LABELS: ReportLabels = {
141
141
  handoff: ENGLISH_HANDOFF_LABELS,
142
142
  }
143
143
 
144
+ // A lane child's summary holds at most this many non-blank lines — the bound
145
+ // `backlogrun-child.md` → "What the summary carries, and how long it may be" states and
146
+ // `report:lint --child-summary` checks, beside the `cause` / `fix` / `result` labels above.
147
+ const CHILD_SUMMARY_MAX_LINES = 25
148
+
144
149
  function labels_for(lang: string): ReportLabels {
145
150
  return session_language.is_japanese(lang) ? JAPANESE_LABELS : ENGLISH_LABELS
146
151
  }
@@ -149,7 +154,13 @@ function session_labels(): ReportLabels {
149
154
  return labels_for(session_language.resolve_session_lang().lang)
150
155
  }
151
156
 
152
- const report_labels = { ENGLISH_LABELS, JAPANESE_LABELS, labels_for, session_labels }
157
+ const report_labels = {
158
+ CHILD_SUMMARY_MAX_LINES,
159
+ ENGLISH_LABELS,
160
+ JAPANESE_LABELS,
161
+ labels_for,
162
+ session_labels,
163
+ }
153
164
 
154
165
  export type { HandoffLabels, ReportLabels }
155
166
  export { report_labels }