vectorvesper 2.0.0 → 2.0.2

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.
@@ -1,37 +1,10 @@
1
- // src/utils/logger.ts
2
- import pc from "picocolors";
3
- var verboseMode = false;
4
- function setVerbose(enabled) {
5
- verboseMode = enabled;
6
- }
7
- var logger = {
8
- /** Standard info message */
9
- info(message) {
10
- console.log(message);
11
- },
12
- /** Success message with green checkmark */
13
- success(message) {
14
- console.log(`${pc.green("\u2714")} ${message}`);
15
- },
16
- /** Warning message */
17
- warn(message) {
18
- console.log(pc.yellow(`\u26A0\uFE0F ${message}`));
19
- },
20
- /** Error message */
21
- error(message) {
22
- console.error(pc.red(`\u274C ${message}`));
23
- },
24
- /** Debug message — only shown when --verbose is active */
25
- debug(message) {
26
- if (verboseMode) {
27
- console.log(pc.dim(` [debug] ${message}`));
28
- }
29
- },
30
- /** Blank line */
31
- break() {
32
- console.log("");
33
- }
34
- };
1
+ import {
2
+ RegistryComponentSchema,
3
+ RegistryIndexSchema,
4
+ getAuthToken,
5
+ logger,
6
+ validateSlug
7
+ } from "./chunk-SFP5K3ZO.js";
35
8
 
36
9
  // src/utils/project.ts
37
10
  import fs from "fs";
@@ -97,203 +70,9 @@ function detectProject(cwd = process.cwd()) {
97
70
  };
98
71
  }
99
72
 
100
- // src/utils/config.ts
73
+ // src/utils/registry.ts
101
74
  import fs2 from "fs";
102
75
  import path2 from "path";
103
- import os from "os";
104
-
105
- // src/utils/types.ts
106
- import { z } from "zod";
107
- var SLUG_REGEX = /^[a-z0-9][a-z0-9-]*$/;
108
- function validateSlug(slug) {
109
- if (!SLUG_REGEX.test(slug)) {
110
- throw new Error(
111
- `Invalid component slug "${slug}". Slugs must contain only lowercase letters, numbers, and hyphens, and cannot start with a hyphen.`
112
- );
113
- }
114
- }
115
- var ComponentFileSchema = z.object({
116
- path: z.string(),
117
- target: z.string(),
118
- type: z.enum(["component", "types", "shader", "lib", "docs"]),
119
- content: z.string()
120
- });
121
- var RegistryComponentSchema = z.object({
122
- slug: z.string(),
123
- name: z.string(),
124
- title: z.string(),
125
- description: z.string(),
126
- version: z.string(),
127
- tier: z.enum(["free", "pro"]),
128
- category: z.string(),
129
- type: z.string(),
130
- frameworks: z.array(z.string()),
131
- files: z.array(ComponentFileSchema),
132
- dependencies: z.array(z.string()),
133
- devDependencies: z.array(z.string()),
134
- registryDependencies: z.array(z.string()),
135
- requiresClient: z.boolean(),
136
- supportsReducedMotion: z.boolean(),
137
- usesWebGL: z.boolean(),
138
- usesPointer: z.boolean(),
139
- usesScroll: z.boolean(),
140
- // Optional metadata — kept in sync with the registry builder schema.
141
- // Declared here (rather than relying on .passthrough()) so the CLI can
142
- // read them with full type-safety for post-install guidance.
143
- entry: z.string().optional(),
144
- exportName: z.string().optional(),
145
- usesTailwind: z.boolean().optional(),
146
- fallbacks: z.array(z.string()).optional(),
147
- recipes: z.array(z.string()).optional(),
148
- docsUrl: z.string().optional(),
149
- previewUrl: z.string().optional()
150
- }).passthrough();
151
- var IndexComponentSchema = z.object({
152
- slug: z.string(),
153
- name: z.string(),
154
- title: z.string(),
155
- description: z.string(),
156
- version: z.string(),
157
- tier: z.enum(["free", "pro"]),
158
- category: z.string(),
159
- type: z.string(),
160
- frameworks: z.array(z.string()),
161
- files: z.array(z.object({
162
- path: z.string(),
163
- target: z.string(),
164
- type: z.enum(["component", "types", "shader", "lib", "docs"])
165
- })),
166
- dependencies: z.array(z.string()),
167
- devDependencies: z.array(z.string()),
168
- registryDependencies: z.array(z.string()),
169
- requiresClient: z.boolean(),
170
- supportsReducedMotion: z.boolean(),
171
- usesWebGL: z.boolean(),
172
- usesPointer: z.boolean(),
173
- usesScroll: z.boolean(),
174
- entry: z.string().optional(),
175
- exportName: z.string().optional(),
176
- usesTailwind: z.boolean().optional(),
177
- // These are emitted by the registry build and were reaching consumers only
178
- // through .passthrough(), i.e. typed as unknown. Declared optional rather
179
- // than required so an older published registry still validates.
180
- fallbacks: z.array(z.string()).optional(),
181
- recipes: z.array(z.string()).optional(),
182
- docsUrl: z.string().optional(),
183
- previewUrl: z.string().optional()
184
- }).passthrough();
185
- var RegistryIndexSchema = z.object({
186
- version: z.string(),
187
- components: z.array(IndexComponentSchema)
188
- });
189
- var VVConfigSchema = z.object({
190
- tsx: z.boolean(),
191
- framework: z.enum(["next", "vite", "unknown"]),
192
- aliases: z.object({
193
- vv: z.string()
194
- })
195
- });
196
- var VVGlobalConfigSchema = z.object({
197
- // Auth — license key for paid components
198
- auth: z.object({
199
- token: z.string().optional(),
200
- email: z.string().optional(),
201
- tier: z.enum(["free", "pro", "team"]).optional(),
202
- expiresAt: z.string().optional()
203
- }).optional(),
204
- // Preferences
205
- telemetry: z.boolean().optional()
206
- }).passthrough();
207
- var ManifestEntrySchema = z.object({
208
- version: z.string(),
209
- installedAt: z.string(),
210
- installedOn: z.string(),
211
- files: z.array(z.string())
212
- });
213
- var ManifestSchema = z.object({
214
- components: z.record(z.string(), ManifestEntrySchema)
215
- });
216
-
217
- // src/utils/config.ts
218
- var CONFIG_FILE_NAME = "vv.config.json";
219
- function getConfigPath(cwd = process.cwd()) {
220
- return path2.join(cwd, CONFIG_FILE_NAME);
221
- }
222
- function loadConfig(cwd = process.cwd()) {
223
- const configPath = getConfigPath(cwd);
224
- if (!fs2.existsSync(configPath)) {
225
- return null;
226
- }
227
- let raw;
228
- try {
229
- const content = fs2.readFileSync(configPath, "utf-8");
230
- raw = JSON.parse(content);
231
- } catch {
232
- throw new Error(
233
- `Failed to parse vv.config.json \u2014 the file contains invalid JSON. Delete it and run "npx vectorvesper init" to regenerate.`
234
- );
235
- }
236
- const result = VVConfigSchema.safeParse(raw);
237
- if (!result.success) {
238
- const issues = result.error.issues.map((i) => ` \u2022 ${i.path.join(".")}: ${i.message}`).join("\n");
239
- throw new Error(
240
- `Invalid vv.config.json \u2014 schema validation failed:
241
- ${issues}
242
- Delete the file and run "npx vectorvesper init" to regenerate.`
243
- );
244
- }
245
- return result.data;
246
- }
247
- function writeConfig(config, cwd = process.cwd()) {
248
- const configPath = getConfigPath(cwd);
249
- fs2.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
250
- }
251
- var GLOBAL_CONFIG_DIR = path2.join(os.homedir(), ".vv");
252
- var GLOBAL_CONFIG_PATH = path2.join(GLOBAL_CONFIG_DIR, "config.json");
253
- function getGlobalConfigPath() {
254
- return GLOBAL_CONFIG_PATH;
255
- }
256
- function loadGlobalConfig() {
257
- if (!fs2.existsSync(GLOBAL_CONFIG_PATH)) {
258
- return {};
259
- }
260
- try {
261
- const content = fs2.readFileSync(GLOBAL_CONFIG_PATH, "utf-8");
262
- const raw = JSON.parse(content);
263
- const result = VVGlobalConfigSchema.safeParse(raw);
264
- if (!result.success) {
265
- logger.debug(`Global config validation failed: ${result.error.message}`);
266
- return {};
267
- }
268
- return result.data;
269
- } catch {
270
- logger.debug("Failed to parse global config, using defaults.");
271
- return {};
272
- }
273
- }
274
- function saveGlobalConfig(config) {
275
- if (!fs2.existsSync(GLOBAL_CONFIG_DIR)) {
276
- fs2.mkdirSync(GLOBAL_CONFIG_DIR, { recursive: true });
277
- }
278
- fs2.writeFileSync(GLOBAL_CONFIG_PATH, JSON.stringify(config, null, 2), "utf-8");
279
- }
280
- function getAuthToken() {
281
- const config = loadGlobalConfig();
282
- return config.auth?.token;
283
- }
284
- function resolveAlias(alias, hasSrcDir) {
285
- if (alias.startsWith("@/")) {
286
- return alias.replace("@/", hasSrcDir ? "src/" : "");
287
- }
288
- if (alias.startsWith("~/")) {
289
- return alias.replace("~/", hasSrcDir ? "src/" : "");
290
- }
291
- return alias;
292
- }
293
-
294
- // src/utils/registry.ts
295
- import fs3 from "fs";
296
- import path3 from "path";
297
76
  import { fileURLToPath } from "url";
298
77
  var DEFAULT_REGISTRY_URL = "https://raw.githubusercontent.com/vectorvesper/vv-components/main/r";
299
78
  var DEFAULT_PRO_API_URL = "https://vectorvesper.dev/api/cli/registry";
@@ -402,12 +181,12 @@ async function fetchRegistryData(urlOrPath) {
402
181
  if (urlOrPath.startsWith("file://")) {
403
182
  cleanPath = fileURLToPath(urlOrPath);
404
183
  }
405
- cleanPath = path3.resolve(cleanPath);
406
- if (!fs3.existsSync(cleanPath)) {
184
+ cleanPath = path2.resolve(cleanPath);
185
+ if (!fs2.existsSync(cleanPath)) {
407
186
  throw new Error(`Registry path not found: ${cleanPath}`);
408
187
  }
409
188
  logger.debug(`Reading local registry: ${cleanPath}`);
410
- return fs3.readFileSync(cleanPath, "utf-8");
189
+ return fs2.readFileSync(cleanPath, "utf-8");
411
190
  }
412
191
  async function fetchRegistryIndex() {
413
192
  const baseUrl = getRegistryBaseUrl();
@@ -482,17 +261,7 @@ ${issues}`);
482
261
  }
483
262
 
484
263
  export {
485
- setVerbose,
486
- logger,
487
264
  detectProject,
488
- validateSlug,
489
- loadConfig,
490
- writeConfig,
491
- getGlobalConfigPath,
492
- loadGlobalConfig,
493
- saveGlobalConfig,
494
- getAuthToken,
495
- resolveAlias,
496
265
  fetchRegistryIndex,
497
266
  fetchComponent
498
267
  };
@@ -0,0 +1,243 @@
1
+ // src/utils/logger.ts
2
+ import pc from "picocolors";
3
+ var verboseMode = false;
4
+ function setVerbose(enabled) {
5
+ verboseMode = enabled;
6
+ }
7
+ var logger = {
8
+ /** Standard info message */
9
+ info(message) {
10
+ console.log(message);
11
+ },
12
+ /** Success message with green checkmark */
13
+ success(message) {
14
+ console.log(`${pc.green("\u2714")} ${message}`);
15
+ },
16
+ /** Warning message */
17
+ warn(message) {
18
+ console.log(pc.yellow(`\u26A0\uFE0F ${message}`));
19
+ },
20
+ /** Error message */
21
+ error(message) {
22
+ console.error(pc.red(`\u274C ${message}`));
23
+ },
24
+ /** Debug message — only shown when --verbose is active */
25
+ debug(message) {
26
+ if (verboseMode) {
27
+ console.log(pc.dim(` [debug] ${message}`));
28
+ }
29
+ },
30
+ /** Blank line */
31
+ break() {
32
+ console.log("");
33
+ }
34
+ };
35
+
36
+ // src/utils/config.ts
37
+ import fs from "fs";
38
+ import path from "path";
39
+ import os from "os";
40
+
41
+ // src/utils/types.ts
42
+ import { z } from "zod";
43
+ var SLUG_REGEX = /^[a-z0-9][a-z0-9-]*$/;
44
+ function validateSlug(slug) {
45
+ if (!SLUG_REGEX.test(slug)) {
46
+ throw new Error(
47
+ `Invalid component slug "${slug}". Slugs must contain only lowercase letters, numbers, and hyphens, and cannot start with a hyphen.`
48
+ );
49
+ }
50
+ }
51
+ var ComponentFileSchema = z.object({
52
+ path: z.string(),
53
+ target: z.string(),
54
+ type: z.enum(["component", "types", "shader", "lib", "docs"]),
55
+ content: z.string()
56
+ });
57
+ var RegistryComponentSchema = z.object({
58
+ slug: z.string(),
59
+ name: z.string(),
60
+ title: z.string(),
61
+ description: z.string(),
62
+ version: z.string(),
63
+ tier: z.enum(["free", "pro"]),
64
+ category: z.string(),
65
+ type: z.string(),
66
+ frameworks: z.array(z.string()),
67
+ files: z.array(ComponentFileSchema),
68
+ dependencies: z.array(z.string()),
69
+ devDependencies: z.array(z.string()),
70
+ registryDependencies: z.array(z.string()),
71
+ requiresClient: z.boolean(),
72
+ supportsReducedMotion: z.boolean(),
73
+ usesWebGL: z.boolean(),
74
+ usesPointer: z.boolean(),
75
+ usesScroll: z.boolean(),
76
+ // Optional metadata — kept in sync with the registry builder schema.
77
+ // Declared here (rather than relying on .passthrough()) so the CLI can
78
+ // read them with full type-safety for post-install guidance.
79
+ entry: z.string().optional(),
80
+ exportName: z.string().optional(),
81
+ usesTailwind: z.boolean().optional(),
82
+ fallbacks: z.array(z.string()).optional(),
83
+ recipes: z.array(z.string()).optional(),
84
+ docsUrl: z.string().optional(),
85
+ previewUrl: z.string().optional()
86
+ }).passthrough();
87
+ var IndexComponentSchema = z.object({
88
+ slug: z.string(),
89
+ name: z.string(),
90
+ title: z.string(),
91
+ description: z.string(),
92
+ version: z.string(),
93
+ tier: z.enum(["free", "pro"]),
94
+ category: z.string(),
95
+ type: z.string(),
96
+ frameworks: z.array(z.string()),
97
+ files: z.array(z.object({
98
+ path: z.string(),
99
+ target: z.string(),
100
+ type: z.enum(["component", "types", "shader", "lib", "docs"])
101
+ })),
102
+ dependencies: z.array(z.string()),
103
+ devDependencies: z.array(z.string()),
104
+ registryDependencies: z.array(z.string()),
105
+ requiresClient: z.boolean(),
106
+ supportsReducedMotion: z.boolean(),
107
+ usesWebGL: z.boolean(),
108
+ usesPointer: z.boolean(),
109
+ usesScroll: z.boolean(),
110
+ entry: z.string().optional(),
111
+ exportName: z.string().optional(),
112
+ usesTailwind: z.boolean().optional(),
113
+ // These are emitted by the registry build and were reaching consumers only
114
+ // through .passthrough(), i.e. typed as unknown. Declared optional rather
115
+ // than required so an older published registry still validates.
116
+ fallbacks: z.array(z.string()).optional(),
117
+ recipes: z.array(z.string()).optional(),
118
+ docsUrl: z.string().optional(),
119
+ previewUrl: z.string().optional()
120
+ }).passthrough();
121
+ var RegistryIndexSchema = z.object({
122
+ version: z.string(),
123
+ components: z.array(IndexComponentSchema)
124
+ });
125
+ var VVConfigSchema = z.object({
126
+ tsx: z.boolean(),
127
+ framework: z.enum(["next", "vite", "unknown"]),
128
+ aliases: z.object({
129
+ vv: z.string()
130
+ })
131
+ });
132
+ var VVGlobalConfigSchema = z.object({
133
+ // Auth — license key for paid components
134
+ auth: z.object({
135
+ token: z.string().optional(),
136
+ email: z.string().optional(),
137
+ tier: z.enum(["free", "pro", "team"]).optional(),
138
+ expiresAt: z.string().optional()
139
+ }).optional(),
140
+ // Preferences
141
+ telemetry: z.boolean().optional()
142
+ }).passthrough();
143
+ var ManifestEntrySchema = z.object({
144
+ version: z.string(),
145
+ installedAt: z.string(),
146
+ installedOn: z.string(),
147
+ files: z.array(z.string())
148
+ });
149
+ var ManifestSchema = z.object({
150
+ components: z.record(z.string(), ManifestEntrySchema)
151
+ });
152
+
153
+ // src/utils/config.ts
154
+ var CONFIG_FILE_NAME = "vv.config.json";
155
+ function getConfigPath(cwd = process.cwd()) {
156
+ return path.join(cwd, CONFIG_FILE_NAME);
157
+ }
158
+ function loadConfig(cwd = process.cwd()) {
159
+ const configPath = getConfigPath(cwd);
160
+ if (!fs.existsSync(configPath)) {
161
+ return null;
162
+ }
163
+ let raw;
164
+ try {
165
+ const content = fs.readFileSync(configPath, "utf-8");
166
+ raw = JSON.parse(content);
167
+ } catch {
168
+ throw new Error(
169
+ `Failed to parse vv.config.json \u2014 the file contains invalid JSON. Delete it and run "npx vectorvesper init" to regenerate.`
170
+ );
171
+ }
172
+ const result = VVConfigSchema.safeParse(raw);
173
+ if (!result.success) {
174
+ const issues = result.error.issues.map((i) => ` \u2022 ${i.path.join(".")}: ${i.message}`).join("\n");
175
+ throw new Error(
176
+ `Invalid vv.config.json \u2014 schema validation failed:
177
+ ${issues}
178
+ Delete the file and run "npx vectorvesper init" to regenerate.`
179
+ );
180
+ }
181
+ return result.data;
182
+ }
183
+ function writeConfig(config, cwd = process.cwd()) {
184
+ const configPath = getConfigPath(cwd);
185
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
186
+ }
187
+ var GLOBAL_CONFIG_DIR = path.join(os.homedir(), ".vv");
188
+ var GLOBAL_CONFIG_PATH = path.join(GLOBAL_CONFIG_DIR, "config.json");
189
+ function getGlobalConfigPath() {
190
+ return GLOBAL_CONFIG_PATH;
191
+ }
192
+ function loadGlobalConfig() {
193
+ if (!fs.existsSync(GLOBAL_CONFIG_PATH)) {
194
+ return {};
195
+ }
196
+ try {
197
+ const content = fs.readFileSync(GLOBAL_CONFIG_PATH, "utf-8");
198
+ const raw = JSON.parse(content);
199
+ const result = VVGlobalConfigSchema.safeParse(raw);
200
+ if (!result.success) {
201
+ logger.debug(`Global config validation failed: ${result.error.message}`);
202
+ return {};
203
+ }
204
+ return result.data;
205
+ } catch {
206
+ logger.debug("Failed to parse global config, using defaults.");
207
+ return {};
208
+ }
209
+ }
210
+ function saveGlobalConfig(config) {
211
+ if (!fs.existsSync(GLOBAL_CONFIG_DIR)) {
212
+ fs.mkdirSync(GLOBAL_CONFIG_DIR, { recursive: true });
213
+ }
214
+ fs.writeFileSync(GLOBAL_CONFIG_PATH, JSON.stringify(config, null, 2), "utf-8");
215
+ }
216
+ function getAuthToken() {
217
+ const config = loadGlobalConfig();
218
+ return config.auth?.token;
219
+ }
220
+ function resolveAlias(alias, hasSrcDir) {
221
+ if (alias.startsWith("@/")) {
222
+ return alias.replace("@/", hasSrcDir ? "src/" : "");
223
+ }
224
+ if (alias.startsWith("~/")) {
225
+ return alias.replace("~/", hasSrcDir ? "src/" : "");
226
+ }
227
+ return alias;
228
+ }
229
+
230
+ export {
231
+ setVerbose,
232
+ logger,
233
+ validateSlug,
234
+ RegistryComponentSchema,
235
+ RegistryIndexSchema,
236
+ loadConfig,
237
+ writeConfig,
238
+ getGlobalConfigPath,
239
+ loadGlobalConfig,
240
+ saveGlobalConfig,
241
+ getAuthToken,
242
+ resolveAlias
243
+ };
@@ -0,0 +1,41 @@
1
+ // src/mcp/manifest.ts
2
+ import fs from "fs";
3
+ import path from "path";
4
+ import { fileURLToPath } from "url";
5
+ var __dirname = path.dirname(fileURLToPath(import.meta.url));
6
+ var CANDIDATES = [
7
+ path.join(__dirname, "hooks.json"),
8
+ path.join(__dirname, "../hooks.json"),
9
+ path.resolve(__dirname, "../../../registry/generated/hooks.lean.json"),
10
+ path.resolve(__dirname, "../../registry/generated/hooks.lean.json")
11
+ ];
12
+ var cached = null;
13
+ function loadHookManifest() {
14
+ if (cached) return cached;
15
+ for (const candidate of CANDIDATES) {
16
+ if (!fs.existsSync(candidate)) continue;
17
+ try {
18
+ const parsed = JSON.parse(fs.readFileSync(candidate, "utf-8"));
19
+ if (Array.isArray(parsed?.hooks)) {
20
+ cached = parsed;
21
+ return cached;
22
+ }
23
+ } catch {
24
+ }
25
+ }
26
+ return null;
27
+ }
28
+ function findHook(name) {
29
+ const manifest = loadHookManifest();
30
+ if (!manifest) return null;
31
+ const wanted = name.toLowerCase();
32
+ return manifest.hooks.find((h) => h.name.toLowerCase() === wanted) ?? // Tolerate "sensor-bus" / "sensorbus" / "SensorBus" for "useSensorBus".
33
+ manifest.hooks.find(
34
+ (h) => h.name.toLowerCase().replace(/^use/, "") === wanted.replace(/^use/, "").replace(/-/g, "")
35
+ ) ?? null;
36
+ }
37
+
38
+ export {
39
+ loadHookManifest,
40
+ findHook
41
+ };