@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,459 +0,0 @@
1
- /**
2
- * step-counter.js — Phase 1 + Phase 2 테스트
3
- *
4
- * 검증 범위:
5
- * - 책임 1) current-run.json steps 증가 (회귀 테스트)
6
- * - 책임 2) current-run.jsonl append (Phase 1)
7
- * - 책임 3) error_category 분류기 + 3-fail detector → anti-pattern md (Phase 2)
8
- * - 책임 간 독립성, hot-path 안정성
9
- *
10
- * 패턴: 훅 스크립트 공통의 execFileSync 방식.
11
- */
12
- import { describe, it, expect, beforeEach } from 'vitest';
13
- import { spawnSync } from 'child_process';
14
- import fs from 'fs';
15
- import os from 'os';
16
- import path from 'path';
17
- import { fileURLToPath } from 'url';
18
-
19
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
20
- const SCRIPT = path.resolve(__dirname, '..', 'step-counter.js');
21
-
22
- /**
23
- * 격리된 임시 프로젝트에서 step-counter 를 1회 실행.
24
- * stdin 으로 PostToolUse payload 전달.
25
- */
26
- function runCounter({ payload, projectDir }) {
27
- const result = spawnSync('node', [SCRIPT], {
28
- input: payload ? JSON.stringify(payload) : '',
29
- encoding: 'utf-8',
30
- timeout: 5000,
31
- env: {
32
- ...process.env,
33
- CLAUDE_PROJECT_DIR: projectDir,
34
- // VIBE_HOOK_DEPTH 미설정 — 재귀 가드 영향 없음
35
- },
36
- });
37
- return result;
38
- }
39
-
40
- function makeTmpProject() {
41
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'vibe-step-counter-'));
42
- // .vibe/metrics/ 는 step-counter 가 직접 생성하도록 미리 만들지 않음
43
- return dir;
44
- }
45
-
46
- function readJson(p) {
47
- return JSON.parse(fs.readFileSync(p, 'utf-8'));
48
- }
49
-
50
- function readJsonl(p) {
51
- return fs.readFileSync(p, 'utf-8').split('\n').filter(Boolean).map((l) => JSON.parse(l));
52
- }
53
-
54
- describe('step-counter PostToolUse hook', () => {
55
- let projectDir;
56
- let runJson;
57
- let runJsonl;
58
-
59
- beforeEach(() => {
60
- projectDir = makeTmpProject();
61
- runJson = path.join(projectDir, '.vibe', 'metrics', 'current-run.json');
62
- runJsonl = path.join(projectDir, '.vibe', 'metrics', 'current-run.jsonl');
63
- });
64
-
65
- // ───────── 책임 1 회귀 ─────────
66
- describe('책임 1: current-run.json 카운터', () => {
67
- it('첫 호출 시 steps=1, startedAt 채움', () => {
68
- const r = runCounter({
69
- payload: { tool_name: 'Bash', tool_input: { command: 'ls' }, tool_response: { is_error: false } },
70
- projectDir,
71
- });
72
- expect(r.status).toBe(0);
73
- const data = readJson(runJson);
74
- expect(data.steps).toBe(1);
75
- expect(data.startedAt).toMatch(/^\d{4}-\d{2}-\d{2}T/);
76
- });
77
-
78
- it('연속 호출 시 steps 누적 (10이벤트 재작성 주기 고려)', () => {
79
- // 10이벤트마다 재작성 — 10회 호출 후에는 steps=10 이 보장됨
80
- for (let i = 0; i < 10; i++) {
81
- runCounter({
82
- payload: { tool_name: 'Bash', tool_input: { command: 'echo hi' }, tool_response: {} },
83
- projectDir,
84
- });
85
- }
86
- const data = readJson(runJson);
87
- expect(data.steps).toBe(10);
88
- });
89
-
90
- it('손상된 JSON 이 있어도 새로 시작 (10회 후 재작성으로 확인)', () => {
91
- fs.mkdirSync(path.join(projectDir, '.vibe', 'metrics'), { recursive: true });
92
- fs.writeFileSync(runJson, '{ broken json');
93
- // 10회 호출해야 재작성 주기 도달
94
- for (let i = 0; i < 10; i++) {
95
- runCounter({
96
- payload: { tool_name: 'Bash', tool_input: {}, tool_response: {} },
97
- projectDir,
98
- });
99
- }
100
- const data = readJson(runJson);
101
- expect(data.steps).toBe(10);
102
- expect(data.startedAt).toMatch(/^\d{4}-\d{2}-\d{2}T/);
103
- });
104
- });
105
-
106
- // ───────── 책임 2 신규 ─────────
107
- describe('책임 2: current-run.jsonl 로깅', () => {
108
- it('툴콜 1회 = jsonl 1라인', () => {
109
- runCounter({
110
- payload: { tool_name: 'Edit', tool_input: { file_path: 'src/foo.ts' }, tool_response: {} },
111
- projectDir,
112
- });
113
- const lines = readJsonl(runJsonl);
114
- expect(lines).toHaveLength(1);
115
- expect(lines[0].tool).toBe('Edit');
116
- expect(lines[0].ok).toBe(true);
117
- expect(lines[0].target_file).toBe('src/foo.ts');
118
- expect(lines[0].error_category).toBeNull();
119
- expect(lines[0].ts).toMatch(/^\d{4}-\d{2}-\d{2}T/);
120
- });
121
-
122
- it('tool_response.is_error=true 면 ok=false', () => {
123
- runCounter({
124
- payload: { tool_name: 'Bash', tool_input: { command: 'false' }, tool_response: { is_error: true } },
125
- projectDir,
126
- });
127
- const [line] = readJsonl(runJsonl);
128
- expect(line.ok).toBe(false);
129
- });
130
-
131
- it('절대 경로 file_path 를 프로젝트 상대 경로로 정규화', () => {
132
- const abs = path.join(projectDir, 'src', 'bar.ts');
133
- runCounter({
134
- payload: { tool_name: 'Write', tool_input: { file_path: abs }, tool_response: {} },
135
- projectDir,
136
- });
137
- const [line] = readJsonl(runJsonl);
138
- expect(line.target_file).toBe('src/bar.ts');
139
- });
140
-
141
- it('file_path 없는 툴콜은 target_file=null', () => {
142
- runCounter({
143
- payload: { tool_name: 'Bash', tool_input: { command: 'pwd' }, tool_response: {} },
144
- projectDir,
145
- });
146
- const [line] = readJsonl(runJsonl);
147
- expect(line.target_file).toBeNull();
148
- });
149
-
150
- it('tool_name 없으면 jsonl 라인 안 씀 (steps 는 증가)', () => {
151
- runCounter({ payload: {}, projectDir });
152
- expect(fs.existsSync(runJsonl)).toBe(false);
153
- expect(readJson(runJson).steps).toBe(1);
154
- });
155
-
156
- it('연속 호출 시 jsonl 누적 (Read는 조기 종료 — 기록 안 됨)', () => {
157
- // Read 는 READ_ONLY_TOOLS 조기 종료 → jsonl 미기록
158
- runCounter({
159
- payload: { tool_name: 'Read', tool_input: { file_path: 'a.ts' }, tool_response: {} },
160
- projectDir,
161
- });
162
- runCounter({
163
- payload: { tool_name: 'Edit', tool_input: { file_path: 'a.ts' }, tool_response: {} },
164
- projectDir,
165
- });
166
- const lines = readJsonl(runJsonl);
167
- expect(lines).toHaveLength(1);
168
- expect(lines[0].tool).toBe('Edit');
169
- });
170
- });
171
-
172
- // ───────── 독립성 ─────────
173
- describe('두 책임의 독립성', () => {
174
- it('payload 가 비어 stdin 무효여도 카운터는 증가', () => {
175
- const r = runCounter({ payload: null, projectDir });
176
- expect(r.status).toBe(0);
177
- expect(readJson(runJson).steps).toBe(1);
178
- });
179
- });
180
-
181
- // ───────── Phase 2: error_category 분류 ─────────
182
- describe('책임 3a: error_category 분류기', () => {
183
- it('TypeError of undefined → nullability', () => {
184
- runCounter({
185
- payload: {
186
- tool_name: 'Bash',
187
- tool_input: { command: 'node x.js' },
188
- tool_response: { is_error: true, error: "TypeError: Cannot read properties of undefined (reading 'foo')" },
189
- },
190
- projectDir,
191
- });
192
- const [line] = readJsonl(runJsonl);
193
- expect(line.error_category).toBe('nullability');
194
- });
195
-
196
- it('TS2345 → type-narrow', () => {
197
- runCounter({
198
- payload: {
199
- tool_name: 'Bash',
200
- tool_input: { command: 'tsc' },
201
- tool_response: { is_error: true, error: "src/x.ts(3,4): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'." },
202
- },
203
- projectDir,
204
- });
205
- const [line] = readJsonl(runJsonl);
206
- expect(line.error_category).toBe('type-narrow');
207
- });
208
-
209
- it('ECONNREFUSED → integration', () => {
210
- runCounter({
211
- payload: {
212
- tool_name: 'Bash',
213
- tool_input: { command: 'curl' },
214
- tool_response: { is_error: true, error: 'connect ECONNREFUSED 127.0.0.1:5432' },
215
- },
216
- projectDir,
217
- });
218
- const [line] = readJsonl(runJsonl);
219
- expect(line.error_category).toBe('integration');
220
- });
221
-
222
- it('알 수 없는 에러 → other', () => {
223
- runCounter({
224
- payload: {
225
- tool_name: 'Bash',
226
- tool_input: { command: 'x' },
227
- tool_response: { is_error: true, error: 'some unrecognized failure mode 12345' },
228
- },
229
- projectDir,
230
- });
231
- const [line] = readJsonl(runJsonl);
232
- expect(line.error_category).toBe('other');
233
- });
234
-
235
- it('성공 툴콜은 error_category=null', () => {
236
- runCounter({
237
- payload: { tool_name: 'Bash', tool_input: { command: 'ls' }, tool_response: { is_error: false } },
238
- projectDir,
239
- });
240
- const [line] = readJsonl(runJsonl);
241
- expect(line.ok).toBe(true);
242
- expect(line.error_category).toBeNull();
243
- });
244
- });
245
-
246
- // ───────── Phase 2: 3-fail detector ─────────
247
- describe('책임 3b: 3-fail detector → anti-pattern md', () => {
248
- function failBash(command, errorText, projectDir) {
249
- runCounter({
250
- payload: {
251
- tool_name: 'Bash',
252
- tool_input: { command },
253
- tool_response: { is_error: true, error: errorText },
254
- },
255
- projectDir,
256
- });
257
- }
258
-
259
- function listAntiPatterns(projectDir) {
260
- const dir = path.join(projectDir, '.vibe', 'anti-patterns');
261
- if (!fs.existsSync(dir)) return [];
262
- return fs.readdirSync(dir).filter((f) => f.endsWith('.md'));
263
- }
264
-
265
- it('같은 (file, category) 3회 누적 시 anti-pattern md 생성', () => {
266
- const err = "TypeError: Cannot read properties of undefined (reading 'x')";
267
- // file_path 없는 Bash 실패 3회 → target_file=null, category=nullability
268
- for (let i = 0; i < 3; i++) failBash(`run-${i}`, err, projectDir);
269
- const files = listAntiPatterns(projectDir);
270
- expect(files).toHaveLength(1);
271
- expect(files[0]).toMatch(/^nullability__global__\d{8}\.md$/);
272
- });
273
-
274
- it('2회만 누적되면 생성 안 함', () => {
275
- const err = 'connect ECONNREFUSED foo';
276
- for (let i = 0; i < 2; i++) failBash(`x-${i}`, err, projectDir);
277
- expect(listAntiPatterns(projectDir)).toHaveLength(0);
278
- });
279
-
280
- it('3회지만 카테고리 다르면 생성 안 함', () => {
281
- failBash('a', "Cannot read properties of undefined", projectDir); // nullability
282
- failBash('b', "ECONNREFUSED", projectDir); // integration
283
- failBash('c', "TS2345 not assignable", projectDir); // type-narrow
284
- expect(listAntiPatterns(projectDir)).toHaveLength(0);
285
- });
286
-
287
- it('동일 (file, category) 4회 — md 1개만 (dedup)', () => {
288
- const err = "TypeError: Cannot read properties of undefined";
289
- for (let i = 0; i < 4; i++) failBash(`r-${i}`, err, projectDir);
290
- expect(listAntiPatterns(projectDir)).toHaveLength(1);
291
- });
292
-
293
- it('frontmatter 가 schema 충족', () => {
294
- const err = "TypeError: Cannot read properties of null";
295
- for (let i = 0; i < 3; i++) failBash(`r-${i}`, err, projectDir);
296
- const [filename] = listAntiPatterns(projectDir);
297
- const content = fs.readFileSync(path.join(projectDir, '.vibe', 'anti-patterns', filename), 'utf-8');
298
- expect(content).toMatch(/^---\n/);
299
- expect(content).toMatch(/^slug: nullability__global__\d{8}$/m);
300
- expect(content).toMatch(/^type: anti-pattern$/m);
301
- expect(content).toMatch(/^root-cause-tag: nullability$/m);
302
- expect(content).toMatch(/^trigger-signature: "/m);
303
- expect(content).toMatch(/^fail-count: 3$/m);
304
- expect(content).toMatch(/^suggested-stop: "/m);
305
- expect(content).toMatch(/^created: \d{4}-\d{2}-\d{2}$/m);
306
- });
307
-
308
- it('파일 경로 있는 실패는 file slug 사용', () => {
309
- const filePath = 'src/cli/foo.ts';
310
- const err = "TypeError: Cannot read properties of undefined";
311
- for (let i = 0; i < 3; i++) {
312
- runCounter({
313
- payload: {
314
- tool_name: 'Edit',
315
- tool_input: { file_path: filePath },
316
- tool_response: { is_error: true, error: err },
317
- },
318
- projectDir,
319
- });
320
- }
321
- const [filename] = listAntiPatterns(projectDir);
322
- expect(filename).toMatch(/^nullability__src-cli-foo-ts__\d{8}\.md$/);
323
- });
324
-
325
- it('윈도우 외 실패는 카운트 안 됨', () => {
326
- const err = "TypeError: Cannot read properties of undefined";
327
- // 같은 카테고리 실패 2회
328
- failBash('a', err, projectDir);
329
- failBash('b', err, projectDir);
330
- // 성공 툴콜로 윈도우 채움 (10줄 이상) — Bash 를 사용 (Read 는 조기 종료로 jsonl 미기록)
331
- for (let i = 0; i < 10; i++) {
332
- runCounter({
333
- payload: { tool_name: 'Bash', tool_input: { command: `echo ${i}` }, tool_response: {} },
334
- projectDir,
335
- });
336
- }
337
- // 마지막 실패 1회 — 윈도우(10줄) 안에는 이 실패 + 직전 성공만 있으므로 트립 안 함
338
- failBash('c', err, projectDir);
339
- expect(listAntiPatterns(projectDir)).toHaveLength(0);
340
- });
341
- });
342
-
343
- // ───────── 차단 금지 ─────────
344
- describe('hot path 안정성', () => {
345
- it('항상 exit 0', () => {
346
- const r = runCounter({
347
- payload: { tool_name: 'Bash', tool_input: { command: 'x' }, tool_response: {} },
348
- projectDir,
349
- });
350
- expect(r.status).toBe(0);
351
- });
352
-
353
- it('잘못된 stdin JSON 도 차단 안 함', () => {
354
- const r = spawnSync('node', [SCRIPT], {
355
- input: 'not json at all',
356
- encoding: 'utf-8',
357
- timeout: 5000,
358
- env: { ...process.env, CLAUDE_PROJECT_DIR: projectDir },
359
- });
360
- expect(r.status).toBe(0);
361
- });
362
- });
363
-
364
- // ───────── 읽기 전용 도구 조기 종료 (defense-in-depth) ─────────
365
- describe('읽기 전용 도구 조기 종료', () => {
366
- const READ_ONLY = ['Read', 'Grep', 'Glob', 'WebFetch', 'WebSearch', 'TodoWrite', 'ToolSearch', 'ListMcpResourcesTool'];
367
-
368
- it.each(READ_ONLY)('%s 호출 시 파일 미생성 + exit 0', (toolName) => {
369
- const r = runCounter({
370
- payload: { tool_name: toolName, tool_input: { file_path: 'src/foo.ts' }, tool_response: {} },
371
- projectDir,
372
- });
373
- expect(r.status).toBe(0);
374
- // jsonl에 기록하지 않아야 함
375
- const jsonlPath = path.join(projectDir, '.vibe', 'metrics', 'current-run.jsonl');
376
- expect(fs.existsSync(jsonlPath)).toBe(false);
377
- // current-run.json 도 생성하지 않아야 함
378
- const jsonPath = path.join(projectDir, '.vibe', 'metrics', 'current-run.json');
379
- expect(fs.existsSync(jsonPath)).toBe(false);
380
- });
381
- });
382
-
383
- // ───────── 쓰기 스로틀 ─────────
384
- describe('쓰기 스로틀: jsonl 항상 append, json 조건부 재작성', () => {
385
- it('첫 번째 이벤트는 current-run.json 생성 (파일 없음 → 스로틀 없음)', () => {
386
- runCounter({
387
- payload: { tool_name: 'Bash', tool_input: { command: 'x' }, tool_response: {} },
388
- projectDir,
389
- });
390
- expect(fs.existsSync(runJson)).toBe(true);
391
- expect(readJson(runJson).steps).toBe(1);
392
- });
393
-
394
- it('10이벤트마다 강제 재작성: 10회 후 steps=jsonl라인수=10', () => {
395
- for (let i = 0; i < 10; i++) {
396
- runCounter({
397
- payload: { tool_name: 'Edit', tool_input: { file_path: 'a.ts' }, tool_response: {} },
398
- projectDir,
399
- });
400
- }
401
- // 10번째 이벤트에서 강제 재작성 (10%10===0) — steps = jsonl 라인 수 = 10
402
- const data = readJson(runJson);
403
- expect(data.steps).toBe(10);
404
- // jsonl 도 10줄
405
- const lines = readJsonl(runJsonl);
406
- expect(lines).toHaveLength(10);
407
- });
408
-
409
- it('jsonl 은 스로틀 무관 항상 즉시 append', () => {
410
- for (let i = 0; i < 5; i++) {
411
- runCounter({
412
- payload: { tool_name: 'Bash', tool_input: { command: `cmd-${i}` }, tool_response: {} },
413
- projectDir,
414
- });
415
- }
416
- const lines = readJsonl(runJsonl);
417
- expect(lines).toHaveLength(5);
418
- });
419
-
420
- it('3-fail 감지는 jsonl 기반 — json 스로틀 후에도 동작', () => {
421
- const err = "TypeError: Cannot read properties of undefined (reading 'x')";
422
- // 3회 실패 (jsonl에 즉시 기록되므로 감지 가능)
423
- for (let i = 0; i < 3; i++) {
424
- runCounter({
425
- payload: {
426
- tool_name: 'Bash',
427
- tool_input: { command: `run-${i}` },
428
- tool_response: { is_error: true, error: err },
429
- },
430
- projectDir,
431
- });
432
- }
433
- const apDir = path.join(projectDir, '.vibe', 'anti-patterns');
434
- const files = fs.existsSync(apDir) ? fs.readdirSync(apDir).filter(f => f.endsWith('.md')) : [];
435
- expect(files).toHaveLength(1);
436
- });
437
- });
438
-
439
- // ───────── A2/D2: 64KB 초과 stdin 페이로드 (구 단일 버퍼 리더 절단 버그 회귀) ─────────
440
- describe('stdin 64KB 초과 페이로드 — 절단 없이 처리', () => {
441
- it('페이로드가 64KB를 넘어도 JSON 전체를 읽어 target_file을 정확히 기록', () => {
442
- // 구현이 64KB 단일 버퍼로 되돌아가면 JSON이 중간에 잘려 파싱 실패 →
443
- // stdinPayload=null → jsonl 라인 자체가 기록되지 않는다.
444
- const padding = 'x'.repeat(80000); // 총 페이로드 > 64KB 보장
445
- runCounter({
446
- payload: {
447
- tool_name: 'Edit',
448
- tool_input: { file_path: 'src/foo.ts', padding },
449
- tool_response: {},
450
- },
451
- projectDir,
452
- });
453
- const lines = readJsonl(runJsonl);
454
- expect(lines).toHaveLength(1);
455
- expect(lines[0].target_file).toBe('src/foo.ts');
456
- expect(lines[0].tool).toBe('Edit');
457
- });
458
- });
459
- });
@@ -1,74 +0,0 @@
1
- /**
2
- * dispatch() 순차 실행 계약 회귀 테스트
3
- *
4
- * stop-dispatcher.js 는 "auto-commit 의 git cascade 와 겹쳐 프로세스 폭주" 를 막기 위해
5
- * 순차 실행을 계약으로 문서화한다(stop-dispatcher.js 헤더). 그러나 dispatch() 가
6
- * Promise.all 로 구현돼 있어 실제로는 병렬이었다 — 이 테스트가 그 회귀를 막는다.
7
- *
8
- * 검증 대상은 내부 구현이 아니라 관측 가능한 실행 구간 겹침이다.
9
- */
10
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
11
- import { execFileSync } from 'child_process';
12
- import fs from 'fs';
13
- import os from 'os';
14
- import path from 'path';
15
- import { fileURLToPath } from 'url';
16
-
17
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
18
- const FIXTURES = path.resolve(__dirname, 'fixtures');
19
- const HARNESS = path.join(FIXTURES, 'seq-harness.js');
20
-
21
- let traceDir;
22
- let tracePath;
23
-
24
- beforeEach(() => {
25
- traceDir = fs.mkdtempSync(path.join(os.tmpdir(), 'vibe-seq-'));
26
- tracePath = path.join(traceDir, 'trace.log');
27
- fs.writeFileSync(tracePath, '');
28
- });
29
-
30
- afterEach(() => {
31
- fs.rmSync(traceDir, { recursive: true, force: true });
32
- });
33
-
34
- function runHarness() {
35
- execFileSync('node', [HARNESS], {
36
- encoding: 'utf-8',
37
- input: JSON.stringify({ tool_name: 'Stop' }),
38
- timeout: 20000,
39
- env: {
40
- ...process.env,
41
- VIBE_SEQ_TRACE: tracePath,
42
- VIBE_SEQ_HOLD_MS: '120',
43
- // config.json 이 없는 디렉터리 → 모든 step enabled
44
- CLAUDE_PROJECT_DIR: traceDir,
45
- },
46
- });
47
- return fs.readFileSync(tracePath, 'utf-8').trim().split('\n').filter(Boolean);
48
- }
49
-
50
- describe('dispatch() 순차 실행 계약', () => {
51
- it('스텝 실행 구간이 겹치지 않는다 (start 직후 항상 같은 스텝의 end)', () => {
52
- const trace = runHarness();
53
-
54
- expect(trace).toHaveLength(6);
55
- for (let i = 0; i < trace.length; i += 2) {
56
- const [startName, startMark] = trace[i].split(':');
57
- const [endName, endMark] = trace[i + 1].split(':');
58
- expect(startMark).toBe('start');
59
- expect(endMark).toBe('end');
60
- // 병렬이면 여기서 다른 스텝의 start 가 끼어든다
61
- expect(endName).toBe(startName);
62
- }
63
- });
64
-
65
- it('선언된 순서(a → b → c)를 그대로 지킨다', () => {
66
- const trace = runHarness();
67
-
68
- expect(trace).toEqual([
69
- 'a:start', 'a:end',
70
- 'b:start', 'b:end',
71
- 'c:start', 'c:end',
72
- ]);
73
- });
74
- });
@@ -1,99 +0,0 @@
1
- /**
2
- * utils.js — getGlobalNpmPath() 파일 캐시 테스트
3
- *
4
- * 검증 범위:
5
- * - L2 파일 캐시 히트 (TTL 내)
6
- * - L2 파일 캐시 만료 (TTL 초과)
7
- * - 캐시 파일 손상 시 fail-open (execSync 재실행)
8
- * - 캐시 파일 없음 시 execSync 실행 후 파일 저장
9
- *
10
- * 격리 전략: 각 테스트는 별도 임시 디렉토리를 캐시 경로로 사용한다.
11
- * NPM_ROOT_CACHE_FILE 환경 변수를 통해 경로를 주입한다.
12
- */
13
- import { describe, it, expect } from 'vitest';
14
- import { spawnSync } from 'child_process';
15
- import fs from 'fs';
16
- import os from 'os';
17
- import path from 'path';
18
- import { fileURLToPath, pathToFileURL } from 'url';
19
-
20
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
21
- // Windows 절대경로(C:\...)는 ESM import 지정자가 될 수 없으므로 file:// URL로 변환
22
- const UTILS_URL = pathToFileURL(path.resolve(__dirname, '..', 'utils.js')).href;
23
-
24
- function makeTempCacheFile() {
25
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'vibe-npm-root-test-'));
26
- return path.join(dir, 'npm-root.json');
27
- }
28
-
29
- /**
30
- * utils.js 의 getGlobalNpmPath() 를 별도 프로세스에서 실행.
31
- * VIBE_NPM_ROOT_CACHE_FILE 환경 변수로 캐시 파일 경로를 주입한다.
32
- */
33
- function runGetNpmRoot(cacheFilePath) {
34
- return spawnSync(process.execPath, ['--input-type=module', '--eval',
35
- `import { getGlobalNpmPath } from '${UTILS_URL}';
36
- process.stdout.write(getGlobalNpmPath() || '');`
37
- ], {
38
- encoding: 'utf-8',
39
- timeout: 10000,
40
- env: {
41
- ...process.env,
42
- VIBE_NPM_ROOT_CACHE_FILE: cacheFilePath,
43
- },
44
- });
45
- }
46
-
47
- describe('utils.js — getGlobalNpmPath() npm-root 파일 캐시', () => {
48
- it('캐시 파일 없으면 execSync 실행 후 캐시 파일 생성', () => {
49
- const cacheFile = makeTempCacheFile();
50
- // 캐시 파일이 없는 상태에서 시작
51
- expect(fs.existsSync(cacheFile)).toBe(false);
52
-
53
- const result = runGetNpmRoot(cacheFile);
54
- expect(result.status).toBe(0);
55
- expect(result.stdout.trim()).toBeTruthy();
56
-
57
- // 캐시 파일이 생성되어야 함
58
- expect(fs.existsSync(cacheFile)).toBe(true);
59
- const cached = JSON.parse(fs.readFileSync(cacheFile, 'utf-8'));
60
- expect(cached.npmRoot).toBe(result.stdout.trim());
61
- expect(typeof cached.savedAt).toBe('number');
62
- });
63
-
64
- it('유효한 캐시 파일이 있으면 execSync 없이 캐시값 반환', () => {
65
- const cacheFile = makeTempCacheFile();
66
- const fakeRoot = '/fake/npm/root/for/test';
67
- // 유효한 캐시 미리 작성
68
- fs.writeFileSync(cacheFile, JSON.stringify({ npmRoot: fakeRoot, savedAt: Date.now() }), { mode: 0o600 });
69
-
70
- const result = runGetNpmRoot(cacheFile);
71
- expect(result.status).toBe(0);
72
- expect(result.stdout.trim()).toBe(fakeRoot);
73
- });
74
-
75
- it('TTL 초과 캐시는 무효화 — execSync 재실행', () => {
76
- const cacheFile = makeTempCacheFile();
77
- const staleRoot = '/stale/path/should/not/be/used';
78
- const expiredAt = Date.now() - (25 * 60 * 60 * 1000); // 25시간 전
79
- fs.writeFileSync(cacheFile, JSON.stringify({ npmRoot: staleRoot, savedAt: expiredAt }), { mode: 0o600 });
80
-
81
- const result = runGetNpmRoot(cacheFile);
82
- expect(result.status).toBe(0);
83
- // stale 값이 아닌 실제 npm root 가 반환되어야 함
84
- expect(result.stdout.trim()).not.toBe(staleRoot);
85
- expect(result.stdout.trim()).toBeTruthy();
86
- });
87
-
88
- it('손상된 캐시 파일 — fail-open (execSync 실행)', () => {
89
- const cacheFile = makeTempCacheFile();
90
- fs.writeFileSync(cacheFile, '{ broken json :::');
91
-
92
- const result = runGetNpmRoot(cacheFile);
93
- expect(result.status).toBe(0);
94
- expect(result.stdout.trim()).toBeTruthy(); // 실제 경로 반환
95
- // 손상된 파일 때문에 프로세스가 crash 나지 않아야 함
96
- const stderr = result.stderr || '';
97
- expect(stderr).not.toMatch(/^Error:/m);
98
- });
99
- });