vectorvesper 2.0.6 → 2.0.7

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
@@ -993,7 +993,7 @@ Remove ${slug}
993
993
  import fs6 from "fs";
994
994
  import path6 from "path";
995
995
  import pc8 from "picocolors";
996
- var CLI_VERSION = true ? "2.0.6" : "0.0.0-dev";
996
+ var CLI_VERSION = true ? "2.0.7" : "0.0.0-dev";
997
997
  async function infoCommand() {
998
998
  console.log(pc8.bold(pc8.cyan("\nVector Vesper Diagnostics\n")));
999
999
  const projectInfo = detectProject();
@@ -1291,7 +1291,7 @@ async function whoamiCommand() {
1291
1291
  }
1292
1292
 
1293
1293
  // src/index.ts
1294
- var version = true ? "2.0.6" : "0.0.0-dev";
1294
+ var version = true ? "2.0.7" : "0.0.0-dev";
1295
1295
  var program = new Command();
1296
1296
  program.name("vv").description("Vector Vesper CLI \u2014 add visual components to your React project").version(version).option("--verbose", "Show detailed debug output").hook("preAction", (thisCommand) => {
1297
1297
  const opts = thisCommand.opts();
@@ -1330,7 +1330,7 @@ program.command("whoami", { hidden: true }).description("Show current authentica
1330
1330
  await whoamiCommand();
1331
1331
  });
1332
1332
  program.command("mcp [action]").description("Run as an MCP server (stdio) for AI coding agents. `vv mcp status` checks the setup.").option("--stdio", "Force server mode even from an interactive terminal").action(async (action, options) => {
1333
- const { mcpCommand } = await import("./mcp-HOFTIXET.js");
1333
+ const { mcpCommand } = await import("./mcp-NVM7DS5P.js");
1334
1334
  await mcpCommand(action, options);
1335
1335
  });
1336
1336
  process.on("unhandledRejection", (error) => {
@@ -7,7 +7,7 @@ import {
7
7
 
8
8
  // src/commands/mcp.ts
9
9
  import pc from "picocolors";
10
- var VERSION = true ? "2.0.6" : "0.0.0-dev";
10
+ var VERSION = true ? "2.0.7" : "0.0.0-dev";
11
11
  var CONFIG_SNIPPET = `{
12
12
  "mcpServers": {
13
13
  "vectorvesper": {
@@ -94,7 +94,7 @@ ${pc.red("\u2717")} Unknown argument "${action}" for \`vv mcp\`.
94
94
  return;
95
95
  }
96
96
  protectStdout();
97
- const { startMcpServer } = await import("./server-TWBMQIV6.js");
97
+ const { startMcpServer } = await import("./server-LJL6ZBE3.js");
98
98
  try {
99
99
  await startMcpServer();
100
100
  } catch (error) {
@@ -37,8 +37,10 @@ function calleeName(callee) {
37
37
  }
38
38
  return void 0;
39
39
  }
40
- function isSetter(name) {
41
- return !!name && /^set[A-Z]/.test(name) && name !== "setInterval" && name !== "setTimeout";
40
+ function isStateSetterCall(callee) {
41
+ if (!callee || callee.type !== "Identifier") return false;
42
+ const name = callee.name;
43
+ return /^set[A-Z]/.test(name) && name !== "setInterval" && name !== "setTimeout";
42
44
  }
43
45
  function collect(ast, traverse) {
44
46
  const f = {
@@ -69,31 +71,50 @@ function collect(ast, traverse) {
69
71
  const hookByName = /* @__PURE__ */ new Map();
70
72
  for (const h of manifest?.hooks ?? []) hookByName.set(h.name, h);
71
73
  let fnDepth = 0;
74
+ const resolveFunction = (argPath) => {
75
+ const node = argPath?.node;
76
+ if (!node) return null;
77
+ if (node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression") return node;
78
+ if (node.type !== "Identifier") return null;
79
+ const binding = argPath.scope?.getBinding(node.name);
80
+ const declaration = binding?.path;
81
+ if (!declaration) return null;
82
+ if (declaration.node?.type === "FunctionDeclaration") return declaration.node;
83
+ const init = declaration.node?.init;
84
+ if (init && (init.type === "ArrowFunctionExpression" || init.type === "FunctionExpression")) return init;
85
+ return null;
86
+ };
72
87
  const scanHotCallback = (cbNode, ctx, fromRaf) => {
73
- if (!cbNode || cbNode.type !== "ArrowFunctionExpression" && cbNode.type !== "FunctionExpression") return;
88
+ if (!cbNode) return;
89
+ const isExpression = cbNode.type === "ArrowFunctionExpression" || cbNode.type === "FunctionExpression";
90
+ const isDeclaration = cbNode.type === "FunctionDeclaration";
91
+ if (!isExpression && !isDeclaration) return;
92
+ const statement = isDeclaration ? cbNode : { type: "ExpressionStatement", expression: cbNode };
74
93
  traverse(
75
- { type: "File", program: { type: "Program", body: [{ type: "ExpressionStatement", expression: cbNode }], directives: [] } },
94
+ { type: "File", program: { type: "Program", body: [statement], directives: [] } },
76
95
  {
77
96
  CallExpression(p) {
78
- if (isSetter(calleeName(p.node.callee))) {
97
+ if (isStateSetterCall(p.node.callee)) {
79
98
  f.setStateInHot.push({ line: cbNode.loc?.start.line ?? 0, ctx, fromRaf });
80
99
  }
81
100
  },
82
101
  OptionalCallExpression(p) {
83
- if (isSetter(calleeName(p.node.callee))) {
102
+ if (isStateSetterCall(p.node.callee)) {
84
103
  f.setStateInHot.push({ line: cbNode.loc?.start.line ?? 0, ctx, fromRaf });
85
104
  }
86
105
  }
87
106
  }
88
107
  );
89
108
  };
90
- const handleCall = (node) => {
109
+ const handleCall = (p) => {
110
+ const node = p.node;
91
111
  const name = calleeName(node.callee);
92
112
  const line = node.loc?.start.line ?? 0;
113
+ const argPaths = typeof p.get === "function" ? p.get("arguments") : [];
93
114
  switch (name) {
94
115
  case "requestAnimationFrame":
95
116
  f.raf.push(line);
96
- scanHotCallback(node.arguments?.[0], "a requestAnimationFrame loop", true);
117
+ scanHotCallback(resolveFunction(argPaths[0]), "a requestAnimationFrame loop", true);
97
118
  break;
98
119
  case "cancelAnimationFrame":
99
120
  f.hasCancelRaf = true;
@@ -108,7 +129,7 @@ function collect(ast, traverse) {
108
129
  f.addEventListener.push(line);
109
130
  const ev = node.arguments?.[0];
110
131
  if (ev?.type === "StringLiteral" && HOT_EVENTS.has(ev.value)) {
111
- scanHotCallback(node.arguments?.[1], `a "${ev.value}" listener`, false);
132
+ scanHotCallback(resolveFunction(argPaths[1]), `a "${ev.value}" listener`, false);
112
133
  }
113
134
  break;
114
135
  }
@@ -205,10 +226,10 @@ function collect(ast, traverse) {
205
226
  }
206
227
  },
207
228
  CallExpression(p) {
208
- handleCall(p.node);
229
+ handleCall(p);
209
230
  },
210
231
  OptionalCallExpression(p) {
211
- handleCall(p.node);
232
+ handleCall(p);
212
233
  }
213
234
  });
214
235
  return f;
@@ -378,7 +399,7 @@ async function checkMotionFiles(files, cwd) {
378
399
  }
379
400
 
380
401
  // src/mcp/server.ts
381
- var VERSION = true ? "2.0.6" : "0.0.0-dev";
402
+ var VERSION = true ? "2.0.7" : "0.0.0-dev";
382
403
  function text(body) {
383
404
  return { content: [{ type: "text", text: body }] };
384
405
  }
@@ -571,11 +592,13 @@ function formatCheckResults(results) {
571
592
  let errors = 0;
572
593
  let warnings = 0;
573
594
  let filesWithFindings = 0;
595
+ let unreadable = 0;
574
596
  const blocks = [];
575
597
  for (const r of results) {
576
598
  if (r.error) {
599
+ unreadable++;
577
600
  blocks.push(`### \`${r.file}\`
578
- - could not analyze: ${r.error}`);
601
+ - **could not analyze** \u2014 ${r.error}`);
579
602
  continue;
580
603
  }
581
604
  if (r.findings.length === 0) continue;
@@ -591,19 +614,16 @@ function formatCheckResults(results) {
591
614
  blocks.push(lines.join("\n"));
592
615
  }
593
616
  const total = errors + warnings;
594
- if (total === 0) {
617
+ const analyzed = results.length - unreadable;
618
+ if (total === 0 && unreadable === 0) {
595
619
  return `\u2713 No motion issues found in ${results.length} file${results.length === 1 ? "" : "s"}.
596
620
 
597
621
  ` + CHECK_SCOPE_NOTE;
598
622
  }
599
- return [
600
- "# Motion check",
601
- `${total} issue${total === 1 ? "" : "s"} across ${filesWithFindings} file${filesWithFindings === 1 ? "" : "s"} \u2014 ${errors} error${errors === 1 ? "" : "s"}, ${warnings} warning${warnings === 1 ? "" : "s"}.`,
602
- "",
603
- ...blocks,
604
- "",
605
- CHECK_SCOPE_NOTE
606
- ].join("\n");
623
+ const headline = total > 0 ? `${total} issue${total === 1 ? "" : "s"} across ${filesWithFindings} file${filesWithFindings === 1 ? "" : "s"} \u2014 ${errors} error${errors === 1 ? "" : "s"}, ${warnings} warning${warnings === 1 ? "" : "s"}.` : `No issues in the ${analyzed} file${analyzed === 1 ? "" : "s"} that could be read.`;
624
+ const unreadableNote = unreadable > 0 ? `
625
+ \u26A0\uFE0F ${unreadable} file${unreadable === 1 ? "" : "s"} could not be analyzed \u2014 ${unreadable === 1 ? "it was" : "they were"} NOT checked. Fix the path or the syntax and run again.` : "";
626
+ return ["# Motion check", headline + unreadableNote, "", ...blocks, "", CHECK_SCOPE_NOTE].join("\n");
607
627
  }
608
628
  async function registerTools(server) {
609
629
  server.registerTool(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vectorvesper",
3
- "version": "2.0.6",
3
+ "version": "2.0.7",
4
4
  "description": "Add WebGL, React Three Fiber & advanced motion components to your project via CLI.",
5
5
  "type": "module",
6
6
  "license": "MIT",