zelune 1.4.0 → 1.5.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.
- package/CHANGELOG.md +29 -0
- package/README.md +8 -15
- package/bin/cli.mjs +215 -31
- package/mcp/server.ts +57 -1
- package/package.json +1 -1
- package/src/canvas/CanvasApp.tsx +89 -4
- package/src/canvas/ScreenArtboard.tsx +1008 -43
- package/src/server/apiMiddleware.ts +185 -12
- package/src/server/astEngine.ts +428 -19
- package/vite.config.ts +91 -24
package/vite.config.ts
CHANGED
|
@@ -1,46 +1,100 @@
|
|
|
1
1
|
import { defineConfig } from 'vite';
|
|
2
2
|
import react from '@vitejs/plugin-react';
|
|
3
3
|
import fs from 'node:fs';
|
|
4
|
+
import { createRequire } from 'node:module';
|
|
4
5
|
import path from 'node:path';
|
|
5
6
|
import { fileURLToPath } from 'node:url';
|
|
6
7
|
import { viteRnSourceInject } from './plugins/viteRnSourceInject';
|
|
7
8
|
import { viteVirtualScreensPlugin } from './plugins/viteVirtualScreensPlugin';
|
|
8
9
|
import { viteCanvasApiMiddleware } from './src/server/apiMiddleware';
|
|
10
|
+
import { findMobileAppRoot } from './src/server/astEngine';
|
|
9
11
|
|
|
10
12
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
11
|
-
const
|
|
13
|
+
const requireFromZelune = createRequire(import.meta.url);
|
|
14
|
+
|
|
15
|
+
const rawTargetRoot = process.env.ANTIGRAVITY_TARGET_PROJECT
|
|
12
16
|
? path.resolve(process.env.ANTIGRAVITY_TARGET_PROJECT)
|
|
13
17
|
: __dirname;
|
|
14
18
|
|
|
19
|
+
const targetProjectRoot = findMobileAppRoot(rawTargetRoot);
|
|
15
20
|
const mockNavShimPath = path.resolve(__dirname, 'src/runtime/MockNavigationContext.tsx');
|
|
16
21
|
|
|
22
|
+
function resolvePackageRootDir(pkgName: string): string {
|
|
23
|
+
try {
|
|
24
|
+
const pkgJsonPath = requireFromZelune.resolve(`${pkgName}/package.json`);
|
|
25
|
+
return path.dirname(pkgJsonPath);
|
|
26
|
+
} catch {
|
|
27
|
+
return pkgName;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const resolvedReactDir = resolvePackageRootDir('react');
|
|
32
|
+
const resolvedReactDomDir = resolvePackageRootDir('react-dom');
|
|
33
|
+
const resolvedRnWebDir = resolvePackageRootDir('react-native-web');
|
|
34
|
+
const resolvedLucideDir = resolvePackageRootDir('lucide-react');
|
|
35
|
+
|
|
36
|
+
const PROTECTED_CORE_ALIASES = new Set([
|
|
37
|
+
'react',
|
|
38
|
+
'react-dom',
|
|
39
|
+
'react-native',
|
|
40
|
+
'react-native-web',
|
|
41
|
+
'lucide-react',
|
|
42
|
+
'lucide-react-native',
|
|
43
|
+
'@react-navigation/native',
|
|
44
|
+
'expo-router',
|
|
45
|
+
'react-native-safe-area-context',
|
|
46
|
+
'expo-status-bar',
|
|
47
|
+
'__proto__',
|
|
48
|
+
'constructor',
|
|
49
|
+
'prototype',
|
|
50
|
+
]);
|
|
51
|
+
|
|
52
|
+
function stripJsonComments(input: string): string {
|
|
53
|
+
return input.replace(
|
|
54
|
+
/("(?:\\.|[^"\\])*")|\/\*[\s\S]*?\*\/|\/\/.*/g,
|
|
55
|
+
(_match, quotedString?: string) => quotedString ?? ''
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
17
59
|
function resolveTargetProjectPathAliases(projectRoot: string): Record<string, string> {
|
|
60
|
+
const normalizedRoot = path.resolve(projectRoot);
|
|
18
61
|
const aliases: Record<string, string> = {};
|
|
19
62
|
try {
|
|
20
|
-
const tsconfigPath = path.join(
|
|
21
|
-
if (
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
63
|
+
const tsconfigPath = path.join(normalizedRoot, 'tsconfig.json');
|
|
64
|
+
if (fs.existsSync(tsconfigPath)) {
|
|
65
|
+
const raw = fs.readFileSync(tsconfigPath, 'utf-8');
|
|
66
|
+
const cleaned = stripJsonComments(raw);
|
|
67
|
+
const parsed = JSON.parse(cleaned) as {
|
|
68
|
+
compilerOptions?: {
|
|
69
|
+
baseUrl?: string;
|
|
70
|
+
paths?: Record<string, string[]>;
|
|
71
|
+
};
|
|
29
72
|
};
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
73
|
+
const baseUrl = parsed.compilerOptions?.baseUrl ?? '.';
|
|
74
|
+
const paths = parsed.compilerOptions?.paths ?? {};
|
|
75
|
+
for (const [pattern, targets] of Object.entries(paths)) {
|
|
76
|
+
if (!targets || targets.length === 0) continue;
|
|
77
|
+
const cleanKey = pattern.replace(/\/\*$/, '');
|
|
78
|
+
if (!cleanKey || PROTECTED_CORE_ALIASES.has(cleanKey)) continue;
|
|
79
|
+
const cleanTarget = targets[0].replace(/\/\*$/, '');
|
|
80
|
+
const resolvedTarget = path.resolve(normalizedRoot, baseUrl, cleanTarget);
|
|
81
|
+
if (
|
|
82
|
+
resolvedTarget === normalizedRoot ||
|
|
83
|
+
resolvedTarget.startsWith(normalizedRoot + path.sep)
|
|
84
|
+
) {
|
|
85
|
+
aliases[cleanKey] = resolvedTarget;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
38
88
|
}
|
|
39
89
|
} catch {
|
|
40
|
-
//
|
|
41
|
-
const srcDir = path.join(projectRoot, 'src');
|
|
42
|
-
aliases['@'] = fs.existsSync(srcDir) ? srcDir : projectRoot;
|
|
90
|
+
// Ignore malformed tsconfig.json and fall back to standard @ alias below
|
|
43
91
|
}
|
|
92
|
+
|
|
93
|
+
if (!aliases['@']) {
|
|
94
|
+
const srcDir = path.join(normalizedRoot, 'src');
|
|
95
|
+
aliases['@'] = fs.existsSync(srcDir) ? srcDir : normalizedRoot;
|
|
96
|
+
}
|
|
97
|
+
|
|
44
98
|
return aliases;
|
|
45
99
|
}
|
|
46
100
|
|
|
@@ -51,15 +105,26 @@ export default defineConfig({
|
|
|
51
105
|
react(),
|
|
52
106
|
viteCanvasApiMiddleware(targetProjectRoot),
|
|
53
107
|
],
|
|
108
|
+
esbuild: {
|
|
109
|
+
// Ensure .tsx/.ts/.jsx files are transpiled even when zelune is installed inside node_modules/zelune
|
|
110
|
+
include: /\.(tsx|ts|jsx)$/,
|
|
111
|
+
exclude: [],
|
|
112
|
+
loader: 'tsx',
|
|
113
|
+
},
|
|
54
114
|
resolve: {
|
|
115
|
+
dedupe: ['react', 'react-dom', 'react-native-web'],
|
|
55
116
|
alias: {
|
|
56
117
|
...resolveTargetProjectPathAliases(targetProjectRoot),
|
|
57
|
-
|
|
118
|
+
react: resolvedReactDir,
|
|
119
|
+
'react-dom': resolvedReactDomDir,
|
|
120
|
+
'react-native': resolvedRnWebDir,
|
|
121
|
+
'react-native-web': resolvedRnWebDir,
|
|
122
|
+
'lucide-react': resolvedLucideDir,
|
|
123
|
+
'lucide-react-native': resolvedLucideDir,
|
|
58
124
|
'@react-navigation/native': mockNavShimPath,
|
|
59
125
|
'expo-router': mockNavShimPath,
|
|
60
126
|
'react-native-safe-area-context': mockNavShimPath,
|
|
61
127
|
'expo-status-bar': mockNavShimPath,
|
|
62
|
-
'lucide-react-native': 'lucide-react',
|
|
63
128
|
},
|
|
64
129
|
extensions: ['.web.tsx', '.web.ts', '.web.js', '.tsx', '.ts', '.jsx', '.js'],
|
|
65
130
|
},
|
|
@@ -74,8 +139,10 @@ export default defineConfig({
|
|
|
74
139
|
host: '127.0.0.1',
|
|
75
140
|
port: 5173,
|
|
76
141
|
strictPort: false,
|
|
142
|
+
cors: false,
|
|
143
|
+
allowedHosts: ['127.0.0.1', 'localhost', '::1'],
|
|
77
144
|
fs: {
|
|
78
|
-
allow: [__dirname, targetProjectRoot],
|
|
145
|
+
allow: Array.from(new Set([__dirname, rawTargetRoot, targetProjectRoot])),
|
|
79
146
|
},
|
|
80
147
|
},
|
|
81
148
|
});
|