zelune 1.5.2 → 1.5.4
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 +25 -0
- package/bin/cli.mjs +17 -6
- package/index.html +9 -2
- package/package.json +2 -1
- package/plugin.json +1 -1
- package/plugins/viteReactNativeFallbackPlugin.ts +568 -0
- package/plugins/viteVirtualScreensPlugin.ts +139 -8
- package/src/canvas/CanvasApp.tsx +111 -23
- package/src/canvas/FlowArrowsLayer.tsx +5 -5
- package/src/canvas/InspectorPanel.tsx +58 -49
- package/src/canvas/ScreenArtboard.tsx +90 -29
- package/src/main.tsx +70 -1
- package/src/runtime/MockNavigationContext.tsx +1007 -38
- package/src/runtime/reactNativeShim.ts +141 -0
- package/src/screens/ProductDetailScreen.tsx +32 -59
- package/src/server/astEngine.ts +10 -1
- package/src/styles.css +182 -21
- package/vite.config.ts +136 -67
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,31 @@
|
|
|
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.5.4] - 2026-10-23
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **Full React Native API Web Shim (`src/runtime/reactNativeShim.ts`)**: Added a dedicated `'react-native'` ESM wrapper that re-exports all of `react-native-web`, provides a `default` export (`import RN from 'react-native'`), and shims React Native APIs missing from `react-native-web@0.19.13` (`useAnimatedValue`, `PermissionsAndroid`, `ToastAndroid`, `ActionSheetIOS`, `InputAccessoryView`, `DrawerLayoutAndroid`, `TurboModuleRegistry`, `requireNativeComponent`, `codegenNativeComponent`, `PlatformColor`, `DynamicColorIOS`, `DevSettings`, `Systrace`, `Networking`, `Settings`).
|
|
9
|
+
- **Zustand, TanStack React Query & Supabase Client Shims (`src/runtime/MockNavigationContext.tsx`)**: Added built-in web shims for Zustand (`create` supporting both standard and curried TypeScript `create<T>()(...)` invocations, plus `useStore`), TanStack React Query (`useQuery`, `useInfiniteQuery`, `useMutation`, `useQueryClient`, `QueryClient`, `QueryClientProvider`), and Supabase (`createClient` with chainable `.from()`, `.auth`, `.storage`, `.channel()`, `.functions`).
|
|
10
|
+
- **Top-Level Studio Recovery Boundary (`src/main.tsx`)**: Wrapped `<CanvasApp />` in `StudioRootErrorBoundary` so `#root` can never unmount into a blank white screen.
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- **External Project Blank Screen Root-Cause Fixes (`vite.config.ts`, `bin/cli.mjs`, `plugins/viteVirtualScreensPlugin.ts`, `plugins/viteReactNativeFallbackPlugin.ts`, `src/runtime/MockNavigationContext.tsx`)**:
|
|
14
|
+
- **Vite Dependency Scanner Isolation (`vite.config.ts`, `plugins/viteVirtualScreensPlugin.ts`)**: Configured `optimizeDeps: { noDiscovery: true, include: ['react', 'react/jsx-runtime', 'react/jsx-dev-runtime', 'react-dom', 'react-dom/client', 'react-native-web', 'lucide-react'] }` and emitted `/@fs/...` URLs with `/* @vite-ignore */` in dev mode so Vite's startup `esbuild` scanner never crawls external project `node_modules` (which contain Flow syntax, native modules, or duplicate React instances that previously crashed `optimizeDeps` before `src/main.tsx` could mount).
|
|
15
|
+
- **AST-Based Named Import & Re-Export Extraction (`plugins/viteReactNativeFallbackPlugin.ts`)**: Replaced the semicolon-dependent regex in `extractNamedImportsFromImporter` with `@babel/parser` AST traversal (`ImportDeclaration` and `ExportNamedDeclaration`) so semicolon-free (`semi: false`) and multiline files never miss named exports, and switched query parsing in `load(id)` to `URLSearchParams` so Vite's `?import&exports=...` injection never drops synthesized exports.
|
|
16
|
+
- **Callable Default Export Proxy (`src/runtime/MockNavigationContext.tsx`)**: Changed `defaultExportProxy` to wrap a callable React component function (`UniversalDefaultExportComponent`) so default-imported components (`import Ionicons from '@expo/vector-icons/Ionicons'`, `import Svg from 'react-native-svg'`, `import LottieView from 'lottie-react-native'`) render as valid React components without throwing `Element type is invalid: expected a string or class/function but got: object`.
|
|
17
|
+
- **Missing Lucide Icon & Local File Fallbacks (`plugins/viteReactNativeFallbackPlugin.ts`)**: Added automatic fallback icon synthesis for any icon name imported from `lucide-react` or `lucide-react-native` not present in `lucide-react@0.469.0`, trailing-comma-safe `tsconfig.json` alias resolution across `targetProjectRoot` and `workspaceRoot`, and automatic virtual-stub fallback for missing/ungenerated local imports.
|
|
18
|
+
- **Nested Monorepo Workspace & `npm run zelune` Script (`bin/cli.mjs`, `vite.config.ts`)**: Passed both `ANTIGRAVITY_WORKSPACE_ROOT` and `ANTIGRAVITY_TARGET_PROJECT` from `bin/cli.mjs`, enabled `server.fs.strict: false` with canonical `realpathSync` roots in `vite.config.ts`, and added `"zelune": "zelune"` alongside `"canvas": "zelune"` during `zelune init`.
|
|
19
|
+
|
|
20
|
+
## [1.5.3] - 2026-10-23
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
- **Studio Light Mode & Dark Mode Theme Toggle (`index.html`, `src/styles.css`, `src/canvas/CanvasApp.tsx`, `src/canvas/InspectorPanel.tsx`, `src/canvas/ScreenArtboard.tsx`, `src/canvas/FlowArrowsLayer.tsx`)**: Added a studio-wide Light/Dark color-scheme toggle (`Sun` / `Moon` button in the top-right toolbar) using `<meta name="color-scheme">`, `:root:has(> head > meta[name="color-scheme"][content="light"|"dark"])`, `light-dark()` tokens with `@supports` and `@media (prefers-color-scheme: dark)` fallbacks, high-contrast semantic badge tokens (`--studio-badge-indigo-*`, `--studio-badge-emerald-*`), zero-FOUC inline `<head>` script, and cross-tab `storage` event synchronization while isolating device artboard viewports so React Native screens render faithfully.
|
|
24
|
+
- **Universal Expo & React Native Ecosystem Web Shims (`src/runtime/MockNavigationContext.tsx`, `plugins/viteReactNativeFallbackPlugin.ts`)**: Added built-in web shims for `@expo/vector-icons`, `expo-linear-gradient`, `expo-blur`, `expo-image`, `react-native-svg`, `react-native-reanimated`, `react-native-gesture-handler`, `expo-haptics`, `expo-constants`, `expo-font`, `expo-splash-screen`, `expo-secure-store`, `expo-clipboard`, `expo-linking`, `@react-native-async-storage/async-storage`, and `@shopify/flash-list`, plus a dynamic AST-aware fallback plugin (`viteReactNativeFallbackPlugin`) that synthesizes named export stubs for any additional native or unresolved bare packages imported by external screens.
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
- **External Project Blank Screen Fix via Dynamic Per-Screen Isolation & `process.env` / `require` Polyfill (`plugins/viteVirtualScreensPlugin.ts`, `vite.config.ts`, `src/server/astEngine.ts`)**: Replaced static top-level `import *` statements in `virtual:zelune-screens` with per-screen dynamic `import()` React wrappers (`createIsolatedScreenComponent`) so a broken import or top-level error in any individual screen renders a diagnostic card inside that screen's artboard rather than blanking out `#root`. Added automatic `EXPO_PUBLIC_*` `.env` loading, a safe `window.process.env` Proxy (so SDK initializers like `createClient(process.env.EXPO_PUBLIC_SUPABASE_URL, ...)` never throw on load), and a `window.require` polyfill for React Native asset `require('./image.png')` calls.
|
|
28
|
+
- **Double-Click On-Canvas Inline `<Text>` Editing (`src/canvas/ScreenArtboard.tsx`)**: Fixed an async race condition where `fetch('/api/inspect')` resolving ~15ms after the first click of a double-click reset `isEditingInlineText` back to `false` and closed the inline `<textarea>`. Gated `isEditingInlineText` resets strictly on selection identity changes (`${screenId}:${astPath}`), added synchronous DOM text extraction (`resolveTextTargetForDoubleClick`) so double-clicking `<Text>` or a parent button/badge immediately opens the inline editor, and persisted the target's `file`/`astPath`/`line` in `inlineEditTargetRef` for reliable AST commits.
|
|
29
|
+
|
|
5
30
|
## [1.5.2] - 2026-10-21
|
|
6
31
|
|
|
7
32
|
### Changed
|
package/bin/cli.mjs
CHANGED
|
@@ -210,10 +210,20 @@ function addCanvasScriptToPackageJson(dirPath) {
|
|
|
210
210
|
try {
|
|
211
211
|
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'));
|
|
212
212
|
pkg.scripts = pkg.scripts || {};
|
|
213
|
-
if (pkg.name !== 'zelune'
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
213
|
+
if (pkg.name !== 'zelune') {
|
|
214
|
+
let modified = false;
|
|
215
|
+
if (!pkg.scripts.zelune || String(pkg.scripts.zelune).includes('npx')) {
|
|
216
|
+
pkg.scripts.zelune = 'zelune';
|
|
217
|
+
modified = true;
|
|
218
|
+
}
|
|
219
|
+
if (!pkg.scripts.canvas || String(pkg.scripts.canvas).includes('npx')) {
|
|
220
|
+
pkg.scripts.canvas = 'zelune';
|
|
221
|
+
modified = true;
|
|
222
|
+
}
|
|
223
|
+
if (modified) {
|
|
224
|
+
fs.writeFileSync(pkgJsonPath, JSON.stringify(pkg, null, 2) + '\n', 'utf8');
|
|
225
|
+
return true;
|
|
226
|
+
}
|
|
217
227
|
}
|
|
218
228
|
} catch {
|
|
219
229
|
// Ignore malformed package.json
|
|
@@ -342,20 +352,21 @@ Usage:
|
|
|
342
352
|
}
|
|
343
353
|
console.log(` • Screens directory: ${result.screensDir}`);
|
|
344
354
|
if (result.updatedPackageJson) {
|
|
345
|
-
console.log(` • Added "
|
|
355
|
+
console.log(` • Added "zelune": "zelune" script to package.json`);
|
|
346
356
|
}
|
|
347
357
|
console.log(` • Configured MCP server in mcp_config.json`);
|
|
348
358
|
console.log(` • Installed AI skill in .agents/skills/zelune/SKILL.md`);
|
|
349
359
|
if (result.createdDesignMd || result.createdProductMd) {
|
|
350
360
|
console.log(` • Created starter DESIGN.md & PRODUCT.md governance docs`);
|
|
351
361
|
}
|
|
352
|
-
console.log(`\n👉 Run "
|
|
362
|
+
console.log(`\n👉 Run "zelune" (or "npm run zelune") to open your screens in the visual canvas!\n`);
|
|
353
363
|
process.exit(0);
|
|
354
364
|
}
|
|
355
365
|
|
|
356
366
|
const resolvedMobileRoot = findMobileAppRoot(targetProject);
|
|
357
367
|
const env = {
|
|
358
368
|
...process.env,
|
|
369
|
+
ANTIGRAVITY_WORKSPACE_ROOT: targetProject,
|
|
359
370
|
ANTIGRAVITY_TARGET_PROJECT: resolvedMobileRoot,
|
|
360
371
|
};
|
|
361
372
|
|
package/index.html
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
|
-
<html lang="en"
|
|
2
|
+
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<meta name="color-scheme" content="light dark" />
|
|
7
|
+
<script>
|
|
8
|
+
try {
|
|
9
|
+
document.querySelector('meta[name="color-scheme"]').content =
|
|
10
|
+
localStorage.getItem('color-scheme') ?? 'dark';
|
|
11
|
+
} catch {}
|
|
12
|
+
</script>
|
|
6
13
|
<title>Zelune — React Native Visual Canvas & AST Studio</title>
|
|
7
14
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
8
15
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
@@ -11,7 +18,7 @@
|
|
|
11
18
|
rel="stylesheet"
|
|
12
19
|
/>
|
|
13
20
|
</head>
|
|
14
|
-
<body
|
|
21
|
+
<body>
|
|
15
22
|
<div id="root"></div>
|
|
16
23
|
<script type="module" src="/src/main.tsx"></script>
|
|
17
24
|
</body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zelune",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
],
|
|
48
48
|
"scripts": {
|
|
49
49
|
"dev": "vite --host 127.0.0.1 --port 5173",
|
|
50
|
+
"zelune": "node ./bin/cli.mjs",
|
|
50
51
|
"canvas": "node ./bin/cli.mjs",
|
|
51
52
|
"build": "vite build",
|
|
52
53
|
"preview": "vite preview --host 127.0.0.1 --port 4173",
|
package/plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zelune",
|
|
3
3
|
"displayName": "Zelune — React Native Visual Canvas",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.5.4",
|
|
5
5
|
"description": "Zelune MCP & Figma-style multi-screen React Native visual canvas with live surgical AST patching and navigation flow visualization for Google Antigravity.",
|
|
6
6
|
"logo": "assets/logo.svg",
|
|
7
7
|
"suggestedPrompts": [
|