vectorvesper 1.2.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
 
@@ -943,11 +514,11 @@ async function handleDependencies(components, projectRoot, projectInfo, options)
943
514
  const missing = getMissingDependencies(components, projectRoot);
944
515
  if (missing.length === 0) return;
945
516
  const installCmd = getInstallCommand(projectInfo.packageManager, missing);
946
- const depsLabel = missing.map((d) => pc6.cyan(d)).join(", ");
517
+ const depsLabel = missing.map((d) => pc5.cyan(d)).join(", ");
947
518
  if (options.install === false) {
948
- console.log(pc6.yellow(`
519
+ console.log(pc5.yellow(`
949
520
  \u26A0\uFE0F Missing dependencies: ${depsLabel}`));
950
- console.log(` Run: ${pc6.bold(pc6.cyan(installCmd))}`);
521
+ console.log(` Run: ${pc5.bold(pc5.cyan(installCmd))}`);
951
522
  return;
952
523
  }
953
524
  let shouldInstall = options.yes === true;
@@ -958,44 +529,44 @@ async function handleDependencies(components, projectRoot, projectInfo, options)
958
529
  initialValue: true
959
530
  });
960
531
  if (isCancel2(answer)) {
961
- console.log(pc6.dim(` Skipped. Run: ${pc6.cyan(installCmd)}`));
532
+ console.log(pc5.dim(` Skipped. Run: ${pc5.cyan(installCmd)}`));
962
533
  return;
963
534
  }
964
535
  shouldInstall = answer;
965
536
  }
966
537
  if (!shouldInstall) {
967
- console.log(pc6.dim(` Skipped. Run: ${pc6.cyan(installCmd)} when ready.`));
538
+ console.log(pc5.dim(` Skipped. Run: ${pc5.cyan(installCmd)} when ready.`));
968
539
  return;
969
540
  }
970
- console.log(pc6.dim(`
541
+ console.log(pc5.dim(`
971
542
  Installing dependencies with ${projectInfo.packageManager}...`));
972
543
  try {
973
544
  const ok = installDependencies(missing, projectInfo.packageManager, projectRoot);
974
545
  if (ok) {
975
- console.log(pc6.green(`\u2714 Dependencies installed.`));
546
+ console.log(pc5.green(`\u2714 Dependencies installed.`));
976
547
  } else {
977
- 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)}`));
978
549
  }
979
550
  } catch (error) {
980
551
  const message = error instanceof Error ? error.message : String(error);
981
- console.log(pc6.yellow(`\u26A0\uFE0F ${message}`));
982
- 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))}`);
983
554
  }
984
555
  }
985
556
  async function handlePrune(orphans, slug, options) {
986
557
  if (orphans.length === 0) return;
987
- 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");
988
559
  let shouldPrune = options.prune === true;
989
560
  if (!shouldPrune) {
990
561
  console.log(
991
- pc6.yellow(
562
+ pc5.yellow(
992
563
  `
993
- \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:`
994
565
  )
995
566
  );
996
567
  console.log(list);
997
568
  if (options.yes) {
998
- 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.`));
999
570
  return;
1000
571
  }
1001
572
  const answer = await confirm2({
@@ -1003,16 +574,16 @@ async function handlePrune(orphans, slug, options) {
1003
574
  initialValue: true
1004
575
  });
1005
576
  if (isCancel2(answer) || !answer) {
1006
- 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.`));
1007
578
  return;
1008
579
  }
1009
580
  shouldPrune = true;
1010
581
  }
1011
582
  removeFiles(orphans);
1012
- console.log(pc6.green(`
583
+ console.log(pc5.green(`
1013
584
  \u{1F9F9} Removed ${orphans.length} orphaned file(s):`));
1014
585
  for (const o of orphans) {
1015
- console.log(` ${pc6.red("\u2212")} ${pc6.cyan(o.relativePath)}`);
586
+ console.log(` ${pc5.red("\u2212")} ${pc5.cyan(o.relativePath)}`);
1016
587
  }
1017
588
  }
1018
589
  async function addCommand(slug, options = {}) {
@@ -1020,7 +591,7 @@ async function addCommand(slug, options = {}) {
1020
591
  validateSlug(slug);
1021
592
  } catch (error) {
1022
593
  const message = error instanceof Error ? error.message : String(error);
1023
- console.error(`${pc6.red(pc6.bold("Error:"))} ${message}`);
594
+ console.error(`${pc5.red(pc5.bold("Error:"))} ${message}`);
1024
595
  process.exit(1);
1025
596
  }
1026
597
  let config;
@@ -1028,13 +599,13 @@ async function addCommand(slug, options = {}) {
1028
599
  config = loadConfig();
1029
600
  } catch (error) {
1030
601
  const message = error instanceof Error ? error.message : String(error);
1031
- console.error(`${pc6.red(pc6.bold("Error:"))} ${message}`);
602
+ console.error(`${pc5.red(pc5.bold("Error:"))} ${message}`);
1032
603
  process.exit(1);
1033
604
  }
1034
605
  if (!config) {
1035
606
  console.error(
1036
- `${pc6.red(pc6.bold("Error:"))} No ${pc6.cyan("vv.config.json")} found in this directory.
1037
- \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.`
1038
609
  );
1039
610
  process.exit(1);
1040
611
  return;
@@ -1042,13 +613,13 @@ async function addCommand(slug, options = {}) {
1042
613
  const projectInfo = detectProject();
1043
614
  const componentInstallDir = resolveAlias(config.aliases.vv, projectInfo.hasSrcDir);
1044
615
  const projectRoot = process.cwd();
1045
- 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();
1046
617
  let resolvedComponents;
1047
618
  try {
1048
619
  resolvedComponents = await resolveComponentTree(slug);
1049
620
  } catch (error) {
1050
621
  const message = error instanceof Error ? error.message : String(error);
1051
- spinner.fail(pc6.red(`Failed to resolve component "${slug}": ${message}`));
622
+ spinner.fail(pc5.red(`Failed to resolve component "${slug}": ${message}`));
1052
623
  process.exit(1);
1053
624
  return;
1054
625
  }
@@ -1070,7 +641,7 @@ async function addCommand(slug, options = {}) {
1070
641
  planned = planFiles(resolvedComponents, componentInstallDir, projectRoot);
1071
642
  } catch (error) {
1072
643
  const message = error instanceof Error ? error.message : String(error);
1073
- spinner.fail(pc6.red(message));
644
+ spinner.fail(pc5.red(message));
1074
645
  process.exit(1);
1075
646
  return;
1076
647
  }
@@ -1079,11 +650,11 @@ async function addCommand(slug, options = {}) {
1079
650
  if (file.exists && !options.dryRun && !options.overwrite && !options.yes) {
1080
651
  spinner.stop();
1081
652
  const answer = await confirm2({
1082
- message: pc6.yellow(`File already exists: "${file.relativePath}". Overwrite?`),
653
+ message: pc5.yellow(`File already exists: "${file.relativePath}". Overwrite?`),
1083
654
  initialValue: false
1084
655
  });
1085
656
  if (isCancel2(answer) || !answer) {
1086
- console.log(pc6.dim(` Skipping existing file: ${file.relativePath}`));
657
+ console.log(pc5.dim(` Skipping existing file: ${file.relativePath}`));
1087
658
  spinner.start("Continuing installation...");
1088
659
  continue;
1089
660
  }
@@ -1096,7 +667,7 @@ async function addCommand(slug, options = {}) {
1096
667
  });
1097
668
  }
1098
669
  const targetComponent = resolvedComponents[resolvedComponents.length - 1];
1099
- const installPath = toForwardSlash(path7.join(componentInstallDir, targetComponent.slug));
670
+ const installPath = toForwardSlash(path4.join(componentInstallDir, targetComponent.slug));
1100
671
  let orphans = [];
1101
672
  try {
1102
673
  const previousManifest = readManifest(projectRoot);
@@ -1105,32 +676,32 @@ async function addCommand(slug, options = {}) {
1105
676
  orphans = [];
1106
677
  }
1107
678
  if (options.dryRun) {
1108
- spinner.succeed(pc6.yellow("Dry-run: simulation completed. No files were written."));
1109
- 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:")));
1110
681
  for (const file of filesToWrite) {
1111
- const status = fs7.existsSync(file.absolutePath) ? pc6.yellow("(exists, would overwrite)") : pc6.green("(new)");
1112
- 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}`);
1113
684
  }
1114
685
  if (orphans.length > 0) {
1115
- 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:")));
1116
687
  for (const o of orphans) {
1117
- const note = options.prune ? pc6.red("(would remove)") : pc6.dim("(use --prune to remove)");
1118
- 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}`);
1119
690
  }
1120
691
  }
1121
692
  const missing = getMissingDependencies(resolvedComponents, projectRoot);
1122
693
  if (missing.length > 0) {
1123
- console.log(pc6.yellow(`
1124
- \u26A0\uFE0F Would need dependencies: ${missing.map((d) => pc6.cyan(d)).join(", ")}`));
1125
- 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))}`);
1126
697
  }
1127
698
  console.log("");
1128
- 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}`)));
1129
700
  console.log("");
1130
701
  return;
1131
702
  }
1132
703
  if (filesToWrite.length === 0) {
1133
- spinner.succeed(pc6.green("All files skipped (already up to date)."));
704
+ spinner.succeed(pc5.green("All files skipped (already up to date)."));
1134
705
  await handlePrune(orphans, targetComponent.slug, options);
1135
706
  return;
1136
707
  }
@@ -1139,7 +710,7 @@ async function addCommand(slug, options = {}) {
1139
710
  writeFiles(filesToWrite);
1140
711
  } catch (error) {
1141
712
  const message = error instanceof Error ? error.message : String(error);
1142
- spinner.fail(pc6.red(`Failed to write files: ${message}`));
713
+ spinner.fail(pc5.red(`Failed to write files: ${message}`));
1143
714
  process.exit(1);
1144
715
  return;
1145
716
  }
@@ -1150,10 +721,10 @@ async function addCommand(slug, options = {}) {
1150
721
  logger.warn(`Failed to update vv-manifest.json: ${message}`);
1151
722
  logger.warn("Component was installed but may not appear in 'npx vectorvesper info' or 'npx vectorvesper diff'.");
1152
723
  }
1153
- spinner.succeed(pc6.green("Files written successfully!"));
1154
- console.log(pc6.dim("\nCreated files:"));
724
+ spinner.succeed(pc5.green("Files written successfully!"));
725
+ console.log(pc5.dim("\nCreated files:"));
1155
726
  for (const file of filesToWrite) {
1156
- console.log(` ${pc6.green("\u2714")} ${pc6.cyan(file.relativePath)}`);
727
+ console.log(` ${pc5.green("\u2714")} ${pc5.cyan(file.relativePath)}`);
1157
728
  }
1158
729
  await handlePrune(orphans, targetComponent.slug, options);
1159
730
  await handleDependencies(resolvedComponents, projectRoot, projectInfo, options);
@@ -1163,20 +734,20 @@ async function addCommand(slug, options = {}) {
1163
734
  hasTailwind: projectInfo.hasTailwind
1164
735
  });
1165
736
  if (transpileWarnings.length > 0) {
1166
- console.log(pc6.yellow(`
737
+ console.log(pc5.yellow(`
1167
738
  \u26A0\uFE0F Some files were kept as TypeScript:`));
1168
- for (const w of transpileWarnings) console.log(` ${pc6.dim(w)}`);
739
+ for (const w of transpileWarnings) console.log(` ${pc5.dim(w)}`);
1169
740
  }
1170
741
  console.log("");
1171
- 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}`)));
1172
743
  console.log("");
1173
- console.log(pc6.gray("\u{1F449} Loving Vector Vesper? Star the repo: https://github.com/vectorvesper/vv-components"));
1174
- 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"));
1175
746
  console.log("");
1176
747
  }
1177
748
 
1178
749
  // src/commands/update.ts
1179
- import pc7 from "picocolors";
750
+ import pc6 from "picocolors";
1180
751
  import ora3 from "ora";
1181
752
  async function updateCommand(slug, options = {}) {
1182
753
  const projectRoot = process.cwd();
@@ -1185,14 +756,14 @@ async function updateCommand(slug, options = {}) {
1185
756
  config = loadConfig();
1186
757
  } catch (error) {
1187
758
  const message = error instanceof Error ? error.message : String(error);
1188
- console.error(`${pc7.red(pc7.bold("Error:"))} ${message}`);
759
+ console.error(`${pc6.red(pc6.bold("Error:"))} ${message}`);
1189
760
  process.exit(1);
1190
761
  return;
1191
762
  }
1192
763
  if (!config) {
1193
764
  console.error(
1194
- `${pc7.red(pc7.bold("Error:"))} No ${pc7.cyan("vv.config.json")} found.
1195
- \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.`
1196
767
  );
1197
768
  process.exit(1);
1198
769
  return;
@@ -1202,9 +773,9 @@ async function updateCommand(slug, options = {}) {
1202
773
  const manifest = readManifest(projectRoot);
1203
774
  const installedSlugs = Object.keys(manifest.components);
1204
775
  if (installedSlugs.length === 0) {
1205
- console.log(pc7.yellow(`
776
+ console.log(pc6.yellow(`
1206
777
  \u26A0\uFE0F No components are installed in this project.`));
1207
- 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>"))}
1208
779
  `);
1209
780
  return;
1210
781
  }
@@ -1214,16 +785,16 @@ async function updateCommand(slug, options = {}) {
1214
785
  validateSlug(slug);
1215
786
  } catch (error) {
1216
787
  const message = error instanceof Error ? error.message : String(error);
1217
- console.error(pc7.red(`
788
+ console.error(pc6.red(`
1218
789
  \u274C ${message}
1219
790
  `));
1220
791
  process.exit(1);
1221
792
  return;
1222
793
  }
1223
794
  if (!manifest.components[slug]) {
1224
- console.log(pc7.red(`
795
+ console.log(pc6.red(`
1225
796
  \u274C Component "${slug}" is not installed in this project.`));
1226
- 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.
1227
798
  `);
1228
799
  return;
1229
800
  }
@@ -1238,7 +809,7 @@ async function updateCommand(slug, options = {}) {
1238
809
  const updatedComponents = [];
1239
810
  const transpileWarnings = [];
1240
811
  for (const target of targets) {
1241
- spinner.text = `Updating ${pc7.cyan(target)}...`;
812
+ spinner.text = `Updating ${pc6.cyan(target)}...`;
1242
813
  try {
1243
814
  let components = await resolveComponentTree(target);
1244
815
  const remote = components[components.length - 1];
@@ -1268,26 +839,26 @@ async function updateCommand(slug, options = {}) {
1268
839
  }
1269
840
  }
1270
841
  spinner.stop();
1271
- console.log(pc7.bold(pc7.cyan("\nVector Vesper Update\n")));
842
+ console.log(pc6.bold(pc6.cyan("\nVector Vesper Update\n")));
1272
843
  if (updated.length > 0) {
1273
- console.log(pc7.bold(pc7.green(` Updated (${updated.length}):`)));
1274
- for (const u of updated) console.log(` ${pc7.green("\u2714")} ${u}`);
1275
- 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."));
1276
847
  }
1277
848
  if (upToDate.length > 0) {
1278
- console.log(pc7.bold(pc7.gray(`
849
+ console.log(pc6.bold(pc6.gray(`
1279
850
  Already up to date (${upToDate.length}):`)));
1280
- console.log(` ${pc7.dim(upToDate.join(", "))}`);
851
+ console.log(` ${pc6.dim(upToDate.join(", "))}`);
1281
852
  }
1282
853
  if (failed.length > 0) {
1283
- console.log(pc7.bold(pc7.red(`
854
+ console.log(pc6.bold(pc6.red(`
1284
855
  Failed (${failed.length}):`)));
1285
- 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)}`);
1286
857
  }
1287
858
  if (transpileWarnings.length > 0) {
1288
- console.log(pc7.yellow(`
859
+ console.log(pc6.yellow(`
1289
860
  \u26A0\uFE0F Some files were kept as TypeScript:`));
1290
- for (const w of transpileWarnings) console.log(` ${pc7.dim(w)}`);
861
+ for (const w of transpileWarnings) console.log(` ${pc6.dim(w)}`);
1291
862
  }
1292
863
  console.log("");
1293
864
  if (updatedComponents.length > 0) {
@@ -1297,16 +868,16 @@ async function updateCommand(slug, options = {}) {
1297
868
  }
1298
869
 
1299
870
  // src/commands/remove.ts
1300
- import fs8 from "fs";
1301
- import path8 from "path";
1302
- import pc8 from "picocolors";
871
+ import fs5 from "fs";
872
+ import path5 from "path";
873
+ import pc7 from "picocolors";
1303
874
  import { confirm as confirm3, isCancel as isCancel3 } from "@clack/prompts";
1304
875
  async function removeCommand(slug, options = {}) {
1305
876
  try {
1306
877
  validateSlug(slug);
1307
878
  } catch (error) {
1308
879
  const message = error instanceof Error ? error.message : String(error);
1309
- console.error(`${pc8.red(pc8.bold("Error:"))} ${message}`);
880
+ console.error(`${pc7.red(pc7.bold("Error:"))} ${message}`);
1310
881
  process.exit(1);
1311
882
  return;
1312
883
  }
@@ -1316,14 +887,14 @@ async function removeCommand(slug, options = {}) {
1316
887
  config = loadConfig();
1317
888
  } catch (error) {
1318
889
  const message = error instanceof Error ? error.message : String(error);
1319
- console.error(`${pc8.red(pc8.bold("Error:"))} ${message}`);
890
+ console.error(`${pc7.red(pc7.bold("Error:"))} ${message}`);
1320
891
  process.exit(1);
1321
892
  return;
1322
893
  }
1323
894
  if (!config) {
1324
895
  console.error(
1325
- `${pc8.red(pc8.bold("Error:"))} No ${pc8.cyan("vv.config.json")} found.
1326
- \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.`
1327
898
  );
1328
899
  process.exit(1);
1329
900
  return;
@@ -1331,50 +902,50 @@ async function removeCommand(slug, options = {}) {
1331
902
  const manifest = readManifest(projectRoot);
1332
903
  const entry = manifest.components[slug];
1333
904
  if (!entry) {
1334
- console.log(pc8.yellow(`
905
+ console.log(pc7.yellow(`
1335
906
  \u26A0\uFE0F Component "${slug}" is not installed (not in vv-manifest.json).`));
1336
- 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"))}
1337
908
  `);
1338
909
  return;
1339
910
  }
1340
911
  const projectInfo = detectProject();
1341
912
  const installDir = resolveAlias(config.aliases.vv, projectInfo.hasSrcDir);
1342
- const baseDir = path8.join(projectRoot, installDir);
913
+ const baseDir = path5.join(projectRoot, installDir);
1343
914
  const targets = entry.files ?? [];
1344
- const absoluteFiles = targets.map((t) => path8.resolve(baseDir, t));
1345
- console.log(pc8.bold(pc8.cyan(`
915
+ const absoluteFiles = targets.map((t) => path5.resolve(baseDir, t));
916
+ console.log(pc7.bold(pc7.cyan(`
1346
917
  Remove ${slug}
1347
918
  `)));
1348
- console.log(pc8.dim(" The following files will be deleted:"));
919
+ console.log(pc7.dim(" The following files will be deleted:"));
1349
920
  for (const f of absoluteFiles) {
1350
- 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))}`);
1351
922
  }
1352
923
  if (!options.yes) {
1353
924
  const answer = await confirm3({
1354
- message: pc8.yellow(`Delete ${absoluteFiles.length} file(s) for "${slug}"?`),
925
+ message: pc7.yellow(`Delete ${absoluteFiles.length} file(s) for "${slug}"?`),
1355
926
  initialValue: false
1356
927
  });
1357
928
  if (isCancel3(answer) || !answer) {
1358
- console.log(pc8.dim("\n Cancelled. Nothing was removed.\n"));
929
+ console.log(pc7.dim("\n Cancelled. Nothing was removed.\n"));
1359
930
  return;
1360
931
  }
1361
932
  }
1362
933
  let deleted = 0;
1363
934
  for (const f of absoluteFiles) {
1364
935
  try {
1365
- if (fs8.existsSync(f)) {
1366
- fs8.rmSync(f);
936
+ if (fs5.existsSync(f)) {
937
+ fs5.rmSync(f);
1367
938
  deleted++;
1368
939
  }
1369
940
  } catch (error) {
1370
941
  const message = error instanceof Error ? error.message : String(error);
1371
- 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}`));
1372
943
  }
1373
944
  }
1374
- const componentDir = path8.resolve(baseDir, slug);
945
+ const componentDir = path5.resolve(baseDir, slug);
1375
946
  try {
1376
- if (fs8.existsSync(componentDir) && fs8.readdirSync(componentDir).length === 0) {
1377
- fs8.rmdirSync(componentDir);
947
+ if (fs5.existsSync(componentDir) && fs5.readdirSync(componentDir).length === 0) {
948
+ fs5.rmdirSync(componentDir);
1378
949
  }
1379
950
  } catch {
1380
951
  }
@@ -1383,23 +954,23 @@ Remove ${slug}
1383
954
  writeManifest(projectRoot, manifest);
1384
955
  } catch (error) {
1385
956
  const message = error instanceof Error ? error.message : String(error);
1386
- 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}`));
1387
958
  }
1388
959
  console.log("");
1389
- 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).`)));
1390
961
  if ((entry.files ?? []).length === 0) {
1391
- 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."));
1392
963
  }
1393
964
  console.log("");
1394
965
  }
1395
966
 
1396
967
  // src/commands/info.ts
1397
- import fs9 from "fs";
1398
- import path9 from "path";
1399
- import pc9 from "picocolors";
968
+ import fs6 from "fs";
969
+ import path6 from "path";
970
+ import pc8 from "picocolors";
1400
971
  var CLI_VERSION = true ? "1.2.0" : "0.0.0-dev";
1401
972
  async function infoCommand() {
1402
- console.log(pc9.bold(pc9.cyan("\nVector Vesper Diagnostics\n")));
973
+ console.log(pc8.bold(pc8.cyan("\nVector Vesper Diagnostics\n")));
1403
974
  const projectInfo = detectProject();
1404
975
  let config;
1405
976
  try {
@@ -1407,84 +978,84 @@ async function infoCommand() {
1407
978
  } catch {
1408
979
  config = null;
1409
980
  }
1410
- console.log(pc9.bold(pc9.white("Environment:")));
1411
- console.log(` \u2022 CLI Version: ${pc9.cyan(CLI_VERSION)}`);
1412
- console.log(` \u2022 Node Version: ${pc9.cyan(process.version)}`);
1413
- console.log(` \u2022 OS: ${pc9.cyan(`${process.platform} ${process.arch}`)}`);
1414
- console.log(` \u2022 Package Manager: ${pc9.cyan(projectInfo.packageManager)}`);
1415
- console.log(` \u2022 Framework: ${pc9.cyan(projectInfo.framework)}`);
1416
- console.log(` \u2022 TypeScript: ${pc9.cyan(projectInfo.isTypeScript ? "Yes" : "No")}`);
1417
- console.log(` \u2022 Has src/ folder: ${pc9.cyan(projectInfo.hasSrcDir ? "Yes" : "No")}`);
1418
- 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")}`);
1419
990
  console.log("");
1420
- console.log(pc9.bold(pc9.white("Configuration (vv.config.json):")));
991
+ console.log(pc8.bold(pc8.white("Configuration (vv.config.json):")));
1421
992
  if (config) {
1422
- console.log(` \u2022 Framework Set: ${pc9.cyan(config.framework)}`);
1423
- console.log(` \u2022 TypeScript Set: ${pc9.cyan(config.tsx ? "Yes" : "No")}`);
1424
- 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)}`);
1425
996
  } else {
1426
- 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.")}`);
1427
998
  }
1428
999
  console.log("");
1429
- console.log(pc9.bold(pc9.white("Installed Components (vv-manifest.json):")));
1430
- const manifestPath = path9.join(process.cwd(), "vv-manifest.json");
1431
- 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)) {
1432
1003
  try {
1433
- const manifest = JSON.parse(fs9.readFileSync(manifestPath, "utf-8"));
1004
+ const manifest = JSON.parse(fs6.readFileSync(manifestPath, "utf-8"));
1434
1005
  const components = manifest.components || {};
1435
1006
  const slugs = Object.keys(components);
1436
1007
  if (slugs.length === 0) {
1437
- console.log(` ${pc9.dim("No components installed yet.")}`);
1008
+ console.log(` ${pc8.dim("No components installed yet.")}`);
1438
1009
  } else {
1439
- console.log(pc9.dim(" ------------------------------------------------------------"));
1440
- console.log(` ${pc9.bold(pc9.white("Component".padEnd(25)))} ${pc9.bold(pc9.white("Version".padEnd(10)))} ${pc9.bold(pc9.white("Installed At"))}`);
1441
- 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(" ------------------------------------------------------------"));
1442
1013
  for (const slug of slugs) {
1443
1014
  const info = components[slug];
1444
1015
  const version2 = info?.version ?? "unknown";
1445
1016
  const installedAt = info?.installedAt ?? "unknown";
1446
- 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)}`);
1447
1018
  }
1448
- console.log(pc9.dim(" ------------------------------------------------------------"));
1019
+ console.log(pc8.dim(" ------------------------------------------------------------"));
1449
1020
  }
1450
1021
  } catch {
1451
- 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.")}`);
1452
1023
  }
1453
1024
  } else {
1454
- 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).")}`);
1455
1026
  }
1456
1027
  console.log("");
1457
1028
  }
1458
1029
 
1459
1030
  // src/commands/diff.ts
1460
- import fs10 from "fs";
1461
- import path10 from "path";
1462
- import pc10 from "picocolors";
1031
+ import fs7 from "fs";
1032
+ import path7 from "path";
1033
+ import pc9 from "picocolors";
1463
1034
  import ora4 from "ora";
1464
1035
  async function diffCommand(slug) {
1465
1036
  const projectRoot = process.cwd();
1466
- const manifestPath = path10.join(projectRoot, "vv-manifest.json");
1467
- if (!fs10.existsSync(manifestPath)) {
1468
- console.log(pc10.yellow(`
1037
+ const manifestPath = path7.join(projectRoot, "vv-manifest.json");
1038
+ if (!fs7.existsSync(manifestPath)) {
1039
+ console.log(pc9.yellow(`
1469
1040
  \u26A0\uFE0F No vv-manifest.json found in this directory.`));
1470
- 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>"))}
1471
1042
  `);
1472
1043
  return;
1473
1044
  }
1474
1045
  let manifest;
1475
1046
  try {
1476
- manifest = JSON.parse(fs10.readFileSync(manifestPath, "utf-8"));
1047
+ manifest = JSON.parse(fs7.readFileSync(manifestPath, "utf-8"));
1477
1048
  } catch {
1478
- 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.`));
1479
1050
  process.exit(1);
1480
1051
  return;
1481
1052
  }
1482
1053
  const installedComponents = manifest.components || {};
1483
1054
  const installedSlugs = Object.keys(installedComponents);
1484
1055
  if (installedSlugs.length === 0) {
1485
- console.log(pc10.yellow(`
1056
+ console.log(pc9.yellow(`
1486
1057
  \u26A0\uFE0F No components are registered as installed in vv-manifest.json.`));
1487
- 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>"))}
1488
1059
  `);
1489
1060
  return;
1490
1061
  }
@@ -1493,21 +1064,21 @@ async function diffCommand(slug) {
1493
1064
  validateSlug(slug);
1494
1065
  } catch (error) {
1495
1066
  const message = error instanceof Error ? error.message : String(error);
1496
- console.error(pc10.red(`
1067
+ console.error(pc9.red(`
1497
1068
  \u274C ${message}
1498
1069
  `));
1499
1070
  process.exit(1);
1500
1071
  }
1501
1072
  if (!installedComponents[slug]) {
1502
- console.log(pc10.red(`
1073
+ console.log(pc9.red(`
1503
1074
  \u274C Component "${slug}" is not installed in this project.`));
1504
- 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.
1505
1076
  `);
1506
1077
  return;
1507
1078
  }
1508
1079
  const localInfo = installedComponents[slug];
1509
1080
  const spinner = ora4({
1510
- text: `Checking updates for ${pc10.cyan(slug)}...`,
1081
+ text: `Checking updates for ${pc9.cyan(slug)}...`,
1511
1082
  color: "cyan"
1512
1083
  }).start();
1513
1084
  try {
@@ -1515,21 +1086,21 @@ async function diffCommand(slug) {
1515
1086
  spinner.stop();
1516
1087
  const localVersion = localInfo.version ?? "unknown";
1517
1088
  const remoteVersion = remoteComponent.version;
1518
- console.log(pc10.bold(pc10.cyan(`
1089
+ console.log(pc9.bold(pc9.cyan(`
1519
1090
  Component Diff: ${slug}`)));
1520
- console.log(` \u2022 Local version: ${pc10.yellow(localVersion)}`);
1521
- 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)}`);
1522
1093
  if (localVersion === remoteVersion) {
1523
- console.log(` \u2022 Status: ${pc10.green("\u2714 Up to date")}
1094
+ console.log(` \u2022 Status: ${pc9.green("\u2714 Up to date")}
1524
1095
  `);
1525
1096
  } else {
1526
- console.log(` \u2022 Status: ${pc10.bold(pc10.yellow("\u26A0\uFE0F Update available!"))}`);
1527
- 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.
1528
1099
  `);
1529
1100
  }
1530
1101
  } catch (error) {
1531
1102
  const message = error instanceof Error ? error.message : String(error);
1532
- spinner.fail(pc10.red(`Failed to fetch remote component details: ${message}`));
1103
+ spinner.fail(pc9.red(`Failed to fetch remote component details: ${message}`));
1533
1104
  process.exit(1);
1534
1105
  }
1535
1106
  } else {
@@ -1540,14 +1111,14 @@ Component Diff: ${slug}`)));
1540
1111
  try {
1541
1112
  const registryIndex = await fetchRegistryIndex();
1542
1113
  spinner.stop();
1543
- console.log(pc10.bold(pc10.cyan("\nVector Vesper Component Version Comparison\n")));
1544
- console.log(pc10.dim(" ----------------------------------------------------------------------"));
1114
+ console.log(pc9.bold(pc9.cyan("\nVector Vesper Component Version Comparison\n")));
1115
+ console.log(pc9.dim(" ----------------------------------------------------------------------"));
1545
1116
  console.log(
1546
- ` ${pc10.bold(pc10.white("Component".padEnd(25)))} ${pc10.bold(
1547
- pc10.white("Local".padEnd(10))
1548
- )} ${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"))}`
1549
1120
  );
1550
- console.log(pc10.dim(" ----------------------------------------------------------------------"));
1121
+ console.log(pc9.dim(" ----------------------------------------------------------------------"));
1551
1122
  let updatesAvailableCount = 0;
1552
1123
  for (const instSlug of installedSlugs) {
1553
1124
  const localInfo = installedComponents[instSlug];
@@ -1555,67 +1126,67 @@ Component Diff: ${slug}`)));
1555
1126
  const remoteInfo = registryIndex.components.find((c) => c.slug === instSlug);
1556
1127
  if (!remoteInfo) {
1557
1128
  console.log(
1558
- ` ${pc10.cyan(instSlug.padEnd(25))} ${pc10.yellow(
1129
+ ` ${pc9.cyan(instSlug.padEnd(25))} ${pc9.yellow(
1559
1130
  localVersion.padEnd(10)
1560
- )} ${pc10.red("unknown".padEnd(10))} ${pc10.red("Not found in registry")}`
1131
+ )} ${pc9.red("unknown".padEnd(10))} ${pc9.red("Not found in registry")}`
1561
1132
  );
1562
1133
  } else {
1563
1134
  const remoteVersion = remoteInfo.version;
1564
1135
  if (localVersion === remoteVersion) {
1565
1136
  console.log(
1566
- ` ${pc10.cyan(instSlug.padEnd(25))} ${pc10.gray(
1137
+ ` ${pc9.cyan(instSlug.padEnd(25))} ${pc9.gray(
1567
1138
  localVersion.padEnd(10)
1568
- )} ${pc10.gray(remoteVersion.padEnd(10))} ${pc10.green("\u2714 Up to date")}`
1139
+ )} ${pc9.gray(remoteVersion.padEnd(10))} ${pc9.green("\u2714 Up to date")}`
1569
1140
  );
1570
1141
  } else {
1571
1142
  updatesAvailableCount++;
1572
1143
  console.log(
1573
- ` ${pc10.cyan(instSlug.padEnd(25))} ${pc10.yellow(
1144
+ ` ${pc9.cyan(instSlug.padEnd(25))} ${pc9.yellow(
1574
1145
  localVersion.padEnd(10)
1575
- )} ${pc10.green(remoteVersion.padEnd(10))} ${pc10.bold(
1576
- pc10.yellow("\u26A0\uFE0F Update available")
1146
+ )} ${pc9.green(remoteVersion.padEnd(10))} ${pc9.bold(
1147
+ pc9.yellow("\u26A0\uFE0F Update available")
1577
1148
  )}`
1578
1149
  );
1579
1150
  }
1580
1151
  }
1581
1152
  }
1582
- console.log(pc10.dim(" ----------------------------------------------------------------------"));
1153
+ console.log(pc9.dim(" ----------------------------------------------------------------------"));
1583
1154
  if (updatesAvailableCount > 0) {
1584
1155
  console.log(
1585
1156
  `
1586
- \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.`
1587
1158
  );
1588
- 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.
1589
1160
  `);
1590
1161
  } else {
1591
1162
  console.log(`
1592
- ${pc10.green("\u2714")} All components are up to date!
1163
+ ${pc9.green("\u2714")} All components are up to date!
1593
1164
  `);
1594
1165
  }
1595
1166
  } catch (error) {
1596
1167
  const message = error instanceof Error ? error.message : String(error);
1597
- spinner.fail(pc10.red(`Failed to check updates: ${message}`));
1168
+ spinner.fail(pc9.red(`Failed to check updates: ${message}`));
1598
1169
  process.exit(1);
1599
1170
  }
1600
1171
  }
1601
1172
  }
1602
1173
 
1603
1174
  // src/commands/auth.ts
1604
- import pc11 from "picocolors";
1175
+ import pc10 from "picocolors";
1605
1176
  async function loginCommand(key) {
1606
1177
  if (!key || key.trim().length === 0) {
1607
- logger.error("Please provide a license key.");
1178
+ logger.error("Please provide your access token.");
1608
1179
  console.log(`
1609
- Usage: ${pc11.cyan("npx vectorvesper login <your-license-key>")}`);
1610
- 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")}
1611
1182
  `);
1612
1183
  process.exit(1);
1613
1184
  }
1614
1185
  const trimmedKey = key.trim();
1615
1186
  if (trimmedKey.length < 8) {
1616
- logger.error("That doesn't look like a valid license key.");
1187
+ logger.error("That doesn't look like a valid token.");
1617
1188
  console.log(`
1618
- \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")}
1619
1190
  `);
1620
1191
  process.exit(1);
1621
1192
  }
@@ -1632,18 +1203,18 @@ async function loginCommand(key) {
1632
1203
  process.exit(1);
1633
1204
  }
1634
1205
  console.log("");
1635
- console.log(` ${pc11.green(pc11.bold("\u2714"))} License key saved successfully!`);
1636
- 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())}`);
1637
1208
  console.log("");
1638
- console.log(` ${pc11.dim("Pro components are now available when you run")} ${pc11.cyan("npx vectorvesper add <slug>")}`);
1639
- 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")}`);
1640
1211
  console.log("");
1641
1212
  }
1642
1213
  async function logoutCommand() {
1643
1214
  const config = loadGlobalConfig();
1644
1215
  if (!config.auth?.token) {
1645
1216
  console.log(`
1646
- ${pc11.dim("You're not logged in. Nothing to do.")}
1217
+ ${pc10.dim("You're not logged in. Nothing to do.")}
1647
1218
  `);
1648
1219
  return;
1649
1220
  }
@@ -1656,40 +1227,40 @@ async function logoutCommand() {
1656
1227
  process.exit(1);
1657
1228
  }
1658
1229
  console.log("");
1659
- console.log(` ${pc11.green(pc11.bold("\u2714"))} Logged out successfully.`);
1660
- console.log(` ${pc11.dim("Your license key has been removed from")} ${pc11.cyan(getGlobalConfigPath())}`);
1661
- 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.")}`);
1662
1233
  console.log("");
1663
1234
  }
1664
1235
  async function whoamiCommand() {
1665
1236
  const config = loadGlobalConfig();
1666
1237
  console.log("");
1667
- console.log(pc11.bold(pc11.cyan(" Vector Vesper Account Status\n")));
1238
+ console.log(pc10.bold(pc10.cyan(" Vector Vesper Account Status\n")));
1668
1239
  if (config.auth?.token) {
1669
1240
  const maskedKey = config.auth.token.slice(0, 6) + "\u2026" + config.auth.token.slice(-4);
1670
1241
  const tier = config.auth.tier || "pro";
1671
- console.log(` ${pc11.bold("Status:")} ${pc11.green("Authenticated")}`);
1672
- console.log(` ${pc11.bold("Key:")} ${pc11.cyan(maskedKey)}`);
1673
- 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)}`);
1674
1245
  if (config.auth.email) {
1675
- console.log(` ${pc11.bold("Email:")} ${pc11.cyan(config.auth.email)}`);
1246
+ console.log(` ${pc10.bold("Email:")} ${pc10.cyan(config.auth.email)}`);
1676
1247
  }
1677
1248
  if (config.auth.expiresAt) {
1678
1249
  const expiry = new Date(config.auth.expiresAt);
1679
1250
  const now = /* @__PURE__ */ new Date();
1680
1251
  const isExpired = expiry < now;
1681
- 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())}`);
1682
1253
  }
1683
1254
  console.log("");
1684
- console.log(` ${pc11.dim("Config:")} ${pc11.cyan(getGlobalConfigPath())}`);
1685
- 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")}`);
1686
1257
  } else {
1687
- console.log(` ${pc11.bold("Status:")} ${pc11.yellow("Anonymous (free tier)")}`);
1688
- 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")}`);
1689
1260
  console.log("");
1690
- console.log(` ${pc11.dim("To unlock pro components:")}`);
1691
- console.log(` ${pc11.cyan("npx vectorvesper login <your-license-key>")}`);
1692
- 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")}`);
1693
1264
  }
1694
1265
  console.log("");
1695
1266
  }
@@ -1733,6 +1304,10 @@ program.command("logout", { hidden: true }).description("Clear stored license cr
1733
1304
  program.command("whoami", { hidden: true }).description("Show current authentication status").action(async () => {
1734
1305
  await whoamiCommand();
1735
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
+ });
1736
1311
  process.on("unhandledRejection", (error) => {
1737
1312
  console.error("An unexpected error occurred:", error instanceof Error ? error.message : error);
1738
1313
  process.exit(1);