@su-record/vibe 3.2.14 → 3.2.15

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 (294) hide show
  1. package/dist/infra/lib/codex-proxy.d.ts +126 -0
  2. package/dist/infra/lib/codex-proxy.d.ts.map +1 -1
  3. package/dist/infra/lib/codex-proxy.js +16 -16
  4. package/dist/infra/lib/codex-proxy.js.map +1 -1
  5. package/dist/infra/lib/figma/audit.d.ts.map +1 -1
  6. package/dist/infra/lib/figma/audit.js +0 -2
  7. package/dist/infra/lib/figma/audit.js.map +1 -1
  8. package/dist/infra/lib/figma/extract.d.ts +6 -1
  9. package/dist/infra/lib/figma/extract.d.ts.map +1 -1
  10. package/dist/infra/lib/figma/extract.js +17 -15
  11. package/dist/infra/lib/figma/extract.js.map +1 -1
  12. package/dist/infra/lib/figma/types.d.ts +103 -0
  13. package/dist/infra/lib/figma/types.d.ts.map +1 -1
  14. package/dist/infra/lib/figma/types.js +8 -0
  15. package/dist/infra/lib/figma/types.js.map +1 -1
  16. package/hooks/scripts/clone-extract.js +16 -1
  17. package/hooks/scripts/code-check.js +12 -5
  18. package/hooks/scripts/lib/dispatcher.js +43 -3
  19. package/package.json +10 -8
  20. package/dist/__tests__/agent-model-sync.test.d.ts +0 -2
  21. package/dist/__tests__/agent-model-sync.test.d.ts.map +0 -1
  22. package/dist/__tests__/agent-model-sync.test.js +0 -71
  23. package/dist/__tests__/agent-model-sync.test.js.map +0 -1
  24. package/dist/__tests__/architecture.test.d.ts +0 -2
  25. package/dist/__tests__/architecture.test.d.ts.map +0 -1
  26. package/dist/__tests__/architecture.test.js +0 -207
  27. package/dist/__tests__/architecture.test.js.map +0 -1
  28. package/dist/__tests__/engines-contract.test.d.ts +0 -2
  29. package/dist/__tests__/engines-contract.test.d.ts.map +0 -1
  30. package/dist/__tests__/engines-contract.test.js +0 -72
  31. package/dist/__tests__/engines-contract.test.js.map +0 -1
  32. package/dist/__tests__/instruction-drift.test.d.ts +0 -2
  33. package/dist/__tests__/instruction-drift.test.d.ts.map +0 -1
  34. package/dist/__tests__/instruction-drift.test.js +0 -116
  35. package/dist/__tests__/instruction-drift.test.js.map +0 -1
  36. package/dist/__tests__/skill-namespace.test.d.ts +0 -2
  37. package/dist/__tests__/skill-namespace.test.d.ts.map +0 -1
  38. package/dist/__tests__/skill-namespace.test.js +0 -60
  39. package/dist/__tests__/skill-namespace.test.js.map +0 -1
  40. package/dist/__tests__/stakes-contract.test.d.ts +0 -2
  41. package/dist/__tests__/stakes-contract.test.d.ts.map +0 -1
  42. package/dist/__tests__/stakes-contract.test.js +0 -173
  43. package/dist/__tests__/stakes-contract.test.js.map +0 -1
  44. package/dist/__tests__/stuck-semantics.test.d.ts +0 -2
  45. package/dist/__tests__/stuck-semantics.test.d.ts.map +0 -1
  46. package/dist/__tests__/stuck-semantics.test.js +0 -161
  47. package/dist/__tests__/stuck-semantics.test.js.map +0 -1
  48. package/dist/__tests__/wiring-integrity.test.d.ts +0 -2
  49. package/dist/__tests__/wiring-integrity.test.d.ts.map +0 -1
  50. package/dist/__tests__/wiring-integrity.test.js +0 -160
  51. package/dist/__tests__/wiring-integrity.test.js.map +0 -1
  52. package/dist/cli/commands/info.test.d.ts +0 -2
  53. package/dist/cli/commands/info.test.d.ts.map +0 -1
  54. package/dist/cli/commands/info.test.js +0 -74
  55. package/dist/cli/commands/info.test.js.map +0 -1
  56. package/dist/cli/commands/upgrade.test.d.ts +0 -2
  57. package/dist/cli/commands/upgrade.test.d.ts.map +0 -1
  58. package/dist/cli/commands/upgrade.test.js +0 -99
  59. package/dist/cli/commands/upgrade.test.js.map +0 -1
  60. package/dist/cli/design/design-md-parser.test.d.ts +0 -2
  61. package/dist/cli/design/design-md-parser.test.d.ts.map +0 -1
  62. package/dist/cli/design/design-md-parser.test.js +0 -149
  63. package/dist/cli/design/design-md-parser.test.js.map +0 -1
  64. package/dist/cli/detect.characterization.test.d.ts +0 -7
  65. package/dist/cli/detect.characterization.test.d.ts.map +0 -1
  66. package/dist/cli/detect.characterization.test.js +0 -294
  67. package/dist/cli/detect.characterization.test.js.map +0 -1
  68. package/dist/cli/postinstall/fs-utils.test.d.ts +0 -2
  69. package/dist/cli/postinstall/fs-utils.test.d.ts.map +0 -1
  70. package/dist/cli/postinstall/fs-utils.test.js +0 -259
  71. package/dist/cli/postinstall/fs-utils.test.js.map +0 -1
  72. package/dist/cli/setup/CodexHooks.test.d.ts +0 -2
  73. package/dist/cli/setup/CodexHooks.test.d.ts.map +0 -1
  74. package/dist/cli/setup/CodexHooks.test.js +0 -52
  75. package/dist/cli/setup/CodexHooks.test.js.map +0 -1
  76. package/dist/cli/setup/GlobalInstaller.test.d.ts +0 -2
  77. package/dist/cli/setup/GlobalInstaller.test.d.ts.map +0 -1
  78. package/dist/cli/setup/GlobalInstaller.test.js +0 -16
  79. package/dist/cli/setup/GlobalInstaller.test.js.map +0 -1
  80. package/dist/cli/utils/cli-detector.test.d.ts +0 -2
  81. package/dist/cli/utils/cli-detector.test.d.ts.map +0 -1
  82. package/dist/cli/utils/cli-detector.test.js +0 -52
  83. package/dist/cli/utils/cli-detector.test.js.map +0 -1
  84. package/dist/infra/lib/SkillFrontmatter.test.d.ts +0 -2
  85. package/dist/infra/lib/SkillFrontmatter.test.d.ts.map +0 -1
  86. package/dist/infra/lib/SkillFrontmatter.test.js +0 -60
  87. package/dist/infra/lib/SkillFrontmatter.test.js.map +0 -1
  88. package/dist/infra/lib/__tests__/AutomationLevel.test.d.ts +0 -2
  89. package/dist/infra/lib/__tests__/AutomationLevel.test.d.ts.map +0 -1
  90. package/dist/infra/lib/__tests__/AutomationLevel.test.js +0 -297
  91. package/dist/infra/lib/__tests__/AutomationLevel.test.js.map +0 -1
  92. package/dist/infra/lib/__tests__/ComponentRegistry.test.d.ts +0 -2
  93. package/dist/infra/lib/__tests__/ComponentRegistry.test.d.ts.map +0 -1
  94. package/dist/infra/lib/__tests__/ComponentRegistry.test.js +0 -99
  95. package/dist/infra/lib/__tests__/ComponentRegistry.test.js.map +0 -1
  96. package/dist/infra/lib/__tests__/DecisionTracer.test.d.ts +0 -2
  97. package/dist/infra/lib/__tests__/DecisionTracer.test.d.ts.map +0 -1
  98. package/dist/infra/lib/__tests__/DecisionTracer.test.js +0 -274
  99. package/dist/infra/lib/__tests__/DecisionTracer.test.js.map +0 -1
  100. package/dist/infra/lib/__tests__/InteractiveCheckpoint.test.d.ts +0 -2
  101. package/dist/infra/lib/__tests__/InteractiveCheckpoint.test.d.ts.map +0 -1
  102. package/dist/infra/lib/__tests__/InteractiveCheckpoint.test.js +0 -350
  103. package/dist/infra/lib/__tests__/InteractiveCheckpoint.test.js.map +0 -1
  104. package/dist/infra/lib/__tests__/LoopBreaker.test.d.ts +0 -2
  105. package/dist/infra/lib/__tests__/LoopBreaker.test.d.ts.map +0 -1
  106. package/dist/infra/lib/__tests__/LoopBreaker.test.js +0 -340
  107. package/dist/infra/lib/__tests__/LoopBreaker.test.js.map +0 -1
  108. package/dist/infra/lib/__tests__/VerificationLoop.test.d.ts +0 -2
  109. package/dist/infra/lib/__tests__/VerificationLoop.test.d.ts.map +0 -1
  110. package/dist/infra/lib/__tests__/VerificationLoop.test.js +0 -486
  111. package/dist/infra/lib/__tests__/VerificationLoop.test.js.map +0 -1
  112. package/dist/infra/lib/config/GlobalConfigManager.test.d.ts +0 -2
  113. package/dist/infra/lib/config/GlobalConfigManager.test.d.ts.map +0 -1
  114. package/dist/infra/lib/config/GlobalConfigManager.test.js +0 -9
  115. package/dist/infra/lib/config/GlobalConfigManager.test.js.map +0 -1
  116. package/dist/infra/lib/embedding/__tests__/EmbeddingProvider.test.d.ts +0 -2
  117. package/dist/infra/lib/embedding/__tests__/EmbeddingProvider.test.d.ts.map +0 -1
  118. package/dist/infra/lib/embedding/__tests__/EmbeddingProvider.test.js +0 -43
  119. package/dist/infra/lib/embedding/__tests__/EmbeddingProvider.test.js.map +0 -1
  120. package/dist/infra/lib/embedding/__tests__/VectorStore.test.d.ts +0 -2
  121. package/dist/infra/lib/embedding/__tests__/VectorStore.test.d.ts.map +0 -1
  122. package/dist/infra/lib/embedding/__tests__/VectorStore.test.js +0 -94
  123. package/dist/infra/lib/embedding/__tests__/VectorStore.test.js.map +0 -1
  124. package/dist/infra/lib/embedding/__tests__/cosine.test.d.ts +0 -2
  125. package/dist/infra/lib/embedding/__tests__/cosine.test.d.ts.map +0 -1
  126. package/dist/infra/lib/embedding/__tests__/cosine.test.js +0 -73
  127. package/dist/infra/lib/embedding/__tests__/cosine.test.js.map +0 -1
  128. package/dist/infra/lib/evolution/__tests__/deprecation.test.d.ts +0 -2
  129. package/dist/infra/lib/evolution/__tests__/deprecation.test.d.ts.map +0 -1
  130. package/dist/infra/lib/evolution/__tests__/deprecation.test.js +0 -251
  131. package/dist/infra/lib/evolution/__tests__/deprecation.test.js.map +0 -1
  132. package/dist/infra/lib/evolution/__tests__/eval.test.d.ts +0 -2
  133. package/dist/infra/lib/evolution/__tests__/eval.test.d.ts.map +0 -1
  134. package/dist/infra/lib/evolution/__tests__/eval.test.js +0 -603
  135. package/dist/infra/lib/evolution/__tests__/eval.test.js.map +0 -1
  136. package/dist/infra/lib/evolution/__tests__/generation.test.d.ts +0 -2
  137. package/dist/infra/lib/evolution/__tests__/generation.test.d.ts.map +0 -1
  138. package/dist/infra/lib/evolution/__tests__/generation.test.js +0 -396
  139. package/dist/infra/lib/evolution/__tests__/generation.test.js.map +0 -1
  140. package/dist/infra/lib/evolution/__tests__/insight.test.d.ts +0 -2
  141. package/dist/infra/lib/evolution/__tests__/insight.test.d.ts.map +0 -1
  142. package/dist/infra/lib/evolution/__tests__/insight.test.js +0 -204
  143. package/dist/infra/lib/evolution/__tests__/insight.test.js.map +0 -1
  144. package/dist/infra/lib/evolution/__tests__/integration.test.d.ts +0 -2
  145. package/dist/infra/lib/evolution/__tests__/integration.test.d.ts.map +0 -1
  146. package/dist/infra/lib/evolution/__tests__/integration.test.js +0 -206
  147. package/dist/infra/lib/evolution/__tests__/integration.test.js.map +0 -1
  148. package/dist/infra/lib/evolution/__tests__/lifecycle.test.d.ts +0 -2
  149. package/dist/infra/lib/evolution/__tests__/lifecycle.test.d.ts.map +0 -1
  150. package/dist/infra/lib/evolution/__tests__/lifecycle.test.js +0 -350
  151. package/dist/infra/lib/evolution/__tests__/lifecycle.test.js.map +0 -1
  152. package/dist/infra/lib/evolution/__tests__/parity.test.d.ts +0 -2
  153. package/dist/infra/lib/evolution/__tests__/parity.test.d.ts.map +0 -1
  154. package/dist/infra/lib/evolution/__tests__/parity.test.js +0 -319
  155. package/dist/infra/lib/evolution/__tests__/parity.test.js.map +0 -1
  156. package/dist/infra/lib/llm/auth/AuthProfileManager.test.d.ts +0 -5
  157. package/dist/infra/lib/llm/auth/AuthProfileManager.test.d.ts.map +0 -1
  158. package/dist/infra/lib/llm/auth/AuthProfileManager.test.js +0 -168
  159. package/dist/infra/lib/llm/auth/AuthProfileManager.test.js.map +0 -1
  160. package/dist/infra/lib/llm/auth/TokenRefresher.test.d.ts +0 -2
  161. package/dist/infra/lib/llm/auth/TokenRefresher.test.d.ts.map +0 -1
  162. package/dist/infra/lib/llm/auth/TokenRefresher.test.js +0 -120
  163. package/dist/infra/lib/llm/auth/TokenRefresher.test.js.map +0 -1
  164. package/dist/infra/lib/llm/timeout.test.d.ts +0 -2
  165. package/dist/infra/lib/llm/timeout.test.d.ts.map +0 -1
  166. package/dist/infra/lib/llm/timeout.test.js +0 -50
  167. package/dist/infra/lib/llm/timeout.test.js.map +0 -1
  168. package/dist/infra/lib/llm-availability.test.d.ts +0 -2
  169. package/dist/infra/lib/llm-availability.test.d.ts.map +0 -1
  170. package/dist/infra/lib/llm-availability.test.js +0 -37
  171. package/dist/infra/lib/llm-availability.test.js.map +0 -1
  172. package/dist/infra/lib/memory/KnowledgeGraph.test.d.ts +0 -2
  173. package/dist/infra/lib/memory/KnowledgeGraph.test.d.ts.map +0 -1
  174. package/dist/infra/lib/memory/KnowledgeGraph.test.js +0 -189
  175. package/dist/infra/lib/memory/KnowledgeGraph.test.js.map +0 -1
  176. package/dist/infra/lib/memory/MemorySearch.test.d.ts +0 -2
  177. package/dist/infra/lib/memory/MemorySearch.test.d.ts.map +0 -1
  178. package/dist/infra/lib/memory/MemorySearch.test.js +0 -149
  179. package/dist/infra/lib/memory/MemorySearch.test.js.map +0 -1
  180. package/dist/infra/lib/memory/MemoryStorage.test.d.ts +0 -2
  181. package/dist/infra/lib/memory/MemoryStorage.test.d.ts.map +0 -1
  182. package/dist/infra/lib/memory/MemoryStorage.test.js +0 -198
  183. package/dist/infra/lib/memory/MemoryStorage.test.js.map +0 -1
  184. package/dist/infra/lib/memory/SessionRAGRetriever.test.d.ts +0 -2
  185. package/dist/infra/lib/memory/SessionRAGRetriever.test.d.ts.map +0 -1
  186. package/dist/infra/lib/memory/SessionRAGRetriever.test.js +0 -180
  187. package/dist/infra/lib/memory/SessionRAGRetriever.test.js.map +0 -1
  188. package/dist/infra/lib/memory/SessionRAGStore.test.d.ts +0 -2
  189. package/dist/infra/lib/memory/SessionRAGStore.test.d.ts.map +0 -1
  190. package/dist/infra/lib/memory/SessionRAGStore.test.js +0 -326
  191. package/dist/infra/lib/memory/SessionRAGStore.test.js.map +0 -1
  192. package/dist/infra/lib/memory/__tests__/InMemoryStorage.test.d.ts +0 -2
  193. package/dist/infra/lib/memory/__tests__/InMemoryStorage.test.d.ts.map +0 -1
  194. package/dist/infra/lib/memory/__tests__/InMemoryStorage.test.js +0 -114
  195. package/dist/infra/lib/memory/__tests__/InMemoryStorage.test.js.map +0 -1
  196. package/dist/infra/lib/memory/__tests__/ReflectionStore.test.d.ts +0 -2
  197. package/dist/infra/lib/memory/__tests__/ReflectionStore.test.d.ts.map +0 -1
  198. package/dist/infra/lib/memory/__tests__/ReflectionStore.test.js +0 -196
  199. package/dist/infra/lib/memory/__tests__/ReflectionStore.test.js.map +0 -1
  200. package/dist/infra/lib/memory/index.test.d.ts +0 -2
  201. package/dist/infra/lib/memory/index.test.d.ts.map +0 -1
  202. package/dist/infra/lib/memory/index.test.js +0 -23
  203. package/dist/infra/lib/memory/index.test.js.map +0 -1
  204. package/dist/infra/lib/telemetry/SkillTelemetry.test.d.ts +0 -2
  205. package/dist/infra/lib/telemetry/SkillTelemetry.test.d.ts.map +0 -1
  206. package/dist/infra/lib/telemetry/SkillTelemetry.test.js +0 -124
  207. package/dist/infra/lib/telemetry/SkillTelemetry.test.js.map +0 -1
  208. package/dist/infra/lib/ui-ux/Bm25Engine.test.d.ts +0 -2
  209. package/dist/infra/lib/ui-ux/Bm25Engine.test.d.ts.map +0 -1
  210. package/dist/infra/lib/ui-ux/Bm25Engine.test.js +0 -159
  211. package/dist/infra/lib/ui-ux/Bm25Engine.test.js.map +0 -1
  212. package/dist/infra/lib/ui-ux/CsvDataLoader.test.d.ts +0 -2
  213. package/dist/infra/lib/ui-ux/CsvDataLoader.test.d.ts.map +0 -1
  214. package/dist/infra/lib/ui-ux/CsvDataLoader.test.js +0 -141
  215. package/dist/infra/lib/ui-ux/CsvDataLoader.test.js.map +0 -1
  216. package/dist/infra/lib/ui-ux/DesignSystemGenerator.test.d.ts +0 -2
  217. package/dist/infra/lib/ui-ux/DesignSystemGenerator.test.d.ts.map +0 -1
  218. package/dist/infra/lib/ui-ux/DesignSystemGenerator.test.js +0 -370
  219. package/dist/infra/lib/ui-ux/DesignSystemGenerator.test.js.map +0 -1
  220. package/dist/infra/lib/ui-ux/SearchService.test.d.ts +0 -2
  221. package/dist/infra/lib/ui-ux/SearchService.test.d.ts.map +0 -1
  222. package/dist/infra/lib/ui-ux/SearchService.test.js +0 -215
  223. package/dist/infra/lib/ui-ux/SearchService.test.js.map +0 -1
  224. package/dist/test-helpers/index.d.ts +0 -36
  225. package/dist/test-helpers/index.d.ts.map +0 -1
  226. package/dist/test-helpers/index.js +0 -85
  227. package/dist/test-helpers/index.js.map +0 -1
  228. package/dist/test-helpers/index.test.d.ts +0 -2
  229. package/dist/test-helpers/index.test.d.ts.map +0 -1
  230. package/dist/test-helpers/index.test.js +0 -92
  231. package/dist/test-helpers/index.test.js.map +0 -1
  232. package/dist/tests/curated-release-notes.test.d.ts +0 -2
  233. package/dist/tests/curated-release-notes.test.d.ts.map +0 -1
  234. package/dist/tests/curated-release-notes.test.js +0 -160
  235. package/dist/tests/curated-release-notes.test.js.map +0 -1
  236. package/dist/tools/convention/analyzeComplexity.test.d.ts +0 -2
  237. package/dist/tools/convention/analyzeComplexity.test.d.ts.map +0 -1
  238. package/dist/tools/convention/analyzeComplexity.test.js +0 -207
  239. package/dist/tools/convention/analyzeComplexity.test.js.map +0 -1
  240. package/dist/tools/convention/validateCodeQuality.test.d.ts +0 -2
  241. package/dist/tools/convention/validateCodeQuality.test.d.ts.map +0 -1
  242. package/dist/tools/convention/validateCodeQuality.test.js +0 -230
  243. package/dist/tools/convention/validateCodeQuality.test.js.map +0 -1
  244. package/dist/tools/loop/validateLoopDefinition.test.d.ts +0 -14
  245. package/dist/tools/loop/validateLoopDefinition.test.d.ts.map +0 -1
  246. package/dist/tools/loop/validateLoopDefinition.test.js +0 -229
  247. package/dist/tools/loop/validateLoopDefinition.test.js.map +0 -1
  248. package/dist/tools/spec/executionPacket.test.d.ts +0 -2
  249. package/dist/tools/spec/executionPacket.test.d.ts.map +0 -1
  250. package/dist/tools/spec/executionPacket.test.js +0 -374
  251. package/dist/tools/spec/executionPacket.test.js.map +0 -1
  252. package/dist/tools/spec/prdParser.test.d.ts +0 -6
  253. package/dist/tools/spec/prdParser.test.d.ts.map +0 -1
  254. package/dist/tools/spec/prdParser.test.js +0 -332
  255. package/dist/tools/spec/prdParser.test.js.map +0 -1
  256. package/dist/tools/spec/specGenerator.test.d.ts +0 -2
  257. package/dist/tools/spec/specGenerator.test.d.ts.map +0 -1
  258. package/dist/tools/spec/specGenerator.test.js +0 -130
  259. package/dist/tools/spec/specGenerator.test.js.map +0 -1
  260. package/dist/tools/spec/traceabilityMatrix.path-resolution.test.d.ts +0 -10
  261. package/dist/tools/spec/traceabilityMatrix.path-resolution.test.d.ts.map +0 -1
  262. package/dist/tools/spec/traceabilityMatrix.path-resolution.test.js +0 -120
  263. package/dist/tools/spec/traceabilityMatrix.path-resolution.test.js.map +0 -1
  264. package/dist/tools/spec/traceabilityMatrix.test.d.ts +0 -6
  265. package/dist/tools/spec/traceabilityMatrix.test.d.ts.map +0 -1
  266. package/dist/tools/spec/traceabilityMatrix.test.js +0 -359
  267. package/dist/tools/spec/traceabilityMatrix.test.js.map +0 -1
  268. package/hooks/scripts/__tests__/.vibe/command-log.txt +0 -3
  269. package/hooks/scripts/__tests__/anchor-inbox.test.js +0 -119
  270. package/hooks/scripts/__tests__/auto-test-debounce.test.js +0 -145
  271. package/hooks/scripts/__tests__/clone-behaviors.test.js +0 -152
  272. package/hooks/scripts/__tests__/clone-merge-responsive.test.js +0 -106
  273. package/hooks/scripts/__tests__/code-check-detectors.test.js +0 -213
  274. package/hooks/scripts/__tests__/code-check-false-positive.test.js +0 -74
  275. package/hooks/scripts/__tests__/code-check-memory-write.test.js +0 -81
  276. package/hooks/scripts/__tests__/codex-hook-adapter.test.js +0 -64
  277. package/hooks/scripts/__tests__/curation-index.test.js +0 -157
  278. package/hooks/scripts/__tests__/dispatcher-inprocess.test.js +0 -99
  279. package/hooks/scripts/__tests__/figma-extract.test.js +0 -338
  280. package/hooks/scripts/__tests__/fixtures/seq-harness.js +0 -13
  281. package/hooks/scripts/__tests__/fixtures/seq-step.js +0 -22
  282. package/hooks/scripts/__tests__/hook-payload.test.js +0 -29
  283. package/hooks/scripts/__tests__/llm-orchestrate-antigravity.test.js +0 -66
  284. package/hooks/scripts/__tests__/loop-ledger.test.js +0 -321
  285. package/hooks/scripts/__tests__/post-edit-dispatcher.test.js +0 -139
  286. package/hooks/scripts/__tests__/pre-tool-guard.test.js +0 -523
  287. package/hooks/scripts/__tests__/recipe-extractor.test.js +0 -244
  288. package/hooks/scripts/__tests__/run-ledger-verify-required.test.js +0 -151
  289. package/hooks/scripts/__tests__/run-ledger.test.js +0 -481
  290. package/hooks/scripts/__tests__/scope-from-spec.test.js +0 -215
  291. package/hooks/scripts/__tests__/sentinel-guard.test.js +0 -263
  292. package/hooks/scripts/__tests__/step-counter.test.js +0 -459
  293. package/hooks/scripts/__tests__/stop-dispatcher-sequential.test.js +0 -74
  294. package/hooks/scripts/__tests__/utils-npm-root.test.js +0 -99
@@ -1,215 +0,0 @@
1
- /**
2
- * scope-from-spec.js 단위 테스트
3
- *
4
- * REQ-harness-remediation-009: scope-guard 기본 활성화
5
- * - enabled 미설정(undefined) → sync 실행 (기본 ON)
6
- * - enabled === false → skip (명시적 opt-out)
7
- * - SPEC 없음 → scope.json 생성 안 함 (노이즈 가드)
8
- */
9
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
10
- import fs from 'fs';
11
- import path from 'path';
12
- import os from 'os';
13
- import { isScopeGuardEnabled, syncScopeFile, findActiveSpecs } from '../lib/scope-from-spec.js';
14
-
15
- // 임시 프로젝트 디렉토리 헬퍼
16
- function makeTempDir() {
17
- return fs.mkdtempSync(path.join(os.tmpdir(), 'vibe-scope-test-'));
18
- }
19
-
20
- function cleanDir(dir) {
21
- try { fs.rmSync(dir, { recursive: true, force: true }); } catch { /* ignore */ }
22
- }
23
-
24
- // config.json 작성 헬퍼
25
- function writeConfig(dir, scopeGuard) {
26
- const vibeDir = path.join(dir, '.vibe');
27
- fs.mkdirSync(vibeDir, { recursive: true });
28
- fs.writeFileSync(path.join(vibeDir, 'config.json'), JSON.stringify({ scopeGuard }));
29
- }
30
-
31
- // 최소 SPEC 작성 헬퍼
32
- function writeSpec(dir, filename, content, status = 'in-progress') {
33
- const specsDir = path.join(dir, '.vibe', 'specs');
34
- fs.mkdirSync(specsDir, { recursive: true });
35
- const frontmatter = status ? `---\nstatus: ${status}\n---\n` : '';
36
- fs.writeFileSync(path.join(specsDir, filename), frontmatter + (content || ''));
37
- }
38
-
39
- // ══════════════════════════════════════════════════
40
- // isScopeGuardEnabled — 기본 OFF (opt-in), CLI isScopeGuardOptedIn 과 동일 기본값
41
- // ══════════════════════════════════════════════════
42
- describe('isScopeGuardEnabled', () => {
43
- let tmpDir;
44
- beforeEach(() => { tmpDir = makeTempDir(); });
45
- afterEach(() => { cleanDir(tmpDir); });
46
-
47
- it('config 없음 → false (기본 OFF)', () => {
48
- expect(isScopeGuardEnabled(tmpDir)).toBe(false);
49
- });
50
-
51
- it('scopeGuard 키 없는 config → false', () => {
52
- writeConfig(tmpDir, undefined);
53
- expect(isScopeGuardEnabled(tmpDir)).toBe(false);
54
- });
55
-
56
- it('scopeGuard.enabled 없는 config → false', () => {
57
- const vibeDir = path.join(tmpDir, '.vibe');
58
- fs.mkdirSync(vibeDir, { recursive: true });
59
- fs.writeFileSync(path.join(vibeDir, 'config.json'), JSON.stringify({ scopeGuard: {} }));
60
- expect(isScopeGuardEnabled(tmpDir)).toBe(false);
61
- });
62
-
63
- it('scopeGuard.enabled=true → true (명시적 opt-in)', () => {
64
- writeConfig(tmpDir, { enabled: true });
65
- expect(isScopeGuardEnabled(tmpDir)).toBe(true);
66
- });
67
-
68
- it('scopeGuard.enabled=false → false', () => {
69
- writeConfig(tmpDir, { enabled: false });
70
- expect(isScopeGuardEnabled(tmpDir)).toBe(false);
71
- });
72
-
73
- it('legacy .claude/vibe/config.json에서도 enabled=true 인식', () => {
74
- const legacyDir = path.join(tmpDir, '.claude', 'vibe');
75
- fs.mkdirSync(legacyDir, { recursive: true });
76
- fs.writeFileSync(path.join(legacyDir, 'config.json'), JSON.stringify({ scopeGuard: { enabled: true } }));
77
- expect(isScopeGuardEnabled(tmpDir)).toBe(true);
78
- });
79
- });
80
-
81
- // ══════════════════════════════════════════════════
82
- // syncScopeFile — 노이즈 가드: SPEC 없으면 생성 안 함
83
- // ══════════════════════════════════════════════════
84
- describe('syncScopeFile — no specs → no scope created', () => {
85
- let tmpDir;
86
- beforeEach(() => { tmpDir = makeTempDir(); });
87
- afterEach(() => { cleanDir(tmpDir); });
88
-
89
- it('SPEC 없음 → skipped-no-specs, scope.json 미생성', () => {
90
- fs.mkdirSync(path.join(tmpDir, '.vibe'), { recursive: true });
91
- const result = syncScopeFile(tmpDir);
92
- expect(result.action).toBe('skipped-no-specs');
93
- expect(fs.existsSync(path.join(tmpDir, '.vibe', 'scope.json'))).toBe(false);
94
- });
95
-
96
- it('specs 디렉토리 없음 → skipped-no-specs', () => {
97
- const result = syncScopeFile(tmpDir);
98
- expect(result.action).toBe('skipped-no-specs');
99
- });
100
- });
101
-
102
- // ══════════════════════════════════════════════════
103
- // syncScopeFile — SPEC 있을 때 sync 실행
104
- // ══════════════════════════════════════════════════
105
- describe('syncScopeFile — spec exists → scope created', () => {
106
- let tmpDir;
107
- beforeEach(() => { tmpDir = makeTempDir(); });
108
- afterEach(() => { cleanDir(tmpDir); });
109
-
110
- // 파생 glob은 실존 디렉토리만 통과하므로, 참조 경로를 실제로 만들어 준다
111
- function materialize(dir, relFile) {
112
- const full = path.join(dir, relFile);
113
- fs.mkdirSync(path.dirname(full), { recursive: true });
114
- fs.writeFileSync(full, '');
115
- }
116
-
117
- it('활성 SPEC 있음 → scope.json 생성', () => {
118
- writeSpec(tmpDir, 'feature.md', 'edit `src/cli/index.ts`');
119
- materialize(tmpDir, 'src/cli/index.ts');
120
- const result = syncScopeFile(tmpDir);
121
- expect(result.action).toBe('created');
122
- const scopeJson = path.join(tmpDir, '.vibe', 'scope.json');
123
- expect(fs.existsSync(scopeJson)).toBe(true);
124
- const scope = JSON.parse(fs.readFileSync(scopeJson, 'utf-8'));
125
- expect(scope.auto).toBe(true);
126
- expect(Array.isArray(scope.allow)).toBe(true);
127
- });
128
-
129
- it('status 없는 최근 SPEC은 활성 간주 → scope.json 생성', () => {
130
- writeSpec(tmpDir, 'no-status.md', 'modify `hooks/scripts/foo.js`', null);
131
- materialize(tmpDir, 'hooks/scripts/foo.js');
132
- const result = syncScopeFile(tmpDir);
133
- expect(result.action).toBe('created');
134
- });
135
-
136
- it('status 없는 오래된 SPEC(>14일)은 비활성 → skipped-no-specs', () => {
137
- writeSpec(tmpDir, 'stale.md', 'modify `hooks/scripts/foo.js`', null);
138
- materialize(tmpDir, 'hooks/scripts/foo.js');
139
- const old = new Date(Date.now() - 15 * 24 * 60 * 60 * 1000);
140
- fs.utimesSync(path.join(tmpDir, '.vibe', 'specs', 'stale.md'), old, old);
141
- const result = syncScopeFile(tmpDir);
142
- expect(result.action).toBe('skipped-no-specs');
143
- });
144
-
145
- it('활성 SPEC에 산출 가능한 경로 없음 → skipped-no-paths, scope.json 미생성', () => {
146
- writeSpec(tmpDir, 'no-paths.md', 'just prose, `nonexistent/dir/file` reference only');
147
- const result = syncScopeFile(tmpDir);
148
- expect(result.action).toBe('skipped-no-paths');
149
- expect(fs.existsSync(path.join(tmpDir, '.vibe', 'scope.json'))).toBe(false);
150
- });
151
-
152
- it('경로 산출 불가로 전환되면 기존 auto scope.json 제거', () => {
153
- writeSpec(tmpDir, 'feature.md', 'edit `src/cli/index.ts`');
154
- materialize(tmpDir, 'src/cli/index.ts');
155
- syncScopeFile(tmpDir); // 생성
156
- fs.rmSync(path.join(tmpDir, 'src'), { recursive: true, force: true });
157
- const result = syncScopeFile(tmpDir);
158
- expect(result.action).toBe('removed');
159
- expect(fs.existsSync(path.join(tmpDir, '.vibe', 'scope.json'))).toBe(false);
160
- });
161
-
162
- it('completed SPEC만 있을 때 → skipped-no-specs (비활성 SPEC은 제외)', () => {
163
- writeSpec(tmpDir, 'done.md', 'edit `src/foo.ts`', 'completed');
164
- const result = syncScopeFile(tmpDir);
165
- expect(result.action).toBe('skipped-no-specs');
166
- });
167
-
168
- it('수동 관리 scope.json(auto:false) → 건드리지 않음', () => {
169
- writeSpec(tmpDir, 'feature.md', 'edit `src/bar.ts`');
170
- const scopeDir = path.join(tmpDir, '.vibe');
171
- fs.mkdirSync(scopeDir, { recursive: true });
172
- const manual = { auto: false, mode: 'block', allow: ['src/**'], deny: [] };
173
- fs.writeFileSync(path.join(scopeDir, 'scope.json'), JSON.stringify(manual));
174
- const result = syncScopeFile(tmpDir);
175
- expect(result.action).toBe('skipped-manual');
176
- const existing = JSON.parse(fs.readFileSync(path.join(scopeDir, 'scope.json'), 'utf-8'));
177
- expect(existing.mode).toBe('block'); // 원본 유지
178
- });
179
-
180
- it('활성 SPEC 제거 후 재호출 → auto scope.json 삭제', () => {
181
- writeSpec(tmpDir, 'feature.md', 'edit `src/cli/index.ts`');
182
- materialize(tmpDir, 'src/cli/index.ts');
183
- syncScopeFile(tmpDir); // 생성
184
- // specs 디렉토리 비우기
185
- fs.rmSync(path.join(tmpDir, '.vibe', 'specs'), { recursive: true, force: true });
186
- const result = syncScopeFile(tmpDir);
187
- expect(result.action).toBe('removed');
188
- expect(fs.existsSync(path.join(tmpDir, '.vibe', 'scope.json'))).toBe(false);
189
- });
190
- });
191
-
192
- // ══════════════════════════════════════════════════
193
- // findActiveSpecs — legacy .claude/vibe/specs 폴백
194
- // ══════════════════════════════════════════════════
195
- describe('findActiveSpecs — resolution order', () => {
196
- let tmpDir;
197
- beforeEach(() => { tmpDir = makeTempDir(); });
198
- afterEach(() => { cleanDir(tmpDir); });
199
-
200
- it('.vibe/specs 우선', () => {
201
- writeSpec(tmpDir, 'main.md', 'content');
202
- const specs = findActiveSpecs(tmpDir);
203
- expect(specs.length).toBe(1);
204
- expect(specs[0]).toContain('.vibe');
205
- });
206
-
207
- it('.vibe 없고 .claude/vibe/specs 있으면 legacy 사용', () => {
208
- const legacySpecsDir = path.join(tmpDir, '.claude', 'vibe', 'specs');
209
- fs.mkdirSync(legacySpecsDir, { recursive: true });
210
- fs.writeFileSync(path.join(legacySpecsDir, 'old.md'), '---\nstatus: in-progress\n---\ncontent');
211
- const specs = findActiveSpecs(tmpDir);
212
- expect(specs.length).toBe(1);
213
- expect(specs[0]).toContain('.claude');
214
- });
215
- });
@@ -1,263 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { execFileSync, execSync } from 'child_process';
3
- import path from 'path';
4
- import { fileURLToPath } from 'url';
5
-
6
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
- const SCRIPT = path.resolve(__dirname, '..', 'sentinel-guard.js');
8
-
9
- /**
10
- * Run sentinel-guard.js with argv arguments.
11
- * Returns { stdout, exitCode }.
12
- */
13
- function runGuard(args = []) {
14
- try {
15
- const stdout = execFileSync('node', [SCRIPT, ...args], {
16
- encoding: 'utf-8',
17
- timeout: 5000,
18
- });
19
- return { stdout: stdout.trim(), exitCode: 0 };
20
- } catch (err) {
21
- return { stdout: (err.stdout || '').trim(), exitCode: err.status };
22
- }
23
- }
24
-
25
- /**
26
- * Run sentinel-guard.js with stdin JSON payload.
27
- */
28
- function runGuardWithStdin(payload) {
29
- const json = typeof payload === 'string' ? payload : JSON.stringify(payload);
30
- try {
31
- const stdout = execFileSync('node', [SCRIPT], {
32
- input: json,
33
- encoding: 'utf-8',
34
- timeout: 5000,
35
- });
36
- return { stdout: stdout.trim(), exitCode: 0 };
37
- } catch (err) {
38
- return { stdout: (err.stdout || '').trim(), exitCode: err.status };
39
- }
40
- }
41
-
42
- // ══════════════════════════════════════════════════
43
- // Sentinel path protection — evolution machinery
44
- // ══════════════════════════════════════════════════
45
- describe('sentinel-guard', () => {
46
- // ─── 실제 보호 경로: src/infra/lib/evolution/ ───
47
- describe('Write/Edit to evolution sentinel path via argv', () => {
48
- it('should block Write to src/infra/lib/evolution/', () => {
49
- const result = runGuard([
50
- 'Write',
51
- JSON.stringify({ file_path: 'src/infra/lib/evolution/EvolutionOrchestrator.ts' }),
52
- ]);
53
- expect(result.exitCode).toBe(2);
54
- expect(result.stdout).toContain('block');
55
- expect(result.stdout).toContain('Sentinel files are protected');
56
- });
57
-
58
- it('should block Edit to evolution sentinel path', () => {
59
- const result = runGuard([
60
- 'Edit',
61
- JSON.stringify({ file_path: 'src/infra/lib/evolution/GuardAnalyzer.ts' }),
62
- ]);
63
- expect(result.exitCode).toBe(2);
64
- expect(result.stdout).toContain('block');
65
- });
66
-
67
- it('should block Write with backslash path separators', () => {
68
- const result = runGuard([
69
- 'Write',
70
- JSON.stringify({ file_path: 'src\\infra\\lib\\evolution\\file.ts' }),
71
- ]);
72
- expect(result.exitCode).toBe(2);
73
- expect(result.stdout).toContain('Sentinel files are protected');
74
- });
75
-
76
- it('should block Write with ./ prefix', () => {
77
- const result = runGuard([
78
- 'Write',
79
- JSON.stringify({ file_path: './src/infra/lib/evolution/index.ts' }),
80
- ]);
81
- expect(result.exitCode).toBe(2);
82
- });
83
- });
84
-
85
- // ─── 실제 보호 경로: hooks/scripts/lib/ ───
86
- describe('Write/Edit to hooks/scripts/lib/ sentinel path', () => {
87
- it('should block Write to hooks/scripts/lib/', () => {
88
- const result = runGuard([
89
- 'Write',
90
- JSON.stringify({ file_path: 'hooks/scripts/lib/dispatcher.js' }),
91
- ]);
92
- expect(result.exitCode).toBe(2);
93
- expect(result.stdout).toContain('Sentinel files are protected');
94
- });
95
-
96
- it('should block Edit to hook-context.js', () => {
97
- const result = runGuard([
98
- 'Edit',
99
- JSON.stringify({ file_path: 'hooks/scripts/lib/hook-context.js' }),
100
- ]);
101
- expect(result.exitCode).toBe(2);
102
- });
103
- });
104
-
105
- // ─── stdin 경로 ───
106
- describe('Write/Edit to sentinel paths via stdin', () => {
107
- it('should block Edit evolution path via stdin payload', () => {
108
- const result = runGuardWithStdin({
109
- tool_name: 'Edit',
110
- tool_input: { file_path: './src/infra/lib/evolution/InsightStore.ts' },
111
- });
112
- expect(result.exitCode).toBe(2);
113
- expect(result.stdout).toContain('block');
114
- });
115
-
116
- it('should block Write evolution path via stdin payload', () => {
117
- const result = runGuardWithStdin({
118
- tool_name: 'Write',
119
- tool_input: { file_path: 'src/infra/lib/evolution/CircuitBreaker.ts' },
120
- });
121
- expect(result.exitCode).toBe(2);
122
- expect(result.stdout).toContain('Sentinel files are protected');
123
- });
124
-
125
- it('should block Write hooks/scripts/lib/ path via stdin', () => {
126
- const result = runGuardWithStdin({
127
- tool_name: 'Write',
128
- tool_input: { file_path: 'hooks/scripts/lib/run-ledger.js' },
129
- });
130
- expect(result.exitCode).toBe(2);
131
- });
132
- });
133
-
134
- // ─── 허용 경로 ───
135
- describe('allowed operations', () => {
136
- it('should allow Write to non-sentinel paths', () => {
137
- const result = runGuard([
138
- 'Write',
139
- JSON.stringify({ file_path: 'src/cli/commands/init.ts' }),
140
- ]);
141
- expect(result.exitCode).toBe(0);
142
- });
143
-
144
- it('should allow Read to sentinel paths (read is not blocked)', () => {
145
- const result = runGuard([
146
- 'Read',
147
- JSON.stringify({ file_path: 'src/infra/lib/evolution/GuardAnalyzer.ts' }),
148
- ]);
149
- expect(result.exitCode).toBe(0);
150
- });
151
-
152
- it('should allow Bash commands that do not target sentinel paths', () => {
153
- const result = runGuard([
154
- 'Bash',
155
- JSON.stringify({ command: 'ls -la src/cli/' }),
156
- ]);
157
- expect(result.exitCode).toBe(0);
158
- });
159
-
160
- it('should allow Write to hooks/scripts/ top level (not lib/ subdir)', () => {
161
- const result = runGuard([
162
- 'Write',
163
- JSON.stringify({ file_path: 'hooks/scripts/step-counter.js' }),
164
- ]);
165
- expect(result.exitCode).toBe(0);
166
- });
167
-
168
- it('should allow Write to src/infra/lib/ parent (not evolution subdir)', () => {
169
- const result = runGuard([
170
- 'Write',
171
- JSON.stringify({ file_path: 'src/infra/lib/constants.ts' }),
172
- ]);
173
- expect(result.exitCode).toBe(0);
174
- });
175
- });
176
-
177
- // ─── 위험한 bash + sentinel 경로 ───
178
- describe('dangerous bash commands targeting sentinel paths', () => {
179
- it('should block rm -rf targeting evolution path', () => {
180
- const result = runGuard([
181
- 'Bash',
182
- JSON.stringify({ command: 'rm -rf src/infra/lib/evolution/' }),
183
- ]);
184
- expect(result.exitCode).toBe(2);
185
- expect(result.stdout).toContain('block');
186
- expect(result.stdout).toContain('Dangerous command targeting sentinel path');
187
- });
188
-
189
- it('should block rm -rf targeting hooks/scripts/lib/', () => {
190
- const result = runGuard([
191
- 'Bash',
192
- JSON.stringify({ command: 'rm -rf hooks/scripts/lib/' }),
193
- ]);
194
- expect(result.exitCode).toBe(2);
195
- });
196
-
197
- it('should allow rm -rf on non-sentinel paths', () => {
198
- const result = runGuard([
199
- 'Bash',
200
- JSON.stringify({ command: 'rm -rf dist/' }),
201
- ]);
202
- expect(result.exitCode).toBe(0);
203
- });
204
-
205
- it('should allow dangerous commands not targeting sentinel paths', () => {
206
- const result = runGuard([
207
- 'Bash',
208
- JSON.stringify({ command: 'rm -rf /tmp/junk' }),
209
- ]);
210
- expect(result.exitCode).toBe(0);
211
- });
212
- });
213
-
214
- // ─── Bash 명령어 문자열이 sentinel 경로로 시작하는 경우 ───
215
- describe('Bash command containing sentinel path in command string', () => {
216
- it('should block when command string itself starts with evolution sentinel path', () => {
217
- const result = runGuard([
218
- 'Bash',
219
- JSON.stringify({ command: 'src/infra/lib/evolution/run.sh' }),
220
- ]);
221
- expect(result.exitCode).toBe(2);
222
- expect(result.stdout).toContain('Sentinel files are protected');
223
- });
224
-
225
- it('should block when command string starts with hooks/scripts/lib/', () => {
226
- const result = runGuard([
227
- 'Bash',
228
- JSON.stringify({ command: 'hooks/scripts/lib/dispatcher.js' }),
229
- ]);
230
- expect(result.exitCode).toBe(2);
231
- });
232
-
233
- it('should not block non-dangerous commands referencing sentinel path mid-string', () => {
234
- const result = runGuard([
235
- 'Bash',
236
- JSON.stringify({ command: 'cat src/infra/lib/evolution/GuardAnalyzer.ts | wc -l' }),
237
- ]);
238
- // 'cat' is not a dangerous command, command does not start with sentinel path
239
- expect(result.exitCode).toBe(0);
240
- });
241
- });
242
-
243
- // ─── stdin vs argv 우선순위 ───
244
- describe('stdin vs argv priority', () => {
245
- it('should prefer stdin payload over argv', () => {
246
- const payload = JSON.stringify({
247
- tool_name: 'Write',
248
- tool_input: { file_path: 'src/infra/lib/evolution/x.ts' },
249
- });
250
- try {
251
- execFileSync('node', [SCRIPT, 'Read', '{}'], {
252
- input: payload,
253
- encoding: 'utf-8',
254
- timeout: 5000,
255
- });
256
- expect.unreachable('should have exited with code 2');
257
- } catch (err) {
258
- expect(err.status).toBe(2);
259
- expect(err.stdout).toContain('block');
260
- }
261
- });
262
- });
263
- });