@phuc1403/musketeer 0.9.0 → 0.11.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 (280) hide show
  1. package/INSTALLATION.md +53 -52
  2. package/README.md +1 -1
  3. package/bin/musketeer.js +168 -168
  4. package/manifest.json +19 -2
  5. package/package.json +48 -48
  6. package/src/dotnet-scaffold-copier.js +79 -79
  7. package/src/provisioner/detect.js +93 -93
  8. package/src/self-update.js +77 -77
  9. package/template/.claude/agents/git-manager.md +18 -18
  10. package/template/.claude/agents/hallmark-auditor.md +78 -78
  11. package/template/.claude/agents/researcher.md +33 -33
  12. package/template/.claude/hooks/block-unsafe-adr-title.cjs +85 -85
  13. package/template/.claude/hooks/init-adr-dir.cjs +173 -173
  14. package/template/.claude/hooks/inject-adr-flags.cjs +94 -94
  15. package/template/.claude/hooks/lib/adr/command-scan.cjs +115 -115
  16. package/template/.claude/hooks/lib/characteristics/checker.cjs +357 -357
  17. package/template/.claude/hooks/lib/git-info-cache.cjs +191 -191
  18. package/template/.claude/hooks/sync-adr-toc.cjs +146 -146
  19. package/template/.claude/hooks/usage-quota-cache-refresh.cjs +166 -166
  20. package/template/.claude/hooks/validate-characteristics-hook.cjs +66 -66
  21. package/template/.claude/hooks/validate-cml-hook.js +146 -145
  22. package/template/.claude/skills/adr-writer/SKILL.md +48 -48
  23. package/template/.claude/skills/adr-writer/references/adr-example.md +35 -35
  24. package/template/.claude/skills/architecture-characteristic-writer/SKILL.md +215 -215
  25. package/template/.claude/skills/architecture-characteristic-writer/assets/worksheet-template.md +29 -29
  26. package/template/.claude/skills/architecture-characteristic-writer/references/characteristics-catalog.md +40 -40
  27. package/template/.claude/skills/architecture-characteristic-writer/scripts/ranking-table.cjs +171 -171
  28. package/template/.claude/skills/context-map/SKILL.md +80 -80
  29. package/template/.claude/skills/context-map/example.cml +106 -106
  30. package/template/.claude/skills/context-map/reference/Bounded Context/Bounded Context.md +40 -40
  31. package/template/.claude/skills/context-map/reference/Bounded Context/businessModel.md +5 -5
  32. package/template/.claude/skills/context-map/reference/Bounded Context/domainVisionStatement.md +2 -2
  33. package/template/.claude/skills/context-map/reference/Bounded Context/evolution.md +5 -5
  34. package/template/.claude/skills/context-map/reference/Bounded Context/implementationTechnology.md +1 -1
  35. package/template/.claude/skills/context-map/reference/Bounded Context/implements.md +1 -1
  36. package/template/.claude/skills/context-map/reference/Bounded Context/knowledgeLevel.md +4 -4
  37. package/template/.claude/skills/context-map/reference/Bounded Context/realizes.md +9 -9
  38. package/template/.claude/skills/context-map/reference/Bounded Context/refines.md +10 -10
  39. package/template/.claude/skills/context-map/reference/Bounded Context/responsibilities.md +26 -26
  40. package/template/.claude/skills/context-map/reference/Bounded Context/type.md +23 -23
  41. package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Anticorruption Layer.md +5 -5
  42. package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Bounded Context Relationship.md +12 -12
  43. package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Conformist.md +5 -5
  44. package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Customer-Supplier (C-S).md +22 -22
  45. package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Open Host Service.md +4 -4
  46. package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Partnership (P).md +13 -13
  47. package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Published Language.md +4 -4
  48. package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Shared Kernel (SK).md +12 -12
  49. package/template/.claude/skills/context-map/reference/Context Map.md +62 -62
  50. package/template/.claude/skills/context-map/reference/Domain/Domain.md +30 -30
  51. package/template/.claude/skills/context-map/reference/Domain/supports.md +33 -33
  52. package/template/.claude/skills/context-map/reference/Domain/type.md +3 -3
  53. package/template/.claude/skills/context-map/reference/Semantic Rules.md +32 -32
  54. package/template/.claude/skills/hallmark/SKILL.md +552 -552
  55. package/template/.claude/skills/hallmark/references/anti-patterns.md +412 -412
  56. package/template/.claude/skills/hallmark/references/assets.md +406 -406
  57. package/template/.claude/skills/hallmark/references/color.md +95 -95
  58. package/template/.claude/skills/hallmark/references/component-cookbook.md +256 -256
  59. package/template/.claude/skills/hallmark/references/components/c1-outlined-chip.md +12 -12
  60. package/template/.claude/skills/hallmark/references/components/c2-inline-form-as-cta.md +16 -16
  61. package/template/.claude/skills/hallmark/references/components/c3-typographic-link.md +8 -8
  62. package/template/.claude/skills/hallmark/references/components/c4-sticky-bottom-bar.md +16 -16
  63. package/template/.claude/skills/hallmark/references/components/f1-bento-grid.md +20 -20
  64. package/template/.claude/skills/hallmark/references/components/f2-sticky-scroll-stack.md +20 -20
  65. package/template/.claude/skills/hallmark/references/components/f3-tabular-spec-sheet.md +11 -11
  66. package/template/.claude/skills/hallmark/references/components/f4-step-sequence.md +11 -11
  67. package/template/.claude/skills/hallmark/references/components/f5-annotated-screenshot.md +11 -11
  68. package/template/.claude/skills/hallmark/references/components/f6-product-card-grid.md +41 -41
  69. package/template/.claude/skills/hallmark/references/components/ft1-mast-headed.md +13 -13
  70. package/template/.claude/skills/hallmark/references/components/ft2-inline-rule-single-line.md +10 -10
  71. package/template/.claude/skills/hallmark/references/components/ft3-index-style-category-list.md +12 -12
  72. package/template/.claude/skills/hallmark/references/components/ft4-dense-typographic.md +10 -10
  73. package/template/.claude/skills/hallmark/references/components/ft5-statement.md +21 -21
  74. package/template/.claude/skills/hallmark/references/components/ft6-letter-close.md +19 -19
  75. package/template/.claude/skills/hallmark/references/components/ft7-newsletter-first.md +27 -27
  76. package/template/.claude/skills/hallmark/references/components/ft8-marquee-scroll.md +25 -25
  77. package/template/.claude/skills/hallmark/references/components/h1-marquee.md +15 -15
  78. package/template/.claude/skills/hallmark/references/components/h2-split-diptych.md +15 -15
  79. package/template/.claude/skills/hallmark/references/components/h3-quote-led.md +11 -11
  80. package/template/.claude/skills/hallmark/references/components/h4-stat-led.md +14 -14
  81. package/template/.claude/skills/hallmark/references/components/h5-letter-hero.md +11 -11
  82. package/template/.claude/skills/hallmark/references/components/h6-photographic-fold.md +16 -16
  83. package/template/.claude/skills/hallmark/references/components/h7-demo-video-clipped-by-viewport-edge.md +27 -27
  84. package/template/.claude/skills/hallmark/references/components/h8-mockup-split-browser-framed.md +23 -23
  85. package/template/.claude/skills/hallmark/references/components/h9-custom-illustration-centerpiece.md +27 -27
  86. package/template/.claude/skills/hallmark/references/components/n1-wordmark-2-links.md +12 -12
  87. package/template/.claude/skills/hallmark/references/components/n10-floating-on-scroll-morph.md +19 -19
  88. package/template/.claude/skills/hallmark/references/components/n2-floating-chip.md +14 -14
  89. package/template/.claude/skills/hallmark/references/components/n3-side-rail.md +14 -14
  90. package/template/.claude/skills/hallmark/references/components/n4-hidden-behind-k.md +9 -9
  91. package/template/.claude/skills/hallmark/references/components/n5-floating-pill.md +28 -28
  92. package/template/.claude/skills/hallmark/references/components/n6-newspaper-masthead.md +24 -24
  93. package/template/.claude/skills/hallmark/references/components/n7-brutal-slab.md +22 -22
  94. package/template/.claude/skills/hallmark/references/components/n8-terminal-command.md +21 -21
  95. package/template/.claude/skills/hallmark/references/components/n9-edge-aligned-minimal.md +17 -17
  96. package/template/.claude/skills/hallmark/references/components/s1-left-margin-numbered.md +15 -15
  97. package/template/.claude/skills/hallmark/references/components/s2-hanging.md +13 -13
  98. package/template/.claude/skills/hallmark/references/components/s3-sticky-pinned.md +19 -19
  99. package/template/.claude/skills/hallmark/references/components/s4-inline-no-break.md +11 -11
  100. package/template/.claude/skills/hallmark/references/components/s5-bottom-anchored.md +13 -13
  101. package/template/.claude/skills/hallmark/references/components/t1-pull-quote-with-marginalia.md +12 -12
  102. package/template/.claude/skills/hallmark/references/components/t2-logo-wall-hairline.md +19 -19
  103. package/template/.claude/skills/hallmark/references/components/t3-single-huge-quote.md +11 -11
  104. package/template/.claude/skills/hallmark/references/components/t4-numbered-stat-strip.md +14 -14
  105. package/template/.claude/skills/hallmark/references/contract.md +24 -24
  106. package/template/.claude/skills/hallmark/references/copy.md +182 -182
  107. package/template/.claude/skills/hallmark/references/custom-craft.md +626 -626
  108. package/template/.claude/skills/hallmark/references/custom-theme.md +329 -329
  109. package/template/.claude/skills/hallmark/references/design-md.md +116 -116
  110. package/template/.claude/skills/hallmark/references/export-formats.md +328 -328
  111. package/template/.claude/skills/hallmark/references/floating-nav.md +89 -89
  112. package/template/.claude/skills/hallmark/references/genres/atmospheric.md +65 -65
  113. package/template/.claude/skills/hallmark/references/genres/editorial.md +70 -70
  114. package/template/.claude/skills/hallmark/references/genres/modern-minimal.md +67 -67
  115. package/template/.claude/skills/hallmark/references/genres/playful.md +65 -65
  116. package/template/.claude/skills/hallmark/references/hero-enrichment.md +474 -474
  117. package/template/.claude/skills/hallmark/references/imagery-kit.md +170 -170
  118. package/template/.claude/skills/hallmark/references/interaction-and-states.md +207 -207
  119. package/template/.claude/skills/hallmark/references/layout-and-space.md +111 -111
  120. package/template/.claude/skills/hallmark/references/macrostructures/01-bento-grid.md +35 -35
  121. package/template/.claude/skills/hallmark/references/macrostructures/02-long-document.md +34 -34
  122. package/template/.claude/skills/hallmark/references/macrostructures/03-marquee-hero.md +31 -31
  123. package/template/.claude/skills/hallmark/references/macrostructures/04-stat-led.md +32 -32
  124. package/template/.claude/skills/hallmark/references/macrostructures/05-workbench.md +32 -32
  125. package/template/.claude/skills/hallmark/references/macrostructures/06-conversational-faq.md +33 -33
  126. package/template/.claude/skills/hallmark/references/macrostructures/07-manifesto.md +32 -32
  127. package/template/.claude/skills/hallmark/references/macrostructures/08-photographic.md +34 -34
  128. package/template/.claude/skills/hallmark/references/macrostructures/09-quote-led.md +32 -32
  129. package/template/.claude/skills/hallmark/references/macrostructures/10-specimen.md +32 -32
  130. package/template/.claude/skills/hallmark/references/macrostructures/11-catalogue.md +23 -23
  131. package/template/.claude/skills/hallmark/references/macrostructures/12-letter.md +23 -23
  132. package/template/.claude/skills/hallmark/references/macrostructures/13-index-first.md +23 -23
  133. package/template/.claude/skills/hallmark/references/macrostructures/14-narrative-workflow.md +23 -23
  134. package/template/.claude/skills/hallmark/references/macrostructures/15-split-studio.md +23 -23
  135. package/template/.claude/skills/hallmark/references/macrostructures/16-feature-stack.md +23 -23
  136. package/template/.claude/skills/hallmark/references/macrostructures/17-type-specimen.md +23 -23
  137. package/template/.claude/skills/hallmark/references/macrostructures/18-portfolio-grid.md +23 -23
  138. package/template/.claude/skills/hallmark/references/macrostructures/19-map-diagram.md +23 -23
  139. package/template/.claude/skills/hallmark/references/macrostructures/20-ecosystem-index.md +23 -23
  140. package/template/.claude/skills/hallmark/references/macrostructures/21-component-playground.md +23 -23
  141. package/template/.claude/skills/hallmark/references/macrostructures.md +89 -89
  142. package/template/.claude/skills/hallmark/references/microinteractions.md +260 -260
  143. package/template/.claude/skills/hallmark/references/motion.md +109 -109
  144. package/template/.claude/skills/hallmark/references/preview-examples.md +49 -49
  145. package/template/.claude/skills/hallmark/references/responsive.md +138 -138
  146. package/template/.claude/skills/hallmark/references/slop-test.md +205 -205
  147. package/template/.claude/skills/hallmark/references/structure.md +164 -164
  148. package/template/.claude/skills/hallmark/references/study.md +511 -511
  149. package/template/.claude/skills/hallmark/references/typography.md +243 -243
  150. package/template/.claude/skills/hallmark/references/verbs/audit.md +25 -25
  151. package/template/.claude/skills/hallmark/references/verbs/redesign.md +269 -269
  152. package/template/.claude/skills/hallmark-loop/SKILL.md +105 -105
  153. package/template/.claude/skills/hallmark-loop/references/auditor-call.md +60 -60
  154. package/template/.claude/skills/hallmark-loop/references/capture.md +78 -78
  155. package/template/.claude/skills/hallmark-loop/references/loop-control.md +79 -79
  156. package/template/.claude/skills/handoff/SKILL.md +15 -15
  157. package/template/.claude/skills/knowledge-crunching/SKILL.md +94 -94
  158. package/template/.claude/skills/logical-components/.gitattributes +2 -0
  159. package/template/.claude/skills/logical-components/SKILL.md +102 -0
  160. package/template/.claude/skills/logical-components/references/component-classifier-prompt.md +53 -0
  161. package/template/.claude/skills/logical-components/references/responsibility-agent-prompt.md +67 -0
  162. package/template/.claude/skills/logical-components/references/responsibility-verifier-prompt.md +39 -0
  163. package/template/.claude/skills/logical-components/scripts/Directory.Build.props +7 -0
  164. package/template/.claude/skills/logical-components/scripts/Directory.Packages.props +8 -0
  165. package/template/.claude/skills/logical-components/scripts/LogicalComponents/BatchPlanning.cs +69 -0
  166. package/template/.claude/skills/logical-components/scripts/LogicalComponents/BatchesCommand.cs +39 -0
  167. package/template/.claude/skills/logical-components/scripts/LogicalComponents/CandidatesCommand.cs +70 -0
  168. package/template/.claude/skills/logical-components/scripts/LogicalComponents/CitableSource.cs +39 -0
  169. package/template/.claude/skills/logical-components/scripts/LogicalComponents/Citation.cs +37 -0
  170. package/template/.claude/skills/logical-components/scripts/LogicalComponents/ClassifyBatchesCommand.cs +65 -0
  171. package/template/.claude/skills/logical-components/scripts/LogicalComponents/ClassifyMergeCommand.cs +187 -0
  172. package/template/.claude/skills/logical-components/scripts/LogicalComponents/ComponentDiscovery.cs +166 -0
  173. package/template/.claude/skills/logical-components/scripts/LogicalComponents/ComponentRule.cs +87 -0
  174. package/template/.claude/skills/logical-components/scripts/LogicalComponents/ComponentsFile.cs +83 -0
  175. package/template/.claude/skills/logical-components/scripts/LogicalComponents/CouplingResolver.cs +196 -0
  176. package/template/.claude/skills/logical-components/scripts/LogicalComponents/DisplayName.cs +14 -0
  177. package/template/.claude/skills/logical-components/scripts/LogicalComponents/EdgeExtraction.cs +111 -0
  178. package/template/.claude/skills/logical-components/scripts/LogicalComponents/ExtractCommand.cs +72 -0
  179. package/template/.claude/skills/logical-components/scripts/LogicalComponents/ExtractConfig.cs +79 -0
  180. package/template/.claude/skills/logical-components/scripts/LogicalComponents/LogicalComponents.csproj +15 -0
  181. package/template/.claude/skills/logical-components/scripts/LogicalComponents/MarkdownRenderer.cs +73 -0
  182. package/template/.claude/skills/logical-components/scripts/LogicalComponents/MemberUseResolution.cs +203 -0
  183. package/template/.claude/skills/logical-components/scripts/LogicalComponents/MemberUses.cs +155 -0
  184. package/template/.claude/skills/logical-components/scripts/LogicalComponents/PortResolution.cs +75 -0
  185. package/template/.claude/skills/logical-components/scripts/LogicalComponents/Program.cs +27 -0
  186. package/template/.claude/skills/logical-components/scripts/LogicalComponents/ProjectFilters.cs +76 -0
  187. package/template/.claude/skills/logical-components/scripts/LogicalComponents/PruneCommand.cs +132 -0
  188. package/template/.claude/skills/logical-components/scripts/LogicalComponents/RenderCommand.cs +173 -0
  189. package/template/.claude/skills/logical-components/scripts/LogicalComponents/ResponsibilityBatches.cs +84 -0
  190. package/template/.claude/skills/logical-components/scripts/LogicalComponents/ResponsibilityValidation.cs +178 -0
  191. package/template/.claude/skills/logical-components/scripts/LogicalComponents/SeamDispatch.cs +59 -0
  192. package/template/.claude/skills/logical-components/scripts/LogicalComponents/SymbolNames.cs +53 -0
  193. package/template/.claude/skills/logical-components/scripts/LogicalComponents/TypeMap.cs +75 -0
  194. package/template/.claude/skills/logical-components/scripts/LogicalComponents/WalkRoots.cs +63 -0
  195. package/template/.claude/skills/logical-components/scripts/LogicalComponents/WorkspaceLoader.cs +227 -0
  196. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/AssignIdsTests.cs +41 -0
  197. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/BatchPlanningTests.cs +82 -0
  198. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/CandidatesCommandTests.cs +34 -0
  199. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/CitationTests.cs +42 -0
  200. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/ClassifyCommandsTests.cs +176 -0
  201. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/ComponentDiscoveryTests.cs +190 -0
  202. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/CouplingExtractionTests.cs +174 -0
  203. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/DisplayNameTests.cs +17 -0
  204. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/ExtractConfigTests.cs +72 -0
  205. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/FixturePaths.cs +32 -0
  206. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/LogicalComponents.Tests.csproj +23 -0
  207. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/MarkdownRendererTests.cs +50 -0
  208. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/ProjectFiltersTests.cs +65 -0
  209. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/PruneCommandTests.cs +119 -0
  210. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/RenderCommandTests.cs +162 -0
  211. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/RenderGoldenTests.cs +34 -0
  212. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/RenderTestData.cs +49 -0
  213. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/ResponsibilityValidationTests.cs +227 -0
  214. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/SampleAppWorkspace.cs +27 -0
  215. package/template/.claude/skills/logical-components/scripts/LogicalComponents.Tests/WorkspaceLoaderTests.cs +87 -0
  216. package/template/.claude/skills/logical-components/scripts/fixtures/BrokenApp/src/Broken.Application/Broken.Application.csproj +7 -0
  217. package/template/.claude/skills/logical-components/scripts/fixtures/BrokenApp/src/Broken.Application/Broken.cs +7 -0
  218. package/template/.claude/skills/logical-components/scripts/fixtures/MultiTargetApp/MultiTargetApp.slnx +6 -0
  219. package/template/.claude/skills/logical-components/scripts/fixtures/MultiTargetApp/src/Legacy.FSharp/Legacy.FSharp.fsproj +8 -0
  220. package/template/.claude/skills/logical-components/scripts/fixtures/MultiTargetApp/src/Legacy.FSharp/Library.fs +5 -0
  221. package/template/.claude/skills/logical-components/scripts/fixtures/MultiTargetApp/src/Multi.Application/Multi.Application.csproj +7 -0
  222. package/template/.claude/skills/logical-components/scripts/fixtures/MultiTargetApp/src/Multi.Application/Scheduling.cs +14 -0
  223. package/template/.claude/skills/logical-components/scripts/fixtures/NoSolutionApp/src/Solo.Application/Solo.Application.csproj +7 -0
  224. package/template/.claude/skills/logical-components/scripts/fixtures/NoSolutionApp/src/Solo.Application/SoloGreeting.cs +7 -0
  225. package/template/.claude/skills/logical-components/scripts/fixtures/NoSolutionApp/src/Solo.Application.Tests/FakeGreeting.cs +6 -0
  226. package/template/.claude/skills/logical-components/scripts/fixtures/NoSolutionApp/src/Solo.Application.Tests/Solo.Application.Tests.csproj +11 -0
  227. package/template/.claude/skills/logical-components/scripts/fixtures/RenderGolden/components.json +63 -0
  228. package/template/.claude/skills/logical-components/scripts/fixtures/RenderGolden/expected.md +28 -0
  229. package/template/.claude/skills/logical-components/scripts/fixtures/RenderGolden/repo/src/App/OrderAcceptance.cs +16 -0
  230. package/template/.claude/skills/logical-components/scripts/fixtures/RenderGolden/repo/src/Infra/OrderQueue.cs +10 -0
  231. package/template/.claude/skills/logical-components/scripts/fixtures/RenderGolden/resp/batch-01.json +18 -0
  232. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/SampleApp.slnx +10 -0
  233. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/logical-components.json +78 -0
  234. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Application/CandidateCases.cs +37 -0
  235. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Application/CouplingCases.cs +33 -0
  236. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Application/DependencyInjection.cs +18 -0
  237. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Application/EdgeCases.cs +63 -0
  238. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Application/LoudNotifying.Base.cs +5 -0
  239. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Application/LoudNotifying.cs +7 -0
  240. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Application/OrderAcceptance.cs +17 -0
  241. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Application/OrderOptions.cs +9 -0
  242. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Application/OrderRejectedException.cs +7 -0
  243. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Application/OrderRequest.cs +4 -0
  244. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Application/OrderRunning.cs +18 -0
  245. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Application/OrderValidation.cs +6 -0
  246. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Application/Ports.cs +19 -0
  247. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Application/PriceRules.cs +7 -0
  248. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Application/ReceiptPrinting.Totals.cs +6 -0
  249. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Application/ReceiptPrinting.cs +7 -0
  250. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Application/ReviewCases.cs +107 -0
  251. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Application/ReviewFixCases.cs +143 -0
  252. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Application/RunClock.cs +12 -0
  253. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Application/Sample.Application.csproj +10 -0
  254. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Application/SeeThroughCases.cs +89 -0
  255. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Billing.Application/OrderRunning.cs +7 -0
  256. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Billing.Application/Sample.Billing.Application.csproj +11 -0
  257. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Infrastructure/ForwardedNotifier.cs +8 -0
  258. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Infrastructure/InfrastructureDependencyInjection.cs +16 -0
  259. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Infrastructure/Mailer.cs +6 -0
  260. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Infrastructure/OrderQueue.cs +11 -0
  261. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Infrastructure/QueueEntry.cs +4 -0
  262. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Infrastructure/QueueStore.cs +8 -0
  263. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Infrastructure/ReviewCases.cs +35 -0
  264. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Infrastructure/ReviewFixCases.cs +13 -0
  265. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Infrastructure/Sample.Infrastructure.csproj +13 -0
  266. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Infrastructure/SeeThroughCases.cs +18 -0
  267. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/src/Sample.Infrastructure/UnreachedPlumbing.cs +7 -0
  268. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/tests/Sample.Tests/FakeOrderQueue.cs +11 -0
  269. package/template/.claude/skills/logical-components/scripts/fixtures/SampleApp/tests/Sample.Tests/Sample.Tests.csproj +11 -0
  270. package/template/.claude/skills/logical-components/scripts/fixtures/SharedOutsideRepo/SharedClock.cs +7 -0
  271. package/template/.claude/skills/logical-components/scripts/global.json +5 -0
  272. package/template/.claude/skills/logical-components/scripts/smoke-sample.sh +26 -0
  273. package/template/.claude/skills/research/SKILL.md +69 -69
  274. package/template/.claude/skills/tdd/SKILL.md +142 -142
  275. package/template/.claude/skills/tdd/deep-modules.md +15 -15
  276. package/template/.claude/skills/tdd/interface-design.md +31 -31
  277. package/template/.claude/skills/tdd/mocking.md +59 -59
  278. package/template/.claude/skills/tdd/refactoring.md +10 -10
  279. package/template/.claude/skills/tdd/tests.md +61 -61
  280. package/template/.claude/statusline.cjs +100 -37
@@ -1,173 +1,173 @@
1
- #!/usr/bin/env node
2
- // PreToolUse guard: set up `.adr-dir` before the first `adr new` in a project,
3
- // so the agent never has to pick between `adr init` and a hand-written file.
4
- //
5
- // Two setup paths, and picking the wrong one is destructive:
6
- // - fresh (no `.adr-dir`, no numbered ADRs yet): `adr init docs/adr` is safe —
7
- // it creates docs/adr/, writes `.adr-dir`, and adds a baseline ADR.
8
- // - migration (numbered ADRs already exist, but no `.adr-dir`): `adr init`
9
- // would ALSO add that baseline ADR, burning the next real number. The fix
10
- // is a plain `.adr-dir` file with no tool call.
11
- // Already initialized: nothing to do, both paths are a no-op.
12
- //
13
- // Also makes sure this skill's ADR template is the one `adr new` picks up, by
14
- // placing it at `<adr-dir>/templates/template.md` — the third step of the tool's
15
- // own template resolution, and the reason no env var has to be injected.
16
- //
17
- // Runs the setup itself (as a side effect) before allowing `adr new` through,
18
- // and denies a *direct* `adr init` call whenever running it would be wrong —
19
- // already initialized, or migration state — since either would burn a number.
20
- // Anything it does is echoed to stdout so it stays visible in the transcript.
21
-
22
- const fs = require('fs');
23
- const path = require('path');
24
- const { spawnSync } = require('child_process');
25
- const { invokesAdr } = require('./lib/adr/command-scan.cjs');
26
-
27
- const root = process.env.CLAUDE_PROJECT_DIR || process.cwd();
28
- const ADR_DIR = 'docs/adr';
29
- const ADR_DIR_FILE = path.join(root, '.adr-dir');
30
- const ADR_FILE = /^\d+-.*\.md$/;
31
- const SKILL_TEMPLATE = path.join(
32
- root,
33
- '.claude',
34
- 'skills',
35
- 'adr-writer',
36
- 'references',
37
- 'adr-template.md'
38
- );
39
-
40
- function allow(message) {
41
- if (message) process.stdout.write(message + '\n');
42
- process.exit(0);
43
- }
44
-
45
- function deny(reason) {
46
- process.stdout.write(
47
- JSON.stringify({
48
- hookSpecificOutput: {
49
- hookEventName: 'PreToolUse',
50
- permissionDecision: 'deny',
51
- permissionDecisionReason: reason,
52
- },
53
- })
54
- );
55
- process.exit(0);
56
- }
57
-
58
- function readAdrDir() {
59
- try {
60
- return fs.readFileSync(ADR_DIR_FILE, 'utf8').trim() || null;
61
- } catch {
62
- return null;
63
- }
64
- }
65
-
66
- function isInitialized() {
67
- return readAdrDir() !== null;
68
- }
69
-
70
- function hasNumberedAdrs() {
71
- try {
72
- return fs.readdirSync(path.join(root, ADR_DIR)).some((f) => ADR_FILE.test(f));
73
- } catch {
74
- return false; // directory doesn't exist yet -> nothing to migrate
75
- }
76
- }
77
-
78
- function runAdrInit() {
79
- // `adr` is an npm bin — a real executable on every platform, so it is called
80
- // directly rather than through a shell script interpreter. `shell: true` is
81
- // here only because npm installs it as `adr.cmd` on Windows, which
82
- // CreateProcess cannot launch on its own; every argument is a constant, so
83
- // there is nothing for a shell to interpolate.
84
- return spawnSync('adr', ['init', ADR_DIR], { cwd: root, shell: true, encoding: 'utf8' });
85
- }
86
-
87
- // `adr init` writes `.adr-dir` with `path.relative`, so on Windows it lands as
88
- // `docs\adr` with no trailing newline. That file is committed and read on every
89
- // other machine, where a backslash is an ordinary filename character and not a
90
- // separator. Rewrite it in the portable form the rest of this toolchain emits.
91
- function normalizeAdrDirFile() {
92
- const declared = readAdrDir();
93
- if (!declared) return;
94
- fs.writeFileSync(ADR_DIR_FILE, `${declared.split(path.sep).join('/')}\n`);
95
- }
96
-
97
- // The tool resolves its template as: explicit argument, then $ADR_TEMPLATE, then
98
- // `<adr-dir>/templates/template.md`, then its own bundled default. Copying this
99
- // skill's template into the third slot means a bare `adr new` produces a
100
- // musketeer ADR with no environment set up for it.
101
- //
102
- // Only ever writes when the file is absent, so a project that has customised its
103
- // own template keeps it.
104
- function ensureTemplate() {
105
- try {
106
- const dir = readAdrDir() || ADR_DIR;
107
- const target = path.join(root, dir, 'templates', 'template.md');
108
- if (fs.existsSync(target) || !fs.existsSync(SKILL_TEMPLATE)) return null;
109
- fs.mkdirSync(path.dirname(target), { recursive: true });
110
- fs.copyFileSync(SKILL_TEMPLATE, target);
111
- return `Installed the adr-writer template at ${dir}/templates/template.md.`;
112
- } catch {
113
- return null; // never block an ADR over the template copy
114
- }
115
- }
116
-
117
- function main() {
118
- const payload = JSON.parse(fs.readFileSync(0, 'utf8'));
119
- const command = payload?.tool_input?.command || '';
120
- const isInit = invokesAdr(command, 'init');
121
- const isNew = invokesAdr(command, 'new');
122
- if (!isInit && !isNew) return allow();
123
-
124
- if (isInitialized()) {
125
- if (isInit) {
126
- return deny(
127
- '.adr-dir already exists — do not run `adr init` again, it would add a duplicate ' +
128
- 'baseline ADR and burn the next number. Run `adr new` directly.'
129
- );
130
- }
131
- return allow(ensureTemplate()); // adr new, already set up: nothing else to do
132
- }
133
-
134
- if (hasNumberedAdrs()) {
135
- // Migration: numbered ADRs exist but `.adr-dir` does not. `adr init` would
136
- // still add a baseline ADR here, so it is never the right command.
137
- if (isInit) {
138
- return deny(
139
- 'Numbered ADRs already exist without `.adr-dir` — this is a migration, not a fresh ' +
140
- 'project. `adr init` would add a duplicate baseline ADR and burn the next number. ' +
141
- 'Run `adr new` directly; `.adr-dir` is set up automatically.'
142
- );
143
- }
144
- fs.writeFileSync(ADR_DIR_FILE, `${ADR_DIR}\n`);
145
- const note = ensureTemplate();
146
- return allow(
147
- `Migration detected: wrote .adr-dir (${ADR_DIR}) by hand, no baseline ADR added.` +
148
- (note ? `\n${note}` : '')
149
- );
150
- }
151
-
152
- // Fresh project.
153
- if (isInit) return allow(); // the agent's own `adr init` call is correct here — let it run
154
- const res = runAdrInit();
155
- if (res.error || res.status !== 0) {
156
- return allow(
157
- `Could not run \`adr init ${ADR_DIR}\` (${res.error?.message || res.stderr}); ` +
158
- 'letting the original command run and fail with its own error.'
159
- );
160
- }
161
- normalizeAdrDirFile();
162
- const note = ensureTemplate();
163
- return allow(
164
- `Fresh project: ran \`adr init ${ADR_DIR}\` (creates the baseline ADR).` +
165
- (note ? `\n${note}` : '')
166
- );
167
- }
168
-
169
- try {
170
- main();
171
- } catch {
172
- allow(); // fail open
173
- }
1
+ #!/usr/bin/env node
2
+ // PreToolUse guard: set up `.adr-dir` before the first `adr new` in a project,
3
+ // so the agent never has to pick between `adr init` and a hand-written file.
4
+ //
5
+ // Two setup paths, and picking the wrong one is destructive:
6
+ // - fresh (no `.adr-dir`, no numbered ADRs yet): `adr init docs/adr` is safe —
7
+ // it creates docs/adr/, writes `.adr-dir`, and adds a baseline ADR.
8
+ // - migration (numbered ADRs already exist, but no `.adr-dir`): `adr init`
9
+ // would ALSO add that baseline ADR, burning the next real number. The fix
10
+ // is a plain `.adr-dir` file with no tool call.
11
+ // Already initialized: nothing to do, both paths are a no-op.
12
+ //
13
+ // Also makes sure this skill's ADR template is the one `adr new` picks up, by
14
+ // placing it at `<adr-dir>/templates/template.md` — the third step of the tool's
15
+ // own template resolution, and the reason no env var has to be injected.
16
+ //
17
+ // Runs the setup itself (as a side effect) before allowing `adr new` through,
18
+ // and denies a *direct* `adr init` call whenever running it would be wrong —
19
+ // already initialized, or migration state — since either would burn a number.
20
+ // Anything it does is echoed to stdout so it stays visible in the transcript.
21
+
22
+ const fs = require('fs');
23
+ const path = require('path');
24
+ const { spawnSync } = require('child_process');
25
+ const { invokesAdr } = require('./lib/adr/command-scan.cjs');
26
+
27
+ const root = process.env.CLAUDE_PROJECT_DIR || process.cwd();
28
+ const ADR_DIR = 'docs/adr';
29
+ const ADR_DIR_FILE = path.join(root, '.adr-dir');
30
+ const ADR_FILE = /^\d+-.*\.md$/;
31
+ const SKILL_TEMPLATE = path.join(
32
+ root,
33
+ '.claude',
34
+ 'skills',
35
+ 'adr-writer',
36
+ 'references',
37
+ 'adr-template.md'
38
+ );
39
+
40
+ function allow(message) {
41
+ if (message) process.stdout.write(message + '\n');
42
+ process.exit(0);
43
+ }
44
+
45
+ function deny(reason) {
46
+ process.stdout.write(
47
+ JSON.stringify({
48
+ hookSpecificOutput: {
49
+ hookEventName: 'PreToolUse',
50
+ permissionDecision: 'deny',
51
+ permissionDecisionReason: reason,
52
+ },
53
+ })
54
+ );
55
+ process.exit(0);
56
+ }
57
+
58
+ function readAdrDir() {
59
+ try {
60
+ return fs.readFileSync(ADR_DIR_FILE, 'utf8').trim() || null;
61
+ } catch {
62
+ return null;
63
+ }
64
+ }
65
+
66
+ function isInitialized() {
67
+ return readAdrDir() !== null;
68
+ }
69
+
70
+ function hasNumberedAdrs() {
71
+ try {
72
+ return fs.readdirSync(path.join(root, ADR_DIR)).some((f) => ADR_FILE.test(f));
73
+ } catch {
74
+ return false; // directory doesn't exist yet -> nothing to migrate
75
+ }
76
+ }
77
+
78
+ function runAdrInit() {
79
+ // `adr` is an npm bin — a real executable on every platform, so it is called
80
+ // directly rather than through a shell script interpreter. `shell: true` is
81
+ // here only because npm installs it as `adr.cmd` on Windows, which
82
+ // CreateProcess cannot launch on its own; every argument is a constant, so
83
+ // there is nothing for a shell to interpolate.
84
+ return spawnSync('adr', ['init', ADR_DIR], { cwd: root, shell: true, encoding: 'utf8' });
85
+ }
86
+
87
+ // `adr init` writes `.adr-dir` with `path.relative`, so on Windows it lands as
88
+ // `docs\adr` with no trailing newline. That file is committed and read on every
89
+ // other machine, where a backslash is an ordinary filename character and not a
90
+ // separator. Rewrite it in the portable form the rest of this toolchain emits.
91
+ function normalizeAdrDirFile() {
92
+ const declared = readAdrDir();
93
+ if (!declared) return;
94
+ fs.writeFileSync(ADR_DIR_FILE, `${declared.split(path.sep).join('/')}\n`);
95
+ }
96
+
97
+ // The tool resolves its template as: explicit argument, then $ADR_TEMPLATE, then
98
+ // `<adr-dir>/templates/template.md`, then its own bundled default. Copying this
99
+ // skill's template into the third slot means a bare `adr new` produces a
100
+ // musketeer ADR with no environment set up for it.
101
+ //
102
+ // Only ever writes when the file is absent, so a project that has customised its
103
+ // own template keeps it.
104
+ function ensureTemplate() {
105
+ try {
106
+ const dir = readAdrDir() || ADR_DIR;
107
+ const target = path.join(root, dir, 'templates', 'template.md');
108
+ if (fs.existsSync(target) || !fs.existsSync(SKILL_TEMPLATE)) return null;
109
+ fs.mkdirSync(path.dirname(target), { recursive: true });
110
+ fs.copyFileSync(SKILL_TEMPLATE, target);
111
+ return `Installed the adr-writer template at ${dir}/templates/template.md.`;
112
+ } catch {
113
+ return null; // never block an ADR over the template copy
114
+ }
115
+ }
116
+
117
+ function main() {
118
+ const payload = JSON.parse(fs.readFileSync(0, 'utf8'));
119
+ const command = payload?.tool_input?.command || '';
120
+ const isInit = invokesAdr(command, 'init');
121
+ const isNew = invokesAdr(command, 'new');
122
+ if (!isInit && !isNew) return allow();
123
+
124
+ if (isInitialized()) {
125
+ if (isInit) {
126
+ return deny(
127
+ '.adr-dir already exists — do not run `adr init` again, it would add a duplicate ' +
128
+ 'baseline ADR and burn the next number. Run `adr new` directly.'
129
+ );
130
+ }
131
+ return allow(ensureTemplate()); // adr new, already set up: nothing else to do
132
+ }
133
+
134
+ if (hasNumberedAdrs()) {
135
+ // Migration: numbered ADRs exist but `.adr-dir` does not. `adr init` would
136
+ // still add a baseline ADR here, so it is never the right command.
137
+ if (isInit) {
138
+ return deny(
139
+ 'Numbered ADRs already exist without `.adr-dir` — this is a migration, not a fresh ' +
140
+ 'project. `adr init` would add a duplicate baseline ADR and burn the next number. ' +
141
+ 'Run `adr new` directly; `.adr-dir` is set up automatically.'
142
+ );
143
+ }
144
+ fs.writeFileSync(ADR_DIR_FILE, `${ADR_DIR}\n`);
145
+ const note = ensureTemplate();
146
+ return allow(
147
+ `Migration detected: wrote .adr-dir (${ADR_DIR}) by hand, no baseline ADR added.` +
148
+ (note ? `\n${note}` : '')
149
+ );
150
+ }
151
+
152
+ // Fresh project.
153
+ if (isInit) return allow(); // the agent's own `adr init` call is correct here — let it run
154
+ const res = runAdrInit();
155
+ if (res.error || res.status !== 0) {
156
+ return allow(
157
+ `Could not run \`adr init ${ADR_DIR}\` (${res.error?.message || res.stderr}); ` +
158
+ 'letting the original command run and fail with its own error.'
159
+ );
160
+ }
161
+ normalizeAdrDirFile();
162
+ const note = ensureTemplate();
163
+ return allow(
164
+ `Fresh project: ran \`adr init ${ADR_DIR}\` (creates the baseline ADR).` +
165
+ (note ? `\n${note}` : '')
166
+ );
167
+ }
168
+
169
+ try {
170
+ main();
171
+ } catch {
172
+ allow(); // fail open
173
+ }
@@ -1,94 +1,94 @@
1
- #!/usr/bin/env node
2
- // PreToolUse guard: add the one flag every `adr new` call needs, so the agent
3
- // can write a bare `adr new -- "Title"` and still get a safe command.
4
- //
5
- // -q / --quiet — without it, an `-s` pattern matching more than one file
6
- // opens an interactive prompt on stdin and hangs the session. With it,
7
- // the ambiguous case throws instead, so the wrong ADR is never superseded
8
- // by a silent guess.
9
- //
10
- // Nothing else is injected. The template no longer needs an env var: `adr`
11
- // resolves `<adr-dir>/templates/template.md` on its own, and init-adr-dir.cjs
12
- // puts musketeer's template there. There is no editor to suppress either —
13
- // `adr` only opens one on an explicit `--open`.
14
- //
15
- // Uses PreToolUse's `updatedInput` (not just allow/deny) to rewrite the
16
- // command before it runs. A `-q` the agent already wrote is left alone, and
17
- // the call is a silent no-op.
18
- //
19
- // Safety: a title that happens to contain the literal text "adr new" could
20
- // make the matching regex fire inside a quoted string. Guarded by counting
21
- // quote characters before each match — an odd count means "inside an open
22
- // string", and that occurrence is left untouched rather than risk corrupting
23
- // the title.
24
-
25
- const fs = require('fs');
26
- const {
27
- invocationRe,
28
- isInsideQuotes,
29
- isInsideHeredoc,
30
- invokesAdr,
31
- } = require('./lib/adr/command-scan.cjs');
32
-
33
- const QUIET = /(?:^|\s)(?:-q|--quiet)(?=\s|$)/;
34
-
35
- // Everything between `adr new` and either the `--` option terminator or the end
36
- // of this command segment, whichever comes first.
37
- //
38
- // The title lives after `--` and may legitimately contain the text "-q"
39
- // ("Use -q for quiet builds"). Scanning it would make the hook believe the flag
40
- // was already supplied and skip an invocation that genuinely needs it, so the
41
- // title is never part of the region searched.
42
- function flagsRegion(command, from) {
43
- const rest = command.slice(from);
44
- let end = rest.length;
45
-
46
- const terminator = rest.search(/\s--(\s|$)/);
47
- if (terminator !== -1) end = terminator;
48
-
49
- for (let i = 0; i < end; i++) {
50
- if (';&|\n'.includes(rest[i]) && !isInsideQuotes(command, from + i)) {
51
- end = i;
52
- break;
53
- }
54
- }
55
- return rest.slice(0, end);
56
- }
57
-
58
- function main() {
59
- const payload = JSON.parse(fs.readFileSync(0, 'utf8'));
60
- const command = payload?.tool_input?.command || '';
61
- if (!invokesAdr(command, 'new')) return;
62
-
63
- let changed = false;
64
- const updated = command.replace(invocationRe('new'), (whole, boundary, ws, envPrefix, adrNew, offset) => {
65
- // Both guards, for the same reason the deny hooks use them: a heredoc body
66
- // is documentation being written, and injecting a flag into it would
67
- // rewrite the file's contents rather than the command.
68
- // `offset` is the boundary character; step past it to the word `adr`.
69
- const at = offset + boundary.length + ws.length + envPrefix.length;
70
- if (isInsideQuotes(command, at) || isInsideHeredoc(command, at)) return whole;
71
- if (QUIET.test(flagsRegion(command, at + adrNew.length))) return whole;
72
- changed = true;
73
- return `${boundary}${ws}${envPrefix}${adrNew} -q`;
74
- });
75
- if (!changed) return;
76
-
77
- process.stdout.write(
78
- JSON.stringify({
79
- systemMessage: 'Added -q to `adr new` — without it an ambiguous -s prompts on stdin and hangs.',
80
- hookSpecificOutput: {
81
- hookEventName: 'PreToolUse',
82
- permissionDecision: 'allow',
83
- updatedInput: { command: updated },
84
- },
85
- })
86
- );
87
- }
88
-
89
- try {
90
- main();
91
- } catch {
92
- /* fail open: leave the command untouched */
93
- }
94
- process.exit(0);
1
+ #!/usr/bin/env node
2
+ // PreToolUse guard: add the one flag every `adr new` call needs, so the agent
3
+ // can write a bare `adr new -- "Title"` and still get a safe command.
4
+ //
5
+ // -q / --quiet — without it, an `-s` pattern matching more than one file
6
+ // opens an interactive prompt on stdin and hangs the session. With it,
7
+ // the ambiguous case throws instead, so the wrong ADR is never superseded
8
+ // by a silent guess.
9
+ //
10
+ // Nothing else is injected. The template no longer needs an env var: `adr`
11
+ // resolves `<adr-dir>/templates/template.md` on its own, and init-adr-dir.cjs
12
+ // puts musketeer's template there. There is no editor to suppress either —
13
+ // `adr` only opens one on an explicit `--open`.
14
+ //
15
+ // Uses PreToolUse's `updatedInput` (not just allow/deny) to rewrite the
16
+ // command before it runs. A `-q` the agent already wrote is left alone, and
17
+ // the call is a silent no-op.
18
+ //
19
+ // Safety: a title that happens to contain the literal text "adr new" could
20
+ // make the matching regex fire inside a quoted string. Guarded by counting
21
+ // quote characters before each match — an odd count means "inside an open
22
+ // string", and that occurrence is left untouched rather than risk corrupting
23
+ // the title.
24
+
25
+ const fs = require('fs');
26
+ const {
27
+ invocationRe,
28
+ isInsideQuotes,
29
+ isInsideHeredoc,
30
+ invokesAdr,
31
+ } = require('./lib/adr/command-scan.cjs');
32
+
33
+ const QUIET = /(?:^|\s)(?:-q|--quiet)(?=\s|$)/;
34
+
35
+ // Everything between `adr new` and either the `--` option terminator or the end
36
+ // of this command segment, whichever comes first.
37
+ //
38
+ // The title lives after `--` and may legitimately contain the text "-q"
39
+ // ("Use -q for quiet builds"). Scanning it would make the hook believe the flag
40
+ // was already supplied and skip an invocation that genuinely needs it, so the
41
+ // title is never part of the region searched.
42
+ function flagsRegion(command, from) {
43
+ const rest = command.slice(from);
44
+ let end = rest.length;
45
+
46
+ const terminator = rest.search(/\s--(\s|$)/);
47
+ if (terminator !== -1) end = terminator;
48
+
49
+ for (let i = 0; i < end; i++) {
50
+ if (';&|\n'.includes(rest[i]) && !isInsideQuotes(command, from + i)) {
51
+ end = i;
52
+ break;
53
+ }
54
+ }
55
+ return rest.slice(0, end);
56
+ }
57
+
58
+ function main() {
59
+ const payload = JSON.parse(fs.readFileSync(0, 'utf8'));
60
+ const command = payload?.tool_input?.command || '';
61
+ if (!invokesAdr(command, 'new')) return;
62
+
63
+ let changed = false;
64
+ const updated = command.replace(invocationRe('new'), (whole, boundary, ws, envPrefix, adrNew, offset) => {
65
+ // Both guards, for the same reason the deny hooks use them: a heredoc body
66
+ // is documentation being written, and injecting a flag into it would
67
+ // rewrite the file's contents rather than the command.
68
+ // `offset` is the boundary character; step past it to the word `adr`.
69
+ const at = offset + boundary.length + ws.length + envPrefix.length;
70
+ if (isInsideQuotes(command, at) || isInsideHeredoc(command, at)) return whole;
71
+ if (QUIET.test(flagsRegion(command, at + adrNew.length))) return whole;
72
+ changed = true;
73
+ return `${boundary}${ws}${envPrefix}${adrNew} -q`;
74
+ });
75
+ if (!changed) return;
76
+
77
+ process.stdout.write(
78
+ JSON.stringify({
79
+ systemMessage: 'Added -q to `adr new` — without it an ambiguous -s prompts on stdin and hangs.',
80
+ hookSpecificOutput: {
81
+ hookEventName: 'PreToolUse',
82
+ permissionDecision: 'allow',
83
+ updatedInput: { command: updated },
84
+ },
85
+ })
86
+ );
87
+ }
88
+
89
+ try {
90
+ main();
91
+ } catch {
92
+ /* fail open: leave the command untouched */
93
+ }
94
+ process.exit(0);