@su-record/vibe 3.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (341) hide show
  1. package/hooks/scripts/__tests__/.vibe/command-log.txt +3 -78
  2. package/hooks/scripts/__tests__/.vibe/memories/memories.db +0 -0
  3. package/hooks/scripts/__tests__/.vibe/memories/memories.db-shm +0 -0
  4. package/hooks/scripts/__tests__/.vibe/memories/memories.db-wal +0 -0
  5. package/hooks/scripts/__tests__/clone-behaviors.test.js +64 -0
  6. package/hooks/scripts/__tests__/clone-merge-responsive.test.js +106 -0
  7. package/hooks/scripts/clone-extract.js +242 -28
  8. package/hooks/scripts/clone-merge-responsive.js +184 -0
  9. package/hooks/scripts/clone-spec.js +33 -8
  10. package/hooks/scripts/clone-validate.js +15 -9
  11. package/package.json +5 -2
  12. package/skills/clone/SKILL.md +132 -55
  13. package/skills/vibe.clone/SKILL.md +39 -19
  14. package/dist/cli/llm/gemini-commands.d.ts +0 -25
  15. package/dist/cli/llm/gemini-commands.d.ts.map +0 -1
  16. package/dist/cli/llm/gemini-commands.js +0 -143
  17. package/dist/cli/llm/gemini-commands.js.map +0 -1
  18. package/dist/cli/postinstall/codex-agents.d.ts +0 -24
  19. package/dist/cli/postinstall/codex-agents.d.ts.map +0 -1
  20. package/dist/cli/postinstall/codex-agents.js +0 -114
  21. package/dist/cli/postinstall/codex-agents.js.map +0 -1
  22. package/dist/cli/postinstall/codex-instruction.d.ts +0 -10
  23. package/dist/cli/postinstall/codex-instruction.d.ts.map +0 -1
  24. package/dist/cli/postinstall/codex-instruction.js +0 -56
  25. package/dist/cli/postinstall/codex-instruction.js.map +0 -1
  26. package/dist/cli/postinstall/gemini-agents.d.ts +0 -12
  27. package/dist/cli/postinstall/gemini-agents.d.ts.map +0 -1
  28. package/dist/cli/postinstall/gemini-agents.js +0 -80
  29. package/dist/cli/postinstall/gemini-agents.js.map +0 -1
  30. package/dist/cli/postinstall/gemini-instruction.d.ts +0 -10
  31. package/dist/cli/postinstall/gemini-instruction.d.ts.map +0 -1
  32. package/dist/cli/postinstall/gemini-instruction.js +0 -59
  33. package/dist/cli/postinstall/gemini-instruction.js.map +0 -1
  34. package/dist/infra/lib/ContextCompressor.d.ts +0 -104
  35. package/dist/infra/lib/ContextCompressor.d.ts.map +0 -1
  36. package/dist/infra/lib/ContextCompressor.js +0 -297
  37. package/dist/infra/lib/ContextCompressor.js.map +0 -1
  38. package/dist/infra/lib/ContextCompressor.test.d.ts +0 -2
  39. package/dist/infra/lib/ContextCompressor.test.d.ts.map +0 -1
  40. package/dist/infra/lib/ContextCompressor.test.js +0 -25
  41. package/dist/infra/lib/ContextCompressor.test.js.map +0 -1
  42. package/dist/infra/lib/ProgressTracker.d.ts +0 -73
  43. package/dist/infra/lib/ProgressTracker.d.ts.map +0 -1
  44. package/dist/infra/lib/ProgressTracker.js +0 -267
  45. package/dist/infra/lib/ProgressTracker.js.map +0 -1
  46. package/dist/infra/lib/TokenBudgetTracker.d.ts +0 -68
  47. package/dist/infra/lib/TokenBudgetTracker.d.ts.map +0 -1
  48. package/dist/infra/lib/TokenBudgetTracker.js +0 -191
  49. package/dist/infra/lib/TokenBudgetTracker.js.map +0 -1
  50. package/dist/infra/lib/autonomy/AuditStore.d.ts +0 -63
  51. package/dist/infra/lib/autonomy/AuditStore.d.ts.map +0 -1
  52. package/dist/infra/lib/autonomy/AuditStore.js +0 -185
  53. package/dist/infra/lib/autonomy/AuditStore.js.map +0 -1
  54. package/dist/infra/lib/autonomy/AutonomyConfig.d.ts +0 -84
  55. package/dist/infra/lib/autonomy/AutonomyConfig.d.ts.map +0 -1
  56. package/dist/infra/lib/autonomy/AutonomyConfig.js +0 -49
  57. package/dist/infra/lib/autonomy/AutonomyConfig.js.map +0 -1
  58. package/dist/infra/lib/autonomy/AutonomyOrchestrator.d.ts +0 -78
  59. package/dist/infra/lib/autonomy/AutonomyOrchestrator.d.ts.map +0 -1
  60. package/dist/infra/lib/autonomy/AutonomyOrchestrator.js +0 -246
  61. package/dist/infra/lib/autonomy/AutonomyOrchestrator.js.map +0 -1
  62. package/dist/infra/lib/autonomy/BackgroundMonitor.d.ts +0 -36
  63. package/dist/infra/lib/autonomy/BackgroundMonitor.d.ts.map +0 -1
  64. package/dist/infra/lib/autonomy/BackgroundMonitor.js +0 -138
  65. package/dist/infra/lib/autonomy/BackgroundMonitor.js.map +0 -1
  66. package/dist/infra/lib/autonomy/CollaborationProtocol.d.ts +0 -56
  67. package/dist/infra/lib/autonomy/CollaborationProtocol.d.ts.map +0 -1
  68. package/dist/infra/lib/autonomy/CollaborationProtocol.js +0 -122
  69. package/dist/infra/lib/autonomy/CollaborationProtocol.js.map +0 -1
  70. package/dist/infra/lib/autonomy/ConfirmationManager.d.ts +0 -42
  71. package/dist/infra/lib/autonomy/ConfirmationManager.d.ts.map +0 -1
  72. package/dist/infra/lib/autonomy/ConfirmationManager.js +0 -200
  73. package/dist/infra/lib/autonomy/ConfirmationManager.js.map +0 -1
  74. package/dist/infra/lib/autonomy/ConfirmationStore.d.ts +0 -55
  75. package/dist/infra/lib/autonomy/ConfirmationStore.d.ts.map +0 -1
  76. package/dist/infra/lib/autonomy/ConfirmationStore.js +0 -130
  77. package/dist/infra/lib/autonomy/ConfirmationStore.js.map +0 -1
  78. package/dist/infra/lib/autonomy/EventBus.d.ts +0 -20
  79. package/dist/infra/lib/autonomy/EventBus.d.ts.map +0 -1
  80. package/dist/infra/lib/autonomy/EventBus.js +0 -119
  81. package/dist/infra/lib/autonomy/EventBus.js.map +0 -1
  82. package/dist/infra/lib/autonomy/EventOutbox.d.ts +0 -32
  83. package/dist/infra/lib/autonomy/EventOutbox.d.ts.map +0 -1
  84. package/dist/infra/lib/autonomy/EventOutbox.js +0 -152
  85. package/dist/infra/lib/autonomy/EventOutbox.js.map +0 -1
  86. package/dist/infra/lib/autonomy/NotificationDispatcher.d.ts +0 -24
  87. package/dist/infra/lib/autonomy/NotificationDispatcher.d.ts.map +0 -1
  88. package/dist/infra/lib/autonomy/NotificationDispatcher.js +0 -112
  89. package/dist/infra/lib/autonomy/NotificationDispatcher.js.map +0 -1
  90. package/dist/infra/lib/autonomy/PolicyEngine.d.ts +0 -76
  91. package/dist/infra/lib/autonomy/PolicyEngine.d.ts.map +0 -1
  92. package/dist/infra/lib/autonomy/PolicyEngine.js +0 -208
  93. package/dist/infra/lib/autonomy/PolicyEngine.js.map +0 -1
  94. package/dist/infra/lib/autonomy/ProactiveAnalyzer.d.ts +0 -61
  95. package/dist/infra/lib/autonomy/ProactiveAnalyzer.d.ts.map +0 -1
  96. package/dist/infra/lib/autonomy/ProactiveAnalyzer.js +0 -236
  97. package/dist/infra/lib/autonomy/ProactiveAnalyzer.js.map +0 -1
  98. package/dist/infra/lib/autonomy/RiskClassifier.d.ts +0 -35
  99. package/dist/infra/lib/autonomy/RiskClassifier.d.ts.map +0 -1
  100. package/dist/infra/lib/autonomy/RiskClassifier.js +0 -147
  101. package/dist/infra/lib/autonomy/RiskClassifier.js.map +0 -1
  102. package/dist/infra/lib/autonomy/SecuritySentinel.d.ts +0 -51
  103. package/dist/infra/lib/autonomy/SecuritySentinel.d.ts.map +0 -1
  104. package/dist/infra/lib/autonomy/SecuritySentinel.js +0 -162
  105. package/dist/infra/lib/autonomy/SecuritySentinel.js.map +0 -1
  106. package/dist/infra/lib/autonomy/SuggestionStore.d.ts +0 -54
  107. package/dist/infra/lib/autonomy/SuggestionStore.d.ts.map +0 -1
  108. package/dist/infra/lib/autonomy/SuggestionStore.js +0 -144
  109. package/dist/infra/lib/autonomy/SuggestionStore.js.map +0 -1
  110. package/dist/infra/lib/autonomy/TaskDecomposer.d.ts +0 -38
  111. package/dist/infra/lib/autonomy/TaskDecomposer.d.ts.map +0 -1
  112. package/dist/infra/lib/autonomy/TaskDecomposer.js +0 -175
  113. package/dist/infra/lib/autonomy/TaskDecomposer.js.map +0 -1
  114. package/dist/infra/lib/autonomy/__tests__/audit-store.test.d.ts +0 -2
  115. package/dist/infra/lib/autonomy/__tests__/audit-store.test.d.ts.map +0 -1
  116. package/dist/infra/lib/autonomy/__tests__/audit-store.test.js +0 -198
  117. package/dist/infra/lib/autonomy/__tests__/audit-store.test.js.map +0 -1
  118. package/dist/infra/lib/autonomy/__tests__/event-bus.test.d.ts +0 -2
  119. package/dist/infra/lib/autonomy/__tests__/event-bus.test.d.ts.map +0 -1
  120. package/dist/infra/lib/autonomy/__tests__/event-bus.test.js +0 -225
  121. package/dist/infra/lib/autonomy/__tests__/event-bus.test.js.map +0 -1
  122. package/dist/infra/lib/autonomy/__tests__/event-core.test.d.ts +0 -2
  123. package/dist/infra/lib/autonomy/__tests__/event-core.test.d.ts.map +0 -1
  124. package/dist/infra/lib/autonomy/__tests__/event-core.test.js +0 -194
  125. package/dist/infra/lib/autonomy/__tests__/event-core.test.js.map +0 -1
  126. package/dist/infra/lib/autonomy/__tests__/governance.test.d.ts +0 -2
  127. package/dist/infra/lib/autonomy/__tests__/governance.test.d.ts.map +0 -1
  128. package/dist/infra/lib/autonomy/__tests__/governance.test.js +0 -540
  129. package/dist/infra/lib/autonomy/__tests__/governance.test.js.map +0 -1
  130. package/dist/infra/lib/autonomy/__tests__/integration.test.d.ts +0 -2
  131. package/dist/infra/lib/autonomy/__tests__/integration.test.d.ts.map +0 -1
  132. package/dist/infra/lib/autonomy/__tests__/integration.test.js +0 -480
  133. package/dist/infra/lib/autonomy/__tests__/integration.test.js.map +0 -1
  134. package/dist/infra/lib/autonomy/__tests__/proactive.test.d.ts +0 -2
  135. package/dist/infra/lib/autonomy/__tests__/proactive.test.d.ts.map +0 -1
  136. package/dist/infra/lib/autonomy/__tests__/proactive.test.js +0 -410
  137. package/dist/infra/lib/autonomy/__tests__/proactive.test.js.map +0 -1
  138. package/dist/infra/lib/autonomy/__tests__/sentinel.test.d.ts +0 -2
  139. package/dist/infra/lib/autonomy/__tests__/sentinel.test.d.ts.map +0 -1
  140. package/dist/infra/lib/autonomy/__tests__/sentinel.test.js +0 -486
  141. package/dist/infra/lib/autonomy/__tests__/sentinel.test.js.map +0 -1
  142. package/dist/infra/lib/autonomy/index.d.ts +0 -18
  143. package/dist/infra/lib/autonomy/index.d.ts.map +0 -1
  144. package/dist/infra/lib/autonomy/index.js +0 -22
  145. package/dist/infra/lib/autonomy/index.js.map +0 -1
  146. package/dist/infra/lib/autonomy/schemas.d.ts +0 -317
  147. package/dist/infra/lib/autonomy/schemas.d.ts.map +0 -1
  148. package/dist/infra/lib/autonomy/schemas.js +0 -90
  149. package/dist/infra/lib/autonomy/schemas.js.map +0 -1
  150. package/dist/infra/lib/claude/index.d.ts +0 -5
  151. package/dist/infra/lib/claude/index.d.ts.map +0 -1
  152. package/dist/infra/lib/claude/index.js +0 -5
  153. package/dist/infra/lib/claude/index.js.map +0 -1
  154. package/dist/infra/lib/claude/storage.d.ts +0 -12
  155. package/dist/infra/lib/claude/storage.d.ts.map +0 -1
  156. package/dist/infra/lib/claude/storage.js +0 -54
  157. package/dist/infra/lib/claude/storage.js.map +0 -1
  158. package/dist/infra/lib/gemini/auth.d.ts +0 -18
  159. package/dist/infra/lib/gemini/auth.d.ts.map +0 -1
  160. package/dist/infra/lib/gemini/auth.js +0 -32
  161. package/dist/infra/lib/gemini/auth.js.map +0 -1
  162. package/dist/infra/lib/gemini/capabilities.d.ts +0 -28
  163. package/dist/infra/lib/gemini/capabilities.d.ts.map +0 -1
  164. package/dist/infra/lib/gemini/capabilities.js +0 -178
  165. package/dist/infra/lib/gemini/capabilities.js.map +0 -1
  166. package/dist/infra/lib/gemini/chat.d.ts +0 -35
  167. package/dist/infra/lib/gemini/chat.d.ts.map +0 -1
  168. package/dist/infra/lib/gemini/chat.js +0 -161
  169. package/dist/infra/lib/gemini/chat.js.map +0 -1
  170. package/dist/infra/lib/gemini/completion.d.ts +0 -12
  171. package/dist/infra/lib/gemini/completion.d.ts.map +0 -1
  172. package/dist/infra/lib/gemini/completion.js +0 -13
  173. package/dist/infra/lib/gemini/completion.js.map +0 -1
  174. package/dist/infra/lib/gemini/constants.d.ts +0 -8
  175. package/dist/infra/lib/gemini/constants.d.ts.map +0 -1
  176. package/dist/infra/lib/gemini/constants.js +0 -11
  177. package/dist/infra/lib/gemini/constants.js.map +0 -1
  178. package/dist/infra/lib/gemini/index.d.ts +0 -13
  179. package/dist/infra/lib/gemini/index.d.ts.map +0 -1
  180. package/dist/infra/lib/gemini/index.js +0 -12
  181. package/dist/infra/lib/gemini/index.js.map +0 -1
  182. package/dist/infra/lib/gemini/models.d.ts +0 -11
  183. package/dist/infra/lib/gemini/models.d.ts.map +0 -1
  184. package/dist/infra/lib/gemini/models.js +0 -38
  185. package/dist/infra/lib/gemini/models.js.map +0 -1
  186. package/dist/infra/lib/gemini/orchestration.d.ts +0 -33
  187. package/dist/infra/lib/gemini/orchestration.d.ts.map +0 -1
  188. package/dist/infra/lib/gemini/orchestration.js +0 -62
  189. package/dist/infra/lib/gemini/orchestration.js.map +0 -1
  190. package/dist/infra/lib/gemini/types.d.ts +0 -115
  191. package/dist/infra/lib/gemini/types.d.ts.map +0 -1
  192. package/dist/infra/lib/gemini/types.js +0 -5
  193. package/dist/infra/lib/gemini/types.js.map +0 -1
  194. package/dist/infra/orchestrator/AgentAnnouncer.d.ts +0 -64
  195. package/dist/infra/orchestrator/AgentAnnouncer.d.ts.map +0 -1
  196. package/dist/infra/orchestrator/AgentAnnouncer.js +0 -127
  197. package/dist/infra/orchestrator/AgentAnnouncer.js.map +0 -1
  198. package/dist/infra/orchestrator/AgentAnnouncer.test.d.ts +0 -5
  199. package/dist/infra/orchestrator/AgentAnnouncer.test.d.ts.map +0 -1
  200. package/dist/infra/orchestrator/AgentAnnouncer.test.js +0 -119
  201. package/dist/infra/orchestrator/AgentAnnouncer.test.js.map +0 -1
  202. package/dist/infra/orchestrator/AgentExecutor.d.ts +0 -22
  203. package/dist/infra/orchestrator/AgentExecutor.d.ts.map +0 -1
  204. package/dist/infra/orchestrator/AgentExecutor.js +0 -272
  205. package/dist/infra/orchestrator/AgentExecutor.js.map +0 -1
  206. package/dist/infra/orchestrator/AgentManager.d.ts +0 -72
  207. package/dist/infra/orchestrator/AgentManager.d.ts.map +0 -1
  208. package/dist/infra/orchestrator/AgentManager.js +0 -183
  209. package/dist/infra/orchestrator/AgentManager.js.map +0 -1
  210. package/dist/infra/orchestrator/AgentManifestCache.d.ts +0 -54
  211. package/dist/infra/orchestrator/AgentManifestCache.d.ts.map +0 -1
  212. package/dist/infra/orchestrator/AgentManifestCache.js +0 -191
  213. package/dist/infra/orchestrator/AgentManifestCache.js.map +0 -1
  214. package/dist/infra/orchestrator/AgentRegistry.d.ts +0 -76
  215. package/dist/infra/orchestrator/AgentRegistry.d.ts.map +0 -1
  216. package/dist/infra/orchestrator/AgentRegistry.js +0 -217
  217. package/dist/infra/orchestrator/AgentRegistry.js.map +0 -1
  218. package/dist/infra/orchestrator/AgentRegistry.test.d.ts +0 -5
  219. package/dist/infra/orchestrator/AgentRegistry.test.d.ts.map +0 -1
  220. package/dist/infra/orchestrator/AgentRegistry.test.js +0 -122
  221. package/dist/infra/orchestrator/AgentRegistry.test.js.map +0 -1
  222. package/dist/infra/orchestrator/BackgroundManager.d.ts +0 -128
  223. package/dist/infra/orchestrator/BackgroundManager.d.ts.map +0 -1
  224. package/dist/infra/orchestrator/BackgroundManager.js +0 -620
  225. package/dist/infra/orchestrator/BackgroundManager.js.map +0 -1
  226. package/dist/infra/orchestrator/BackgroundManager.test.d.ts +0 -6
  227. package/dist/infra/orchestrator/BackgroundManager.test.d.ts.map +0 -1
  228. package/dist/infra/orchestrator/BackgroundManager.test.js +0 -162
  229. package/dist/infra/orchestrator/BackgroundManager.test.js.map +0 -1
  230. package/dist/infra/orchestrator/CheckpointManager.d.ts +0 -54
  231. package/dist/infra/orchestrator/CheckpointManager.d.ts.map +0 -1
  232. package/dist/infra/orchestrator/CheckpointManager.js +0 -121
  233. package/dist/infra/orchestrator/CheckpointManager.js.map +0 -1
  234. package/dist/infra/orchestrator/CodexAgentRuntime.d.ts +0 -12
  235. package/dist/infra/orchestrator/CodexAgentRuntime.d.ts.map +0 -1
  236. package/dist/infra/orchestrator/CodexAgentRuntime.js +0 -94
  237. package/dist/infra/orchestrator/CodexAgentRuntime.js.map +0 -1
  238. package/dist/infra/orchestrator/CodexAgentRuntime.test.d.ts +0 -2
  239. package/dist/infra/orchestrator/CodexAgentRuntime.test.d.ts.map +0 -1
  240. package/dist/infra/orchestrator/CodexAgentRuntime.test.js +0 -37
  241. package/dist/infra/orchestrator/CodexAgentRuntime.test.js.map +0 -1
  242. package/dist/infra/orchestrator/LLMCluster.d.ts +0 -82
  243. package/dist/infra/orchestrator/LLMCluster.d.ts.map +0 -1
  244. package/dist/infra/orchestrator/LLMCluster.js +0 -146
  245. package/dist/infra/orchestrator/LLMCluster.js.map +0 -1
  246. package/dist/infra/orchestrator/MultiLlmResearch.d.ts +0 -31
  247. package/dist/infra/orchestrator/MultiLlmResearch.d.ts.map +0 -1
  248. package/dist/infra/orchestrator/MultiLlmResearch.js +0 -160
  249. package/dist/infra/orchestrator/MultiLlmResearch.js.map +0 -1
  250. package/dist/infra/orchestrator/PhasePipeline.d.ts +0 -122
  251. package/dist/infra/orchestrator/PhasePipeline.d.ts.map +0 -1
  252. package/dist/infra/orchestrator/PhasePipeline.js +0 -385
  253. package/dist/infra/orchestrator/PhasePipeline.js.map +0 -1
  254. package/dist/infra/orchestrator/PhaseResultStore.d.ts +0 -39
  255. package/dist/infra/orchestrator/PhaseResultStore.d.ts.map +0 -1
  256. package/dist/infra/orchestrator/PhaseResultStore.js +0 -151
  257. package/dist/infra/orchestrator/PhaseResultStore.js.map +0 -1
  258. package/dist/infra/orchestrator/SessionStore.d.ts +0 -40
  259. package/dist/infra/orchestrator/SessionStore.d.ts.map +0 -1
  260. package/dist/infra/orchestrator/SessionStore.js +0 -116
  261. package/dist/infra/orchestrator/SessionStore.js.map +0 -1
  262. package/dist/infra/orchestrator/SmartRouter.d.ts +0 -90
  263. package/dist/infra/orchestrator/SmartRouter.d.ts.map +0 -1
  264. package/dist/infra/orchestrator/SmartRouter.js +0 -277
  265. package/dist/infra/orchestrator/SmartRouter.js.map +0 -1
  266. package/dist/infra/orchestrator/SmartRouter.test.d.ts +0 -5
  267. package/dist/infra/orchestrator/SmartRouter.test.d.ts.map +0 -1
  268. package/dist/infra/orchestrator/SmartRouter.test.js +0 -484
  269. package/dist/infra/orchestrator/SmartRouter.test.js.map +0 -1
  270. package/dist/infra/orchestrator/SwarmOrchestrator.d.ts +0 -143
  271. package/dist/infra/orchestrator/SwarmOrchestrator.d.ts.map +0 -1
  272. package/dist/infra/orchestrator/SwarmOrchestrator.js +0 -378
  273. package/dist/infra/orchestrator/SwarmOrchestrator.js.map +0 -1
  274. package/dist/infra/orchestrator/SwarmOrchestrator.test.d.ts +0 -5
  275. package/dist/infra/orchestrator/SwarmOrchestrator.test.d.ts.map +0 -1
  276. package/dist/infra/orchestrator/SwarmOrchestrator.test.js +0 -95
  277. package/dist/infra/orchestrator/SwarmOrchestrator.test.js.map +0 -1
  278. package/dist/infra/orchestrator/agentDiscovery.d.ts +0 -26
  279. package/dist/infra/orchestrator/agentDiscovery.d.ts.map +0 -1
  280. package/dist/infra/orchestrator/agentDiscovery.js +0 -175
  281. package/dist/infra/orchestrator/agentDiscovery.js.map +0 -1
  282. package/dist/infra/orchestrator/backgroundAgent.d.ts +0 -9
  283. package/dist/infra/orchestrator/backgroundAgent.d.ts.map +0 -1
  284. package/dist/infra/orchestrator/backgroundAgent.js +0 -10
  285. package/dist/infra/orchestrator/backgroundAgent.js.map +0 -1
  286. package/dist/infra/orchestrator/index.d.ts +0 -207
  287. package/dist/infra/orchestrator/index.d.ts.map +0 -1
  288. package/dist/infra/orchestrator/index.js +0 -362
  289. package/dist/infra/orchestrator/index.js.map +0 -1
  290. package/dist/infra/orchestrator/orchestrator.d.ts +0 -60
  291. package/dist/infra/orchestrator/orchestrator.d.ts.map +0 -1
  292. package/dist/infra/orchestrator/orchestrator.js +0 -214
  293. package/dist/infra/orchestrator/orchestrator.js.map +0 -1
  294. package/dist/infra/orchestrator/parallelResearch.d.ts +0 -27
  295. package/dist/infra/orchestrator/parallelResearch.d.ts.map +0 -1
  296. package/dist/infra/orchestrator/parallelResearch.js +0 -285
  297. package/dist/infra/orchestrator/parallelResearch.js.map +0 -1
  298. package/dist/infra/orchestrator/types.d.ts +0 -205
  299. package/dist/infra/orchestrator/types.d.ts.map +0 -1
  300. package/dist/infra/orchestrator/types.js +0 -87
  301. package/dist/infra/orchestrator/types.js.map +0 -1
  302. package/dist/infra/orchestrator/types.test.d.ts +0 -2
  303. package/dist/infra/orchestrator/types.test.d.ts.map +0 -1
  304. package/dist/infra/orchestrator/types.test.js +0 -57
  305. package/dist/infra/orchestrator/types.test.js.map +0 -1
  306. package/dist/tools/semantic/analyzeDependencyGraph.d.ts +0 -12
  307. package/dist/tools/semantic/analyzeDependencyGraph.d.ts.map +0 -1
  308. package/dist/tools/semantic/analyzeDependencyGraph.js +0 -359
  309. package/dist/tools/semantic/analyzeDependencyGraph.js.map +0 -1
  310. package/dist/tools/semantic/astGrep.d.ts +0 -25
  311. package/dist/tools/semantic/astGrep.d.ts.map +0 -1
  312. package/dist/tools/semantic/astGrep.js +0 -324
  313. package/dist/tools/semantic/astGrep.js.map +0 -1
  314. package/dist/tools/semantic/astGrep.test.d.ts +0 -2
  315. package/dist/tools/semantic/astGrep.test.d.ts.map +0 -1
  316. package/dist/tools/semantic/astGrep.test.js +0 -74
  317. package/dist/tools/semantic/astGrep.test.js.map +0 -1
  318. package/dist/tools/semantic/findReferences.d.ts +0 -9
  319. package/dist/tools/semantic/findReferences.d.ts.map +0 -1
  320. package/dist/tools/semantic/findReferences.js +0 -200
  321. package/dist/tools/semantic/findReferences.js.map +0 -1
  322. package/dist/tools/semantic/findSymbol.d.ts +0 -8
  323. package/dist/tools/semantic/findSymbol.d.ts.map +0 -1
  324. package/dist/tools/semantic/findSymbol.js +0 -204
  325. package/dist/tools/semantic/findSymbol.js.map +0 -1
  326. package/dist/tools/semantic/index.d.ts +0 -9
  327. package/dist/tools/semantic/index.d.ts.map +0 -1
  328. package/dist/tools/semantic/index.js +0 -11
  329. package/dist/tools/semantic/index.js.map +0 -1
  330. package/dist/tools/semantic/lsp.d.ts +0 -68
  331. package/dist/tools/semantic/lsp.d.ts.map +0 -1
  332. package/dist/tools/semantic/lsp.js +0 -561
  333. package/dist/tools/semantic/lsp.js.map +0 -1
  334. package/dist/tools/spec/e2eTestGenerator.d.ts +0 -61
  335. package/dist/tools/spec/e2eTestGenerator.d.ts.map +0 -1
  336. package/dist/tools/spec/e2eTestGenerator.js +0 -255
  337. package/dist/tools/spec/e2eTestGenerator.js.map +0 -1
  338. package/dist/tools/spec/specVersioning.d.ts +0 -76
  339. package/dist/tools/spec/specVersioning.d.ts.map +0 -1
  340. package/dist/tools/spec/specVersioning.js +0 -236
  341. package/dist/tools/spec/specVersioning.js.map +0 -1
@@ -0,0 +1,184 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * clone-merge-responsive.js — MO/PC per-BP SCSS → mobile-first responsive merge
5
+ *
6
+ * Usage:
7
+ * node clone-merge-responsive.js --mo=<styles-dir> --pc=<styles-dir> --out=<dir> [--breakpoint=1024]
8
+ *
9
+ * Why this exists (clone Phase 3C):
10
+ * Phase 3A/3B produce two fixed-viewport SCSS trees (styles/{feature}/mo, /pc).
11
+ * This merges them mobile-first: MO declarations become the base, and only the
12
+ * declarations where PC differs go into a single @media (min-width: <bp>) block.
13
+ * Deterministic text merge — no value invention. Post-merge correctness is judged
14
+ * by Phase 5 (pixel + computed-CSS verification at BOTH viewports).
15
+ *
16
+ * Fail-open:
17
+ * - PC-only selectors → whole rule inside the media block
18
+ * - MO-only selectors → base as-is (reported)
19
+ * - unparseable/missing files → reported and skipped, never a hard abort
20
+ */
21
+
22
+ import fs from 'fs';
23
+ import path from 'path';
24
+ import { parseScss, normalize } from './clone-validate.js';
25
+
26
+ // ─── CLI ────────────────────────────────────────────────────────────
27
+ function parseArgs(argv) {
28
+ const opts = { breakpoint: 1024 };
29
+ for (const a of argv.slice(2)) {
30
+ if (a.startsWith('--mo=')) opts.mo = a.slice(5);
31
+ else if (a.startsWith('--pc=')) opts.pc = a.slice(5);
32
+ else if (a.startsWith('--out=')) opts.out = a.slice(6);
33
+ else if (a.startsWith('--breakpoint=')) opts.breakpoint = Number(a.slice(13)) || 1024;
34
+ }
35
+ return opts;
36
+ }
37
+
38
+ // ─── Merge core (pure — exported for tests) ─────────────────────────
39
+ // moRules/pcRules: Map<selector, {prop: value}> (parseScss output)
40
+ // → { base: Map, media: Map, stats }
41
+ function mergeRules(moRules, pcRules) {
42
+ const base = new Map();
43
+ const media = new Map();
44
+ const stats = { selectors: 0, moOnly: 0, pcOnly: 0, overrides: 0, shared: 0 };
45
+
46
+ const selectors = new Set([...moRules.keys(), ...pcRules.keys()]);
47
+ for (const sel of selectors) {
48
+ stats.selectors++;
49
+ const mo = moRules.get(sel);
50
+ const pc = pcRules.get(sel);
51
+ if (mo && Object.keys(mo).length) base.set(sel, mo);
52
+
53
+ if (!pc || !Object.keys(pc).length) { if (mo) stats.moOnly++; continue; }
54
+ if (!mo || !Object.keys(mo).length) {
55
+ // PC 전용 셀렉터 — 데스크탑에서만 존재하는 노드
56
+ media.set(sel, pc);
57
+ stats.pcOnly++;
58
+ continue;
59
+ }
60
+
61
+ const diff = {};
62
+ for (const [prop, val] of Object.entries(pc)) {
63
+ if (mo[prop] === undefined || normalize(mo[prop]) !== normalize(val)) diff[prop] = val;
64
+ }
65
+ if (Object.keys(diff).length) { media.set(sel, diff); stats.overrides++; }
66
+ else stats.shared++;
67
+ }
68
+ return { base, media, stats };
69
+ }
70
+
71
+ function emitRules(rules, indent) {
72
+ const out = [];
73
+ for (const [sel, decls] of rules) {
74
+ const body = Object.entries(decls).map(([p, v]) => `${indent} ${p}: ${v};`).join('\n');
75
+ if (!body) continue;
76
+ out.push(`${indent}${sel} {\n${body}\n${indent}}`);
77
+ }
78
+ return out.join('\n\n');
79
+ }
80
+
81
+ // Merged partial: MO base rules + one @media (min-width) block with PC diffs.
82
+ function emitMerged(moRules, pcRules, breakpoint, header) {
83
+ const { base, media, stats } = mergeRules(moRules, pcRules);
84
+ const parts = [header, '', emitRules(base, '')];
85
+ if (media.size) {
86
+ parts.push('');
87
+ parts.push(`@media (min-width: ${breakpoint}px) {`);
88
+ parts.push(emitRules(media, ' '));
89
+ parts.push('}');
90
+ }
91
+ return { scss: parts.filter((p) => p !== null).join('\n') + '\n', stats };
92
+ }
93
+
94
+ // ─── File-level orchestration ───────────────────────────────────────
95
+ function readScssRules(file) {
96
+ if (!fs.existsSync(file)) return null;
97
+ try { return parseScss(fs.readFileSync(file, 'utf8')); }
98
+ catch (e) {
99
+ console.error(`[clone-merge] parse skipped (${e.message}): ${file}`);
100
+ return null;
101
+ }
102
+ }
103
+
104
+ function listSections(dir) {
105
+ const d = path.join(dir, 'sections');
106
+ if (!fs.existsSync(d)) return [];
107
+ return fs.readdirSync(d).filter((f) => f.startsWith('_') && f.endsWith('.scss'));
108
+ }
109
+
110
+ function mergeTokens(moDir, pcDir, outDir, breakpoint) {
111
+ const mo = readScssRules(path.join(moDir, '_tokens.scss')) || new Map();
112
+ const pc = readScssRules(path.join(pcDir, '_tokens.scss')) || new Map();
113
+ const { scss } = emitMerged(mo, pc, breakpoint, '// Auto-merged by clone-merge-responsive.js (mobile-first)');
114
+ fs.writeFileSync(path.join(outDir, '_tokens.scss'), scss);
115
+ }
116
+
117
+ function copyIfExists(src, dst) {
118
+ if (fs.existsSync(src)) fs.copyFileSync(src, dst);
119
+ }
120
+
121
+ function mergeClassPlans(moDir, pcDir, outDir) {
122
+ const read = (d) => {
123
+ const f = path.join(d, 'class-plan.json');
124
+ return fs.existsSync(f) ? JSON.parse(fs.readFileSync(f, 'utf8')) : {};
125
+ };
126
+ // MO 우선 — 동일 노드 id가 다른 클래스면 MO가 base이므로 MO를 채택
127
+ const merged = { ...read(pcDir), ...read(moDir) };
128
+ fs.writeFileSync(path.join(outDir, 'class-plan.json'), JSON.stringify(merged, null, 2));
129
+ }
130
+
131
+ function main() {
132
+ const opts = parseArgs(process.argv);
133
+ if (!opts.mo || !opts.pc || !opts.out) {
134
+ console.error('Usage: node clone-merge-responsive.js --mo=<styles-dir> --pc=<styles-dir> --out=<dir> [--breakpoint=1024]');
135
+ process.exit(2);
136
+ }
137
+
138
+ fs.mkdirSync(path.join(opts.out, 'sections'), { recursive: true });
139
+
140
+ const files = [...new Set([...listSections(opts.mo), ...listSections(opts.pc)])].sort();
141
+ const totals = { selectors: 0, moOnly: 0, pcOnly: 0, overrides: 0, shared: 0 };
142
+ const merged = [];
143
+
144
+ for (const f of files) {
145
+ const mo = readScssRules(path.join(opts.mo, 'sections', f)) || new Map();
146
+ const pc = readScssRules(path.join(opts.pc, 'sections', f)) || new Map();
147
+ if (!mo.size && !pc.size) { console.error(`[clone-merge] empty on both BPs, skipped: ${f}`); continue; }
148
+ const { scss, stats } = emitMerged(mo, pc, opts.breakpoint, `// Section: ${f} — merged mobile-first`);
149
+ fs.writeFileSync(path.join(opts.out, 'sections', f), scss);
150
+ for (const k of Object.keys(totals)) totals[k] += stats[k];
151
+ merged.push(f);
152
+ }
153
+
154
+ mergeTokens(opts.mo, opts.pc, opts.out, opts.breakpoint);
155
+ copyIfExists(path.join(opts.mo, '_base.scss'), path.join(opts.out, '_base.scss'));
156
+ copyIfExists(path.join(opts.mo, '_shared.scss'), path.join(opts.out, '_shared.scss'));
157
+ mergeClassPlans(opts.mo, opts.pc, opts.out);
158
+
159
+ const index = [
160
+ '// Auto-merged by clone-merge-responsive.js — mobile-first responsive',
161
+ '',
162
+ `@use './tokens';`,
163
+ `@use './base';`,
164
+ `@use './shared';`,
165
+ ...merged.map((f) => `@use './sections/${f.replace(/^_|\.scss$/g, '')}';`),
166
+ ].join('\n') + '\n';
167
+ fs.writeFileSync(path.join(opts.out, 'index.scss'), index);
168
+
169
+ console.log(`[clone-merge] done → ${opts.out}`);
170
+ console.log(` sections: ${merged.length}, selectors: ${totals.selectors} (shared ${totals.shared}, overrides ${totals.overrides}, mo-only ${totals.moOnly}, pc-only ${totals.pcOnly})`);
171
+ console.log(` breakpoint: @media (min-width: ${opts.breakpoint}px)`);
172
+ }
173
+
174
+ const isMain = process.argv[1] && process.argv[1].replace(/\\/g, '/').endsWith('clone-merge-responsive.js');
175
+ if (isMain) {
176
+ try { main(); }
177
+ catch (e) {
178
+ console.error(`[clone-merge] FAIL: ${e.message}`);
179
+ if (process.env.DEBUG) console.error(e.stack);
180
+ process.exit(1);
181
+ }
182
+ }
183
+
184
+ export { mergeRules, emitMerged };
@@ -28,6 +28,7 @@ function parseArgs(argv) {
28
28
  else if (a.startsWith('--section=')) opts.section = a.slice(10);
29
29
  else if (a.startsWith('--feature=')) opts.feature = a.slice(10);
30
30
  else if (a.startsWith('--behaviors=')) opts.behaviors = a.slice(12);
31
+ else if (a === '--real-content') opts.realContent = true;
31
32
  }
32
33
  return { sectionsPath, opts };
33
34
  }
@@ -101,20 +102,28 @@ function sectionHasNode(section, tag, cls) {
101
102
  return (section.children || []).some(hit);
102
103
  }
103
104
 
105
+ function diffLines(changed) {
106
+ return Object.entries(changed)
107
+ .map(([k, v]) => ` - ${k}: \`${v.from}\` → \`${v.to}\``).join('\n');
108
+ }
109
+
104
110
  function behaviorsBlock(section, behaviors) {
105
111
  if (!behaviors) return null;
106
- const scroll = (behaviors.scroll || []).filter((b) => sectionHasNode(section, b.tag, b.cls));
112
+ const inSection = (list) => (list || []).filter((b) => sectionHasNode(section, b.tag, b.cls));
113
+ const scroll = inSection(behaviors.scroll);
114
+ const hover = inSection(behaviors.hover);
115
+ const inview = inSection(behaviors.inview);
116
+ const timed = inSection(behaviors.timeDriven);
107
117
  // Tab groups aren't tag-keyed; attach to any section that contains a [role=tab]-ish node.
108
118
  const tabs = (behaviors.interactive || []).filter(() =>
109
119
  sectionHasNode(section, 'button') || sectionHasNode(section, 'li') || sectionHasNode(section, 'a'),
110
120
  );
111
- if (!scroll.length && !tabs.length) return null;
121
+ const lib = behaviors.scrollLib;
122
+ if (!scroll.length && !tabs.length && !hover.length && !inview.length && !timed.length && !lib) return null;
112
123
 
113
124
  const lines = [];
114
125
  for (const b of scroll) {
115
- const diffs = Object.entries(b.changed)
116
- .map(([k, v]) => ` - ${k}: \`${v.from}\` → \`${v.to}\``).join('\n');
117
- lines.push(`- **Scroll-triggered** on \`${b.label}\` (past ~${b.triggerScrollY}px scroll):\n${diffs}`);
126
+ lines.push(`- **Scroll-triggered** on \`${b.label}\` (past ~${b.triggerScrollY}px scroll):\n${diffLines(b.changed)}`);
118
127
  }
119
128
  for (const t of tabs) {
120
129
  const labels = (t.tabLabels || []).map((l) => `"${l}"`).join(', ') || '(unlabeled)';
@@ -123,6 +132,19 @@ function behaviorsBlock(section, behaviors) {
123
132
  : 'no content swap detected (styling-only tabs)';
124
133
  lines.push(`- **Tab group** ×${t.count} [${labels}]: ${swap}`);
125
134
  }
135
+ for (const b of hover) {
136
+ const tr = b.transition && b.transition !== 'all 0s ease 0s' ? ` (transition: \`${b.transition}\`)` : '';
137
+ lines.push(`- **Hover** on \`${b.label}\`${tr}:\n${diffLines(b.changed)}`);
138
+ }
139
+ for (const b of inview) {
140
+ lines.push(`- **In-view entrance** on \`${b.label}\` (enters at ~${b.triggerY}px):\n${diffLines(b.changed)}`);
141
+ }
142
+ for (const b of timed) {
143
+ lines.push(`- **Time-driven** \`${b.label}\` — ${b.mutations} mutations/3s [${(b.kinds || []).join(', ')}] → carousel/auto-cycle candidate`);
144
+ }
145
+ if (lib) {
146
+ lines.push(`- **Smooth-scroll library (page-level):** ${lib.name} (evidence: \`${lib.evidence}\`) → wire in globals, not per-section`);
147
+ }
126
148
  return lines.join('\n');
127
149
  }
128
150
 
@@ -171,7 +193,9 @@ ${cssBlock(section.css)}
171
193
  ## Assets (local paths only — never hotlink)
172
194
  ${assetsBlock(section.images)}
173
195
 
174
- ## Text content (replace copyrighted copy with placeholders)
196
+ ## Text content ${meta.realContent
197
+ ? '(verbatim — user confirmed rights to reuse this copy)'
198
+ : '(replace copyrighted copy with placeholders)'}
175
199
  ${textBlock}
176
200
 
177
201
  ## Component candidates
@@ -179,7 +203,7 @@ ${componentsBlock(section.components)}
179
203
 
180
204
  ## Build checklist
181
205
  - [ ] HTML semantics + final tags chosen
182
- - [ ] SCSS via clone-to-scss.js (computed values as-is no eyeballing)
206
+ - [ ] SCSS started from the clone-to-scss.js draft value edits only with evidence cited from computed.json/states.json/behaviors.json (no eyeballing); clone-validate.js is the judge
183
207
  - [ ] Every state above implemented
184
208
  - [ ] Interaction model confirmed on live site & wired
185
209
  - [ ] All assets local (public/images/${meta.feature}/) — no hotlinks
@@ -196,6 +220,7 @@ function main() {
196
220
  url: data.meta && data.meta.url,
197
221
  viewport: data.meta && data.meta.viewport,
198
222
  bp: opts.section ? (data.meta && data.meta.bp) : (data.meta && data.meta.bp) || '?',
223
+ realContent: !!opts.realContent,
199
224
  };
200
225
  // behaviors.json (active interaction sweep) lives next to the source computed.json.
201
226
  const behaviorsPath = opts.behaviors || path.join(path.dirname(sectionsPath), 'behaviors.json');
@@ -223,7 +248,7 @@ function main() {
223
248
  const isMain = process.argv[1] && process.argv[1].replace(/\\/g, '/').endsWith('clone-spec.js');
224
249
  if (isMain) {
225
250
  if (!sectionsPath || !opts.out) {
226
- console.error('Usage: node clone-spec.js <sections.json> --out=<dir> [--section=Name] [--feature=name] [--behaviors=path]');
251
+ console.error('Usage: node clone-spec.js <sections.json> --out=<dir> [--section=Name] [--feature=name] [--behaviors=path] [--real-content]');
227
252
  process.exit(1);
228
253
  }
229
254
  try { main(); }
@@ -34,10 +34,6 @@ function parseArgs(argv) {
34
34
  }
35
35
 
36
36
  const { stylesDir, sectionsPath, opts } = parseArgs(process.argv);
37
- if (!stylesDir || !sectionsPath) {
38
- console.error('Usage: node clone-validate.js <styles-dir> <sections.json> [--section=<name>]');
39
- process.exit(2);
40
- }
41
37
 
42
38
  // ─── Minimal SCSS parser ────────────────────────────────────────────
43
39
  // Strips comments, expands `&::pseudo` (one level), flattens nested rules.
@@ -272,9 +268,19 @@ function main() {
272
268
  process.exit(0);
273
269
  }
274
270
 
275
- try { main(); }
276
- catch (e) {
277
- console.error(`[clone-validate] FAIL: ${e.message}`);
278
- if (process.env.DEBUG) console.error(e.stack);
279
- process.exit(2);
271
+ // isMain 가드 — clone-merge-responsive.js가 parseScss를 import할 때 main() 돌면 안 된다
272
+ const isMain = process.argv[1] && process.argv[1].replace(/\\/g, '/').endsWith('clone-validate.js');
273
+ if (isMain) {
274
+ if (!stylesDir || !sectionsPath) {
275
+ console.error('Usage: node clone-validate.js <styles-dir> <sections.json> [--section=<name>]');
276
+ process.exit(2);
277
+ }
278
+ try { main(); }
279
+ catch (e) {
280
+ console.error(`[clone-validate] FAIL: ${e.message}`);
281
+ if (process.env.DEBUG) console.error(e.stack);
282
+ process.exit(2);
283
+ }
280
284
  }
285
+
286
+ export { parseScss, normalize, compareValue };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@su-record/vibe",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "AI Coding Framework for Claude Code — 10+ agents, 59 skills, multi-LLM orchestration",
5
5
  "type": "module",
6
6
  "main": "dist/cli/index.js",
@@ -33,7 +33,7 @@
33
33
  "test:watch": "vitest",
34
34
  "prepublishOnly": "pnpm build",
35
35
  "postinstall": "node -e \"import('./dist/cli/postinstall/main.js').then(m=>m.main()).catch(()=>{})\"",
36
- "release": "pnpm version patch && npm publish --access public"
36
+ "release": "pnpm version patch && git push origin main --follow-tags"
37
37
  },
38
38
  "keywords": [
39
39
  "ai",
@@ -58,6 +58,9 @@
58
58
  "type": "git",
59
59
  "url": "git+https://github.com/su-record/vibe.git"
60
60
  },
61
+ "bugs": {
62
+ "url": "https://github.com/su-record/vibe/issues"
63
+ },
61
64
  "homepage": "https://github.com/su-record/vibe#readme",
62
65
  "publishConfig": {
63
66
  "access": "public"
@@ -24,8 +24,14 @@ The rendered DOM is the source of truth for markup. Screenshots are for pixel ve
24
24
 
25
25
  ```
26
26
  1. Do NOT generate CSS values by guessing or eyeballing screenshots.
27
- Use clone-extract.js computed CSS output as-is.
28
- Do NOT write CSS values directly inside scoped <style> blocks.
27
+ ✅ clone-to-scss.js output is a DRAFT (skeleton), not a frozen artifact. You MAY
28
+ rewrite SCSS values/selectors but ONLY with evidence cited from computed.json /
29
+ states.json / behaviors.json (value correction, dedupe, selector restructuring).
30
+ ✅ clone-validate.js PASS is the sole judge of value correctness — not self-report.
31
+ ❌ Do NOT invent values with no extraction evidence ("looks like 18px" is forbidden).
32
+ ❌ Do NOT write CSS values directly inside scoped <style> blocks — style LOCATION
33
+ rule: all values live in styles/{feature}/ SCSS (value authority and style
34
+ location are separate rules; both hold).
29
35
 
30
36
  2. Do NOT hotlink remote assets. All images/fonts must be downloaded and rewritten.
31
37
 
@@ -34,6 +40,9 @@ The rendered DOM is the source of truth for markup. Screenshots are for pixel ve
34
40
  4. Do NOT copy textual content verbatim from copyrighted sources for production use.
35
41
  This skill is for layout/markup learning ("클론 코딩"). Replace text with placeholders
36
42
  or user-provided copy when shipping a real product.
43
+ Exception: `--real-content` — the user confirms (once, explicitly) they own the site
44
+ or have permission. Then keep text verbatim; clone-spec.js is invoked with
45
+ `--real-content` so specs mark copy as verbatim.
37
46
 
38
47
  5. Do NOT build a section without confirming its interaction model. The model in
39
48
  sections.json is a static-DOM heuristic — verify scroll-driven vs click-driven vs
@@ -42,10 +51,11 @@ The rendered DOM is the source of truth for markup. Screenshots are for pixel ve
42
51
  6. Do NOT ship default-state-only. Implement every harvested state (hover/focus/active/open/
43
52
  tab-switch) from states.json / the section spec.
44
53
 
45
- 7. Do NOT ignore behaviors.json. The ACTIVE interaction sweep (scroll-state diffs +
46
- click-driven tab content-swap detection) catches JS-set state that static CSS harvesting
47
- is blind to. When the spec's "Dynamic behaviors" block conflicts with the static
48
- interaction heuristic, the active capture wins.
54
+ 7. Do NOT ignore behaviors.json. The ACTIVE interaction sweep (scroll-state diffs,
55
+ click-driven tab content-swap detection, hover diffs, in-view entrance animations,
56
+ time-driven mutation candidates, smooth-scroll-lib detection) catches JS-set state
57
+ that static CSS harvesting is blind to. When the spec's "Dynamic behaviors" block
58
+ conflicts with the static interaction heuristic, the active capture wins.
49
59
  ```
50
60
 
51
61
  ## Full Flow
@@ -56,9 +66,11 @@ Input: a URL (or multiple URLs for multi-page clones)
56
66
  → Phase 0: Setup (stack detection, feature naming, working dir)
57
67
  → Phase 1: Capture (Puppeteer → rendered HTML + computed CSS + screenshots + assets)
58
68
  → Phase 2: Refine (DOM → sections.json per breakpoint; + interaction model + states)
59
- → Phase 3: Scaffold (spec gate SCSS auto-gen + Claude-authored HTML/components)
69
+ → Phase 2.5: Foundation (fonts / favicon / OG / SVG icons — sequential, before any section)
70
+ → Phase 3: Scaffold (spec gate → SCSS draft + builder dispatch, parallel per section)
71
+ → Phase 3C: Responsive merge (clone-merge-responsive.js — mobile-first @media)
60
72
  → Phase 4: Compile gate
61
- → Phase 5: Pixel verification loop
73
+ → Phase 5: Pixel verification loop (BOTH viewports after merge)
62
74
 
63
75
  Working directory:
64
76
  /tmp/{feature}/
@@ -67,7 +79,9 @@ Working directory:
67
79
  └── tokens.json — extracted design tokens (colors/fonts/spacing)
68
80
 
69
81
  Code output: placed directly in the project directory per detected stack
70
- components/{feature}/, components/{feature}/_specs/, styles/{feature}/, public/images/{feature}/
82
+ components/{feature}/, components/{feature}/_specs/{mo,pc}/,
83
+ styles/{feature}/{mo,pc}/ (per-BP drafts) → styles/{feature}/ (Phase 3C merged),
84
+ public/images/{feature}/, public/ (favicons/OG from assets/seo/)
71
85
  ```
72
86
 
73
87
  ---
@@ -124,10 +138,11 @@ node {{VIBE_PATH}}/hooks/scripts/clone-extract.js capture <URL> \
124
138
  ├── computed.json — per-element computed CSS + bounding box
125
139
  ├── screenshot.png — full-page screenshot
126
140
  ├── states.json — non-default state rules (hover/focus/active/checked/tab/aria/data-state)
127
- ├── behaviors.json — ACTIVE sweep: scroll-triggered header/nav diffs + click-driven tab groups
141
+ ├── behaviors.json — ACTIVE sweep: scroll / tab / hover / in-view / time-driven + scrollLib
128
142
  ├── assets/
129
143
  │ ├── images/ — all <img>, background-image, <picture> sources
130
- └── fonts/ — @font-face srcs
144
+ ├── fonts/ — @font-face srcs
145
+ │ └── seo/ — favicons, apple-touch-icons, OG images, webmanifest
131
146
  └── asset-map.json — remote URL → local path mapping
132
147
  ```
133
148
 
@@ -149,7 +164,15 @@ node {{VIBE_PATH}}/hooks/scripts/clone-extract.js capture <URL> \
149
164
  - Scroll-state diff: tag sticky/fixed/top-bar headers+nav, snapshot computed CSS at
150
165
  scroll 0, scroll past threshold, re-snapshot, diff → {prop: {from, to}, triggerScrollY}
151
166
  - Tab groups: click tab-like sibling sets, detect whether content swaps on click
167
+ - Hover diff: hover interactive elements (1 sample per tag+class signature, max 30),
168
+ diff computed styles → JS-set hover states that :hover harvesting misses
169
+ - In-view entrance: fresh reload, tag below-fold "waiting to animate" nodes
170
+ (opacity 0 / transform offset), scroll each into view, diff → fade-up/slide-in
171
+ - Time-driven: 3s no-input MutationObserver watch → carousel/auto-cycle candidates
172
+ - Scroll-lib detection: Lenis / Locomotive Scroll (native scrolling feels different —
173
+ the user spots it immediately; wire the lib page-level, not per-section)
152
174
  Disable with --no-interact (restores the old fully-deterministic, screenshot-stable capture).
175
+ 10. SEO asset harvest: favicon / apple-touch-icon / webmanifest / og:image → assets/seo/
153
176
  ```
154
177
 
155
178
  ---
@@ -240,6 +263,26 @@ Refinement applied when converting rendered.html + computed.json → sections.js
240
263
 
241
264
  ---
242
265
 
266
+ ## Phase 2.5: Foundation ← sequential, BEFORE any section build
267
+
268
+ Nothing renders right until the foundation exists. Do this yourself (not delegated) — it
269
+ touches shared files:
270
+
271
+ ```
272
+ 1. Fonts: verify _base.scss @font-face srcs point at downloaded assets/fonts/ files.
273
+ Next.js stack → wire via next/font/local in the layout instead of raw @font-face.
274
+ 2. Favicon / OG / manifest: copy assets/seo/* → public/ (project convention path),
275
+ wire metadata (layout.tsx metadata / <head>) to the local files.
276
+ 3. SVG icons: collect inline <svg> from rendered.html, dedupe by path data,
277
+ emit one stack-appropriate icon module (e.g. components/{feature}/icons.tsx).
278
+ Name by visual function (SearchIcon, ArrowRightIcon, LogoIcon).
279
+ 4. Global behaviors from behaviors.json: scrollLib detected → install/wire page-level
280
+ (Lenis etc.); global keyframes/scroll-snap → styles/{feature}/_shared.scss.
281
+ 5. Verify: compile passes before moving on.
282
+ ```
283
+
284
+ ---
285
+
243
286
  ## Phase 3: Scaffold ← stack-specific code generation
244
287
 
245
288
  **⛔ Implement MO fully first → pass verification → then PC. No responsive conversion in this phase.**
@@ -251,78 +294,105 @@ Refinement applied when converting rendered.html + computed.json → sections.js
251
294
  # Step 0: Generate per-section build-contract specs (run once per BP)
252
295
  node {{VIBE_PATH}}/hooks/scripts/clone-spec.js \
253
296
  /tmp/{feature}/{bp}/sections.json \
254
- --out=/path/to/project/components/{feature}/_specs/ \
255
- --feature={feature}
297
+ --out=/path/to/project/components/{feature}/_specs/{bp}/ \
298
+ --feature={feature} [--real-content]
256
299
 
257
- # Step A: Auto-generate SCSS skeleton (run once per BP)
300
+ # Step A: Auto-generate SCSS draft (run once per BP — note the per-BP out dir)
258
301
  node {{VIBE_PATH}}/hooks/scripts/clone-to-scss.js \
259
302
  /tmp/{feature}/{bp}/sections.json \
260
- --out=/path/to/project/styles/{feature}/ \
303
+ --out=/path/to/project/styles/{feature}/{bp}/ \
261
304
  --token-file=/tmp/{feature}/project-tokens.json
262
305
 
263
306
  # Step B: Per-section validation (after writing each section's component code)
264
307
  node {{VIBE_PATH}}/hooks/scripts/clone-validate.js \
265
- /path/to/project/styles/{feature}/ \
308
+ /path/to/project/styles/{feature}/{bp}/ \
266
309
  /tmp/{feature}/{bp}/sections.json \
267
310
  --section={SectionName}
268
311
  ```
269
312
 
270
313
  ⛔ **No section is built without a completed spec.** Step 0 emits `_specs/{Section}.spec.md`
271
- (interaction model + **active-capture Dynamic behaviors** + states + computed CSS + assets +
272
- text + checklist). clone-spec.js auto-loads `behaviors.json` from the sections.json dir and
273
- attaches matching scroll/tab behaviors per section. Before writing a
274
- section's component, Claude reviews its spec and resolves every `TODO` (confirm interaction
275
- model, list states to implement, choose tags, replace copyrighted text). The spec is the
276
- contract AND the audit trail it forces extraction rigor before any code is written.
277
- **Writing SCSS files directly without calling clone-to-scss.js invalidates Phase 3.**
314
+ (interaction model + **active-capture Dynamic behaviors** (scroll/tab/hover/in-view/
315
+ time-driven/scroll-lib) + states + computed CSS + assets + text + checklist).
316
+ clone-spec.js auto-loads `behaviors.json` from the sections.json dir and attaches matching
317
+ behaviors per section. Before dispatching a section's builder, Claude reviews its spec and
318
+ resolves every `TODO` (confirm interaction model, list states to implement, choose tags,
319
+ replace copyrighted text skipped with --real-content). The spec is the contract AND the
320
+ audit trail it forces extraction rigor before any code is written.
321
+ ⛔ **clone-to-scss.js must run first (Step A) — its output is the DRAFT every section starts
322
+ from.** After that, SCSS edits are allowed per Immutable Rule 1 (evidence-cited only);
323
+ clone-validate.js PASS is the judge.
278
324
  ⛔ **Do NOT write custom SCSS / spec generation scripts.**
279
- ⛔ **Do NOT proceed to the next section without a clone-validate.js PASS.**
280
- ✅ Use clone-spec.js / clone-to-scss.js output as-is. If unsatisfactory, modify the script.
325
+ ⛔ **Do NOT proceed past a section without a clone-validate.js PASS for it.**
281
326
 
282
327
  ```
283
- Phase 3A: MO Scaffold
328
+ Phase 3A: MO Scaffold — parallel builder dispatch
284
329
  Input: /tmp/{feature}/mo/sections.json
285
- Step 0 once: clone-spec.js → emit _specs/{Section}.spec.md for every section
286
- No parallelism. Process one section at a time:
287
- 1. Read the target section's spec resolve every TODO:
288
- ├─ Confirm the interaction model (spec.interaction is a heuristic guess)
289
- ├─ List the states to implement (spec.states)
290
- └─ Mark copyrighted text for placeholder replacement
291
- 2. Map component candidates against component-index.json
292
- ├─ Match import existing
293
- └─ No match create new in components/{feature}/
294
- 3. clone-to-scss.js auto-generate SCSS skeleton (computed values as-is) Step A once
295
- 4. Claude: HTML structure + semantic tags + framework-specific component file
296
- No CSS written directly in <style> blocks only @import/@use allowed
297
- Build for the CONFIRMED interaction model (don't build a click UI for a
298
- scroll-driven original); wire every state from the spec (hover/active/open/…)
299
- Framework mapping:
300
- - React/Next .tsx with CSS Modules or styled-components per stack
301
- - Vue/Nuxt → .vue with scoped <style lang="scss"> @import only
302
- - Svelte → .svelte with <style> @import only
303
- - Vanilla .html + linked .scss
304
- 5. Asset references public/images/{feature}/ (already populated in Phase 1)
305
- 6. clone-validate.js compare SCSS vs sections.json Step B
306
- ├─ PASS next section
330
+ Prep (sequential, once):
331
+ a. Step 0: clone-spec.js emit _specs/mo/{Section}.spec.md for every section
332
+ b. Step A: clone-to-scss.js SCSS draft in styles/{feature}/mo/ (computed values)
333
+ c. Orchestrator resolves every spec TODO BEFORE dispatch:
334
+ ├─ Confirm the interaction model (spec.interaction is a heuristic guess;
335
+ │ the spec's active-capture "Dynamic behaviors" block overrides it on conflict)
336
+ ├─ List the states to implement (spec.states + Dynamic behaviors)
337
+ ├─ Mark copyrighted text for placeholder replacement (skip with --real-content)
338
+ └─ Map component candidates against component-index.json (reuse vs create)
339
+ d. 150-line split rule (mechanical wc -l, don't override with "but it's related"):
340
+ a completed spec over 150 lines means the section is too big for one builder →
341
+ split into sub-component specs (one per card variant / repeated pattern) + one
342
+ wrapper spec that imports them.
343
+ Dispatch (parallel):
344
+ Every builder prompt embeds the FULL spec text INLINE — never "go read the file".
345
+ The spec file stays on disk as the audit trail; the prompt must be self-sufficient.
346
+ Builders that write files in parallel run in worktree isolation; sub-component
347
+ builders complete before their wrapper builder starts.
348
+ Builder contract (each agent):
349
+ 1. Build HTML structure + semantic tags + framework-specific component file
350
+ No CSS in <style> blocksonly @import/@use of styles/{feature}/mo/
351
+ Build for the CONFIRMED interaction model in the spec; wire every state
352
+ Framework mapping:
353
+ - React/Next → .tsx with CSS Modules or styled-components per stack
354
+ - Vue/Nuxt → .vue with scoped <style lang="scss"> @import only
355
+ - Svelte → .svelte with <style> @import only
356
+ - Vanilla → .html + linked .scss
357
+ 2. Asset references → public/images/{feature}/ (already populated in Phase 1)
358
+ 3. SCSS edits per Immutable Rule 1 (evidence-cited only)
359
+ 4. Verify compile (tsc --noEmit or stack equivalent) before finishing
360
+ Merge (orchestrator, as builders complete):
361
+ 5. Merge worktrees; resolve conflicts (you have full context on every spec)
362
+ 6. clone-validate.js per section — Step B
363
+ ├─ PASS → section done
307
364
  └─ FAIL → fix discrepancies → re-run step 6 (loop until P1=0, no round cap)
308
365
  → Phase 4 (MO compile) → Phase 5 (MO pixel verification)
309
366
 
310
367
  Phase 3B: PC Scaffold
311
- Same process as MO, input /tmp/{feature}/pc/sections.json
368
+ Same process as MO, input /tmp/{feature}/pc/sections.json → styles/{feature}/pc/
312
369
  → Phase 4 (PC compile) → Phase 5 (PC pixel verification)
313
370
 
314
- Phase 3C: Responsive Integration (after both MO+PC pass verification)
315
- Merge MO+PC styles into @media-based responsive layout (separate flow, TODO)
316
-
317
- Claude's role (restricted):
371
+ Phase 3C: Responsive Integration (after both MO+PC pass Phase 5)
372
+ 1. node {{VIBE_PATH}}/hooks/scripts/clone-merge-responsive.js \
373
+ --mo=/path/to/project/styles/{feature}/mo/ \
374
+ --pc=/path/to/project/styles/{feature}/pc/ \
375
+ --out=/path/to/project/styles/{feature}/ \
376
+ [--breakpoint=1024]
377
+ → mobile-first merge: MO declarations = base, PC diffs → @media (min-width) block
378
+ 2. Switch component style imports from styles/{feature}/{bp}/index.scss to the merged
379
+ styles/{feature}/index.scss
380
+ 3. Review pc-only/mo-only selectors in the merge report — hide/show them with the
381
+ media query if the original does (evidence: the two sections.json trees)
382
+ 4. → Phase 4 (compile) → Phase 5 at BOTH viewports against each BP's screenshot.
383
+ ⛔ The clone is NOT complete until the MERGED build passes Phase 5 at both.
384
+
385
+ Claude's role:
318
386
  ✅ Component candidates: decide which patterns become reusable components
319
387
  ✅ HTML semantics: section/h1/p/button/nav tag selection
320
388
  ✅ Text replacement: substitute copyrighted copy with placeholders or user-supplied text
321
389
  ✅ Interaction model: confirm the spec's heuristic guess, then build for the real model
322
390
  ✅ Interactions: implement every state in the spec (hover/focus/active/open), click handlers
323
- Do NOT modify SCSS CSS values (use clone-to-scss.js output as-is)
391
+ SCSS value edits WITH cited evidence (computed.json/states.json/behaviors.json)
392
+ clone-validate.js PASS is the judge
393
+ ❌ Do NOT invent CSS values without extraction evidence
324
394
  ❌ Do NOT write CSS directly in <style> blocks
325
- ❌ Do NOT use vw/clamp/@media or create custom mixins in Phase 3A/3B
395
+ ❌ Do NOT hand-write vw/clamp/@media in Phase 3A/3B (responsive comes from Phase 3C merge)
326
396
  ❌ Do NOT hotlink remote URLs — all assets must use local public/images/ paths
327
397
  ```
328
398
 
@@ -382,6 +452,9 @@ Termination:
382
452
  ultrawork mode: on stuck, record TODO without prompting and complete
383
453
 
384
454
  Responsive: after MO verification → change viewport → repeat against PC screenshot
455
+ Post-merge (Phase 3C): re-run at BOTH viewports (375×812 vs mo/screenshot.png,
456
+ 1440×900 vs pc/screenshot.png) — either failing means the merge regressed; fix the
457
+ merged SCSS (evidence: the per-BP sections.json), never by re-guessing values
385
458
  Cleanup: shut down browser + dev server
386
459
 
387
460
  ⛔ "Completion summary" output only allowed after Phase 5 completes.
@@ -404,6 +477,8 @@ NOT intended for:
404
477
 
405
478
  Claude must:
406
479
  - Replace copyrighted text content with placeholders (e.g. "[Lorem ipsum]") by default
480
+ - --real-content: ask ONE explicit confirmation (site ownership / permission) before
481
+ Phase 3; on confirmation keep text verbatim (clone-spec.js --real-content)
407
482
  - Skip and warn when robots.txt disallows fetching the target path
408
483
  - Refuse if the user's stated intent is brand impersonation or deception
409
484
  ```
@@ -423,3 +498,5 @@ Claude must:
423
498
  | Interaction model guess wrong (Phase 5) | section.interaction is a static-DOM heuristic. Re-observe the live site, correct the model in the spec, rebuild the section for the confirmed model. |
424
499
  | states.json empty but site has hover/tabs | States may be set via inline JS, not CSS rules. Check behaviors.json (active sweep captures scroll/tab JS state). If still missing, note in the spec and capture manually during Phase 5. |
425
500
  | behaviors.json missing or empty | Active sweep was disabled (--no-interact), hit no sticky/tab elements, or errored (logged, non-fatal). Falls back to static states.json. Re-run without --no-interact to retry. |
501
+ | clone-merge-responsive.js reports many mo-only/pc-only selectors | Section detection diverged between BPs (layout differs structurally). Expected for hidden-on-mobile elements; verify each against the two sections.json trees and gate with the media query manually if needed. |
502
+ | Merged build fails Phase 5 at one viewport only | The merge dropped or mis-bucketed a declaration. Diff the failing viewport's computed CSS against its sections.json; fix in the merged SCSS with that evidence. |