vibe-ui-suite 4.1.0 → 6.2.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/README.md CHANGED
@@ -46,14 +46,18 @@ This interactive command sets up:
46
46
  Add verified, zero-emoji, accessible React 19 component templates directly into your codebase (`components/vibe-ui/`):
47
47
 
48
48
  ```bash
49
- # Add an expandable reasoning / thinking trace drawer
49
+ # Core AI & Telemetry Primitives:
50
50
  npx vibe-ui-suite add thinking-drawer
51
-
52
- # Add a dense telemetry HUD with live metric formatting
53
51
  npx vibe-ui-suite add telemetry-hud
54
-
55
- # Add a real-time WCAG AAA contrast indicator badge
56
52
  npx vibe-ui-suite add contrast-badge
53
+ npx vibe-ui-suite add theme-toggle
54
+
55
+ # Living Micro-Interactions (v6.1.0):
56
+ npx vibe-ui-suite add shimmer-button
57
+ npx vibe-ui-suite add cyber-loader
58
+ npx vibe-ui-suite add holographic-card
59
+ npx vibe-ui-suite add tactile-switch
60
+ npx vibe-ui-suite add glow-input
57
61
  ```
58
62
 
59
63
  ### 3. List Registry Components (`list`)
@@ -62,6 +66,13 @@ npx vibe-ui-suite add contrast-badge
62
66
  npx vibe-ui-suite list
63
67
  ```
64
68
 
69
+ ### 4. Galaxy Inspiration Engine (`inspire`)
70
+
71
+ Search 3,800+ community micro-interactions with offline caching:
72
+ ```bash
73
+ npx vibe-ui-suite inspire "neon button"
74
+ ```
75
+
65
76
  ---
66
77
 
67
78
  ## 🎨 Programmatic Usage
@@ -77,7 +88,7 @@ In your global stylesheet (e.g. `app/globals.css` or `src/index.css`):
77
88
 
78
89
  Zero JavaScript configuration files required. Instantly unlocks:
79
90
  - **Semantic Color Utilities:** `bg-vibe-canvas`, `bg-vibe-surface`, `text-vibe-primary`, `border-vibe-border`
80
- - **Physics Springs:** `transition-vibe-spring`, `transition-vibe-snap`, `transition-vibe-glide`
91
+ - **Physics Springs:** `ease-vibe-spring`, `ease-vibe-snap`, `ease-vibe-glide` (or utility `.vibe-spring`)
81
92
  - **Surface Elevation:** `shadow-vibe-brutal`, `shadow-vibe-glass`
82
93
 
83
94
  ---
package/dist/cli.js CHANGED
@@ -39,36 +39,47 @@ const path = __importStar(require("path"));
39
39
  const readline = __importStar(require("readline"));
40
40
  const components_1 = require("./registry/components");
41
41
  const index_1 = require("./index");
42
- const VERSION = '4.0.0';
42
+ const VERSION = '6.2.0';
43
43
  function printBanner() {
44
- console.log(`
45
- \x1b[35m ▲ VIBE UI CLI v${VERSION}\x1b[0m
46
- \x1b[90mDeterministic UI contracts & component primitives for AI coding assistants\x1b[0m
44
+ console.log(`
45
+ \x1b[35m ▲ VIBE UI CLI v${VERSION}\x1b[0m
46
+ \x1b[90mDeterministic UI contracts, 11 design paradigms & flagship components for AI coding assistants\x1b[0m
47
47
  `);
48
48
  }
49
49
  function printHelp() {
50
50
  printBanner();
51
- console.log(`\x1b[1mUSAGE:\x1b[0m
52
- npx vibe-ui-suite <command> [options]
53
- npx @omid-io/tokens <command> [options]
54
- vibe-ui <command> [options]
55
-
56
- \x1b[1mCOMMANDS:\x1b[0m
57
- \x1b[32minit\x1b[0m Initialize Vibe UI contracts, OKLCH tokens & AI rules in current project
58
- \x1b[32madd <component>\x1b[0m Add an accessible, AI-native component template to your project
59
- \x1b[32mlist\x1b[0m List all available component primitives in the registry
60
-
61
- \x1b[1mOPTIONS:\x1b[0m
62
- -f, --force Overwrite existing files (creates automated .bak backups)
63
- --dry-run Preview file operations without making actual modifications
64
- -v, --version Show CLI version
65
- -h, --help Show help menu
66
-
67
- \x1b[1mEXAMPLES:\x1b[0m
68
- npx vibe-ui-suite init
69
- npx vibe-ui-suite init --dry-run
70
- npx vibe-ui-suite add thinking-drawer
71
- npx vibe-ui-suite add thinking-drawer --force
51
+ console.log(`\x1b[1mUSAGE:\x1b[0m
52
+ npx vibe-ui-suite <command> [options]
53
+ vibe-ui <command> [options]
54
+
55
+ \x1b[1mCOMMANDS:\x1b[0m
56
+ \x1b[32minit\x1b[0m Initialize Vibe UI contracts, 11 paradigm tokens & AI rules in current project
57
+ \x1b[32msync\x1b[0m Synchronize existing AI contracts to canonical v${VERSION} master rules
58
+ \x1b[32minstall-skills\x1b[0m Install or update Vibe UI agent skills in .agents/skills/
59
+ \x1b[32madd <component>\x1b[0m Add an accessible, AI-native component template to your project
60
+ \x1b[32mlist\x1b[0m List all available component primitives in the registry
61
+
62
+ \x1b[1mOPTIONS:\x1b[0m
63
+ -f, --force Overwrite existing files (creates automated .bak backups)
64
+ -y, --yes Non-interactive mode (use defaults without prompting)
65
+ --chemistry <1-5> Select visual chemistry in non-interactive mode
66
+ --editor <1-4> Select target AI editor in non-interactive mode (1: Cursor, 2: Claude, 3: Windsurf, 4: All)
67
+ --dry-run Preview file operations without making actual modifications
68
+ -v, --version Show CLI version
69
+ -h, --help Show help menu
70
+
71
+ \x1b[1mEXAMPLES:\x1b[0m
72
+ npx vibe-ui-suite init
73
+ npx vibe-ui-suite init -y
74
+ npx vibe-ui-suite sync
75
+ npx vibe-ui-suite install-skills
76
+ npx vibe-ui-suite add device-mockup
77
+ npx vibe-ui-suite add before-after-lens
78
+ npx vibe-ui-suite add specular-card
79
+ npx vibe-ui-suite add thinking-drawer
80
+ npx vibe-ui-suite add shimmer-button
81
+ npx vibe-ui-suite add theme-toggle
82
+ npx vibe-ui-suite add device-mockup --force
72
83
  `);
73
84
  }
74
85
  function prompt(rl, query) {
@@ -94,115 +105,266 @@ function safeWriteFile(filePath, content, options) {
94
105
  fs.writeFileSync(filePath, content, 'utf-8');
95
106
  return { written: true, skipped: false };
96
107
  }
97
- const CONTRACT_RULES = `# Vibe UI Design & Code Quality Contract
98
- # Generated via npx vibe-ui-suite init
99
-
100
- Follow strict anti-slop guidelines:
101
- - Zero raw unicode emojis (use inline SVGs only)
102
- - Strict WCAG 2.2 AA contrast (>= 4.5:1 body, >= 3.0:1 headings)
103
- - Use typed OKLCH color spaces for perceptual accuracy
104
- - Strict maximum of 3 backdrop-filter / glass layers
105
- - Semantic RTL: preserve physical macro coordinate stability
108
+ const CONTRACT_RULES = `# 👑 Vibe UI Master Design & Architecture Contract (v6.2.0)
109
+ # Generated via npx vibe-ui-suite init / sync
110
+
111
+ ## 🏛️ The 5 Master Execution Gates & Autonomous Lazy-Prompt Protocol
112
+ When receiving UI design or redesign prompts (especially lazy prompts: "design this", "redesign this", "make it look good", "make it pop", "craft a modern UI"):
113
+
114
+ 1. 📸 MANDATORY PRE-EDIT VISUAL AUDIT:
115
+ - Before editing any code, capture an initial browser screenshot (screenshots/before.png).
116
+ - Visually critique layout flaws, spacing balance, visual hierarchy, and focal points with multimodal vision.
117
+
118
+ 2. 🎨 ARCHITECTURAL PARADIGM & TREND BENCHMARKING:
119
+ - Benchmark against premier design sources: Dribbble, Figma Community, Mobbin, and Awwwards.
120
+ - Autonomously select a modern paradigm (Bento Grid, Linear Minimal, Stripe Crisp Light, Swiss Editorial).
121
+ - Light Mode is the primary default canvas (#ffffff/#f8fafc). Mandatory dual-theme support with accessible Dark Mode toggle.
122
+
123
+ 3. 🧱 STRUCTURAL DOM & SPATIAL OVERHAUL:
124
+ - ZERO COSMETIC-ONLY PATCH INVARIANT: Strictly forbidden to perform shallow skin-patches (altering only colors, borders, or emojis while leaving dead layouts untouched).
125
+ - Overhaul structural spatial rhythm, 8pt spacing system, and asymmetric bento card hierarchies.
126
+ - Inject tactile micro-interactions (shimmer buttons, cyber loaders, tactile switches, holographic cards) and authentic imagery.
127
+ - CONTEXTUAL CREATIVE MEDIA: Background video is strictly contextual (for creative/cinematic requests only); never force video onto utility SaaS or dashboards. Intelligently evaluate whether curated video, lightweight SVG particles, or static photography deliver the cleanest UX.
128
+
129
+ 4. 👁️ MULTI-VIEWPORT LIVING VISUAL VERIFICATION:
130
+ - Capture post-edit full-page screenshots (screenshots/after.png, Desktop 1440px / Mobile 390px).
131
+ - Multimodal self-critique: verify visual rhythm, zero horizontal overflow, and pristine typography hierarchy before handoff.
132
+
133
+ 5. 🧼 SILENT TABLE-STAKES (INTERNAL WORKER BASELINES):
134
+ - Low-level hygiene (OKLCH color math, WCAG AAA formulas, zero raw unicode emojis -> inline SVGs, <bdi> bidirectional text isolation) are silent worker requirements.
135
+ - NEVER report these hygiene baselines as headline accomplishments or key deliverables in chat summaries.
136
+ - Chat summaries MUST lead with architectural layout transformations, aesthetic paradigm chosen, and visual before/after evidence.
106
137
  `;
138
+ function findSourceSkillsDir() {
139
+ const candidates = [
140
+ path.resolve(__dirname, '..', 'skills'),
141
+ path.resolve(__dirname, 'skills'),
142
+ path.resolve(__dirname, '..', '..', '..', 'skills'),
143
+ path.resolve(process.cwd(), 'skills'),
144
+ ];
145
+ for (const c of candidates) {
146
+ if (fs.existsSync(c) && fs.existsSync(path.join(c, 'ui-kit', 'SKILL.md'))) {
147
+ return c;
148
+ }
149
+ }
150
+ return null;
151
+ }
152
+ function installSkills(targetProjectDir, options) {
153
+ const srcSkillsDir = findSourceSkillsDir();
154
+ const installed = [];
155
+ const skipped = [];
156
+ if (!srcSkillsDir) {
157
+ console.log(' \x1b[33m[warn]\x1b[0m Could not locate Vibe UI skills source directory to install.');
158
+ return { installed, skipped };
159
+ }
160
+ const destSkillsDir = path.join(targetProjectDir, '.agents', 'skills');
161
+ if (options.dryRun) {
162
+ console.log(` \x1b[34m[dry-run]\x1b[0m Would install Vibe UI skills to: ${path.relative(process.cwd(), destSkillsDir)}`);
163
+ return { installed, skipped };
164
+ }
165
+ if (!fs.existsSync(destSkillsDir)) {
166
+ fs.mkdirSync(destSkillsDir, { recursive: true });
167
+ }
168
+ const skillsList = fs.readdirSync(srcSkillsDir).filter((f) => {
169
+ const full = path.join(srcSkillsDir, f);
170
+ return fs.statSync(full).isDirectory() && fs.existsSync(path.join(full, 'SKILL.md'));
171
+ });
172
+ for (const skillName of skillsList) {
173
+ const srcSkillPath = path.join(srcSkillsDir, skillName);
174
+ const destSkillPath = path.join(destSkillsDir, skillName);
175
+ if (fs.existsSync(destSkillPath) && !options.force) {
176
+ skipped.push(skillName);
177
+ continue;
178
+ }
179
+ if (fs.existsSync(destSkillPath) && options.force) {
180
+ fs.rmSync(destSkillPath, { recursive: true, force: true });
181
+ }
182
+ fs.cpSync(srcSkillPath, destSkillPath, { recursive: true });
183
+ installed.push(skillName);
184
+ }
185
+ return { installed, skipped };
186
+ }
187
+ async function handleInstallSkills(options) {
188
+ printBanner();
189
+ console.log('\x1b[36mInstalling Vibe UI Agent Skills into current project workspace (.agents/skills/)...\x1b[0m\n');
190
+ const cwd = process.cwd();
191
+ const res = installSkills(cwd, options);
192
+ if (res.installed.length > 0) {
193
+ console.log(`\n\x1b[32m✔ Successfully installed ${res.installed.length} skill(s) in .agents/skills/:\x1b[0m`);
194
+ res.installed.forEach((s) => console.log(` + .agents/skills/${s}`));
195
+ }
196
+ if (res.skipped.length > 0) {
197
+ console.log(`\n\x1b[33mSkipped ${res.skipped.length} existing skill(s) (use --force to overwrite):\x1b[0m`);
198
+ res.skipped.forEach((s) => console.log(` - ${s}`));
199
+ }
200
+ }
201
+ async function handleSync(options) {
202
+ printBanner();
203
+ console.log('\x1b[36mSynchronizing AI contracts to canonical v6.2.0 Master Architectural Standard...\x1b[0m\n');
204
+ const cwd = process.cwd();
205
+ const targetFiles = ['.cursorrules', '.windsurfrules', 'CLAUDE.md'];
206
+ let updatedCount = 0;
207
+ for (const filename of targetFiles) {
208
+ const filePath = path.join(cwd, filename);
209
+ if (fs.existsSync(filePath)) {
210
+ const res = safeWriteFile(filePath, CONTRACT_RULES, { ...options, force: true });
211
+ if (res.written) {
212
+ console.log(` \x1b[32m✔\x1b[0m Updated \x1b[1m${filename}\x1b[0m to v6.2.0 contract rules`);
213
+ updatedCount++;
214
+ }
215
+ }
216
+ }
217
+ const destSkills = path.join(cwd, '.agents', 'skills');
218
+ if (fs.existsSync(destSkills) || updatedCount > 0) {
219
+ console.log('\n\x1b[36mSynchronizing Vibe UI workspace skills (.agents/skills/):\x1b[0m');
220
+ const skillRes = installSkills(cwd, { ...options, force: true });
221
+ if (skillRes.installed.length > 0) {
222
+ console.log(` \x1b[32m✔\x1b[0m Synchronized ${skillRes.installed.length} skills in .agents/skills/`);
223
+ }
224
+ }
225
+ if (updatedCount === 0) {
226
+ console.log(' \x1b[33mNo existing AI rule files found in current directory.\x1b[0m');
227
+ console.log(' Run \x1b[32mnpx vibe-ui-suite init\x1b[0m to initialize contracts from scratch.');
228
+ }
229
+ else {
230
+ console.log(`\n\x1b[32m✔ Successfully synchronized AI rule file(s) and workspace skills to v6.2.0!\x1b[0m`);
231
+ }
232
+ }
107
233
  async function handleInit(options) {
108
234
  printBanner();
109
235
  if (options.dryRun) {
110
236
  console.log('\x1b[34m[DRY-RUN MODE ACTIVATED: No files will be modified on disk]\x1b[0m\n');
111
237
  }
112
- const rl = readline.createInterface({
113
- input: process.stdin,
114
- output: process.stdout,
115
- });
116
- try {
117
- console.log('\x1b[1mInitialize Vibe UI in current workspace:\x1b[0m\n');
118
- // 1. Select Visual Chemistry
119
- console.log('\x1b[36m1. Select Visual Chemistry:\x1b[0m');
120
- console.log(' [1] Minimalist SaaS (Monochrome restraint, high signal - Recommended)');
121
- console.log(' [2] Luxury Glass 2.0 (Specular Fresnel, deep dark, gold accents)');
122
- console.log(' [3] Neobrutalism (Hard 3px black offset shadows, bold high saturation)');
123
- console.log(' [4] Swiss Editorial (Asymmetric grid, typography-first, high contrast)');
124
- console.log(' [5] Stripe Crisp Light (Developer docs, precision micro-borders)');
125
- const chemChoice = (await prompt(rl, 'Choice [1-5] (default: 1): ')).trim() || '1';
126
- const chemMap = {
127
- '1': 'MINIMALIST_SAAS',
128
- '2': 'LUXURY_GLASS_2',
129
- '3': 'NEOBRUTALISM',
130
- '4': 'SWISS_EDITORIAL',
131
- '5': 'STRIPE_CRISP_LIGHT',
132
- };
133
- const selectedChemKey = chemMap[chemChoice] || 'MINIMALIST_SAAS';
134
- const selectedChem = index_1.VISUAL_CHEMISTRIES[selectedChemKey];
135
- // 2. Select AI Editor
136
- console.log('\n\x1b[36m2. Select AI Coding Environment:\x1b[0m');
137
- console.log(' [1] Cursor (.cursorrules - Recommended)');
138
- console.log(' [2] Claude Code (CLAUDE.md)');
139
- console.log(' [3] Windsurf (.windsurfrules)');
140
- console.log(' [4] All of the above');
141
- const editorChoice = (await prompt(rl, 'Choice [1-4] (default: 1): ')).trim() || '1';
142
- // 3. Write contract rules safely
143
- const cwd = process.cwd();
144
- const createdFiles = [];
145
- if (editorChoice === '1' || editorChoice === '4') {
146
- const res = safeWriteFile(path.join(cwd, '.cursorrules'), CONTRACT_RULES, options);
147
- if (res.written)
148
- createdFiles.push('.cursorrules');
238
+ const isInteractive = !options.yes && Boolean(process.stdin.isTTY);
239
+ let chemChoice = options.chemistry || '1';
240
+ let editorChoice = options.editor || '4';
241
+ const chemMap = {
242
+ '1': 'MINIMALIST_SAAS',
243
+ '2': 'LUXURY_GLASS_2',
244
+ '3': 'NEOBRUTALISM',
245
+ '4': 'SWISS_EDITORIAL',
246
+ '5': 'STRIPE_CRISP_LIGHT',
247
+ };
248
+ if (isInteractive) {
249
+ const rl = readline.createInterface({
250
+ input: process.stdin,
251
+ output: process.stdout,
252
+ });
253
+ try {
254
+ console.log('\x1b[1mInitialize Vibe UI in current workspace:\x1b[0m\n');
255
+ // 1. Select Visual Chemistry
256
+ console.log('\x1b[36m1. Select Visual Chemistry:\x1b[0m');
257
+ console.log(' [1] Minimalist SaaS (Monochrome restraint, high signal - Recommended)');
258
+ console.log(' [2] Luxury Glass 2.0 (Specular Fresnel, deep dark, gold accents)');
259
+ console.log(' [3] Neobrutalism (Hard 3px black offset shadows, bold high saturation)');
260
+ console.log(' [4] Swiss Editorial (Asymmetric grid, typography-first, high contrast)');
261
+ console.log(' [5] Stripe Crisp Light (Developer docs, precision micro-borders)');
262
+ chemChoice = (await prompt(rl, 'Choice [1-5] (default: 1): ')).trim() || '1';
263
+ // 2. Select AI Editor
264
+ console.log('\n\x1b[36m2. Select AI Coding Environment:\x1b[0m');
265
+ console.log(' [1] Cursor (.cursorrules - Recommended)');
266
+ console.log(' [2] Claude Code (CLAUDE.md)');
267
+ console.log(' [3] Windsurf (.windsurfrules)');
268
+ console.log(' [4] All of the above');
269
+ editorChoice = (await prompt(rl, 'Choice [1-4] (default: 1): ')).trim() || '1';
149
270
  }
150
- if (editorChoice === '2' || editorChoice === '4') {
151
- const claudePath = path.join(cwd, 'CLAUDE.md');
152
- if (options.dryRun) {
153
- console.log(' \x1b[34m[dry-run]\x1b[0m Would update CLAUDE.md');
154
- }
155
- else if (fs.existsSync(claudePath)) {
156
- fs.appendFileSync(claudePath, `\n\n${CONTRACT_RULES}`, 'utf-8');
157
- createdFiles.push('CLAUDE.md (appended)');
158
- }
159
- else {
160
- const res = safeWriteFile(claudePath, CONTRACT_RULES, options);
161
- if (res.written)
162
- createdFiles.push('CLAUDE.md');
163
- }
271
+ finally {
272
+ rl.close();
273
+ }
274
+ }
275
+ else {
276
+ console.log('\x1b[36m [auto]\x1b[0m Non-interactive mode activated. Using defaults.');
277
+ }
278
+ const selectedChemKey = chemMap[chemChoice] || 'MINIMALIST_SAAS';
279
+ const selectedChem = index_1.VISUAL_CHEMISTRIES[selectedChemKey];
280
+ const darkColors = selectedChem.darkColors || selectedChem.colors;
281
+ console.log(` \x1b[32m✔\x1b[0m Visual Chemistry: \x1b[1m${selectedChem.name}\x1b[0m (Dual Light & Dark Themes)`);
282
+ // 3. Write contract rules safely
283
+ const cwd = process.cwd();
284
+ const createdFiles = [];
285
+ if (editorChoice === '1' || editorChoice === '4') {
286
+ const res = safeWriteFile(path.join(cwd, '.cursorrules'), CONTRACT_RULES, options);
287
+ if (res.written)
288
+ createdFiles.push('.cursorrules');
289
+ }
290
+ if (editorChoice === '2' || editorChoice === '4') {
291
+ const claudePath = path.join(cwd, 'CLAUDE.md');
292
+ if (options.dryRun) {
293
+ console.log(' \x1b[34m[dry-run]\x1b[0m Would update CLAUDE.md');
164
294
  }
165
- if (editorChoice === '3' || editorChoice === '4') {
166
- const res = safeWriteFile(path.join(cwd, '.windsurfrules'), CONTRACT_RULES, options);
295
+ else if (fs.existsSync(claudePath)) {
296
+ fs.appendFileSync(claudePath, `\n\n${CONTRACT_RULES}`, 'utf-8');
297
+ createdFiles.push('CLAUDE.md (appended)');
298
+ }
299
+ else {
300
+ const res = safeWriteFile(claudePath, CONTRACT_RULES, options);
167
301
  if (res.written)
168
- createdFiles.push('.windsurfrules');
302
+ createdFiles.push('CLAUDE.md');
169
303
  }
170
- // 4. Generate CSS Tokens file safely
171
- const cssContent = `:root {
172
- /* Vibe UI Chemistry: ${selectedChem.name} (${selectedChem.id}) */
173
- --vibe-canvas: ${selectedChem.colors.canvas};
174
- --vibe-surface: ${selectedChem.colors.surface};
175
- --vibe-border: ${selectedChem.colors.border};
176
- --vibe-primary-accent: ${selectedChem.colors.primaryAccent};
177
- --vibe-text-primary: ${selectedChem.colors.textPrimary};
178
- --vibe-text-muted: ${selectedChem.colors.textMuted};
179
- --vibe-ring: ${selectedChem.colors.ring};
180
- }
304
+ }
305
+ if (editorChoice === '3' || editorChoice === '4') {
306
+ const res = safeWriteFile(path.join(cwd, '.windsurfrules'), CONTRACT_RULES, options);
307
+ if (res.written)
308
+ createdFiles.push('.windsurfrules');
309
+ }
310
+ // 4. Generate Dual-Theme CSS Tokens file safely
311
+ const cssContent = `:root {
312
+ /* Vibe UI Chemistry: ${selectedChem.name} (${selectedChem.id}) - Light Theme */
313
+ --vibe-canvas: ${selectedChem.colors.canvas};
314
+ --vibe-surface: ${selectedChem.colors.surface};
315
+ --vibe-border: ${selectedChem.colors.border};
316
+ --vibe-primary-accent: ${selectedChem.colors.primaryAccent};
317
+ --vibe-on-primary: ${selectedChem.colors.onPrimaryAccent};
318
+ --vibe-text-primary: ${selectedChem.colors.textPrimary};
319
+ --vibe-text-muted: ${selectedChem.colors.textMuted};
320
+ --vibe-ring: ${selectedChem.colors.ring};
321
+ }
322
+
323
+ .dark, [data-theme="dark"] {
324
+ /* Vibe UI Chemistry: ${selectedChem.name} (${selectedChem.id}) - Dark Theme */
325
+ --vibe-canvas: ${darkColors.canvas};
326
+ --vibe-surface: ${darkColors.surface};
327
+ --vibe-border: ${darkColors.border};
328
+ --vibe-primary-accent: ${darkColors.primaryAccent};
329
+ --vibe-on-primary: ${darkColors.onPrimaryAccent};
330
+ --vibe-text-primary: ${darkColors.textPrimary};
331
+ --vibe-text-muted: ${darkColors.textMuted};
332
+ --vibe-ring: ${darkColors.ring};
333
+ }
181
334
  `;
182
- const cssPath = path.join(cwd, 'vibe-tokens.css');
183
- const cssRes = safeWriteFile(cssPath, cssContent, options);
184
- if (cssRes.written)
185
- createdFiles.push('vibe-tokens.css');
186
- console.log('\n\x1b[32m✔ Initialized successfully!\x1b[0m');
187
- if (createdFiles.length > 0) {
188
- console.log('\x1b[90mGenerated/Updated files:\x1b[0m');
189
- createdFiles.forEach((f) => console.log(` + ${f}`));
190
- }
191
- console.log(`
192
- \x1b[1mNext Steps:\x1b[0m
193
- 1. Import \x1b[35mvibe-tokens.css\x1b[0m into your layout or globals.css
194
- 2. Run \x1b[32mnpx @omid-io/tokens add thinking-drawer\x1b[0m to add your first AI component
195
- `);
335
+ const cssPath = path.join(cwd, 'vibe-tokens.css');
336
+ const cssRes = safeWriteFile(cssPath, cssContent, options);
337
+ if (cssRes.written)
338
+ createdFiles.push('vibe-tokens.css');
339
+ // 5. Install Vibe UI Workspace Skills into .agents/skills/
340
+ console.log('\n\x1b[36mInstalling Vibe UI Agent Skills (.agents/skills/):\x1b[0m');
341
+ const skillRes = installSkills(cwd, options);
342
+ if (skillRes.installed.length > 0) {
343
+ skillRes.installed.forEach((s) => {
344
+ console.log(` \x1b[32m✔\x1b[0m Installed skill: \x1b[1m${s}\x1b[0m`);
345
+ createdFiles.push(`.agents/skills/${s}`);
346
+ });
196
347
  }
197
- finally {
198
- rl.close();
348
+ if (skillRes.skipped.length > 0) {
349
+ skillRes.skipped.forEach((s) => console.log(` \x1b[33m[skip]\x1b[0m Skill ${s} already installed (use --force to overwrite)`));
199
350
  }
351
+ console.log('\n\x1b[32m✔ Initialized successfully!\x1b[0m');
352
+ if (createdFiles.length > 0) {
353
+ console.log('\x1b[90mGenerated/Updated files:\x1b[0m');
354
+ createdFiles.forEach((f) => console.log(` + ${f}`));
355
+ }
356
+ console.log(`
357
+ \x1b[1mNext Steps:\x1b[0m
358
+ 1. Import \x1b[35mvibe-tokens.css\x1b[0m into your layout or globals.css
359
+ 2. Run \x1b[32mnpx vibe-ui-suite add thinking-drawer\x1b[0m to add your first AI component
360
+ 3. Run \x1b[32mnpx vibe-ui-suite add theme-toggle\x1b[0m to add accessible Dark/Light theme switch
361
+ `);
200
362
  }
201
363
  function handleAdd(componentName, options = { force: false, dryRun: false }) {
202
364
  if (!componentName) {
203
365
  console.log('\x1b[33mError: Please specify a component to add.\x1b[0m\n');
204
366
  handleList();
205
- console.log('\nUsage: npx @omid-io/tokens add <component> [--force]');
367
+ console.log('\nUsage: npx vibe-ui-suite add <component> [--force]');
206
368
  process.exit(1);
207
369
  return;
208
370
  }
@@ -223,7 +385,7 @@ function handleAdd(componentName, options = { force: false, dryRun: false }) {
223
385
  if (writeRes.skipped) {
224
386
  console.log(`\n\x1b[33mWarning: Component already exists at components/vibe-ui/${comp.filename}\x1b[0m`);
225
387
  console.log(`To overwrite with automated .bak backup, re-run with:`);
226
- console.log(` \x1b[32mnpx @omid-io/tokens add ${componentName} --force\x1b[0m\n`);
388
+ console.log(` \x1b[32mnpx vibe-ui-suite add ${componentName} --force\x1b[0m\n`);
227
389
  return;
228
390
  }
229
391
  if (writeRes.written) {
@@ -235,18 +397,37 @@ function handleAdd(componentName, options = { force: false, dryRun: false }) {
235
397
  }
236
398
  }
237
399
  function handleList() {
238
- console.log('\x1b[1mAvailable Vibe UI Components:\x1b[0m');
239
- Object.values(components_1.COMPONENT_REGISTRY).forEach((comp) => {
240
- console.log(` \x1b[32m${comp.name.padEnd(18)}\x1b[0m \x1b[90m${comp.description}\x1b[0m`);
400
+ console.log('\x1b[1mAvailable Vibe UI Components:\x1b[0m\n');
401
+ console.log(' \x1b[1;36mAI Contracts & Observation:\x1b[0m');
402
+ Object.values(components_1.COMPONENT_REGISTRY)
403
+ .filter((comp) => comp.category === 'ai-contracts')
404
+ .forEach((comp) => {
405
+ console.log(` \x1b[32m${comp.name.padEnd(20)}\x1b[0m \x1b[90m${comp.description}\x1b[0m`);
406
+ });
407
+ console.log('\n \x1b[1;35mLiving Micro-Interactions:\x1b[0m');
408
+ Object.values(components_1.COMPONENT_REGISTRY)
409
+ .filter((comp) => comp.category === 'living-micro-interactions')
410
+ .forEach((comp) => {
411
+ console.log(` \x1b[32m${comp.name.padEnd(20)}\x1b[0m \x1b[90m${comp.description}\x1b[0m`);
241
412
  });
413
+ console.log('');
242
414
  }
243
415
  async function main() {
244
416
  const rawArgs = process.argv.slice(2);
245
417
  const force = rawArgs.includes('--force') || rawArgs.includes('-f');
246
418
  const dryRun = rawArgs.includes('--dry-run');
247
- const filteredArgs = rawArgs.filter((a) => !['--force', '-f', '--dry-run'].includes(a));
419
+ const yes = rawArgs.includes('--yes') || rawArgs.includes('-y');
420
+ let chemistry;
421
+ let editor;
422
+ for (let i = 0; i < rawArgs.length; i++) {
423
+ if (rawArgs[i] === '--chemistry' && rawArgs[i + 1])
424
+ chemistry = rawArgs[i + 1];
425
+ if (rawArgs[i] === '--editor' && rawArgs[i + 1])
426
+ editor = rawArgs[i + 1];
427
+ }
428
+ const filteredArgs = rawArgs.filter((a) => !['--force', '-f', '--dry-run', '--yes', '-y', '--chemistry', '--editor'].includes(a) && a !== chemistry && a !== editor);
248
429
  const cmd = filteredArgs[0]?.toLowerCase();
249
- const options = { force, dryRun };
430
+ const options = { force, dryRun, yes, chemistry, editor };
250
431
  if (!cmd || cmd === '--help' || cmd === '-h') {
251
432
  printHelp();
252
433
  return;
@@ -259,6 +440,14 @@ async function main() {
259
440
  case 'init':
260
441
  await handleInit(options);
261
442
  break;
443
+ case 'sync':
444
+ case 'update':
445
+ await handleSync(options);
446
+ break;
447
+ case 'install-skills':
448
+ case 'skills':
449
+ await handleInstallSkills(options);
450
+ break;
262
451
  case 'add':
263
452
  handleAdd(filteredArgs[1], options);
264
453
  break;