zelune 1.5.7 → 1.6.1

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/CHANGELOG.md CHANGED
@@ -2,6 +2,33 @@
2
2
 
3
3
  All notable changes to the **Zelune — React Native Visual Canvas & MCP** project are documented in this file.
4
4
 
5
+ ## [1.6.1] - 2026-10-24
6
+
7
+ ### Security
8
+ - **Supply-Chain & Socket.dev Security Remediation (`vite.config.ts`, `bin/cli.mjs`, `mcp/server.ts`, `mcp/server.mjs`, `plugins/viteReactNativeFallbackPlugin.ts`, `package.json`)**:
9
+ - **Static AST Tailwind Config Extraction (No `new Function` / `eval`)**: Replaced `new Function()` dynamic evaluation in `vite.config.ts` with pure `@babel/parser` AST inspection (`parseTailwindConfigSource`) and replaced manual `.env` file loops / `'SECRET'`-keyword heuristics with Vite's official `loadEnv` API, eliminating `Uses eval` and `AI-detected potential security risk` / `code anomaly` flags.
10
+ - **In-Process CLI & Zero `child_process` / `createRequire` (`bin/cli.mjs`, `plugins/viteReactNativeFallbackPlugin.ts`, `vite.config.ts`)**: Removed `node:child_process` (`spawn`) and `node:module` (`createRequire`) across the codebase by launching Vite programmatically via `createServer`, running the MCP server in-process (`mcp/server.mjs`), and resolving package paths with native `import.meta.resolve`.
11
+ - **Zero-Dependency Native Stdio MCP Server & Dependency Tree Pruning (`mcp/server.ts`, `package.json`)**: Replaced `@modelcontextprotocol/sdk` and `tsx` in runtime `dependencies` with a native Node `node:readline` JSON-RPC 2.0 MCP implementation compiled to unminified ESM (`mcp/server.mjs`), pruning **93+ transitive npm packages** (`express`, `hono`, `ajv`, `cross-spawn`, `require-from-string`, etc.).
12
+ - **Vite 6 & `esbuild` CVE Upgrade (`package.json`)**: Upgraded `vite` to `6.4.4` (with `esbuild@0.25.12`) and `@vitejs/plugin-react` to `^4.7.0`, resolving High and Medium CVEs in Vite 5 and `esbuild <= 0.24.2`.
13
+
14
+ ## [1.6.0] - 2026-10-24
15
+
16
+ ### Added
17
+ - **Visual Component & Section Insertion Engine (`src/server/astEngine.ts`, `src/server/apiMiddleware.ts`, `src/canvas/InspectorPanel.tsx`, `src/canvas/CanvasApp.tsx`, `mcp/server.ts`)**:
18
+ - Added `insertElement`, `duplicateElement`, and `deleteElement` AST mutations (`POST /api/insert`, `POST /api/duplicate`, `POST /api/delete`, plus MCP tools `insert_screen_element`, `duplicate_screen_element`, `delete_screen_element`) with full `Cmd+Z` Undo / `Cmd+Shift+Z` Redo history.
19
+ - Added 8 one-click React Native component presets in the Studio Inspector & Top Bar (`+ Add Element`): **Button** (`<TouchableOpacity>` with optional screen navigation flow link), **Section Card** (`<View>` card with title + body), **Row Item** (horizontal `<View>`), **Heading** (`<Text>`), **Paragraph** (`<Text>`), **Text Input** (`<TextInput>`), **Badge Pill** (`<View>` + `<Text>`), and **Divider** (`<View>`).
20
+ - Automatically injects missing `react-native` named imports (`TouchableOpacity`, `TextInput`, `View`, `Text`) into the screen's `.tsx` file and supports inserting **After**, **Before**, or **Inside** any selected element (or directly into the active screen's main container when no element is selected), plus one-click **Clone**, **Move Up/Down**, and **Delete** actions.
21
+
22
+ ## [1.5.8] - 2026-10-24
23
+
24
+ ### Fixed
25
+ - **Universal Forward & Return Navigation Flow Wire Extraction (`src/server/astEngine.ts`)**:
26
+ - Upgraded `discoverScreens` to unwrap TypeScript assertions (`as any`, `as never`, `<any>`, `satisfies`), extract route targets from `TemplateLiteral` (e.g., `` `/dealers/${id}` ``), `ObjectExpression` (`{ pathname, screen, route, name }`), nested React Navigation 2nd-arg `{ screen: '...' }`, `<Link href="...">`, data-driven route arrays (`route`, `screen`, `href`, `pathname`, `id`), `onPress` callback identifiers, and `signOut`/`logout` calls.
27
+ - Added `resolveCandidateToScreenId` to match extracted routes against discovered project screens (exact, path segment, and stem/singular-plural matching) so `edge.toScreen` always matches a valid screen ID in `layout`.
28
+ - Added automatic Return / Back flow wire synthesis (`:return`) for screens calling `router.back()`, `navigation.goBack()`, `navigation.pop()`, or rendering a `Back` header button, plus hub/auth/tab connectivity so all screens have complete forward and return interconnection wires.
29
+ - **2D Multi-Row Grid Wire Routing & Dual-Color (Blue Forward + Green Return/Active) Visibility (`src/canvas/FlowArrowsLayer.tsx`, `src/canvas/CanvasApp.tsx`)**:
30
+ - Updated `FlowArrowsLayer` to render **Blue/Indigo (`#6366F1`) solid wires** for forward flows and **Emerald/Green (`#10B981`) dashed/highlighted wires** for return/back and active screen flows simultaneously, elevated `zIndex: 25` so cross-row wires and `From → To` badges are never hidden behind artboard cards, and added 2D row-aware cubic-Bezier routing with exact `t = 0.5` Bezier midpoint badge placement.
31
+
5
32
  ## [1.5.7] - 2026-10-24
6
33
 
7
34
  ### Added
package/bin/cli.mjs CHANGED
@@ -1,14 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import { spawn } from 'node:child_process';
3
2
  import fs from 'node:fs';
4
- import { createRequire } from 'node:module';
5
3
  import net from 'node:net';
6
4
  import path from 'node:path';
7
5
  import { fileURLToPath, pathToFileURL } from 'node:url';
8
6
 
9
7
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
10
8
  const defaultPackageRoot = path.resolve(__dirname, '..');
11
- const requireFromCli = createRequire(import.meta.url);
12
9
 
13
10
  const SCREEN_DIR_CANDIDATES = ['src/screens', 'screens', 'app', 'src/app'];
14
11
  const IGNORED_SCAN_DIRS = new Set([
@@ -364,25 +361,18 @@ Usage:
364
361
  }
365
362
 
366
363
  const resolvedMobileRoot = findMobileAppRoot(targetProject);
367
- const env = {
368
- ...process.env,
369
- ANTIGRAVITY_WORKSPACE_ROOT: targetProject,
370
- ANTIGRAVITY_TARGET_PROJECT: resolvedMobileRoot,
371
- };
364
+ process.env.ANTIGRAVITY_WORKSPACE_ROOT = targetProject;
365
+ process.env.ANTIGRAVITY_TARGET_PROJECT = resolvedMobileRoot;
372
366
 
373
367
  if (isMcpMode) {
374
- const mcpServerPath = path.join(defaultPackageRoot, 'mcp/server.ts');
375
- const child = spawn('npx', ['tsx', mcpServerPath], {
376
- cwd: defaultPackageRoot,
377
- env,
378
- stdio: 'inherit',
379
- });
380
- child.on('exit', (code) => process.exit(code ?? 0));
368
+ const mcpBundleUrl = pathToFileURL(path.join(defaultPackageRoot, 'mcp/server.mjs')).href;
369
+ const { startMcpServer } = await import(mcpBundleUrl);
370
+ startMcpServer(resolvedMobileRoot);
381
371
  return;
382
372
  }
383
373
 
384
374
  const portFlagIdx = args.indexOf('--port');
385
- let port;
375
+ let portNumber;
386
376
  if (portFlagIdx !== -1 && args[portFlagIdx + 1]) {
387
377
  const parsedPort = Number.parseInt(String(args[portFlagIdx + 1]), 10);
388
378
  if (!Number.isInteger(parsedPort) || parsedPort < 1 || parsedPort > 65535) {
@@ -391,42 +381,32 @@ Usage:
391
381
  );
392
382
  process.exit(1);
393
383
  }
394
- port = String(parsedPort);
384
+ portNumber = parsedPort;
395
385
  } else {
396
- const resolvedPort = await findAvailablePort(5173);
397
- port = String(resolvedPort);
386
+ portNumber = await findAvailablePort(5173);
398
387
  }
399
388
 
400
389
  const shouldOpenBrowser = !args.includes('--no-open');
401
- const viteCliFlags = ['--host', '127.0.0.1', '--port', port];
402
- if (shouldOpenBrowser) {
403
- viteCliFlags.push('--open');
404
- }
405
390
 
406
391
  console.log(`\n🚀 Zelune — React Native Visual Canvas & MCP`);
407
392
  console.log(`📂 Workspace Root: ${targetProject}`);
408
393
  if (resolvedMobileRoot !== targetProject) {
409
394
  console.log(`📱 Mobile App Dir: ${resolvedMobileRoot}`);
410
395
  }
411
- console.log(`🌐 Studio URL: http://127.0.0.1:${port}\n`);
412
-
413
- let child;
414
- try {
415
- const viteBinPath = requireFromCli.resolve('vite/bin/vite.js');
416
- child = spawn(process.execPath, [viteBinPath, ...viteCliFlags], {
417
- cwd: defaultPackageRoot,
418
- env,
419
- stdio: 'inherit',
420
- });
421
- } catch {
422
- child = spawn('npx', ['vite', ...viteCliFlags], {
423
- cwd: defaultPackageRoot,
424
- env,
425
- stdio: 'inherit',
426
- });
427
- }
428
-
429
- child.on('exit', (code) => process.exit(code ?? 0));
396
+ console.log(`🌐 Studio Port: 127.0.0.1:${portNumber}\n`);
397
+
398
+ const { createServer } = await import('vite');
399
+ const server = await createServer({
400
+ root: defaultPackageRoot,
401
+ configFile: path.join(defaultPackageRoot, 'vite.config.ts'),
402
+ server: {
403
+ host: '127.0.0.1',
404
+ port: portNumber,
405
+ open: shouldOpenBrowser,
406
+ },
407
+ });
408
+ await server.listen();
409
+ server.printUrls();
430
410
  }
431
411
 
432
412
  const isDirectExecution =