@su-record/vibe 3.2.14 → 3.2.16

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 (351) hide show
  1. package/dist/cli/commands/index.d.ts +1 -1
  2. package/dist/cli/commands/index.d.ts.map +1 -1
  3. package/dist/cli/commands/index.js +1 -1
  4. package/dist/cli/commands/index.js.map +1 -1
  5. package/dist/cli/commands/info.d.ts +3 -1
  6. package/dist/cli/commands/info.d.ts.map +1 -1
  7. package/dist/cli/commands/info.js +12 -3
  8. package/dist/cli/commands/info.js.map +1 -1
  9. package/dist/cli/commands/init.d.ts +0 -7
  10. package/dist/cli/commands/init.d.ts.map +1 -1
  11. package/dist/cli/commands/init.js +5 -37
  12. package/dist/cli/commands/init.js.map +1 -1
  13. package/dist/cli/commands/update.d.ts.map +1 -1
  14. package/dist/cli/commands/update.js +4 -6
  15. package/dist/cli/commands/update.js.map +1 -1
  16. package/dist/cli/commands/upgrade.d.ts +1 -1
  17. package/dist/cli/commands/upgrade.d.ts.map +1 -1
  18. package/dist/cli/commands/upgrade.js +7 -2
  19. package/dist/cli/commands/upgrade.js.map +1 -1
  20. package/dist/cli/postinstall/claude-agents.js +1 -1
  21. package/dist/cli/postinstall/claude-agents.js.map +1 -1
  22. package/dist/cli/postinstall/constants.d.ts +0 -1
  23. package/dist/cli/postinstall/constants.d.ts.map +1 -1
  24. package/dist/cli/postinstall/constants.js +0 -8
  25. package/dist/cli/postinstall/constants.js.map +1 -1
  26. package/dist/cli/postinstall/main.d.ts.map +1 -1
  27. package/dist/cli/postinstall/main.js +20 -13
  28. package/dist/cli/postinstall/main.js.map +1 -1
  29. package/dist/cli/postinstall.d.ts +0 -3
  30. package/dist/cli/postinstall.d.ts.map +1 -1
  31. package/dist/cli/postinstall.js +0 -3
  32. package/dist/cli/postinstall.js.map +1 -1
  33. package/dist/cli/setup/InstallHome.d.ts +27 -0
  34. package/dist/cli/setup/InstallHome.d.ts.map +1 -0
  35. package/dist/cli/setup/InstallHome.js +105 -0
  36. package/dist/cli/setup/InstallHome.js.map +1 -0
  37. package/dist/cli/setup/ProjectSetup.d.ts +0 -8
  38. package/dist/cli/setup/ProjectSetup.d.ts.map +1 -1
  39. package/dist/cli/setup/ProjectSetup.js +0 -96
  40. package/dist/cli/setup/ProjectSetup.js.map +1 -1
  41. package/dist/cli/setup.d.ts +1 -1
  42. package/dist/cli/setup.d.ts.map +1 -1
  43. package/dist/cli/setup.js +1 -1
  44. package/dist/cli/setup.js.map +1 -1
  45. package/dist/infra/lib/codex-proxy.d.ts +126 -0
  46. package/dist/infra/lib/codex-proxy.d.ts.map +1 -1
  47. package/dist/infra/lib/codex-proxy.js +16 -16
  48. package/dist/infra/lib/codex-proxy.js.map +1 -1
  49. package/dist/infra/lib/figma/audit.d.ts.map +1 -1
  50. package/dist/infra/lib/figma/audit.js +0 -2
  51. package/dist/infra/lib/figma/audit.js.map +1 -1
  52. package/dist/infra/lib/figma/extract.d.ts +6 -1
  53. package/dist/infra/lib/figma/extract.d.ts.map +1 -1
  54. package/dist/infra/lib/figma/extract.js +17 -15
  55. package/dist/infra/lib/figma/extract.js.map +1 -1
  56. package/dist/infra/lib/figma/types.d.ts +103 -0
  57. package/dist/infra/lib/figma/types.d.ts.map +1 -1
  58. package/dist/infra/lib/figma/types.js +8 -0
  59. package/dist/infra/lib/figma/types.js.map +1 -1
  60. package/hooks/scripts/clone-extract.js +16 -1
  61. package/hooks/scripts/code-check.js +12 -5
  62. package/hooks/scripts/lib/dispatcher.js +43 -3
  63. package/hooks/scripts/utils.js +32 -2
  64. package/package.json +10 -8
  65. package/dist/__tests__/agent-model-sync.test.d.ts +0 -2
  66. package/dist/__tests__/agent-model-sync.test.d.ts.map +0 -1
  67. package/dist/__tests__/agent-model-sync.test.js +0 -71
  68. package/dist/__tests__/agent-model-sync.test.js.map +0 -1
  69. package/dist/__tests__/architecture.test.d.ts +0 -2
  70. package/dist/__tests__/architecture.test.d.ts.map +0 -1
  71. package/dist/__tests__/architecture.test.js +0 -207
  72. package/dist/__tests__/architecture.test.js.map +0 -1
  73. package/dist/__tests__/engines-contract.test.d.ts +0 -2
  74. package/dist/__tests__/engines-contract.test.d.ts.map +0 -1
  75. package/dist/__tests__/engines-contract.test.js +0 -72
  76. package/dist/__tests__/engines-contract.test.js.map +0 -1
  77. package/dist/__tests__/instruction-drift.test.d.ts +0 -2
  78. package/dist/__tests__/instruction-drift.test.d.ts.map +0 -1
  79. package/dist/__tests__/instruction-drift.test.js +0 -116
  80. package/dist/__tests__/instruction-drift.test.js.map +0 -1
  81. package/dist/__tests__/skill-namespace.test.d.ts +0 -2
  82. package/dist/__tests__/skill-namespace.test.d.ts.map +0 -1
  83. package/dist/__tests__/skill-namespace.test.js +0 -60
  84. package/dist/__tests__/skill-namespace.test.js.map +0 -1
  85. package/dist/__tests__/stakes-contract.test.d.ts +0 -2
  86. package/dist/__tests__/stakes-contract.test.d.ts.map +0 -1
  87. package/dist/__tests__/stakes-contract.test.js +0 -173
  88. package/dist/__tests__/stakes-contract.test.js.map +0 -1
  89. package/dist/__tests__/stuck-semantics.test.d.ts +0 -2
  90. package/dist/__tests__/stuck-semantics.test.d.ts.map +0 -1
  91. package/dist/__tests__/stuck-semantics.test.js +0 -161
  92. package/dist/__tests__/stuck-semantics.test.js.map +0 -1
  93. package/dist/__tests__/wiring-integrity.test.d.ts +0 -2
  94. package/dist/__tests__/wiring-integrity.test.d.ts.map +0 -1
  95. package/dist/__tests__/wiring-integrity.test.js +0 -160
  96. package/dist/__tests__/wiring-integrity.test.js.map +0 -1
  97. package/dist/cli/commands/info.test.d.ts +0 -2
  98. package/dist/cli/commands/info.test.d.ts.map +0 -1
  99. package/dist/cli/commands/info.test.js +0 -74
  100. package/dist/cli/commands/info.test.js.map +0 -1
  101. package/dist/cli/commands/upgrade.test.d.ts +0 -2
  102. package/dist/cli/commands/upgrade.test.d.ts.map +0 -1
  103. package/dist/cli/commands/upgrade.test.js +0 -99
  104. package/dist/cli/commands/upgrade.test.js.map +0 -1
  105. package/dist/cli/design/design-md-parser.test.d.ts +0 -2
  106. package/dist/cli/design/design-md-parser.test.d.ts.map +0 -1
  107. package/dist/cli/design/design-md-parser.test.js +0 -149
  108. package/dist/cli/design/design-md-parser.test.js.map +0 -1
  109. package/dist/cli/detect.characterization.test.d.ts +0 -7
  110. package/dist/cli/detect.characterization.test.d.ts.map +0 -1
  111. package/dist/cli/detect.characterization.test.js +0 -294
  112. package/dist/cli/detect.characterization.test.js.map +0 -1
  113. package/dist/cli/postinstall/cursor-agents.d.ts +0 -13
  114. package/dist/cli/postinstall/cursor-agents.d.ts.map +0 -1
  115. package/dist/cli/postinstall/cursor-agents.js +0 -89
  116. package/dist/cli/postinstall/cursor-agents.js.map +0 -1
  117. package/dist/cli/postinstall/cursor-rules.d.ts +0 -11
  118. package/dist/cli/postinstall/cursor-rules.d.ts.map +0 -1
  119. package/dist/cli/postinstall/cursor-rules.js +0 -205
  120. package/dist/cli/postinstall/cursor-rules.js.map +0 -1
  121. package/dist/cli/postinstall/cursor-skills.d.ts +0 -9
  122. package/dist/cli/postinstall/cursor-skills.d.ts.map +0 -1
  123. package/dist/cli/postinstall/cursor-skills.js +0 -796
  124. package/dist/cli/postinstall/cursor-skills.js.map +0 -1
  125. package/dist/cli/postinstall/fs-utils.test.d.ts +0 -2
  126. package/dist/cli/postinstall/fs-utils.test.d.ts.map +0 -1
  127. package/dist/cli/postinstall/fs-utils.test.js +0 -259
  128. package/dist/cli/postinstall/fs-utils.test.js.map +0 -1
  129. package/dist/cli/setup/CodexHooks.test.d.ts +0 -2
  130. package/dist/cli/setup/CodexHooks.test.d.ts.map +0 -1
  131. package/dist/cli/setup/CodexHooks.test.js +0 -52
  132. package/dist/cli/setup/CodexHooks.test.js.map +0 -1
  133. package/dist/cli/setup/GlobalInstaller.test.d.ts +0 -2
  134. package/dist/cli/setup/GlobalInstaller.test.d.ts.map +0 -1
  135. package/dist/cli/setup/GlobalInstaller.test.js +0 -16
  136. package/dist/cli/setup/GlobalInstaller.test.js.map +0 -1
  137. package/dist/cli/utils/cli-detector.test.d.ts +0 -2
  138. package/dist/cli/utils/cli-detector.test.d.ts.map +0 -1
  139. package/dist/cli/utils/cli-detector.test.js +0 -52
  140. package/dist/cli/utils/cli-detector.test.js.map +0 -1
  141. package/dist/infra/lib/SkillFrontmatter.test.d.ts +0 -2
  142. package/dist/infra/lib/SkillFrontmatter.test.d.ts.map +0 -1
  143. package/dist/infra/lib/SkillFrontmatter.test.js +0 -60
  144. package/dist/infra/lib/SkillFrontmatter.test.js.map +0 -1
  145. package/dist/infra/lib/__tests__/AutomationLevel.test.d.ts +0 -2
  146. package/dist/infra/lib/__tests__/AutomationLevel.test.d.ts.map +0 -1
  147. package/dist/infra/lib/__tests__/AutomationLevel.test.js +0 -297
  148. package/dist/infra/lib/__tests__/AutomationLevel.test.js.map +0 -1
  149. package/dist/infra/lib/__tests__/ComponentRegistry.test.d.ts +0 -2
  150. package/dist/infra/lib/__tests__/ComponentRegistry.test.d.ts.map +0 -1
  151. package/dist/infra/lib/__tests__/ComponentRegistry.test.js +0 -99
  152. package/dist/infra/lib/__tests__/ComponentRegistry.test.js.map +0 -1
  153. package/dist/infra/lib/__tests__/DecisionTracer.test.d.ts +0 -2
  154. package/dist/infra/lib/__tests__/DecisionTracer.test.d.ts.map +0 -1
  155. package/dist/infra/lib/__tests__/DecisionTracer.test.js +0 -274
  156. package/dist/infra/lib/__tests__/DecisionTracer.test.js.map +0 -1
  157. package/dist/infra/lib/__tests__/InteractiveCheckpoint.test.d.ts +0 -2
  158. package/dist/infra/lib/__tests__/InteractiveCheckpoint.test.d.ts.map +0 -1
  159. package/dist/infra/lib/__tests__/InteractiveCheckpoint.test.js +0 -350
  160. package/dist/infra/lib/__tests__/InteractiveCheckpoint.test.js.map +0 -1
  161. package/dist/infra/lib/__tests__/LoopBreaker.test.d.ts +0 -2
  162. package/dist/infra/lib/__tests__/LoopBreaker.test.d.ts.map +0 -1
  163. package/dist/infra/lib/__tests__/LoopBreaker.test.js +0 -340
  164. package/dist/infra/lib/__tests__/LoopBreaker.test.js.map +0 -1
  165. package/dist/infra/lib/__tests__/VerificationLoop.test.d.ts +0 -2
  166. package/dist/infra/lib/__tests__/VerificationLoop.test.d.ts.map +0 -1
  167. package/dist/infra/lib/__tests__/VerificationLoop.test.js +0 -486
  168. package/dist/infra/lib/__tests__/VerificationLoop.test.js.map +0 -1
  169. package/dist/infra/lib/config/GlobalConfigManager.test.d.ts +0 -2
  170. package/dist/infra/lib/config/GlobalConfigManager.test.d.ts.map +0 -1
  171. package/dist/infra/lib/config/GlobalConfigManager.test.js +0 -9
  172. package/dist/infra/lib/config/GlobalConfigManager.test.js.map +0 -1
  173. package/dist/infra/lib/embedding/__tests__/EmbeddingProvider.test.d.ts +0 -2
  174. package/dist/infra/lib/embedding/__tests__/EmbeddingProvider.test.d.ts.map +0 -1
  175. package/dist/infra/lib/embedding/__tests__/EmbeddingProvider.test.js +0 -43
  176. package/dist/infra/lib/embedding/__tests__/EmbeddingProvider.test.js.map +0 -1
  177. package/dist/infra/lib/embedding/__tests__/VectorStore.test.d.ts +0 -2
  178. package/dist/infra/lib/embedding/__tests__/VectorStore.test.d.ts.map +0 -1
  179. package/dist/infra/lib/embedding/__tests__/VectorStore.test.js +0 -94
  180. package/dist/infra/lib/embedding/__tests__/VectorStore.test.js.map +0 -1
  181. package/dist/infra/lib/embedding/__tests__/cosine.test.d.ts +0 -2
  182. package/dist/infra/lib/embedding/__tests__/cosine.test.d.ts.map +0 -1
  183. package/dist/infra/lib/embedding/__tests__/cosine.test.js +0 -73
  184. package/dist/infra/lib/embedding/__tests__/cosine.test.js.map +0 -1
  185. package/dist/infra/lib/evolution/__tests__/deprecation.test.d.ts +0 -2
  186. package/dist/infra/lib/evolution/__tests__/deprecation.test.d.ts.map +0 -1
  187. package/dist/infra/lib/evolution/__tests__/deprecation.test.js +0 -251
  188. package/dist/infra/lib/evolution/__tests__/deprecation.test.js.map +0 -1
  189. package/dist/infra/lib/evolution/__tests__/eval.test.d.ts +0 -2
  190. package/dist/infra/lib/evolution/__tests__/eval.test.d.ts.map +0 -1
  191. package/dist/infra/lib/evolution/__tests__/eval.test.js +0 -603
  192. package/dist/infra/lib/evolution/__tests__/eval.test.js.map +0 -1
  193. package/dist/infra/lib/evolution/__tests__/generation.test.d.ts +0 -2
  194. package/dist/infra/lib/evolution/__tests__/generation.test.d.ts.map +0 -1
  195. package/dist/infra/lib/evolution/__tests__/generation.test.js +0 -396
  196. package/dist/infra/lib/evolution/__tests__/generation.test.js.map +0 -1
  197. package/dist/infra/lib/evolution/__tests__/insight.test.d.ts +0 -2
  198. package/dist/infra/lib/evolution/__tests__/insight.test.d.ts.map +0 -1
  199. package/dist/infra/lib/evolution/__tests__/insight.test.js +0 -204
  200. package/dist/infra/lib/evolution/__tests__/insight.test.js.map +0 -1
  201. package/dist/infra/lib/evolution/__tests__/integration.test.d.ts +0 -2
  202. package/dist/infra/lib/evolution/__tests__/integration.test.d.ts.map +0 -1
  203. package/dist/infra/lib/evolution/__tests__/integration.test.js +0 -206
  204. package/dist/infra/lib/evolution/__tests__/integration.test.js.map +0 -1
  205. package/dist/infra/lib/evolution/__tests__/lifecycle.test.d.ts +0 -2
  206. package/dist/infra/lib/evolution/__tests__/lifecycle.test.d.ts.map +0 -1
  207. package/dist/infra/lib/evolution/__tests__/lifecycle.test.js +0 -350
  208. package/dist/infra/lib/evolution/__tests__/lifecycle.test.js.map +0 -1
  209. package/dist/infra/lib/evolution/__tests__/parity.test.d.ts +0 -2
  210. package/dist/infra/lib/evolution/__tests__/parity.test.d.ts.map +0 -1
  211. package/dist/infra/lib/evolution/__tests__/parity.test.js +0 -319
  212. package/dist/infra/lib/evolution/__tests__/parity.test.js.map +0 -1
  213. package/dist/infra/lib/llm/auth/AuthProfileManager.test.d.ts +0 -5
  214. package/dist/infra/lib/llm/auth/AuthProfileManager.test.d.ts.map +0 -1
  215. package/dist/infra/lib/llm/auth/AuthProfileManager.test.js +0 -168
  216. package/dist/infra/lib/llm/auth/AuthProfileManager.test.js.map +0 -1
  217. package/dist/infra/lib/llm/auth/TokenRefresher.test.d.ts +0 -2
  218. package/dist/infra/lib/llm/auth/TokenRefresher.test.d.ts.map +0 -1
  219. package/dist/infra/lib/llm/auth/TokenRefresher.test.js +0 -120
  220. package/dist/infra/lib/llm/auth/TokenRefresher.test.js.map +0 -1
  221. package/dist/infra/lib/llm/timeout.test.d.ts +0 -2
  222. package/dist/infra/lib/llm/timeout.test.d.ts.map +0 -1
  223. package/dist/infra/lib/llm/timeout.test.js +0 -50
  224. package/dist/infra/lib/llm/timeout.test.js.map +0 -1
  225. package/dist/infra/lib/llm-availability.test.d.ts +0 -2
  226. package/dist/infra/lib/llm-availability.test.d.ts.map +0 -1
  227. package/dist/infra/lib/llm-availability.test.js +0 -37
  228. package/dist/infra/lib/llm-availability.test.js.map +0 -1
  229. package/dist/infra/lib/memory/KnowledgeGraph.test.d.ts +0 -2
  230. package/dist/infra/lib/memory/KnowledgeGraph.test.d.ts.map +0 -1
  231. package/dist/infra/lib/memory/KnowledgeGraph.test.js +0 -189
  232. package/dist/infra/lib/memory/KnowledgeGraph.test.js.map +0 -1
  233. package/dist/infra/lib/memory/MemorySearch.test.d.ts +0 -2
  234. package/dist/infra/lib/memory/MemorySearch.test.d.ts.map +0 -1
  235. package/dist/infra/lib/memory/MemorySearch.test.js +0 -149
  236. package/dist/infra/lib/memory/MemorySearch.test.js.map +0 -1
  237. package/dist/infra/lib/memory/MemoryStorage.test.d.ts +0 -2
  238. package/dist/infra/lib/memory/MemoryStorage.test.d.ts.map +0 -1
  239. package/dist/infra/lib/memory/MemoryStorage.test.js +0 -198
  240. package/dist/infra/lib/memory/MemoryStorage.test.js.map +0 -1
  241. package/dist/infra/lib/memory/SessionRAGRetriever.test.d.ts +0 -2
  242. package/dist/infra/lib/memory/SessionRAGRetriever.test.d.ts.map +0 -1
  243. package/dist/infra/lib/memory/SessionRAGRetriever.test.js +0 -180
  244. package/dist/infra/lib/memory/SessionRAGRetriever.test.js.map +0 -1
  245. package/dist/infra/lib/memory/SessionRAGStore.test.d.ts +0 -2
  246. package/dist/infra/lib/memory/SessionRAGStore.test.d.ts.map +0 -1
  247. package/dist/infra/lib/memory/SessionRAGStore.test.js +0 -326
  248. package/dist/infra/lib/memory/SessionRAGStore.test.js.map +0 -1
  249. package/dist/infra/lib/memory/__tests__/InMemoryStorage.test.d.ts +0 -2
  250. package/dist/infra/lib/memory/__tests__/InMemoryStorage.test.d.ts.map +0 -1
  251. package/dist/infra/lib/memory/__tests__/InMemoryStorage.test.js +0 -114
  252. package/dist/infra/lib/memory/__tests__/InMemoryStorage.test.js.map +0 -1
  253. package/dist/infra/lib/memory/__tests__/ReflectionStore.test.d.ts +0 -2
  254. package/dist/infra/lib/memory/__tests__/ReflectionStore.test.d.ts.map +0 -1
  255. package/dist/infra/lib/memory/__tests__/ReflectionStore.test.js +0 -196
  256. package/dist/infra/lib/memory/__tests__/ReflectionStore.test.js.map +0 -1
  257. package/dist/infra/lib/memory/index.test.d.ts +0 -2
  258. package/dist/infra/lib/memory/index.test.d.ts.map +0 -1
  259. package/dist/infra/lib/memory/index.test.js +0 -23
  260. package/dist/infra/lib/memory/index.test.js.map +0 -1
  261. package/dist/infra/lib/telemetry/SkillTelemetry.test.d.ts +0 -2
  262. package/dist/infra/lib/telemetry/SkillTelemetry.test.d.ts.map +0 -1
  263. package/dist/infra/lib/telemetry/SkillTelemetry.test.js +0 -124
  264. package/dist/infra/lib/telemetry/SkillTelemetry.test.js.map +0 -1
  265. package/dist/infra/lib/ui-ux/Bm25Engine.test.d.ts +0 -2
  266. package/dist/infra/lib/ui-ux/Bm25Engine.test.d.ts.map +0 -1
  267. package/dist/infra/lib/ui-ux/Bm25Engine.test.js +0 -159
  268. package/dist/infra/lib/ui-ux/Bm25Engine.test.js.map +0 -1
  269. package/dist/infra/lib/ui-ux/CsvDataLoader.test.d.ts +0 -2
  270. package/dist/infra/lib/ui-ux/CsvDataLoader.test.d.ts.map +0 -1
  271. package/dist/infra/lib/ui-ux/CsvDataLoader.test.js +0 -141
  272. package/dist/infra/lib/ui-ux/CsvDataLoader.test.js.map +0 -1
  273. package/dist/infra/lib/ui-ux/DesignSystemGenerator.test.d.ts +0 -2
  274. package/dist/infra/lib/ui-ux/DesignSystemGenerator.test.d.ts.map +0 -1
  275. package/dist/infra/lib/ui-ux/DesignSystemGenerator.test.js +0 -370
  276. package/dist/infra/lib/ui-ux/DesignSystemGenerator.test.js.map +0 -1
  277. package/dist/infra/lib/ui-ux/SearchService.test.d.ts +0 -2
  278. package/dist/infra/lib/ui-ux/SearchService.test.d.ts.map +0 -1
  279. package/dist/infra/lib/ui-ux/SearchService.test.js +0 -215
  280. package/dist/infra/lib/ui-ux/SearchService.test.js.map +0 -1
  281. package/dist/test-helpers/index.d.ts +0 -36
  282. package/dist/test-helpers/index.d.ts.map +0 -1
  283. package/dist/test-helpers/index.js +0 -85
  284. package/dist/test-helpers/index.js.map +0 -1
  285. package/dist/test-helpers/index.test.d.ts +0 -2
  286. package/dist/test-helpers/index.test.d.ts.map +0 -1
  287. package/dist/test-helpers/index.test.js +0 -92
  288. package/dist/test-helpers/index.test.js.map +0 -1
  289. package/dist/tests/curated-release-notes.test.d.ts +0 -2
  290. package/dist/tests/curated-release-notes.test.d.ts.map +0 -1
  291. package/dist/tests/curated-release-notes.test.js +0 -160
  292. package/dist/tests/curated-release-notes.test.js.map +0 -1
  293. package/dist/tools/convention/analyzeComplexity.test.d.ts +0 -2
  294. package/dist/tools/convention/analyzeComplexity.test.d.ts.map +0 -1
  295. package/dist/tools/convention/analyzeComplexity.test.js +0 -207
  296. package/dist/tools/convention/analyzeComplexity.test.js.map +0 -1
  297. package/dist/tools/convention/validateCodeQuality.test.d.ts +0 -2
  298. package/dist/tools/convention/validateCodeQuality.test.d.ts.map +0 -1
  299. package/dist/tools/convention/validateCodeQuality.test.js +0 -230
  300. package/dist/tools/convention/validateCodeQuality.test.js.map +0 -1
  301. package/dist/tools/loop/validateLoopDefinition.test.d.ts +0 -14
  302. package/dist/tools/loop/validateLoopDefinition.test.d.ts.map +0 -1
  303. package/dist/tools/loop/validateLoopDefinition.test.js +0 -229
  304. package/dist/tools/loop/validateLoopDefinition.test.js.map +0 -1
  305. package/dist/tools/spec/executionPacket.test.d.ts +0 -2
  306. package/dist/tools/spec/executionPacket.test.d.ts.map +0 -1
  307. package/dist/tools/spec/executionPacket.test.js +0 -374
  308. package/dist/tools/spec/executionPacket.test.js.map +0 -1
  309. package/dist/tools/spec/prdParser.test.d.ts +0 -6
  310. package/dist/tools/spec/prdParser.test.d.ts.map +0 -1
  311. package/dist/tools/spec/prdParser.test.js +0 -332
  312. package/dist/tools/spec/prdParser.test.js.map +0 -1
  313. package/dist/tools/spec/specGenerator.test.d.ts +0 -2
  314. package/dist/tools/spec/specGenerator.test.d.ts.map +0 -1
  315. package/dist/tools/spec/specGenerator.test.js +0 -130
  316. package/dist/tools/spec/specGenerator.test.js.map +0 -1
  317. package/dist/tools/spec/traceabilityMatrix.path-resolution.test.d.ts +0 -10
  318. package/dist/tools/spec/traceabilityMatrix.path-resolution.test.d.ts.map +0 -1
  319. package/dist/tools/spec/traceabilityMatrix.path-resolution.test.js +0 -120
  320. package/dist/tools/spec/traceabilityMatrix.path-resolution.test.js.map +0 -1
  321. package/dist/tools/spec/traceabilityMatrix.test.d.ts +0 -6
  322. package/dist/tools/spec/traceabilityMatrix.test.d.ts.map +0 -1
  323. package/dist/tools/spec/traceabilityMatrix.test.js +0 -359
  324. package/dist/tools/spec/traceabilityMatrix.test.js.map +0 -1
  325. package/hooks/scripts/__tests__/.vibe/command-log.txt +0 -3
  326. package/hooks/scripts/__tests__/anchor-inbox.test.js +0 -119
  327. package/hooks/scripts/__tests__/auto-test-debounce.test.js +0 -145
  328. package/hooks/scripts/__tests__/clone-behaviors.test.js +0 -152
  329. package/hooks/scripts/__tests__/clone-merge-responsive.test.js +0 -106
  330. package/hooks/scripts/__tests__/code-check-detectors.test.js +0 -213
  331. package/hooks/scripts/__tests__/code-check-false-positive.test.js +0 -74
  332. package/hooks/scripts/__tests__/code-check-memory-write.test.js +0 -81
  333. package/hooks/scripts/__tests__/codex-hook-adapter.test.js +0 -64
  334. package/hooks/scripts/__tests__/curation-index.test.js +0 -157
  335. package/hooks/scripts/__tests__/dispatcher-inprocess.test.js +0 -99
  336. package/hooks/scripts/__tests__/figma-extract.test.js +0 -338
  337. package/hooks/scripts/__tests__/fixtures/seq-harness.js +0 -13
  338. package/hooks/scripts/__tests__/fixtures/seq-step.js +0 -22
  339. package/hooks/scripts/__tests__/hook-payload.test.js +0 -29
  340. package/hooks/scripts/__tests__/llm-orchestrate-antigravity.test.js +0 -66
  341. package/hooks/scripts/__tests__/loop-ledger.test.js +0 -321
  342. package/hooks/scripts/__tests__/post-edit-dispatcher.test.js +0 -139
  343. package/hooks/scripts/__tests__/pre-tool-guard.test.js +0 -523
  344. package/hooks/scripts/__tests__/recipe-extractor.test.js +0 -244
  345. package/hooks/scripts/__tests__/run-ledger-verify-required.test.js +0 -151
  346. package/hooks/scripts/__tests__/run-ledger.test.js +0 -481
  347. package/hooks/scripts/__tests__/scope-from-spec.test.js +0 -215
  348. package/hooks/scripts/__tests__/sentinel-guard.test.js +0 -263
  349. package/hooks/scripts/__tests__/step-counter.test.js +0 -459
  350. package/hooks/scripts/__tests__/stop-dispatcher-sequential.test.js +0 -74
  351. package/hooks/scripts/__tests__/utils-npm-root.test.js +0 -99
@@ -1,145 +0,0 @@
1
- /**
2
- * auto-test.js debounce 테스트
3
- *
4
- * 검증 대상:
5
- * - debounce 모드에서 쿨다운 내 + 소스 미변경 → 스킵
6
- * - 쿨다운 만료 → 재실행
7
- * - 소스 변경 → 재실행
8
- * - mode='off' → 실행 안 함
9
- * - mode='always' → debounce 없이 항상 실행 시도
10
- */
11
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
12
- import { fileURLToPath } from 'url';
13
- import path from 'path';
14
- import fs from 'fs';
15
- import os from 'os';
16
- import { createHash } from 'crypto';
17
-
18
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
19
-
20
- let tmpDir;
21
- beforeEach(() => {
22
- tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'vibe-autotest-debounce-'));
23
- });
24
- afterEach(() => {
25
- try { fs.rmSync(tmpDir, { recursive: true, force: true }); } catch { /* ignore */ }
26
- });
27
-
28
- // debounce 로직 단위 테스트 (auto-test.js와 동일 알고리즘)
29
- const DEBOUNCE_COOLDOWN_MS = 120_000;
30
-
31
- function fileHash(filePath) {
32
- try {
33
- const content = fs.readFileSync(filePath, 'utf-8');
34
- return createHash('sha256').update(content).digest('hex').slice(0, 16);
35
- } catch {
36
- return '';
37
- }
38
- }
39
-
40
- function makeDebounceHelpers(stateFile) {
41
- function readState() {
42
- try {
43
- if (fs.existsSync(stateFile)) return JSON.parse(fs.readFileSync(stateFile, 'utf-8'));
44
- } catch { /* ignore */ }
45
- return {};
46
- }
47
-
48
- function writeState(state) {
49
- try {
50
- fs.mkdirSync(path.dirname(stateFile), { recursive: true });
51
- fs.writeFileSync(stateFile, JSON.stringify(state, null, 2), 'utf-8');
52
- } catch { /* ignore */ }
53
- }
54
-
55
- function shouldSkip(testFile, srcFile) {
56
- try {
57
- const state = readState();
58
- const entry = state[testFile];
59
- if (!entry) return false;
60
- const elapsed = Date.now() - entry.lastRun;
61
- if (elapsed > DEBOUNCE_COOLDOWN_MS) return false;
62
- const currentHash = fileHash(srcFile);
63
- if (currentHash !== entry.srcHash) return false;
64
- return true;
65
- } catch {
66
- return false;
67
- }
68
- }
69
-
70
- function updateState(testFile, srcFile) {
71
- const state = readState();
72
- state[testFile] = { lastRun: Date.now(), srcHash: fileHash(srcFile) };
73
- writeState(state);
74
- }
75
-
76
- return { shouldSkip, updateState, readState };
77
- }
78
-
79
- describe('auto-test debounce: 핵심 로직', () => {
80
- it('첫 실행: state 없음 → 스킵 안 함', () => {
81
- const stateFile = path.join(tmpDir, 'auto-test-state.json');
82
- const { shouldSkip } = makeDebounceHelpers(stateFile);
83
- const testFile = path.join(tmpDir, 'foo.test.ts');
84
- const srcFile = path.join(tmpDir, 'foo.ts');
85
- fs.writeFileSync(srcFile, 'const x = 1;\n', 'utf-8');
86
- expect(shouldSkip(testFile, srcFile)).toBe(false);
87
- });
88
-
89
- it('state 업데이트 후 쿨다운 내 + 소스 미변경 → 스킵', () => {
90
- const stateFile = path.join(tmpDir, 'auto-test-state.json');
91
- const { shouldSkip, updateState } = makeDebounceHelpers(stateFile);
92
- const testFile = path.join(tmpDir, 'foo.test.ts');
93
- const srcFile = path.join(tmpDir, 'foo.ts');
94
- fs.writeFileSync(srcFile, 'const x = 1;\n', 'utf-8');
95
- updateState(testFile, srcFile);
96
- // 소스 변경 없음 + 즉시 재호출 → 스킵
97
- expect(shouldSkip(testFile, srcFile)).toBe(true);
98
- });
99
-
100
- it('소스 변경 후 → 스킵 안 함 (재실행)', () => {
101
- const stateFile = path.join(tmpDir, 'auto-test-state.json');
102
- const { shouldSkip, updateState } = makeDebounceHelpers(stateFile);
103
- const testFile = path.join(tmpDir, 'foo.test.ts');
104
- const srcFile = path.join(tmpDir, 'foo.ts');
105
- fs.writeFileSync(srcFile, 'const x = 1;\n', 'utf-8');
106
- updateState(testFile, srcFile);
107
- // 소스 변경
108
- fs.writeFileSync(srcFile, 'const x = 2;\n', 'utf-8');
109
- expect(shouldSkip(testFile, srcFile)).toBe(false);
110
- });
111
-
112
- it('쿨다운 만료 → 스킵 안 함 (재실행)', () => {
113
- const stateFile = path.join(tmpDir, 'auto-test-state.json');
114
- const { shouldSkip, updateState, readState } = makeDebounceHelpers(stateFile);
115
- const testFile = path.join(tmpDir, 'foo.test.ts');
116
- const srcFile = path.join(tmpDir, 'foo.ts');
117
- fs.writeFileSync(srcFile, 'const x = 1;\n', 'utf-8');
118
- updateState(testFile, srcFile);
119
-
120
- // lastRun을 과거로 조작 (쿨다운 초과)
121
- const state = readState();
122
- state[testFile].lastRun = Date.now() - DEBOUNCE_COOLDOWN_MS - 1000;
123
- fs.mkdirSync(path.dirname(stateFile), { recursive: true });
124
- fs.writeFileSync(stateFile, JSON.stringify(state), 'utf-8');
125
-
126
- expect(shouldSkip(testFile, srcFile)).toBe(false);
127
- });
128
-
129
- it('state 파일 없어도 fail-open (스킵 안 함)', () => {
130
- const stateFile = path.join(tmpDir, 'nonexistent', 'state.json');
131
- const { shouldSkip } = makeDebounceHelpers(stateFile);
132
- const testFile = path.join(tmpDir, 'foo.test.ts');
133
- const srcFile = path.join(tmpDir, 'foo.ts');
134
- expect(shouldSkip(testFile, srcFile)).toBe(false);
135
- });
136
- });
137
-
138
- describe('auto-test: state 파일 경로 패턴', () => {
139
- it('state 파일이 .vibe/metrics/ 하위에 위치', () => {
140
- // 경로 패턴 검증 (실제 PROJECT_DIR은 다름)
141
- const expectedPattern = /\.vibe[/\\]metrics[/\\]auto-test-state\.json$/;
142
- const stateFile = path.join('/some/project', '.vibe', 'metrics', 'auto-test-state.json');
143
- expect(expectedPattern.test(stateFile)).toBe(true);
144
- });
145
- });
@@ -1,152 +0,0 @@
1
- /**
2
- * clone active-interaction-sweep helpers
3
- * - diffStyles: before/after computed-style differ (clone-extract.js)
4
- * - sectionHasNode / behaviorsBlock: behavior→section attachment (clone-spec.js)
5
- */
6
-
7
- import { describe, it, expect } from 'vitest';
8
- import { collectSubUrls, diffStyles } from '../clone-extract.js';
9
- import { sectionHasNode, behaviorsBlock } from '../clone-spec.js';
10
-
11
- describe('diffStyles', () => {
12
- it('reports only changed props with from/to', () => {
13
- const a = { 'background-color': 'rgba(0, 0, 0, 0)', height: '80px' };
14
- const b = { 'background-color': 'rgb(255, 255, 255)', height: '80px' };
15
- expect(diffStyles(a, b)).toEqual({
16
- 'background-color': { from: 'rgba(0, 0, 0, 0)', to: 'rgb(255, 255, 255)' },
17
- });
18
- });
19
-
20
- it('captures props that appear or disappear', () => {
21
- const d = diffStyles({}, { 'box-shadow': '0 4px 20px rgba(0,0,0,0.1)' });
22
- expect(d['box-shadow']).toEqual({ from: null, to: '0 4px 20px rgba(0,0,0,0.1)' });
23
- });
24
-
25
- it('returns empty when nothing changed or a snapshot is missing', () => {
26
- expect(diffStyles({ color: 'red' }, { color: 'red' })).toEqual({});
27
- expect(diffStyles(null, { color: 'red' })).toEqual({});
28
- });
29
- });
30
-
31
- describe('collectSubUrls', () => {
32
- it('keeps same-origin locale menu links and drops footer/external links', () => {
33
- const urls = collectSubUrls('https://www.lgdisplay.com/kor', [
34
- { href: '/kor/company/info/outline/greeting', text: '기업개요' },
35
- { href: '/kor/product/tv/oled', text: 'TV' },
36
- { href: '/eng', text: 'ENG' },
37
- { href: '/kor/privacy', text: '개인정보처리방침' },
38
- { href: 'https://news.lgdisplay.com/news', text: 'Newsroom' },
39
- { href: 'https://www.youtube.com/@lgdisplay', text: 'You Tube' },
40
- { href: '#top', text: 'TOP' },
41
- ]);
42
-
43
- expect(urls).toEqual([
44
- 'https://www.lgdisplay.com/kor',
45
- 'https://www.lgdisplay.com/kor/company/info/outline/greeting',
46
- 'https://www.lgdisplay.com/kor/product/tv/oled',
47
- ]);
48
- });
49
-
50
- it('deduplicates links after dropping query strings and hashes', () => {
51
- const urls = collectSubUrls('https://example.com/kor', [
52
- { href: '/kor/company?utm_source=x', text: 'Company' },
53
- { href: '/kor/company#ceo', text: 'Company' },
54
- ]);
55
-
56
- expect(urls).toEqual([
57
- 'https://example.com/kor',
58
- 'https://example.com/kor/company',
59
- ]);
60
- });
61
- });
62
-
63
- describe('behavior → section attachment', () => {
64
- const section = {
65
- name: 'Header',
66
- children: [{ tag: 'header', classes: 'site-nav top', children: [{ tag: 'button', classes: 'tab', children: [] }] }],
67
- };
68
-
69
- it('matches a node by tag and class', () => {
70
- expect(sectionHasNode(section, 'header', 'site-nav')).toBe(true);
71
- expect(sectionHasNode(section, 'header', 'missing')).toBe(false);
72
- expect(sectionHasNode(section, 'button')).toBe(true);
73
- });
74
-
75
- it('attaches a scroll behavior to the matching section only', () => {
76
- const behaviors = {
77
- scroll: [{ label: 'header.site-nav', tag: 'header', cls: 'site-nav', triggerScrollY: 700, changed: { height: { from: '80px', to: '56px' } } }],
78
- interactive: [{ kind: 'tab-group', count: 3, tabLabels: ['A', 'B', 'C'], contentSwapsOnClick: true }],
79
- };
80
- const block = behaviorsBlock(section, behaviors);
81
- expect(block).toContain('Scroll-triggered');
82
- expect(block).toContain('height');
83
- expect(block).toContain('content SWAPS on click');
84
-
85
- const footer = { name: 'Footer', children: [{ tag: 'p', classes: '', children: [] }] };
86
- expect(behaviorsBlock(footer, behaviors)).toBeNull();
87
- });
88
-
89
- it('renders hover / in-view / time-driven / scroll-lib behavior kinds', () => {
90
- const behaviors = {
91
- scroll: [],
92
- interactive: [],
93
- hover: [{ label: 'a.cta', tag: 'a', cls: 'cta', transition: 'all 0.3s ease 0s', changed: { 'background-color': { from: 'rgb(0, 0, 0)', to: 'rgb(255, 0, 0)' } } }],
94
- inview: [{ label: 'div.fade', tag: 'div', cls: 'fade', triggerY: 1400, changed: { opacity: { from: '0', to: '1' } } }],
95
- timeDriven: [{ label: 'div.slide', tag: 'div', cls: 'slide', mutations: 12, kinds: ['class'] }],
96
- scrollLib: { name: 'lenis', evidence: 'html.lenis' },
97
- };
98
- const hero = {
99
- name: 'Hero',
100
- children: [{ tag: 'div', classes: 'fade slide', children: [{ tag: 'a', classes: 'cta', children: [] }] }],
101
- };
102
- const block = behaviorsBlock(hero, behaviors);
103
- expect(block).toContain('**Hover** on `a.cta`');
104
- expect(block).toContain('transition: `all 0.3s ease 0s`');
105
- expect(block).toContain('**In-view entrance** on `div.fade` (enters at ~1400px)');
106
- expect(block).toContain('opacity: `0` → `1`');
107
- expect(block).toContain('**Time-driven** `div.slide` — 12 mutations/3s');
108
- expect(block).toContain('lenis');
109
- });
110
-
111
- it('renders a page-level scroll-lib note even when no section-scoped behavior matches', () => {
112
- const onlyLib = { scroll: [], interactive: [], scrollLib: { name: 'lenis', evidence: 'window.Lenis' } };
113
- const footer = { name: 'Footer', children: [{ tag: 'p', classes: '', children: [] }] };
114
- expect(behaviorsBlock(footer, onlyLib)).toContain('lenis');
115
- });
116
-
117
- it('suppresses the default transition value on hover entries', () => {
118
- const behaviors = {
119
- hover: [{ label: 'button.x', tag: 'button', cls: 'x', transition: 'all 0s ease 0s', changed: { color: { from: 'rgb(0, 0, 0)', to: 'rgb(9, 9, 9)' } } }],
120
- };
121
- const sec = { name: 'S', children: [{ tag: 'button', classes: 'x', children: [] }] };
122
- expect(behaviorsBlock(sec, behaviors)).not.toContain('transition:');
123
- });
124
- });
125
-
126
- describe('clone-spec CLI --real-content', () => {
127
- const runCli = async (extraArgs) => {
128
- const [fs, os, path, url, cp] = await Promise.all([
129
- import('fs'), import('os'), import('path'), import('url'), import('child_process'),
130
- ]);
131
- const tmp = fs.default.mkdtempSync(path.default.join(os.default.tmpdir(), 'clone-spec-'));
132
- const sections = path.default.join(tmp, 'sections.json');
133
- fs.default.writeFileSync(sections, JSON.stringify({
134
- meta: { feature: 'f', bp: 'mo', url: 'https://x.test' },
135
- sections: [{ name: 'Hero', nodeRef: '0', tag: 'section', css: {}, children: [] }],
136
- }));
137
- const script = url.default.fileURLToPath(new URL('../clone-spec.js', import.meta.url));
138
- cp.default.execFileSync('node', [script, sections, `--out=${tmp}/specs`, ...extraArgs]);
139
- return fs.default.readFileSync(path.default.join(tmp, 'specs', 'Hero.spec.md'), 'utf8');
140
- };
141
-
142
- it('defaults to placeholder replacement wording', async () => {
143
- const spec = await runCli([]);
144
- expect(spec).toContain('(replace copyrighted copy with placeholders)');
145
- });
146
-
147
- it('switches to verbatim wording with --real-content', async () => {
148
- const spec = await runCli(['--real-content']);
149
- expect(spec).toContain('(verbatim — user confirmed rights to reuse this copy)');
150
- expect(spec).not.toContain('(replace copyrighted copy with placeholders)');
151
- });
152
- });
@@ -1,106 +0,0 @@
1
- /**
2
- * clone-merge-responsive — MO/PC SCSS → mobile-first 병합
3
- * - mergeRules/emitMerged: 순수 병합 코어
4
- * - CLI: fixture 디렉토리 → sections/tokens/index/class-plan 병합 산출
5
- */
6
-
7
- import { describe, it, expect } from 'vitest';
8
- import fs from 'fs';
9
- import os from 'os';
10
- import path from 'path';
11
- import { fileURLToPath } from 'url';
12
- import { execFileSync } from 'child_process';
13
- import { mergeRules, emitMerged } from '../clone-merge-responsive.js';
14
- import { parseScss } from '../clone-validate.js';
15
-
16
- const SCRIPT = fileURLToPath(new URL('../clone-merge-responsive.js', import.meta.url));
17
-
18
- const MO = `.f__hero { display: flex; flex-direction: column; padding-top: 24px; }
19
- .f__hero__title { font-size: 28px; color: rgb(0, 0, 0); }`;
20
-
21
- const PC = `.f__hero { display: flex; flex-direction: row; padding-top: 64px; }
22
- .f__hero__title { font-size: 48px; color: rgb(0, 0, 0); }
23
- .f__hero__side { width: 320px; }`;
24
-
25
- describe('mergeRules', () => {
26
- const { base, media, stats } = mergeRules(parseScss(MO), parseScss(PC));
27
-
28
- it('keeps MO declarations as the mobile-first base', () => {
29
- expect(base.get('.f__hero')).toEqual({
30
- display: 'flex', 'flex-direction': 'column', 'padding-top': '24px',
31
- });
32
- });
33
-
34
- it('puts only differing PC declarations into the media bucket', () => {
35
- expect(media.get('.f__hero')).toEqual({ 'flex-direction': 'row', 'padding-top': '64px' });
36
- // color는 양쪽 동일 → media에서 제외
37
- expect(media.get('.f__hero__title')).toEqual({ 'font-size': '48px' });
38
- });
39
-
40
- it('moves PC-only selectors wholly into the media bucket', () => {
41
- expect(base.has('.f__hero__side')).toBe(false);
42
- expect(media.get('.f__hero__side')).toEqual({ width: '320px' });
43
- expect(stats.pcOnly).toBe(1);
44
- });
45
- });
46
-
47
- describe('emitMerged', () => {
48
- it('emits base + a single min-width block without duplicating shared declarations', () => {
49
- const { scss } = emitMerged(parseScss(MO), parseScss(PC), 1024, '// merged');
50
- expect(scss).toContain('@media (min-width: 1024px)');
51
- expect(scss.match(/@media/g)).toHaveLength(1);
52
- // 양 BP 동일 선언은 base에 1번만 등장
53
- expect(scss.match(/display: flex;/g)).toHaveLength(1);
54
- expect(scss.match(/color: rgb\(0, 0, 0\);/g)).toHaveLength(1);
55
- });
56
-
57
- it('omits the media block when PC has no differences', () => {
58
- const { scss } = emitMerged(parseScss(MO), parseScss(MO), 1024, '// same');
59
- expect(scss).not.toContain('@media');
60
- });
61
- });
62
-
63
- describe('CLI file-level merge', () => {
64
- const write = (dir, rel, content) => {
65
- const f = path.join(dir, rel);
66
- fs.mkdirSync(path.dirname(f), { recursive: true });
67
- fs.writeFileSync(f, content);
68
- };
69
-
70
- it('merges section dirs and writes index/tokens/class-plan', () => {
71
- const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'clone-merge-'));
72
- const mo = path.join(tmp, 'mo');
73
- const pc = path.join(tmp, 'pc');
74
- const out = path.join(tmp, 'merged');
75
- write(mo, 'sections/_hero.scss', MO);
76
- write(pc, 'sections/_hero.scss', PC);
77
- write(pc, 'sections/_footer.scss', '.f__footer { height: 200px; }'); // PC 전용 섹션
78
- write(mo, '_tokens.scss', ':root { --c-1: #000; --sp-1: 16px; }');
79
- write(pc, '_tokens.scss', ':root { --c-1: #000; --sp-1: 32px; }');
80
- write(mo, 'class-plan.json', JSON.stringify({ 0: 'f__hero' }));
81
- write(pc, 'class-plan.json', JSON.stringify({ 0: 'f__hero', 0.9: 'f__footer' }));
82
-
83
- execFileSync('node', [SCRIPT, `--mo=${mo}`, `--pc=${pc}`, `--out=${out}`, '--breakpoint=1024']);
84
-
85
- const hero = fs.readFileSync(path.join(out, 'sections/_hero.scss'), 'utf8');
86
- expect(hero).toContain('flex-direction: column');
87
- expect(hero).toContain('@media (min-width: 1024px)');
88
-
89
- // PC 전용 섹션 파일은 통째로 media 블록 안
90
- const footer = fs.readFileSync(path.join(out, 'sections/_footer.scss'), 'utf8');
91
- expect(footer).toContain('@media (min-width: 1024px)');
92
- expect(footer).toContain('height: 200px');
93
-
94
- const tokens = fs.readFileSync(path.join(out, '_tokens.scss'), 'utf8');
95
- expect(tokens).toContain('--sp-1: 16px'); // base = MO
96
- expect(tokens).toContain('--sp-1: 32px'); // PC diff → media
97
-
98
- const index = fs.readFileSync(path.join(out, 'index.scss'), 'utf8');
99
- expect(index).toContain(`@use './sections/hero'`);
100
- expect(index).toContain(`@use './sections/footer'`);
101
-
102
- const plan = JSON.parse(fs.readFileSync(path.join(out, 'class-plan.json'), 'utf8'));
103
- expect(plan['0']).toBe('f__hero');
104
- expect(plan['0.9']).toBe('f__footer');
105
- });
106
- });
@@ -1,213 +0,0 @@
1
- /**
2
- * code-check.js 정밀 탐지기 테스트
3
- *
4
- * 검증 대상:
5
- * - any 탐지: 단어 경계 기반 (false positive: 'company', 'anything' 등)
6
- * - any 탐지: `: any`, `as any`, `@ts-ignore`, `<any>` (true positive)
7
- * - console.log 정책: 경로별 허용/차단
8
- * - run-ledger verifyRequired round-trip + pass 시 clear
9
- * - auto-commit verifyRequired skip
10
- */
11
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
12
- import { fileURLToPath } from 'url';
13
- import path from 'path';
14
- import fs from 'fs';
15
- import os from 'os';
16
-
17
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
18
-
19
- // ─── any 탐지 정규식 (code-check.js와 동일) ──────────────────────────────
20
- const P1_DETECTORS = [
21
- /:\s*any\b/,
22
- /\bas\s+any\b/,
23
- /<any[\s,>]/,
24
- /@ts-ignore\b/,
25
- ];
26
-
27
- function detectsAny(line) {
28
- return P1_DETECTORS.some(re => re.test(line));
29
- }
30
-
31
- describe('any 탐지: true positive', () => {
32
- it(': any — 타입 어노테이션', () => {
33
- expect(detectsAny('function foo(x: any): void {}')).toBe(true);
34
- });
35
-
36
- it(': any — 공백 포함', () => {
37
- expect(detectsAny('const x: any = 1;')).toBe(true);
38
- });
39
-
40
- it('as any — 타입 캐스트', () => {
41
- expect(detectsAny('const y = x as any;')).toBe(true);
42
- });
43
-
44
- it('<any> — 제네릭', () => {
45
- expect(detectsAny('const z = foo<any>();')).toBe(true);
46
- });
47
-
48
- it('<any, — 제네릭 다중 파라미터', () => {
49
- expect(detectsAny('const m = new Map<any, string>();')).toBe(true);
50
- });
51
-
52
- it('@ts-ignore — 라인 직전', () => {
53
- expect(detectsAny('// @ts-ignore')).toBe(true);
54
- });
55
-
56
- it('@ts-ignore — 인라인', () => {
57
- expect(detectsAny(' @ts-ignore ')).toBe(true);
58
- });
59
- });
60
-
61
- describe('any 탐지: false negative (탐지 안 됨)', () => {
62
- it('"company" 단어 포함 — 탐지 안 됨', () => {
63
- expect(detectsAny('const company = "Acme";')).toBe(false);
64
- });
65
-
66
- it('"anything" 식별자 — 탐지 안 됨', () => {
67
- expect(detectsAny('if (anything) return;')).toBe(false);
68
- });
69
-
70
- it('"manyThings" — 탐지 안 됨', () => {
71
- expect(detectsAny('const manyThings = [];')).toBe(false);
72
- });
73
-
74
- it('"fantasy" — 탐지 안 됨', () => {
75
- expect(detectsAny('const fantasy = "world";')).toBe(false);
76
- });
77
-
78
- it('문자열 리터럴 "any" — 정규식은 문자열 내부도 매칭할 수 있음 (알려진 한계, 문서화)', () => {
79
- // NOTE: 현재 구현은 문자열 내 "any"를 완전히 제외하지 않음.
80
- // 실제 코드에서 ": any" 패턴이 문자열로 존재하는 경우는 극히 드물어 허용.
81
- // 이 테스트는 동작을 문서화하는 것이 목적.
82
- const result = detectsAny('const msg = "type: any is bad";');
83
- // 문자열 내 ": any" 도 탐지될 수 있음 — false positive지만 드문 케이스
84
- expect(typeof result).toBe('boolean');
85
- });
86
- });
87
-
88
- // ─── console.log 경로 정책 ────────────────────────────────────────────────
89
- describe('console.log 허용 경로 정책', () => {
90
- // 허용 glob 패턴 (code-check.js 기본값과 동일)
91
- const DEFAULT_ALLOW_GLOBS = [
92
- 'hooks/scripts/**',
93
- 'scripts/**',
94
- '**/cli/**',
95
- '**/*.test.*',
96
- '**/*.spec.*',
97
- '**/__tests__/**',
98
- ];
99
-
100
- function globToRegExp(glob) {
101
- const normalized = glob.replace(/\\/g, '/');
102
- let out = '';
103
- for (let i = 0; i < normalized.length; i++) {
104
- const c = normalized[i];
105
- if (c === '*') {
106
- if (normalized[i + 1] === '*') {
107
- out += '.*';
108
- i++;
109
- if (normalized[i + 1] === '/') i++;
110
- } else {
111
- out += '[^/]*';
112
- }
113
- } else if (c === '?') {
114
- out += '[^/]';
115
- } else if ('.+^$()|{}[]\\'.includes(c)) {
116
- out += '\\' + c;
117
- } else {
118
- out += c;
119
- }
120
- }
121
- return new RegExp('^' + out + '$');
122
- }
123
-
124
- function isConsoleAllowed(relPath) {
125
- return DEFAULT_ALLOW_GLOBS.some(g => globToRegExp(g).test(relPath));
126
- }
127
-
128
- it('hooks/scripts/auto-test.js → 허용', () => {
129
- expect(isConsoleAllowed('hooks/scripts/auto-test.js')).toBe(true);
130
- });
131
-
132
- it('hooks/scripts/lib/run-ledger.js → 허용', () => {
133
- expect(isConsoleAllowed('hooks/scripts/lib/run-ledger.js')).toBe(true);
134
- });
135
-
136
- it('src/cli/index.ts → 허용 (**/cli/**)', () => {
137
- expect(isConsoleAllowed('src/cli/index.ts')).toBe(true);
138
- });
139
-
140
- it('src/tools/foo.test.ts → 허용 (**/*.test.*)', () => {
141
- expect(isConsoleAllowed('src/tools/foo.test.ts')).toBe(true);
142
- });
143
-
144
- it('src/__tests__/bar.ts → 허용 (**/__tests__/**)', () => {
145
- expect(isConsoleAllowed('src/__tests__/bar.ts')).toBe(true);
146
- });
147
-
148
- it('src/tools/convention/validateCodeQuality.ts → 차단', () => {
149
- expect(isConsoleAllowed('src/tools/convention/validateCodeQuality.ts')).toBe(false);
150
- });
151
-
152
- it('src/infra/lib/MemoryManager.ts → 차단', () => {
153
- expect(isConsoleAllowed('src/infra/lib/MemoryManager.ts')).toBe(false);
154
- });
155
- });
156
-
157
- // ─── 확장자 게이트 (문서 안의 코드 스니펫 오탐 방지) ──────────────────────
158
- /**
159
- * SKILL.md 등 문서에 인용된 `console.log(` 는 커밋되면 안 되는 디버그 코드가
160
- * 아니라 예시다. 확장자 게이트가 없으면 문서를 편집할 때마다 고칠 수도 없는
161
- * P1 이 주입되고, 반복되는 오탐이 게이트 신뢰도를 깎는다.
162
- *
163
- * 재구현이 아니라 실제 code-check.js 의 run() 을 통과시켜 검증한다.
164
- */
165
- describe('console.log 확장자 게이트', () => {
166
- let tempDir;
167
- let runCodeCheck;
168
-
169
- beforeEach(async () => {
170
- tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'vibe-codecheck-ext-'));
171
- ({ run: runCodeCheck } = await import('../code-check.js'));
172
- });
173
-
174
- afterEach(() => {
175
- fs.rmSync(tempDir, { recursive: true, force: true });
176
- });
177
-
178
- /** 허용 glob 에 걸리지 않는 경로를 쓰기 위해 src/feature/ 아래에 만든다 */
179
- function writeFixture(name, body) {
180
- const dir = path.join(tempDir, 'src', 'feature');
181
- fs.mkdirSync(dir, { recursive: true });
182
- const full = path.join(dir, name);
183
- fs.writeFileSync(full, body);
184
- return full;
185
- }
186
-
187
- it('마크다운 안의 console.log 는 findings 를 만들지 않는다', async () => {
188
- const filePath = writeFixture(
189
- 'guide.md',
190
- ['# Guide', '', '```bash', 'node -e "console.log(1)"', '```', ''].join('\n'),
191
- );
192
-
193
- const { findings } = await runCodeCheck({ filePath });
194
-
195
- expect(findings.filter(f => /console\.log/.test(f))).toEqual([]);
196
- });
197
-
198
- it('JSON 안의 console.log 문자열도 findings 를 만들지 않는다', async () => {
199
- const filePath = writeFixture('fixture.json', '{ "cmd": "console.log(1)" }\n');
200
-
201
- const { findings } = await runCodeCheck({ filePath });
202
-
203
- expect(findings.filter(f => /console\.log/.test(f))).toEqual([]);
204
- });
205
-
206
- it('코드 확장자에서는 여전히 탐지한다 (게이트가 탐지 자체를 죽이지 않음)', async () => {
207
- const filePath = writeFixture('service.ts', 'export const f = () => { console.log(1); };\n');
208
-
209
- const { findings } = await runCodeCheck({ filePath });
210
-
211
- expect(findings.some(f => /console\.log/.test(f))).toBe(true);
212
- });
213
- });