@joshuafolkken/kit 1.1010.0 → 1.1050.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 (350) hide show
  1. package/.claude/settings.json +1 -5
  2. package/.claude/skills/dependency-update/SKILL.md +6 -3
  3. package/.claude/skills/epic-commands/SKILL.md +46 -17
  4. package/.claude/skills/verify-ui/SKILL.md +1 -1
  5. package/.claude/skills/workflow-commands/SKILL.md +10 -25
  6. package/.claude/skills/workflow-commands/background-commands.md +1 -1
  7. package/.claude/skills/workflow-commands/backlogrun-child.md +6 -4
  8. package/.claude/skills/workflow-commands/backlogrun-lanes.md +1 -1
  9. package/.claude/skills/workflow-commands/backlogrun-park.md +6 -0
  10. package/.claude/skills/workflow-commands/backlogrun-progress.md +30 -36
  11. package/.claude/skills/workflow-commands/backlogrun-steps.md +16 -16
  12. package/.claude/skills/workflow-commands/backlogrun.md +3 -12
  13. package/.claude/skills/workflow-commands/chain-rule.md +2 -2
  14. package/.claude/skills/workflow-commands/followup-reference.md +2 -2
  15. package/.claude/skills/workflow-commands/fullrun-steps.md +4 -3
  16. package/.claude/skills/workflow-commands/fullrun.md +1 -1
  17. package/.claude/skills/workflow-commands/halfrun.md +2 -1
  18. package/.claude/skills/workflow-commands/into-target.md +1 -1
  19. package/.claude/skills/workflow-commands/issue-comments.md +1 -1
  20. package/.claude/skills/workflow-commands/observation-filing.md +80 -126
  21. package/.claude/skills/workflow-commands/pre-gate-cut.md +33 -36
  22. package/.claude/skills/workflow-commands/prerequisite.md +1 -1
  23. package/.claude/skills/workflow-commands/working-tree-hold.md +2 -2
  24. package/.codex/hooks.json +1 -5
  25. package/.github/workflows/auto-tag.yml +21 -0
  26. package/.github/workflows/publish.yml +9 -10
  27. package/.github/workflows/sonar-qube.yml +1 -1
  28. package/AGENTS.md +4 -25
  29. package/CLAUDE.md +24 -38
  30. package/GEMINI.md +4 -24
  31. package/README.md +22 -56
  32. package/dist/CLAUDE.md +24 -38
  33. package/dist/hooks/batch-guard.js +4 -4
  34. package/dist/hooks/{chunk-6PSTVOLH.js → chunk-5BK3K7V4.js} +114 -90
  35. package/dist/hooks/{chunk-PAXMLGSS.js → chunk-7VPDUBRN.js} +93 -175
  36. package/dist/hooks/{chunk-KPZN42RT.js → chunk-DMQN45FN.js} +3 -3
  37. package/dist/hooks/{chunk-WMIR5SNX.js → chunk-EJDX2TOB.js} +13 -3
  38. package/dist/hooks/{chunk-A2H5I2VD.js → chunk-GQ7KP45M.js} +2 -2
  39. package/dist/hooks/{chunk-4GDR2YTV.js → chunk-HJIISEAC.js} +4 -4
  40. package/dist/hooks/{chunk-AWTFKKFW.js → chunk-NAS4C7GP.js} +6 -33
  41. package/dist/hooks/{chunk-56LGMJJV.js → chunk-NJQOBE6L.js} +2 -2
  42. package/dist/hooks/{chunk-EZLHXKJ6.js → chunk-RLDX5SOC.js} +1222 -941
  43. package/dist/hooks/{chunk-GBJUERYK.js → chunk-WQ4OSBSS.js} +10 -3
  44. package/dist/hooks/codex-hook-adapter.js +10 -10
  45. package/dist/hooks/duplicate-read-guard.js +5 -5
  46. package/dist/hooks/format-edited.js +15 -34
  47. package/dist/hooks/investigation-guard.js +5 -5
  48. package/dist/hooks/pretool-guard.js +23 -16
  49. package/dist/hooks/stop-guard.js +21 -200
  50. package/dist/josh.js +42 -125
  51. package/dist/version/index.js +466 -42
  52. package/eslint/base.js +2 -11
  53. package/package.json +36 -10
  54. package/prompts/coding-standards.md +15 -290
  55. package/prompts/collaboration-workflow/cross-repo-epic.md +2 -51
  56. package/prompts/collaboration-workflow/epic-audit.md +2 -53
  57. package/prompts/collaboration-workflow/epic-bundle.md +2 -106
  58. package/prompts/collaboration-workflow/file-edits.md +6 -53
  59. package/prompts/collaboration-workflow/issue-template.md +4 -4
  60. package/prompts/collaboration-workflow/operating-rules.md +18 -75
  61. package/prompts/collaboration-workflow/principles.md +74 -0
  62. package/prompts/collaboration-workflow/residency.md +55 -15
  63. package/prompts/collaboration-workflow/rule-delivery.md +5 -46
  64. package/prompts/collaboration-workflow/shell-body.md +7 -9
  65. package/prompts/collaboration-workflow/turn-batching.md +21 -37
  66. package/prompts/collaboration-workflow/upstream-interrupt.md +1 -1
  67. package/prompts/collaboration-workflow/wip-cap.md +15 -18
  68. package/prompts/collaboration-workflow.md +22 -28
  69. package/prompts/sonar-hotspot-handling.md +1 -1
  70. package/scripts/adopt/adopt-logic.ts +2 -2
  71. package/scripts/adopt/adopt-toolkits.ts +3 -1
  72. package/scripts/adopt/adopt.ts +2 -2
  73. package/scripts/agent/agent-event.ts +2 -9
  74. package/scripts/agent/agent-exit-record.ts +2 -9
  75. package/scripts/auto-ok/auto-ok-cli.ts +9 -9
  76. package/scripts/backlog/backlog-budget-cli.ts +2 -6
  77. package/scripts/backlog/backlog-drive-cli.ts +20 -10
  78. package/scripts/backlog/backlog-drive.ts +50 -16
  79. package/scripts/backlog/backlog-next.ts +24 -8
  80. package/scripts/backlog/backlog-offer-cli.ts +6 -5
  81. package/scripts/backlog/backlog-plan-cli.ts +5 -1
  82. package/scripts/backlog/backlog-plan.ts +1 -1
  83. package/scripts/backlog/backlog-pool.ts +31 -11
  84. package/scripts/backlog/backlog-rank.ts +106 -0
  85. package/scripts/backlog/backlog-waves.ts +42 -29
  86. package/scripts/build/build-bin.ts +2 -1
  87. package/scripts/build/build-config-merge.ts +2 -1
  88. package/scripts/build/build-hooks.ts +31 -6
  89. package/scripts/build/build-managed-marker.ts +2 -1
  90. package/scripts/build/build-self-sync-guard.ts +2 -1
  91. package/scripts/build/build-version.ts +2 -1
  92. package/scripts/cases/cases-logic.ts +2 -6
  93. package/scripts/ci/pr-classification.ts +13 -11
  94. package/scripts/cost-runtime/cost-transcript.ts +4 -11
  95. package/scripts/delegation/delegation-policy.ts +11 -0
  96. package/scripts/doctor/doctor-consumer.ts +5 -12
  97. package/scripts/doctor/doctor-ports.ts +2 -2
  98. package/scripts/document/document-byte-budget.ts +13 -21
  99. package/scripts/document/document-section.ts +2 -6
  100. package/scripts/document/entry-read-budget.ts +6 -5
  101. package/scripts/{git/git-epic-add-body.ts → epic/epic-add-body.ts} +23 -23
  102. package/scripts/{git/git-epic-add-plan.ts → epic/epic-add-plan.ts} +23 -26
  103. package/scripts/{git/git-epic-add.ts → epic/epic-add.ts} +17 -17
  104. package/scripts/epic/epic-audit-cli.ts +4 -4
  105. package/scripts/epic/epic-audit-orphans.ts +2 -2
  106. package/scripts/epic/epic-audit-rationale.ts +1 -1
  107. package/scripts/epic/epic-audit.ts +1 -1
  108. package/scripts/{git/git-epic-body.ts → epic/epic-body.ts} +6 -6
  109. package/scripts/epic/epic-bundle-cli.ts +1 -1
  110. package/scripts/epic/epic-bundle.ts +2 -2
  111. package/scripts/epic/epic-candidate-confirm.ts +2 -1
  112. package/scripts/{git/git-epic-chains.ts → epic/epic-chains.ts} +4 -4
  113. package/{scripts-ai → scripts/epic}/epic-check.ts +5 -4
  114. package/{scripts-ai → scripts/epic}/epic-cli.ts +4 -4
  115. package/scripts/{git/git-epic-close-comment.ts → epic/epic-close-comment.ts} +9 -9
  116. package/scripts/{git/git-epic-close.ts → epic/epic-close.ts} +23 -19
  117. package/scripts/epic/epic-cross-repo.ts +21 -38
  118. package/scripts/{git/git-epic-decision.ts → epic/epic-decision.ts} +12 -14
  119. package/scripts/epic/epic-fetch.ts +3 -3
  120. package/scripts/epic/epic-graph.ts +3 -3
  121. package/scripts/epic/epic-index.ts +2 -2
  122. package/scripts/epic/epic-issue.ts +1 -1
  123. package/scripts/epic/epic-lane-offer.ts +11 -22
  124. package/scripts/epic/epic-next.ts +3 -3
  125. package/scripts/{git/git-epic-parse.ts → epic/epic-parse.ts} +3 -3
  126. package/scripts/{git/git-epic-promote.ts → epic/epic-promote.ts} +10 -10
  127. package/scripts/epic/epic-rank.ts +37 -0
  128. package/scripts/{git/git-epic-read.ts → epic/epic-read.ts} +9 -9
  129. package/scripts/{git/git-epic-reconcile.ts → epic/epic-reconcile.ts} +18 -20
  130. package/scripts/{git/git-epic-reference.ts → epic/epic-reference.ts} +4 -23
  131. package/scripts/epic/epic-relation-recheck.ts +4 -3
  132. package/scripts/{git/git-epic-relations.ts → epic/epic-relations.ts} +5 -5
  133. package/scripts/{git/git-epic-remove-plan.ts → epic/epic-remove-plan.ts} +17 -19
  134. package/scripts/{git/git-epic-remove.ts → epic/epic-remove.ts} +13 -13
  135. package/scripts/{git/git-epic-run.ts → epic/epic-run.ts} +27 -27
  136. package/scripts/{git/git-epic-sections.ts → epic/epic-sections.ts} +6 -6
  137. package/scripts/{git/git-epic-shape.ts → epic/epic-shape.ts} +7 -7
  138. package/scripts/epic/epic-solo.ts +29 -28
  139. package/scripts/{git/git-epic-validate.ts → epic/epic-validate.ts} +13 -13
  140. package/{scripts-ai → scripts/epic}/epic.ts +17 -16
  141. package/scripts/gh/fix-gh-packages.ts +2 -1
  142. package/scripts/gh/gh-spawn.ts +12 -10
  143. package/scripts/git/constants.ts +1 -1
  144. package/scripts/git/git-branch.ts +10 -1
  145. package/scripts/git/git-command.ts +2 -2
  146. package/scripts/git/git-error.ts +2 -5
  147. package/scripts/git/git-execa-error.ts +6 -1
  148. package/{scripts-ai → scripts/git}/git-followup-finish.ts +7 -7
  149. package/scripts/git/git-followup-flush.ts +74 -48
  150. package/scripts/git/git-followup-issue-close.ts +2 -2
  151. package/scripts/git/git-followup-label.ts +1 -1
  152. package/scripts/git/git-followup-pending.ts +1 -1
  153. package/{scripts-ai → scripts/git}/git-followup-workflow.ts +23 -11
  154. package/scripts/git/git-gh-exec.ts +85 -26
  155. package/scripts/git/git-gh-issue-read.ts +2 -2
  156. package/scripts/git/git-gh-issue-rest.ts +2 -2
  157. package/scripts/git/git-gh-issue-write.ts +6 -6
  158. package/scripts/git/git-gh-pr-read.ts +0 -21
  159. package/scripts/git/git-gh-pr.ts +2 -23
  160. package/scripts/git/git-next-issues.ts +34 -5
  161. package/scripts/git/git-pr-followup-wrapup.ts +2 -6
  162. package/scripts/git/git-preflight.ts +25 -10
  163. package/scripts/git/git-push-transport.ts +12 -69
  164. package/scripts/git/git-spawn.ts +79 -3
  165. package/scripts/git/git-ssh-keepalive.ts +74 -0
  166. package/scripts/git/git-staging.ts +21 -9
  167. package/{scripts-ai → scripts/git}/git-workflow.ts +11 -11
  168. package/scripts/git/github-issue-url.ts +1 -1
  169. package/scripts/git/gone-branch.ts +3 -2
  170. package/scripts/git/issue-labels.ts +13 -1
  171. package/scripts/git/issue-rank.ts +89 -0
  172. package/scripts/git/issue-reference.ts +19 -0
  173. package/scripts/git/main-merge.ts +2 -1
  174. package/scripts/git/main-sync.ts +3 -2
  175. package/scripts/git/schemas.ts +1 -1
  176. package/scripts/git/stash-pop-args.ts +7 -13
  177. package/scripts/git/stash-pop-cli.ts +2 -1
  178. package/{scripts-ai → scripts/git}/telegram-test-logic.ts +2 -2
  179. package/{scripts-ai → scripts/git}/telegram-test.ts +7 -7
  180. package/scripts/hooks/format-edited-cli.ts +15 -0
  181. package/scripts/hooks/format-edited-file.ts +2 -9
  182. package/scripts/hooks/format-rewrite-notice.ts +2 -8
  183. package/scripts/hooks/pretool-guard-cli.ts +21 -0
  184. package/scripts/hooks/pretool-guard.ts +14 -15
  185. package/scripts/init/init-ai-copy.ts +2 -5
  186. package/scripts/init/init.ts +8 -4
  187. package/scripts/init/start-exec.ts +7 -1
  188. package/scripts/init/start-plan.ts +18 -5
  189. package/scripts/init/start-setup-pr.ts +46 -19
  190. package/scripts/init/start-steps.ts +43 -10
  191. package/scripts/init/start.ts +42 -11
  192. package/scripts/issue/issue-cite.ts +19 -1
  193. package/scripts/issue/issue-comment-cli.ts +2 -1
  194. package/scripts/issue/issue-file-cli.ts +2 -1
  195. package/scripts/issue/issue-fold-cli.ts +9 -16
  196. package/scripts/issue/issue-scout-cli.ts +8 -13
  197. package/scripts/issue/measure-rerun-cli.ts +7 -6
  198. package/scripts/josh/josh-command-map.ts +0 -102
  199. package/scripts/josh/josh-commands-ai.ts +2 -2
  200. package/scripts/josh/josh-commands-backlog.ts +1 -1
  201. package/scripts/josh/josh-commands-development.ts +3 -3
  202. package/scripts/josh/josh-commands-project.ts +1 -1
  203. package/scripts/josh/josh-commands-workflow.ts +4 -4
  204. package/scripts/lane/lane-child-marker.ts +16 -2
  205. package/scripts/lane/lane-cli.ts +34 -15
  206. package/scripts/lane/lane-open.ts +3 -2
  207. package/scripts/lane/lane-registry.ts +3 -6
  208. package/scripts/lane/lane-report.ts +10 -4
  209. package/scripts/lib/cli-flags.ts +20 -2
  210. package/scripts/lib/error-message.ts +9 -0
  211. package/scripts/lib/read-file.ts +26 -2
  212. package/scripts/observations/observation-ledger-home.ts +98 -26
  213. package/scripts/observations/observation-ledger-migrate.ts +26 -21
  214. package/scripts/observations/observation-ledger-prepare.ts +10 -20
  215. package/scripts/observations/observation-ledger.ts +58 -25
  216. package/scripts/observations/observations-flush-cli.ts +6 -23
  217. package/scripts/observations/observations-flush-landing.ts +2 -1
  218. package/scripts/observations/observations-flush.ts +29 -20
  219. package/scripts/package/package-scout-cli.ts +8 -16
  220. package/scripts/ports/port-command.ts +2 -1
  221. package/scripts/propagate/propagate-plan.ts +185 -0
  222. package/scripts/propagate/propagate-publish.ts +6 -7
  223. package/scripts/propagate/propagate-run.ts +5 -1
  224. package/scripts/propagate/propagate-steps.ts +18 -2
  225. package/scripts/propagate/propagate-targets.ts +13 -2
  226. package/scripts/propagate/propagate.ts +63 -44
  227. package/scripts/refactor/import-graph.ts +2 -6
  228. package/scripts/registry-migration/migrate-logic.ts +1 -0
  229. package/scripts/registry-migration/migrate.ts +3 -2
  230. package/scripts/registry-migration/user-npmrc.ts +2 -2
  231. package/scripts/release/github-release.ts +1 -1
  232. package/scripts/release/release-cli.ts +2 -1
  233. package/scripts/repo/repo-setting.ts +10 -8
  234. package/scripts/review/review-attest.ts +44 -0
  235. package/scripts/review/review-brief-cli.ts +49 -2
  236. package/scripts/review/review-brief.ts +46 -1
  237. package/scripts/review/review-finding-ledger.ts +3 -3
  238. package/scripts/review/review-findings-cli.ts +4 -11
  239. package/scripts/review/review-record-cli.ts +14 -11
  240. package/scripts/review/review-record.ts +6 -16
  241. package/scripts/review/review-stamps.ts +7 -0
  242. package/scripts/rules/decision-oracle.ts +2 -2
  243. package/scripts/rules/implementation-cut.ts +1 -1
  244. package/scripts/rules/issue-fold.ts +1 -2
  245. package/scripts/rules/lane-carry-conflict.ts +1 -2
  246. package/scripts/rules/lane-park.ts +1 -2
  247. package/scripts/rules/pre-gate-cut.ts +2 -2
  248. package/scripts/rules/rule-body-guard.ts +2 -2
  249. package/scripts/rules/rule-value-cache.ts +99 -0
  250. package/scripts/rules/rule-value-cli.ts +10 -9
  251. package/scripts/rules/rule-value.ts +1 -1
  252. package/scripts/run/run-carry-args.ts +2 -6
  253. package/scripts/run/run-carry-cli.ts +5 -7
  254. package/scripts/run/run-cut-args.ts +7 -13
  255. package/scripts/run/run-ending-cli.ts +4 -7
  256. package/scripts/run/run-event-stream.ts +2 -5
  257. package/scripts/run/run-headless.ts +22 -6
  258. package/scripts/run/run-liveness-cli.ts +4 -7
  259. package/scripts/run/run-parent-cut-hook.ts +144 -0
  260. package/scripts/run/run-progress-args.ts +2 -6
  261. package/scripts/run/run-progress-cli.ts +2 -1
  262. package/scripts/run/run-progress-read.ts +2 -1
  263. package/scripts/run/run-progress.ts +21 -8
  264. package/scripts/run/run-ship-cli.ts +6 -74
  265. package/scripts/run/run-ship-preflight.ts +87 -0
  266. package/scripts/run/run-ship-review-steps.ts +5 -26
  267. package/scripts/run/run-ship-review.ts +9 -0
  268. package/scripts/run/run-ship-scoped.ts +44 -0
  269. package/scripts/run/run-ship-stage.ts +5 -1
  270. package/scripts/run/run-ship-steps.ts +105 -0
  271. package/scripts/run/run-ship.ts +2 -0
  272. package/scripts/run/run-tail-cli.ts +3 -3
  273. package/scripts/run/run-tidy-stashes.ts +7 -14
  274. package/scripts/run/run-wake-cli.ts +4 -8
  275. package/scripts/run/run-wake-describe.ts +19 -1
  276. package/scripts/run/run-wake-driver.ts +15 -2
  277. package/scripts/run/run-wake-session.ts +14 -4
  278. package/scripts/run/run-watcher-hook.ts +1 -1
  279. package/scripts/safe-chain/project-config.ts +3 -6
  280. package/scripts/security/security-audit-provision.ts +6 -7
  281. package/scripts/sonar/sonar-hotspots-cli.ts +2 -1
  282. package/scripts/sync/directory-copy-guard.ts +2 -1
  283. package/scripts/sync/sync-ai-files.ts +3 -3
  284. package/scripts/sync/template-source-logic.ts +3 -4
  285. package/scripts/test/e2e-retry-check.ts +3 -6
  286. package/scripts/time-runtime/time-bundle-call.ts +2 -2
  287. package/scripts/ui/ui-routes-cli.ts +3 -6
  288. package/scripts/version/bump-version.ts +2 -1
  289. package/scripts/version/npm-registry.ts +97 -0
  290. package/scripts/version/version-commands.ts +5 -4
  291. package/scripts/version/version-remote.ts +38 -33
  292. package/scripts/version/version-targets.ts +3 -3
  293. package/.claude/skills/workflow-commands/rule-residency.md +0 -267
  294. package/evals/scenarios/consult-not-execute.json +0 -20
  295. package/evals/scenarios/no-implicit-workflow.json +0 -26
  296. package/evals/scenarios/overrides-both-locations.json +0 -29
  297. package/evals/scenarios/upstream-interrupt.json +0 -23
  298. package/evals/scenarios/workflow-skill-loaded.json +0 -16
  299. package/prompts/agent-lint-protocol.json +0 -79
  300. package/prompts/agent-rules.md +0 -63
  301. package/prompts/collaboration-workflow/consultation-vs-execution.md +0 -8
  302. package/prompts/collaboration-workflow/distributed-docs.md +0 -7
  303. package/prompts/collaboration-workflow/durable-rules.md +0 -24
  304. package/prompts/collaboration-workflow/latest-first.md +0 -14
  305. package/prompts/collaboration-workflow/no-clones.md +0 -11
  306. package/prompts/collaboration-workflow/simplicity-first.md +0 -9
  307. package/prompts/collaboration-workflow/single-source-rules.md +0 -13
  308. package/scripts/build/shim-shell.ts +0 -25
  309. package/scripts/claude/skill-meta.ts +0 -37
  310. package/scripts/document/document-scan.ts +0 -108
  311. package/scripts/document/generate-catalog.ts +0 -69
  312. package/scripts/document/retired-phrases.ts +0 -143
  313. package/scripts/document/review-agent-type.ts +0 -46
  314. package/scripts/document/single-source.ts +0 -73
  315. package/scripts/git/git-fixture-workspace.ts +0 -88
  316. package/scripts/hooks/format-edited-file-fixtures.ts +0 -109
  317. package/scripts/hooks/prompt-hooks.ts +0 -38
  318. package/scripts/init/hook-command-bootstrap.ts +0 -83
  319. package/scripts/issue/issue-logic.ts +0 -50
  320. package/scripts/josh/__snapshots__/josh-command-map.test.ts.snap +0 -1227
  321. package/scripts/josh/josh-script-reader.ts +0 -11
  322. package/scripts/package/production-dependency-graph.ts +0 -68
  323. package/scripts/retrospective/retrospective-cli.ts +0 -97
  324. package/scripts/retrospective/retrospective.ts +0 -127
  325. package/scripts/rules/delivered-rules-harness.ts +0 -72
  326. package/scripts/rules/top-level-scripts-guard.ts +0 -47
  327. package/scripts/run/run-carry-flush.ts +0 -58
  328. package/scripts/run/run-transcript.golden.txt +0 -57
  329. package/scripts/run/run-wake-work.ts +0 -108
  330. package/scripts/sync/dependabot-pin-logic.ts +0 -135
  331. package/scripts/test/classify-isolation.ts +0 -149
  332. package/scripts/test/http-fault-injection.ts +0 -79
  333. package/scripts/test/josh-harness-environment.ts +0 -260
  334. package/scripts/test/josh-harness.ts +0 -96
  335. package/scripts/test/pilot-files.ts +0 -452
  336. package/scripts/test/pilot-measure.ts +0 -78
  337. package/scripts/test/test-network-guard.ts +0 -453
  338. package/scripts/test/test-repository-guard.ts +0 -317
  339. package/scripts/test/test-state-guard.ts +0 -85
  340. package/scripts/test/test-stdout-guard.ts +0 -54
  341. package/scripts/test/test-telegram-guard.ts +0 -90
  342. package/scripts/test/unit-guard-environment.ts +0 -12
  343. package/scripts/test/unit-projects.ts +0 -139
  344. package/scripts/test/vitest-include-globs.ts +0 -12
  345. package/scripts/time-runtime/time-batch-guard-fixtures.ts +0 -66
  346. package/scripts-ai/completion-gate.ts +0 -13
  347. package/scripts-ai/environment-loader.ts +0 -9
  348. /package/{scripts-ai → scripts/epic}/epic-cli-argv.ts +0 -0
  349. /package/{scripts-ai → scripts/epic}/epic-cli-remove.ts +0 -0
  350. /package/{scripts-ai → scripts/git}/followup-issue-number.ts +0 -0
@@ -1,143 +0,0 @@
1
- // Phrases retracted from the distributed documents, kept so a clone or a reverted decision cannot
2
- // creep back unnoticed (joshuafolkken/kit#1923). This is the small negative table that replaced the
3
- // ~140 scattered `not.toContain` assertions the per-rule marker suites carried: each phrase is
4
- // checked absent from the whole document corpus at once by `document-markers.test.ts`.
5
- //
6
- // Whitespace is collapsed on both sides before the comparison, so a phrase that the formatter would
7
- // wrap across a line break is still caught. A phrase here must stay genuinely gone everywhere; if one
8
- // is ever a legitimate part of a new document, remove its row rather than scoping it.
9
- const RETIRED_PHRASES: ReadonlyArray<string> = [
10
- '"Implemented <title>:',
11
- '"dev": "vite dev --port $(josh port dev)',
12
- '"dev": "vite dev --port $(pnpm josh port dev)',
13
- '"preview": "wrangler dev --port $(josh port preview)',
14
- '"preview": "wrangler dev --port $(pnpm josh port preview)',
15
- '"preview:stop": "kill-port $(josh port preview)',
16
- '"preview:stop": "kill-port $(pnpm josh port preview)',
17
- '### セッション対話の言語(`JOSH_SESSION_LANG`)',
18
- '**2 つ目を作ってはならない。**',
19
- '**2 件目以降で `--exclude` を省略してはならない。**',
20
- '**EPIC 作成へ落ちてはならない。**',
21
- '**`#N` が宣言された順序に載っていなくても構わない。**',
22
- '**`--ordered` は必須であって好みの問題ではない。**',
23
- '**`-u` は省略できない。**',
24
- '**■ Overview (plain language — always first)**',
25
- '**書き換えられた lock ファイルは最初の子と一緒に入る。**',
26
- '--- 技術詳細 ---',
27
- '2 件以上に分割したら常に epic を作る。件数の閾値も、実行順序の有無による分岐も無い',
28
- '3-6 line work summary',
29
- '3–6 line work summary',
30
- 'Artifact languages are unaffected',
31
- 'Ask the user to run `pnpm josh test` and share the output',
32
- 'CI only runs the suite it can find, so specs stay under',
33
- 'CI status check indicates a managed config file was updated',
34
- "Cross-package problems → interrupt with a new Issue, don't patch locally.",
35
- 'EPIC 全体で 1 回の質問',
36
- 'Fix in place and re-run `/code-review` at the level `pnpm josh review:level` prints on `git diff main`',
37
- 'Implement + PR',
38
- 'Invoking `halfrun` authorizes commit, push, and PR creation',
39
- 'Issue / PR / Telegram の言語は英語のまま変更なし',
40
- 'Issue plan comments MUST be written in English',
41
- 'Issue 本文に「`halfrun` で実行すること」と書いても強制力が無く',
42
- 'Neither toolkit carries `shot` yet',
43
- 'No toolkit ships that command yet',
44
- 'Plan comments MUST be in English',
45
- 'Poll at the polling interval; ask',
46
- 'Post the agreed plan in English',
47
- 'Post the plan in English',
48
- 'Print the headings exactly as written',
49
- 'Re-run after applying fixes until **no high or medium findings remain**.',
50
- 'The recommended default when in doubt is the root-cause interrupt',
51
- 'The user runs `pnpm josh test` and shares the full output',
52
- String.raw`Today that\n> is every consumer`,
53
- 'Typing `halfrun` approved implementing and merging',
54
- 'Verify **every** rule below. These are non-standard, so call out any violation.',
55
- 'What still waits for a person, today',
56
- '`into owner/repo#N` は正しい書式である',
57
- '`queue` との違いはひとつだけである',
58
- 'about 60 characters in Japanese, 15 words in English',
59
- 'artifact languages (Issue / PR / Telegram = English) are unchanged',
60
- 'ask them to run **`pnpm josh test`** locally',
61
- 'blocker を見る前に',
62
- 'chain-rule decision table in \\',
63
- 'code-reviewer',
64
- 'compose an implementation summary in English',
65
- 'exactly what it was) → `pnpm josh git -y` →',
66
- 'exists in neither toolkit yet',
67
- 'fix them in place and re-run `/code-review` at the level `pnpm josh review:level` prints. Nothing is committed yet',
68
- 'fresh-context',
69
- 'fresh-context subagent',
70
- 'gh issue list --label review-round2-skipped',
71
- 'including commit, push, PR creation',
72
- 'is a separate deliverable',
73
- "it asks only after a child that ran in the parent's own context",
74
- 'its own `pnpm josh gate` join',
75
- 'join it, and `pnpm josh git -y`; on `skip`',
76
- 'kit exports that rule for consumers and does not apply it to itself',
77
- 'operating-rules.md` → "Auto-merge',
78
- 'park したことで人が必要になる',
79
- 'park しない',
80
- 'park は依存として表現できない場合に限る',
81
- 'post the final review markdown as a PR comment',
82
- 'queue #101',
83
- 'runs the same pipeline through PR creation',
84
- 'sleep the polling interval and go back to step 1',
85
- 'stay in English regardless of `JOSH_SESSION_LANG`',
86
- 'stop before merge',
87
- 'stop with the PR OPEN',
88
- 'the artifact language stays English',
89
- 'the completed PR diff',
90
- "the threshold is the same number the epic's own measurement produced",
91
- 'through PR creation',
92
- 'until the user confirms E2E passed',
93
- 'while the PR is still OPEN',
94
- '→ `pnpm josh git -y` → the follow-up filing',
95
- '→ join → `pnpm josh git -y`,',
96
- '■ これからやること',
97
- 'この停止は残す',
98
- 'これが無いと、判断が返ったのに子が永久に止まる',
99
- 'これは advisory であり、アトミックではない',
100
- 'これは分割ではない',
101
- 'これは意図した差である',
102
- 'そのたびに人が口頭で起票先を指示していた',
103
- 'どちらを取るか迷う場合は、**根本対応(割り込み Issue)を既定とする**',
104
- 'コミット後かつ `pnpm josh followup` 実行前',
105
- 'マップが答えるのは「チェックアウトがどこにあるか」であって',
106
- 'ラウンドごとのコミットや CI 再実行も発生しない',
107
- 'ラベルはリポジトリごとに一度作る',
108
- 'レビュー自体はコミットの前のままで',
109
- '今こうなっている: <1文',
110
- '位置の判断は対象 EPIC が既に採ってきた基準に従う',
111
- '候補画像からの採用決定など',
112
- '入口ごとに条件が違う状態は欠陥である',
113
- '入口だけがこの記法から取り残されていた',
114
- '勝手に clone することは人の作業機の配置を勝手に決めることである',
115
- '子 1 件の `fullrun` は分単位。これより短くしても API 消費が増えるだけ',
116
- '子が 13 件なら stash も 13 個になる',
117
- '子を実装するリポジトリではない',
118
- '実行手順の正典は本節であり',
119
- '常駐判定の問いは',
120
- '成果物が存在した時点で入れる',
121
- '成果物の良し悪しは機械では測れない',
122
- '成果物は常に英語',
123
- '打ち忘れた回の Issue はどの EPIC にも属さない',
124
- '排他はリポジトリ単位であり、それを適用するのは `epic:next` である',
125
- '推薦は信号が弱ければ何もしないが',
126
- '新規 EPIC を作る前に、`#N` が既に EPIC の子でないかを確かめる',
127
- '日本語で 60 字程度',
128
- '昇格が他人の Issue を容れ物へ書き換える構造変更であり',
129
- '最後の行が最も重要である',
130
- '検討した 3 案のうち',
131
- '片方だけでは後から辿れない',
132
- '理由は綴りである',
133
- '省略可能な確認ではない',
134
- '矛盾を抱えた計画に対して一括決定を行っても、決定ごと作り直しになる',
135
- '確認という歯止めを外す以上、上限を付ける',
136
- '禁じられているのは裸の',
137
- '自分で外せる印は印として機能せず',
138
- '自動投稿される Issue コメント文面は英語で記載する',
139
- '読み取りにこそ付け忘れやすく、付け忘れは黙って通る',
140
- '閉じていない blocker を宣言している候補を除外する',
141
- ]
142
-
143
- export { RETIRED_PHRASES }
@@ -1,46 +0,0 @@
1
- import { read_unwrapped } from './ai-document-fixture'
2
-
3
- // The `/code-review` subagent's agent type is named once, in `chain-rule.md` step 1, so a run stops
4
- // guessing a name like `code-reviewer` and receiving `Agent type not found` (joshuafolkken/kit#2297).
5
- // This reads that name back and checks it is a real Claude Code agent type rather than a plausible
6
- // invention.
7
-
8
- const CHAIN_RULE = '.claude/skills/workflow-commands/chain-rule.md'
9
-
10
- // The built-in Claude Code agent types the `Agent` tool resolves. `general-purpose` is the one the
11
- // review uses — it carries every tool, so it can load the review skill and, with `--fix`, apply
12
- // findings. The set is the source of truth the document test measures the named type against; there is
13
- // no runtime registry to derive it from, so it is enumerated here.
14
- const KNOWN_AGENT_TYPES: ReadonlySet<string> = new Set([
15
- 'general-purpose',
16
- 'Explore',
17
- 'Plan',
18
- 'claude',
19
- 'claude-code-guide',
20
- 'statusline-setup',
21
- ])
22
-
23
- // The type named as `` `<name>` agent type ``, read from the unwrapped document so a reflow that moved
24
- // the words to a new line does not hide it.
25
- const AGENT_TYPE_PATTERN = /`([\w-]+)` agent type/u
26
-
27
- function named_agent_type(text: string = read_unwrapped(CHAIN_RULE)): string | undefined {
28
- return AGENT_TYPE_PATTERN.exec(text)?.[1]
29
- }
30
-
31
- // Whether the document names an agent type and that type is a real one. A missing name and an invented
32
- // name are both failures — the first leaves the run guessing, the second is the guess made canonical.
33
- function names_known_type(text: string = read_unwrapped(CHAIN_RULE)): boolean {
34
- const named = named_agent_type(text)
35
-
36
- return named !== undefined && KNOWN_AGENT_TYPES.has(named)
37
- }
38
-
39
- const review_agent_type = {
40
- CHAIN_RULE,
41
- KNOWN_AGENT_TYPES,
42
- named_agent_type,
43
- names_known_type,
44
- }
45
-
46
- export { review_agent_type }
@@ -1,73 +0,0 @@
1
- // The single-source check a document-rule test runs to keep one piece of prose in one place
2
- // (joshuafolkken/kit#2188). Epic #2166 trims the entry read by turning prose a reader interprets into
3
- // commands and reference-only pointers; that only holds if the body moved to its command's help does
4
- // not get pasted back into the prose. This is the framework a later child pins each such move with —
5
- // give it the body marker and the file allowed to carry it, and it names every other document that
6
- // still carries the body.
7
- //
8
- // **It is a pure function of the corpus, so the reader is injected.** Reading the repository is the
9
- // test's job (`ai-document-fixture.read_repo_file`); this module takes a `read` and answers from what
10
- // it returns, so the same logic verifies synthetic inputs in its own test and the real corpus in a
11
- // document-rule suite.
12
-
13
- const SINGLE = 1
14
-
15
- interface SingleSourceRule {
16
- // The prose fragment that must live in exactly one place.
17
- marker: string
18
- // The one document allowed to carry it; every reference elsewhere points here rather than copying.
19
- canonical: string
20
- }
21
-
22
- type ReadDocument = (document_path: string) => string
23
-
24
- // Prose is re-wrapped by the formatter, so a marker that spans a line break would miss on a reflow
25
- // that changed nothing. Collapsing whitespace on both sides pins the words rather than the column,
26
- // exactly as `read_unwrapped` does for the marker suites.
27
- function collapsed(text: string): string {
28
- return text.replaceAll(/\s+/gu, ' ')
29
- }
30
-
31
- function carries(text: string, marker: string): boolean {
32
- return collapsed(text).includes(collapsed(marker))
33
- }
34
-
35
- // Every document whose text carries the marker, canonical included — the primitive the two checks
36
- // below read from.
37
- function carriers(
38
- marker: string,
39
- documents: ReadonlyArray<string>,
40
- read: ReadDocument,
41
- ): Array<string> {
42
- return documents.filter((document_path) => carries(read(document_path), marker))
43
- }
44
-
45
- // The documents that carry the body but are not its canonical home — a non-empty result is the
46
- // violation a single-source suite asserts against.
47
- function violations(
48
- rule: SingleSourceRule,
49
- documents: ReadonlyArray<string>,
50
- read: ReadDocument,
51
- ): Array<string> {
52
- return carriers(rule.marker, documents, read).filter(
53
- (document_path) => document_path !== rule.canonical,
54
- )
55
- }
56
-
57
- // True only when the canonical carries the body and nothing else does. A body missing from its
58
- // canonical home is as wrong as one copied elsewhere — a pointer left with nothing to point at — so
59
- // both halves are checked here rather than only the copies.
60
- function is_single_sourced(
61
- rule: SingleSourceRule,
62
- documents: ReadonlyArray<string>,
63
- read: ReadDocument,
64
- ): boolean {
65
- const found = carriers(rule.marker, documents, read)
66
-
67
- return found.length === SINGLE && found[0] === rule.canonical
68
- }
69
-
70
- const single_source = { carriers, is_single_sourced, violations }
71
-
72
- export type { ReadDocument, SingleSourceRule }
73
- export { single_source }
@@ -1,88 +0,0 @@
1
- import { mkdtempSync } from 'node:fs'
2
- import { rm } from 'node:fs/promises'
3
- import { tmpdir } from 'node:os'
4
- import path from 'node:path'
5
- import { execa } from 'execa'
6
- import { git_location_environment } from './git-location-environment'
7
-
8
- // The scaffolding a test needs to drive **real git** in a throwaway repository
9
- // (joshuafolkken/kit#1533).
10
- //
11
- // Two suites need it — `lane-change-base.test.ts` builds a lane topology, `rename-changed-paths.test.ts`
12
- // builds a branch that renames a file away — and neither can use a mocked git, because what each one
13
- // asserts is a property of git itself rather than of an argument list this repository assembles.
14
- //
15
- // **It is one module rather than one copy per suite because this scaffolding has already had to be
16
- // hardened once.** joshuafolkken/kit#1530 found these fixtures committing into the repository the
17
- // suite was running in: under a git hook, `GIT_DIR` and `GIT_INDEX_FILE` beat `cwd` outright, and
18
- // `git config user.email` wrote the fixture's identity into a `--local` config that every linked work
19
- // tree shares. Both halves of that fix live below. A second copy would take the next such hardening
20
- // in one place and silently keep the old behavior in the other — the clone `CLAUDE.md` prohibits.
21
-
22
- // `restore_environment` is declared as "present, possibly undefined" rather than optional:
23
- // `exactOptionalPropertyTypes` is on, so an optional property cannot be *assigned* `undefined`, and
24
- // every suite here starts from a literal that has not opened a workspace yet.
25
- interface FixtureWorkspace {
26
- workspace: string
27
- previous_cwd: string
28
- restore_environment: (() => void) | undefined
29
- }
30
-
31
- const MAIN_BRANCH = '--initial-branch=main'
32
-
33
- // The name commits are authored under, exported because a suite asserts it: proving the identity
34
- // reached the commit is half of proving it was never written into a config file.
35
- const AUTHOR_NAME = 'Kit Fixture'
36
-
37
- // **The identity rides on `-c` rather than being written with `git config`** (joshuafolkken/kit#1530).
38
- // A `--local` write outlives the test and is shared by every work tree of the repository it lands in;
39
- // an option is scoped to the one command.
40
- const IDENTITY_OPTIONS: ReadonlyArray<string> = [
41
- '-c',
42
- 'user.email=fixture@example.test',
43
- '-c',
44
- `user.name=${AUTHOR_NAME}`,
45
- '-c',
46
- 'commit.gpgsign=false',
47
- ]
48
-
49
- // **The environment is cleared rather than inherited** (joshuafolkken/kit#1530). Run from a git hook,
50
- // this process holds `GIT_DIR` and `GIT_INDEX_FILE` pointing at the repository being pushed, and both
51
- // beat `cwd` — so every command here would act on that repository instead of on the fixture.
52
- async function git(cwd: string, arguments_: ReadonlyArray<string>): Promise<string> {
53
- const { stdout } = await execa('git', [...IDENTITY_OPTIONS, ...arguments_], {
54
- cwd,
55
- env: git_location_environment.location_free_environment(),
56
- extendEnv: true,
57
- })
58
-
59
- return stdout.trimEnd()
60
- }
61
-
62
- // Cleared for this process too, not only for the children `git` spawns: a suite's assertions drive
63
- // `git_command`, which spawns git with no environment of its own and so inherits this one.
64
- function open_workspace(prefix: string): FixtureWorkspace {
65
- return {
66
- restore_environment: git_location_environment.clear_git_location_variables(),
67
- previous_cwd: process.cwd(),
68
- workspace: mkdtempSync(path.join(tmpdir(), prefix)),
69
- }
70
- }
71
-
72
- async function close_workspace(fixture: FixtureWorkspace): Promise<void> {
73
- process.chdir(fixture.previous_cwd)
74
- fixture.restore_environment?.()
75
- await rm(fixture.workspace, { force: true, recursive: true })
76
- }
77
-
78
- const git_fixture_workspace = {
79
- AUTHOR_NAME,
80
- close_workspace,
81
- git,
82
- IDENTITY_OPTIONS,
83
- MAIN_BRANCH,
84
- open_workspace,
85
- }
86
-
87
- export type { FixtureWorkspace }
88
- export { git_fixture_workspace }
@@ -1,109 +0,0 @@
1
- import { mkdirSync, writeFileSync } from 'node:fs'
2
- import path from 'node:path'
3
- import { plan_commands, type CommandRunner, type FormatCommand } from './format-edited-file'
4
-
5
- // Shared across the two `format-edited-file` suites so neither redefines the other's fixtures. The
6
- // per-suite temp directory stays in each test file — vitest isolates the files, so each evaluates
7
- // this module and its own `afterAll` teardown of its own `mkdtemp`.
8
- const PRETTIER = 'prettier'
9
- const ESLINT = 'eslint'
10
-
11
- // What a formatter that ran and had nothing to say returns, so a test runner reads as "this route
12
- // worked" and no fallback is attempted.
13
- const RAN_CLEANLY = { exit_code: 0, stdout: '' }
14
-
15
- function payload_for(file_path: string): string {
16
- return JSON.stringify({
17
- hook_event_name: 'PostToolUse',
18
- tool_input: { file_path },
19
- tool_name: 'Edit',
20
- })
21
- }
22
-
23
- // What Claude Code hands this hook after a shell call, which the matcher covers since
24
- // joshuafolkken/kit#1337: a command, and no edited path anywhere in the payload. The command edits a
25
- // file on purpose — an agent working through `sed` is the mode the widening was measured against,
26
- // and nothing here may start formatting a path it had to guess at.
27
- function shell_payload(transcript_path?: string): string {
28
- return JSON.stringify({
29
- tool_name: 'Bash',
30
- tool_input: { command: `sed -i '' s/a/b/ app.ts` },
31
- transcript_path,
32
- })
33
- }
34
-
35
- function eslint_failing_runner(runs: Array<string>): CommandRunner {
36
- return async (command) => {
37
- await Promise.resolve()
38
-
39
- if (command.bin === ESLINT) throw new Error('spawn ENOENT')
40
-
41
- runs.push(command.bin)
42
-
43
- return RAN_CLEANLY
44
- }
45
- }
46
-
47
- const failing_runner: CommandRunner = async () => {
48
- await Promise.resolve()
49
- throw new Error('the formatter failed to start')
50
- }
51
-
52
- function recording_runner(runs: Array<string>): CommandRunner {
53
- return async (command) => {
54
- runs.push(command.bin)
55
-
56
- await Promise.resolve()
57
-
58
- return RAN_CLEANLY
59
- }
60
- }
61
-
62
- // eslint exits non-zero with its problems on stdout when a `--fix` pass leaves something it could
63
- // not fix; prettier runs cleanly. This is the shape the hook has to lift the diagnostics out of.
64
- function eslint_reporting_runner(stdout: string): CommandRunner {
65
- return async (command) => {
66
- await Promise.resolve()
67
-
68
- if (command.bin === ESLINT) return { exit_code: 1, stdout }
69
-
70
- return RAN_CLEANLY
71
- }
72
- }
73
-
74
- interface DirectoryHelpers {
75
- write_fixture: (...segments: ReadonlyArray<string>) => string
76
- plan_commands_in: (file_path: string) => ReadonlyArray<FormatCommand>
77
- }
78
-
79
- // Bound to a suite's own temp directory so the call sites stay `write_fixture('app.ts')`. The nested
80
- // functions close over `directory`, so they cannot be hoisted to module scope.
81
- function make_directory_helpers(directory: string): DirectoryHelpers {
82
- function write_fixture(...segments: ReadonlyArray<string>): string {
83
- const file_path = path.join(directory, ...segments)
84
-
85
- mkdirSync(path.dirname(file_path), { recursive: true })
86
- writeFileSync(file_path, '\n', 'utf8')
87
-
88
- return file_path
89
- }
90
-
91
- function plan_commands_in(file_path: string): ReadonlyArray<FormatCommand> {
92
- return plan_commands(file_path, directory)
93
- }
94
-
95
- return { write_fixture, plan_commands_in }
96
- }
97
-
98
- export {
99
- eslint_failing_runner,
100
- eslint_reporting_runner,
101
- failing_runner,
102
- make_directory_helpers,
103
- payload_for,
104
- recording_runner,
105
- shell_payload,
106
- ESLINT,
107
- PRETTIER,
108
- RAN_CLEANLY,
109
- }
@@ -1,38 +0,0 @@
1
- import { json_value } from '#scripts/lib/json-value'
2
- import { z } from 'zod'
3
-
4
- // The `UserPromptSubmit` hook commands declared in a `.claude/settings.json`
5
- // (joshuafolkken/kit#1151).
6
- //
7
- // What these commands echo is injected into **every** user turn and then re-read as accumulated
8
- // context on every turn after it, which is why joshuafolkken/kit#967 put a ceiling on their size and
9
- // why `josh cost` names them in the resident breakdown. Two readers, one parser: the suite that
10
- // enforces the ceiling and the report that prices it must agree on what is being measured, or the
11
- // ceiling guards a quantity the report does not show.
12
-
13
- const HOOK_SCHEMA = z.object({ command: z.string().nullish() })
14
- const MATCHER_SCHEMA = z.object({ hooks: z.array(HOOK_SCHEMA).nullish() })
15
- const SETTINGS_SCHEMA = z.object({
16
- hooks: z
17
- .object({
18
- UserPromptSubmit: z.array(MATCHER_SCHEMA).nullish(),
19
- })
20
- .nullish(),
21
- })
22
-
23
- // An unreadable or hook-less settings file yields no commands rather than throwing: a consumer
24
- // project may have neither, and `josh cost` must still print a breakdown there.
25
- function user_prompt_hook_commands(settings_text: string): Array<string> {
26
- const parsed = SETTINGS_SCHEMA.safeParse(json_value.parse_or_undefined(settings_text))
27
- const matchers = parsed.success ? (parsed.data.hooks?.UserPromptSubmit ?? []) : []
28
-
29
- return matchers.flatMap((matcher) =>
30
- (matcher.hooks ?? []).flatMap((hook) =>
31
- typeof hook.command === 'string' ? [hook.command] : [],
32
- ),
33
- )
34
- }
35
-
36
- const prompt_hooks = { user_prompt_hook_commands }
37
-
38
- export { prompt_hooks }
@@ -1,83 +0,0 @@
1
- import { spawnSync } from 'node:child_process'
2
- import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
3
- import { tmpdir } from 'node:os'
4
- import path from 'node:path'
5
- import { git_location_environment } from '#scripts/git/git-location-environment'
6
-
7
- interface HookResult {
8
- status: number | null
9
- stdout: string
10
- stderr: string
11
- }
12
-
13
- interface CheckoutOptions {
14
- git_overrides?: Record<string, string>
15
- is_external_git?: boolean
16
- }
17
-
18
- function create_partial_install(temporary_root: string): void {
19
- const package_root = path.join(temporary_root, 'node_modules/@joshuafolkken/kit')
20
- const hook_path = path.join(package_root, 'dist/hooks/pretool-guard.js')
21
-
22
- mkdirSync(path.dirname(hook_path), { recursive: true })
23
- writeFileSync(path.join(package_root, 'package.json'), '{}')
24
- writeFileSync(hook_path, "process.stdout.write('guard ran')")
25
- }
26
-
27
- function execution_directory(temporary_root: string, is_nested: boolean): string {
28
- if (!is_nested) return temporary_root
29
-
30
- const nested_root = path.join(temporary_root, 'src')
31
-
32
- mkdirSync(nested_root)
33
-
34
- return nested_root
35
- }
36
-
37
- function checkout_environment(temporary_root: string, options: CheckoutOptions): NodeJS.ProcessEnv {
38
- const metadata_root = path.join(temporary_root, 'metadata')
39
- const git_environment = {
40
- ...process.env,
41
- ...git_location_environment.location_free_environment(),
42
- }
43
- const git_arguments = options.is_external_git
44
- ? ['init', '--bare', '-q', metadata_root]
45
- : ['init', '-q']
46
-
47
- spawnSync('git', git_arguments, { cwd: temporary_root, env: git_environment })
48
-
49
- if (options.is_external_git) {
50
- return { ...git_environment, GIT_DIR: metadata_root, GIT_WORK_TREE: temporary_root }
51
- }
52
-
53
- return { ...git_environment, ...options.git_overrides }
54
- }
55
-
56
- function run_in_temporary_checkout(
57
- command: string,
58
- is_partial_install = false,
59
- is_nested = false,
60
- options: CheckoutOptions = {},
61
- ): HookResult {
62
- const temporary_root = mkdtempSync(path.join(tmpdir(), 'kit-hook-bootstrap-'))
63
-
64
- try {
65
- const hook_environment = checkout_environment(temporary_root, options)
66
-
67
- if (is_partial_install) create_partial_install(temporary_root)
68
-
69
- const { status, stdout, stderr } = spawnSync('sh', ['-c', command], {
70
- cwd: execution_directory(temporary_root, is_nested),
71
- encoding: 'utf8',
72
- env: hook_environment,
73
- })
74
-
75
- return { status, stdout, stderr }
76
- } finally {
77
- rmSync(temporary_root, { recursive: true, force: true })
78
- }
79
- }
80
-
81
- const hook_command_bootstrap = { run_in_temporary_checkout }
82
-
83
- export { hook_command_bootstrap }
@@ -1,50 +0,0 @@
1
- /**
2
- * CJK Unified Ideographs range + Hiragana + Katakana + CJK symbols.
3
- * Used to detect non-English issue titles that need translation.
4
- */
5
- const CJK_PATTERN = /[\u{3000}-\u{9FFF}\u{F900}-\u{FAFF}\u{AC00}-\u{D7AF}\u{20000}-\u{2FA1F}]/u
6
-
7
- const MAX_BRANCH_SLUG_LENGTH = 50
8
-
9
- function has_cjk(text: string): boolean {
10
- return CJK_PATTERN.test(text)
11
- }
12
-
13
- function slugify(text: string): string {
14
- const slug = text
15
- .toLowerCase()
16
- .normalize('NFKD')
17
- .replaceAll(/[^a-z0-9]+/gu, '-')
18
- .replaceAll(/-+/gu, '-')
19
- .replaceAll(/(^-)|(-$)/gu, '')
20
-
21
- if (slug.length === 0) return 'update'
22
-
23
- return slug.length > MAX_BRANCH_SLUG_LENGTH
24
- ? slug.slice(0, MAX_BRANCH_SLUG_LENGTH).replace(/-$/u, '')
25
- : slug
26
- }
27
-
28
- function suggest_branch_name(issue_number: number, title: string): string {
29
- return `${String(issue_number)}-${slugify(title)}`
30
- }
31
-
32
- interface IssuePrepResult {
33
- number: number
34
- title: string
35
- is_cjk: boolean
36
- suggested_branch: string
37
- }
38
-
39
- function prepare(issue_number: number, title: string): IssuePrepResult {
40
- return {
41
- number: issue_number,
42
- title,
43
- is_cjk: has_cjk(title),
44
- suggested_branch: suggest_branch_name(issue_number, title),
45
- }
46
- }
47
-
48
- const issue_logic = { has_cjk, slugify, suggest_branch_name, prepare }
49
-
50
- export { issue_logic }