vectorvesper 1.1.0 → 2.0.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/dist/index.js CHANGED
@@ -1,304 +1,31 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ detectProject,
4
+ fetchComponent,
5
+ fetchRegistryIndex,
6
+ getAuthToken,
7
+ getGlobalConfigPath,
8
+ loadConfig,
9
+ loadGlobalConfig,
10
+ logger,
11
+ resolveAlias,
12
+ saveGlobalConfig,
13
+ setVerbose,
14
+ validateSlug,
15
+ writeConfig
16
+ } from "./chunk-32GDEAJM.js";
2
17
 
3
18
  // src/index.ts
4
19
  import { Command } from "commander";
5
20
 
6
- // src/utils/logger.ts
7
- import pc from "picocolors";
8
- var verboseMode = false;
9
- function setVerbose(enabled) {
10
- verboseMode = enabled;
11
- }
12
- var logger = {
13
- /** Standard info message */
14
- info(message) {
15
- console.log(message);
16
- },
17
- /** Success message with green checkmark */
18
- success(message) {
19
- console.log(`${pc.green("\u2714")} ${message}`);
20
- },
21
- /** Warning message */
22
- warn(message) {
23
- console.log(pc.yellow(`\u26A0\uFE0F ${message}`));
24
- },
25
- /** Error message */
26
- error(message) {
27
- console.error(pc.red(`\u274C ${message}`));
28
- },
29
- /** Debug message — only shown when --verbose is active */
30
- debug(message) {
31
- if (verboseMode) {
32
- console.log(pc.dim(` [debug] ${message}`));
33
- }
34
- },
35
- /** Blank line */
36
- break() {
37
- console.log("");
38
- }
39
- };
40
-
41
21
  // src/commands/init.ts
42
22
  import { intro, outro, select, text, confirm, isCancel } from "@clack/prompts";
43
- import pc2 from "picocolors";
44
- import fs3 from "fs";
45
- import path3 from "path";
46
-
47
- // src/utils/project.ts
23
+ import pc from "picocolors";
48
24
  import fs from "fs";
49
25
  import path from "path";
50
- function detectProject(cwd = process.cwd()) {
51
- const rootPath = cwd;
52
- let packageManager = "npm";
53
- if (fs.existsSync(path.join(rootPath, "pnpm-lock.yaml"))) {
54
- packageManager = "pnpm";
55
- } else if (fs.existsSync(path.join(rootPath, "yarn.lock"))) {
56
- packageManager = "yarn";
57
- } else if (fs.existsSync(path.join(rootPath, "bun.lockb")) || fs.existsSync(path.join(rootPath, "bun.lock"))) {
58
- packageManager = "bun";
59
- }
60
- const isTypeScript = fs.existsSync(path.join(rootPath, "tsconfig.json"));
61
- const hasSrcDir = fs.existsSync(path.join(rootPath, "src"));
62
- const pkgPath = path.join(rootPath, "package.json");
63
- let dependencies = {};
64
- let devDependencies = {};
65
- if (fs.existsSync(pkgPath)) {
66
- try {
67
- const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
68
- dependencies = pkg.dependencies || {};
69
- devDependencies = pkg.devDependencies || {};
70
- } catch {
71
- }
72
- }
73
- const allDeps = { ...dependencies, ...devDependencies };
74
- const tailwindConfigs = [
75
- "tailwind.config.js",
76
- "tailwind.config.ts",
77
- "tailwind.config.cjs",
78
- "tailwind.config.mjs"
79
- ];
80
- const hasTailwindConfig = tailwindConfigs.some(
81
- (config) => fs.existsSync(path.join(rootPath, config))
82
- );
83
- const hasTailwindDep = "tailwindcss" in allDeps || "@tailwindcss/postcss" in allDeps || "@tailwindcss/vite" in allDeps;
84
- const hasTailwind = hasTailwindConfig || hasTailwindDep;
85
- let framework = "unknown";
86
- let nextRouter;
87
- if (dependencies["next"] || devDependencies["next"]) {
88
- framework = "next";
89
- const searchPath = hasSrcDir ? path.join(rootPath, "src") : rootPath;
90
- if (fs.existsSync(path.join(searchPath, "app"))) {
91
- nextRouter = "app";
92
- } else if (fs.existsSync(path.join(searchPath, "pages"))) {
93
- nextRouter = "pages";
94
- } else {
95
- nextRouter = "app";
96
- }
97
- } else if (dependencies["vite"] || devDependencies["vite"] || fs.existsSync(path.join(rootPath, "vite.config.ts")) || fs.existsSync(path.join(rootPath, "vite.config.js"))) {
98
- framework = "vite";
99
- }
100
- return {
101
- packageManager,
102
- isTypeScript,
103
- framework,
104
- nextRouter,
105
- hasSrcDir,
106
- hasTailwind,
107
- rootPath
108
- };
109
- }
110
-
111
- // src/utils/config.ts
112
- import fs2 from "fs";
113
- import path2 from "path";
114
- import os from "os";
115
-
116
- // src/utils/types.ts
117
- import { z } from "zod";
118
- var SLUG_REGEX = /^[a-z0-9][a-z0-9-]*$/;
119
- function validateSlug(slug) {
120
- if (!SLUG_REGEX.test(slug)) {
121
- throw new Error(
122
- `Invalid component slug "${slug}". Slugs must contain only lowercase letters, numbers, and hyphens, and cannot start with a hyphen.`
123
- );
124
- }
125
- }
126
- var ComponentFileSchema = z.object({
127
- path: z.string(),
128
- target: z.string(),
129
- type: z.enum(["component", "types", "shader", "lib", "docs"]),
130
- content: z.string()
131
- });
132
- var RegistryComponentSchema = z.object({
133
- slug: z.string(),
134
- name: z.string(),
135
- title: z.string(),
136
- description: z.string(),
137
- version: z.string(),
138
- tier: z.enum(["free", "pro"]),
139
- category: z.string(),
140
- type: z.string(),
141
- frameworks: z.array(z.string()),
142
- files: z.array(ComponentFileSchema),
143
- dependencies: z.array(z.string()),
144
- devDependencies: z.array(z.string()),
145
- registryDependencies: z.array(z.string()),
146
- requiresClient: z.boolean(),
147
- supportsReducedMotion: z.boolean(),
148
- usesWebGL: z.boolean(),
149
- usesPointer: z.boolean(),
150
- usesScroll: z.boolean(),
151
- // Optional metadata — kept in sync with the registry builder schema.
152
- // Declared here (rather than relying on .passthrough()) so the CLI can
153
- // read them with full type-safety for post-install guidance.
154
- entry: z.string().optional(),
155
- exportName: z.string().optional(),
156
- usesTailwind: z.boolean().optional(),
157
- fallbacks: z.array(z.string()).optional(),
158
- recipes: z.array(z.string()).optional(),
159
- docsUrl: z.string().optional(),
160
- previewUrl: z.string().optional()
161
- }).passthrough();
162
- var IndexComponentSchema = z.object({
163
- slug: z.string(),
164
- name: z.string(),
165
- title: z.string(),
166
- description: z.string(),
167
- version: z.string(),
168
- tier: z.enum(["free", "pro"]),
169
- category: z.string(),
170
- type: z.string(),
171
- frameworks: z.array(z.string()),
172
- files: z.array(z.object({
173
- path: z.string(),
174
- target: z.string(),
175
- type: z.enum(["component", "types", "shader", "lib", "docs"])
176
- })),
177
- dependencies: z.array(z.string()),
178
- devDependencies: z.array(z.string()),
179
- registryDependencies: z.array(z.string()),
180
- requiresClient: z.boolean(),
181
- supportsReducedMotion: z.boolean(),
182
- usesWebGL: z.boolean(),
183
- usesPointer: z.boolean(),
184
- usesScroll: z.boolean(),
185
- entry: z.string().optional(),
186
- exportName: z.string().optional(),
187
- usesTailwind: z.boolean().optional()
188
- }).passthrough();
189
- var RegistryIndexSchema = z.object({
190
- version: z.string(),
191
- components: z.array(IndexComponentSchema)
192
- });
193
- var VVConfigSchema = z.object({
194
- tsx: z.boolean(),
195
- framework: z.enum(["next", "vite", "unknown"]),
196
- aliases: z.object({
197
- vv: z.string()
198
- })
199
- });
200
- var VVGlobalConfigSchema = z.object({
201
- // Auth — license key for paid components
202
- auth: z.object({
203
- token: z.string().optional(),
204
- email: z.string().optional(),
205
- tier: z.enum(["free", "pro", "team"]).optional(),
206
- expiresAt: z.string().optional()
207
- }).optional(),
208
- // Preferences
209
- telemetry: z.boolean().optional()
210
- }).passthrough();
211
- var ManifestEntrySchema = z.object({
212
- version: z.string(),
213
- installedAt: z.string(),
214
- installedOn: z.string(),
215
- files: z.array(z.string())
216
- });
217
- var ManifestSchema = z.object({
218
- components: z.record(z.string(), ManifestEntrySchema)
219
- });
220
-
221
- // src/utils/config.ts
222
- var CONFIG_FILE_NAME = "vv.config.json";
223
- function getConfigPath(cwd = process.cwd()) {
224
- return path2.join(cwd, CONFIG_FILE_NAME);
225
- }
226
- function loadConfig(cwd = process.cwd()) {
227
- const configPath = getConfigPath(cwd);
228
- if (!fs2.existsSync(configPath)) {
229
- return null;
230
- }
231
- let raw;
232
- try {
233
- const content = fs2.readFileSync(configPath, "utf-8");
234
- raw = JSON.parse(content);
235
- } catch {
236
- throw new Error(
237
- `Failed to parse vv.config.json \u2014 the file contains invalid JSON. Delete it and run "npx vectorvesper init" to regenerate.`
238
- );
239
- }
240
- const result = VVConfigSchema.safeParse(raw);
241
- if (!result.success) {
242
- const issues = result.error.issues.map((i) => ` \u2022 ${i.path.join(".")}: ${i.message}`).join("\n");
243
- throw new Error(
244
- `Invalid vv.config.json \u2014 schema validation failed:
245
- ${issues}
246
- Delete the file and run "npx vectorvesper init" to regenerate.`
247
- );
248
- }
249
- return result.data;
250
- }
251
- function writeConfig(config, cwd = process.cwd()) {
252
- const configPath = getConfigPath(cwd);
253
- fs2.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
254
- }
255
- var GLOBAL_CONFIG_DIR = path2.join(os.homedir(), ".vv");
256
- var GLOBAL_CONFIG_PATH = path2.join(GLOBAL_CONFIG_DIR, "config.json");
257
- function getGlobalConfigPath() {
258
- return GLOBAL_CONFIG_PATH;
259
- }
260
- function loadGlobalConfig() {
261
- if (!fs2.existsSync(GLOBAL_CONFIG_PATH)) {
262
- return {};
263
- }
264
- try {
265
- const content = fs2.readFileSync(GLOBAL_CONFIG_PATH, "utf-8");
266
- const raw = JSON.parse(content);
267
- const result = VVGlobalConfigSchema.safeParse(raw);
268
- if (!result.success) {
269
- logger.debug(`Global config validation failed: ${result.error.message}`);
270
- return {};
271
- }
272
- return result.data;
273
- } catch {
274
- logger.debug("Failed to parse global config, using defaults.");
275
- return {};
276
- }
277
- }
278
- function saveGlobalConfig(config) {
279
- if (!fs2.existsSync(GLOBAL_CONFIG_DIR)) {
280
- fs2.mkdirSync(GLOBAL_CONFIG_DIR, { recursive: true });
281
- }
282
- fs2.writeFileSync(GLOBAL_CONFIG_PATH, JSON.stringify(config, null, 2), "utf-8");
283
- }
284
- function getAuthToken() {
285
- const config = loadGlobalConfig();
286
- return config.auth?.token;
287
- }
288
- function resolveAlias(alias, hasSrcDir) {
289
- if (alias.startsWith("@/")) {
290
- return alias.replace("@/", hasSrcDir ? "src/" : "");
291
- }
292
- if (alias.startsWith("~/")) {
293
- return alias.replace("~/", hasSrcDir ? "src/" : "");
294
- }
295
- return alias;
296
- }
297
-
298
- // src/commands/init.ts
299
26
  async function initCommand(options = {}) {
300
27
  console.log("");
301
- intro(pc2.cyan(pc2.bold(" Vector Vesper Setup ")));
28
+ intro(pc.cyan(pc.bold(" Vector Vesper Setup ")));
302
29
  const projectInfo = detectProject();
303
30
  let tsx = projectInfo.isTypeScript;
304
31
  let framework = projectInfo.framework;
@@ -308,39 +35,39 @@ async function initCommand(options = {}) {
308
35
  const existingConfig = loadConfig();
309
36
  if (existingConfig) {
310
37
  const shouldOverwrite = await confirm({
311
- message: pc2.yellow("vv.config.json already exists. Overwrite it?"),
38
+ message: pc.yellow("vv.config.json already exists. Overwrite it?"),
312
39
  initialValue: false
313
40
  });
314
41
  if (isCancel(shouldOverwrite) || !shouldOverwrite) {
315
- outro(pc2.red("Setup cancelled."));
42
+ outro(pc.red("Setup cancelled."));
316
43
  return;
317
44
  }
318
45
  }
319
46
  } catch (error) {
320
47
  const message = error instanceof Error ? error.message : String(error);
321
- console.log(pc2.yellow(`
48
+ console.log(pc.yellow(`
322
49
  \u26A0\uFE0F ${message}
323
50
  `));
324
51
  const shouldReplace = await confirm({
325
- message: pc2.yellow("Replace the corrupted config?"),
52
+ message: pc.yellow("Replace the corrupted config?"),
326
53
  initialValue: true
327
54
  });
328
55
  if (isCancel(shouldReplace) || !shouldReplace) {
329
- outro(pc2.red("Setup cancelled."));
56
+ outro(pc.red("Setup cancelled."));
330
57
  return;
331
58
  }
332
59
  }
333
60
  const tsxResponse = await confirm({
334
- message: `Use TypeScript? ${pc2.dim(`(Detected: ${projectInfo.isTypeScript ? "Yes" : "No"})`)}`,
61
+ message: `Use TypeScript? ${pc.dim(`(Detected: ${projectInfo.isTypeScript ? "Yes" : "No"})`)}`,
335
62
  initialValue: projectInfo.isTypeScript
336
63
  });
337
64
  if (isCancel(tsxResponse)) {
338
- outro(pc2.red("Setup cancelled."));
65
+ outro(pc.red("Setup cancelled."));
339
66
  return;
340
67
  }
341
68
  tsx = tsxResponse;
342
69
  const frameworkResponse = await select({
343
- message: `Configure your framework: ${pc2.dim(`(Detected: ${projectInfo.framework})`)}`,
70
+ message: `Configure your framework: ${pc.dim(`(Detected: ${projectInfo.framework})`)}`,
344
71
  options: [
345
72
  { value: "next", label: "Next.js" },
346
73
  { value: "vite", label: "Vite" },
@@ -349,7 +76,7 @@ async function initCommand(options = {}) {
349
76
  initialValue: projectInfo.framework
350
77
  });
351
78
  if (isCancel(frameworkResponse)) {
352
- outro(pc2.red("Setup cancelled."));
79
+ outro(pc.red("Setup cancelled."));
353
80
  return;
354
81
  }
355
82
  framework = frameworkResponse;
@@ -365,15 +92,15 @@ async function initCommand(options = {}) {
365
92
  }
366
93
  });
367
94
  if (isCancel(aliasResponse)) {
368
- outro(pc2.red("Setup cancelled."));
95
+ outro(pc.red("Setup cancelled."));
369
96
  return;
370
97
  }
371
98
  aliasInput = aliasResponse;
372
99
  } else {
373
- console.log(pc2.dim(` \u26A1 Running in non-interactive mode (-y)`));
374
- console.log(pc2.dim(` \u2022 TypeScript: ${tsx ? "Yes" : "No"}`));
375
- console.log(pc2.dim(` \u2022 Framework: ${framework}`));
376
- console.log(pc2.dim(` \u2022 Components Alias: ${aliasInput}`));
100
+ console.log(pc.dim(` \u26A1 Running in non-interactive mode (-y)`));
101
+ console.log(pc.dim(` \u2022 TypeScript: ${tsx ? "Yes" : "No"}`));
102
+ console.log(pc.dim(` \u2022 Framework: ${framework}`));
103
+ console.log(pc.dim(` \u2022 Components Alias: ${aliasInput}`));
377
104
  }
378
105
  const config = {
379
106
  tsx,
@@ -385,190 +112,34 @@ async function initCommand(options = {}) {
385
112
  try {
386
113
  writeConfig(config);
387
114
  const targetLocalDir = resolveAlias(aliasInput, projectInfo.hasSrcDir);
388
- const absoluteTargetDir = path3.join(process.cwd(), targetLocalDir);
389
- if (!fs3.existsSync(absoluteTargetDir)) {
390
- fs3.mkdirSync(absoluteTargetDir, { recursive: true });
115
+ const absoluteTargetDir = path.join(process.cwd(), targetLocalDir);
116
+ if (!fs.existsSync(absoluteTargetDir)) {
117
+ fs.mkdirSync(absoluteTargetDir, { recursive: true });
391
118
  }
392
- const manifestPath = path3.join(process.cwd(), "vv-manifest.json");
393
- if (!fs3.existsSync(manifestPath)) {
394
- fs3.writeFileSync(manifestPath, JSON.stringify({ components: {} }, null, 2), "utf-8");
119
+ const manifestPath = path.join(process.cwd(), "vv-manifest.json");
120
+ if (!fs.existsSync(manifestPath)) {
121
+ fs.writeFileSync(manifestPath, JSON.stringify({ components: {} }, null, 2), "utf-8");
395
122
  }
396
123
  console.log("");
397
124
  outro(
398
- `${pc2.green(pc2.bold("\u2714 Success!"))} Vector Vesper initialized.
125
+ `${pc.green(pc.bold("\u2714 Success!"))} Vector Vesper initialized.
399
126
 
400
- \u2022 Configuration written to ${pc2.cyan("vv.config.json")}
401
- \u2022 Target directory created at ${pc2.cyan(targetLocalDir)}
402
- \u2022 Manifest created at ${pc2.cyan("vv-manifest.json")}
127
+ \u2022 Configuration written to ${pc.cyan("vv.config.json")}
128
+ \u2022 Target directory created at ${pc.cyan(targetLocalDir)}
129
+ \u2022 Manifest created at ${pc.cyan("vv-manifest.json")}
403
130
 
404
- \u{1F449} Next, run: ${pc2.bold(pc2.cyan("npx vectorvesper add <slug>"))} to add a component.`
131
+ \u{1F449} Next, run: ${pc.bold(pc.cyan("npx vectorvesper add <slug>"))} to add a component.`
405
132
  );
406
133
  } catch (error) {
407
134
  const message = error instanceof Error ? error.message : String(error);
408
- outro(pc2.red(`Failed to initialize: ${message}`));
135
+ outro(pc.red(`Failed to initialize: ${message}`));
409
136
  process.exit(1);
410
137
  }
411
138
  }
412
139
 
413
140
  // src/commands/list.ts
414
- import pc3 from "picocolors";
141
+ import pc2 from "picocolors";
415
142
  import ora from "ora";
416
-
417
- // src/utils/registry.ts
418
- import fs4 from "fs";
419
- import path4 from "path";
420
- import { fileURLToPath } from "url";
421
- var DEFAULT_REGISTRY_URL = "https://raw.githubusercontent.com/vectorvesper/vv-components/main/r";
422
- var FETCH_TIMEOUT_MS = 15e3;
423
- var MAX_RETRIES = 1;
424
- var RETRY_DELAY_MS = 1e3;
425
- function getRegistryBaseUrl() {
426
- return process.env.VV_REGISTRY_URL || DEFAULT_REGISTRY_URL;
427
- }
428
- function handleHttpError(status, url) {
429
- switch (status) {
430
- case 401:
431
- throw new Error(
432
- `Authentication required. This component requires a valid license key.
433
- \u{1F449} Run "npx vectorvesper login <your-license-key>" to authenticate.
434
- \u{1F511} Get a license at https://vectorvesper.dev/pricing`
435
- );
436
- case 402:
437
- throw new Error(
438
- `This is a Pro component and requires a license.
439
- \u{1F449} Get lifetime access at https://vectorvesper.dev/pricing
440
- \u{1F4A1} Run "npx vectorvesper list" to see all free components.`
441
- );
442
- case 403:
443
- throw new Error(
444
- `Access denied. Your license doesn't include this component.
445
- \u{1F449} Check your account at https://vectorvesper.dev/account
446
- \u{1F4A1} Run "npx vectorvesper whoami" to see your current access.`
447
- );
448
- case 404:
449
- throw new Error(
450
- `Component not found in the registry.
451
- \u{1F449} Run "npx vectorvesper list" to see all available components.`
452
- );
453
- case 429:
454
- throw new Error(
455
- `Rate limited by the registry. Please wait a moment and try again.`
456
- );
457
- default:
458
- throw new Error(
459
- `Registry request failed: HTTP ${status}
460
- URL: ${url}`
461
- );
462
- }
463
- }
464
- async function fetchWithRetry(url) {
465
- const token = getAuthToken();
466
- const headers = {
467
- "User-Agent": "vv-cli",
468
- "Accept": "application/json"
469
- };
470
- const isPublicRegistry = url.includes("raw.githubusercontent.com");
471
- if (token && !isPublicRegistry) {
472
- headers["Authorization"] = `Bearer ${token}`;
473
- logger.debug(`Using auth token for request`);
474
- }
475
- let lastError = null;
476
- for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
477
- try {
478
- if (attempt > 0) {
479
- logger.debug(`Retry attempt ${attempt} for ${url}`);
480
- await new Promise((resolve) => setTimeout(resolve, RETRY_DELAY_MS * attempt));
481
- }
482
- logger.debug(`Fetching: ${url}`);
483
- const response = await fetch(url, {
484
- headers,
485
- signal: AbortSignal.timeout(FETCH_TIMEOUT_MS)
486
- });
487
- if (!response.ok) {
488
- if (response.status >= 400 && response.status < 500) {
489
- handleHttpError(response.status, url);
490
- }
491
- throw new Error(`HTTP ${response.status}`);
492
- }
493
- return await response.text();
494
- } catch (error) {
495
- if (error instanceof Error) {
496
- if (error.message.includes("Authentication required") || error.message.includes("Pro component") || error.message.includes("Access denied") || error.message.includes("not found in the registry")) {
497
- throw error;
498
- }
499
- if (error.name === "TimeoutError" || error.name === "AbortError") {
500
- lastError = new Error(
501
- `Request timed out after ${FETCH_TIMEOUT_MS / 1e3}s. Check your internet connection or try again.`
502
- );
503
- continue;
504
- }
505
- lastError = error;
506
- } else {
507
- lastError = new Error(String(error));
508
- }
509
- }
510
- }
511
- throw lastError || new Error(`Failed to fetch: ${url}`);
512
- }
513
- async function fetchRegistryData(urlOrPath) {
514
- if (urlOrPath.startsWith("http://") || urlOrPath.startsWith("https://")) {
515
- if (urlOrPath.startsWith("http://") && !urlOrPath.includes("localhost") && !urlOrPath.includes("127.0.0.1")) {
516
- logger.warn("Using insecure HTTP for registry. Consider switching to HTTPS.");
517
- }
518
- return fetchWithRetry(urlOrPath);
519
- }
520
- let cleanPath = urlOrPath;
521
- if (urlOrPath.startsWith("file://")) {
522
- cleanPath = fileURLToPath(urlOrPath);
523
- }
524
- cleanPath = path4.resolve(cleanPath);
525
- if (!fs4.existsSync(cleanPath)) {
526
- throw new Error(`Registry path not found: ${cleanPath}`);
527
- }
528
- logger.debug(`Reading local registry: ${cleanPath}`);
529
- return fs4.readFileSync(cleanPath, "utf-8");
530
- }
531
- async function fetchRegistryIndex() {
532
- const baseUrl = getRegistryBaseUrl();
533
- const url = baseUrl.endsWith("/") ? `${baseUrl}registry.json` : `${baseUrl}/registry.json`;
534
- const content = await fetchRegistryData(url);
535
- let raw;
536
- try {
537
- raw = JSON.parse(content);
538
- } catch {
539
- throw new Error("Failed to parse registry index \u2014 received invalid JSON.");
540
- }
541
- const result = RegistryIndexSchema.safeParse(raw);
542
- if (!result.success) {
543
- logger.debug(`Registry index validation errors: ${result.error.message}`);
544
- throw new Error("Registry index failed validation. The registry may be corrupted or incompatible with this CLI version.");
545
- }
546
- return result.data;
547
- }
548
- async function fetchComponent(slug) {
549
- validateSlug(slug);
550
- const baseUrl = getRegistryBaseUrl();
551
- const url = baseUrl.endsWith("/") ? `${baseUrl}${slug}.json` : `${baseUrl}/${slug}.json`;
552
- const content = await fetchRegistryData(url);
553
- let raw;
554
- try {
555
- raw = JSON.parse(content);
556
- } catch {
557
- throw new Error(`Failed to parse component "${slug}" \u2014 received invalid JSON.`);
558
- }
559
- const result = RegistryComponentSchema.safeParse(raw);
560
- if (!result.success) {
561
- const issues = result.error.issues.map((i) => ` \u2022 ${i.path.join(".")}: ${i.message}`).join("\n");
562
- logger.debug(`Component "${slug}" validation errors:
563
- ${issues}`);
564
- throw new Error(
565
- `Component "${slug}" failed validation. This may indicate an incompatible registry version. Try updating the CLI.`
566
- );
567
- }
568
- return result.data;
569
- }
570
-
571
- // src/commands/list.ts
572
143
  async function listCommand() {
573
144
  const spinner = ora({
574
145
  text: "Fetching components list...",
@@ -576,55 +147,55 @@ async function listCommand() {
576
147
  }).start();
577
148
  try {
578
149
  const registry = await fetchRegistryIndex();
579
- spinner.succeed(pc3.green("Fetched components list successfully!\n"));
150
+ spinner.succeed(pc2.green("Fetched components list successfully!\n"));
580
151
  if (registry.components.length === 0) {
581
- console.log(pc3.dim(" No components available in the registry yet."));
582
- console.log(pc3.dim(" Check back soon or visit https://vectorvesper.dev\n"));
152
+ console.log(pc2.dim(" No components available in the registry yet."));
153
+ console.log(pc2.dim(" Check back soon or visit https://vectorvesper.dev\n"));
583
154
  return;
584
155
  }
585
156
  const hasAuth = !!getAuthToken();
586
- console.log(pc3.bold(pc3.white("Vector Vesper Available Components:")));
587
- console.log(pc3.dim("--------------------------------------------------------------------------------"));
157
+ console.log(pc2.bold(pc2.white("Vector Vesper Available Components:")));
158
+ console.log(pc2.dim("--------------------------------------------------------------------------------"));
588
159
  for (const c of registry.components) {
589
- const slugCol = pc3.cyan(c.slug.padEnd(25));
590
- const categoryCol = pc3.yellow(c.category.padEnd(15));
160
+ const slugCol = pc2.cyan(c.slug.padEnd(25));
161
+ const categoryCol = pc2.yellow(c.category.padEnd(15));
591
162
  let tierBadge;
592
163
  if (c.tier === "pro") {
593
- tierBadge = hasAuth ? pc3.magenta("pro ") : pc3.dim("\u{1F512} ");
164
+ tierBadge = hasAuth ? pc2.magenta("pro ") : pc2.dim("\u{1F512} ");
594
165
  } else {
595
- tierBadge = pc3.green("free");
166
+ tierBadge = pc2.green("free");
596
167
  }
597
- console.log(`${slugCol} [${tierBadge}] ${categoryCol} ${pc3.gray(c.description)}`);
168
+ console.log(`${slugCol} [${tierBadge}] ${categoryCol} ${pc2.gray(c.description)}`);
598
169
  }
599
- console.log(pc3.dim("--------------------------------------------------------------------------------"));
170
+ console.log(pc2.dim("--------------------------------------------------------------------------------"));
600
171
  const freeCount = registry.components.filter((c) => c.tier === "free").length;
601
172
  const proCount = registry.components.filter((c) => c.tier === "pro").length;
602
173
  console.log(`
603
- ${pc3.green(String(freeCount))} free components${proCount > 0 ? ` \xB7 ${pc3.magenta(String(proCount))} pro components` : ""}`);
174
+ ${pc2.green(String(freeCount))} free components${proCount > 0 ? ` \xB7 ${pc2.magenta(String(proCount))} pro components` : ""}`);
604
175
  if (proCount > 0 && !hasAuth) {
605
- console.log(` \u{1F511} ${pc3.dim("Unlock pro components:")} ${pc3.cyan("npx vectorvesper login <key>")} ${pc3.dim("\xB7")} ${pc3.cyan("https://vectorvesper.dev/pricing")}`);
176
+ console.log(` \u{1F511} ${pc2.dim("Unlock pro components:")} ${pc2.cyan("npx vectorvesper login <key>")} ${pc2.dim("\xB7")} ${pc2.cyan("https://vectorvesper.dev/pricing")}`);
606
177
  }
607
178
  console.log(`
608
- \u{1F449} Run ${pc3.bold(pc3.cyan("npx vectorvesper add <slug>"))} to add a component to your project.
179
+ \u{1F449} Run ${pc2.bold(pc2.cyan("npx vectorvesper add <slug>"))} to add a component to your project.
609
180
  `);
610
181
  } catch (error) {
611
182
  const message = error instanceof Error ? error.message : String(error);
612
- spinner.fail(pc3.red(`Failed to fetch components list: ${message}`));
183
+ spinner.fail(pc2.red(`Failed to fetch components list: ${message}`));
613
184
  process.exit(1);
614
185
  }
615
186
  }
616
187
 
617
188
  // src/commands/add.ts
618
- import fs7 from "fs";
619
- import path7 from "path";
189
+ import fs4 from "fs";
190
+ import path4 from "path";
620
191
  import ora2 from "ora";
621
- import pc6 from "picocolors";
192
+ import pc5 from "picocolors";
622
193
  import { confirm as confirm2, isCancel as isCancel2 } from "@clack/prompts";
623
194
 
624
195
  // src/utils/installer.ts
625
- import fs5 from "fs";
626
- import path5 from "path";
627
- import pc4 from "picocolors";
196
+ import fs2 from "fs";
197
+ import path2 from "path";
198
+ import pc3 from "picocolors";
628
199
  var MAX_DEPTH = 20;
629
200
  function toForwardSlash(p) {
630
201
  return p.replace(/\\/g, "/");
@@ -644,8 +215,8 @@ async function resolveComponentTree(slug) {
644
215
  if (component.tier === "pro" && !getAuthToken()) {
645
216
  throw new Error(
646
217
  `"${componentSlug}" is a Pro component and requires a license.
647
- \u{1F449} Run ${pc4.cyan("npx vectorvesper login <your-license-key>")} to unlock pro components.
648
- \u{1F511} Get a license at ${pc4.cyan("https://vectorvesper.dev/pricing")}`
218
+ \u{1F449} Run ${pc3.cyan("npx vectorvesper login <your-license-key>")} to unlock pro components.
219
+ \u{1F511} Get a license at ${pc3.cyan("https://vectorvesper.dev/pricing")}`
649
220
  );
650
221
  }
651
222
  for (const depSlug of component.registryDependencies ?? []) {
@@ -658,12 +229,12 @@ async function resolveComponentTree(slug) {
658
229
  }
659
230
  function planFiles(components, installDir, projectRoot) {
660
231
  const planned = [];
661
- const compDir = path5.join(projectRoot, installDir);
232
+ const compDir = path2.join(projectRoot, installDir);
662
233
  for (const component of components) {
663
234
  for (const file of component.files) {
664
- const absolutePath = path5.resolve(compDir, file.target);
665
- const relativeFromRoot = path5.relative(projectRoot, absolutePath);
666
- if (relativeFromRoot.startsWith("..") || path5.isAbsolute(relativeFromRoot)) {
235
+ const absolutePath = path2.resolve(compDir, file.target);
236
+ const relativeFromRoot = path2.relative(projectRoot, absolutePath);
237
+ if (relativeFromRoot.startsWith("..") || path2.isAbsolute(relativeFromRoot)) {
667
238
  throw new Error(
668
239
  `Security Error: component target tries to escape project root: ${file.target}`
669
240
  );
@@ -673,7 +244,7 @@ function planFiles(components, installDir, projectRoot) {
673
244
  relativePath: relativeFromRoot,
674
245
  target: file.target,
675
246
  content: file.content,
676
- exists: fs5.existsSync(absolutePath)
247
+ exists: fs2.existsSync(absolutePath)
677
248
  });
678
249
  }
679
250
  }
@@ -681,28 +252,28 @@ function planFiles(components, installDir, projectRoot) {
681
252
  }
682
253
  function writeFiles(files) {
683
254
  for (const file of files) {
684
- const folder = path5.dirname(file.absolutePath);
685
- if (!fs5.existsSync(folder)) {
686
- fs5.mkdirSync(folder, { recursive: true });
255
+ const folder = path2.dirname(file.absolutePath);
256
+ if (!fs2.existsSync(folder)) {
257
+ fs2.mkdirSync(folder, { recursive: true });
687
258
  }
688
- fs5.writeFileSync(file.absolutePath, file.content, "utf-8");
259
+ fs2.writeFileSync(file.absolutePath, file.content, "utf-8");
689
260
  }
690
261
  }
691
262
  var MANIFEST_NAME = "vv-manifest.json";
692
263
  function getManifestPath(projectRoot) {
693
- return path5.join(projectRoot, MANIFEST_NAME);
264
+ return path2.join(projectRoot, MANIFEST_NAME);
694
265
  }
695
266
  function readManifest(projectRoot) {
696
267
  const manifestPath = getManifestPath(projectRoot);
697
- if (!fs5.existsSync(manifestPath)) {
268
+ if (!fs2.existsSync(manifestPath)) {
698
269
  return { components: {} };
699
270
  }
700
- const parsed = JSON.parse(fs5.readFileSync(manifestPath, "utf-8"));
271
+ const parsed = JSON.parse(fs2.readFileSync(manifestPath, "utf-8"));
701
272
  if (!parsed.components) parsed.components = {};
702
273
  return parsed;
703
274
  }
704
275
  function writeManifest(projectRoot, manifest) {
705
- fs5.writeFileSync(getManifestPath(projectRoot), JSON.stringify(manifest, null, 2), "utf-8");
276
+ fs2.writeFileSync(getManifestPath(projectRoot), JSON.stringify(manifest, null, 2), "utf-8");
706
277
  }
707
278
  function recordInstall(components, installDir, projectRoot) {
708
279
  const manifest = readManifest(projectRoot);
@@ -710,7 +281,7 @@ function recordInstall(components, installDir, projectRoot) {
710
281
  for (const component of components) {
711
282
  manifest.components[component.slug] = {
712
283
  version: component.version,
713
- installedAt: toForwardSlash(path5.join(installDir, component.slug)),
284
+ installedAt: toForwardSlash(path2.join(installDir, component.slug)),
714
285
  installedOn: today,
715
286
  files: component.files.map((f) => f.target)
716
287
  };
@@ -718,7 +289,7 @@ function recordInstall(components, installDir, projectRoot) {
718
289
  writeManifest(projectRoot, manifest);
719
290
  }
720
291
  function findOrphanedFiles(components, installDir, projectRoot, previousManifest) {
721
- const compDir = path5.join(projectRoot, installDir);
292
+ const compDir = path2.join(projectRoot, installDir);
722
293
  const currentTargets = /* @__PURE__ */ new Set();
723
294
  for (const component of components) {
724
295
  for (const file of component.files) currentTargets.add(file.target);
@@ -732,10 +303,10 @@ function findOrphanedFiles(components, installDir, projectRoot, previousManifest
732
303
  if (currentTargets.has(target)) continue;
733
304
  if (seen.has(target)) continue;
734
305
  seen.add(target);
735
- const absolutePath = path5.resolve(compDir, target);
736
- const relativeFromRoot = path5.relative(projectRoot, absolutePath);
737
- if (relativeFromRoot.startsWith("..") || path5.isAbsolute(relativeFromRoot)) continue;
738
- if (!fs5.existsSync(absolutePath)) continue;
306
+ const absolutePath = path2.resolve(compDir, target);
307
+ const relativeFromRoot = path2.relative(projectRoot, absolutePath);
308
+ if (relativeFromRoot.startsWith("..") || path2.isAbsolute(relativeFromRoot)) continue;
309
+ if (!fs2.existsSync(absolutePath)) continue;
739
310
  orphans.push({ absolutePath, relativePath: relativeFromRoot, target });
740
311
  }
741
312
  }
@@ -743,26 +314,26 @@ function findOrphanedFiles(components, installDir, projectRoot, previousManifest
743
314
  }
744
315
  function removeFiles(files) {
745
316
  for (const file of files) {
746
- if (fs5.existsSync(file.absolutePath)) {
747
- fs5.rmSync(file.absolutePath, { force: true });
317
+ if (fs2.existsSync(file.absolutePath)) {
318
+ fs2.rmSync(file.absolutePath, { force: true });
748
319
  }
749
320
  }
750
321
  }
751
322
 
752
323
  // src/utils/install.ts
753
- import fs6 from "fs";
754
- import path6 from "path";
324
+ import fs3 from "fs";
325
+ import path3 from "path";
755
326
  import { spawnSync } from "child_process";
756
327
  var NPM_NAME_REGEX = /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/i;
757
328
  function isValidPackageName(name) {
758
329
  return NPM_NAME_REGEX.test(name);
759
330
  }
760
331
  function getMissingDependencies(components, projectRoot) {
761
- const pkgPath = path6.join(projectRoot, "package.json");
762
- if (!fs6.existsSync(pkgPath)) return [];
332
+ const pkgPath = path3.join(projectRoot, "package.json");
333
+ if (!fs3.existsSync(pkgPath)) return [];
763
334
  let installed = {};
764
335
  try {
765
- const pkg = JSON.parse(fs6.readFileSync(pkgPath, "utf-8"));
336
+ const pkg = JSON.parse(fs3.readFileSync(pkgPath, "utf-8"));
766
337
  installed = {
767
338
  ...pkg.dependencies,
768
339
  ...pkg.devDependencies,
@@ -807,7 +378,7 @@ function installDependencies(deps, pm, projectRoot) {
807
378
  }
808
379
 
809
380
  // src/utils/guidance.ts
810
- import pc5 from "picocolors";
381
+ import pc4 from "picocolors";
811
382
  function toPascalCase(input) {
812
383
  return input.split(/[^a-zA-Z0-9]+/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
813
384
  }
@@ -858,24 +429,24 @@ const ${varName} = dynamic(
858
429
  }
859
430
  function printGuidance(component, ctx) {
860
431
  const g = buildGuidance(component, ctx);
861
- console.log(pc5.bold(pc5.white(`
432
+ console.log(pc4.bold(pc4.white(`
862
433
  Using ${component.title || component.name}:`)));
863
434
  if (g.ssrSnippet) {
864
- console.log(pc5.dim(" // SSR-safe (Next.js) \u2014 disables server rendering for WebGL:"));
435
+ console.log(pc4.dim(" // SSR-safe (Next.js) \u2014 disables server rendering for WebGL:"));
865
436
  for (const line of g.ssrSnippet.split("\n")) {
866
- console.log(line ? ` ${pc5.cyan(line)}` : "");
437
+ console.log(line ? ` ${pc4.cyan(line)}` : "");
867
438
  }
868
439
  } else {
869
- console.log(` ${pc5.cyan(g.importSnippet)}`);
440
+ console.log(` ${pc4.cyan(g.importSnippet)}`);
870
441
  }
871
442
  for (const note of g.notes) {
872
- console.log(` ${pc5.green("\u2022")} ${pc5.dim(note)}`);
443
+ console.log(` ${pc4.green("\u2022")} ${pc4.dim(note)}`);
873
444
  }
874
445
  for (const warning of g.warnings) {
875
- console.log(` ${pc5.yellow("\u26A0")} ${pc5.yellow(warning)}`);
446
+ console.log(` ${pc4.yellow("\u26A0")} ${pc4.yellow(warning)}`);
876
447
  }
877
448
  if (g.docsUrl) {
878
- console.log(` ${pc5.dim("Docs:")} ${pc5.cyan(g.docsUrl)}`);
449
+ console.log(` ${pc4.dim("Docs:")} ${pc4.cyan(g.docsUrl)}`);
879
450
  }
880
451
  }
881
452
 
@@ -909,6 +480,7 @@ async function stripTypes(content, filename) {
909
480
  return result.code;
910
481
  }
911
482
  async function fileToJs(target, content) {
483
+ if (/\.d\.ts$/i.test(target)) return { target, content };
912
484
  if (!isTsSource(target)) return { target, content };
913
485
  try {
914
486
  const code = await stripTypes(content, target);
@@ -942,11 +514,11 @@ async function handleDependencies(components, projectRoot, projectInfo, options)
942
514
  const missing = getMissingDependencies(components, projectRoot);
943
515
  if (missing.length === 0) return;
944
516
  const installCmd = getInstallCommand(projectInfo.packageManager, missing);
945
- const depsLabel = missing.map((d) => pc6.cyan(d)).join(", ");
517
+ const depsLabel = missing.map((d) => pc5.cyan(d)).join(", ");
946
518
  if (options.install === false) {
947
- console.log(pc6.yellow(`
519
+ console.log(pc5.yellow(`
948
520
  \u26A0\uFE0F Missing dependencies: ${depsLabel}`));
949
- console.log(` Run: ${pc6.bold(pc6.cyan(installCmd))}`);
521
+ console.log(` Run: ${pc5.bold(pc5.cyan(installCmd))}`);
950
522
  return;
951
523
  }
952
524
  let shouldInstall = options.yes === true;
@@ -957,44 +529,44 @@ async function handleDependencies(components, projectRoot, projectInfo, options)
957
529
  initialValue: true
958
530
  });
959
531
  if (isCancel2(answer)) {
960
- console.log(pc6.dim(` Skipped. Run: ${pc6.cyan(installCmd)}`));
532
+ console.log(pc5.dim(` Skipped. Run: ${pc5.cyan(installCmd)}`));
961
533
  return;
962
534
  }
963
535
  shouldInstall = answer;
964
536
  }
965
537
  if (!shouldInstall) {
966
- console.log(pc6.dim(` Skipped. Run: ${pc6.cyan(installCmd)} when ready.`));
538
+ console.log(pc5.dim(` Skipped. Run: ${pc5.cyan(installCmd)} when ready.`));
967
539
  return;
968
540
  }
969
- console.log(pc6.dim(`
541
+ console.log(pc5.dim(`
970
542
  Installing dependencies with ${projectInfo.packageManager}...`));
971
543
  try {
972
544
  const ok = installDependencies(missing, projectInfo.packageManager, projectRoot);
973
545
  if (ok) {
974
- console.log(pc6.green(`\u2714 Dependencies installed.`));
546
+ console.log(pc5.green(`\u2714 Dependencies installed.`));
975
547
  } else {
976
- console.log(pc6.yellow(`\u26A0\uFE0F Dependency install did not complete. Run manually: ${pc6.cyan(installCmd)}`));
548
+ console.log(pc5.yellow(`\u26A0\uFE0F Dependency install did not complete. Run manually: ${pc5.cyan(installCmd)}`));
977
549
  }
978
550
  } catch (error) {
979
551
  const message = error instanceof Error ? error.message : String(error);
980
- console.log(pc6.yellow(`\u26A0\uFE0F ${message}`));
981
- console.log(` Run manually: ${pc6.bold(pc6.cyan(installCmd))}`);
552
+ console.log(pc5.yellow(`\u26A0\uFE0F ${message}`));
553
+ console.log(` Run manually: ${pc5.bold(pc5.cyan(installCmd))}`);
982
554
  }
983
555
  }
984
556
  async function handlePrune(orphans, slug, options) {
985
557
  if (orphans.length === 0) return;
986
- const list = orphans.map((o) => ` ${pc6.dim("\u2022")} ${pc6.cyan(o.relativePath)}`).join("\n");
558
+ const list = orphans.map((o) => ` ${pc5.dim("\u2022")} ${pc5.cyan(o.relativePath)}`).join("\n");
987
559
  let shouldPrune = options.prune === true;
988
560
  if (!shouldPrune) {
989
561
  console.log(
990
- pc6.yellow(
562
+ pc5.yellow(
991
563
  `
992
- \u{1F9F9} ${orphans.length} file(s) from a previous version of ${pc6.cyan(slug)} are no longer part of it:`
564
+ \u{1F9F9} ${orphans.length} file(s) from a previous version of ${pc5.cyan(slug)} are no longer part of it:`
993
565
  )
994
566
  );
995
567
  console.log(list);
996
568
  if (options.yes) {
997
- console.log(pc6.dim(` Re-run with ${pc6.cyan("--prune")} to remove them.`));
569
+ console.log(pc5.dim(` Re-run with ${pc5.cyan("--prune")} to remove them.`));
998
570
  return;
999
571
  }
1000
572
  const answer = await confirm2({
@@ -1002,16 +574,16 @@ async function handlePrune(orphans, slug, options) {
1002
574
  initialValue: true
1003
575
  });
1004
576
  if (isCancel2(answer) || !answer) {
1005
- console.log(pc6.dim(` Left in place. Run with ${pc6.cyan("--prune")} later to remove them.`));
577
+ console.log(pc5.dim(` Left in place. Run with ${pc5.cyan("--prune")} later to remove them.`));
1006
578
  return;
1007
579
  }
1008
580
  shouldPrune = true;
1009
581
  }
1010
582
  removeFiles(orphans);
1011
- console.log(pc6.green(`
583
+ console.log(pc5.green(`
1012
584
  \u{1F9F9} Removed ${orphans.length} orphaned file(s):`));
1013
585
  for (const o of orphans) {
1014
- console.log(` ${pc6.red("\u2212")} ${pc6.cyan(o.relativePath)}`);
586
+ console.log(` ${pc5.red("\u2212")} ${pc5.cyan(o.relativePath)}`);
1015
587
  }
1016
588
  }
1017
589
  async function addCommand(slug, options = {}) {
@@ -1019,7 +591,7 @@ async function addCommand(slug, options = {}) {
1019
591
  validateSlug(slug);
1020
592
  } catch (error) {
1021
593
  const message = error instanceof Error ? error.message : String(error);
1022
- console.error(`${pc6.red(pc6.bold("Error:"))} ${message}`);
594
+ console.error(`${pc5.red(pc5.bold("Error:"))} ${message}`);
1023
595
  process.exit(1);
1024
596
  }
1025
597
  let config;
@@ -1027,13 +599,13 @@ async function addCommand(slug, options = {}) {
1027
599
  config = loadConfig();
1028
600
  } catch (error) {
1029
601
  const message = error instanceof Error ? error.message : String(error);
1030
- console.error(`${pc6.red(pc6.bold("Error:"))} ${message}`);
602
+ console.error(`${pc5.red(pc5.bold("Error:"))} ${message}`);
1031
603
  process.exit(1);
1032
604
  }
1033
605
  if (!config) {
1034
606
  console.error(
1035
- `${pc6.red(pc6.bold("Error:"))} No ${pc6.cyan("vv.config.json")} found in this directory.
1036
- \u{1F449} Run ${pc6.bold(pc6.cyan("npx vectorvesper init"))} first to set up your project.`
607
+ `${pc5.red(pc5.bold("Error:"))} No ${pc5.cyan("vv.config.json")} found in this directory.
608
+ \u{1F449} Run ${pc5.bold(pc5.cyan("npx vectorvesper init"))} first to set up your project.`
1037
609
  );
1038
610
  process.exit(1);
1039
611
  return;
@@ -1041,13 +613,13 @@ async function addCommand(slug, options = {}) {
1041
613
  const projectInfo = detectProject();
1042
614
  const componentInstallDir = resolveAlias(config.aliases.vv, projectInfo.hasSrcDir);
1043
615
  const projectRoot = process.cwd();
1044
- const spinner = ora2({ text: `Resolving component ${pc6.cyan(slug)}...`, color: "cyan" }).start();
616
+ const spinner = ora2({ text: `Resolving component ${pc5.cyan(slug)}...`, color: "cyan" }).start();
1045
617
  let resolvedComponents;
1046
618
  try {
1047
619
  resolvedComponents = await resolveComponentTree(slug);
1048
620
  } catch (error) {
1049
621
  const message = error instanceof Error ? error.message : String(error);
1050
- spinner.fail(pc6.red(`Failed to resolve component "${slug}": ${message}`));
622
+ spinner.fail(pc5.red(`Failed to resolve component "${slug}": ${message}`));
1051
623
  process.exit(1);
1052
624
  return;
1053
625
  }
@@ -1057,6 +629,11 @@ async function addCommand(slug, options = {}) {
1057
629
  const t = await maybeTranspile(resolvedComponents, false);
1058
630
  resolvedComponents = t.components;
1059
631
  transpileWarnings = t.warnings;
632
+ } else {
633
+ resolvedComponents = resolvedComponents.map((c) => ({
634
+ ...c,
635
+ files: c.files.filter((f) => f.type !== "types")
636
+ }));
1060
637
  }
1061
638
  spinner.text = "Checking file conflicts...";
1062
639
  let planned;
@@ -1064,7 +641,7 @@ async function addCommand(slug, options = {}) {
1064
641
  planned = planFiles(resolvedComponents, componentInstallDir, projectRoot);
1065
642
  } catch (error) {
1066
643
  const message = error instanceof Error ? error.message : String(error);
1067
- spinner.fail(pc6.red(message));
644
+ spinner.fail(pc5.red(message));
1068
645
  process.exit(1);
1069
646
  return;
1070
647
  }
@@ -1073,11 +650,11 @@ async function addCommand(slug, options = {}) {
1073
650
  if (file.exists && !options.dryRun && !options.overwrite && !options.yes) {
1074
651
  spinner.stop();
1075
652
  const answer = await confirm2({
1076
- message: pc6.yellow(`File already exists: "${file.relativePath}". Overwrite?`),
653
+ message: pc5.yellow(`File already exists: "${file.relativePath}". Overwrite?`),
1077
654
  initialValue: false
1078
655
  });
1079
656
  if (isCancel2(answer) || !answer) {
1080
- console.log(pc6.dim(` Skipping existing file: ${file.relativePath}`));
657
+ console.log(pc5.dim(` Skipping existing file: ${file.relativePath}`));
1081
658
  spinner.start("Continuing installation...");
1082
659
  continue;
1083
660
  }
@@ -1090,7 +667,7 @@ async function addCommand(slug, options = {}) {
1090
667
  });
1091
668
  }
1092
669
  const targetComponent = resolvedComponents[resolvedComponents.length - 1];
1093
- const installPath = toForwardSlash(path7.join(componentInstallDir, targetComponent.slug));
670
+ const installPath = toForwardSlash(path4.join(componentInstallDir, targetComponent.slug));
1094
671
  let orphans = [];
1095
672
  try {
1096
673
  const previousManifest = readManifest(projectRoot);
@@ -1099,32 +676,32 @@ async function addCommand(slug, options = {}) {
1099
676
  orphans = [];
1100
677
  }
1101
678
  if (options.dryRun) {
1102
- spinner.succeed(pc6.yellow("Dry-run: simulation completed. No files were written."));
1103
- console.log(pc6.bold(pc6.yellow("\n[Dry Run] Files that would be created/modified:")));
679
+ spinner.succeed(pc5.yellow("Dry-run: simulation completed. No files were written."));
680
+ console.log(pc5.bold(pc5.yellow("\n[Dry Run] Files that would be created/modified:")));
1104
681
  for (const file of filesToWrite) {
1105
- const status = fs7.existsSync(file.absolutePath) ? pc6.yellow("(exists, would overwrite)") : pc6.green("(new)");
1106
- console.log(` ${pc6.cyan(file.relativePath)} ${status}`);
682
+ const status = fs4.existsSync(file.absolutePath) ? pc5.yellow("(exists, would overwrite)") : pc5.green("(new)");
683
+ console.log(` ${pc5.cyan(file.relativePath)} ${status}`);
1107
684
  }
1108
685
  if (orphans.length > 0) {
1109
- console.log(pc6.bold(pc6.yellow("\n[Dry Run] Orphaned files from a previous version:")));
686
+ console.log(pc5.bold(pc5.yellow("\n[Dry Run] Orphaned files from a previous version:")));
1110
687
  for (const o of orphans) {
1111
- const note = options.prune ? pc6.red("(would remove)") : pc6.dim("(use --prune to remove)");
1112
- console.log(` ${pc6.cyan(o.relativePath)} ${note}`);
688
+ const note = options.prune ? pc5.red("(would remove)") : pc5.dim("(use --prune to remove)");
689
+ console.log(` ${pc5.cyan(o.relativePath)} ${note}`);
1113
690
  }
1114
691
  }
1115
692
  const missing = getMissingDependencies(resolvedComponents, projectRoot);
1116
693
  if (missing.length > 0) {
1117
- console.log(pc6.yellow(`
1118
- \u26A0\uFE0F Would need dependencies: ${missing.map((d) => pc6.cyan(d)).join(", ")}`));
1119
- console.log(` ${pc6.dim(getInstallCommand(projectInfo.packageManager, missing))}`);
694
+ console.log(pc5.yellow(`
695
+ \u26A0\uFE0F Would need dependencies: ${missing.map((d) => pc5.cyan(d)).join(", ")}`));
696
+ console.log(` ${pc5.dim(getInstallCommand(projectInfo.packageManager, missing))}`);
1120
697
  }
1121
698
  console.log("");
1122
- console.log(pc6.bold(pc6.yellow(`\u2714 [Dry Run] Would add ${pc6.cyan(targetComponent.slug)} to ${installPath}`)));
699
+ console.log(pc5.bold(pc5.yellow(`\u2714 [Dry Run] Would add ${pc5.cyan(targetComponent.slug)} to ${installPath}`)));
1123
700
  console.log("");
1124
701
  return;
1125
702
  }
1126
703
  if (filesToWrite.length === 0) {
1127
- spinner.succeed(pc6.green("All files skipped (already up to date)."));
704
+ spinner.succeed(pc5.green("All files skipped (already up to date)."));
1128
705
  await handlePrune(orphans, targetComponent.slug, options);
1129
706
  return;
1130
707
  }
@@ -1133,7 +710,7 @@ async function addCommand(slug, options = {}) {
1133
710
  writeFiles(filesToWrite);
1134
711
  } catch (error) {
1135
712
  const message = error instanceof Error ? error.message : String(error);
1136
- spinner.fail(pc6.red(`Failed to write files: ${message}`));
713
+ spinner.fail(pc5.red(`Failed to write files: ${message}`));
1137
714
  process.exit(1);
1138
715
  return;
1139
716
  }
@@ -1144,10 +721,10 @@ async function addCommand(slug, options = {}) {
1144
721
  logger.warn(`Failed to update vv-manifest.json: ${message}`);
1145
722
  logger.warn("Component was installed but may not appear in 'npx vectorvesper info' or 'npx vectorvesper diff'.");
1146
723
  }
1147
- spinner.succeed(pc6.green("Files written successfully!"));
1148
- console.log(pc6.dim("\nCreated files:"));
724
+ spinner.succeed(pc5.green("Files written successfully!"));
725
+ console.log(pc5.dim("\nCreated files:"));
1149
726
  for (const file of filesToWrite) {
1150
- console.log(` ${pc6.green("\u2714")} ${pc6.cyan(file.relativePath)}`);
727
+ console.log(` ${pc5.green("\u2714")} ${pc5.cyan(file.relativePath)}`);
1151
728
  }
1152
729
  await handlePrune(orphans, targetComponent.slug, options);
1153
730
  await handleDependencies(resolvedComponents, projectRoot, projectInfo, options);
@@ -1157,20 +734,20 @@ async function addCommand(slug, options = {}) {
1157
734
  hasTailwind: projectInfo.hasTailwind
1158
735
  });
1159
736
  if (transpileWarnings.length > 0) {
1160
- console.log(pc6.yellow(`
737
+ console.log(pc5.yellow(`
1161
738
  \u26A0\uFE0F Some files were kept as TypeScript:`));
1162
- for (const w of transpileWarnings) console.log(` ${pc6.dim(w)}`);
739
+ for (const w of transpileWarnings) console.log(` ${pc5.dim(w)}`);
1163
740
  }
1164
741
  console.log("");
1165
- console.log(pc6.bold(pc6.green(`\u2714 Added ${pc6.cyan(targetComponent.slug)} to ${installPath}`)));
742
+ console.log(pc5.bold(pc5.green(`\u2714 Added ${pc5.cyan(targetComponent.slug)} to ${installPath}`)));
1166
743
  console.log("");
1167
- console.log(pc6.gray("\u{1F449} Loving Vector Vesper? Star the repo: https://github.com/vectorvesper/vv-components"));
1168
- console.log(pc6.gray("\u{1F680} Premium shader & pixel systems: https://vectorvesper.dev/pricing"));
744
+ console.log(pc5.gray("\u{1F449} Loving Vector Vesper? Star the repo: https://github.com/vectorvesper/vv-components"));
745
+ console.log(pc5.gray("\u{1F680} Premium shader & pixel systems: https://vectorvesper.dev/pricing"));
1169
746
  console.log("");
1170
747
  }
1171
748
 
1172
749
  // src/commands/update.ts
1173
- import pc7 from "picocolors";
750
+ import pc6 from "picocolors";
1174
751
  import ora3 from "ora";
1175
752
  async function updateCommand(slug, options = {}) {
1176
753
  const projectRoot = process.cwd();
@@ -1179,14 +756,14 @@ async function updateCommand(slug, options = {}) {
1179
756
  config = loadConfig();
1180
757
  } catch (error) {
1181
758
  const message = error instanceof Error ? error.message : String(error);
1182
- console.error(`${pc7.red(pc7.bold("Error:"))} ${message}`);
759
+ console.error(`${pc6.red(pc6.bold("Error:"))} ${message}`);
1183
760
  process.exit(1);
1184
761
  return;
1185
762
  }
1186
763
  if (!config) {
1187
764
  console.error(
1188
- `${pc7.red(pc7.bold("Error:"))} No ${pc7.cyan("vv.config.json")} found.
1189
- \u{1F449} Run ${pc7.bold(pc7.cyan("npx vectorvesper init"))} first.`
765
+ `${pc6.red(pc6.bold("Error:"))} No ${pc6.cyan("vv.config.json")} found.
766
+ \u{1F449} Run ${pc6.bold(pc6.cyan("npx vectorvesper init"))} first.`
1190
767
  );
1191
768
  process.exit(1);
1192
769
  return;
@@ -1196,9 +773,9 @@ async function updateCommand(slug, options = {}) {
1196
773
  const manifest = readManifest(projectRoot);
1197
774
  const installedSlugs = Object.keys(manifest.components);
1198
775
  if (installedSlugs.length === 0) {
1199
- console.log(pc7.yellow(`
776
+ console.log(pc6.yellow(`
1200
777
  \u26A0\uFE0F No components are installed in this project.`));
1201
- console.log(`\u{1F449} Add one with ${pc7.bold(pc7.cyan("npx vectorvesper add <slug>"))}
778
+ console.log(`\u{1F449} Add one with ${pc6.bold(pc6.cyan("npx vectorvesper add <slug>"))}
1202
779
  `);
1203
780
  return;
1204
781
  }
@@ -1208,16 +785,16 @@ async function updateCommand(slug, options = {}) {
1208
785
  validateSlug(slug);
1209
786
  } catch (error) {
1210
787
  const message = error instanceof Error ? error.message : String(error);
1211
- console.error(pc7.red(`
788
+ console.error(pc6.red(`
1212
789
  \u274C ${message}
1213
790
  `));
1214
791
  process.exit(1);
1215
792
  return;
1216
793
  }
1217
794
  if (!manifest.components[slug]) {
1218
- console.log(pc7.red(`
795
+ console.log(pc6.red(`
1219
796
  \u274C Component "${slug}" is not installed in this project.`));
1220
- console.log(`\u{1F449} Run ${pc7.cyan(`npx vectorvesper add ${slug}`)} to install it.
797
+ console.log(`\u{1F449} Run ${pc6.cyan(`npx vectorvesper add ${slug}`)} to install it.
1221
798
  `);
1222
799
  return;
1223
800
  }
@@ -1232,7 +809,7 @@ async function updateCommand(slug, options = {}) {
1232
809
  const updatedComponents = [];
1233
810
  const transpileWarnings = [];
1234
811
  for (const target of targets) {
1235
- spinner.text = `Updating ${pc7.cyan(target)}...`;
812
+ spinner.text = `Updating ${pc6.cyan(target)}...`;
1236
813
  try {
1237
814
  let components = await resolveComponentTree(target);
1238
815
  const remote = components[components.length - 1];
@@ -1245,6 +822,11 @@ async function updateCommand(slug, options = {}) {
1245
822
  const t = await maybeTranspile(components, false);
1246
823
  components = t.components;
1247
824
  transpileWarnings.push(...t.warnings);
825
+ } else {
826
+ components = components.map((c) => ({
827
+ ...c,
828
+ files: c.files.filter((f) => f.type !== "types")
829
+ }));
1248
830
  }
1249
831
  const planned = planFiles(components, installDir, projectRoot);
1250
832
  writeFiles(planned.map((f) => ({ absolutePath: f.absolutePath, content: f.content })));
@@ -1257,26 +839,26 @@ async function updateCommand(slug, options = {}) {
1257
839
  }
1258
840
  }
1259
841
  spinner.stop();
1260
- console.log(pc7.bold(pc7.cyan("\nVector Vesper Update\n")));
842
+ console.log(pc6.bold(pc6.cyan("\nVector Vesper Update\n")));
1261
843
  if (updated.length > 0) {
1262
- console.log(pc7.bold(pc7.green(` Updated (${updated.length}):`)));
1263
- for (const u of updated) console.log(` ${pc7.green("\u2714")} ${u}`);
1264
- console.log(pc7.dim(" Note: updating overwrites local edits to these files."));
844
+ console.log(pc6.bold(pc6.green(` Updated (${updated.length}):`)));
845
+ for (const u of updated) console.log(` ${pc6.green("\u2714")} ${u}`);
846
+ console.log(pc6.dim(" Note: updating overwrites local edits to these files."));
1265
847
  }
1266
848
  if (upToDate.length > 0) {
1267
- console.log(pc7.bold(pc7.gray(`
849
+ console.log(pc6.bold(pc6.gray(`
1268
850
  Already up to date (${upToDate.length}):`)));
1269
- console.log(` ${pc7.dim(upToDate.join(", "))}`);
851
+ console.log(` ${pc6.dim(upToDate.join(", "))}`);
1270
852
  }
1271
853
  if (failed.length > 0) {
1272
- console.log(pc7.bold(pc7.red(`
854
+ console.log(pc6.bold(pc6.red(`
1273
855
  Failed (${failed.length}):`)));
1274
- for (const f of failed) console.log(` ${pc7.red("\u2716")} ${f.slug}: ${pc7.dim(f.reason)}`);
856
+ for (const f of failed) console.log(` ${pc6.red("\u2716")} ${f.slug}: ${pc6.dim(f.reason)}`);
1275
857
  }
1276
858
  if (transpileWarnings.length > 0) {
1277
- console.log(pc7.yellow(`
859
+ console.log(pc6.yellow(`
1278
860
  \u26A0\uFE0F Some files were kept as TypeScript:`));
1279
- for (const w of transpileWarnings) console.log(` ${pc7.dim(w)}`);
861
+ for (const w of transpileWarnings) console.log(` ${pc6.dim(w)}`);
1280
862
  }
1281
863
  console.log("");
1282
864
  if (updatedComponents.length > 0) {
@@ -1286,16 +868,16 @@ async function updateCommand(slug, options = {}) {
1286
868
  }
1287
869
 
1288
870
  // src/commands/remove.ts
1289
- import fs8 from "fs";
1290
- import path8 from "path";
1291
- import pc8 from "picocolors";
871
+ import fs5 from "fs";
872
+ import path5 from "path";
873
+ import pc7 from "picocolors";
1292
874
  import { confirm as confirm3, isCancel as isCancel3 } from "@clack/prompts";
1293
875
  async function removeCommand(slug, options = {}) {
1294
876
  try {
1295
877
  validateSlug(slug);
1296
878
  } catch (error) {
1297
879
  const message = error instanceof Error ? error.message : String(error);
1298
- console.error(`${pc8.red(pc8.bold("Error:"))} ${message}`);
880
+ console.error(`${pc7.red(pc7.bold("Error:"))} ${message}`);
1299
881
  process.exit(1);
1300
882
  return;
1301
883
  }
@@ -1305,14 +887,14 @@ async function removeCommand(slug, options = {}) {
1305
887
  config = loadConfig();
1306
888
  } catch (error) {
1307
889
  const message = error instanceof Error ? error.message : String(error);
1308
- console.error(`${pc8.red(pc8.bold("Error:"))} ${message}`);
890
+ console.error(`${pc7.red(pc7.bold("Error:"))} ${message}`);
1309
891
  process.exit(1);
1310
892
  return;
1311
893
  }
1312
894
  if (!config) {
1313
895
  console.error(
1314
- `${pc8.red(pc8.bold("Error:"))} No ${pc8.cyan("vv.config.json")} found.
1315
- \u{1F449} Run ${pc8.bold(pc8.cyan("npx vectorvesper init"))} first.`
896
+ `${pc7.red(pc7.bold("Error:"))} No ${pc7.cyan("vv.config.json")} found.
897
+ \u{1F449} Run ${pc7.bold(pc7.cyan("npx vectorvesper init"))} first.`
1316
898
  );
1317
899
  process.exit(1);
1318
900
  return;
@@ -1320,50 +902,50 @@ async function removeCommand(slug, options = {}) {
1320
902
  const manifest = readManifest(projectRoot);
1321
903
  const entry = manifest.components[slug];
1322
904
  if (!entry) {
1323
- console.log(pc8.yellow(`
905
+ console.log(pc7.yellow(`
1324
906
  \u26A0\uFE0F Component "${slug}" is not installed (not in vv-manifest.json).`));
1325
- console.log(`\u{1F449} See installed components with ${pc8.bold(pc8.cyan("npx vectorvesper info"))}
907
+ console.log(`\u{1F449} See installed components with ${pc7.bold(pc7.cyan("npx vectorvesper info"))}
1326
908
  `);
1327
909
  return;
1328
910
  }
1329
911
  const projectInfo = detectProject();
1330
912
  const installDir = resolveAlias(config.aliases.vv, projectInfo.hasSrcDir);
1331
- const baseDir = path8.join(projectRoot, installDir);
913
+ const baseDir = path5.join(projectRoot, installDir);
1332
914
  const targets = entry.files ?? [];
1333
- const absoluteFiles = targets.map((t) => path8.resolve(baseDir, t));
1334
- console.log(pc8.bold(pc8.cyan(`
915
+ const absoluteFiles = targets.map((t) => path5.resolve(baseDir, t));
916
+ console.log(pc7.bold(pc7.cyan(`
1335
917
  Remove ${slug}
1336
918
  `)));
1337
- console.log(pc8.dim(" The following files will be deleted:"));
919
+ console.log(pc7.dim(" The following files will be deleted:"));
1338
920
  for (const f of absoluteFiles) {
1339
- console.log(` ${fs8.existsSync(f) ? pc8.red("\u2212") : pc8.dim("\xB7")} ${pc8.cyan(path8.relative(projectRoot, f))}`);
921
+ console.log(` ${fs5.existsSync(f) ? pc7.red("\u2212") : pc7.dim("\xB7")} ${pc7.cyan(path5.relative(projectRoot, f))}`);
1340
922
  }
1341
923
  if (!options.yes) {
1342
924
  const answer = await confirm3({
1343
- message: pc8.yellow(`Delete ${absoluteFiles.length} file(s) for "${slug}"?`),
925
+ message: pc7.yellow(`Delete ${absoluteFiles.length} file(s) for "${slug}"?`),
1344
926
  initialValue: false
1345
927
  });
1346
928
  if (isCancel3(answer) || !answer) {
1347
- console.log(pc8.dim("\n Cancelled. Nothing was removed.\n"));
929
+ console.log(pc7.dim("\n Cancelled. Nothing was removed.\n"));
1348
930
  return;
1349
931
  }
1350
932
  }
1351
933
  let deleted = 0;
1352
934
  for (const f of absoluteFiles) {
1353
935
  try {
1354
- if (fs8.existsSync(f)) {
1355
- fs8.rmSync(f);
936
+ if (fs5.existsSync(f)) {
937
+ fs5.rmSync(f);
1356
938
  deleted++;
1357
939
  }
1358
940
  } catch (error) {
1359
941
  const message = error instanceof Error ? error.message : String(error);
1360
- console.log(pc8.yellow(` \u26A0\uFE0F Could not delete ${path8.relative(projectRoot, f)}: ${message}`));
942
+ console.log(pc7.yellow(` \u26A0\uFE0F Could not delete ${path5.relative(projectRoot, f)}: ${message}`));
1361
943
  }
1362
944
  }
1363
- const componentDir = path8.resolve(baseDir, slug);
945
+ const componentDir = path5.resolve(baseDir, slug);
1364
946
  try {
1365
- if (fs8.existsSync(componentDir) && fs8.readdirSync(componentDir).length === 0) {
1366
- fs8.rmdirSync(componentDir);
947
+ if (fs5.existsSync(componentDir) && fs5.readdirSync(componentDir).length === 0) {
948
+ fs5.rmdirSync(componentDir);
1367
949
  }
1368
950
  } catch {
1369
951
  }
@@ -1372,23 +954,23 @@ Remove ${slug}
1372
954
  writeManifest(projectRoot, manifest);
1373
955
  } catch (error) {
1374
956
  const message = error instanceof Error ? error.message : String(error);
1375
- console.log(pc8.yellow(` \u26A0\uFE0F Removed files but failed to update vv-manifest.json: ${message}`));
957
+ console.log(pc7.yellow(` \u26A0\uFE0F Removed files but failed to update vv-manifest.json: ${message}`));
1376
958
  }
1377
959
  console.log("");
1378
- console.log(pc8.bold(pc8.green(`\u2714 Removed ${pc8.cyan(slug)} (${deleted} file(s) deleted).`)));
960
+ console.log(pc7.bold(pc7.green(`\u2714 Removed ${pc7.cyan(slug)} (${deleted} file(s) deleted).`)));
1379
961
  if ((entry.files ?? []).length === 0) {
1380
- console.log(pc8.dim(" No files were tracked for this component; manifest entry cleared."));
962
+ console.log(pc7.dim(" No files were tracked for this component; manifest entry cleared."));
1381
963
  }
1382
964
  console.log("");
1383
965
  }
1384
966
 
1385
967
  // src/commands/info.ts
1386
- import fs9 from "fs";
1387
- import path9 from "path";
1388
- import pc9 from "picocolors";
1389
- var CLI_VERSION = true ? "1.1.0" : "0.0.0-dev";
968
+ import fs6 from "fs";
969
+ import path6 from "path";
970
+ import pc8 from "picocolors";
971
+ var CLI_VERSION = true ? "1.2.0" : "0.0.0-dev";
1390
972
  async function infoCommand() {
1391
- console.log(pc9.bold(pc9.cyan("\nVector Vesper Diagnostics\n")));
973
+ console.log(pc8.bold(pc8.cyan("\nVector Vesper Diagnostics\n")));
1392
974
  const projectInfo = detectProject();
1393
975
  let config;
1394
976
  try {
@@ -1396,84 +978,84 @@ async function infoCommand() {
1396
978
  } catch {
1397
979
  config = null;
1398
980
  }
1399
- console.log(pc9.bold(pc9.white("Environment:")));
1400
- console.log(` \u2022 CLI Version: ${pc9.cyan(CLI_VERSION)}`);
1401
- console.log(` \u2022 Node Version: ${pc9.cyan(process.version)}`);
1402
- console.log(` \u2022 OS: ${pc9.cyan(`${process.platform} ${process.arch}`)}`);
1403
- console.log(` \u2022 Package Manager: ${pc9.cyan(projectInfo.packageManager)}`);
1404
- console.log(` \u2022 Framework: ${pc9.cyan(projectInfo.framework)}`);
1405
- console.log(` \u2022 TypeScript: ${pc9.cyan(projectInfo.isTypeScript ? "Yes" : "No")}`);
1406
- console.log(` \u2022 Has src/ folder: ${pc9.cyan(projectInfo.hasSrcDir ? "Yes" : "No")}`);
1407
- console.log(` \u2022 Tailwind CSS: ${pc9.cyan(projectInfo.hasTailwind ? "Yes" : "No")}`);
981
+ console.log(pc8.bold(pc8.white("Environment:")));
982
+ console.log(` \u2022 CLI Version: ${pc8.cyan(CLI_VERSION)}`);
983
+ console.log(` \u2022 Node Version: ${pc8.cyan(process.version)}`);
984
+ console.log(` \u2022 OS: ${pc8.cyan(`${process.platform} ${process.arch}`)}`);
985
+ console.log(` \u2022 Package Manager: ${pc8.cyan(projectInfo.packageManager)}`);
986
+ console.log(` \u2022 Framework: ${pc8.cyan(projectInfo.framework)}`);
987
+ console.log(` \u2022 TypeScript: ${pc8.cyan(projectInfo.isTypeScript ? "Yes" : "No")}`);
988
+ console.log(` \u2022 Has src/ folder: ${pc8.cyan(projectInfo.hasSrcDir ? "Yes" : "No")}`);
989
+ console.log(` \u2022 Tailwind CSS: ${pc8.cyan(projectInfo.hasTailwind ? "Yes" : "No")}`);
1408
990
  console.log("");
1409
- console.log(pc9.bold(pc9.white("Configuration (vv.config.json):")));
991
+ console.log(pc8.bold(pc8.white("Configuration (vv.config.json):")));
1410
992
  if (config) {
1411
- console.log(` \u2022 Framework Set: ${pc9.cyan(config.framework)}`);
1412
- console.log(` \u2022 TypeScript Set: ${pc9.cyan(config.tsx ? "Yes" : "No")}`);
1413
- console.log(` \u2022 Component Alias: ${pc9.cyan(config.aliases.vv)}`);
993
+ console.log(` \u2022 Framework Set: ${pc8.cyan(config.framework)}`);
994
+ console.log(` \u2022 TypeScript Set: ${pc8.cyan(config.tsx ? "Yes" : "No")}`);
995
+ console.log(` \u2022 Component Alias: ${pc8.cyan(config.aliases.vv)}`);
1414
996
  } else {
1415
- console.log(` ${pc9.yellow("\u26A0\uFE0F No vv.config.json found in this directory.")}`);
997
+ console.log(` ${pc8.yellow("\u26A0\uFE0F No vv.config.json found in this directory.")}`);
1416
998
  }
1417
999
  console.log("");
1418
- console.log(pc9.bold(pc9.white("Installed Components (vv-manifest.json):")));
1419
- const manifestPath = path9.join(process.cwd(), "vv-manifest.json");
1420
- if (fs9.existsSync(manifestPath)) {
1000
+ console.log(pc8.bold(pc8.white("Installed Components (vv-manifest.json):")));
1001
+ const manifestPath = path6.join(process.cwd(), "vv-manifest.json");
1002
+ if (fs6.existsSync(manifestPath)) {
1421
1003
  try {
1422
- const manifest = JSON.parse(fs9.readFileSync(manifestPath, "utf-8"));
1004
+ const manifest = JSON.parse(fs6.readFileSync(manifestPath, "utf-8"));
1423
1005
  const components = manifest.components || {};
1424
1006
  const slugs = Object.keys(components);
1425
1007
  if (slugs.length === 0) {
1426
- console.log(` ${pc9.dim("No components installed yet.")}`);
1008
+ console.log(` ${pc8.dim("No components installed yet.")}`);
1427
1009
  } else {
1428
- console.log(pc9.dim(" ------------------------------------------------------------"));
1429
- console.log(` ${pc9.bold(pc9.white("Component".padEnd(25)))} ${pc9.bold(pc9.white("Version".padEnd(10)))} ${pc9.bold(pc9.white("Installed At"))}`);
1430
- console.log(pc9.dim(" ------------------------------------------------------------"));
1010
+ console.log(pc8.dim(" ------------------------------------------------------------"));
1011
+ console.log(` ${pc8.bold(pc8.white("Component".padEnd(25)))} ${pc8.bold(pc8.white("Version".padEnd(10)))} ${pc8.bold(pc8.white("Installed At"))}`);
1012
+ console.log(pc8.dim(" ------------------------------------------------------------"));
1431
1013
  for (const slug of slugs) {
1432
1014
  const info = components[slug];
1433
1015
  const version2 = info?.version ?? "unknown";
1434
1016
  const installedAt = info?.installedAt ?? "unknown";
1435
- console.log(` ${pc9.cyan(slug.padEnd(25))} ${pc9.green(version2.padEnd(10))} ${pc9.gray(installedAt)}`);
1017
+ console.log(` ${pc8.cyan(slug.padEnd(25))} ${pc8.green(version2.padEnd(10))} ${pc8.gray(installedAt)}`);
1436
1018
  }
1437
- console.log(pc9.dim(" ------------------------------------------------------------"));
1019
+ console.log(pc8.dim(" ------------------------------------------------------------"));
1438
1020
  }
1439
1021
  } catch {
1440
- console.log(` ${pc9.red("\u274C Error reading vv-manifest.json: Invalid JSON format.")}`);
1022
+ console.log(` ${pc8.red("\u274C Error reading vv-manifest.json: Invalid JSON format.")}`);
1441
1023
  }
1442
1024
  } else {
1443
- console.log(` ${pc9.dim("No components installed yet (vv-manifest.json not found).")}`);
1025
+ console.log(` ${pc8.dim("No components installed yet (vv-manifest.json not found).")}`);
1444
1026
  }
1445
1027
  console.log("");
1446
1028
  }
1447
1029
 
1448
1030
  // src/commands/diff.ts
1449
- import fs10 from "fs";
1450
- import path10 from "path";
1451
- import pc10 from "picocolors";
1031
+ import fs7 from "fs";
1032
+ import path7 from "path";
1033
+ import pc9 from "picocolors";
1452
1034
  import ora4 from "ora";
1453
1035
  async function diffCommand(slug) {
1454
1036
  const projectRoot = process.cwd();
1455
- const manifestPath = path10.join(projectRoot, "vv-manifest.json");
1456
- if (!fs10.existsSync(manifestPath)) {
1457
- console.log(pc10.yellow(`
1037
+ const manifestPath = path7.join(projectRoot, "vv-manifest.json");
1038
+ if (!fs7.existsSync(manifestPath)) {
1039
+ console.log(pc9.yellow(`
1458
1040
  \u26A0\uFE0F No vv-manifest.json found in this directory.`));
1459
- console.log(`\u{1F449} Add components first using ${pc10.bold(pc10.cyan("npx vectorvesper add <slug>"))}
1041
+ console.log(`\u{1F449} Add components first using ${pc9.bold(pc9.cyan("npx vectorvesper add <slug>"))}
1460
1042
  `);
1461
1043
  return;
1462
1044
  }
1463
1045
  let manifest;
1464
1046
  try {
1465
- manifest = JSON.parse(fs10.readFileSync(manifestPath, "utf-8"));
1047
+ manifest = JSON.parse(fs7.readFileSync(manifestPath, "utf-8"));
1466
1048
  } catch {
1467
- console.error(pc10.red(`\u274C Error reading vv-manifest.json: Invalid JSON format.`));
1049
+ console.error(pc9.red(`\u274C Error reading vv-manifest.json: Invalid JSON format.`));
1468
1050
  process.exit(1);
1469
1051
  return;
1470
1052
  }
1471
1053
  const installedComponents = manifest.components || {};
1472
1054
  const installedSlugs = Object.keys(installedComponents);
1473
1055
  if (installedSlugs.length === 0) {
1474
- console.log(pc10.yellow(`
1056
+ console.log(pc9.yellow(`
1475
1057
  \u26A0\uFE0F No components are registered as installed in vv-manifest.json.`));
1476
- console.log(`\u{1F449} Add components using ${pc10.bold(pc10.cyan("npx vectorvesper add <slug>"))}
1058
+ console.log(`\u{1F449} Add components using ${pc9.bold(pc9.cyan("npx vectorvesper add <slug>"))}
1477
1059
  `);
1478
1060
  return;
1479
1061
  }
@@ -1482,21 +1064,21 @@ async function diffCommand(slug) {
1482
1064
  validateSlug(slug);
1483
1065
  } catch (error) {
1484
1066
  const message = error instanceof Error ? error.message : String(error);
1485
- console.error(pc10.red(`
1067
+ console.error(pc9.red(`
1486
1068
  \u274C ${message}
1487
1069
  `));
1488
1070
  process.exit(1);
1489
1071
  }
1490
1072
  if (!installedComponents[slug]) {
1491
- console.log(pc10.red(`
1073
+ console.log(pc9.red(`
1492
1074
  \u274C Component "${slug}" is not installed in this project.`));
1493
- console.log(`\u{1F449} Run ${pc10.cyan(`npx vectorvesper add ${slug}`)} to install it.
1075
+ console.log(`\u{1F449} Run ${pc9.cyan(`npx vectorvesper add ${slug}`)} to install it.
1494
1076
  `);
1495
1077
  return;
1496
1078
  }
1497
1079
  const localInfo = installedComponents[slug];
1498
1080
  const spinner = ora4({
1499
- text: `Checking updates for ${pc10.cyan(slug)}...`,
1081
+ text: `Checking updates for ${pc9.cyan(slug)}...`,
1500
1082
  color: "cyan"
1501
1083
  }).start();
1502
1084
  try {
@@ -1504,21 +1086,21 @@ async function diffCommand(slug) {
1504
1086
  spinner.stop();
1505
1087
  const localVersion = localInfo.version ?? "unknown";
1506
1088
  const remoteVersion = remoteComponent.version;
1507
- console.log(pc10.bold(pc10.cyan(`
1089
+ console.log(pc9.bold(pc9.cyan(`
1508
1090
  Component Diff: ${slug}`)));
1509
- console.log(` \u2022 Local version: ${pc10.yellow(localVersion)}`);
1510
- console.log(` \u2022 Latest version: ${pc10.green(remoteVersion)}`);
1091
+ console.log(` \u2022 Local version: ${pc9.yellow(localVersion)}`);
1092
+ console.log(` \u2022 Latest version: ${pc9.green(remoteVersion)}`);
1511
1093
  if (localVersion === remoteVersion) {
1512
- console.log(` \u2022 Status: ${pc10.green("\u2714 Up to date")}
1094
+ console.log(` \u2022 Status: ${pc9.green("\u2714 Up to date")}
1513
1095
  `);
1514
1096
  } else {
1515
- console.log(` \u2022 Status: ${pc10.bold(pc10.yellow("\u26A0\uFE0F Update available!"))}`);
1516
- console.log(` \u2022 Run ${pc10.bold(pc10.cyan(`npx vectorvesper add ${slug} --overwrite`))} to update.
1097
+ console.log(` \u2022 Status: ${pc9.bold(pc9.yellow("\u26A0\uFE0F Update available!"))}`);
1098
+ console.log(` \u2022 Run ${pc9.bold(pc9.cyan(`npx vectorvesper add ${slug} --overwrite`))} to update.
1517
1099
  `);
1518
1100
  }
1519
1101
  } catch (error) {
1520
1102
  const message = error instanceof Error ? error.message : String(error);
1521
- spinner.fail(pc10.red(`Failed to fetch remote component details: ${message}`));
1103
+ spinner.fail(pc9.red(`Failed to fetch remote component details: ${message}`));
1522
1104
  process.exit(1);
1523
1105
  }
1524
1106
  } else {
@@ -1529,14 +1111,14 @@ Component Diff: ${slug}`)));
1529
1111
  try {
1530
1112
  const registryIndex = await fetchRegistryIndex();
1531
1113
  spinner.stop();
1532
- console.log(pc10.bold(pc10.cyan("\nVector Vesper Component Version Comparison\n")));
1533
- console.log(pc10.dim(" ----------------------------------------------------------------------"));
1114
+ console.log(pc9.bold(pc9.cyan("\nVector Vesper Component Version Comparison\n")));
1115
+ console.log(pc9.dim(" ----------------------------------------------------------------------"));
1534
1116
  console.log(
1535
- ` ${pc10.bold(pc10.white("Component".padEnd(25)))} ${pc10.bold(
1536
- pc10.white("Local".padEnd(10))
1537
- )} ${pc10.bold(pc10.white("Latest".padEnd(10)))} ${pc10.bold(pc10.white("Status"))}`
1117
+ ` ${pc9.bold(pc9.white("Component".padEnd(25)))} ${pc9.bold(
1118
+ pc9.white("Local".padEnd(10))
1119
+ )} ${pc9.bold(pc9.white("Latest".padEnd(10)))} ${pc9.bold(pc9.white("Status"))}`
1538
1120
  );
1539
- console.log(pc10.dim(" ----------------------------------------------------------------------"));
1121
+ console.log(pc9.dim(" ----------------------------------------------------------------------"));
1540
1122
  let updatesAvailableCount = 0;
1541
1123
  for (const instSlug of installedSlugs) {
1542
1124
  const localInfo = installedComponents[instSlug];
@@ -1544,67 +1126,67 @@ Component Diff: ${slug}`)));
1544
1126
  const remoteInfo = registryIndex.components.find((c) => c.slug === instSlug);
1545
1127
  if (!remoteInfo) {
1546
1128
  console.log(
1547
- ` ${pc10.cyan(instSlug.padEnd(25))} ${pc10.yellow(
1129
+ ` ${pc9.cyan(instSlug.padEnd(25))} ${pc9.yellow(
1548
1130
  localVersion.padEnd(10)
1549
- )} ${pc10.red("unknown".padEnd(10))} ${pc10.red("Not found in registry")}`
1131
+ )} ${pc9.red("unknown".padEnd(10))} ${pc9.red("Not found in registry")}`
1550
1132
  );
1551
1133
  } else {
1552
1134
  const remoteVersion = remoteInfo.version;
1553
1135
  if (localVersion === remoteVersion) {
1554
1136
  console.log(
1555
- ` ${pc10.cyan(instSlug.padEnd(25))} ${pc10.gray(
1137
+ ` ${pc9.cyan(instSlug.padEnd(25))} ${pc9.gray(
1556
1138
  localVersion.padEnd(10)
1557
- )} ${pc10.gray(remoteVersion.padEnd(10))} ${pc10.green("\u2714 Up to date")}`
1139
+ )} ${pc9.gray(remoteVersion.padEnd(10))} ${pc9.green("\u2714 Up to date")}`
1558
1140
  );
1559
1141
  } else {
1560
1142
  updatesAvailableCount++;
1561
1143
  console.log(
1562
- ` ${pc10.cyan(instSlug.padEnd(25))} ${pc10.yellow(
1144
+ ` ${pc9.cyan(instSlug.padEnd(25))} ${pc9.yellow(
1563
1145
  localVersion.padEnd(10)
1564
- )} ${pc10.green(remoteVersion.padEnd(10))} ${pc10.bold(
1565
- pc10.yellow("\u26A0\uFE0F Update available")
1146
+ )} ${pc9.green(remoteVersion.padEnd(10))} ${pc9.bold(
1147
+ pc9.yellow("\u26A0\uFE0F Update available")
1566
1148
  )}`
1567
1149
  );
1568
1150
  }
1569
1151
  }
1570
1152
  }
1571
- console.log(pc10.dim(" ----------------------------------------------------------------------"));
1153
+ console.log(pc9.dim(" ----------------------------------------------------------------------"));
1572
1154
  if (updatesAvailableCount > 0) {
1573
1155
  console.log(
1574
1156
  `
1575
- \u{1F4E2} ${pc10.bold(pc10.yellow(String(updatesAvailableCount)))} component(s) have updates available.`
1157
+ \u{1F4E2} ${pc9.bold(pc9.yellow(String(updatesAvailableCount)))} component(s) have updates available.`
1576
1158
  );
1577
- console.log(`\u{1F449} Run ${pc10.bold(pc10.cyan("npx vectorvesper add <slug> --overwrite"))} to update a component.
1159
+ console.log(`\u{1F449} Run ${pc9.bold(pc9.cyan("npx vectorvesper add <slug> --overwrite"))} to update a component.
1578
1160
  `);
1579
1161
  } else {
1580
1162
  console.log(`
1581
- ${pc10.green("\u2714")} All components are up to date!
1163
+ ${pc9.green("\u2714")} All components are up to date!
1582
1164
  `);
1583
1165
  }
1584
1166
  } catch (error) {
1585
1167
  const message = error instanceof Error ? error.message : String(error);
1586
- spinner.fail(pc10.red(`Failed to check updates: ${message}`));
1168
+ spinner.fail(pc9.red(`Failed to check updates: ${message}`));
1587
1169
  process.exit(1);
1588
1170
  }
1589
1171
  }
1590
1172
  }
1591
1173
 
1592
1174
  // src/commands/auth.ts
1593
- import pc11 from "picocolors";
1175
+ import pc10 from "picocolors";
1594
1176
  async function loginCommand(key) {
1595
1177
  if (!key || key.trim().length === 0) {
1596
- logger.error("Please provide a license key.");
1178
+ logger.error("Please provide your access token.");
1597
1179
  console.log(`
1598
- Usage: ${pc11.cyan("npx vectorvesper login <your-license-key>")}`);
1599
- console.log(` \u{1F511} Get a key at ${pc11.cyan("https://vectorvesper.dev/pricing")}
1180
+ Usage: ${pc10.cyan("npx vectorvesper login <token>")}`);
1181
+ console.log(` \u{1F511} Generate a token at ${pc10.cyan("https://vectorvesper.dev/account")}
1600
1182
  `);
1601
1183
  process.exit(1);
1602
1184
  }
1603
1185
  const trimmedKey = key.trim();
1604
1186
  if (trimmedKey.length < 8) {
1605
- logger.error("That doesn't look like a valid license key.");
1187
+ logger.error("That doesn't look like a valid token.");
1606
1188
  console.log(`
1607
- \u{1F511} License keys are available at ${pc11.cyan("https://vectorvesper.dev/pricing")}
1189
+ \u{1F511} Generate a token at ${pc10.cyan("https://vectorvesper.dev/account")}
1608
1190
  `);
1609
1191
  process.exit(1);
1610
1192
  }
@@ -1621,18 +1203,18 @@ async function loginCommand(key) {
1621
1203
  process.exit(1);
1622
1204
  }
1623
1205
  console.log("");
1624
- console.log(` ${pc11.green(pc11.bold("\u2714"))} License key saved successfully!`);
1625
- console.log(` ${pc11.dim("Stored at:")} ${pc11.cyan(getGlobalConfigPath())}`);
1206
+ console.log(` ${pc10.green(pc10.bold("\u2714"))} Token saved \u2014 you're logged in.`);
1207
+ console.log(` ${pc10.dim("Stored at:")} ${pc10.cyan(getGlobalConfigPath())}`);
1626
1208
  console.log("");
1627
- console.log(` ${pc11.dim("Pro components are now available when you run")} ${pc11.cyan("npx vectorvesper add <slug>")}`);
1628
- console.log(` ${pc11.dim("To verify your account:")} ${pc11.cyan("npx vectorvesper whoami")}`);
1209
+ console.log(` ${pc10.dim("Pro components are now available when you run")} ${pc10.cyan("npx vectorvesper add <slug>")}`);
1210
+ console.log(` ${pc10.dim("To verify your account:")} ${pc10.cyan("npx vectorvesper whoami")}`);
1629
1211
  console.log("");
1630
1212
  }
1631
1213
  async function logoutCommand() {
1632
1214
  const config = loadGlobalConfig();
1633
1215
  if (!config.auth?.token) {
1634
1216
  console.log(`
1635
- ${pc11.dim("You're not logged in. Nothing to do.")}
1217
+ ${pc10.dim("You're not logged in. Nothing to do.")}
1636
1218
  `);
1637
1219
  return;
1638
1220
  }
@@ -1645,46 +1227,46 @@ async function logoutCommand() {
1645
1227
  process.exit(1);
1646
1228
  }
1647
1229
  console.log("");
1648
- console.log(` ${pc11.green(pc11.bold("\u2714"))} Logged out successfully.`);
1649
- console.log(` ${pc11.dim("Your license key has been removed from")} ${pc11.cyan(getGlobalConfigPath())}`);
1650
- console.log(` ${pc11.dim("Free components remain available.")}`);
1230
+ console.log(` ${pc10.green(pc10.bold("\u2714"))} Logged out successfully.`);
1231
+ console.log(` ${pc10.dim("Your token has been removed from")} ${pc10.cyan(getGlobalConfigPath())}`);
1232
+ console.log(` ${pc10.dim("Free components remain available.")}`);
1651
1233
  console.log("");
1652
1234
  }
1653
1235
  async function whoamiCommand() {
1654
1236
  const config = loadGlobalConfig();
1655
1237
  console.log("");
1656
- console.log(pc11.bold(pc11.cyan(" Vector Vesper Account Status\n")));
1238
+ console.log(pc10.bold(pc10.cyan(" Vector Vesper Account Status\n")));
1657
1239
  if (config.auth?.token) {
1658
1240
  const maskedKey = config.auth.token.slice(0, 6) + "\u2026" + config.auth.token.slice(-4);
1659
1241
  const tier = config.auth.tier || "pro";
1660
- console.log(` ${pc11.bold("Status:")} ${pc11.green("Authenticated")}`);
1661
- console.log(` ${pc11.bold("Key:")} ${pc11.cyan(maskedKey)}`);
1662
- console.log(` ${pc11.bold("Tier:")} ${pc11.magenta(tier)}`);
1242
+ console.log(` ${pc10.bold("Status:")} ${pc10.green("Authenticated")}`);
1243
+ console.log(` ${pc10.bold("Token:")} ${pc10.cyan(maskedKey)}`);
1244
+ console.log(` ${pc10.bold("Tier:")} ${pc10.magenta(tier)}`);
1663
1245
  if (config.auth.email) {
1664
- console.log(` ${pc11.bold("Email:")} ${pc11.cyan(config.auth.email)}`);
1246
+ console.log(` ${pc10.bold("Email:")} ${pc10.cyan(config.auth.email)}`);
1665
1247
  }
1666
1248
  if (config.auth.expiresAt) {
1667
1249
  const expiry = new Date(config.auth.expiresAt);
1668
1250
  const now = /* @__PURE__ */ new Date();
1669
1251
  const isExpired = expiry < now;
1670
- console.log(` ${pc11.bold("Expires:")} ${isExpired ? pc11.red("EXPIRED") : pc11.green(expiry.toLocaleDateString())}`);
1252
+ console.log(` ${pc10.bold("Expires:")} ${isExpired ? pc10.red("EXPIRED") : pc10.green(expiry.toLocaleDateString())}`);
1671
1253
  }
1672
1254
  console.log("");
1673
- console.log(` ${pc11.dim("Config:")} ${pc11.cyan(getGlobalConfigPath())}`);
1674
- console.log(` ${pc11.dim("Manage your account at")} ${pc11.cyan("https://vectorvesper.dev/account")}`);
1255
+ console.log(` ${pc10.dim("Config:")} ${pc10.cyan(getGlobalConfigPath())}`);
1256
+ console.log(` ${pc10.dim("Manage your account at")} ${pc10.cyan("https://vectorvesper.dev/account")}`);
1675
1257
  } else {
1676
- console.log(` ${pc11.bold("Status:")} ${pc11.yellow("Anonymous (free tier)")}`);
1677
- console.log(` ${pc11.bold("Access:")} ${pc11.dim("Free components only")}`);
1258
+ console.log(` ${pc10.bold("Status:")} ${pc10.yellow("Anonymous (free tier)")}`);
1259
+ console.log(` ${pc10.bold("Access:")} ${pc10.dim("Free components only")}`);
1678
1260
  console.log("");
1679
- console.log(` ${pc11.dim("To unlock pro components:")}`);
1680
- console.log(` ${pc11.cyan("npx vectorvesper login <your-license-key>")}`);
1681
- console.log(` \u{1F511} ${pc11.dim("Get a key at")} ${pc11.cyan("https://vectorvesper.dev/pricing")}`);
1261
+ console.log(` ${pc10.dim("To unlock pro components:")}`);
1262
+ console.log(` ${pc10.cyan("npx vectorvesper login <token>")}`);
1263
+ console.log(` \u{1F511} ${pc10.dim("Generate a token at")} ${pc10.cyan("https://vectorvesper.dev/account")}`);
1682
1264
  }
1683
1265
  console.log("");
1684
1266
  }
1685
1267
 
1686
1268
  // src/index.ts
1687
- var version = true ? "1.1.0" : "0.0.0-dev";
1269
+ var version = true ? "1.2.0" : "0.0.0-dev";
1688
1270
  var program = new Command();
1689
1271
  program.name("vv").description("Vector Vesper CLI \u2014 add visual components to your React project").version(version).option("--verbose", "Show detailed debug output").hook("preAction", (thisCommand) => {
1690
1272
  const opts = thisCommand.opts();
@@ -1722,6 +1304,10 @@ program.command("logout", { hidden: true }).description("Clear stored license cr
1722
1304
  program.command("whoami", { hidden: true }).description("Show current authentication status").action(async () => {
1723
1305
  await whoamiCommand();
1724
1306
  });
1307
+ program.command("mcp").description("Run as an MCP server (stdio) for AI coding agents").action(async () => {
1308
+ const { mcpCommand } = await import("./mcp-DOUIUZGA.js");
1309
+ await mcpCommand();
1310
+ });
1725
1311
  process.on("unhandledRejection", (error) => {
1726
1312
  console.error("An unexpected error occurred:", error instanceof Error ? error.message : error);
1727
1313
  process.exit(1);