zelune 1.6.4 → 1.6.5

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/mcp/server.mjs CHANGED
@@ -224,7 +224,7 @@ function resolveScreensDirectory(projectRoot) {
224
224
  };
225
225
  }
226
226
  const FORBIDDEN_OBJECT_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
227
- function safeRealpath(targetPath) {
227
+ function safeRealpath$1(targetPath) {
228
228
  try {
229
229
  return fs$1.realpathSync(targetPath);
230
230
  } catch {
@@ -232,12 +232,12 @@ function safeRealpath(targetPath) {
232
232
  }
233
233
  }
234
234
  function resolveSafeScreenPath(workspaceRoot, relativeFile) {
235
- const normalizedRoot = safeRealpath(getActiveProjectRoot(workspaceRoot));
235
+ const normalizedRoot = safeRealpath$1(getActiveProjectRoot(workspaceRoot));
236
236
  const cleanRel = String(relativeFile ?? "").replace(/^[/\\]+/, "");
237
237
  const resolved = path.resolve(normalizedRoot, cleanRel);
238
238
  const allowedDirs = ["src/screens", "screens", "app", "src/app"].map((d) => {
239
239
  const candidate = path.resolve(normalizedRoot, d);
240
- return fs$1.existsSync(candidate) ? safeRealpath(candidate) : candidate;
240
+ return fs$1.existsSync(candidate) ? safeRealpath$1(candidate) : candidate;
241
241
  });
242
242
  const isLexicallyAllowed = allowedDirs.some(
243
243
  (dir) => resolved.startsWith(dir + path.sep) || resolved === dir
@@ -257,7 +257,7 @@ function resolveSafeScreenPath(workspaceRoot, relativeFile) {
257
257
  `Security violation: Symbolic link "${relativeFile}" is not permitted inside screen directories`
258
258
  );
259
259
  }
260
- const realTarget = safeRealpath(resolved);
260
+ const realTarget = safeRealpath$1(resolved);
261
261
  const isRealInsideAllowed = allowedDirs.some(
262
262
  (dir) => realTarget.startsWith(dir + path.sep) || realTarget === dir
263
263
  );
@@ -2080,6 +2080,7 @@ async function readJsonBody(req) {
2080
2080
  }
2081
2081
  const generate = _generate.default ?? _generate;
2082
2082
  const ALLOWED_SCREEN_PREFIXES = ["src/screens/", "screens/", "app/", "src/app/"];
2083
+ const ASSET_EXT_REGEX = /\.(png|jpe?g|gif|webp|svg|avif|bmp|ico|ttf|otf|woff2?|mp3|mp4|wav|m4a|webm|lottie|pdf|bin)$/i;
2083
2084
  const RESOLVABLE_EXTENSIONS = [
2084
2085
  ".web.tsx",
2085
2086
  ".web.ts",
@@ -2089,9 +2090,20 @@ const RESOLVABLE_EXTENSIONS = [
2089
2090
  ".ts",
2090
2091
  ".jsx",
2091
2092
  ".js",
2093
+ ".native.tsx",
2094
+ ".native.ts",
2095
+ ".native.jsx",
2096
+ ".native.js",
2097
+ ".ios.tsx",
2098
+ ".ios.ts",
2099
+ ".android.tsx",
2100
+ ".android.ts",
2101
+ ".mjs",
2102
+ ".cjs",
2092
2103
  ".json",
2093
2104
  ".css"
2094
2105
  ];
2106
+ const ZELUNE_JSX_REACT_IDENT = "__zeluneReact";
2095
2107
  function stripJsonCommentsAndTrailingCommas(input) {
2096
2108
  const withoutComments = input.replace(
2097
2109
  /("(?:\\.|[^"\\])*")|\/\*[\s\S]*?\*\/|\/\/.*/g,
@@ -2200,7 +2212,7 @@ function convertJsxElementNameToExpr(nameNode) {
2200
2212
  }
2201
2213
  return t.stringLiteral("div");
2202
2214
  }
2203
- function convertJsxAttributesToExpr(attributes) {
2215
+ function convertJsxAttributesToExpr(attributes, onJsxSeen) {
2204
2216
  if (attributes.length === 0) {
2205
2217
  return t.nullLiteral();
2206
2218
  }
@@ -2222,7 +2234,7 @@ function convertJsxAttributesToExpr(attributes) {
2222
2234
  valExpr = attr.value.expression;
2223
2235
  }
2224
2236
  } else if (t.isJSXElement(attr.value) || t.isJSXFragment(attr.value)) {
2225
- valExpr = transformJsxNode(attr.value);
2237
+ valExpr = transformJsxNode(attr.value, onJsxSeen);
2226
2238
  } else {
2227
2239
  valExpr = attr.value;
2228
2240
  }
@@ -2230,9 +2242,10 @@ function convertJsxAttributesToExpr(attributes) {
2230
2242
  }
2231
2243
  return t.objectExpression(props);
2232
2244
  }
2233
- function convertJsxChildrenToExprs(children) {
2245
+ function convertJsxChildrenToExprs(children, onJsxSeen) {
2234
2246
  const out = [];
2235
2247
  for (const child of children) {
2248
+ if (!child) continue;
2236
2249
  if (t.isJSXText(child)) {
2237
2250
  const cleaned = cleanJsxText(child.value);
2238
2251
  if (cleaned !== null) {
@@ -2245,27 +2258,30 @@ function convertJsxChildrenToExprs(children) {
2245
2258
  } else if (t.isJSXSpreadChild(child)) {
2246
2259
  out.push(child.expression);
2247
2260
  } else if (t.isJSXElement(child) || t.isJSXFragment(child)) {
2248
- out.push(transformJsxNode(child));
2261
+ out.push(transformJsxNode(child, onJsxSeen));
2262
+ } else if (t.isSpreadElement(child) || t.isExpression(child)) {
2263
+ out.push(child);
2249
2264
  }
2250
2265
  }
2251
2266
  return out;
2252
2267
  }
2253
- function transformJsxNode(node) {
2268
+ function transformJsxNode(node, onJsxSeen) {
2269
+ onJsxSeen();
2254
2270
  const createElMember = t.memberExpression(
2255
- t.identifier("React"),
2271
+ t.identifier(ZELUNE_JSX_REACT_IDENT),
2256
2272
  t.identifier("createElement")
2257
2273
  );
2258
2274
  if (t.isJSXFragment(node)) {
2259
2275
  const fragMember = t.memberExpression(
2260
- t.identifier("React"),
2276
+ t.identifier(ZELUNE_JSX_REACT_IDENT),
2261
2277
  t.identifier("Fragment")
2262
2278
  );
2263
- const children2 = convertJsxChildrenToExprs(node.children);
2279
+ const children2 = convertJsxChildrenToExprs(node.children, onJsxSeen);
2264
2280
  return t.callExpression(createElMember, [fragMember, t.nullLiteral(), ...children2]);
2265
2281
  }
2266
2282
  const tagExpr = convertJsxElementNameToExpr(node.openingElement.name);
2267
- const propsExpr = convertJsxAttributesToExpr(node.openingElement.attributes);
2268
- const children = convertJsxChildrenToExprs(node.children);
2283
+ const propsExpr = convertJsxAttributesToExpr(node.openingElement.attributes, onJsxSeen);
2284
+ const children = convertJsxChildrenToExprs(node.children, onJsxSeen);
2269
2285
  return t.callExpression(createElMember, [tagExpr, propsExpr, ...children]);
2270
2286
  }
2271
2287
  function convertTsEnumToVar(enumNode) {
@@ -2288,27 +2304,52 @@ function convertTsEnumToVar(enumNode) {
2288
2304
  t.variableDeclarator(t.identifier(enumNode.id.name), t.objectExpression(props))
2289
2305
  ]);
2290
2306
  }
2291
- function stripTypeScriptAndTransformJsxAst(node) {
2292
- var _a;
2307
+ function isTsDeclarationOnlyNode(item) {
2308
+ const nodeType = item.type;
2309
+ if (nodeType === "TSInterfaceDeclaration" || nodeType === "TSTypeAliasDeclaration" || nodeType === "TSDeclareFunction" || nodeType === "TSDeclareMethod" || nodeType === "TSModuleDeclaration" || nodeType === "TSIndexSignature" || nodeType === "TSAbstractMethodDefinition" || nodeType === "TSAbstractPropertyDefinition" || nodeType === "TSAbstractAccessorProperty") {
2310
+ return true;
2311
+ }
2312
+ if ((nodeType === "ClassMethod" || nodeType === "ClassProperty" || nodeType === "ClassPrivateProperty" || nodeType === "AccessorProperty") && (item.abstract === true || item.declare === true)) {
2313
+ return true;
2314
+ }
2315
+ if (nodeType === "VariableDeclaration" && item.declare === true) {
2316
+ return true;
2317
+ }
2318
+ if (nodeType === "ClassDeclaration" && item.declare === true) {
2319
+ return true;
2320
+ }
2321
+ return false;
2322
+ }
2323
+ function stripTypeScriptAndTransformJsxAst(node, onJsxSeen = () => {
2324
+ }) {
2325
+ var _a, _b, _c, _d, _e;
2293
2326
  if (!node || typeof node !== "object") return node;
2294
2327
  if (Array.isArray(node)) {
2295
2328
  const nextArr = [];
2296
2329
  for (let i = 0; i < node.length; i++) {
2297
2330
  const item = node[i];
2298
2331
  if (!item) continue;
2299
- if (item.type === "TSInterfaceDeclaration" || item.type === "TSTypeAliasDeclaration" || item.type === "TSDeclareFunction" || item.type === "TSDeclareMethod" || item.type === "TSModuleDeclaration" || item.type === "TSIndexSignature") {
2332
+ if (isTsDeclarationOnlyNode(item)) {
2300
2333
  continue;
2301
2334
  }
2302
2335
  if (item.type === "ImportDeclaration" && item.importKind === "type") {
2303
2336
  continue;
2304
2337
  }
2338
+ if (item.type === "ExportAllDeclaration" && item.exportKind === "type") {
2339
+ continue;
2340
+ }
2305
2341
  if (item.type === "ExportNamedDeclaration") {
2306
2342
  if (item.exportKind === "type") continue;
2307
- if (item.declaration && (item.declaration.type === "TSInterfaceDeclaration" || item.declaration.type === "TSTypeAliasDeclaration" || item.declaration.type === "TSDeclareFunction" || item.declaration.type === "TSModuleDeclaration")) {
2343
+ if (item.declaration && isTsDeclarationOnlyNode(item.declaration)) {
2344
+ continue;
2345
+ }
2346
+ }
2347
+ if (item.type === "ExportDefaultDeclaration") {
2348
+ if (item.declaration && isTsDeclarationOnlyNode(item.declaration)) {
2308
2349
  continue;
2309
2350
  }
2310
2351
  }
2311
- const transformed = stripTypeScriptAndTransformJsxAst(item);
2352
+ const transformed = stripTypeScriptAndTransformJsxAst(item, onJsxSeen);
2312
2353
  if (transformed !== null && transformed !== void 0) {
2313
2354
  nextArr.push(transformed);
2314
2355
  }
@@ -2355,9 +2396,48 @@ function stripTypeScriptAndTransformJsxAst(node) {
2355
2396
  delete node.readonly;
2356
2397
  delete node.declare;
2357
2398
  delete node.override;
2358
- delete node.optional;
2399
+ delete node.abstract;
2400
+ delete node.importKind;
2401
+ delete node.exportKind;
2402
+ if (node.type !== "OptionalMemberExpression" && node.type !== "OptionalCallExpression") {
2403
+ delete node.optional;
2404
+ }
2405
+ if ((node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression" || node.type === "ObjectMethod" || node.type === "ClassMethod" || node.type === "ClassPrivateMethod") && Array.isArray(node.params) && ((_b = node.params[0]) == null ? void 0 : _b.type) === "Identifier" && ((_c = node.params[0]) == null ? void 0 : _c.name) === "this") {
2406
+ node.params = node.params.slice(1);
2407
+ }
2408
+ if (node.type === "ClassMethod" && node.kind === "constructor" && Array.isArray(node.params) && ((_d = node.body) == null ? void 0 : _d.type) === "BlockStatement" && Array.isArray(node.body.body)) {
2409
+ const paramPropAssignments = [];
2410
+ for (const p of node.params) {
2411
+ if ((p == null ? void 0 : p.type) === "TSParameterProperty") {
2412
+ const inner = p.parameter;
2413
+ const propName = (inner == null ? void 0 : inner.type) === "Identifier" ? inner.name : (inner == null ? void 0 : inner.type) === "AssignmentPattern" && ((_e = inner.left) == null ? void 0 : _e.type) === "Identifier" ? inner.left.name : null;
2414
+ if (propName) {
2415
+ paramPropAssignments.push(
2416
+ t.expressionStatement(
2417
+ t.assignmentExpression(
2418
+ "=",
2419
+ t.memberExpression(t.thisExpression(), t.identifier(propName)),
2420
+ t.identifier(propName)
2421
+ )
2422
+ )
2423
+ );
2424
+ }
2425
+ }
2426
+ }
2427
+ if (paramPropAssignments.length > 0) {
2428
+ const superIdx = node.body.body.findIndex(
2429
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2430
+ (s) => {
2431
+ var _a2, _b2;
2432
+ return (s == null ? void 0 : s.type) === "ExpressionStatement" && ((_a2 = s.expression) == null ? void 0 : _a2.type) === "CallExpression" && ((_b2 = s.expression.callee) == null ? void 0 : _b2.type) === "Super";
2433
+ }
2434
+ );
2435
+ const insertPos = superIdx >= 0 ? superIdx + 1 : 0;
2436
+ node.body.body.splice(insertPos, 0, ...paramPropAssignments);
2437
+ }
2438
+ }
2359
2439
  if (node.type === "TSParameterProperty") {
2360
- return stripTypeScriptAndTransformJsxAst(node.parameter);
2440
+ return stripTypeScriptAndTransformJsxAst(node.parameter, onJsxSeen);
2361
2441
  }
2362
2442
  for (const key of Object.keys(node)) {
2363
2443
  if (key === "loc" || key === "comments" || key === "leadingComments" || key === "trailingComments") {
@@ -2365,11 +2445,11 @@ function stripTypeScriptAndTransformJsxAst(node) {
2365
2445
  }
2366
2446
  const val = node[key];
2367
2447
  if (val && typeof val === "object") {
2368
- node[key] = stripTypeScriptAndTransformJsxAst(val);
2448
+ node[key] = stripTypeScriptAndTransformJsxAst(val, onJsxSeen);
2369
2449
  }
2370
2450
  }
2371
2451
  if (node.type === "JSXElement" || node.type === "JSXFragment") {
2372
- return transformJsxNode(node);
2452
+ return transformJsxNode(node, onJsxSeen);
2373
2453
  }
2374
2454
  return node;
2375
2455
  }
@@ -2431,8 +2511,117 @@ function injectScreenAgyAttributes(ast, relPath) {
2431
2511
  visit(ast);
2432
2512
  return hasJsx;
2433
2513
  }
2514
+ function collectNamespaceMemberAccesses(ast, namespaceLocalNames) {
2515
+ const accesses = /* @__PURE__ */ new Map();
2516
+ if (namespaceLocalNames.size === 0) return accesses;
2517
+ for (const name of namespaceLocalNames) {
2518
+ accesses.set(name, /* @__PURE__ */ new Set());
2519
+ }
2520
+ function visit(node) {
2521
+ var _a;
2522
+ if (!node || typeof node !== "object" || typeof node.type !== "string") return;
2523
+ const typed = node;
2524
+ if ((typed.type === "MemberExpression" || typed.type === "OptionalMemberExpression") && !typed.computed && typed.object.type === "Identifier" && namespaceLocalNames.has(typed.object.name) && typed.property.type === "Identifier") {
2525
+ (_a = accesses.get(typed.object.name)) == null ? void 0 : _a.add(typed.property.name);
2526
+ }
2527
+ const keys = t.VISITOR_KEYS[typed.type];
2528
+ if (!keys) return;
2529
+ const rec = typed;
2530
+ for (const key of keys) {
2531
+ const child = rec[key];
2532
+ if (Array.isArray(child)) {
2533
+ for (let i = 0; i < child.length; i++) {
2534
+ if (child[i]) visit(child[i]);
2535
+ }
2536
+ } else if (child && typeof child === "object") {
2537
+ visit(child);
2538
+ }
2539
+ }
2540
+ }
2541
+ visit(ast);
2542
+ return accesses;
2543
+ }
2544
+ function collectRuntimeReferencedIdentifiers(stmts) {
2545
+ const refs = /* @__PURE__ */ new Set();
2546
+ function walk(node) {
2547
+ if (!node || typeof node !== "object") return;
2548
+ if (Array.isArray(node)) {
2549
+ for (let i = 0; i < node.length; i++) {
2550
+ if (node[i]) walk(node[i]);
2551
+ }
2552
+ return;
2553
+ }
2554
+ if (node.type === "Identifier" && typeof node.name === "string") {
2555
+ refs.add(node.name);
2556
+ }
2557
+ for (const key of Object.keys(node)) {
2558
+ if (key === "loc" || key === "comments" || key === "leadingComments" || key === "trailingComments") {
2559
+ continue;
2560
+ }
2561
+ const val = node[key];
2562
+ if (val && typeof val === "object") {
2563
+ walk(val);
2564
+ }
2565
+ }
2566
+ }
2567
+ for (const stmt of stmts) {
2568
+ if (stmt && stmt.type !== "ImportDeclaration") {
2569
+ walk(stmt);
2570
+ }
2571
+ }
2572
+ return refs;
2573
+ }
2574
+ function getLocalTypeOnlyDeclaredNames(localFilePath) {
2575
+ var _a;
2576
+ const typeNames = /* @__PURE__ */ new Set();
2577
+ const valueNames = /* @__PURE__ */ new Set();
2578
+ try {
2579
+ if (!/\.(tsx?|mts|cts)$/i.test(localFilePath) || !fs$1.existsSync(localFilePath)) {
2580
+ return typeNames;
2581
+ }
2582
+ const raw = fs$1.readFileSync(localFilePath, "utf-8");
2583
+ const parsed = parse(raw, {
2584
+ sourceType: "module",
2585
+ plugins: ["typescript", "jsx", "decorators-legacy"],
2586
+ errorRecovery: true
2587
+ });
2588
+ for (const stmt of parsed.program.body) {
2589
+ if (stmt.type === "ExportNamedDeclaration") {
2590
+ if (stmt.exportKind === "type") {
2591
+ if (stmt.declaration && "id" in stmt.declaration && ((_a = stmt.declaration.id) == null ? void 0 : _a.type) === "Identifier") {
2592
+ typeNames.add(stmt.declaration.id.name);
2593
+ }
2594
+ for (const s of stmt.specifiers) {
2595
+ if (s.type === "ExportSpecifier") {
2596
+ const exp = s.exported.type === "Identifier" ? s.exported.name : s.exported.value;
2597
+ typeNames.add(exp);
2598
+ }
2599
+ }
2600
+ continue;
2601
+ }
2602
+ const decl = stmt.declaration;
2603
+ if (decl) {
2604
+ if (decl.type === "TSInterfaceDeclaration" || decl.type === "TSTypeAliasDeclaration") {
2605
+ typeNames.add(decl.id.name);
2606
+ } else if ((decl.type === "FunctionDeclaration" || decl.type === "ClassDeclaration" || decl.type === "TSEnumDeclaration") && decl.id) {
2607
+ valueNames.add(decl.id.name);
2608
+ } else if (decl.type === "VariableDeclaration") {
2609
+ for (const d of decl.declarations) {
2610
+ if (d.id.type === "Identifier") valueNames.add(d.id.name);
2611
+ }
2612
+ }
2613
+ }
2614
+ }
2615
+ }
2616
+ for (const v of valueNames) {
2617
+ typeNames.delete(v);
2618
+ }
2619
+ } catch {
2620
+ }
2621
+ return typeNames;
2622
+ }
2434
2623
  function compileModuleForBrowser(options) {
2435
- const { filePath, targetProjectRoot, workspaceRoot = targetProjectRoot } = options;
2624
+ const { filePath, targetProjectRoot, workspaceRoot = targetProjectRoot, versionTag } = options;
2436
2625
  const cleanFilePath = filePath.split("?")[0];
2437
2626
  const ext = path.extname(cleanFilePath).toLowerCase();
2438
2627
  if (ext === ".css") {
@@ -2443,7 +2632,7 @@ function compileModuleForBrowser(options) {
2443
2632
  return `export default ${rawJson};
2444
2633
  `;
2445
2634
  }
2446
- if (/\.(png|jpe?g|gif|webp|svg|avif|bmp)$/i.test(ext)) {
2635
+ if (ASSET_EXT_REGEX.test(ext)) {
2447
2636
  const assetUrl = `/@zelune/asset?file=${encodeURIComponent(cleanFilePath)}`;
2448
2637
  return `export default { uri: ${JSON.stringify(assetUrl)} };
2449
2638
  `;
@@ -2457,7 +2646,12 @@ function compileModuleForBrowser(options) {
2457
2646
  const normalizedTargetRoot = path.resolve(targetProjectRoot);
2458
2647
  const relPath = path.relative(normalizedTargetRoot, path.resolve(cleanFilePath)).replace(/\\/g, "/");
2459
2648
  const isScreenFile = ALLOWED_SCREEN_PREFIXES.some((prefix) => relPath.startsWith(prefix));
2460
- const hadJsx = isScreenFile ? injectScreenAgyAttributes(ast, relPath) : true;
2649
+ let emittedJsx = false;
2650
+ if (isScreenFile) {
2651
+ if (injectScreenAgyAttributes(ast, relPath)) {
2652
+ emittedJsx = true;
2653
+ }
2654
+ }
2461
2655
  const uniqueRoots = Array.from(
2462
2656
  /* @__PURE__ */ new Set([path.resolve(targetProjectRoot), path.resolve(workspaceRoot)])
2463
2657
  );
@@ -2484,6 +2678,29 @@ function compileModuleForBrowser(options) {
2484
2678
  }
2485
2679
  return null;
2486
2680
  }
2681
+ function resolveLocalOrAliasFile(specifier) {
2682
+ if (specifier.startsWith(".")) {
2683
+ const candidate = path.resolve(path.dirname(cleanFilePath), specifier);
2684
+ return tryResolveLocalModule(candidate);
2685
+ }
2686
+ if (specifier.startsWith("@/") || specifier.startsWith("~/") || tsconfigAliases.some((m) => specifier === m.prefix || specifier.startsWith(m.prefix + "/"))) {
2687
+ return resolveAlias(specifier);
2688
+ }
2689
+ return null;
2690
+ }
2691
+ function rewriteResolvedLocalFile(resolved, requestedExports) {
2692
+ const normalized = resolved.replace(/\\/g, "/");
2693
+ if (normalized.endsWith("/src/runtime/MockNavigationContext.tsx")) {
2694
+ return `/@zelune/shim/stub.js?pkg=zelune-mock-nav&exports=${encodeURIComponent(
2695
+ requestedExports.join(",")
2696
+ )}`;
2697
+ }
2698
+ if (normalized.endsWith("/src/runtime/reactNativeShim.ts")) {
2699
+ return "/@zelune/shim/react-native.js";
2700
+ }
2701
+ const vSuffix = versionTag ? `&t=${encodeURIComponent(versionTag)}` : "";
2702
+ return `/@zelune/module?file=${encodeURIComponent(resolved)}${vSuffix}`;
2703
+ }
2487
2704
  function rewriteSpecifier(specifier, requestedExports) {
2488
2705
  if (specifier === "react" || specifier === "react/jsx-runtime" || specifier === "react/jsx-dev-runtime") {
2489
2706
  return "/@zelune/shim/react.js";
@@ -2497,20 +2714,10 @@ function compileModuleForBrowser(options) {
2497
2714
  if (specifier === "lucide-react" || specifier === "lucide-react-native") {
2498
2715
  return `/@zelune/shim/lucide.js?exports=${encodeURIComponent(requestedExports.join(","))}`;
2499
2716
  }
2500
- if (specifier.startsWith(".")) {
2501
- const candidate = path.resolve(path.dirname(cleanFilePath), specifier);
2502
- const resolved = tryResolveLocalModule(candidate);
2503
- if (resolved) {
2504
- return `/@zelune/module?file=${encodeURIComponent(resolved)}`;
2505
- }
2506
- return `/@zelune/shim/stub.js?pkg=${encodeURIComponent(specifier)}&exports=${encodeURIComponent(
2507
- requestedExports.join(",")
2508
- )}`;
2509
- }
2510
- if (specifier.startsWith("@/") || specifier.startsWith("~/") || tsconfigAliases.some((m) => specifier === m.prefix || specifier.startsWith(m.prefix + "/"))) {
2511
- const resolved = resolveAlias(specifier);
2717
+ if (specifier.startsWith(".") || specifier.startsWith("@/") || specifier.startsWith("~/") || tsconfigAliases.some((m) => specifier === m.prefix || specifier.startsWith(m.prefix + "/"))) {
2718
+ const resolved = resolveLocalOrAliasFile(specifier);
2512
2719
  if (resolved) {
2513
- return `/@zelune/module?file=${encodeURIComponent(resolved)}`;
2720
+ return rewriteResolvedLocalFile(resolved, requestedExports);
2514
2721
  }
2515
2722
  return `/@zelune/shim/stub.js?pkg=${encodeURIComponent(specifier)}&exports=${encodeURIComponent(
2516
2723
  requestedExports.join(",")
@@ -2520,20 +2727,122 @@ function compileModuleForBrowser(options) {
2520
2727
  requestedExports.join(",")
2521
2728
  )}`;
2522
2729
  }
2523
- stripTypeScriptAndTransformJsxAst(ast);
2524
- let hasReactIdentifierInScope = false;
2730
+ const sideEffectImportNodes = /* @__PURE__ */ new WeakSet();
2731
+ for (const stmt of ast.program.body) {
2732
+ if (stmt.type === "ImportDeclaration" && stmt.specifiers.length === 0 && stmt.importKind !== "type") {
2733
+ sideEffectImportNodes.add(stmt);
2734
+ }
2735
+ }
2736
+ stripTypeScriptAndTransformJsxAst(ast, () => {
2737
+ emittedJsx = true;
2738
+ });
2739
+ const hoistedRequireImports = [];
2740
+ let reqCounter = 0;
2741
+ function transformRequireCalls(node) {
2742
+ var _a, _b;
2743
+ if (!node || typeof node !== "object") return node;
2744
+ if (Array.isArray(node)) {
2745
+ for (let i = 0; i < node.length; i++) {
2746
+ if (node[i]) node[i] = transformRequireCalls(node[i]);
2747
+ }
2748
+ return node;
2749
+ }
2750
+ for (const key of Object.keys(node)) {
2751
+ if (key === "loc" || key === "comments" || key === "leadingComments" || key === "trailingComments") {
2752
+ continue;
2753
+ }
2754
+ const val = node[key];
2755
+ if (val && typeof val === "object") {
2756
+ node[key] = transformRequireCalls(val);
2757
+ }
2758
+ }
2759
+ if (node.type === "CallExpression" && ((_a = node.callee) == null ? void 0 : _a.type) === "Identifier" && node.callee.name === "require" && Array.isArray(node.arguments) && node.arguments.length === 1 && ((_b = node.arguments[0]) == null ? void 0 : _b.type) === "StringLiteral") {
2760
+ const rawSpec = node.arguments[0].value;
2761
+ const localResolved = resolveLocalOrAliasFile(rawSpec);
2762
+ if (localResolved && ASSET_EXT_REGEX.test(path.extname(localResolved))) {
2763
+ const assetUrl = `/@zelune/asset?file=${encodeURIComponent(localResolved)}`;
2764
+ return t.objectExpression([
2765
+ t.objectProperty(t.identifier("uri"), t.stringLiteral(assetUrl))
2766
+ ]);
2767
+ }
2768
+ if (ASSET_EXT_REGEX.test(rawSpec)) {
2769
+ return t.objectExpression([
2770
+ t.objectProperty(t.identifier("uri"), t.stringLiteral(""))
2771
+ ]);
2772
+ }
2773
+ const reqIdent = t.identifier(`__zeluneReq_${reqCounter++}`);
2774
+ const rewritten = localResolved ? rewriteResolvedLocalFile(localResolved, []) : rewriteSpecifier(rawSpec, []);
2775
+ hoistedRequireImports.push(
2776
+ t.importDeclaration([t.importNamespaceSpecifier(reqIdent)], t.stringLiteral(rewritten))
2777
+ );
2778
+ return t.logicalExpression(
2779
+ "??",
2780
+ t.optionalMemberExpression(reqIdent, t.identifier("default"), false, true),
2781
+ reqIdent
2782
+ );
2783
+ }
2784
+ return node;
2785
+ }
2786
+ transformRequireCalls(ast.program.body);
2787
+ const runtimeReferencedIds = collectRuntimeReferencedIdentifiers(ast.program.body);
2788
+ const elidedBody = [];
2789
+ for (const stmt of ast.program.body) {
2790
+ if (stmt.type === "ImportDeclaration") {
2791
+ if (sideEffectImportNodes.has(stmt)) {
2792
+ elidedBody.push(stmt);
2793
+ continue;
2794
+ }
2795
+ stmt.specifiers = stmt.specifiers.filter((spec) => runtimeReferencedIds.has(spec.local.name));
2796
+ if (stmt.specifiers.length > 0) {
2797
+ elidedBody.push(stmt);
2798
+ }
2799
+ continue;
2800
+ }
2801
+ if (stmt.type === "ExportNamedDeclaration" && stmt.source && !stmt.declaration && stmt.specifiers.length > 0) {
2802
+ const localTarget = resolveLocalOrAliasFile(stmt.source.value);
2803
+ if (localTarget) {
2804
+ const typeOnlyNames = getLocalTypeOnlyDeclaredNames(localTarget);
2805
+ if (typeOnlyNames.size > 0) {
2806
+ stmt.specifiers = stmt.specifiers.filter((spec) => {
2807
+ if (spec.type !== "ExportSpecifier") return true;
2808
+ return !typeOnlyNames.has(spec.local.name);
2809
+ });
2810
+ if (stmt.specifiers.length === 0) {
2811
+ continue;
2812
+ }
2813
+ }
2814
+ }
2815
+ }
2816
+ elidedBody.push(stmt);
2817
+ }
2818
+ ast.program.body = elidedBody;
2819
+ const namespaceLocals = /* @__PURE__ */ new Set();
2525
2820
  for (const stmt of ast.program.body) {
2526
2821
  if (stmt.type === "ImportDeclaration") {
2527
- const requested = [];
2528
2822
  for (const spec of stmt.specifiers) {
2529
- if (spec.local.name === "React") {
2530
- hasReactIdentifierInScope = true;
2823
+ if (spec.type === "ImportNamespaceSpecifier") {
2824
+ namespaceLocals.add(spec.local.name);
2531
2825
  }
2826
+ }
2827
+ }
2828
+ }
2829
+ const namespaceMemberMap = collectNamespaceMemberAccesses(ast, namespaceLocals);
2830
+ for (const stmt of ast.program.body) {
2831
+ if (stmt.type === "ImportDeclaration") {
2832
+ const requested = [];
2833
+ for (const spec of stmt.specifiers) {
2532
2834
  if (spec.type === "ImportSpecifier") {
2533
2835
  const importedName = spec.imported.type === "Identifier" ? spec.imported.name : spec.imported.value;
2534
2836
  if (importedName && importedName !== "default") {
2535
2837
  requested.push(importedName);
2536
2838
  }
2839
+ } else if (spec.type === "ImportNamespaceSpecifier") {
2840
+ const accessed = namespaceMemberMap.get(spec.local.name);
2841
+ if (accessed) {
2842
+ for (const memberName of accessed) {
2843
+ if (memberName !== "default") requested.push(memberName);
2844
+ }
2845
+ }
2537
2846
  }
2538
2847
  }
2539
2848
  stmt.source.value = rewriteSpecifier(stmt.source.value, requested);
@@ -2542,7 +2851,7 @@ function compileModuleForBrowser(options) {
2542
2851
  if (stmt.type === "ExportNamedDeclaration") {
2543
2852
  for (const spec of stmt.specifiers) {
2544
2853
  if (spec.type === "ExportSpecifier") {
2545
- const localName = spec.local.type === "Identifier" ? spec.local.name : spec.local.value;
2854
+ const localName = spec.local.name;
2546
2855
  const exportedName = spec.exported.type === "Identifier" ? spec.exported.name : spec.exported.value;
2547
2856
  if (localName && localName !== "default") requested.push(localName);
2548
2857
  if (exportedName && exportedName !== "default") requested.push(exportedName);
@@ -2552,10 +2861,13 @@ function compileModuleForBrowser(options) {
2552
2861
  stmt.source.value = rewriteSpecifier(stmt.source.value, requested);
2553
2862
  }
2554
2863
  }
2555
- if (hadJsx && !hasReactIdentifierInScope) {
2864
+ if (hoistedRequireImports.length > 0) {
2865
+ ast.program.body.unshift(...hoistedRequireImports);
2866
+ }
2867
+ if (emittedJsx) {
2556
2868
  ast.program.body.unshift(
2557
2869
  t.importDeclaration(
2558
- [t.importDefaultSpecifier(t.identifier("React"))],
2870
+ [t.importDefaultSpecifier(t.identifier(ZELUNE_JSX_REACT_IDENT))],
2559
2871
  t.stringLiteral("/@zelune/shim/react.js")
2560
2872
  )
2561
2873
  );
@@ -2721,7 +3033,17 @@ const MIME_TYPES = {
2721
3033
  ".jpeg": "image/jpeg",
2722
3034
  ".webp": "image/webp",
2723
3035
  ".gif": "image/gif",
2724
- ".ico": "image/x-icon"
3036
+ ".avif": "image/avif",
3037
+ ".bmp": "image/bmp",
3038
+ ".ico": "image/x-icon",
3039
+ ".ttf": "font/ttf",
3040
+ ".otf": "font/otf",
3041
+ ".woff": "font/woff",
3042
+ ".woff2": "font/woff2",
3043
+ ".mp3": "audio/mpeg",
3044
+ ".wav": "audio/wav",
3045
+ ".mp4": "video/mp4",
3046
+ ".webm": "video/webm"
2725
3047
  };
2726
3048
  const REACT_EXPORTS = [
2727
3049
  "Children",
@@ -2827,6 +3149,240 @@ const REACT_NATIVE_EXPORTS = [
2827
3149
  "Networking",
2828
3150
  "Settings"
2829
3151
  ];
3152
+ const DEFAULT_MOCK_NAV_EXPORTS = [
3153
+ "MockNavigationProvider",
3154
+ "useNavigation",
3155
+ "useRoute",
3156
+ "useFocusEffect",
3157
+ "useIsFocused",
3158
+ "useScrollToTop",
3159
+ "NavigationContainer",
3160
+ "CommonActions",
3161
+ "StackActions",
3162
+ "createNativeStackNavigator",
3163
+ "createStackNavigator",
3164
+ "createBottomTabNavigator",
3165
+ "createDrawerNavigator",
3166
+ "createMaterialTopTabNavigator",
3167
+ "DefaultTheme",
3168
+ "DarkTheme",
3169
+ "ThemeProvider",
3170
+ "useTheme",
3171
+ "useNavigationContainerRef",
3172
+ "useRouter",
3173
+ "router",
3174
+ "useLocalSearchParams",
3175
+ "useGlobalSearchParams",
3176
+ "usePathname",
3177
+ "useSegments",
3178
+ "useRootNavigationState",
3179
+ "Link",
3180
+ "Redirect",
3181
+ "Stack",
3182
+ "Tabs",
3183
+ "Drawer",
3184
+ "Slot",
3185
+ "SplashScreen",
3186
+ "SafeAreaProvider",
3187
+ "SafeAreaView",
3188
+ "useSafeAreaInsets",
3189
+ "useSafeAreaFrame",
3190
+ "SafeAreaInsetsContext",
3191
+ "SafeAreaFrameContext",
3192
+ "withSafeAreaInsets",
3193
+ "initialWindowMetrics",
3194
+ "StatusBar",
3195
+ "createVectorIconComponent",
3196
+ "Ionicons",
3197
+ "Feather",
3198
+ "MaterialIcons",
3199
+ "MaterialCommunityIcons",
3200
+ "FontAwesome",
3201
+ "FontAwesome5",
3202
+ "FontAwesome6",
3203
+ "AntDesign",
3204
+ "Entypo",
3205
+ "EvilIcons",
3206
+ "Foundation",
3207
+ "Octicons",
3208
+ "SimpleLineIcons",
3209
+ "Zocial",
3210
+ "Fontisto",
3211
+ "createIconSet",
3212
+ "createIconSetFromIcoMoon",
3213
+ "createIconSetFromFontello",
3214
+ "LinearGradient",
3215
+ "BlurView",
3216
+ "Image",
3217
+ "ImageBackground",
3218
+ "FlashList",
3219
+ "Svg",
3220
+ "Circle",
3221
+ "Ellipse",
3222
+ "G",
3223
+ "SvgText",
3224
+ "TSpan",
3225
+ "TextPath",
3226
+ "Path",
3227
+ "Polygon",
3228
+ "Polyline",
3229
+ "Line",
3230
+ "Rect",
3231
+ "Use",
3232
+ "SvgImage",
3233
+ "Symbol",
3234
+ "Defs",
3235
+ "RadialGradient",
3236
+ "Stop",
3237
+ "ClipPath",
3238
+ "Pattern",
3239
+ "Mask",
3240
+ "ForeignObject",
3241
+ "SvgXml",
3242
+ "SvgUri",
3243
+ "FadeIn",
3244
+ "FadeInDown",
3245
+ "FadeInUp",
3246
+ "FadeInLeft",
3247
+ "FadeInRight",
3248
+ "FadeOut",
3249
+ "FadeOutDown",
3250
+ "FadeOutUp",
3251
+ "SlideInDown",
3252
+ "SlideInUp",
3253
+ "SlideInLeft",
3254
+ "SlideInRight",
3255
+ "SlideOutDown",
3256
+ "SlideOutUp",
3257
+ "SlideOutLeft",
3258
+ "SlideOutRight",
3259
+ "ZoomIn",
3260
+ "ZoomOut",
3261
+ "Layout",
3262
+ "LinearTransition",
3263
+ "SequencedTransition",
3264
+ "FadingTransition",
3265
+ "useSharedValue",
3266
+ "useAnimatedStyle",
3267
+ "useDerivedValue",
3268
+ "useAnimatedProps",
3269
+ "useAnimatedScrollHandler",
3270
+ "useAnimatedRef",
3271
+ "useAnimatedGestureHandler",
3272
+ "withTiming",
3273
+ "withSpring",
3274
+ "withDelay",
3275
+ "withSequence",
3276
+ "withRepeat",
3277
+ "cancelAnimation",
3278
+ "runOnJS",
3279
+ "runOnUI",
3280
+ "interpolate",
3281
+ "Extrapolation",
3282
+ "Extrapolate",
3283
+ "Easing",
3284
+ "createAnimatedComponent",
3285
+ "Animated",
3286
+ "GestureHandlerRootView",
3287
+ "ScrollView",
3288
+ "FlatList",
3289
+ "TouchableOpacity",
3290
+ "TouchableHighlight",
3291
+ "TouchableWithoutFeedback",
3292
+ "Pressable",
3293
+ "Swipeable",
3294
+ "DrawerLayout",
3295
+ "PanGestureHandler",
3296
+ "TapGestureHandler",
3297
+ "LongPressGestureHandler",
3298
+ "GestureDetector",
3299
+ "Gesture",
3300
+ "State",
3301
+ "Directions",
3302
+ "ImpactFeedbackStyle",
3303
+ "NotificationFeedbackType",
3304
+ "impactAsync",
3305
+ "notificationAsync",
3306
+ "selectionAsync",
3307
+ "Constants",
3308
+ "useFonts",
3309
+ "loadAsync",
3310
+ "isLoaded",
3311
+ "preventAutoHideAsync",
3312
+ "hideAsync",
3313
+ "AsyncStorage",
3314
+ "getItemAsync",
3315
+ "setItemAsync",
3316
+ "deleteItemAsync",
3317
+ "setStringAsync",
3318
+ "getStringAsync",
3319
+ "openURL",
3320
+ "createURL",
3321
+ "create",
3322
+ "useStore",
3323
+ "QueryClient",
3324
+ "QueryClientProvider",
3325
+ "useQueryClient",
3326
+ "useQuery",
3327
+ "useInfiniteQuery",
3328
+ "useMutation",
3329
+ "createSafeChainableProxy",
3330
+ "SAFE_CHAINABLE_PROXY",
3331
+ "z",
3332
+ "string",
3333
+ "number",
3334
+ "boolean",
3335
+ "object",
3336
+ "array",
3337
+ "union",
3338
+ "literal",
3339
+ "record",
3340
+ "tuple",
3341
+ "any",
3342
+ "unknown",
3343
+ "optional",
3344
+ "nullable",
3345
+ "coerce",
3346
+ "zodResolver",
3347
+ "yupResolver",
3348
+ "scale",
3349
+ "verticalScale",
3350
+ "moderateScale",
3351
+ "moderateVerticalScale",
3352
+ "s",
3353
+ "vs",
3354
+ "ms",
3355
+ "mvs",
3356
+ "RFValue",
3357
+ "RFPercentage",
3358
+ "widthPercentageToDP",
3359
+ "heightPercentageToDP",
3360
+ "wp",
3361
+ "hp",
3362
+ "clsx",
3363
+ "cn",
3364
+ "twMerge",
3365
+ "styled",
3366
+ "cssInterop",
3367
+ "remapProps",
3368
+ "tw",
3369
+ "createTw",
3370
+ "useForm",
3371
+ "useFormContext",
3372
+ "FormProvider",
3373
+ "useWatch",
3374
+ "useFieldArray",
3375
+ "Controller",
3376
+ "SAFE_CONTEXT_FALLBACK",
3377
+ "createClient"
3378
+ ];
3379
+ function safeRealpath(targetPath) {
3380
+ try {
3381
+ return fs$1.realpathSync(targetPath);
3382
+ } catch {
3383
+ return path.resolve(targetPath);
3384
+ }
3385
+ }
2830
3386
  function sendJson(res, status, payload) {
2831
3387
  res.statusCode = status;
2832
3388
  res.setHeader("Content-Type", "application/json; charset=utf-8");
@@ -2934,7 +3490,7 @@ function buildUniversalStubModule(requestedNames) {
2934
3490
  ];
2935
3491
  const unique = Array.from(
2936
3492
  new Set(
2937
- requestedNames.map((s) => s.trim()).filter((s) => /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(s) && s !== "default")
3493
+ [...DEFAULT_MOCK_NAV_EXPORTS, ...requestedNames].map((s) => s.trim()).filter((s) => /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(s) && s !== "default")
2938
3494
  )
2939
3495
  );
2940
3496
  for (const name of unique) {
@@ -2966,16 +3522,37 @@ async function resolveConnectedProjectName(workspaceRoot) {
2966
3522
  async function startStudioHttpServer(options) {
2967
3523
  const { packageRoot, targetProjectRoot, workspaceRoot } = options;
2968
3524
  const distDir = path.resolve(packageRoot, "dist");
3525
+ const activeProjectRoot = getActiveProjectRoot(targetProjectRoot);
2969
3526
  const allowedRoots = Array.from(
2970
3527
  /* @__PURE__ */ new Set([
2971
3528
  path.resolve(packageRoot),
3529
+ safeRealpath(packageRoot),
2972
3530
  path.resolve(targetProjectRoot),
2973
- path.resolve(workspaceRoot)
3531
+ safeRealpath(targetProjectRoot),
3532
+ path.resolve(activeProjectRoot),
3533
+ safeRealpath(activeProjectRoot),
3534
+ path.resolve(workspaceRoot),
3535
+ safeRealpath(workspaceRoot)
2974
3536
  ])
2975
3537
  );
2976
- function isPathAllowed(candidatePath) {
2977
- const resolved = path.resolve(candidatePath);
2978
- return allowedRoots.some((root) => resolved === root || resolved.startsWith(root + path.sep));
3538
+ function resolveCandidateFileParam(rawParam) {
3539
+ const clean = rawParam.split("?")[0].trim();
3540
+ if (!clean) return null;
3541
+ const candidate = path.isAbsolute(clean) ? path.resolve(clean) : path.resolve(getActiveProjectRoot(targetProjectRoot), clean.replace(/^[/\\]+/, ""));
3542
+ const lexicallyAllowed = allowedRoots.some(
3543
+ (root) => candidate === root || candidate.startsWith(root + path.sep)
3544
+ );
3545
+ if (!lexicallyAllowed || !fs$1.existsSync(candidate)) {
3546
+ return null;
3547
+ }
3548
+ const real = safeRealpath(candidate);
3549
+ const canonicallyAllowed = allowedRoots.some(
3550
+ (root) => real === root || real.startsWith(root + path.sep)
3551
+ );
3552
+ if (!canonicallyAllowed) {
3553
+ return null;
3554
+ }
3555
+ return real;
2979
3556
  }
2980
3557
  const requestHandler = async (req, res) => {
2981
3558
  const rawUrl = req.url ?? "/";
@@ -3115,34 +3692,36 @@ async function startStudioHttpServer(options) {
3115
3692
  }
3116
3693
  if (pathname === "/@zelune/module") {
3117
3694
  const fileParam = searchParams.get("file") ?? "";
3118
- if (!fileParam || !isPathAllowed(fileParam) || !fs$1.existsSync(fileParam)) {
3119
- res.statusCode = 404;
3120
- return res.end("// Module not found\nexport default {};\n");
3695
+ const versionTag = searchParams.get("t") ?? void 0;
3696
+ const resolvedFile = resolveCandidateFileParam(fileParam);
3697
+ if (!resolvedFile) {
3698
+ return sendJs(res, "// Module not found\nexport default {};\n");
3121
3699
  }
3122
3700
  try {
3123
3701
  const compiled = compileModuleForBrowser({
3124
- filePath: fileParam,
3125
- targetProjectRoot,
3126
- workspaceRoot
3702
+ filePath: resolvedFile,
3703
+ targetProjectRoot: getActiveProjectRoot(targetProjectRoot),
3704
+ workspaceRoot,
3705
+ versionTag
3127
3706
  });
3128
3707
  return sendJs(res, compiled);
3129
3708
  } catch (err) {
3130
3709
  const msg = err instanceof Error ? err.message : String(err);
3131
- res.statusCode = 500;
3132
- return res.end(`throw new Error(${JSON.stringify(msg)});
3710
+ return sendJs(res, `throw new Error(${JSON.stringify(msg)});
3133
3711
  `);
3134
3712
  }
3135
3713
  }
3136
3714
  if (pathname === "/@zelune/asset") {
3137
3715
  const fileParam = searchParams.get("file") ?? "";
3138
- if (!fileParam || !isPathAllowed(fileParam) || !fs$1.existsSync(fileParam)) {
3716
+ const resolvedAsset = resolveCandidateFileParam(fileParam);
3717
+ if (!resolvedAsset) {
3139
3718
  res.statusCode = 404;
3140
3719
  return res.end("Not found");
3141
3720
  }
3142
- const ext = path.extname(fileParam).toLowerCase();
3721
+ const ext = path.extname(resolvedAsset).toLowerCase();
3143
3722
  res.statusCode = 200;
3144
3723
  res.setHeader("Content-Type", MIME_TYPES[ext] ?? "application/octet-stream");
3145
- return fs$1.createReadStream(fileParam).pipe(res);
3724
+ return fs$1.createReadStream(resolvedAsset).pipe(res);
3146
3725
  }
3147
3726
  if (pathname === "/" || pathname === "/index.html") {
3148
3727
  const indexHtmlPath = path.join(distDir, "index.html");
@@ -3153,9 +3732,9 @@ async function startStudioHttpServer(options) {
3153
3732
  const rawHtml = await fs.readFile(indexHtmlPath, "utf-8");
3154
3733
  const tailwindTheme = loadProjectTailwindTheme([targetProjectRoot, workspaceRoot]);
3155
3734
  const discoveredManifest = discoverScreenFilesSync(targetProjectRoot);
3156
- const runtimeScript = `<script>window.__ZELUNE_TAILWIND_THEME__ = ${JSON.stringify(
3157
- tailwindTheme
3158
- )}; window.__ZELUNE_SCREEN_MANIFEST__ = ${JSON.stringify(discoveredManifest)};<\/script>`;
3735
+ const safeThemeJson = JSON.stringify(tailwindTheme).replace(/</g, "\\u003c");
3736
+ const safeManifestJson = JSON.stringify(discoveredManifest).replace(/</g, "\\u003c");
3737
+ const runtimeScript = `<script>window.__ZELUNE_STUDIO_SERVER__ = true; window.__ZELUNE_TAILWIND_THEME__ = ${safeThemeJson}; window.__ZELUNE_SCREEN_MANIFEST__ = ${safeManifestJson};<\/script>`;
3159
3738
  const injectedHtml = rawHtml.replace("<head>", `<head>
3160
3739
  ${runtimeScript}`);
3161
3740
  res.statusCode = 200;
@@ -3449,7 +4028,7 @@ async function handleMcpJsonRpcRequest(request, customWorkspaceRoot) {
3449
4028
  },
3450
4029
  serverInfo: {
3451
4030
  name: "zelune",
3452
- version: "1.6.4"
4031
+ version: "1.6.5"
3453
4032
  }
3454
4033
  }
3455
4034
  };