@su-record/vibe 3.2.13 → 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 (305) hide show
  1. package/CLAUDE.md +15 -14
  2. package/README.en.md +1 -1
  3. package/README.md +1 -1
  4. package/dist/cli/setup/ProjectSetup.d.ts +6 -0
  5. package/dist/cli/setup/ProjectSetup.d.ts.map +1 -1
  6. package/dist/cli/setup/ProjectSetup.js +19 -13
  7. package/dist/cli/setup/ProjectSetup.js.map +1 -1
  8. package/dist/infra/lib/codex-proxy.d.ts +126 -0
  9. package/dist/infra/lib/codex-proxy.d.ts.map +1 -1
  10. package/dist/infra/lib/codex-proxy.js +16 -16
  11. package/dist/infra/lib/codex-proxy.js.map +1 -1
  12. package/dist/infra/lib/figma/audit.d.ts.map +1 -1
  13. package/dist/infra/lib/figma/audit.js +0 -2
  14. package/dist/infra/lib/figma/audit.js.map +1 -1
  15. package/dist/infra/lib/figma/extract.d.ts +6 -1
  16. package/dist/infra/lib/figma/extract.d.ts.map +1 -1
  17. package/dist/infra/lib/figma/extract.js +17 -15
  18. package/dist/infra/lib/figma/extract.js.map +1 -1
  19. package/dist/infra/lib/figma/types.d.ts +103 -0
  20. package/dist/infra/lib/figma/types.d.ts.map +1 -1
  21. package/dist/infra/lib/figma/types.js +8 -0
  22. package/dist/infra/lib/figma/types.js.map +1 -1
  23. package/hooks/hooks.json +1 -1
  24. package/hooks/scripts/clone-extract.js +16 -1
  25. package/hooks/scripts/code-check.js +72 -55
  26. package/hooks/scripts/lib/anchor.js +74 -0
  27. package/hooks/scripts/lib/console-allow.js +66 -0
  28. package/hooks/scripts/lib/dispatcher.js +71 -19
  29. package/hooks/scripts/lib/inbox.js +60 -0
  30. package/hooks/scripts/loop-ledger.js +24 -1
  31. package/hooks/scripts/post-edit-dispatcher.js +4 -3
  32. package/hooks/scripts/post-edit.js +2 -2
  33. package/package.json +13 -9
  34. package/skills/vibe/SKILL.md +2 -1
  35. package/skills/vibe.clone/references/verification-loops.md +6 -3
  36. package/skills/vibe.loop/SKILL.md +7 -4
  37. package/skills/vibe.review/SKILL.md +5 -1
  38. package/skills/vibe.run/references/e2e-and-autofix.md +1 -1
  39. package/skills/vibe.run/references/process-steps.md +1 -1
  40. package/vibe/constitution.md +1 -1
  41. package/vibe/rules/loop-contract.md +40 -3
  42. package/vibe/rules/quality/checklist.md +3 -3
  43. package/vibe/templates/constitution-template.md +1 -1
  44. package/dist/__tests__/agent-model-sync.test.d.ts +0 -2
  45. package/dist/__tests__/agent-model-sync.test.d.ts.map +0 -1
  46. package/dist/__tests__/agent-model-sync.test.js +0 -71
  47. package/dist/__tests__/agent-model-sync.test.js.map +0 -1
  48. package/dist/__tests__/architecture.test.d.ts +0 -2
  49. package/dist/__tests__/architecture.test.d.ts.map +0 -1
  50. package/dist/__tests__/architecture.test.js +0 -207
  51. package/dist/__tests__/architecture.test.js.map +0 -1
  52. package/dist/__tests__/skill-namespace.test.d.ts +0 -2
  53. package/dist/__tests__/skill-namespace.test.d.ts.map +0 -1
  54. package/dist/__tests__/skill-namespace.test.js +0 -60
  55. package/dist/__tests__/skill-namespace.test.js.map +0 -1
  56. package/dist/__tests__/stakes-contract.test.d.ts +0 -2
  57. package/dist/__tests__/stakes-contract.test.d.ts.map +0 -1
  58. package/dist/__tests__/stakes-contract.test.js +0 -166
  59. package/dist/__tests__/stakes-contract.test.js.map +0 -1
  60. package/dist/__tests__/stuck-semantics.test.d.ts +0 -2
  61. package/dist/__tests__/stuck-semantics.test.d.ts.map +0 -1
  62. package/dist/__tests__/stuck-semantics.test.js +0 -109
  63. package/dist/__tests__/stuck-semantics.test.js.map +0 -1
  64. package/dist/__tests__/wiring-integrity.test.d.ts +0 -2
  65. package/dist/__tests__/wiring-integrity.test.d.ts.map +0 -1
  66. package/dist/__tests__/wiring-integrity.test.js +0 -160
  67. package/dist/__tests__/wiring-integrity.test.js.map +0 -1
  68. package/dist/cli/commands/info.test.d.ts +0 -2
  69. package/dist/cli/commands/info.test.d.ts.map +0 -1
  70. package/dist/cli/commands/info.test.js +0 -74
  71. package/dist/cli/commands/info.test.js.map +0 -1
  72. package/dist/cli/commands/upgrade.test.d.ts +0 -2
  73. package/dist/cli/commands/upgrade.test.d.ts.map +0 -1
  74. package/dist/cli/commands/upgrade.test.js +0 -99
  75. package/dist/cli/commands/upgrade.test.js.map +0 -1
  76. package/dist/cli/design/design-md-parser.test.d.ts +0 -2
  77. package/dist/cli/design/design-md-parser.test.d.ts.map +0 -1
  78. package/dist/cli/design/design-md-parser.test.js +0 -149
  79. package/dist/cli/design/design-md-parser.test.js.map +0 -1
  80. package/dist/cli/detect.characterization.test.d.ts +0 -7
  81. package/dist/cli/detect.characterization.test.d.ts.map +0 -1
  82. package/dist/cli/detect.characterization.test.js +0 -294
  83. package/dist/cli/detect.characterization.test.js.map +0 -1
  84. package/dist/cli/postinstall/fs-utils.test.d.ts +0 -2
  85. package/dist/cli/postinstall/fs-utils.test.d.ts.map +0 -1
  86. package/dist/cli/postinstall/fs-utils.test.js +0 -259
  87. package/dist/cli/postinstall/fs-utils.test.js.map +0 -1
  88. package/dist/cli/setup/CodexHooks.test.d.ts +0 -2
  89. package/dist/cli/setup/CodexHooks.test.d.ts.map +0 -1
  90. package/dist/cli/setup/CodexHooks.test.js +0 -52
  91. package/dist/cli/setup/CodexHooks.test.js.map +0 -1
  92. package/dist/cli/setup/GlobalInstaller.test.d.ts +0 -2
  93. package/dist/cli/setup/GlobalInstaller.test.d.ts.map +0 -1
  94. package/dist/cli/setup/GlobalInstaller.test.js +0 -16
  95. package/dist/cli/setup/GlobalInstaller.test.js.map +0 -1
  96. package/dist/cli/utils/cli-detector.test.d.ts +0 -2
  97. package/dist/cli/utils/cli-detector.test.d.ts.map +0 -1
  98. package/dist/cli/utils/cli-detector.test.js +0 -52
  99. package/dist/cli/utils/cli-detector.test.js.map +0 -1
  100. package/dist/infra/lib/SkillFrontmatter.test.d.ts +0 -2
  101. package/dist/infra/lib/SkillFrontmatter.test.d.ts.map +0 -1
  102. package/dist/infra/lib/SkillFrontmatter.test.js +0 -60
  103. package/dist/infra/lib/SkillFrontmatter.test.js.map +0 -1
  104. package/dist/infra/lib/__tests__/AutomationLevel.test.d.ts +0 -2
  105. package/dist/infra/lib/__tests__/AutomationLevel.test.d.ts.map +0 -1
  106. package/dist/infra/lib/__tests__/AutomationLevel.test.js +0 -297
  107. package/dist/infra/lib/__tests__/AutomationLevel.test.js.map +0 -1
  108. package/dist/infra/lib/__tests__/ComponentRegistry.test.d.ts +0 -2
  109. package/dist/infra/lib/__tests__/ComponentRegistry.test.d.ts.map +0 -1
  110. package/dist/infra/lib/__tests__/ComponentRegistry.test.js +0 -99
  111. package/dist/infra/lib/__tests__/ComponentRegistry.test.js.map +0 -1
  112. package/dist/infra/lib/__tests__/DecisionTracer.test.d.ts +0 -2
  113. package/dist/infra/lib/__tests__/DecisionTracer.test.d.ts.map +0 -1
  114. package/dist/infra/lib/__tests__/DecisionTracer.test.js +0 -274
  115. package/dist/infra/lib/__tests__/DecisionTracer.test.js.map +0 -1
  116. package/dist/infra/lib/__tests__/InteractiveCheckpoint.test.d.ts +0 -2
  117. package/dist/infra/lib/__tests__/InteractiveCheckpoint.test.d.ts.map +0 -1
  118. package/dist/infra/lib/__tests__/InteractiveCheckpoint.test.js +0 -350
  119. package/dist/infra/lib/__tests__/InteractiveCheckpoint.test.js.map +0 -1
  120. package/dist/infra/lib/__tests__/LoopBreaker.test.d.ts +0 -2
  121. package/dist/infra/lib/__tests__/LoopBreaker.test.d.ts.map +0 -1
  122. package/dist/infra/lib/__tests__/LoopBreaker.test.js +0 -340
  123. package/dist/infra/lib/__tests__/LoopBreaker.test.js.map +0 -1
  124. package/dist/infra/lib/__tests__/VerificationLoop.test.d.ts +0 -2
  125. package/dist/infra/lib/__tests__/VerificationLoop.test.d.ts.map +0 -1
  126. package/dist/infra/lib/__tests__/VerificationLoop.test.js +0 -486
  127. package/dist/infra/lib/__tests__/VerificationLoop.test.js.map +0 -1
  128. package/dist/infra/lib/config/GlobalConfigManager.test.d.ts +0 -2
  129. package/dist/infra/lib/config/GlobalConfigManager.test.d.ts.map +0 -1
  130. package/dist/infra/lib/config/GlobalConfigManager.test.js +0 -9
  131. package/dist/infra/lib/config/GlobalConfigManager.test.js.map +0 -1
  132. package/dist/infra/lib/embedding/__tests__/EmbeddingProvider.test.d.ts +0 -2
  133. package/dist/infra/lib/embedding/__tests__/EmbeddingProvider.test.d.ts.map +0 -1
  134. package/dist/infra/lib/embedding/__tests__/EmbeddingProvider.test.js +0 -43
  135. package/dist/infra/lib/embedding/__tests__/EmbeddingProvider.test.js.map +0 -1
  136. package/dist/infra/lib/embedding/__tests__/VectorStore.test.d.ts +0 -2
  137. package/dist/infra/lib/embedding/__tests__/VectorStore.test.d.ts.map +0 -1
  138. package/dist/infra/lib/embedding/__tests__/VectorStore.test.js +0 -94
  139. package/dist/infra/lib/embedding/__tests__/VectorStore.test.js.map +0 -1
  140. package/dist/infra/lib/embedding/__tests__/cosine.test.d.ts +0 -2
  141. package/dist/infra/lib/embedding/__tests__/cosine.test.d.ts.map +0 -1
  142. package/dist/infra/lib/embedding/__tests__/cosine.test.js +0 -73
  143. package/dist/infra/lib/embedding/__tests__/cosine.test.js.map +0 -1
  144. package/dist/infra/lib/evolution/__tests__/deprecation.test.d.ts +0 -2
  145. package/dist/infra/lib/evolution/__tests__/deprecation.test.d.ts.map +0 -1
  146. package/dist/infra/lib/evolution/__tests__/deprecation.test.js +0 -251
  147. package/dist/infra/lib/evolution/__tests__/deprecation.test.js.map +0 -1
  148. package/dist/infra/lib/evolution/__tests__/eval.test.d.ts +0 -2
  149. package/dist/infra/lib/evolution/__tests__/eval.test.d.ts.map +0 -1
  150. package/dist/infra/lib/evolution/__tests__/eval.test.js +0 -603
  151. package/dist/infra/lib/evolution/__tests__/eval.test.js.map +0 -1
  152. package/dist/infra/lib/evolution/__tests__/generation.test.d.ts +0 -2
  153. package/dist/infra/lib/evolution/__tests__/generation.test.d.ts.map +0 -1
  154. package/dist/infra/lib/evolution/__tests__/generation.test.js +0 -396
  155. package/dist/infra/lib/evolution/__tests__/generation.test.js.map +0 -1
  156. package/dist/infra/lib/evolution/__tests__/insight.test.d.ts +0 -2
  157. package/dist/infra/lib/evolution/__tests__/insight.test.d.ts.map +0 -1
  158. package/dist/infra/lib/evolution/__tests__/insight.test.js +0 -204
  159. package/dist/infra/lib/evolution/__tests__/insight.test.js.map +0 -1
  160. package/dist/infra/lib/evolution/__tests__/integration.test.d.ts +0 -2
  161. package/dist/infra/lib/evolution/__tests__/integration.test.d.ts.map +0 -1
  162. package/dist/infra/lib/evolution/__tests__/integration.test.js +0 -206
  163. package/dist/infra/lib/evolution/__tests__/integration.test.js.map +0 -1
  164. package/dist/infra/lib/evolution/__tests__/lifecycle.test.d.ts +0 -2
  165. package/dist/infra/lib/evolution/__tests__/lifecycle.test.d.ts.map +0 -1
  166. package/dist/infra/lib/evolution/__tests__/lifecycle.test.js +0 -350
  167. package/dist/infra/lib/evolution/__tests__/lifecycle.test.js.map +0 -1
  168. package/dist/infra/lib/evolution/__tests__/parity.test.d.ts +0 -2
  169. package/dist/infra/lib/evolution/__tests__/parity.test.d.ts.map +0 -1
  170. package/dist/infra/lib/evolution/__tests__/parity.test.js +0 -319
  171. package/dist/infra/lib/evolution/__tests__/parity.test.js.map +0 -1
  172. package/dist/infra/lib/llm/auth/AuthProfileManager.test.d.ts +0 -5
  173. package/dist/infra/lib/llm/auth/AuthProfileManager.test.d.ts.map +0 -1
  174. package/dist/infra/lib/llm/auth/AuthProfileManager.test.js +0 -168
  175. package/dist/infra/lib/llm/auth/AuthProfileManager.test.js.map +0 -1
  176. package/dist/infra/lib/llm/auth/TokenRefresher.test.d.ts +0 -2
  177. package/dist/infra/lib/llm/auth/TokenRefresher.test.d.ts.map +0 -1
  178. package/dist/infra/lib/llm/auth/TokenRefresher.test.js +0 -120
  179. package/dist/infra/lib/llm/auth/TokenRefresher.test.js.map +0 -1
  180. package/dist/infra/lib/llm/timeout.test.d.ts +0 -2
  181. package/dist/infra/lib/llm/timeout.test.d.ts.map +0 -1
  182. package/dist/infra/lib/llm/timeout.test.js +0 -50
  183. package/dist/infra/lib/llm/timeout.test.js.map +0 -1
  184. package/dist/infra/lib/llm-availability.test.d.ts +0 -2
  185. package/dist/infra/lib/llm-availability.test.d.ts.map +0 -1
  186. package/dist/infra/lib/llm-availability.test.js +0 -37
  187. package/dist/infra/lib/llm-availability.test.js.map +0 -1
  188. package/dist/infra/lib/memory/KnowledgeGraph.test.d.ts +0 -2
  189. package/dist/infra/lib/memory/KnowledgeGraph.test.d.ts.map +0 -1
  190. package/dist/infra/lib/memory/KnowledgeGraph.test.js +0 -189
  191. package/dist/infra/lib/memory/KnowledgeGraph.test.js.map +0 -1
  192. package/dist/infra/lib/memory/MemorySearch.test.d.ts +0 -2
  193. package/dist/infra/lib/memory/MemorySearch.test.d.ts.map +0 -1
  194. package/dist/infra/lib/memory/MemorySearch.test.js +0 -149
  195. package/dist/infra/lib/memory/MemorySearch.test.js.map +0 -1
  196. package/dist/infra/lib/memory/MemoryStorage.test.d.ts +0 -2
  197. package/dist/infra/lib/memory/MemoryStorage.test.d.ts.map +0 -1
  198. package/dist/infra/lib/memory/MemoryStorage.test.js +0 -198
  199. package/dist/infra/lib/memory/MemoryStorage.test.js.map +0 -1
  200. package/dist/infra/lib/memory/SessionRAGRetriever.test.d.ts +0 -2
  201. package/dist/infra/lib/memory/SessionRAGRetriever.test.d.ts.map +0 -1
  202. package/dist/infra/lib/memory/SessionRAGRetriever.test.js +0 -180
  203. package/dist/infra/lib/memory/SessionRAGRetriever.test.js.map +0 -1
  204. package/dist/infra/lib/memory/SessionRAGStore.test.d.ts +0 -2
  205. package/dist/infra/lib/memory/SessionRAGStore.test.d.ts.map +0 -1
  206. package/dist/infra/lib/memory/SessionRAGStore.test.js +0 -326
  207. package/dist/infra/lib/memory/SessionRAGStore.test.js.map +0 -1
  208. package/dist/infra/lib/memory/__tests__/InMemoryStorage.test.d.ts +0 -2
  209. package/dist/infra/lib/memory/__tests__/InMemoryStorage.test.d.ts.map +0 -1
  210. package/dist/infra/lib/memory/__tests__/InMemoryStorage.test.js +0 -114
  211. package/dist/infra/lib/memory/__tests__/InMemoryStorage.test.js.map +0 -1
  212. package/dist/infra/lib/memory/__tests__/ReflectionStore.test.d.ts +0 -2
  213. package/dist/infra/lib/memory/__tests__/ReflectionStore.test.d.ts.map +0 -1
  214. package/dist/infra/lib/memory/__tests__/ReflectionStore.test.js +0 -196
  215. package/dist/infra/lib/memory/__tests__/ReflectionStore.test.js.map +0 -1
  216. package/dist/infra/lib/memory/index.test.d.ts +0 -2
  217. package/dist/infra/lib/memory/index.test.d.ts.map +0 -1
  218. package/dist/infra/lib/memory/index.test.js +0 -23
  219. package/dist/infra/lib/memory/index.test.js.map +0 -1
  220. package/dist/infra/lib/telemetry/SkillTelemetry.test.d.ts +0 -2
  221. package/dist/infra/lib/telemetry/SkillTelemetry.test.d.ts.map +0 -1
  222. package/dist/infra/lib/telemetry/SkillTelemetry.test.js +0 -124
  223. package/dist/infra/lib/telemetry/SkillTelemetry.test.js.map +0 -1
  224. package/dist/infra/lib/ui-ux/Bm25Engine.test.d.ts +0 -2
  225. package/dist/infra/lib/ui-ux/Bm25Engine.test.d.ts.map +0 -1
  226. package/dist/infra/lib/ui-ux/Bm25Engine.test.js +0 -159
  227. package/dist/infra/lib/ui-ux/Bm25Engine.test.js.map +0 -1
  228. package/dist/infra/lib/ui-ux/CsvDataLoader.test.d.ts +0 -2
  229. package/dist/infra/lib/ui-ux/CsvDataLoader.test.d.ts.map +0 -1
  230. package/dist/infra/lib/ui-ux/CsvDataLoader.test.js +0 -141
  231. package/dist/infra/lib/ui-ux/CsvDataLoader.test.js.map +0 -1
  232. package/dist/infra/lib/ui-ux/DesignSystemGenerator.test.d.ts +0 -2
  233. package/dist/infra/lib/ui-ux/DesignSystemGenerator.test.d.ts.map +0 -1
  234. package/dist/infra/lib/ui-ux/DesignSystemGenerator.test.js +0 -370
  235. package/dist/infra/lib/ui-ux/DesignSystemGenerator.test.js.map +0 -1
  236. package/dist/infra/lib/ui-ux/SearchService.test.d.ts +0 -2
  237. package/dist/infra/lib/ui-ux/SearchService.test.d.ts.map +0 -1
  238. package/dist/infra/lib/ui-ux/SearchService.test.js +0 -215
  239. package/dist/infra/lib/ui-ux/SearchService.test.js.map +0 -1
  240. package/dist/test-helpers/index.d.ts +0 -36
  241. package/dist/test-helpers/index.d.ts.map +0 -1
  242. package/dist/test-helpers/index.js +0 -85
  243. package/dist/test-helpers/index.js.map +0 -1
  244. package/dist/test-helpers/index.test.d.ts +0 -2
  245. package/dist/test-helpers/index.test.d.ts.map +0 -1
  246. package/dist/test-helpers/index.test.js +0 -92
  247. package/dist/test-helpers/index.test.js.map +0 -1
  248. package/dist/tests/curated-release-notes.test.d.ts +0 -2
  249. package/dist/tests/curated-release-notes.test.d.ts.map +0 -1
  250. package/dist/tests/curated-release-notes.test.js +0 -160
  251. package/dist/tests/curated-release-notes.test.js.map +0 -1
  252. package/dist/tools/convention/analyzeComplexity.test.d.ts +0 -2
  253. package/dist/tools/convention/analyzeComplexity.test.d.ts.map +0 -1
  254. package/dist/tools/convention/analyzeComplexity.test.js +0 -207
  255. package/dist/tools/convention/analyzeComplexity.test.js.map +0 -1
  256. package/dist/tools/convention/validateCodeQuality.test.d.ts +0 -2
  257. package/dist/tools/convention/validateCodeQuality.test.d.ts.map +0 -1
  258. package/dist/tools/convention/validateCodeQuality.test.js +0 -230
  259. package/dist/tools/convention/validateCodeQuality.test.js.map +0 -1
  260. package/dist/tools/loop/validateLoopDefinition.test.d.ts +0 -14
  261. package/dist/tools/loop/validateLoopDefinition.test.d.ts.map +0 -1
  262. package/dist/tools/loop/validateLoopDefinition.test.js +0 -229
  263. package/dist/tools/loop/validateLoopDefinition.test.js.map +0 -1
  264. package/dist/tools/spec/executionPacket.test.d.ts +0 -2
  265. package/dist/tools/spec/executionPacket.test.d.ts.map +0 -1
  266. package/dist/tools/spec/executionPacket.test.js +0 -374
  267. package/dist/tools/spec/executionPacket.test.js.map +0 -1
  268. package/dist/tools/spec/prdParser.test.d.ts +0 -6
  269. package/dist/tools/spec/prdParser.test.d.ts.map +0 -1
  270. package/dist/tools/spec/prdParser.test.js +0 -332
  271. package/dist/tools/spec/prdParser.test.js.map +0 -1
  272. package/dist/tools/spec/specGenerator.test.d.ts +0 -2
  273. package/dist/tools/spec/specGenerator.test.d.ts.map +0 -1
  274. package/dist/tools/spec/specGenerator.test.js +0 -130
  275. package/dist/tools/spec/specGenerator.test.js.map +0 -1
  276. package/dist/tools/spec/traceabilityMatrix.path-resolution.test.d.ts +0 -10
  277. package/dist/tools/spec/traceabilityMatrix.path-resolution.test.d.ts.map +0 -1
  278. package/dist/tools/spec/traceabilityMatrix.path-resolution.test.js +0 -120
  279. package/dist/tools/spec/traceabilityMatrix.path-resolution.test.js.map +0 -1
  280. package/dist/tools/spec/traceabilityMatrix.test.d.ts +0 -6
  281. package/dist/tools/spec/traceabilityMatrix.test.d.ts.map +0 -1
  282. package/dist/tools/spec/traceabilityMatrix.test.js +0 -359
  283. package/dist/tools/spec/traceabilityMatrix.test.js.map +0 -1
  284. package/hooks/scripts/__tests__/.vibe/command-log.txt +0 -3
  285. package/hooks/scripts/__tests__/auto-test-debounce.test.js +0 -145
  286. package/hooks/scripts/__tests__/clone-behaviors.test.js +0 -152
  287. package/hooks/scripts/__tests__/clone-merge-responsive.test.js +0 -106
  288. package/hooks/scripts/__tests__/code-check-detectors.test.js +0 -213
  289. package/hooks/scripts/__tests__/code-check-memory-write.test.js +0 -81
  290. package/hooks/scripts/__tests__/codex-hook-adapter.test.js +0 -64
  291. package/hooks/scripts/__tests__/curation-index.test.js +0 -157
  292. package/hooks/scripts/__tests__/dispatcher-inprocess.test.js +0 -99
  293. package/hooks/scripts/__tests__/figma-extract.test.js +0 -338
  294. package/hooks/scripts/__tests__/hook-payload.test.js +0 -29
  295. package/hooks/scripts/__tests__/llm-orchestrate-antigravity.test.js +0 -66
  296. package/hooks/scripts/__tests__/loop-ledger.test.js +0 -321
  297. package/hooks/scripts/__tests__/post-edit-dispatcher.test.js +0 -139
  298. package/hooks/scripts/__tests__/pre-tool-guard.test.js +0 -523
  299. package/hooks/scripts/__tests__/recipe-extractor.test.js +0 -244
  300. package/hooks/scripts/__tests__/run-ledger-verify-required.test.js +0 -151
  301. package/hooks/scripts/__tests__/run-ledger.test.js +0 -481
  302. package/hooks/scripts/__tests__/scope-from-spec.test.js +0 -215
  303. package/hooks/scripts/__tests__/sentinel-guard.test.js +0 -263
  304. package/hooks/scripts/__tests__/step-counter.test.js +0 -459
  305. 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
- });