@joshuafolkken/kit 1.1035.0 → 1.1094.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (605) hide show
  1. package/.claude/settings.json +9 -8
  2. package/.claude/skills/epic-commands/SKILL.md +5 -7
  3. package/.claude/skills/verify-ui/SKILL.md +1 -1
  4. package/.claude/skills/workflow-commands/SKILL.md +21 -13
  5. package/.claude/skills/workflow-commands/background-commands.md +5 -4
  6. package/.claude/skills/workflow-commands/backlogrun-child.md +3 -3
  7. package/.claude/skills/workflow-commands/backlogrun-lanes.md +9 -7
  8. package/.claude/skills/workflow-commands/backlogrun-park.md +6 -0
  9. package/.claude/skills/workflow-commands/backlogrun-progress.md +31 -37
  10. package/.claude/skills/workflow-commands/backlogrun-steps.md +25 -25
  11. package/.claude/skills/workflow-commands/backlogrun.md +2 -2
  12. package/.claude/skills/workflow-commands/chain-rule.md +6 -4
  13. package/.claude/skills/workflow-commands/delegation.md +3 -3
  14. package/.claude/skills/workflow-commands/followup-reference.md +3 -3
  15. package/.claude/skills/workflow-commands/followup.md +7 -3
  16. package/.claude/skills/workflow-commands/fullrun-steps.md +3 -2
  17. package/.claude/skills/workflow-commands/fullrun.md +3 -2
  18. package/.claude/skills/workflow-commands/halfrun.md +16 -19
  19. package/.claude/skills/workflow-commands/issue-comments.md +2 -2
  20. package/.claude/skills/workflow-commands/issue-fold-existing.md +10 -10
  21. package/.claude/skills/workflow-commands/issue-scout.md +1 -1
  22. package/.claude/skills/workflow-commands/kickoff.md +9 -4
  23. package/.claude/skills/workflow-commands/latest-gate.md +1 -1
  24. package/.claude/skills/workflow-commands/needs-human-review.md +1 -1
  25. package/.claude/skills/workflow-commands/observation-filing.md +44 -89
  26. package/.claude/skills/workflow-commands/pre-gate-cut.md +33 -36
  27. package/.claude/skills/workflow-commands/prerequisite.md +1 -1
  28. package/.claude/skills/workflow-commands/prrun.md +36 -0
  29. package/.claude/skills/workflow-commands/retrospective.md +1 -1
  30. package/.claude/skills/workflow-commands/working-tree-hold.md +24 -4
  31. package/.codex/hooks.json +16 -20
  32. package/.github/actions/setup-pnpm/action.yml +93 -0
  33. package/.github/dependabot.yml +5 -1
  34. package/.github/workflows/auto-tag.yml +21 -0
  35. package/.github/workflows/ci.yml +26 -128
  36. package/.github/workflows/pr-classification.yml +5 -41
  37. package/.github/workflows/publish.yml +42 -48
  38. package/.github/workflows/sonar-qube.yml +37 -4
  39. package/AGENTS.md +12 -2
  40. package/CLAUDE.md +15 -16
  41. package/GEMINI.md +14 -2
  42. package/README.md +59 -18
  43. package/SECURITY.md +36 -6
  44. package/cspell/index.yaml +2 -1
  45. package/dist/CLAUDE.md +15 -16
  46. package/dist/config-merge/index.js +15 -3
  47. package/dist/hooks/batch-guard.js +4 -4
  48. package/dist/hooks/{chunk-Y27M6A7X.js → chunk-3C4YCCEF.js} +5 -13
  49. package/dist/hooks/{chunk-D67KVGGY.js → chunk-7ZPFAVR7.js} +17 -88
  50. package/dist/hooks/{chunk-HOYJU5RM.js → chunk-E54KGFEQ.js} +11 -4
  51. package/dist/hooks/{chunk-KG6PZD72.js → chunk-IL27YTPH.js} +2 -2
  52. package/dist/hooks/{chunk-GJT4BNVE.js → chunk-KHWHKJOM.js} +3 -3
  53. package/dist/hooks/{chunk-HU66PWWL.js → chunk-M2XDCUKD.js} +1076 -509
  54. package/dist/hooks/{chunk-GLBDBJOK.js → chunk-NKOG3XAV.js} +199 -304
  55. package/dist/hooks/{chunk-ZXNE6NY3.js → chunk-O4LL4HTI.js} +2 -7
  56. package/dist/hooks/{chunk-XPLP27WA.js → chunk-OIZUHPJI.js} +5 -27
  57. package/dist/hooks/{chunk-EIFCAJRB.js → chunk-UD24EAIL.js} +2546 -1636
  58. package/dist/hooks/codex-hook-adapter.js +10 -11
  59. package/dist/hooks/duplicate-read-guard.js +5 -5
  60. package/dist/hooks/format-edited.js +15 -34
  61. package/dist/hooks/inputs.json +279 -0
  62. package/dist/hooks/investigation-guard.js +5 -5
  63. package/dist/hooks/pretool-guard.js +23 -16
  64. package/dist/hooks/session-lang.js +0 -1
  65. package/dist/hooks/stop-guard.js +188 -509
  66. package/dist/josh.js +166 -225
  67. package/dist/managed-marker/index.js +2 -1
  68. package/dist/version/index.js +412 -64
  69. package/eslint/rules/promise.js +5 -0
  70. package/package.json +13 -8
  71. package/prompts/collaboration-workflow/file-edits.md +6 -53
  72. package/prompts/collaboration-workflow/issue-citation.md +5 -5
  73. package/prompts/collaboration-workflow/operating-rules.md +4 -4
  74. package/prompts/collaboration-workflow/overview.md +13 -1
  75. package/prompts/collaboration-workflow/report-format.md +1 -1
  76. package/prompts/collaboration-workflow/residency.md +4 -4
  77. package/prompts/collaboration-workflow/rule-delivery.md +5 -36
  78. package/prompts/collaboration-workflow/shell-body.md +7 -9
  79. package/prompts/collaboration-workflow/turn-batching.md +21 -37
  80. package/prompts/collaboration-workflow/upstream-interrupt.md +1 -1
  81. package/prompts/collaboration-workflow/wip-cap.md +36 -36
  82. package/prompts/collaboration-workflow.md +5 -8
  83. package/prompts/review-rubric.md +1 -1
  84. package/prompts/review.md +3 -3
  85. package/prompts/sonar-hotspot-handling.md +12 -4
  86. package/prompts/testing-guide.md +3 -3
  87. package/scripts/adopt/adopt-toolkits.ts +2 -2
  88. package/scripts/adopt/adopt.ts +0 -2
  89. package/scripts/agent/agent-argv.ts +0 -2
  90. package/scripts/agent/agent-diagnostics.ts +1 -1
  91. package/scripts/agent/agent-role-profile.ts +0 -7
  92. package/scripts/agent/claude-agent-argv.ts +0 -2
  93. package/scripts/agent/codex-agent-argv.ts +1 -1
  94. package/scripts/agent/codex-hooks.ts +92 -0
  95. package/scripts/agent/interactive-ask.ts +1 -1
  96. package/scripts/auto-ok/auto-ok-cli.ts +15 -25
  97. package/scripts/backlog/backlog-budget.ts +0 -2
  98. package/scripts/backlog/backlog-defect-priority.ts +2 -2
  99. package/scripts/backlog/backlog-drive-cli.ts +10 -8
  100. package/scripts/backlog/backlog-drive-named-offer.ts +16 -3
  101. package/scripts/backlog/backlog-drive-named.ts +2 -1
  102. package/scripts/backlog/backlog-drive.ts +76 -16
  103. package/scripts/backlog/backlog-named.ts +0 -3
  104. package/scripts/backlog/backlog-next.ts +32 -22
  105. package/scripts/backlog/backlog-offer-cli.ts +0 -5
  106. package/scripts/backlog/backlog-plan-cli.ts +6 -8
  107. package/scripts/backlog/backlog-plan.ts +1 -1
  108. package/scripts/backlog/backlog-pool.ts +34 -17
  109. package/scripts/backlog/backlog-rank.ts +106 -0
  110. package/scripts/backlog/backlog-ready.ts +19 -3
  111. package/scripts/backlog/backlog-scope.ts +1 -3
  112. package/scripts/backlog/backlog-stalled-detect.ts +2 -2
  113. package/scripts/backlog/backlog-stalled.ts +0 -1
  114. package/scripts/backlog/backlog-waves.ts +47 -31
  115. package/scripts/behavior/behavior-cli.ts +1 -1
  116. package/scripts/build/build-codex-hooks.ts +26 -0
  117. package/scripts/build/build-hooks.ts +92 -11
  118. package/scripts/build/hook-bundle-stamp.ts +111 -0
  119. package/scripts/cases/cases-cli.ts +1 -1
  120. package/scripts/cases/cases-logic.ts +1 -1
  121. package/scripts/ci/composite-actions.ts +30 -0
  122. package/scripts/ci/pr-classification.ts +3 -3
  123. package/scripts/claude/workflow-destination.ts +10 -1
  124. package/scripts/clone/clone-fingerprint.ts +0 -1
  125. package/scripts/clone/clone-scan-cli.ts +1 -1
  126. package/scripts/clone/clone-scan.ts +1 -1
  127. package/scripts/config-merge/json-format.ts +0 -1
  128. package/scripts/config-merge/patch-yaml-list.ts +1 -1
  129. package/scripts/cost-runtime/codex-usage.ts +2 -9
  130. package/scripts/cost-runtime/cost-attribute.ts +0 -1
  131. package/scripts/cost-runtime/cost-cli.ts +0 -3
  132. package/scripts/cost-runtime/cost-corpus.ts +0 -2
  133. package/scripts/cost-runtime/cost-format.ts +0 -3
  134. package/scripts/cost-runtime/cost-pricing.ts +0 -1
  135. package/scripts/cost-runtime/cost-tokens.ts +0 -1
  136. package/scripts/delegation/delegation-cli.ts +1 -1
  137. package/scripts/delegation/delegation-policy.ts +11 -1
  138. package/scripts/delegation/duplicate-read-guard.ts +0 -8
  139. package/scripts/delegation/fanout-cli.ts +1 -1
  140. package/scripts/delegation/fanout.ts +0 -2
  141. package/scripts/delegation/investigation-reads.ts +1 -164
  142. package/scripts/discovery/repo-map-logic.ts +0 -1
  143. package/scripts/discovery/repo-party-cli.ts +1 -1
  144. package/scripts/doctor/doctor-consumer.ts +4 -6
  145. package/scripts/doctor/doctor-logic.ts +0 -4
  146. package/scripts/doctor/doctor.ts +14 -9
  147. package/scripts/document/document-byte-budget.ts +8 -9
  148. package/scripts/document/document-byte-check.ts +0 -1
  149. package/scripts/document/document-read-cli.ts +0 -2
  150. package/scripts/document/document-section-cli.ts +1 -1
  151. package/scripts/document/document-section.ts +0 -3
  152. package/scripts/document/edit-files-cli.ts +0 -1
  153. package/scripts/document/entry-read-budget.ts +13 -4
  154. package/scripts/document/lane-child-read-set.ts +1 -6
  155. package/scripts/document/read-files-cli.ts +0 -4
  156. package/scripts/document/read-set-cli.ts +0 -2
  157. package/scripts/document/read-set-point-of-use.ts +1 -0
  158. package/scripts/document/read-set-pricing.ts +0 -1
  159. package/scripts/document/read-set-trim.ts +1 -1
  160. package/scripts/epic/epic-add.ts +1 -1
  161. package/scripts/epic/epic-audit-cli.ts +1 -4
  162. package/scripts/epic/epic-audit-orphans.ts +1 -3
  163. package/scripts/epic/epic-audit-rationale.ts +0 -1
  164. package/scripts/epic/epic-audit-report.ts +0 -2
  165. package/scripts/epic/epic-audit.ts +5 -4
  166. package/scripts/epic/epic-bundle-cli.ts +1 -1
  167. package/scripts/epic/epic-bundle-evidence.ts +0 -1
  168. package/scripts/epic/epic-bundle-referenced.ts +1 -5
  169. package/scripts/epic/epic-bundle.ts +0 -4
  170. package/scripts/epic/epic-busy.ts +4 -5
  171. package/scripts/epic/epic-candidate-confirm.ts +0 -5
  172. package/scripts/epic/epic-classify.ts +2 -2
  173. package/scripts/epic/epic-cli-argv.ts +0 -1
  174. package/scripts/epic/epic-close-comment.ts +1 -1
  175. package/scripts/epic/epic-close.ts +5 -2
  176. package/scripts/epic/epic-cross-repo.ts +2 -4
  177. package/scripts/epic/epic-decision.ts +0 -1
  178. package/scripts/epic/epic-fetch.ts +2 -2
  179. package/scripts/epic/epic-index.ts +2 -3
  180. package/scripts/epic/epic-issue.ts +1 -15
  181. package/scripts/epic/epic-lane-offer.ts +20 -30
  182. package/scripts/epic/epic-nested.ts +1 -1
  183. package/scripts/epic/epic-next-read.ts +1 -3
  184. package/scripts/epic/epic-next-views.ts +0 -1
  185. package/scripts/epic/epic-next.ts +1 -10
  186. package/scripts/epic/epic-parse.ts +0 -1
  187. package/scripts/epic/epic-promote.ts +0 -9
  188. package/scripts/epic/epic-rank.ts +37 -0
  189. package/scripts/epic/epic-read.ts +1 -2
  190. package/scripts/epic/epic-reconcile.ts +1 -1
  191. package/scripts/epic/epic-reference.ts +1 -13
  192. package/scripts/epic/epic-relation-recheck.ts +1 -1
  193. package/scripts/epic/epic-relations.ts +1 -1
  194. package/scripts/epic/epic-remove.ts +1 -1
  195. package/scripts/epic/epic-report.ts +0 -1
  196. package/scripts/epic/epic-run.ts +2 -3
  197. package/scripts/epic/epic-shape.ts +1 -1
  198. package/scripts/epic/epic-solo-stale.ts +107 -0
  199. package/scripts/epic/epic-solo.ts +32 -30
  200. package/scripts/epic/epic-triage.ts +1 -1
  201. package/scripts/epic/epic-validate.ts +1 -1
  202. package/scripts/epic/epic.ts +1 -1
  203. package/scripts/exports/unused-members-cli.ts +53 -0
  204. package/scripts/{git → followup}/followup-issue-number.ts +1 -6
  205. package/scripts/{git → followup}/git-followup-cleanup.ts +2 -1
  206. package/scripts/{git → followup}/git-followup-finish.ts +1 -3
  207. package/scripts/{git → followup}/git-followup-flush.ts +2 -2
  208. package/scripts/{git → followup}/git-followup-issue-close.ts +2 -2
  209. package/scripts/{git → followup}/git-followup-label.ts +4 -4
  210. package/scripts/followup/git-followup-merged.ts +112 -0
  211. package/scripts/{git → followup}/git-followup-pending.ts +1 -1
  212. package/scripts/{git → followup}/git-followup-workflow.ts +19 -11
  213. package/scripts/{git → followup}/git-pr-followup-wrapup.ts +9 -3
  214. package/scripts/{git → followup}/git-pr-followup.ts +53 -16
  215. package/scripts/gate/core-budget.ts +3 -9
  216. package/scripts/gate/gate-plan.ts +7 -4
  217. package/scripts/gate/gate-report.ts +0 -6
  218. package/scripts/gate/gate-tree.ts +1 -1
  219. package/scripts/gate/pre-commit-type-check.ts +0 -6
  220. package/scripts/gate/project-checks.ts +7 -8
  221. package/scripts/gate/scoped-green.ts +0 -1
  222. package/scripts/gate/type-check-step.ts +1 -1
  223. package/scripts/gate/verification-gate.ts +0 -2
  224. package/scripts/gh/fix-gh-packages.ts +15 -12
  225. package/scripts/gh/gh-spawn.ts +2 -2
  226. package/scripts/{git → gh}/git-ai-review-scan.ts +1 -5
  227. package/scripts/{git → gh}/git-gh-check.ts +2 -1
  228. package/scripts/{git → gh}/git-gh-exec.ts +1 -1
  229. package/scripts/{git → gh}/git-gh-failure.ts +1 -1
  230. package/scripts/{git → gh}/git-gh-helpers.ts +0 -1
  231. package/scripts/{git → gh}/git-gh-issue-list.ts +2 -0
  232. package/scripts/{git → gh}/git-gh-issue-read.ts +1 -1
  233. package/scripts/{git → gh}/git-gh-issue-rest.ts +6 -3
  234. package/scripts/{git → gh}/git-gh-pr-read.ts +24 -0
  235. package/scripts/{git → gh}/git-gh-pr-rest.ts +5 -2
  236. package/scripts/{git → gh}/git-gh-pr-review.ts +2 -2
  237. package/scripts/{git → gh}/git-gh-pr-rollup.ts +1 -3
  238. package/scripts/{git → gh}/git-gh-pr.ts +3 -1
  239. package/scripts/{git → gh}/git-pr-ai-review.ts +2 -5
  240. package/scripts/{git → gh}/git-pr-checks-eval.ts +0 -10
  241. package/scripts/{git → gh}/git-pr-checks-parse.ts +4 -20
  242. package/scripts/{git → gh}/git-pr-checks.ts +2 -1
  243. package/scripts/{git → gh}/git-pr-coderabbit.ts +2 -5
  244. package/scripts/{git → gh}/git-pr-confirmation.ts +1 -3
  245. package/scripts/{git → gh}/git-pr-managed-config.ts +2 -3
  246. package/scripts/{git → gh}/git-pr.ts +3 -3
  247. package/scripts/git/changed-file-scope.ts +0 -1
  248. package/scripts/git/git-branch.ts +3 -6
  249. package/scripts/git/git-command.ts +1 -1
  250. package/scripts/git/git-commit.ts +1 -1
  251. package/scripts/git/git-common-directory.ts +80 -24
  252. package/scripts/git/git-error.ts +66 -9
  253. package/scripts/git/git-execa-error.ts +6 -1
  254. package/scripts/git/git-issue.ts +1 -1
  255. package/scripts/git/git-preflight.ts +24 -6
  256. package/scripts/git/git-prompt.ts +6 -31
  257. package/scripts/git/git-push-transport.ts +12 -69
  258. package/scripts/git/git-push.ts +1 -1
  259. package/scripts/git/git-spawn.ts +79 -3
  260. package/scripts/git/git-ssh-keepalive.ts +74 -0
  261. package/scripts/git/git-staging.ts +1 -0
  262. package/scripts/git/git-status.ts +1 -1
  263. package/scripts/git/git-workflow.ts +1 -1
  264. package/scripts/git/gone-branch.ts +4 -2
  265. package/scripts/git/listing-cutoff.ts +1 -1
  266. package/scripts/git/main-merge.ts +1 -1
  267. package/scripts/git/main-sync.ts +19 -1
  268. package/scripts/git/parse-json-array.ts +0 -3
  269. package/scripts/git/repository-lock.ts +16 -16
  270. package/scripts/git/{git-stash.ts → stash/git-stash.ts} +1 -1
  271. package/scripts/git/{stash-pop-args.ts → stash/stash-pop-args.ts} +1 -1
  272. package/scripts/git/{stash-pop-cli.ts → stash/stash-pop-cli.ts} +0 -1
  273. package/scripts/git/{stash-sweep-lock.ts → stash/stash-sweep-lock.ts} +3 -3
  274. package/scripts/hooks/codex-hook-adapter.ts +0 -1
  275. package/scripts/hooks/edited-cspell.ts +1 -1
  276. package/scripts/hooks/format-edited-cli.ts +15 -0
  277. package/scripts/hooks/format-edited-file.ts +4 -9
  278. package/scripts/hooks/pre-push-unit.ts +0 -4
  279. package/scripts/hooks/pretool-guard-cli.ts +21 -0
  280. package/scripts/hooks/pretool-guard.ts +36 -19
  281. package/scripts/hooks/reserved-run.ts +1 -1
  282. package/scripts/hooks/step-zero-notice.ts +76 -0
  283. package/scripts/hooks/stop-guard.ts +47 -21
  284. package/scripts/init/claude-plugin-config.ts +4 -5
  285. package/scripts/init/hook-command-rewrite.ts +16 -8
  286. package/scripts/init/hook-launch.ts +41 -15
  287. package/scripts/init/init-basic.ts +2 -5
  288. package/scripts/init/init-logic.ts +7 -0
  289. package/scripts/init/init.ts +0 -3
  290. package/scripts/init/project-profile.ts +6 -11
  291. package/scripts/init/start-exec.ts +8 -2
  292. package/scripts/init/start-plan.ts +18 -5
  293. package/scripts/init/start-setup-pr.ts +52 -25
  294. package/scripts/init/start-steps.ts +42 -9
  295. package/scripts/init/start.ts +40 -10
  296. package/scripts/issue/behavior-change-lint.ts +0 -1
  297. package/scripts/issue/defect-rate-cli.ts +3 -3
  298. package/scripts/issue/defect-rate.ts +1 -2
  299. package/scripts/{git → issue}/git-next-issues.ts +37 -8
  300. package/scripts/issue/issue-backlinks-cli.ts +1 -5
  301. package/scripts/issue/issue-cite-cli.ts +2 -6
  302. package/scripts/issue/issue-cite.ts +19 -3
  303. package/scripts/issue/issue-classification.ts +1 -9
  304. package/scripts/issue/issue-closing-pr.ts +4 -4
  305. package/scripts/issue/issue-comment-cli.ts +2 -2
  306. package/scripts/issue/issue-file-cli.ts +5 -5
  307. package/scripts/issue/issue-file.ts +2 -2
  308. package/scripts/issue/issue-fold-cli.ts +1 -1
  309. package/scripts/issue/issue-fold-existing-cli.ts +1 -1
  310. package/scripts/{git → issue}/issue-labels.ts +20 -0
  311. package/scripts/issue/issue-lint-cli.ts +1 -1
  312. package/scripts/issue/issue-merged.ts +2 -2
  313. package/scripts/issue/issue-rank.ts +89 -0
  314. package/scripts/issue/issue-read-cli.ts +8 -47
  315. package/scripts/issue/issue-read.ts +0 -2
  316. package/scripts/issue/issue-report-failures.ts +80 -0
  317. package/scripts/issue/issue-scout-cli.ts +1 -7
  318. package/scripts/issue/issue-scout-closed.ts +2 -2
  319. package/scripts/issue/issue-scout.ts +0 -2
  320. package/scripts/issue/issue-state-cli.ts +5 -46
  321. package/scripts/issue/issue-state.ts +1 -5
  322. package/scripts/issue/markdown-section.ts +1 -1
  323. package/scripts/issue/measure-rerun-cli.ts +1 -1
  324. package/scripts/issue/reproduction-measure.ts +1 -1
  325. package/scripts/josh/cli-body.ts +1 -1
  326. package/scripts/josh/file-map-stamp.ts +0 -3
  327. package/scripts/josh/josh-command-map.ts +2 -102
  328. package/scripts/josh/josh-commands-ai.ts +9 -102
  329. package/scripts/josh/josh-commands-backlog.ts +5 -1
  330. package/scripts/josh/josh-commands-development.ts +10 -3
  331. package/scripts/josh/josh-commands-issue.ts +2 -2
  332. package/scripts/josh/josh-commands-maintenance.ts +7 -0
  333. package/scripts/josh/josh-commands-project.ts +7 -1
  334. package/scripts/josh/josh-commands-run.ts +114 -0
  335. package/scripts/josh/josh-commands-versioning.ts +8 -0
  336. package/scripts/josh/josh-commands-workflow.ts +2 -2
  337. package/scripts/josh/path-decision.ts +0 -3
  338. package/scripts/josh/process-owner.ts +16 -0
  339. package/scripts/josh/session-language-cli.ts +0 -1
  340. package/scripts/lane/lane-await.ts +3 -6
  341. package/scripts/lane/lane-capacity.ts +6 -3
  342. package/scripts/lane/lane-child-invocation.ts +20 -7
  343. package/scripts/lane/lane-child-marker.ts +16 -2
  344. package/scripts/lane/lane-cli.ts +33 -18
  345. package/scripts/lane/lane-close.ts +1 -3
  346. package/scripts/lane/lane-dispatch.ts +3 -4
  347. package/scripts/lane/lane-environment.ts +0 -9
  348. package/scripts/lane/lane-handoff.ts +38 -0
  349. package/scripts/lane/lane-launch-cli.ts +21 -11
  350. package/scripts/lane/lane-open.ts +0 -3
  351. package/scripts/lane/lane-output.ts +0 -1
  352. package/scripts/lane/lane-registry.ts +9 -0
  353. package/scripts/lane/lane-report.ts +10 -4
  354. package/scripts/lane/openai-lane-ship.ts +2 -0
  355. package/scripts/lane/openai-lane-supervisor-decision.ts +2 -1
  356. package/scripts/lane/openai-lane-supervisor.ts +6 -4
  357. package/scripts/lane/openai-review-broker.ts +3 -0
  358. package/scripts/lib/bounded-pool.ts +1 -0
  359. package/scripts/lib/json-value.ts +5 -4
  360. package/scripts/lib/poll.ts +3 -1
  361. package/scripts/lib/timed-fetch.ts +15 -0
  362. package/scripts/lib/timeouts.ts +13 -0
  363. package/scripts/{yaml → lib}/yaml-document.ts +3 -1
  364. package/scripts/{bytes → lines}/bytes-command.ts +0 -2
  365. package/scripts/lines/lines-command.ts +0 -1
  366. package/scripts/lint/lint-related-scope.ts +0 -1
  367. package/scripts/lint/lint-related.ts +1 -1
  368. package/scripts/{git → notify}/telegram-notify.ts +2 -2
  369. package/scripts/{git → notify}/telegram-test.ts +4 -4
  370. package/scripts/observations/observation-ledger-home.ts +0 -1
  371. package/scripts/observations/observation-ledger-line.ts +0 -1
  372. package/scripts/observations/observation-ledger-migrate.ts +1 -1
  373. package/scripts/observations/observations-flush-landing.ts +3 -3
  374. package/scripts/observations/observations-flush.ts +2 -2
  375. package/scripts/overrides/lockfile-overrides.ts +1 -1
  376. package/scripts/overrides/overrides-logic.ts +1 -1
  377. package/scripts/package/package-scout-cli.ts +2 -7
  378. package/scripts/package/package-scout.ts +0 -2
  379. package/scripts/propagate/propagate-git-failure.ts +0 -1
  380. package/scripts/propagate/propagate-git.ts +0 -2
  381. package/scripts/propagate/propagate-plan.ts +185 -0
  382. package/scripts/propagate/propagate-publish.ts +2 -3
  383. package/scripts/propagate/propagate-run.ts +5 -3
  384. package/scripts/propagate/propagate-steps.ts +19 -6
  385. package/scripts/propagate/propagate-targets.ts +13 -6
  386. package/scripts/propagate/propagate.ts +60 -46
  387. package/scripts/refactor/import-graph.ts +0 -1
  388. package/scripts/refactor/refactor-lint.ts +0 -2
  389. package/scripts/refactor/refactor-scan.ts +0 -1
  390. package/scripts/refactor/refactor-targets.ts +0 -1
  391. package/scripts/registry-migration/migrate-logic.ts +1 -2
  392. package/scripts/registry-migration/migrate.ts +19 -9
  393. package/scripts/release/github-release-cli.ts +8 -6
  394. package/scripts/release/github-release-environment.ts +46 -0
  395. package/scripts/release/github-release.ts +151 -94
  396. package/scripts/release/release-history.ts +0 -1
  397. package/scripts/release/release-plan.ts +0 -1
  398. package/scripts/release/release-publish.ts +2 -3
  399. package/scripts/release/release-scope-cli.ts +1 -2
  400. package/scripts/release/release-tag.ts +2 -4
  401. package/scripts/repo/auto-merge-setting-logic.ts +1 -4
  402. package/scripts/repo/repo-setting.ts +1 -1
  403. package/scripts/repo/repository-labels.ts +3 -3
  404. package/scripts/repo/required-checks-logic.ts +206 -0
  405. package/scripts/repo/required-checks-report.ts +71 -0
  406. package/scripts/repo/ruleset-check-cli.ts +53 -0
  407. package/scripts/repo/ruleset-check.ts +147 -0
  408. package/scripts/report/report-lint-cli.ts +0 -4
  409. package/scripts/review/disposition-cli.ts +1 -1
  410. package/scripts/review/live-evidence.ts +1 -1
  411. package/scripts/review/review-attest-cli.ts +0 -6
  412. package/scripts/review/review-attest.ts +48 -16
  413. package/scripts/review/review-brief-cli.ts +72 -8
  414. package/scripts/review/review-brief.ts +67 -9
  415. package/scripts/review/review-diff-parts.ts +89 -0
  416. package/scripts/review/review-diff-write.ts +97 -0
  417. package/scripts/review/review-finding-ledger.ts +0 -1
  418. package/scripts/review/review-record-cli.ts +1 -1
  419. package/scripts/review/review-record.ts +0 -1
  420. package/scripts/review/review-round2-cli.ts +1 -1
  421. package/scripts/review/review-stamps.ts +6 -2
  422. package/scripts/review/review-tree.ts +14 -2
  423. package/scripts/rules/decision-oracle-stage.ts +18 -0
  424. package/scripts/rules/decision-oracle.ts +10 -7
  425. package/scripts/rules/delivered-rules.ts +9 -1
  426. package/scripts/rules/destructive-command.ts +119 -0
  427. package/scripts/rules/direct-filing.ts +1 -1
  428. package/scripts/rules/file-body.ts +0 -3
  429. package/scripts/rules/filing-cap.ts +0 -2
  430. package/scripts/rules/gh-api.ts +7 -2
  431. package/scripts/rules/git-argv.ts +18 -7
  432. package/scripts/rules/git-force.ts +0 -2
  433. package/scripts/rules/implementation-cut.ts +1 -2
  434. package/scripts/rules/index-guard.ts +71 -0
  435. package/scripts/rules/issue-citation.ts +50 -25
  436. package/scripts/rules/issue-fold.ts +1 -2
  437. package/scripts/rules/lane-background.ts +15 -7
  438. package/scripts/rules/lane-carry-conflict.ts +1 -2
  439. package/scripts/rules/lane-park.ts +14 -8
  440. package/scripts/rules/last-prompt.ts +1 -0
  441. package/scripts/rules/oracle-consulted.ts +1 -1
  442. package/scripts/rules/oracle-firing.ts +1 -0
  443. package/scripts/rules/oracle-list-cli.ts +0 -3
  444. package/scripts/rules/permission-guards.ts +14 -0
  445. package/scripts/rules/pre-gate-cut.ts +2 -2
  446. package/scripts/rules/protected-files.ts +74 -0
  447. package/scripts/rules/reply-language.ts +1 -1
  448. package/scripts/rules/rule-body-guard.ts +0 -3
  449. package/scripts/rules/rule-value-cli.ts +0 -1
  450. package/scripts/rules/shell-body-trigger.ts +0 -1
  451. package/scripts/rules/shell-segments.ts +0 -1
  452. package/scripts/rules/stop-rules.ts +13 -5
  453. package/scripts/rules/tail-commands.ts +1 -1
  454. package/scripts/rules/test-declared-commit.ts +1 -1
  455. package/scripts/rules/third-party-write.ts +0 -1
  456. package/scripts/rules/worktree-guard.ts +26 -9
  457. package/scripts/run/run-carry-cli.ts +0 -2
  458. package/scripts/run/run-carry-stash.ts +2 -2
  459. package/scripts/run/run-carry-streak.ts +1 -1
  460. package/scripts/run/run-cut-cli.ts +0 -7
  461. package/scripts/run/run-cut.ts +8 -54
  462. package/scripts/run/run-ending-cli.ts +1 -1
  463. package/scripts/run/run-ending.ts +1 -4
  464. package/scripts/run/run-entry-cli.ts +101 -24
  465. package/scripts/run/run-entry.ts +0 -1
  466. package/scripts/run/run-event-cli.ts +0 -2
  467. package/scripts/run/run-event-follow.ts +1 -0
  468. package/scripts/run/run-event-render.ts +1 -1
  469. package/scripts/run/run-event-scope.ts +53 -4
  470. package/scripts/run/run-event-stream.ts +0 -3
  471. package/scripts/run/run-event-watch.ts +1 -0
  472. package/scripts/run/run-halfrun-resume.ts +20 -7
  473. package/scripts/run/run-headless.ts +24 -8
  474. package/scripts/run/run-hold-cli.ts +33 -10
  475. package/scripts/run/run-hold.ts +25 -5
  476. package/scripts/run/run-issue-number.ts +1 -1
  477. package/scripts/run/run-liveness-cli.ts +1 -1
  478. package/scripts/run/run-liveness.ts +2 -3
  479. package/scripts/run/run-merge-cli.ts +5 -13
  480. package/scripts/run/run-merge-steps.ts +5 -5
  481. package/scripts/run/run-merge.ts +1 -1
  482. package/scripts/run/run-next-cli.ts +1 -1
  483. package/scripts/run/run-parent-cut-hook.ts +143 -0
  484. package/scripts/run/run-preflight.ts +2 -9
  485. package/scripts/run/run-prep-cli.ts +2 -2
  486. package/scripts/run/run-prep-locate.ts +1 -1
  487. package/scripts/run/run-progress-cli.ts +4 -7
  488. package/scripts/run/run-progress-clock.ts +6 -34
  489. package/scripts/run/run-progress-config.ts +0 -4
  490. package/scripts/run/run-progress-read.ts +3 -3
  491. package/scripts/run/run-progress.ts +22 -10
  492. package/scripts/run/run-prrun-resume.ts +117 -0
  493. package/scripts/run/run-report-cli.ts +1 -2
  494. package/scripts/run/run-report.ts +0 -1
  495. package/scripts/run/run-retrospective.ts +1 -1
  496. package/scripts/run/run-review-cli.ts +0 -3
  497. package/scripts/run/run-review-steps.ts +2 -0
  498. package/scripts/run/run-review.ts +0 -2
  499. package/scripts/run/run-ship-cli.ts +27 -77
  500. package/scripts/run/run-ship-detach.ts +1 -0
  501. package/scripts/run/run-ship-next.ts +106 -0
  502. package/scripts/run/run-ship-preflight.ts +87 -0
  503. package/scripts/run/run-ship-return.ts +8 -3
  504. package/scripts/run/run-ship-review-steps.ts +23 -30
  505. package/scripts/run/run-ship-review.ts +20 -0
  506. package/scripts/run/run-ship-scoped.ts +45 -0
  507. package/scripts/run/run-ship-stage.ts +5 -1
  508. package/scripts/run/run-ship-steps.ts +105 -0
  509. package/scripts/run/run-ship.ts +2 -1
  510. package/scripts/run/run-stage-read.ts +62 -0
  511. package/scripts/run/run-stage.ts +160 -0
  512. package/scripts/run/run-status-cli.ts +1 -1
  513. package/scripts/run/run-step-cli.ts +21 -14
  514. package/scripts/run/run-step.ts +1 -1
  515. package/scripts/run/run-stop-notify.ts +1 -3
  516. package/scripts/run/run-stranded-cli.ts +0 -4
  517. package/scripts/run/run-stranded-detect.ts +2 -2
  518. package/scripts/run/run-tail-cli.ts +17 -11
  519. package/scripts/run/run-tail.ts +2 -0
  520. package/scripts/run/run-tidy-lanes.ts +2 -1
  521. package/scripts/run/run-tidy-stashes.ts +12 -12
  522. package/scripts/run/run-wake-cli.ts +4 -5
  523. package/scripts/run/run-wake-describe.ts +19 -1
  524. package/scripts/run/run-wake-loop.ts +2 -2
  525. package/scripts/run/run-wake.ts +2 -4
  526. package/scripts/run/run-watcher-guard-cli.ts +0 -4
  527. package/scripts/run/run-watcher-guard.ts +9 -7
  528. package/scripts/run/run-watcher-hook.ts +1 -1
  529. package/scripts/safe-chain/ci-installer-pin.ts +11 -5
  530. package/scripts/safe-chain/project-config.ts +1 -1
  531. package/scripts/security/security-audit-provision-logic.ts +0 -1
  532. package/scripts/security/security-audit-provision.ts +3 -2
  533. package/scripts/security/security-audit.ts +0 -1
  534. package/scripts/security/security-updates-logic.ts +0 -1
  535. package/scripts/sonar/sonar-hotspots-cli.ts +10 -52
  536. package/scripts/sonar/sonar-hotspots.ts +0 -1
  537. package/scripts/sonar/sonar-new-code-cli.ts +150 -0
  538. package/scripts/sonar/sonar-new-code.ts +79 -0
  539. package/scripts/sonar/sonar-project.ts +97 -0
  540. package/scripts/split/split-assess-cli.ts +1 -1
  541. package/scripts/split/split-assess.ts +2 -5
  542. package/scripts/sync/managed-config-scope-cli.ts +1 -1
  543. package/scripts/sync/skill-migration.ts +0 -1
  544. package/scripts/sync/sync-hook-safety.ts +2 -3
  545. package/scripts/sync/sync.ts +1 -8
  546. package/scripts/sync/template-source-logic.ts +0 -1
  547. package/scripts/sync/workflow-pin-logic.ts +16 -28
  548. package/scripts/test/test-declared-logic.ts +0 -1
  549. package/scripts/test/test-declared.ts +0 -2
  550. package/scripts/test/test-red-commit.ts +2 -2
  551. package/scripts/test/test-red.ts +14 -7
  552. package/scripts/test/test-type-logic.ts +1 -1
  553. package/scripts/test/unit-worker-share.ts +7 -16
  554. package/scripts/time-runtime/time-batch-guard.ts +1 -2
  555. package/scripts/time-runtime/time-bundle-call.ts +2 -3
  556. package/scripts/time-runtime/time-bundles.ts +0 -4
  557. package/scripts/time-runtime/time-density-hook.ts +0 -2
  558. package/scripts/time-runtime/time-followup-stage.ts +1 -1
  559. package/scripts/time-runtime/time-format.ts +0 -73
  560. package/scripts/time-runtime/time-round-trips.ts +0 -4
  561. package/scripts/time-runtime/time-single-check.ts +1 -1
  562. package/scripts/time-runtime/time-spans.ts +1 -1
  563. package/scripts/time-runtime/time-transcript-line.ts +1 -2
  564. package/scripts/ui/ui-routes-cli.ts +0 -5
  565. package/scripts/ui/ui-routes.ts +0 -5
  566. package/scripts/version/effective-upstream.ts +2 -2
  567. package/scripts/version/latest-corepack.ts +7 -9
  568. package/scripts/version/latest-scope-cli.ts +0 -2
  569. package/scripts/version/latest-update.ts +0 -2
  570. package/scripts/version/npm-registry.ts +97 -0
  571. package/scripts/version/publishable-range-check.ts +1 -1
  572. package/scripts/version/release-hold.ts +0 -4
  573. package/scripts/version/running-binary.ts +2 -2
  574. package/scripts/version/version-check-logic.ts +0 -2
  575. package/scripts/version/version-commands.ts +5 -4
  576. package/scripts/version/version-remote.ts +28 -14
  577. package/scripts/version/version-targets.ts +4 -4
  578. package/templates/sonar-project.properties +28 -1
  579. package/templates/workflows/dependabot-auto-merge.yml +5 -3
  580. package/templates/workflows/github-release.yml +81 -0
  581. package/prompts/collaboration-workflow/cross-repo-epic.md +0 -5
  582. package/prompts/collaboration-workflow/epic-audit.md +0 -5
  583. package/prompts/collaboration-workflow/epic-bundle.md +0 -5
  584. package/scripts/init/plugin-install-hint.ts +0 -47
  585. package/scripts/version/parse-json.ts +0 -13
  586. /package/scripts/{git → followup}/git-followup-stages.ts +0 -0
  587. /package/scripts/{git → gh}/git-gh-api-path.ts +0 -0
  588. /package/scripts/{git → gh}/git-gh-command.ts +0 -0
  589. /package/scripts/{git → gh}/git-gh-issue-write.ts +0 -0
  590. /package/scripts/{git → gh}/git-gh-issue.ts +0 -0
  591. /package/scripts/{git → gh}/git-gh-pr-auto-merge.ts +0 -0
  592. /package/scripts/{git → gh}/git-gh-pr-snapshot.ts +0 -0
  593. /package/scripts/{git → gh}/git-gh-reachability.ts +0 -0
  594. /package/scripts/{git → gh}/git-gh-repo.ts +0 -0
  595. /package/scripts/{git → gh}/git-gh-rest-state.ts +0 -0
  596. /package/scripts/{git → gh}/git-pr-checks-watch.ts +0 -0
  597. /package/scripts/{git → gh}/git-pr-error.ts +0 -0
  598. /package/scripts/{git → gh}/git-pr-messages.ts +0 -0
  599. /package/scripts/{git → gh}/github-issue-url.ts +0 -0
  600. /package/scripts/git/{stash-orphans.ts → stash/stash-orphans.ts} +0 -0
  601. /package/scripts/{git → issue}/issue-reference.ts +0 -0
  602. /package/scripts/{git → lib}/animation-helpers.ts +0 -0
  603. /package/scripts/{git → lib}/git-animation.ts +0 -0
  604. /package/scripts/{git → notify}/git-notify.ts +0 -0
  605. /package/scripts/{git → notify}/telegram-test-logic.ts +0 -0
@@ -1,6 +1,12 @@
1
1
  import { execa } from 'execa'
2
2
  import { git_utilities } from './constants'
3
- import { create_spawn_error, get_exit_code, has_timed_out } from './git-execa-error'
3
+ import {
4
+ create_spawn_error,
5
+ get_exit_code,
6
+ has_timed_out,
7
+ TIMEOUT_EXIT_CODE,
8
+ } from './git-execa-error'
9
+ import { git_ssh_keepalive } from './git-ssh-keepalive'
4
10
 
5
11
  const MS_PER_SECOND = 1000
6
12
 
@@ -33,65 +39,10 @@ const PUSH_TIMEOUT_LABEL = `${String(PUSH_TIMEOUT_SECONDS)}s`
33
39
  // said no" are different diagnoses, and only the first one is worth retrying.
34
40
  const PUSH_TIMEOUT_MESSAGE = 'git push timed out'
35
41
 
36
- // A timeout has no exit code — the process was killed rather than allowed to exit — so `cause` says
37
- // so in the slot every other git failure puts a number in. `is_upstream_not_set_error` compares
38
- // against '128', which this can never equal, so a timed-out bare push is never mistaken for a
39
- // missing upstream and retried as `--set-upstream`.
40
- const PUSH_TIMEOUT_EXIT_CODE = 'timeout'
41
-
42
- // SSH's own liveness probe: three unanswered checks 15 seconds apart, so a connection that dies
43
- // mid-transfer is noticed in about 45 seconds instead of waiting on the TCP default. The budget
44
- // above bounds the damage either way; this is what makes the common case fail in seconds rather
45
- // than sit out the whole budget.
46
- const SSH_KEEPALIVE_OPTIONS = '-o ServerAliveInterval=15 -o ServerAliveCountMax=3'
47
- const SSH_COMMAND_VARIABLE = 'GIT_SSH_COMMAND'
48
- const SSH_LEGACY_VARIABLE = 'GIT_SSH'
49
- const KEEPALIVE_SSH_COMMAND = `ssh ${SSH_KEEPALIVE_OPTIONS}`
50
- const SSH_COMMAND_CONFIG_KEY = 'core.sshCommand'
42
+ // `TIMEOUT_EXIT_CODE` is never '128', which `is_upstream_not_set_error` compares against, so a
43
+ // timed-out bare push is never mistaken for a missing upstream and retried as `--set-upstream`.
51
44
  const PUSH_SUBCOMMAND = 'push'
52
45
 
53
- // Whatever already decides how ssh is invoked, or an empty string when nothing does. git reads three
54
- // sources in this order — `GIT_SSH_COMMAND`, `core.sshCommand`, then the legacy `GIT_SSH` — and the
55
- // last one has to be asked as well precisely because it loses: setting `GIT_SSH_COMMAND` on top of a
56
- // `GIT_SSH=plink.exe` outranks it, so the push would run an ssh binary the user did not choose.
57
- function to_environment_value(name: string): string {
58
- return process.env[name]?.trim() ?? ''
59
- }
60
-
61
- function to_configured_ssh_command(): string {
62
- const from_command = to_environment_value(SSH_COMMAND_VARIABLE)
63
-
64
- return from_command === '' ? to_environment_value(SSH_LEGACY_VARIABLE) : from_command
65
- }
66
-
67
- // Whether any of those three sources answered. **A hit means hands off entirely.**
68
- //
69
- // Appending the options to a command someone else chose is not safe, because they are OpenSSH's:
70
- // `plink` and `TortoiseGitPlink` are supported ssh commands on the platform `get_git_command_for_spawn`
71
- // goes out of its way to handle, and a wrapper script with a fixed argument list is common on any
72
- // platform — each of them exits on a usage error rather than pushing. Setting the variable while
73
- // `core.sshCommand` is configured is the same mistake from the other side: the environment wins, so
74
- // a per-repository key would be silently replaced by a plain `ssh`.
75
- //
76
- // What those users lose is the keepalive, not the fix: the budget above still bounds their push, and
77
- // `ServerAliveInterval` belongs in their own ssh config where it applies to every tool they run.
78
- async function has_configured_ssh_command(): Promise<boolean> {
79
- if (to_configured_ssh_command() !== '') return true
80
-
81
- try {
82
- const git_command_bin = git_utilities.get_git_command_for_spawn()
83
- // execa runs the binary directly with an argument array and no `shell` option, so CLI
84
- // args cannot break out of a shell sandbox; the git command and args are internally
85
- // controlled, never untrusted input. tssecurity:S8705 is a false positive here.
86
- const { stdout } = await execa(git_command_bin, ['config', '--get', SSH_COMMAND_CONFIG_KEY]) // NOSONAR
87
-
88
- return stdout.trim() !== ''
89
- } catch {
90
- // `git config --get` exits 1 when the key is unset, which is the answer rather than a failure.
91
- return false
92
- }
93
- }
94
-
95
46
  interface PushOptions {
96
47
  stdio: 'inherit'
97
48
  timeout: number
@@ -99,12 +50,10 @@ interface PushOptions {
99
50
  }
100
51
 
101
52
  async function to_push_options(): Promise<PushOptions> {
102
- const should_keep_alive = !(await has_configured_ssh_command())
103
-
104
53
  return {
105
54
  stdio: 'inherit',
106
55
  timeout: PUSH_TIMEOUT_MS,
107
- env: should_keep_alive ? { [SSH_COMMAND_VARIABLE]: KEEPALIVE_SSH_COMMAND } : {},
56
+ env: await git_ssh_keepalive.to_environment(),
108
57
  }
109
58
  }
110
59
 
@@ -142,7 +91,7 @@ function to_retry_notice(arguments_list: Array<string>): string {
142
91
  function create_timeout_error(arguments_list: Array<string>): Error {
143
92
  const message = `${PUSH_TIMEOUT_MESSAGE} twice (${PUSH_TIMEOUT_LABEL} each). Re-run it by hand: ${to_manual_command(arguments_list)}`
144
93
 
145
- return new Error(message, { cause: { exit_code: PUSH_TIMEOUT_EXIT_CODE } })
94
+ return new Error(message, { cause: { exit_code: TIMEOUT_EXIT_CODE } })
146
95
  }
147
96
 
148
97
  // One push, bounded and retried once — and **only** on a timeout. A push the remote rejected (a
@@ -164,10 +113,4 @@ const git_push_transport = {
164
113
  }
165
114
 
166
115
  export { git_push_transport }
167
- export {
168
- KEEPALIVE_SSH_COMMAND,
169
- PUSH_TIMEOUT_MESSAGE,
170
- PUSH_TIMEOUT_MS,
171
- SSH_COMMAND_VARIABLE,
172
- SSH_LEGACY_VARIABLE,
173
- }
116
+ export { PUSH_TIMEOUT_MESSAGE, PUSH_TIMEOUT_MS }
@@ -1,4 +1,4 @@
1
- import { animation_helpers, create_git_operation_config } from './animation-helpers'
1
+ import { animation_helpers, create_git_operation_config } from '#scripts/lib/animation-helpers'
2
2
  import { git_command } from './git-command'
3
3
 
4
4
  async function push(): Promise<void> {
@@ -1,6 +1,13 @@
1
1
  import { execa } from 'execa'
2
2
  import { git_utilities } from './constants'
3
- import { create_spawn_error, get_exit_code } from './git-execa-error'
3
+ import {
4
+ create_spawn_error,
5
+ get_exit_code,
6
+ has_timed_out,
7
+ TIMEOUT_EXIT_CODE,
8
+ } from './git-execa-error'
9
+ import { PUSH_TIMEOUT_MS } from './git-push-transport'
10
+ import { git_ssh_keepalive } from './git-ssh-keepalive'
4
11
 
5
12
  // The one place the ordinary git commands are spawned from (joshuafolkken/kit#1640). It sits in a
6
13
  // module of its own rather than inside `git-command.ts` so that a second command module —
@@ -9,8 +16,8 @@ import { create_spawn_error, get_exit_code } from './git-execa-error'
9
16
  // `CLAUDE.md` prohibits, so a new caller imports this one instead of growing its own.
10
17
  //
11
18
  // **`git-push-transport.ts` is the one deliberate exception among the command modules** and is not a
12
- // second helper of this kind: a push needs a timeout and a transport-fault retry that no other
13
- // command has, so it spawns git itself. Those two files are the spawn sites of the ordinary command
19
+ // second helper of this kind: a push needs a transport-fault retry that no other command has, so it
20
+ // spawns git itself. The timeout it carries is shared here by `read_remote` / `with_output_remote`. Those two files are the spawn sites of the ordinary command
14
21
  // modules — the claim stops there. Other parts of this package spawn git for their own purposes
15
22
  // (`scripts/run/run-progress-clock.ts`, `scripts/propagate/propagate-git.ts`,
16
23
  // `scripts/doctor/doctor-io.ts`, `scripts/git/git-fixture-workspace.ts`), and an audit of how the git
@@ -26,6 +33,73 @@ async function read(arguments_: Array<string>): Promise<string> {
26
33
  return stdout.trimEnd()
27
34
  }
28
35
 
36
+ // The budget for a git call that talks to the remote — `fetch` and `pull` (joshuafolkken/kit#2942).
37
+ // `read` and `with_output` wait without end, and a `git fetch --prune` under `josh main:sync` sat on
38
+ // a dead ssh connection for 37 minutes, stalling the unattended backlog driver whose merge step runs
39
+ // it. The push's budget is reused rather than a second number chosen: both transfer objects over the
40
+ // same transport, and that one is already read off what a healthy transfer costs here.
41
+ const REMOTE_TIMEOUT_MS = PUSH_TIMEOUT_MS
42
+ const MS_PER_SECOND = 1000
43
+
44
+ // A budget kill is reported as a timeout, never as whatever the killed process printed first, and
45
+ // `cause` carries the same `TIMEOUT_EXIT_CODE` a timed-out push does. Unlike the push it is not
46
+ // retried here: what the issue needed is that the wait ends, and a failure then surfaces to the
47
+ // caller — `run:merge` raises a failed `main:sync` — instead of a second budget doubling the wait.
48
+ function to_remote_error(command: string, error: unknown, timeout_ms: number): Error {
49
+ if (!has_timed_out(error)) return create_spawn_error(command, get_exit_code(error))
50
+
51
+ const seconds = String(Math.round(timeout_ms / MS_PER_SECOND))
52
+
53
+ return new Error(`git ${command} timed out after ${seconds}s`, {
54
+ cause: { exit_code: TIMEOUT_EXIT_CODE },
55
+ })
56
+ }
57
+
58
+ interface RemoteOptions {
59
+ stdio?: 'inherit'
60
+ timeout: number
61
+ env: Record<string, string>
62
+ }
63
+
64
+ // One remote call, bounded and kept alive. execa kills git on the budget; the ssh keepalive is what
65
+ // makes ssh — which git does not kill with itself — exit on a dead connection as well.
66
+ async function spawn_remote(arguments_: Array<string>, options: RemoteOptions): Promise<string> {
67
+ const git_cmd = git_utilities.get_git_command_for_spawn()
68
+
69
+ try {
70
+ // execa runs the binary directly with an argument array and no `shell` option, so CLI
71
+ // args cannot break out of a shell sandbox; the git command and args are internally
72
+ // controlled, never untrusted input. tssecurity:S8705 is a false positive here.
73
+ const { stdout } = await execa(git_cmd, arguments_, options) // NOSONAR
74
+
75
+ return typeof stdout === 'string' ? stdout.trimEnd() : ''
76
+ } catch (error) {
77
+ throw to_remote_error(arguments_[0] ?? '', error, options.timeout)
78
+ }
79
+ }
80
+
81
+ // `read` for a call that reaches the remote. The budget is a parameter only so a test can hold it to
82
+ // seconds; every production caller takes the default.
83
+ async function read_remote(
84
+ arguments_: Array<string>,
85
+ timeout_ms: number = REMOTE_TIMEOUT_MS,
86
+ ): Promise<string> {
87
+ return await spawn_remote(arguments_, {
88
+ timeout: timeout_ms,
89
+ env: await git_ssh_keepalive.to_environment(),
90
+ })
91
+ }
92
+
93
+ // `with_output` for a call that reaches the remote — the output stays on the terminal, as a pull's
94
+ // progress and a credential prompt need.
95
+ async function with_output_remote(command: string, arguments_list: Array<string>): Promise<void> {
96
+ await spawn_remote([command, ...arguments_list], {
97
+ stdio: 'inherit',
98
+ timeout: REMOTE_TIMEOUT_MS,
99
+ env: await git_ssh_keepalive.to_environment(),
100
+ })
101
+ }
102
+
29
103
  async function with_output(command: string, arguments_list: Array<string>): Promise<void> {
30
104
  const git_command_bin = git_utilities.get_git_command_for_spawn()
31
105
 
@@ -41,7 +115,9 @@ async function with_output(command: string, arguments_list: Array<string>): Prom
41
115
 
42
116
  const git_spawn = {
43
117
  read,
118
+ read_remote,
44
119
  with_output,
120
+ with_output_remote,
45
121
  }
46
122
 
47
123
  export { git_spawn }
@@ -0,0 +1,74 @@
1
+ import { execa } from 'execa'
2
+ import { git_utilities } from './constants'
3
+
4
+ // The ssh environment every git network call runs under (joshuafolkken/kit#2942). It began inside
5
+ // `git-push-transport.ts` as the push's own (joshuafolkken/kit#1251), and moved here when the fetch
6
+ // and pull of `josh main:sync` turned out to need the same thing: a dead connection under a `git
7
+ // fetch` was waited on for 37 minutes, stalling the unattended backlog driver behind it.
8
+ //
9
+ // SSH's own liveness probe: three unanswered checks 15 seconds apart, so a connection that dies
10
+ // mid-transfer is noticed in about 45 seconds instead of waiting on the TCP default. The caller's
11
+ // timeout bounds the damage either way; this is what makes the common case fail in seconds rather
12
+ // than sit out the whole budget — and, because ssh exits on its own, it is also what leaves no ssh
13
+ // behind: git does not kill its transport child when it is itself killed on a timeout.
14
+ const SSH_KEEPALIVE_OPTIONS = '-o ServerAliveInterval=15 -o ServerAliveCountMax=3'
15
+ const SSH_COMMAND_VARIABLE = 'GIT_SSH_COMMAND'
16
+ const SSH_LEGACY_VARIABLE = 'GIT_SSH'
17
+ const KEEPALIVE_SSH_COMMAND = `ssh ${SSH_KEEPALIVE_OPTIONS}`
18
+ const SSH_COMMAND_CONFIG_KEY = 'core.sshCommand'
19
+
20
+ // Whatever already decides how ssh is invoked, or an empty string when nothing does. git reads three
21
+ // sources in this order — `GIT_SSH_COMMAND`, `core.sshCommand`, then the legacy `GIT_SSH` — and the
22
+ // last one has to be asked as well precisely because it loses: setting `GIT_SSH_COMMAND` on top of a
23
+ // `GIT_SSH=plink.exe` outranks it, so git would run an ssh binary the user did not choose.
24
+ function to_environment_value(name: string): string {
25
+ return process.env[name]?.trim() ?? ''
26
+ }
27
+
28
+ function to_configured_ssh_command(): string {
29
+ const from_command = to_environment_value(SSH_COMMAND_VARIABLE)
30
+
31
+ return from_command === '' ? to_environment_value(SSH_LEGACY_VARIABLE) : from_command
32
+ }
33
+
34
+ // Whether any of those three sources answered. **A hit means hands off entirely.**
35
+ //
36
+ // Appending the options to a command someone else chose is not safe, because they are OpenSSH's:
37
+ // `plink` and `TortoiseGitPlink` are supported ssh commands on the platform `get_git_command_for_spawn`
38
+ // goes out of its way to handle, and a wrapper script with a fixed argument list is common on any
39
+ // platform — each of them exits on a usage error rather than connecting. Setting the variable while
40
+ // `core.sshCommand` is configured is the same mistake from the other side: the environment wins, so
41
+ // a per-repository key would be silently replaced by a plain `ssh`.
42
+ //
43
+ // What those users lose is the keepalive, not the fix: the caller's timeout still bounds the call,
44
+ // and `ServerAliveInterval` belongs in their own ssh config where it applies to every tool they run.
45
+ async function has_configured_ssh_command(): Promise<boolean> {
46
+ if (to_configured_ssh_command() !== '') return true
47
+
48
+ try {
49
+ const git_command_bin = git_utilities.get_git_command_for_spawn()
50
+ // execa runs the binary directly with an argument array and no `shell` option, so CLI
51
+ // args cannot break out of a shell sandbox; the git command and args are internally
52
+ // controlled, never untrusted input. tssecurity:S8705 is a false positive here.
53
+ const { stdout } = await execa(git_command_bin, ['config', '--get', SSH_COMMAND_CONFIG_KEY]) // NOSONAR
54
+
55
+ return stdout.trim() !== ''
56
+ } catch {
57
+ // `git config --get` exits 1 when the key is unset, which is the answer rather than a failure.
58
+ return false
59
+ }
60
+ }
61
+
62
+ // The `env` a git network spawn passes to execa: the keepalive command, or nothing at all.
63
+ async function to_environment(): Promise<Record<string, string>> {
64
+ const should_keep_alive = !(await has_configured_ssh_command())
65
+
66
+ return should_keep_alive ? { [SSH_COMMAND_VARIABLE]: KEEPALIVE_SSH_COMMAND } : {}
67
+ }
68
+
69
+ const git_ssh_keepalive = {
70
+ to_environment,
71
+ }
72
+
73
+ export { git_ssh_keepalive }
74
+ export { KEEPALIVE_SSH_COMMAND, SSH_COMMAND_VARIABLE, SSH_LEGACY_VARIABLE }
@@ -62,6 +62,7 @@ async function stage_untracked_files(files: ReadonlyArray<string>): Promise<void
62
62
  if (files.length === 0) return
63
63
 
64
64
  for (const file of files) {
65
+ // eslint-disable-next-line no-await-in-loop -- git add holds the index lock, so two at once fail
65
66
  await git_command.add_path(file)
66
67
  }
67
68
 
@@ -1,4 +1,4 @@
1
- import { animation_helpers, type AnimationOptions } from './animation-helpers'
1
+ import { animation_helpers, type AnimationOptions } from '#scripts/lib/animation-helpers'
2
2
  import { REQUIRED_STATUS_LENGTH, STAGED_STATUS_INDEX, UNTRACKED_FILE_PREFIX } from './constants'
3
3
  import { git_command } from './git-command'
4
4
 
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env tsx
2
2
  import { parseArgs } from 'node:util'
3
+ import { git_pr } from '#scripts/gh/git-pr'
3
4
  import { cli_body } from '#scripts/josh/cli-body'
4
5
  import { test_red_commit } from '#scripts/test/test-red-commit'
5
6
  import { git_branch } from './git-branch'
6
7
  import { git_commit } from './git-commit'
7
8
  import { git_error } from './git-error'
8
9
  import { git_issue, type IssueInfo } from './git-issue'
9
- import { git_pr } from './git-pr'
10
10
  import { git_preflight } from './git-preflight'
11
11
  import { git_prompt, type WorkflowConfirmations } from './git-prompt'
12
12
  import { git_push } from './git-push'
@@ -89,6 +89,7 @@ async function delete_each(names: ReadonlyArray<string>): Promise<PruneResult> {
89
89
 
90
90
  for (const name of names) {
91
91
  try {
92
+ // eslint-disable-next-line no-await-in-loop -- branch deletions write the same refs, one at a time
92
93
  await git_spawn.read(['branch', '-d', name])
93
94
  result.deleted.push(name)
94
95
  } catch {
@@ -100,9 +101,10 @@ async function delete_each(names: ReadonlyArray<string>): Promise<PruneResult> {
100
101
  }
101
102
 
102
103
  // `fetch --prune` first, because `[gone]` is read from the remote-tracking refs and those outlive the
103
- // remote branch until something prunes them.
104
+ // remote branch until something prunes them. The fetch is the one call here that reaches the remote,
105
+ // so it is the one bounded (joshuafolkken/kit#2942).
104
106
  async function prune(default_branch: string): Promise<PruneResult> {
105
- await git_spawn.read(['fetch', '--prune'])
107
+ await git_spawn.read_remote(['fetch', '--prune'])
106
108
 
107
109
  return await delete_each(await read_candidates(default_branch))
108
110
  }
@@ -1,4 +1,4 @@
1
- import { MAX_SCANNED } from './git-gh-issue-list'
1
+ import { MAX_SCANNED } from '#scripts/gh/git-gh-issue-list'
2
2
 
3
3
  // Why an open-issue listing stopped short of the end of the backlog, or that it did not
4
4
  // (joshuafolkken/kit#1067).
@@ -114,7 +114,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
114
114
  process.exitCode = await run(argv)
115
115
  }
116
116
 
117
- const main_merge = { COMMAND_NAME, main, run }
117
+ const main_merge = { run }
118
118
 
119
119
  if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
120
120
 
@@ -70,9 +70,27 @@ async function prune_quietly(default_branch: string): Promise<void> {
70
70
  }
71
71
  }
72
72
 
73
+ // **The local default branch is fast-forwarded before it is checked out** (joshuafolkken/kit#2979).
74
+ // A run's ledger file is committed on its feature branch and merged; a line appended afterwards leaves
75
+ // it dirty, and git refuses to check out a stale default branch that lacks the file — so `run:tail`'s
76
+ // sync failed exactly when the flush after it had work. Once fast-forwarded, the default branch holds
77
+ // the committed file and the checkout carries the dirty lines over (the same step the flush takes,
78
+ // joshuafolkken/kit#2462). Skipped on the default branch, where `fetch` refuses to update the checked-out
79
+ // ref; a refusal elsewhere — a local default ahead of origin — is left to the checkout and pull to judge.
80
+ async function fast_forward_quietly(default_branch: string): Promise<void> {
81
+ if ((await git_command.branch()) === default_branch) return
82
+
83
+ try {
84
+ await git_command.fast_forward_local(default_branch)
85
+ } catch {
86
+ // The checkout and `pull --ff-only` below decide, exactly as before this step existed.
87
+ }
88
+ }
89
+
73
90
  async function synchronize(): Promise<number> {
74
91
  const default_branch = await git_command.get_default_branch()
75
92
 
93
+ await fast_forward_quietly(default_branch)
76
94
  await git_command.checkout(default_branch)
77
95
  await git_command.pull_fast_forward()
78
96
  await prune_quietly(default_branch)
@@ -115,7 +133,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
115
133
  process.exitCode = await run(argv)
116
134
  }
117
135
 
118
- const main_sync = { COMMAND_NAME, LANE_REFUSAL, main, run }
136
+ const main_sync = { run }
119
137
 
120
138
  if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
121
139
 
@@ -87,10 +87,7 @@ function parse_json_object_safe<T>(raw_json: string, schema: z.ZodType<T>): T |
87
87
  }
88
88
 
89
89
  const parse_json = {
90
- parse_json_array_safe,
91
- parse_json_array_or_undefined,
92
90
  parse_json_object_safe,
93
- read_json_listing,
94
91
  }
95
92
 
96
93
  export {
@@ -2,7 +2,9 @@ import { randomUUID } from 'node:crypto'
2
2
  import { linkSync, renameSync, rmSync } from 'node:fs'
3
3
  import { setTimeout as sleep } from 'node:timers/promises'
4
4
  import { process_identity } from '#scripts/josh/process-identity'
5
+ import { process_owner_schema, type ProcessOwner } from '#scripts/josh/process-owner'
5
6
  import { stamp_file } from '#scripts/josh/stamp-file'
7
+ import { json_value } from '#scripts/lib/json-value'
6
8
  import { git_common_directory } from './git-common-directory'
7
9
 
8
10
  // One holder at a time per repository, for work that every work tree of that repository shares
@@ -14,32 +16,29 @@ import { git_common_directory } from './git-common-directory'
14
16
 
15
17
  const POLL_INTERVAL_MS = 200
16
18
 
17
- interface LockOwner {
18
- pid: number
19
- process_start?: string
20
- }
21
-
22
- type IsGone = (owner: LockOwner) => boolean
19
+ type IsGone = (owner: ProcessOwner) => boolean
23
20
 
24
- function lock_path(prefix: string, cwd: string = process.cwd()): string {
25
- return stamp_file.stamp_path(prefix, git_common_directory.repository(cwd) ?? cwd)
21
+ // Without a `cwd` the read keeps the inherited git location variables, as every other git call of the
22
+ // running process does; an explicit `cwd` clears them so that directory is the one answered for.
23
+ function lock_path(prefix: string, cwd?: string): string {
24
+ return stamp_file.stamp_path(prefix, git_common_directory.repository(cwd) ?? cwd ?? process.cwd())
26
25
  }
27
26
 
28
- function parse_owner(raw: string | undefined): LockOwner | undefined {
27
+ // A record that is not JSON, or is JSON of any other shape — `null`, an array, an object with no
28
+ // numeric `pid` — is unreadable rather than an owner, so it is never judged and never cleared.
29
+ function parse_owner(raw: string | undefined): ProcessOwner | undefined {
29
30
  if (raw === undefined) return undefined
30
31
 
31
- try {
32
- return JSON.parse(raw) as LockOwner
33
- } catch {
34
- return undefined
35
- }
32
+ const parsed = process_owner_schema.safeParse(json_value.parse_or_undefined(raw))
33
+
34
+ return parsed.success ? parsed.data : undefined
36
35
  }
37
36
 
38
- function read_owner(target: string): LockOwner | undefined {
37
+ function read_owner(target: string): ProcessOwner | undefined {
39
38
  return parse_owner(stamp_file.read_stamp_text(target))
40
39
  }
41
40
 
42
- function is_owner_gone(owner: LockOwner): boolean {
41
+ function is_owner_gone(owner: ProcessOwner): boolean {
43
42
  return process_identity.is_same_process(owner.pid, owner.process_start) === false
44
43
  }
45
44
 
@@ -111,6 +110,7 @@ async function acquire(target: string, max_wait_ms: number): Promise<boolean> {
111
110
 
112
111
  while (!claim(target)) {
113
112
  if (Date.now() >= deadline) return false
113
+ // eslint-disable-next-line no-await-in-loop -- polling: each read waits on the state the previous one saw
114
114
  await sleep(POLL_INTERVAL_MS)
115
115
  }
116
116
 
@@ -1,4 +1,4 @@
1
- import { git_spawn } from './git-spawn'
1
+ import { git_spawn } from '#scripts/git/git-spawn'
2
2
 
3
3
  // The one place a sanctioned `git stash pop` is targeted by its message rather than its stack
4
4
  // position (joshuafolkken/kit#2050). The stash is a single repository-wide stack shared by every
@@ -47,7 +47,7 @@ function to_request(parsed: ParsedValues): Request | undefined {
47
47
  return { message, dir: parsed.values.dir }
48
48
  }
49
49
 
50
- const stash_pop_args = { USAGE, message_of, read_arguments, to_request }
50
+ const stash_pop_args = { USAGE, read_arguments, to_request }
51
51
 
52
52
  export type { Request }
53
53
  export { stash_pop_args }
@@ -97,7 +97,6 @@ const stash_pop_cli = {
97
97
  CONFLICTED_VERDICT,
98
98
  NO_MATCH_VERDICT,
99
99
  POPPED_VERDICT,
100
- main,
101
100
  run,
102
101
  }
103
102
 
@@ -1,4 +1,4 @@
1
- import { repository_lock } from './repository-lock'
1
+ import { repository_lock } from '#scripts/git/repository-lock'
2
2
 
3
3
  // One stash sweep at a time per repository (joshuafolkken/kit#2701). The stash is a single stack every
4
4
  // work tree shares, and a `backlogrun` runs one sweep per lane seat at once: two sweeps that each
@@ -11,7 +11,7 @@ const LOCK_PREFIX = 'josh-stash-sweep-lock-'
11
11
  // wait; the cap only bounds a holder that hung, and a sweep that gives up keeps its entries.
12
12
  const MAX_WAIT_MS = 30_000
13
13
 
14
- function lock_path(cwd: string = process.cwd()): string {
14
+ function lock_path(cwd?: string): string {
15
15
  return repository_lock.lock_path(LOCK_PREFIX, cwd)
16
16
  }
17
17
 
@@ -25,6 +25,6 @@ async function with_lock<T>(
25
25
  return await repository_lock.with_lock(work, target, max_wait_ms)
26
26
  }
27
27
 
28
- const stash_sweep_lock = { clear_stale: repository_lock.clear_stale, lock_path, with_lock }
28
+ const stash_sweep_lock = { clear_stale: repository_lock.clear_stale, with_lock }
29
29
 
30
30
  export { stash_sweep_lock }
@@ -146,7 +146,6 @@ if (process.argv[1] === fileURLToPath(import.meta.url)) {
146
146
 
147
147
  const codex_hook_adapter = {
148
148
  format_posttool_payloads,
149
- patch_paths,
150
149
  posttool_payloads,
151
150
  pretool_outcome,
152
151
  pretool_payload,
@@ -122,7 +122,7 @@ async function spelling_diagnostics(
122
122
  }
123
123
  }
124
124
 
125
- const edited_cspell = { format_unknown_words, is_checkable, spelling_diagnostics }
125
+ const edited_cspell = { format_unknown_words, spelling_diagnostics }
126
126
 
127
127
  export type { CspellRunner }
128
128
  export { edited_cspell, MAX_DIAGNOSTIC_CHARS }
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env tsx
2
+ import { text } from 'node:stream/consumers'
3
+ import { fileURLToPath } from 'node:url'
4
+ import { report_no_payload, run_hook } from './format-edited-file'
5
+
6
+ // The `PostToolUse` hook's entry, kept apart from `format-edited-file.ts` for the reason
7
+ // `pretool-guard-cli.ts` gives (joshuafolkken/kit#2922): `codex-hook-adapter.ts` imports that module,
8
+ // so a self-invoke left in it lands in a shared chunk and the bundled hook never runs.
9
+ if (process.argv[1] === fileURLToPath(import.meta.url)) {
10
+ if (process.stdin.isTTY) {
11
+ report_no_payload()
12
+ } else {
13
+ await run_hook(await text(process.stdin))
14
+ }
15
+ }
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env tsx
2
2
  import { existsSync } from 'node:fs'
3
3
  import path from 'node:path'
4
- import { text } from 'node:stream/consumers'
5
4
  import { fileURLToPath } from 'node:url'
6
5
  import { resolve_local_bin, resolve_package_bin } from '#scripts/build/local-bin'
7
6
  import { ESLINT_EDIT_CACHE_FLAGS } from '#scripts/josh/josh-command-types'
@@ -328,6 +327,7 @@ async function run_command(command: FormatCommand, project_root: string): Promis
328
327
  let outcome: CommandOutcome = { exit_code: 0, stdout: '' }
329
328
 
330
329
  for (const invocation of resolve_invocations(command, project_root)) {
330
+ // eslint-disable-next-line no-await-in-loop -- a fallback route runs only when the previous one failed to start
331
331
  outcome = await spawn_invocation(invocation, project_root)
332
332
  if (!is_start_failure(outcome)) return outcome
333
333
  }
@@ -375,6 +375,7 @@ async function collect_unfixed(
375
375
 
376
376
  for (const command of plan) {
377
377
  try {
378
+ // eslint-disable-next-line no-await-in-loop -- formatters rewrite the same file, in plan order
378
379
  unfixed = eslint_unfixed(command, await runner(command, project_root)) ?? unfixed
379
380
  } catch {
380
381
  // One formatter failing to start is not a reason to skip the next: prettier runs last, and
@@ -482,14 +483,6 @@ async function run_hook(payload: string): Promise<void> {
482
483
  if (context !== undefined) process.stdout.write(`${build_envelope(context)}\n`)
483
484
  }
484
485
 
485
- if (process.argv[1] === fileURLToPath(import.meta.url)) {
486
- if (process.stdin.isTTY) {
487
- report_no_payload()
488
- } else {
489
- await run_hook(await text(process.stdin))
490
- }
491
- }
492
-
493
486
  export {
494
487
  build_envelope,
495
488
  compose_context,
@@ -501,7 +494,9 @@ export {
501
494
  plan_commands,
502
495
  plan_daemon_restart,
503
496
  relative_to_root,
497
+ report_no_payload,
504
498
  resolve_invocations,
499
+ run_hook,
505
500
  select_invocation,
506
501
  ESLINT_DAEMON,
507
502
  MAX_DIAGNOSTIC_CHARS,
@@ -136,10 +136,6 @@ if (process.argv[1] === fileURLToPath(import.meta.url)) {
136
136
 
137
137
  const pre_push_unit = {
138
138
  FORCE_ENV,
139
- format_skip,
140
- forwarded_arguments,
141
- read_push_tree,
142
- reusable_green_push,
143
139
  run_pre_push_unit,
144
140
  }
145
141