@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.
- package/hooks/scripts/__tests__/.vibe/command-log.txt +3 -78
- package/hooks/scripts/__tests__/.vibe/memories/memories.db +0 -0
- package/hooks/scripts/__tests__/.vibe/memories/memories.db-shm +0 -0
- package/hooks/scripts/__tests__/.vibe/memories/memories.db-wal +0 -0
- package/hooks/scripts/__tests__/clone-behaviors.test.js +64 -0
- package/hooks/scripts/__tests__/clone-merge-responsive.test.js +106 -0
- package/hooks/scripts/clone-extract.js +242 -28
- package/hooks/scripts/clone-merge-responsive.js +184 -0
- package/hooks/scripts/clone-spec.js +33 -8
- package/hooks/scripts/clone-validate.js +15 -9
- package/package.json +5 -2
- package/skills/clone/SKILL.md +132 -55
- package/skills/vibe.clone/SKILL.md +39 -19
- package/dist/cli/llm/gemini-commands.d.ts +0 -25
- package/dist/cli/llm/gemini-commands.d.ts.map +0 -1
- package/dist/cli/llm/gemini-commands.js +0 -143
- package/dist/cli/llm/gemini-commands.js.map +0 -1
- package/dist/cli/postinstall/codex-agents.d.ts +0 -24
- package/dist/cli/postinstall/codex-agents.d.ts.map +0 -1
- package/dist/cli/postinstall/codex-agents.js +0 -114
- package/dist/cli/postinstall/codex-agents.js.map +0 -1
- package/dist/cli/postinstall/codex-instruction.d.ts +0 -10
- package/dist/cli/postinstall/codex-instruction.d.ts.map +0 -1
- package/dist/cli/postinstall/codex-instruction.js +0 -56
- package/dist/cli/postinstall/codex-instruction.js.map +0 -1
- package/dist/cli/postinstall/gemini-agents.d.ts +0 -12
- package/dist/cli/postinstall/gemini-agents.d.ts.map +0 -1
- package/dist/cli/postinstall/gemini-agents.js +0 -80
- package/dist/cli/postinstall/gemini-agents.js.map +0 -1
- package/dist/cli/postinstall/gemini-instruction.d.ts +0 -10
- package/dist/cli/postinstall/gemini-instruction.d.ts.map +0 -1
- package/dist/cli/postinstall/gemini-instruction.js +0 -59
- package/dist/cli/postinstall/gemini-instruction.js.map +0 -1
- package/dist/infra/lib/ContextCompressor.d.ts +0 -104
- package/dist/infra/lib/ContextCompressor.d.ts.map +0 -1
- package/dist/infra/lib/ContextCompressor.js +0 -297
- package/dist/infra/lib/ContextCompressor.js.map +0 -1
- package/dist/infra/lib/ContextCompressor.test.d.ts +0 -2
- package/dist/infra/lib/ContextCompressor.test.d.ts.map +0 -1
- package/dist/infra/lib/ContextCompressor.test.js +0 -25
- package/dist/infra/lib/ContextCompressor.test.js.map +0 -1
- package/dist/infra/lib/ProgressTracker.d.ts +0 -73
- package/dist/infra/lib/ProgressTracker.d.ts.map +0 -1
- package/dist/infra/lib/ProgressTracker.js +0 -267
- package/dist/infra/lib/ProgressTracker.js.map +0 -1
- package/dist/infra/lib/TokenBudgetTracker.d.ts +0 -68
- package/dist/infra/lib/TokenBudgetTracker.d.ts.map +0 -1
- package/dist/infra/lib/TokenBudgetTracker.js +0 -191
- package/dist/infra/lib/TokenBudgetTracker.js.map +0 -1
- package/dist/infra/lib/autonomy/AuditStore.d.ts +0 -63
- package/dist/infra/lib/autonomy/AuditStore.d.ts.map +0 -1
- package/dist/infra/lib/autonomy/AuditStore.js +0 -185
- package/dist/infra/lib/autonomy/AuditStore.js.map +0 -1
- package/dist/infra/lib/autonomy/AutonomyConfig.d.ts +0 -84
- package/dist/infra/lib/autonomy/AutonomyConfig.d.ts.map +0 -1
- package/dist/infra/lib/autonomy/AutonomyConfig.js +0 -49
- package/dist/infra/lib/autonomy/AutonomyConfig.js.map +0 -1
- package/dist/infra/lib/autonomy/AutonomyOrchestrator.d.ts +0 -78
- package/dist/infra/lib/autonomy/AutonomyOrchestrator.d.ts.map +0 -1
- package/dist/infra/lib/autonomy/AutonomyOrchestrator.js +0 -246
- package/dist/infra/lib/autonomy/AutonomyOrchestrator.js.map +0 -1
- package/dist/infra/lib/autonomy/BackgroundMonitor.d.ts +0 -36
- package/dist/infra/lib/autonomy/BackgroundMonitor.d.ts.map +0 -1
- package/dist/infra/lib/autonomy/BackgroundMonitor.js +0 -138
- package/dist/infra/lib/autonomy/BackgroundMonitor.js.map +0 -1
- package/dist/infra/lib/autonomy/CollaborationProtocol.d.ts +0 -56
- package/dist/infra/lib/autonomy/CollaborationProtocol.d.ts.map +0 -1
- package/dist/infra/lib/autonomy/CollaborationProtocol.js +0 -122
- package/dist/infra/lib/autonomy/CollaborationProtocol.js.map +0 -1
- package/dist/infra/lib/autonomy/ConfirmationManager.d.ts +0 -42
- package/dist/infra/lib/autonomy/ConfirmationManager.d.ts.map +0 -1
- package/dist/infra/lib/autonomy/ConfirmationManager.js +0 -200
- package/dist/infra/lib/autonomy/ConfirmationManager.js.map +0 -1
- package/dist/infra/lib/autonomy/ConfirmationStore.d.ts +0 -55
- package/dist/infra/lib/autonomy/ConfirmationStore.d.ts.map +0 -1
- package/dist/infra/lib/autonomy/ConfirmationStore.js +0 -130
- package/dist/infra/lib/autonomy/ConfirmationStore.js.map +0 -1
- package/dist/infra/lib/autonomy/EventBus.d.ts +0 -20
- package/dist/infra/lib/autonomy/EventBus.d.ts.map +0 -1
- package/dist/infra/lib/autonomy/EventBus.js +0 -119
- package/dist/infra/lib/autonomy/EventBus.js.map +0 -1
- package/dist/infra/lib/autonomy/EventOutbox.d.ts +0 -32
- package/dist/infra/lib/autonomy/EventOutbox.d.ts.map +0 -1
- package/dist/infra/lib/autonomy/EventOutbox.js +0 -152
- package/dist/infra/lib/autonomy/EventOutbox.js.map +0 -1
- package/dist/infra/lib/autonomy/NotificationDispatcher.d.ts +0 -24
- package/dist/infra/lib/autonomy/NotificationDispatcher.d.ts.map +0 -1
- package/dist/infra/lib/autonomy/NotificationDispatcher.js +0 -112
- package/dist/infra/lib/autonomy/NotificationDispatcher.js.map +0 -1
- package/dist/infra/lib/autonomy/PolicyEngine.d.ts +0 -76
- package/dist/infra/lib/autonomy/PolicyEngine.d.ts.map +0 -1
- package/dist/infra/lib/autonomy/PolicyEngine.js +0 -208
- package/dist/infra/lib/autonomy/PolicyEngine.js.map +0 -1
- package/dist/infra/lib/autonomy/ProactiveAnalyzer.d.ts +0 -61
- package/dist/infra/lib/autonomy/ProactiveAnalyzer.d.ts.map +0 -1
- package/dist/infra/lib/autonomy/ProactiveAnalyzer.js +0 -236
- package/dist/infra/lib/autonomy/ProactiveAnalyzer.js.map +0 -1
- package/dist/infra/lib/autonomy/RiskClassifier.d.ts +0 -35
- package/dist/infra/lib/autonomy/RiskClassifier.d.ts.map +0 -1
- package/dist/infra/lib/autonomy/RiskClassifier.js +0 -147
- package/dist/infra/lib/autonomy/RiskClassifier.js.map +0 -1
- package/dist/infra/lib/autonomy/SecuritySentinel.d.ts +0 -51
- package/dist/infra/lib/autonomy/SecuritySentinel.d.ts.map +0 -1
- package/dist/infra/lib/autonomy/SecuritySentinel.js +0 -162
- package/dist/infra/lib/autonomy/SecuritySentinel.js.map +0 -1
- package/dist/infra/lib/autonomy/SuggestionStore.d.ts +0 -54
- package/dist/infra/lib/autonomy/SuggestionStore.d.ts.map +0 -1
- package/dist/infra/lib/autonomy/SuggestionStore.js +0 -144
- package/dist/infra/lib/autonomy/SuggestionStore.js.map +0 -1
- package/dist/infra/lib/autonomy/TaskDecomposer.d.ts +0 -38
- package/dist/infra/lib/autonomy/TaskDecomposer.d.ts.map +0 -1
- package/dist/infra/lib/autonomy/TaskDecomposer.js +0 -175
- package/dist/infra/lib/autonomy/TaskDecomposer.js.map +0 -1
- package/dist/infra/lib/autonomy/__tests__/audit-store.test.d.ts +0 -2
- package/dist/infra/lib/autonomy/__tests__/audit-store.test.d.ts.map +0 -1
- package/dist/infra/lib/autonomy/__tests__/audit-store.test.js +0 -198
- package/dist/infra/lib/autonomy/__tests__/audit-store.test.js.map +0 -1
- package/dist/infra/lib/autonomy/__tests__/event-bus.test.d.ts +0 -2
- package/dist/infra/lib/autonomy/__tests__/event-bus.test.d.ts.map +0 -1
- package/dist/infra/lib/autonomy/__tests__/event-bus.test.js +0 -225
- package/dist/infra/lib/autonomy/__tests__/event-bus.test.js.map +0 -1
- package/dist/infra/lib/autonomy/__tests__/event-core.test.d.ts +0 -2
- package/dist/infra/lib/autonomy/__tests__/event-core.test.d.ts.map +0 -1
- package/dist/infra/lib/autonomy/__tests__/event-core.test.js +0 -194
- package/dist/infra/lib/autonomy/__tests__/event-core.test.js.map +0 -1
- package/dist/infra/lib/autonomy/__tests__/governance.test.d.ts +0 -2
- package/dist/infra/lib/autonomy/__tests__/governance.test.d.ts.map +0 -1
- package/dist/infra/lib/autonomy/__tests__/governance.test.js +0 -540
- package/dist/infra/lib/autonomy/__tests__/governance.test.js.map +0 -1
- package/dist/infra/lib/autonomy/__tests__/integration.test.d.ts +0 -2
- package/dist/infra/lib/autonomy/__tests__/integration.test.d.ts.map +0 -1
- package/dist/infra/lib/autonomy/__tests__/integration.test.js +0 -480
- package/dist/infra/lib/autonomy/__tests__/integration.test.js.map +0 -1
- package/dist/infra/lib/autonomy/__tests__/proactive.test.d.ts +0 -2
- package/dist/infra/lib/autonomy/__tests__/proactive.test.d.ts.map +0 -1
- package/dist/infra/lib/autonomy/__tests__/proactive.test.js +0 -410
- package/dist/infra/lib/autonomy/__tests__/proactive.test.js.map +0 -1
- package/dist/infra/lib/autonomy/__tests__/sentinel.test.d.ts +0 -2
- package/dist/infra/lib/autonomy/__tests__/sentinel.test.d.ts.map +0 -1
- package/dist/infra/lib/autonomy/__tests__/sentinel.test.js +0 -486
- package/dist/infra/lib/autonomy/__tests__/sentinel.test.js.map +0 -1
- package/dist/infra/lib/autonomy/index.d.ts +0 -18
- package/dist/infra/lib/autonomy/index.d.ts.map +0 -1
- package/dist/infra/lib/autonomy/index.js +0 -22
- package/dist/infra/lib/autonomy/index.js.map +0 -1
- package/dist/infra/lib/autonomy/schemas.d.ts +0 -317
- package/dist/infra/lib/autonomy/schemas.d.ts.map +0 -1
- package/dist/infra/lib/autonomy/schemas.js +0 -90
- package/dist/infra/lib/autonomy/schemas.js.map +0 -1
- package/dist/infra/lib/claude/index.d.ts +0 -5
- package/dist/infra/lib/claude/index.d.ts.map +0 -1
- package/dist/infra/lib/claude/index.js +0 -5
- package/dist/infra/lib/claude/index.js.map +0 -1
- package/dist/infra/lib/claude/storage.d.ts +0 -12
- package/dist/infra/lib/claude/storage.d.ts.map +0 -1
- package/dist/infra/lib/claude/storage.js +0 -54
- package/dist/infra/lib/claude/storage.js.map +0 -1
- package/dist/infra/lib/gemini/auth.d.ts +0 -18
- package/dist/infra/lib/gemini/auth.d.ts.map +0 -1
- package/dist/infra/lib/gemini/auth.js +0 -32
- package/dist/infra/lib/gemini/auth.js.map +0 -1
- package/dist/infra/lib/gemini/capabilities.d.ts +0 -28
- package/dist/infra/lib/gemini/capabilities.d.ts.map +0 -1
- package/dist/infra/lib/gemini/capabilities.js +0 -178
- package/dist/infra/lib/gemini/capabilities.js.map +0 -1
- package/dist/infra/lib/gemini/chat.d.ts +0 -35
- package/dist/infra/lib/gemini/chat.d.ts.map +0 -1
- package/dist/infra/lib/gemini/chat.js +0 -161
- package/dist/infra/lib/gemini/chat.js.map +0 -1
- package/dist/infra/lib/gemini/completion.d.ts +0 -12
- package/dist/infra/lib/gemini/completion.d.ts.map +0 -1
- package/dist/infra/lib/gemini/completion.js +0 -13
- package/dist/infra/lib/gemini/completion.js.map +0 -1
- package/dist/infra/lib/gemini/constants.d.ts +0 -8
- package/dist/infra/lib/gemini/constants.d.ts.map +0 -1
- package/dist/infra/lib/gemini/constants.js +0 -11
- package/dist/infra/lib/gemini/constants.js.map +0 -1
- package/dist/infra/lib/gemini/index.d.ts +0 -13
- package/dist/infra/lib/gemini/index.d.ts.map +0 -1
- package/dist/infra/lib/gemini/index.js +0 -12
- package/dist/infra/lib/gemini/index.js.map +0 -1
- package/dist/infra/lib/gemini/models.d.ts +0 -11
- package/dist/infra/lib/gemini/models.d.ts.map +0 -1
- package/dist/infra/lib/gemini/models.js +0 -38
- package/dist/infra/lib/gemini/models.js.map +0 -1
- package/dist/infra/lib/gemini/orchestration.d.ts +0 -33
- package/dist/infra/lib/gemini/orchestration.d.ts.map +0 -1
- package/dist/infra/lib/gemini/orchestration.js +0 -62
- package/dist/infra/lib/gemini/orchestration.js.map +0 -1
- package/dist/infra/lib/gemini/types.d.ts +0 -115
- package/dist/infra/lib/gemini/types.d.ts.map +0 -1
- package/dist/infra/lib/gemini/types.js +0 -5
- package/dist/infra/lib/gemini/types.js.map +0 -1
- package/dist/infra/orchestrator/AgentAnnouncer.d.ts +0 -64
- package/dist/infra/orchestrator/AgentAnnouncer.d.ts.map +0 -1
- package/dist/infra/orchestrator/AgentAnnouncer.js +0 -127
- package/dist/infra/orchestrator/AgentAnnouncer.js.map +0 -1
- package/dist/infra/orchestrator/AgentAnnouncer.test.d.ts +0 -5
- package/dist/infra/orchestrator/AgentAnnouncer.test.d.ts.map +0 -1
- package/dist/infra/orchestrator/AgentAnnouncer.test.js +0 -119
- package/dist/infra/orchestrator/AgentAnnouncer.test.js.map +0 -1
- package/dist/infra/orchestrator/AgentExecutor.d.ts +0 -22
- package/dist/infra/orchestrator/AgentExecutor.d.ts.map +0 -1
- package/dist/infra/orchestrator/AgentExecutor.js +0 -272
- package/dist/infra/orchestrator/AgentExecutor.js.map +0 -1
- package/dist/infra/orchestrator/AgentManager.d.ts +0 -72
- package/dist/infra/orchestrator/AgentManager.d.ts.map +0 -1
- package/dist/infra/orchestrator/AgentManager.js +0 -183
- package/dist/infra/orchestrator/AgentManager.js.map +0 -1
- package/dist/infra/orchestrator/AgentManifestCache.d.ts +0 -54
- package/dist/infra/orchestrator/AgentManifestCache.d.ts.map +0 -1
- package/dist/infra/orchestrator/AgentManifestCache.js +0 -191
- package/dist/infra/orchestrator/AgentManifestCache.js.map +0 -1
- package/dist/infra/orchestrator/AgentRegistry.d.ts +0 -76
- package/dist/infra/orchestrator/AgentRegistry.d.ts.map +0 -1
- package/dist/infra/orchestrator/AgentRegistry.js +0 -217
- package/dist/infra/orchestrator/AgentRegistry.js.map +0 -1
- package/dist/infra/orchestrator/AgentRegistry.test.d.ts +0 -5
- package/dist/infra/orchestrator/AgentRegistry.test.d.ts.map +0 -1
- package/dist/infra/orchestrator/AgentRegistry.test.js +0 -122
- package/dist/infra/orchestrator/AgentRegistry.test.js.map +0 -1
- package/dist/infra/orchestrator/BackgroundManager.d.ts +0 -128
- package/dist/infra/orchestrator/BackgroundManager.d.ts.map +0 -1
- package/dist/infra/orchestrator/BackgroundManager.js +0 -620
- package/dist/infra/orchestrator/BackgroundManager.js.map +0 -1
- package/dist/infra/orchestrator/BackgroundManager.test.d.ts +0 -6
- package/dist/infra/orchestrator/BackgroundManager.test.d.ts.map +0 -1
- package/dist/infra/orchestrator/BackgroundManager.test.js +0 -162
- package/dist/infra/orchestrator/BackgroundManager.test.js.map +0 -1
- package/dist/infra/orchestrator/CheckpointManager.d.ts +0 -54
- package/dist/infra/orchestrator/CheckpointManager.d.ts.map +0 -1
- package/dist/infra/orchestrator/CheckpointManager.js +0 -121
- package/dist/infra/orchestrator/CheckpointManager.js.map +0 -1
- package/dist/infra/orchestrator/CodexAgentRuntime.d.ts +0 -12
- package/dist/infra/orchestrator/CodexAgentRuntime.d.ts.map +0 -1
- package/dist/infra/orchestrator/CodexAgentRuntime.js +0 -94
- package/dist/infra/orchestrator/CodexAgentRuntime.js.map +0 -1
- package/dist/infra/orchestrator/CodexAgentRuntime.test.d.ts +0 -2
- package/dist/infra/orchestrator/CodexAgentRuntime.test.d.ts.map +0 -1
- package/dist/infra/orchestrator/CodexAgentRuntime.test.js +0 -37
- package/dist/infra/orchestrator/CodexAgentRuntime.test.js.map +0 -1
- package/dist/infra/orchestrator/LLMCluster.d.ts +0 -82
- package/dist/infra/orchestrator/LLMCluster.d.ts.map +0 -1
- package/dist/infra/orchestrator/LLMCluster.js +0 -146
- package/dist/infra/orchestrator/LLMCluster.js.map +0 -1
- package/dist/infra/orchestrator/MultiLlmResearch.d.ts +0 -31
- package/dist/infra/orchestrator/MultiLlmResearch.d.ts.map +0 -1
- package/dist/infra/orchestrator/MultiLlmResearch.js +0 -160
- package/dist/infra/orchestrator/MultiLlmResearch.js.map +0 -1
- package/dist/infra/orchestrator/PhasePipeline.d.ts +0 -122
- package/dist/infra/orchestrator/PhasePipeline.d.ts.map +0 -1
- package/dist/infra/orchestrator/PhasePipeline.js +0 -385
- package/dist/infra/orchestrator/PhasePipeline.js.map +0 -1
- package/dist/infra/orchestrator/PhaseResultStore.d.ts +0 -39
- package/dist/infra/orchestrator/PhaseResultStore.d.ts.map +0 -1
- package/dist/infra/orchestrator/PhaseResultStore.js +0 -151
- package/dist/infra/orchestrator/PhaseResultStore.js.map +0 -1
- package/dist/infra/orchestrator/SessionStore.d.ts +0 -40
- package/dist/infra/orchestrator/SessionStore.d.ts.map +0 -1
- package/dist/infra/orchestrator/SessionStore.js +0 -116
- package/dist/infra/orchestrator/SessionStore.js.map +0 -1
- package/dist/infra/orchestrator/SmartRouter.d.ts +0 -90
- package/dist/infra/orchestrator/SmartRouter.d.ts.map +0 -1
- package/dist/infra/orchestrator/SmartRouter.js +0 -277
- package/dist/infra/orchestrator/SmartRouter.js.map +0 -1
- package/dist/infra/orchestrator/SmartRouter.test.d.ts +0 -5
- package/dist/infra/orchestrator/SmartRouter.test.d.ts.map +0 -1
- package/dist/infra/orchestrator/SmartRouter.test.js +0 -484
- package/dist/infra/orchestrator/SmartRouter.test.js.map +0 -1
- package/dist/infra/orchestrator/SwarmOrchestrator.d.ts +0 -143
- package/dist/infra/orchestrator/SwarmOrchestrator.d.ts.map +0 -1
- package/dist/infra/orchestrator/SwarmOrchestrator.js +0 -378
- package/dist/infra/orchestrator/SwarmOrchestrator.js.map +0 -1
- package/dist/infra/orchestrator/SwarmOrchestrator.test.d.ts +0 -5
- package/dist/infra/orchestrator/SwarmOrchestrator.test.d.ts.map +0 -1
- package/dist/infra/orchestrator/SwarmOrchestrator.test.js +0 -95
- package/dist/infra/orchestrator/SwarmOrchestrator.test.js.map +0 -1
- package/dist/infra/orchestrator/agentDiscovery.d.ts +0 -26
- package/dist/infra/orchestrator/agentDiscovery.d.ts.map +0 -1
- package/dist/infra/orchestrator/agentDiscovery.js +0 -175
- package/dist/infra/orchestrator/agentDiscovery.js.map +0 -1
- package/dist/infra/orchestrator/backgroundAgent.d.ts +0 -9
- package/dist/infra/orchestrator/backgroundAgent.d.ts.map +0 -1
- package/dist/infra/orchestrator/backgroundAgent.js +0 -10
- package/dist/infra/orchestrator/backgroundAgent.js.map +0 -1
- package/dist/infra/orchestrator/index.d.ts +0 -207
- package/dist/infra/orchestrator/index.d.ts.map +0 -1
- package/dist/infra/orchestrator/index.js +0 -362
- package/dist/infra/orchestrator/index.js.map +0 -1
- package/dist/infra/orchestrator/orchestrator.d.ts +0 -60
- package/dist/infra/orchestrator/orchestrator.d.ts.map +0 -1
- package/dist/infra/orchestrator/orchestrator.js +0 -214
- package/dist/infra/orchestrator/orchestrator.js.map +0 -1
- package/dist/infra/orchestrator/parallelResearch.d.ts +0 -27
- package/dist/infra/orchestrator/parallelResearch.d.ts.map +0 -1
- package/dist/infra/orchestrator/parallelResearch.js +0 -285
- package/dist/infra/orchestrator/parallelResearch.js.map +0 -1
- package/dist/infra/orchestrator/types.d.ts +0 -205
- package/dist/infra/orchestrator/types.d.ts.map +0 -1
- package/dist/infra/orchestrator/types.js +0 -87
- package/dist/infra/orchestrator/types.js.map +0 -1
- package/dist/infra/orchestrator/types.test.d.ts +0 -2
- package/dist/infra/orchestrator/types.test.d.ts.map +0 -1
- package/dist/infra/orchestrator/types.test.js +0 -57
- package/dist/infra/orchestrator/types.test.js.map +0 -1
- package/dist/tools/semantic/analyzeDependencyGraph.d.ts +0 -12
- package/dist/tools/semantic/analyzeDependencyGraph.d.ts.map +0 -1
- package/dist/tools/semantic/analyzeDependencyGraph.js +0 -359
- package/dist/tools/semantic/analyzeDependencyGraph.js.map +0 -1
- package/dist/tools/semantic/astGrep.d.ts +0 -25
- package/dist/tools/semantic/astGrep.d.ts.map +0 -1
- package/dist/tools/semantic/astGrep.js +0 -324
- package/dist/tools/semantic/astGrep.js.map +0 -1
- package/dist/tools/semantic/astGrep.test.d.ts +0 -2
- package/dist/tools/semantic/astGrep.test.d.ts.map +0 -1
- package/dist/tools/semantic/astGrep.test.js +0 -74
- package/dist/tools/semantic/astGrep.test.js.map +0 -1
- package/dist/tools/semantic/findReferences.d.ts +0 -9
- package/dist/tools/semantic/findReferences.d.ts.map +0 -1
- package/dist/tools/semantic/findReferences.js +0 -200
- package/dist/tools/semantic/findReferences.js.map +0 -1
- package/dist/tools/semantic/findSymbol.d.ts +0 -8
- package/dist/tools/semantic/findSymbol.d.ts.map +0 -1
- package/dist/tools/semantic/findSymbol.js +0 -204
- package/dist/tools/semantic/findSymbol.js.map +0 -1
- package/dist/tools/semantic/index.d.ts +0 -9
- package/dist/tools/semantic/index.d.ts.map +0 -1
- package/dist/tools/semantic/index.js +0 -11
- package/dist/tools/semantic/index.js.map +0 -1
- package/dist/tools/semantic/lsp.d.ts +0 -68
- package/dist/tools/semantic/lsp.d.ts.map +0 -1
- package/dist/tools/semantic/lsp.js +0 -561
- package/dist/tools/semantic/lsp.js.map +0 -1
- package/dist/tools/spec/e2eTestGenerator.d.ts +0 -61
- package/dist/tools/spec/e2eTestGenerator.d.ts.map +0 -1
- package/dist/tools/spec/e2eTestGenerator.js +0 -255
- package/dist/tools/spec/e2eTestGenerator.js.map +0 -1
- package/dist/tools/spec/specVersioning.d.ts +0 -76
- package/dist/tools/spec/specVersioning.d.ts.map +0 -1
- package/dist/tools/spec/specVersioning.js +0 -236
- 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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
if (
|
|
279
|
-
|
|
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.
|
|
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 &&
|
|
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"
|
package/skills/clone/SKILL.md
CHANGED
|
@@ -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
|
-
✅
|
|
28
|
-
|
|
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
|
|
47
|
-
|
|
48
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
│
|
|
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
|
|
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**
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
section's
|
|
275
|
-
model, list states to implement, choose tags,
|
|
276
|
-
|
|
277
|
-
|
|
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
|
|
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
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
├─
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
├─
|
|
293
|
-
└─
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
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> blocks — only @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
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
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
|
-
|
|
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
|
|
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. |
|