vibe-ui-suite 6.2.0 โ 6.3.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/package.json +77 -77
- package/skills/conversion-copy-engine/SKILL.md +65 -65
- package/skills/ui-verifier/SKILL.md +130 -130
- package/skills/visual-chemistry-engine/SKILL.md +165 -165
- package/dist/cli.d.ts +0 -2
- package/dist/cli.js +0 -467
- package/dist/cli.mjs +0 -432
- package/dist/index.d.ts +0 -48
- package/dist/index.js +0 -245
- package/dist/index.mjs +0 -239
- package/dist/registry/components.d.ts +0 -12
- package/dist/registry/components.js +0 -995
- package/dist/registry/components.mjs +0 -992
- package/dist/tailwind.d.ts +0 -11
- package/dist/tailwind.js +0 -64
- package/dist/tailwind.mjs +0 -60
- package/dist/v4.css +0 -361
package/dist/cli.mjs
DELETED
|
@@ -1,432 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import * as fs from 'fs';
|
|
3
|
-
import * as path from 'path';
|
|
4
|
-
import * as readline from 'readline';
|
|
5
|
-
import { COMPONENT_REGISTRY } from './registry/components.mjs';
|
|
6
|
-
import { VISUAL_CHEMISTRIES } from './index.mjs';
|
|
7
|
-
const VERSION = '6.2.0';
|
|
8
|
-
function printBanner() {
|
|
9
|
-
console.log(`
|
|
10
|
-
\x1b[35m โฒ VIBE UI CLI v${VERSION}\x1b[0m
|
|
11
|
-
\x1b[90mDeterministic UI contracts, 11 design paradigms & flagship components for AI coding assistants\x1b[0m
|
|
12
|
-
`);
|
|
13
|
-
}
|
|
14
|
-
function printHelp() {
|
|
15
|
-
printBanner();
|
|
16
|
-
console.log(`\x1b[1mUSAGE:\x1b[0m
|
|
17
|
-
npx vibe-ui-suite <command> [options]
|
|
18
|
-
vibe-ui <command> [options]
|
|
19
|
-
|
|
20
|
-
\x1b[1mCOMMANDS:\x1b[0m
|
|
21
|
-
\x1b[32minit\x1b[0m Initialize Vibe UI contracts, 11 paradigm tokens & AI rules in current project
|
|
22
|
-
\x1b[32msync\x1b[0m Synchronize existing AI contracts to canonical v${VERSION} master rules
|
|
23
|
-
\x1b[32minstall-skills\x1b[0m Install or update Vibe UI agent skills in .agents/skills/
|
|
24
|
-
\x1b[32madd <component>\x1b[0m Add an accessible, AI-native component template to your project
|
|
25
|
-
\x1b[32mlist\x1b[0m List all available component primitives in the registry
|
|
26
|
-
|
|
27
|
-
\x1b[1mOPTIONS:\x1b[0m
|
|
28
|
-
-f, --force Overwrite existing files (creates automated .bak backups)
|
|
29
|
-
-y, --yes Non-interactive mode (use defaults without prompting)
|
|
30
|
-
--chemistry <1-5> Select visual chemistry in non-interactive mode
|
|
31
|
-
--editor <1-4> Select target AI editor in non-interactive mode (1: Cursor, 2: Claude, 3: Windsurf, 4: All)
|
|
32
|
-
--dry-run Preview file operations without making actual modifications
|
|
33
|
-
-v, --version Show CLI version
|
|
34
|
-
-h, --help Show help menu
|
|
35
|
-
|
|
36
|
-
\x1b[1mEXAMPLES:\x1b[0m
|
|
37
|
-
npx vibe-ui-suite init
|
|
38
|
-
npx vibe-ui-suite init -y
|
|
39
|
-
npx vibe-ui-suite sync
|
|
40
|
-
npx vibe-ui-suite install-skills
|
|
41
|
-
npx vibe-ui-suite add device-mockup
|
|
42
|
-
npx vibe-ui-suite add before-after-lens
|
|
43
|
-
npx vibe-ui-suite add specular-card
|
|
44
|
-
npx vibe-ui-suite add thinking-drawer
|
|
45
|
-
npx vibe-ui-suite add shimmer-button
|
|
46
|
-
npx vibe-ui-suite add theme-toggle
|
|
47
|
-
npx vibe-ui-suite add device-mockup --force
|
|
48
|
-
`);
|
|
49
|
-
}
|
|
50
|
-
function prompt(rl, query) {
|
|
51
|
-
return new Promise((resolve) => rl.question(query, resolve));
|
|
52
|
-
}
|
|
53
|
-
function safeWriteFile(filePath, content, options) {
|
|
54
|
-
const relPath = path.relative(process.cwd(), filePath);
|
|
55
|
-
if (options.dryRun) {
|
|
56
|
-
console.log(` \x1b[34m[dry-run]\x1b[0m Would write: ${relPath}`);
|
|
57
|
-
return { written: false, skipped: false };
|
|
58
|
-
}
|
|
59
|
-
if (fs.existsSync(filePath) && !options.force) {
|
|
60
|
-
console.log(` \x1b[33m[skip]\x1b[0m ${relPath} already exists. (Use --force to overwrite)`);
|
|
61
|
-
return { written: false, skipped: true };
|
|
62
|
-
}
|
|
63
|
-
if (fs.existsSync(filePath) && options.force) {
|
|
64
|
-
const backupPath = `${filePath}.bak`;
|
|
65
|
-
fs.copyFileSync(filePath, backupPath);
|
|
66
|
-
fs.writeFileSync(filePath, content, 'utf-8');
|
|
67
|
-
console.log(` \x1b[35m[backup]\x1b[0m Backed up existing file to ${path.relative(process.cwd(), backupPath)}`);
|
|
68
|
-
return { written: true, skipped: false, backup: backupPath };
|
|
69
|
-
}
|
|
70
|
-
fs.writeFileSync(filePath, content, 'utf-8');
|
|
71
|
-
return { written: true, skipped: false };
|
|
72
|
-
}
|
|
73
|
-
const CONTRACT_RULES = `# ๐ Vibe UI Master Design & Architecture Contract (v6.2.0)
|
|
74
|
-
# Generated via npx vibe-ui-suite init / sync
|
|
75
|
-
|
|
76
|
-
## ๐๏ธ The 5 Master Execution Gates & Autonomous Lazy-Prompt Protocol
|
|
77
|
-
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"):
|
|
78
|
-
|
|
79
|
-
1. ๐ธ MANDATORY PRE-EDIT VISUAL AUDIT:
|
|
80
|
-
- Before editing any code, capture an initial browser screenshot (screenshots/before.png).
|
|
81
|
-
- Visually critique layout flaws, spacing balance, visual hierarchy, and focal points with multimodal vision.
|
|
82
|
-
|
|
83
|
-
2. ๐จ ARCHITECTURAL PARADIGM & TREND BENCHMARKING:
|
|
84
|
-
- Benchmark against premier design sources: Dribbble, Figma Community, Mobbin, and Awwwards.
|
|
85
|
-
- Autonomously select a modern paradigm (Bento Grid, Linear Minimal, Stripe Crisp Light, Swiss Editorial).
|
|
86
|
-
- Light Mode is the primary default canvas (#ffffff/#f8fafc). Mandatory dual-theme support with accessible Dark Mode toggle.
|
|
87
|
-
|
|
88
|
-
3. ๐งฑ STRUCTURAL DOM & SPATIAL OVERHAUL:
|
|
89
|
-
- ZERO COSMETIC-ONLY PATCH INVARIANT: Strictly forbidden to perform shallow skin-patches (altering only colors, borders, or emojis while leaving dead layouts untouched).
|
|
90
|
-
- Overhaul structural spatial rhythm, 8pt spacing system, and asymmetric bento card hierarchies.
|
|
91
|
-
- Inject tactile micro-interactions (shimmer buttons, cyber loaders, tactile switches, holographic cards) and authentic imagery.
|
|
92
|
-
- 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.
|
|
93
|
-
|
|
94
|
-
4. ๐๏ธ MULTI-VIEWPORT LIVING VISUAL VERIFICATION:
|
|
95
|
-
- Capture post-edit full-page screenshots (screenshots/after.png, Desktop 1440px / Mobile 390px).
|
|
96
|
-
- Multimodal self-critique: verify visual rhythm, zero horizontal overflow, and pristine typography hierarchy before handoff.
|
|
97
|
-
|
|
98
|
-
5. ๐งผ SILENT TABLE-STAKES (INTERNAL WORKER BASELINES):
|
|
99
|
-
- Low-level hygiene (OKLCH color math, WCAG AAA formulas, zero raw unicode emojis -> inline SVGs, <bdi> bidirectional text isolation) are silent worker requirements.
|
|
100
|
-
- NEVER report these hygiene baselines as headline accomplishments or key deliverables in chat summaries.
|
|
101
|
-
- Chat summaries MUST lead with architectural layout transformations, aesthetic paradigm chosen, and visual before/after evidence.
|
|
102
|
-
`;
|
|
103
|
-
function findSourceSkillsDir() {
|
|
104
|
-
const candidates = [
|
|
105
|
-
path.resolve(__dirname, '..', 'skills'),
|
|
106
|
-
path.resolve(__dirname, 'skills'),
|
|
107
|
-
path.resolve(__dirname, '..', '..', '..', 'skills'),
|
|
108
|
-
path.resolve(process.cwd(), 'skills'),
|
|
109
|
-
];
|
|
110
|
-
for (const c of candidates) {
|
|
111
|
-
if (fs.existsSync(c) && fs.existsSync(path.join(c, 'ui-kit', 'SKILL.md'))) {
|
|
112
|
-
return c;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
return null;
|
|
116
|
-
}
|
|
117
|
-
function installSkills(targetProjectDir, options) {
|
|
118
|
-
const srcSkillsDir = findSourceSkillsDir();
|
|
119
|
-
const installed = [];
|
|
120
|
-
const skipped = [];
|
|
121
|
-
if (!srcSkillsDir) {
|
|
122
|
-
console.log(' \x1b[33m[warn]\x1b[0m Could not locate Vibe UI skills source directory to install.');
|
|
123
|
-
return { installed, skipped };
|
|
124
|
-
}
|
|
125
|
-
const destSkillsDir = path.join(targetProjectDir, '.agents', 'skills');
|
|
126
|
-
if (options.dryRun) {
|
|
127
|
-
console.log(` \x1b[34m[dry-run]\x1b[0m Would install Vibe UI skills to: ${path.relative(process.cwd(), destSkillsDir)}`);
|
|
128
|
-
return { installed, skipped };
|
|
129
|
-
}
|
|
130
|
-
if (!fs.existsSync(destSkillsDir)) {
|
|
131
|
-
fs.mkdirSync(destSkillsDir, { recursive: true });
|
|
132
|
-
}
|
|
133
|
-
const skillsList = fs.readdirSync(srcSkillsDir).filter((f) => {
|
|
134
|
-
const full = path.join(srcSkillsDir, f);
|
|
135
|
-
return fs.statSync(full).isDirectory() && fs.existsSync(path.join(full, 'SKILL.md'));
|
|
136
|
-
});
|
|
137
|
-
for (const skillName of skillsList) {
|
|
138
|
-
const srcSkillPath = path.join(srcSkillsDir, skillName);
|
|
139
|
-
const destSkillPath = path.join(destSkillsDir, skillName);
|
|
140
|
-
if (fs.existsSync(destSkillPath) && !options.force) {
|
|
141
|
-
skipped.push(skillName);
|
|
142
|
-
continue;
|
|
143
|
-
}
|
|
144
|
-
if (fs.existsSync(destSkillPath) && options.force) {
|
|
145
|
-
fs.rmSync(destSkillPath, { recursive: true, force: true });
|
|
146
|
-
}
|
|
147
|
-
fs.cpSync(srcSkillPath, destSkillPath, { recursive: true });
|
|
148
|
-
installed.push(skillName);
|
|
149
|
-
}
|
|
150
|
-
return { installed, skipped };
|
|
151
|
-
}
|
|
152
|
-
async function handleInstallSkills(options) {
|
|
153
|
-
printBanner();
|
|
154
|
-
console.log('\x1b[36mInstalling Vibe UI Agent Skills into current project workspace (.agents/skills/)...\x1b[0m\n');
|
|
155
|
-
const cwd = process.cwd();
|
|
156
|
-
const res = installSkills(cwd, options);
|
|
157
|
-
if (res.installed.length > 0) {
|
|
158
|
-
console.log(`\n\x1b[32mโ Successfully installed ${res.installed.length} skill(s) in .agents/skills/:\x1b[0m`);
|
|
159
|
-
res.installed.forEach((s) => console.log(` + .agents/skills/${s}`));
|
|
160
|
-
}
|
|
161
|
-
if (res.skipped.length > 0) {
|
|
162
|
-
console.log(`\n\x1b[33mSkipped ${res.skipped.length} existing skill(s) (use --force to overwrite):\x1b[0m`);
|
|
163
|
-
res.skipped.forEach((s) => console.log(` - ${s}`));
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
async function handleSync(options) {
|
|
167
|
-
printBanner();
|
|
168
|
-
console.log('\x1b[36mSynchronizing AI contracts to canonical v6.2.0 Master Architectural Standard...\x1b[0m\n');
|
|
169
|
-
const cwd = process.cwd();
|
|
170
|
-
const targetFiles = ['.cursorrules', '.windsurfrules', 'CLAUDE.md'];
|
|
171
|
-
let updatedCount = 0;
|
|
172
|
-
for (const filename of targetFiles) {
|
|
173
|
-
const filePath = path.join(cwd, filename);
|
|
174
|
-
if (fs.existsSync(filePath)) {
|
|
175
|
-
const res = safeWriteFile(filePath, CONTRACT_RULES, { ...options, force: true });
|
|
176
|
-
if (res.written) {
|
|
177
|
-
console.log(` \x1b[32mโ\x1b[0m Updated \x1b[1m${filename}\x1b[0m to v6.2.0 contract rules`);
|
|
178
|
-
updatedCount++;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
const destSkills = path.join(cwd, '.agents', 'skills');
|
|
183
|
-
if (fs.existsSync(destSkills) || updatedCount > 0) {
|
|
184
|
-
console.log('\n\x1b[36mSynchronizing Vibe UI workspace skills (.agents/skills/):\x1b[0m');
|
|
185
|
-
const skillRes = installSkills(cwd, { ...options, force: true });
|
|
186
|
-
if (skillRes.installed.length > 0) {
|
|
187
|
-
console.log(` \x1b[32mโ\x1b[0m Synchronized ${skillRes.installed.length} skills in .agents/skills/`);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
if (updatedCount === 0) {
|
|
191
|
-
console.log(' \x1b[33mNo existing AI rule files found in current directory.\x1b[0m');
|
|
192
|
-
console.log(' Run \x1b[32mnpx vibe-ui-suite init\x1b[0m to initialize contracts from scratch.');
|
|
193
|
-
}
|
|
194
|
-
else {
|
|
195
|
-
console.log(`\n\x1b[32mโ Successfully synchronized AI rule file(s) and workspace skills to v6.2.0!\x1b[0m`);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
async function handleInit(options) {
|
|
199
|
-
printBanner();
|
|
200
|
-
if (options.dryRun) {
|
|
201
|
-
console.log('\x1b[34m[DRY-RUN MODE ACTIVATED: No files will be modified on disk]\x1b[0m\n');
|
|
202
|
-
}
|
|
203
|
-
const isInteractive = !options.yes && Boolean(process.stdin.isTTY);
|
|
204
|
-
let chemChoice = options.chemistry || '1';
|
|
205
|
-
let editorChoice = options.editor || '4';
|
|
206
|
-
const chemMap = {
|
|
207
|
-
'1': 'MINIMALIST_SAAS',
|
|
208
|
-
'2': 'LUXURY_GLASS_2',
|
|
209
|
-
'3': 'NEOBRUTALISM',
|
|
210
|
-
'4': 'SWISS_EDITORIAL',
|
|
211
|
-
'5': 'STRIPE_CRISP_LIGHT',
|
|
212
|
-
};
|
|
213
|
-
if (isInteractive) {
|
|
214
|
-
const rl = readline.createInterface({
|
|
215
|
-
input: process.stdin,
|
|
216
|
-
output: process.stdout,
|
|
217
|
-
});
|
|
218
|
-
try {
|
|
219
|
-
console.log('\x1b[1mInitialize Vibe UI in current workspace:\x1b[0m\n');
|
|
220
|
-
// 1. Select Visual Chemistry
|
|
221
|
-
console.log('\x1b[36m1. Select Visual Chemistry:\x1b[0m');
|
|
222
|
-
console.log(' [1] Minimalist SaaS (Monochrome restraint, high signal - Recommended)');
|
|
223
|
-
console.log(' [2] Luxury Glass 2.0 (Specular Fresnel, deep dark, gold accents)');
|
|
224
|
-
console.log(' [3] Neobrutalism (Hard 3px black offset shadows, bold high saturation)');
|
|
225
|
-
console.log(' [4] Swiss Editorial (Asymmetric grid, typography-first, high contrast)');
|
|
226
|
-
console.log(' [5] Stripe Crisp Light (Developer docs, precision micro-borders)');
|
|
227
|
-
chemChoice = (await prompt(rl, 'Choice [1-5] (default: 1): ')).trim() || '1';
|
|
228
|
-
// 2. Select AI Editor
|
|
229
|
-
console.log('\n\x1b[36m2. Select AI Coding Environment:\x1b[0m');
|
|
230
|
-
console.log(' [1] Cursor (.cursorrules - Recommended)');
|
|
231
|
-
console.log(' [2] Claude Code (CLAUDE.md)');
|
|
232
|
-
console.log(' [3] Windsurf (.windsurfrules)');
|
|
233
|
-
console.log(' [4] All of the above');
|
|
234
|
-
editorChoice = (await prompt(rl, 'Choice [1-4] (default: 1): ')).trim() || '1';
|
|
235
|
-
}
|
|
236
|
-
finally {
|
|
237
|
-
rl.close();
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
else {
|
|
241
|
-
console.log('\x1b[36m [auto]\x1b[0m Non-interactive mode activated. Using defaults.');
|
|
242
|
-
}
|
|
243
|
-
const selectedChemKey = chemMap[chemChoice] || 'MINIMALIST_SAAS';
|
|
244
|
-
const selectedChem = VISUAL_CHEMISTRIES[selectedChemKey];
|
|
245
|
-
const darkColors = selectedChem.darkColors || selectedChem.colors;
|
|
246
|
-
console.log(` \x1b[32mโ\x1b[0m Visual Chemistry: \x1b[1m${selectedChem.name}\x1b[0m (Dual Light & Dark Themes)`);
|
|
247
|
-
// 3. Write contract rules safely
|
|
248
|
-
const cwd = process.cwd();
|
|
249
|
-
const createdFiles = [];
|
|
250
|
-
if (editorChoice === '1' || editorChoice === '4') {
|
|
251
|
-
const res = safeWriteFile(path.join(cwd, '.cursorrules'), CONTRACT_RULES, options);
|
|
252
|
-
if (res.written)
|
|
253
|
-
createdFiles.push('.cursorrules');
|
|
254
|
-
}
|
|
255
|
-
if (editorChoice === '2' || editorChoice === '4') {
|
|
256
|
-
const claudePath = path.join(cwd, 'CLAUDE.md');
|
|
257
|
-
if (options.dryRun) {
|
|
258
|
-
console.log(' \x1b[34m[dry-run]\x1b[0m Would update CLAUDE.md');
|
|
259
|
-
}
|
|
260
|
-
else if (fs.existsSync(claudePath)) {
|
|
261
|
-
fs.appendFileSync(claudePath, `\n\n${CONTRACT_RULES}`, 'utf-8');
|
|
262
|
-
createdFiles.push('CLAUDE.md (appended)');
|
|
263
|
-
}
|
|
264
|
-
else {
|
|
265
|
-
const res = safeWriteFile(claudePath, CONTRACT_RULES, options);
|
|
266
|
-
if (res.written)
|
|
267
|
-
createdFiles.push('CLAUDE.md');
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
if (editorChoice === '3' || editorChoice === '4') {
|
|
271
|
-
const res = safeWriteFile(path.join(cwd, '.windsurfrules'), CONTRACT_RULES, options);
|
|
272
|
-
if (res.written)
|
|
273
|
-
createdFiles.push('.windsurfrules');
|
|
274
|
-
}
|
|
275
|
-
// 4. Generate Dual-Theme CSS Tokens file safely
|
|
276
|
-
const cssContent = `:root {
|
|
277
|
-
/* Vibe UI Chemistry: ${selectedChem.name} (${selectedChem.id}) - Light Theme */
|
|
278
|
-
--vibe-canvas: ${selectedChem.colors.canvas};
|
|
279
|
-
--vibe-surface: ${selectedChem.colors.surface};
|
|
280
|
-
--vibe-border: ${selectedChem.colors.border};
|
|
281
|
-
--vibe-primary-accent: ${selectedChem.colors.primaryAccent};
|
|
282
|
-
--vibe-on-primary: ${selectedChem.colors.onPrimaryAccent};
|
|
283
|
-
--vibe-text-primary: ${selectedChem.colors.textPrimary};
|
|
284
|
-
--vibe-text-muted: ${selectedChem.colors.textMuted};
|
|
285
|
-
--vibe-ring: ${selectedChem.colors.ring};
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
.dark, [data-theme="dark"] {
|
|
289
|
-
/* Vibe UI Chemistry: ${selectedChem.name} (${selectedChem.id}) - Dark Theme */
|
|
290
|
-
--vibe-canvas: ${darkColors.canvas};
|
|
291
|
-
--vibe-surface: ${darkColors.surface};
|
|
292
|
-
--vibe-border: ${darkColors.border};
|
|
293
|
-
--vibe-primary-accent: ${darkColors.primaryAccent};
|
|
294
|
-
--vibe-on-primary: ${darkColors.onPrimaryAccent};
|
|
295
|
-
--vibe-text-primary: ${darkColors.textPrimary};
|
|
296
|
-
--vibe-text-muted: ${darkColors.textMuted};
|
|
297
|
-
--vibe-ring: ${darkColors.ring};
|
|
298
|
-
}
|
|
299
|
-
`;
|
|
300
|
-
const cssPath = path.join(cwd, 'vibe-tokens.css');
|
|
301
|
-
const cssRes = safeWriteFile(cssPath, cssContent, options);
|
|
302
|
-
if (cssRes.written)
|
|
303
|
-
createdFiles.push('vibe-tokens.css');
|
|
304
|
-
// 5. Install Vibe UI Workspace Skills into .agents/skills/
|
|
305
|
-
console.log('\n\x1b[36mInstalling Vibe UI Agent Skills (.agents/skills/):\x1b[0m');
|
|
306
|
-
const skillRes = installSkills(cwd, options);
|
|
307
|
-
if (skillRes.installed.length > 0) {
|
|
308
|
-
skillRes.installed.forEach((s) => {
|
|
309
|
-
console.log(` \x1b[32mโ\x1b[0m Installed skill: \x1b[1m${s}\x1b[0m`);
|
|
310
|
-
createdFiles.push(`.agents/skills/${s}`);
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
if (skillRes.skipped.length > 0) {
|
|
314
|
-
skillRes.skipped.forEach((s) => console.log(` \x1b[33m[skip]\x1b[0m Skill ${s} already installed (use --force to overwrite)`));
|
|
315
|
-
}
|
|
316
|
-
console.log('\n\x1b[32mโ Initialized successfully!\x1b[0m');
|
|
317
|
-
if (createdFiles.length > 0) {
|
|
318
|
-
console.log('\x1b[90mGenerated/Updated files:\x1b[0m');
|
|
319
|
-
createdFiles.forEach((f) => console.log(` + ${f}`));
|
|
320
|
-
}
|
|
321
|
-
console.log(`
|
|
322
|
-
\x1b[1mNext Steps:\x1b[0m
|
|
323
|
-
1. Import \x1b[35mvibe-tokens.css\x1b[0m into your layout or globals.css
|
|
324
|
-
2. Run \x1b[32mnpx vibe-ui-suite add thinking-drawer\x1b[0m to add your first AI component
|
|
325
|
-
3. Run \x1b[32mnpx vibe-ui-suite add theme-toggle\x1b[0m to add accessible Dark/Light theme switch
|
|
326
|
-
`);
|
|
327
|
-
}
|
|
328
|
-
function handleAdd(componentName, options = { force: false, dryRun: false }) {
|
|
329
|
-
if (!componentName) {
|
|
330
|
-
console.log('\x1b[33mError: Please specify a component to add.\x1b[0m\n');
|
|
331
|
-
handleList();
|
|
332
|
-
console.log('\nUsage: npx vibe-ui-suite add <component> [--force]');
|
|
333
|
-
process.exit(1);
|
|
334
|
-
return;
|
|
335
|
-
}
|
|
336
|
-
const comp = COMPONENT_REGISTRY[componentName.toLowerCase()];
|
|
337
|
-
if (!comp) {
|
|
338
|
-
console.log(`\x1b[31mError: Unknown component "${componentName}".\x1b[0m\n`);
|
|
339
|
-
handleList();
|
|
340
|
-
process.exit(1);
|
|
341
|
-
return;
|
|
342
|
-
}
|
|
343
|
-
const cwd = process.cwd();
|
|
344
|
-
const targetDir = path.join(cwd, 'components', 'vibe-ui');
|
|
345
|
-
if (!options.dryRun) {
|
|
346
|
-
fs.mkdirSync(targetDir, { recursive: true });
|
|
347
|
-
}
|
|
348
|
-
const targetFile = path.join(targetDir, comp.filename);
|
|
349
|
-
const writeRes = safeWriteFile(targetFile, comp.code, options);
|
|
350
|
-
if (writeRes.skipped) {
|
|
351
|
-
console.log(`\n\x1b[33mWarning: Component already exists at components/vibe-ui/${comp.filename}\x1b[0m`);
|
|
352
|
-
console.log(`To overwrite with automated .bak backup, re-run with:`);
|
|
353
|
-
console.log(` \x1b[32mnpx vibe-ui-suite add ${componentName} --force\x1b[0m\n`);
|
|
354
|
-
return;
|
|
355
|
-
}
|
|
356
|
-
if (writeRes.written) {
|
|
357
|
-
console.log(`\x1b[32mโ Added component "${comp.name}"!\x1b[0m`);
|
|
358
|
-
console.log(` \x1b[90mLocation:\x1b[0m components/vibe-ui/${comp.filename}`);
|
|
359
|
-
console.log(` \x1b[90mDescription:\x1b[0m ${comp.description}\n`);
|
|
360
|
-
console.log(`\x1b[1mUsage in your page or view:\x1b[0m`);
|
|
361
|
-
console.log(` import { ${comp.filename.replace('.tsx', '')} } from '@/components/vibe-ui/${comp.filename.replace('.tsx', '')}';\n`);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
function handleList() {
|
|
365
|
-
console.log('\x1b[1mAvailable Vibe UI Components:\x1b[0m\n');
|
|
366
|
-
console.log(' \x1b[1;36mAI Contracts & Observation:\x1b[0m');
|
|
367
|
-
Object.values(COMPONENT_REGISTRY)
|
|
368
|
-
.filter((comp) => comp.category === 'ai-contracts')
|
|
369
|
-
.forEach((comp) => {
|
|
370
|
-
console.log(` \x1b[32m${comp.name.padEnd(20)}\x1b[0m \x1b[90m${comp.description}\x1b[0m`);
|
|
371
|
-
});
|
|
372
|
-
console.log('\n \x1b[1;35mLiving Micro-Interactions:\x1b[0m');
|
|
373
|
-
Object.values(COMPONENT_REGISTRY)
|
|
374
|
-
.filter((comp) => comp.category === 'living-micro-interactions')
|
|
375
|
-
.forEach((comp) => {
|
|
376
|
-
console.log(` \x1b[32m${comp.name.padEnd(20)}\x1b[0m \x1b[90m${comp.description}\x1b[0m`);
|
|
377
|
-
});
|
|
378
|
-
console.log('');
|
|
379
|
-
}
|
|
380
|
-
async function main() {
|
|
381
|
-
const rawArgs = process.argv.slice(2);
|
|
382
|
-
const force = rawArgs.includes('--force') || rawArgs.includes('-f');
|
|
383
|
-
const dryRun = rawArgs.includes('--dry-run');
|
|
384
|
-
const yes = rawArgs.includes('--yes') || rawArgs.includes('-y');
|
|
385
|
-
let chemistry;
|
|
386
|
-
let editor;
|
|
387
|
-
for (let i = 0; i < rawArgs.length; i++) {
|
|
388
|
-
if (rawArgs[i] === '--chemistry' && rawArgs[i + 1])
|
|
389
|
-
chemistry = rawArgs[i + 1];
|
|
390
|
-
if (rawArgs[i] === '--editor' && rawArgs[i + 1])
|
|
391
|
-
editor = rawArgs[i + 1];
|
|
392
|
-
}
|
|
393
|
-
const filteredArgs = rawArgs.filter((a) => !['--force', '-f', '--dry-run', '--yes', '-y', '--chemistry', '--editor'].includes(a) && a !== chemistry && a !== editor);
|
|
394
|
-
const cmd = filteredArgs[0]?.toLowerCase();
|
|
395
|
-
const options = { force, dryRun, yes, chemistry, editor };
|
|
396
|
-
if (!cmd || cmd === '--help' || cmd === '-h') {
|
|
397
|
-
printHelp();
|
|
398
|
-
return;
|
|
399
|
-
}
|
|
400
|
-
if (cmd === '--version' || cmd === '-v') {
|
|
401
|
-
console.log(`v${VERSION}`);
|
|
402
|
-
return;
|
|
403
|
-
}
|
|
404
|
-
switch (cmd) {
|
|
405
|
-
case 'init':
|
|
406
|
-
await handleInit(options);
|
|
407
|
-
break;
|
|
408
|
-
case 'sync':
|
|
409
|
-
case 'update':
|
|
410
|
-
await handleSync(options);
|
|
411
|
-
break;
|
|
412
|
-
case 'install-skills':
|
|
413
|
-
case 'skills':
|
|
414
|
-
await handleInstallSkills(options);
|
|
415
|
-
break;
|
|
416
|
-
case 'add':
|
|
417
|
-
handleAdd(filteredArgs[1], options);
|
|
418
|
-
break;
|
|
419
|
-
case 'list':
|
|
420
|
-
printBanner();
|
|
421
|
-
handleList();
|
|
422
|
-
break;
|
|
423
|
-
default:
|
|
424
|
-
console.log(`\x1b[31mUnknown command "${cmd}".\x1b[0m`);
|
|
425
|
-
printHelp();
|
|
426
|
-
process.exit(1);
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
main().catch((err) => {
|
|
430
|
-
console.error('\x1b[31mFatal CLI error:\x1b[0m', err);
|
|
431
|
-
process.exit(1);
|
|
432
|
-
});
|
package/dist/index.d.ts
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @vibe-ui/tokens
|
|
3
|
-
* Typed OKLCH design tokens, physics curves, and contrast utilities.
|
|
4
|
-
*/
|
|
5
|
-
export type VisualChemistryId = 'MINIMALIST_SAAS' | 'LUXURY_GLASS_2' | 'NEOBRUTALISM' | 'SWISS_EDITORIAL' | 'STRIPE_CRISP_LIGHT' | 'CLAYMORPHISM';
|
|
6
|
-
export interface ChemistryColors {
|
|
7
|
-
canvas: string;
|
|
8
|
-
surface: string;
|
|
9
|
-
border: string;
|
|
10
|
-
primaryAccent: string;
|
|
11
|
-
/** Text color on primary accent guaranteeing >= 4.5:1 (AA) or >= 7:1 (AAA) contrast */
|
|
12
|
-
onPrimaryAccent: string;
|
|
13
|
-
textPrimary: string;
|
|
14
|
-
textMuted: string;
|
|
15
|
-
ring: string;
|
|
16
|
-
}
|
|
17
|
-
export interface ChemistryTypography {
|
|
18
|
-
display: string;
|
|
19
|
-
body: string;
|
|
20
|
-
mono: string;
|
|
21
|
-
}
|
|
22
|
-
export interface ChemistryPhysics {
|
|
23
|
-
springStiffness: number;
|
|
24
|
-
dampingRatio: number;
|
|
25
|
-
lerpAlpha: string;
|
|
26
|
-
}
|
|
27
|
-
export interface VisualChemistry {
|
|
28
|
-
id: VisualChemistryId;
|
|
29
|
-
name: string;
|
|
30
|
-
tagline: string;
|
|
31
|
-
colors: ChemistryColors;
|
|
32
|
-
darkColors?: ChemistryColors;
|
|
33
|
-
typography: ChemistryTypography;
|
|
34
|
-
physics: ChemistryPhysics;
|
|
35
|
-
}
|
|
36
|
-
export declare const VISUAL_CHEMISTRIES: Record<VisualChemistryId, VisualChemistry>;
|
|
37
|
-
/** Easing curves adhering to Vibe UI motion standards */
|
|
38
|
-
export declare const MOTION_CURVES: {
|
|
39
|
-
readonly naturalSpring: "cubic-bezier(0.16, 1, 0.3, 1)";
|
|
40
|
-
readonly responsiveSnap: "cubic-bezier(0.25, 1, 0.5, 1)";
|
|
41
|
-
readonly crispEnter: "cubic-bezier(0, 0, 0.2, 1)";
|
|
42
|
-
readonly crispExit: "cubic-bezier(0.4, 0, 1, 1)";
|
|
43
|
-
};
|
|
44
|
-
/** Relative luminance formula conforming to WCAG 2.2 */
|
|
45
|
-
export declare function getRelativeLuminance(r: number, g: number, b: number): number;
|
|
46
|
-
/** Contrast ratio between two luminance values */
|
|
47
|
-
export declare function getContrastRatio(lumA: number, lumB: number): number;
|
|
48
|
-
export { COMPONENT_REGISTRY, type ComponentTemplate } from './registry/components';
|