@ibealec/create-zed-bridge 1.0.0 ā 1.0.3
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 +180 -71
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/@zed-controller/react-bridge/dist/index.cjs +2572 -0
- package/templates/@zed-controller/react-bridge/dist/index.cjs.map +1 -0
- package/templates/@zed-controller/react-bridge/dist/index.d.cts +121 -0
- package/templates/@zed-controller/react-bridge/dist/index.d.ts +121 -0
- package/templates/@zed-controller/react-bridge/dist/index.js +2536 -0
- package/templates/@zed-controller/react-bridge/dist/index.js.map +1 -0
- package/templates/@zed-controller/react-bridge/package.json +27 -0
- package/templates/@zed-controller/shared/dist/index.d.ts +226 -0
- package/templates/@zed-controller/shared/dist/index.d.ts.map +1 -0
- package/templates/@zed-controller/shared/dist/index.js +2 -0
- package/templates/@zed-controller/shared/dist/index.js.map +1 -0
- package/templates/@zed-controller/shared/package.json +7 -0
package/dist/index.js
CHANGED
|
@@ -8,6 +8,9 @@ import fs from "fs-extra";
|
|
|
8
8
|
import path from "path";
|
|
9
9
|
import { execSync } from "child_process";
|
|
10
10
|
import Enquirer from "enquirer";
|
|
11
|
+
import { fileURLToPath } from "url";
|
|
12
|
+
var __filename = fileURLToPath(import.meta.url);
|
|
13
|
+
var __dirname = path.dirname(__filename);
|
|
11
14
|
var program = new Command();
|
|
12
15
|
async function detectProject(cwd) {
|
|
13
16
|
const packageJsonPath = path.join(cwd, "package.json");
|
|
@@ -65,18 +68,84 @@ function getInstallCommand(pm, packages, isDev = false) {
|
|
|
65
68
|
}
|
|
66
69
|
}
|
|
67
70
|
async function installDependencies(pm, cwd, spinner) {
|
|
68
|
-
const
|
|
69
|
-
const
|
|
70
|
-
spinner.text = "
|
|
71
|
-
|
|
71
|
+
const templatesDir = path.join(__dirname, "..", "templates");
|
|
72
|
+
const localPkgDir = path.join(cwd, ".zed-controller");
|
|
73
|
+
spinner.text = "Copying @zed-controller packages...";
|
|
74
|
+
await fs.ensureDir(localPkgDir);
|
|
75
|
+
await fs.copy(
|
|
76
|
+
path.join(templatesDir, "@zed-controller", "shared"),
|
|
77
|
+
path.join(localPkgDir, "shared")
|
|
78
|
+
);
|
|
79
|
+
await fs.copy(
|
|
80
|
+
path.join(templatesDir, "@zed-controller", "react-bridge"),
|
|
81
|
+
path.join(localPkgDir, "react-bridge")
|
|
82
|
+
);
|
|
83
|
+
const reactBridgePkgPath = path.join(localPkgDir, "react-bridge", "package.json");
|
|
84
|
+
const reactBridgePkg = await fs.readJson(reactBridgePkgPath);
|
|
85
|
+
reactBridgePkg.dependencies["@zed-controller/shared"] = "file:../shared";
|
|
86
|
+
await fs.writeJson(reactBridgePkgPath, reactBridgePkg, { spaces: 2 });
|
|
87
|
+
const gitignorePath = path.join(cwd, ".gitignore");
|
|
88
|
+
if (fs.existsSync(gitignorePath)) {
|
|
89
|
+
let gitignore = fs.readFileSync(gitignorePath, "utf-8");
|
|
90
|
+
if (!gitignore.includes(".zed-controller")) {
|
|
91
|
+
gitignore += "\n# Zed Controller local packages\n.zed-controller/\n";
|
|
92
|
+
fs.writeFileSync(gitignorePath, gitignore);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
spinner.text = "Installing @zed-controller packages...";
|
|
96
|
+
const zedPkgs = [
|
|
97
|
+
`@zed-controller/shared@file:.zed-controller/shared`,
|
|
98
|
+
`@zed-controller/react-bridge@file:.zed-controller/react-bridge`
|
|
99
|
+
];
|
|
100
|
+
execSync(getInstallCommand(pm, zedPkgs), { cwd, stdio: "pipe" });
|
|
72
101
|
spinner.text = "Installing LocatorJS dependencies...";
|
|
102
|
+
const devDeps = ["@locator/runtime", "@locator/babel-jsx"];
|
|
73
103
|
execSync(getInstallCommand(pm, devDeps, true), { cwd, stdio: "pipe" });
|
|
74
104
|
}
|
|
105
|
+
function ensureModeParameter(content) {
|
|
106
|
+
if (content.includes("{ mode }") || content.includes("{ mode,") || content.includes(", mode }") || content.includes(", mode,")) {
|
|
107
|
+
return content;
|
|
108
|
+
}
|
|
109
|
+
const arrowFnRegex = /defineConfig\s*\(\s*(async\s*)?\(\s*\)\s*=>/;
|
|
110
|
+
if (arrowFnRegex.test(content)) {
|
|
111
|
+
return content.replace(arrowFnRegex, (match, asyncPart) => {
|
|
112
|
+
return `defineConfig(${asyncPart || ""}({ mode }) =>`;
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
const arrowFnWithParamsRegex = /defineConfig\s*\(\s*(async\s*)?\(\s*\{\s*([^}]+)\s*\}\s*\)\s*=>/;
|
|
116
|
+
if (arrowFnWithParamsRegex.test(content)) {
|
|
117
|
+
return content.replace(arrowFnWithParamsRegex, (match, asyncPart, params) => {
|
|
118
|
+
const existingParams = params.trim();
|
|
119
|
+
return `defineConfig(${asyncPart || ""}({ mode, ${existingParams} }) =>`;
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
const objectRegex = /defineConfig\s*\(\s*\{/;
|
|
123
|
+
if (objectRegex.test(content)) {
|
|
124
|
+
content = content.replace(objectRegex, "defineConfig(({ mode }) => ({");
|
|
125
|
+
const lastBrace = content.lastIndexOf("});");
|
|
126
|
+
if (lastBrace !== -1) {
|
|
127
|
+
content = content.slice(0, lastBrace) + "}));";
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return content;
|
|
131
|
+
}
|
|
75
132
|
function modifyViteConfig(configPath) {
|
|
76
133
|
let content = fs.readFileSync(configPath, "utf-8");
|
|
77
134
|
if (content.includes("@locator/babel-jsx")) {
|
|
78
135
|
return { success: true, message: "LocatorJS already configured in vite.config" };
|
|
79
136
|
}
|
|
137
|
+
const lastImportMatch = content.match(/^import .+ from ['"][^'"]+['"];?\s*$/gm);
|
|
138
|
+
if (lastImportMatch) {
|
|
139
|
+
const lastImport = lastImportMatch[lastImportMatch.length - 1];
|
|
140
|
+
content = content.replace(
|
|
141
|
+
lastImport,
|
|
142
|
+
`${lastImport}
|
|
143
|
+
import locatorBabelPlugin from "@locator/babel-jsx";`
|
|
144
|
+
);
|
|
145
|
+
} else {
|
|
146
|
+
content = `import locatorBabelPlugin from "@locator/babel-jsx";
|
|
147
|
+
${content}`;
|
|
148
|
+
}
|
|
80
149
|
const reactPluginRegex = /react\s*\(\s*\{/;
|
|
81
150
|
const reactPluginSimpleRegex = /react\s*\(\s*\)/;
|
|
82
151
|
if (reactPluginRegex.test(content)) {
|
|
@@ -86,20 +155,11 @@ function modifyViteConfig(configPath) {
|
|
|
86
155
|
babel: {
|
|
87
156
|
plugins: [
|
|
88
157
|
// LocatorJS - adds source location data to elements (dev only)
|
|
89
|
-
...(mode === 'development' ? [
|
|
158
|
+
...(mode === 'development' ? [locatorBabelPlugin] : []),
|
|
90
159
|
],
|
|
91
160
|
},`
|
|
92
161
|
);
|
|
93
|
-
|
|
94
|
-
content = content.replace(
|
|
95
|
-
/defineConfig\s*\(\s*\{/,
|
|
96
|
-
"defineConfig(({ mode }) => ({"
|
|
97
|
-
);
|
|
98
|
-
const lastBrace = content.lastIndexOf("});");
|
|
99
|
-
if (lastBrace !== -1) {
|
|
100
|
-
content = content.slice(0, lastBrace) + "}));";
|
|
101
|
-
}
|
|
102
|
-
}
|
|
162
|
+
content = ensureModeParameter(content);
|
|
103
163
|
} else if (reactPluginSimpleRegex.test(content)) {
|
|
104
164
|
content = content.replace(
|
|
105
165
|
reactPluginSimpleRegex,
|
|
@@ -107,21 +167,12 @@ function modifyViteConfig(configPath) {
|
|
|
107
167
|
babel: {
|
|
108
168
|
plugins: [
|
|
109
169
|
// LocatorJS - adds source location data to elements (dev only)
|
|
110
|
-
...(mode === 'development' ? [
|
|
170
|
+
...(mode === 'development' ? [locatorBabelPlugin] : []),
|
|
111
171
|
],
|
|
112
172
|
},
|
|
113
173
|
})`
|
|
114
174
|
);
|
|
115
|
-
|
|
116
|
-
content = content.replace(
|
|
117
|
-
/defineConfig\s*\(\s*\{/,
|
|
118
|
-
"defineConfig(({ mode }) => ({"
|
|
119
|
-
);
|
|
120
|
-
const lastBrace = content.lastIndexOf("});");
|
|
121
|
-
if (lastBrace !== -1) {
|
|
122
|
-
content = content.slice(0, lastBrace) + "}));";
|
|
123
|
-
}
|
|
124
|
-
}
|
|
175
|
+
content = ensureModeParameter(content);
|
|
125
176
|
} else {
|
|
126
177
|
return {
|
|
127
178
|
success: false,
|
|
@@ -140,56 +191,106 @@ VITE_PROJECT_ROOT=${projectRoot}
|
|
|
140
191
|
`;
|
|
141
192
|
fs.writeFileSync(envPath, content);
|
|
142
193
|
}
|
|
143
|
-
function
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
194
|
+
function modifyMainTsx(mainTsxPath) {
|
|
195
|
+
let content = fs.readFileSync(mainTsxPath, "utf-8");
|
|
196
|
+
if (content.includes("ClaudeBridgeProvider")) {
|
|
197
|
+
return { success: true, message: "ClaudeBridgeProvider already configured in main entry file" };
|
|
198
|
+
}
|
|
199
|
+
const lastImportMatch = content.match(/^import .+ from ['"][^'"]+['"];?\s*$/gm);
|
|
200
|
+
if (lastImportMatch) {
|
|
201
|
+
const lastImport = lastImportMatch[lastImportMatch.length - 1];
|
|
202
|
+
content = content.replace(
|
|
203
|
+
lastImport,
|
|
204
|
+
`${lastImport}
|
|
205
|
+
import { ClaudeBridgeProvider } from '@zed-controller/react-bridge';`
|
|
206
|
+
);
|
|
207
|
+
} else {
|
|
208
|
+
return { success: false, message: "Could not find imports in main entry file" };
|
|
209
|
+
}
|
|
210
|
+
const locatorAndEnvCode = `
|
|
211
|
+
// LocatorJS runtime initialization
|
|
153
212
|
if (import.meta.env.DEV) {
|
|
154
213
|
import('@locator/runtime').then((locator) => {
|
|
155
214
|
locator.default({});
|
|
156
215
|
});
|
|
157
216
|
}
|
|
158
217
|
|
|
159
|
-
//
|
|
218
|
+
// Zed Controller environment variables
|
|
160
219
|
const ZED_SERVER_URL = import.meta.env.VITE_ZED_SERVER_URL || 'https://localhost:3000';
|
|
161
220
|
const ZED_TOKEN = import.meta.env.VITE_ZED_TOKEN || '';
|
|
162
221
|
const PROJECT_ROOT = import.meta.env.VITE_PROJECT_ROOT || '';
|
|
163
|
-
|
|
164
|
-
// ============================================
|
|
165
|
-
// Wrap your app with ClaudeBridgeProvider:
|
|
166
|
-
// ============================================
|
|
167
|
-
|
|
168
|
-
// Before:
|
|
169
|
-
// ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
170
|
-
// <React.StrictMode>
|
|
171
|
-
// <App />
|
|
172
|
-
// </React.StrictMode>
|
|
173
|
-
// );
|
|
174
|
-
|
|
175
|
-
// After:
|
|
176
|
-
// ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
177
|
-
// <React.StrictMode>
|
|
178
|
-
// <ClaudeBridgeProvider
|
|
179
|
-
// serverUrl={ZED_SERVER_URL}
|
|
180
|
-
// token={ZED_TOKEN}
|
|
181
|
-
// projectRoot={PROJECT_ROOT}
|
|
182
|
-
// questionShortcut="Meta+Shift+L"
|
|
183
|
-
// enabled={import.meta.env.DEV && !!ZED_TOKEN}
|
|
184
|
-
// onTaskCreated={(taskId) => console.log('[ClaudeBridge] Task created:', taskId)}
|
|
185
|
-
// onTaskCompleted={(taskId) => console.log('[ClaudeBridge] Task completed:', taskId)}
|
|
186
|
-
// onError={(error) => console.error('[ClaudeBridge] Error:', error)}
|
|
187
|
-
// >
|
|
188
|
-
// <App />
|
|
189
|
-
// </ClaudeBridgeProvider>
|
|
190
|
-
// </React.StrictMode>
|
|
191
|
-
// );
|
|
192
222
|
`;
|
|
223
|
+
const importEndRegex = /^import .+ from ['"][^'"]+['"];?\s*\n/gm;
|
|
224
|
+
let lastImportEnd = 0;
|
|
225
|
+
let match;
|
|
226
|
+
while ((match = importEndRegex.exec(content)) !== null) {
|
|
227
|
+
lastImportEnd = match.index + match[0].length;
|
|
228
|
+
}
|
|
229
|
+
if (lastImportEnd > 0) {
|
|
230
|
+
content = content.slice(0, lastImportEnd) + locatorAndEnvCode + content.slice(lastImportEnd);
|
|
231
|
+
}
|
|
232
|
+
const claudeBridgeWrapper = `<ClaudeBridgeProvider
|
|
233
|
+
serverUrl={ZED_SERVER_URL}
|
|
234
|
+
token={ZED_TOKEN}
|
|
235
|
+
projectRoot={PROJECT_ROOT}
|
|
236
|
+
questionShortcut="Meta+Shift+L"
|
|
237
|
+
enabled={import.meta.env.DEV && !!ZED_TOKEN}
|
|
238
|
+
onTaskCreated={(taskId) => console.log('[ClaudeBridge] Task created:', taskId)}
|
|
239
|
+
onTaskCompleted={(taskId) => console.log('[ClaudeBridge] Task completed:', taskId)}
|
|
240
|
+
onError={(error) => console.error('[ClaudeBridge] Error:', error)}
|
|
241
|
+
>`;
|
|
242
|
+
const strictModePatterns = [
|
|
243
|
+
// <React.StrictMode>\n <App />
|
|
244
|
+
/(<React\.StrictMode>)\s*\n(\s*)(<App\s*\/>)/,
|
|
245
|
+
// <StrictMode>\n <App />
|
|
246
|
+
/(<StrictMode>)\s*\n(\s*)(<App\s*\/>)/,
|
|
247
|
+
// <React.StrictMode><App /></React.StrictMode> (inline)
|
|
248
|
+
/(<React\.StrictMode>)(<App\s*\/>)(<\/React\.StrictMode>)/,
|
|
249
|
+
// <StrictMode><App /></StrictMode> (inline)
|
|
250
|
+
/(<StrictMode>)(<App\s*\/>)(<\/StrictMode>)/
|
|
251
|
+
];
|
|
252
|
+
let wrapped = false;
|
|
253
|
+
for (const pattern of strictModePatterns) {
|
|
254
|
+
if (pattern.test(content)) {
|
|
255
|
+
if (pattern.source.includes("\\n")) {
|
|
256
|
+
content = content.replace(pattern, (match2, strictModeOpen, indent, appComponent) => {
|
|
257
|
+
return `${strictModeOpen}
|
|
258
|
+
${indent}${claudeBridgeWrapper}
|
|
259
|
+
${indent} ${appComponent}
|
|
260
|
+
${indent}</ClaudeBridgeProvider>`;
|
|
261
|
+
});
|
|
262
|
+
} else {
|
|
263
|
+
content = content.replace(pattern, (match2, strictModeOpen, appComponent, strictModeClose) => {
|
|
264
|
+
return `${strictModeOpen}
|
|
265
|
+
${claudeBridgeWrapper}
|
|
266
|
+
${appComponent}
|
|
267
|
+
</ClaudeBridgeProvider>
|
|
268
|
+
${strictModeClose}`;
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
wrapped = true;
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
if (!wrapped) {
|
|
276
|
+
const renderAppPattern = /(\.render\s*\(\s*\n?\s*)(<App\s*\/>)/;
|
|
277
|
+
if (renderAppPattern.test(content)) {
|
|
278
|
+
content = content.replace(renderAppPattern, (match2, renderPart, appComponent) => {
|
|
279
|
+
return `${renderPart}${claudeBridgeWrapper}
|
|
280
|
+
${appComponent}
|
|
281
|
+
</ClaudeBridgeProvider>`;
|
|
282
|
+
});
|
|
283
|
+
wrapped = true;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
if (!wrapped) {
|
|
287
|
+
return {
|
|
288
|
+
success: false,
|
|
289
|
+
message: "Could not find App component to wrap. Please add ClaudeBridgeProvider manually."
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
fs.writeFileSync(mainTsxPath, content);
|
|
293
|
+
return { success: true, message: "Main entry file updated with ClaudeBridgeProvider" };
|
|
193
294
|
}
|
|
194
295
|
async function runSetup(options) {
|
|
195
296
|
const cwd = process.cwd();
|
|
@@ -255,16 +356,24 @@ async function runSetup(options) {
|
|
|
255
356
|
spinner.start("Creating .env.local.example...");
|
|
256
357
|
createEnvExample(projectInfo.envExamplePath, serverUrl, projectRoot);
|
|
257
358
|
spinner.succeed("Created .env.local.example");
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
359
|
+
if (projectInfo.mainTsxPath) {
|
|
360
|
+
spinner.start("Configuring main entry file...");
|
|
361
|
+
const result = modifyMainTsx(projectInfo.mainTsxPath);
|
|
362
|
+
if (result.success) {
|
|
363
|
+
spinner.succeed(result.message);
|
|
364
|
+
} else {
|
|
365
|
+
spinner.warn(result.message);
|
|
366
|
+
}
|
|
367
|
+
} else {
|
|
368
|
+
console.log(chalk.yellow("\n\u26A0\uFE0F Could not find main entry file (main.tsx/main.jsx/index.tsx/index.jsx)"));
|
|
369
|
+
console.log(chalk.gray("Please add ClaudeBridgeProvider manually to your entry file."));
|
|
370
|
+
}
|
|
261
371
|
console.log(chalk.bold.green("\n\u2705 Setup Complete!\n"));
|
|
262
372
|
console.log(chalk.white("Next steps:"));
|
|
263
373
|
console.log(chalk.gray(" 1. Copy .env.local.example to .env.local"));
|
|
264
374
|
console.log(chalk.gray(" 2. Get your JWT token from zed-controller server"));
|
|
265
375
|
console.log(chalk.gray(" 3. Update VITE_ZED_TOKEN in .env.local"));
|
|
266
|
-
console.log(chalk.gray(" 4.
|
|
267
|
-
console.log(chalk.gray(" 5. Start your dev server and press Meta+Shift+L to test"));
|
|
376
|
+
console.log(chalk.gray(" 4. Start your dev server and press Meta+Shift+L to test"));
|
|
268
377
|
console.log();
|
|
269
378
|
}
|
|
270
379
|
program.name("@ibealec/create-zed-bridge").description("Setup @zed-controller/react-bridge and LocatorJS in your React project").version("1.0.0").option("-s, --server-url <url>", "Zed Controller server URL").option("-p, --project-root <path>", "Project root path").option("--skip-install", "Skip installing dependencies").action(runSetup);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { execSync } from 'child_process';\nimport Enquirer from 'enquirer';\n\nconst program = new Command();\n\ninterface SetupOptions {\n serverUrl?: string;\n projectRoot?: string;\n skipInstall?: boolean;\n}\n\ninterface ProjectInfo {\n packageManager: 'npm' | 'yarn' | 'pnpm' | 'bun';\n hasVite: boolean;\n hasReact: boolean;\n mainTsxPath: string | null;\n viteConfigPath: string | null;\n envExamplePath: string;\n srcDir: string;\n}\n\nasync function detectProject(cwd: string): Promise<ProjectInfo> {\n const packageJsonPath = path.join(cwd, 'package.json');\n\n if (!fs.existsSync(packageJsonPath)) {\n throw new Error('No package.json found. Please run this command in a React project directory.');\n }\n\n const packageJson = await fs.readJson(packageJsonPath);\n const allDeps = { ...packageJson.dependencies, ...packageJson.devDependencies };\n\n // Detect package manager\n let packageManager: 'npm' | 'yarn' | 'pnpm' | 'bun' = 'npm';\n if (fs.existsSync(path.join(cwd, 'bun.lockb'))) packageManager = 'bun';\n else if (fs.existsSync(path.join(cwd, 'pnpm-lock.yaml'))) packageManager = 'pnpm';\n else if (fs.existsSync(path.join(cwd, 'yarn.lock'))) packageManager = 'yarn';\n\n // Detect Vite\n const hasVite = !!allDeps['vite'];\n\n // Detect React\n const hasReact = !!allDeps['react'];\n\n // Find vite config\n let viteConfigPath: string | null = null;\n const viteConfigNames = ['vite.config.ts', 'vite.config.js', 'vite.config.mts', 'vite.config.mjs'];\n for (const name of viteConfigNames) {\n const fullPath = path.join(cwd, name);\n if (fs.existsSync(fullPath)) {\n viteConfigPath = fullPath;\n break;\n }\n }\n\n // Find main.tsx or main.jsx\n let mainTsxPath: string | null = null;\n const srcDir = path.join(cwd, 'src');\n const mainNames = ['main.tsx', 'main.jsx', 'index.tsx', 'index.jsx'];\n for (const name of mainNames) {\n const fullPath = path.join(srcDir, name);\n if (fs.existsSync(fullPath)) {\n mainTsxPath = fullPath;\n break;\n }\n }\n\n return {\n packageManager,\n hasVite,\n hasReact,\n mainTsxPath,\n viteConfigPath,\n envExamplePath: path.join(cwd, '.env.local.example'),\n srcDir,\n };\n}\n\nfunction getInstallCommand(pm: string, packages: string[], isDev = false): string {\n const devFlag = isDev ? (pm === 'npm' ? '--save-dev' : '-D') : '';\n switch (pm) {\n case 'yarn':\n return `yarn add ${devFlag} ${packages.join(' ')}`;\n case 'pnpm':\n return `pnpm add ${devFlag} ${packages.join(' ')}`;\n case 'bun':\n return `bun add ${devFlag} ${packages.join(' ')}`;\n default:\n return `npm install ${devFlag} ${packages.join(' ')}`;\n }\n}\n\ntype Spinner = ReturnType<typeof ora>;\n\nasync function installDependencies(pm: string, cwd: string, spinner: Spinner): Promise<void> {\n const deps = ['@zed-controller/react-bridge'];\n const devDeps = ['@locator/runtime', '@locator/babel-jsx'];\n\n spinner.text = 'Installing @zed-controller/react-bridge...';\n execSync(getInstallCommand(pm, deps), { cwd, stdio: 'pipe' });\n\n spinner.text = 'Installing LocatorJS dependencies...';\n execSync(getInstallCommand(pm, devDeps, true), { cwd, stdio: 'pipe' });\n}\n\nfunction modifyViteConfig(configPath: string): { success: boolean; message: string } {\n let content = fs.readFileSync(configPath, 'utf-8');\n\n // Check if already configured\n if (content.includes('@locator/babel-jsx')) {\n return { success: true, message: 'LocatorJS already configured in vite.config' };\n }\n\n // Find the react plugin configuration\n const reactPluginRegex = /react\\s*\\(\\s*\\{/;\n const reactPluginSimpleRegex = /react\\s*\\(\\s*\\)/;\n\n if (reactPluginRegex.test(content)) {\n // React plugin has config object - add babel config\n content = content.replace(\n reactPluginRegex,\n `react({\n babel: {\n plugins: [\n // LocatorJS - adds source location data to elements (dev only)\n ...(mode === 'development' ? [require.resolve('@locator/babel-jsx')] : []),\n ],\n },`\n );\n\n // Ensure mode is a parameter in defineConfig\n if (!content.includes('({ mode })') && !content.includes('{ mode }')) {\n content = content.replace(\n /defineConfig\\s*\\(\\s*\\{/,\n 'defineConfig(({ mode }) => ({'\n );\n // Need to close the function properly\n const lastBrace = content.lastIndexOf('});');\n if (lastBrace !== -1) {\n content = content.slice(0, lastBrace) + '}));';\n }\n }\n } else if (reactPluginSimpleRegex.test(content)) {\n // React plugin with no config - add full babel config\n content = content.replace(\n reactPluginSimpleRegex,\n `react({\n babel: {\n plugins: [\n // LocatorJS - adds source location data to elements (dev only)\n ...(mode === 'development' ? [require.resolve('@locator/babel-jsx')] : []),\n ],\n },\n })`\n );\n\n // Ensure mode is a parameter\n if (!content.includes('({ mode })') && !content.includes('{ mode }')) {\n content = content.replace(\n /defineConfig\\s*\\(\\s*\\{/,\n 'defineConfig(({ mode }) => ({'\n );\n const lastBrace = content.lastIndexOf('});');\n if (lastBrace !== -1) {\n content = content.slice(0, lastBrace) + '}));';\n }\n }\n } else {\n return {\n success: false,\n message: 'Could not find react() plugin in vite.config. Please add LocatorJS manually.'\n };\n }\n\n fs.writeFileSync(configPath, content);\n return { success: true, message: 'Vite config updated with LocatorJS' };\n}\n\nfunction createEnvExample(envPath: string, serverUrl: string, projectRoot: string): void {\n const content = `# Zed Controller Integration\n# Get your token by running: npm run token --workspace=server (in zed-controller)\nVITE_ZED_SERVER_URL=${serverUrl}\nVITE_ZED_TOKEN=your-jwt-token-here\nVITE_PROJECT_ROOT=${projectRoot}\n`;\n fs.writeFileSync(envPath, content);\n}\n\nfunction generateMainTsxCode(isTypeScript: boolean): string {\n return `\n// ============================================\n// Zed Controller / React Bridge Setup\n// Add these imports at the top of your file:\n// ============================================\n\nimport { ClaudeBridgeProvider } from '@zed-controller/react-bridge';\n\n// Add LocatorJS runtime initialization (before ReactDOM.render):\nif (import.meta.env.DEV) {\n import('@locator/runtime').then((locator) => {\n locator.default({});\n });\n}\n\n// Environment variables:\nconst ZED_SERVER_URL = import.meta.env.VITE_ZED_SERVER_URL || 'https://localhost:3000';\nconst ZED_TOKEN = import.meta.env.VITE_ZED_TOKEN || '';\nconst PROJECT_ROOT = import.meta.env.VITE_PROJECT_ROOT || '';\n\n// ============================================\n// Wrap your app with ClaudeBridgeProvider:\n// ============================================\n\n// Before:\n// ReactDOM.createRoot(document.getElementById('root')!).render(\n// <React.StrictMode>\n// <App />\n// </React.StrictMode>\n// );\n\n// After:\n// ReactDOM.createRoot(document.getElementById('root')!).render(\n// <React.StrictMode>\n// <ClaudeBridgeProvider\n// serverUrl={ZED_SERVER_URL}\n// token={ZED_TOKEN}\n// projectRoot={PROJECT_ROOT}\n// questionShortcut=\"Meta+Shift+L\"\n// enabled={import.meta.env.DEV && !!ZED_TOKEN}\n// onTaskCreated={(taskId) => console.log('[ClaudeBridge] Task created:', taskId)}\n// onTaskCompleted={(taskId) => console.log('[ClaudeBridge] Task completed:', taskId)}\n// onError={(error) => console.error('[ClaudeBridge] Error:', error)}\n// >\n// <App />\n// </ClaudeBridgeProvider>\n// </React.StrictMode>\n// );\n`;\n}\n\nasync function runSetup(options: SetupOptions): Promise<void> {\n const cwd = process.cwd();\n\n console.log(chalk.bold.cyan('\\nš Zed Controller / React Bridge Setup\\n'));\n\n const spinner = ora('Detecting project...').start();\n\n let projectInfo: ProjectInfo;\n try {\n projectInfo = await detectProject(cwd);\n } catch (error) {\n spinner.fail((error as Error).message);\n process.exit(1);\n }\n\n if (!projectInfo.hasReact) {\n spinner.fail('This does not appear to be a React project. React is required.');\n process.exit(1);\n }\n\n if (!projectInfo.hasVite) {\n spinner.warn('Vite not detected. LocatorJS setup will need to be done manually.');\n }\n\n spinner.succeed(`Detected ${projectInfo.packageManager} project with ${projectInfo.hasVite ? 'Vite + ' : ''}React`);\n\n // Gather configuration\n let serverUrl = options.serverUrl;\n let projectRoot = options.projectRoot;\n\n if (!serverUrl || !projectRoot) {\n const answers = await Enquirer.prompt<{ serverUrl: string; projectRoot: string }>([\n {\n type: 'input',\n name: 'serverUrl',\n message: 'Zed Controller server URL:',\n initial: serverUrl || 'https://localhost:3000',\n skip: !!serverUrl,\n },\n {\n type: 'input',\n name: 'projectRoot',\n message: 'Project root path (absolute):',\n initial: projectRoot || cwd,\n skip: !!projectRoot,\n },\n ]);\n serverUrl = serverUrl || answers.serverUrl;\n projectRoot = projectRoot || answers.projectRoot;\n }\n\n // Install dependencies\n if (!options.skipInstall) {\n spinner.start('Installing dependencies...');\n try {\n await installDependencies(projectInfo.packageManager, cwd, spinner);\n spinner.succeed('Dependencies installed');\n } catch (error) {\n spinner.fail('Failed to install dependencies');\n console.error(chalk.red((error as Error).message));\n process.exit(1);\n }\n }\n\n // Modify Vite config\n if (projectInfo.viteConfigPath) {\n spinner.start('Configuring Vite...');\n const result = modifyViteConfig(projectInfo.viteConfigPath);\n if (result.success) {\n spinner.succeed(result.message);\n } else {\n spinner.warn(result.message);\n }\n }\n\n // Create .env.local.example\n spinner.start('Creating .env.local.example...');\n createEnvExample(projectInfo.envExamplePath, serverUrl!, projectRoot!);\n spinner.succeed('Created .env.local.example');\n\n // Generate main.tsx instructions\n console.log(chalk.bold.yellow('\\nš Manual Setup Required:\\n'));\n console.log(chalk.gray('Add the following to your main entry file (main.tsx or index.tsx):'));\n console.log(chalk.cyan(generateMainTsxCode(projectInfo.mainTsxPath?.endsWith('.tsx') ?? true)));\n\n // Final instructions\n console.log(chalk.bold.green('\\nā
Setup Complete!\\n'));\n console.log(chalk.white('Next steps:'));\n console.log(chalk.gray(' 1. Copy .env.local.example to .env.local'));\n console.log(chalk.gray(' 2. Get your JWT token from zed-controller server'));\n console.log(chalk.gray(' 3. Update VITE_ZED_TOKEN in .env.local'));\n console.log(chalk.gray(' 4. Add ClaudeBridgeProvider wrapper to your main.tsx (see above)'));\n console.log(chalk.gray(' 5. Start your dev server and press Meta+Shift+L to test'));\n console.log();\n}\n\nprogram\n .name('@ibealec/create-zed-bridge')\n .description('Setup @zed-controller/react-bridge and LocatorJS in your React project')\n .version('1.0.0')\n .option('-s, --server-url <url>', 'Zed Controller server URL')\n .option('-p, --project-root <path>', 'Project root path')\n .option('--skip-install', 'Skip installing dependencies')\n .action(runSetup);\n\nprogram.parse();\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { execSync } from 'child_process';\nimport Enquirer from 'enquirer';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nconst program = new Command();\n\ninterface SetupOptions {\n serverUrl?: string;\n projectRoot?: string;\n skipInstall?: boolean;\n}\n\ninterface ProjectInfo {\n packageManager: 'npm' | 'yarn' | 'pnpm' | 'bun';\n hasVite: boolean;\n hasReact: boolean;\n mainTsxPath: string | null;\n viteConfigPath: string | null;\n envExamplePath: string;\n srcDir: string;\n}\n\nasync function detectProject(cwd: string): Promise<ProjectInfo> {\n const packageJsonPath = path.join(cwd, 'package.json');\n\n if (!fs.existsSync(packageJsonPath)) {\n throw new Error('No package.json found. Please run this command in a React project directory.');\n }\n\n const packageJson = await fs.readJson(packageJsonPath);\n const allDeps = { ...packageJson.dependencies, ...packageJson.devDependencies };\n\n // Detect package manager\n let packageManager: 'npm' | 'yarn' | 'pnpm' | 'bun' = 'npm';\n if (fs.existsSync(path.join(cwd, 'bun.lockb'))) packageManager = 'bun';\n else if (fs.existsSync(path.join(cwd, 'pnpm-lock.yaml'))) packageManager = 'pnpm';\n else if (fs.existsSync(path.join(cwd, 'yarn.lock'))) packageManager = 'yarn';\n\n // Detect Vite\n const hasVite = !!allDeps['vite'];\n\n // Detect React\n const hasReact = !!allDeps['react'];\n\n // Find vite config\n let viteConfigPath: string | null = null;\n const viteConfigNames = ['vite.config.ts', 'vite.config.js', 'vite.config.mts', 'vite.config.mjs'];\n for (const name of viteConfigNames) {\n const fullPath = path.join(cwd, name);\n if (fs.existsSync(fullPath)) {\n viteConfigPath = fullPath;\n break;\n }\n }\n\n // Find main.tsx or main.jsx\n let mainTsxPath: string | null = null;\n const srcDir = path.join(cwd, 'src');\n const mainNames = ['main.tsx', 'main.jsx', 'index.tsx', 'index.jsx'];\n for (const name of mainNames) {\n const fullPath = path.join(srcDir, name);\n if (fs.existsSync(fullPath)) {\n mainTsxPath = fullPath;\n break;\n }\n }\n\n return {\n packageManager,\n hasVite,\n hasReact,\n mainTsxPath,\n viteConfigPath,\n envExamplePath: path.join(cwd, '.env.local.example'),\n srcDir,\n };\n}\n\nfunction getInstallCommand(pm: string, packages: string[], isDev = false): string {\n const devFlag = isDev ? (pm === 'npm' ? '--save-dev' : '-D') : '';\n switch (pm) {\n case 'yarn':\n return `yarn add ${devFlag} ${packages.join(' ')}`;\n case 'pnpm':\n return `pnpm add ${devFlag} ${packages.join(' ')}`;\n case 'bun':\n return `bun add ${devFlag} ${packages.join(' ')}`;\n default:\n return `npm install ${devFlag} ${packages.join(' ')}`;\n }\n}\n\ntype Spinner = ReturnType<typeof ora>;\n\nasync function installDependencies(pm: string, cwd: string, spinner: Spinner): Promise<void> {\n // Path to bundled templates (relative to dist/index.js -> ../templates)\n const templatesDir = path.join(__dirname, '..', 'templates');\n\n // Copy packages to a local .zed-controller directory (not directly to node_modules)\n // This allows npm to handle transitive dependencies properly\n const localPkgDir = path.join(cwd, '.zed-controller');\n\n spinner.text = 'Copying @zed-controller packages...';\n await fs.ensureDir(localPkgDir);\n await fs.copy(\n path.join(templatesDir, '@zed-controller', 'shared'),\n path.join(localPkgDir, 'shared')\n );\n await fs.copy(\n path.join(templatesDir, '@zed-controller', 'react-bridge'),\n path.join(localPkgDir, 'react-bridge')\n );\n\n // Update the react-bridge package.json to point to local shared package\n const reactBridgePkgPath = path.join(localPkgDir, 'react-bridge', 'package.json');\n const reactBridgePkg = await fs.readJson(reactBridgePkgPath);\n reactBridgePkg.dependencies['@zed-controller/shared'] = 'file:../shared';\n await fs.writeJson(reactBridgePkgPath, reactBridgePkg, { spaces: 2 });\n\n // Add .zed-controller to .gitignore if not already there\n const gitignorePath = path.join(cwd, '.gitignore');\n if (fs.existsSync(gitignorePath)) {\n let gitignore = fs.readFileSync(gitignorePath, 'utf-8');\n if (!gitignore.includes('.zed-controller')) {\n gitignore += '\\n# Zed Controller local packages\\n.zed-controller/\\n';\n fs.writeFileSync(gitignorePath, gitignore);\n }\n }\n\n // Install @zed-controller packages as file dependencies\n // This lets npm handle transitive dependencies (xterm, html2canvas, etc.)\n spinner.text = 'Installing @zed-controller packages...';\n const zedPkgs = [\n `@zed-controller/shared@file:.zed-controller/shared`,\n `@zed-controller/react-bridge@file:.zed-controller/react-bridge`\n ];\n execSync(getInstallCommand(pm, zedPkgs), { cwd, stdio: 'pipe' });\n\n // Install LocatorJS dev dependencies\n spinner.text = 'Installing LocatorJS dependencies...';\n const devDeps = ['@locator/runtime', '@locator/babel-jsx'];\n execSync(getInstallCommand(pm, devDeps, true), { cwd, stdio: 'pipe' });\n}\n\nfunction ensureModeParameter(content: string): string {\n // Already has mode destructured\n if (content.includes('{ mode }') || content.includes('{ mode,') || content.includes(', mode }') || content.includes(', mode,')) {\n return content;\n }\n\n // Pattern 1: defineConfig(async () => ({ or defineConfig(() => ({\n // Add mode parameter to arrow function\n const arrowFnRegex = /defineConfig\\s*\\(\\s*(async\\s*)?\\(\\s*\\)\\s*=>/;\n if (arrowFnRegex.test(content)) {\n return content.replace(arrowFnRegex, (match, asyncPart) => {\n return `defineConfig(${asyncPart || ''}({ mode }) =>`;\n });\n }\n\n // Pattern 2: defineConfig(async ({ command }) => ({ or similar - add mode to existing params\n const arrowFnWithParamsRegex = /defineConfig\\s*\\(\\s*(async\\s*)?\\(\\s*\\{\\s*([^}]+)\\s*\\}\\s*\\)\\s*=>/;\n if (arrowFnWithParamsRegex.test(content)) {\n return content.replace(arrowFnWithParamsRegex, (match, asyncPart, params) => {\n const existingParams = params.trim();\n return `defineConfig(${asyncPart || ''}({ mode, ${existingParams} }) =>`;\n });\n }\n\n // Pattern 3: defineConfig({ - convert to function form\n const objectRegex = /defineConfig\\s*\\(\\s*\\{/;\n if (objectRegex.test(content)) {\n content = content.replace(objectRegex, 'defineConfig(({ mode }) => ({');\n // Need to close the function properly - find the matching closing\n const lastBrace = content.lastIndexOf('});');\n if (lastBrace !== -1) {\n content = content.slice(0, lastBrace) + '}));';\n }\n }\n\n return content;\n}\n\nfunction modifyViteConfig(configPath: string): { success: boolean; message: string } {\n let content = fs.readFileSync(configPath, 'utf-8');\n\n // Check if already configured\n if (content.includes('@locator/babel-jsx')) {\n return { success: true, message: 'LocatorJS already configured in vite.config' };\n }\n\n // Add import for locator babel plugin at the top (after other imports)\n const lastImportMatch = content.match(/^import .+ from ['\"][^'\"]+['\"];?\\s*$/gm);\n if (lastImportMatch) {\n const lastImport = lastImportMatch[lastImportMatch.length - 1];\n content = content.replace(\n lastImport,\n `${lastImport}\\nimport locatorBabelPlugin from \"@locator/babel-jsx\";`\n );\n } else {\n // No imports found, add at the beginning\n content = `import locatorBabelPlugin from \"@locator/babel-jsx\";\\n${content}`;\n }\n\n // Find the react plugin configuration\n const reactPluginRegex = /react\\s*\\(\\s*\\{/;\n const reactPluginSimpleRegex = /react\\s*\\(\\s*\\)/;\n\n if (reactPluginRegex.test(content)) {\n // React plugin has config object - add babel config\n content = content.replace(\n reactPluginRegex,\n `react({\n babel: {\n plugins: [\n // LocatorJS - adds source location data to elements (dev only)\n ...(mode === 'development' ? [locatorBabelPlugin] : []),\n ],\n },`\n );\n\n // Ensure mode is available in defineConfig\n content = ensureModeParameter(content);\n } else if (reactPluginSimpleRegex.test(content)) {\n // React plugin with no config - add full babel config\n content = content.replace(\n reactPluginSimpleRegex,\n `react({\n babel: {\n plugins: [\n // LocatorJS - adds source location data to elements (dev only)\n ...(mode === 'development' ? [locatorBabelPlugin] : []),\n ],\n },\n })`\n );\n\n // Ensure mode is available in defineConfig\n content = ensureModeParameter(content);\n } else {\n return {\n success: false,\n message: 'Could not find react() plugin in vite.config. Please add LocatorJS manually.'\n };\n }\n\n fs.writeFileSync(configPath, content);\n return { success: true, message: 'Vite config updated with LocatorJS' };\n}\n\nfunction createEnvExample(envPath: string, serverUrl: string, projectRoot: string): void {\n const content = `# Zed Controller Integration\n# Get your token by running: npm run token --workspace=server (in zed-controller)\nVITE_ZED_SERVER_URL=${serverUrl}\nVITE_ZED_TOKEN=your-jwt-token-here\nVITE_PROJECT_ROOT=${projectRoot}\n`;\n fs.writeFileSync(envPath, content);\n}\n\nfunction modifyMainTsx(mainTsxPath: string): { success: boolean; message: string } {\n let content = fs.readFileSync(mainTsxPath, 'utf-8');\n\n // Check if already configured\n if (content.includes('ClaudeBridgeProvider')) {\n return { success: true, message: 'ClaudeBridgeProvider already configured in main entry file' };\n }\n\n // 1. Add import for ClaudeBridgeProvider after the last import\n const lastImportMatch = content.match(/^import .+ from ['\"][^'\"]+['\"];?\\s*$/gm);\n if (lastImportMatch) {\n const lastImport = lastImportMatch[lastImportMatch.length - 1];\n content = content.replace(\n lastImport,\n `${lastImport}\\nimport { ClaudeBridgeProvider } from '@zed-controller/react-bridge';`\n );\n } else {\n return { success: false, message: 'Could not find imports in main entry file' };\n }\n\n // 2. Add LocatorJS runtime init and env variables after imports, before any other code\n const locatorAndEnvCode = `\n// LocatorJS runtime initialization\nif (import.meta.env.DEV) {\n import('@locator/runtime').then((locator) => {\n locator.default({});\n });\n}\n\n// Zed Controller environment variables\nconst ZED_SERVER_URL = import.meta.env.VITE_ZED_SERVER_URL || 'https://localhost:3000';\nconst ZED_TOKEN = import.meta.env.VITE_ZED_TOKEN || '';\nconst PROJECT_ROOT = import.meta.env.VITE_PROJECT_ROOT || '';\n`;\n\n // Find where imports end and code begins - look for first non-import statement\n const importEndRegex = /^import .+ from ['\"][^'\"]+['\"];?\\s*\\n/gm;\n let lastImportEnd = 0;\n let match;\n while ((match = importEndRegex.exec(content)) !== null) {\n lastImportEnd = match.index + match[0].length;\n }\n\n if (lastImportEnd > 0) {\n content = content.slice(0, lastImportEnd) + locatorAndEnvCode + content.slice(lastImportEnd);\n }\n\n // 3. Wrap App with ClaudeBridgeProvider in the render call\n // Handle various patterns:\n // Pattern 1: <React.StrictMode><App /></React.StrictMode>\n // Pattern 2: <StrictMode><App /></StrictMode>\n // Pattern 3: <App /> (no StrictMode)\n\n const claudeBridgeWrapper = `<ClaudeBridgeProvider\n serverUrl={ZED_SERVER_URL}\n token={ZED_TOKEN}\n projectRoot={PROJECT_ROOT}\n questionShortcut=\"Meta+Shift+L\"\n enabled={import.meta.env.DEV && !!ZED_TOKEN}\n onTaskCreated={(taskId) => console.log('[ClaudeBridge] Task created:', taskId)}\n onTaskCompleted={(taskId) => console.log('[ClaudeBridge] Task completed:', taskId)}\n onError={(error) => console.error('[ClaudeBridge] Error:', error)}\n >`;\n\n // Try to find and wrap the App component inside StrictMode\n const strictModePatterns = [\n // <React.StrictMode>\\n <App />\n /(<React\\.StrictMode>)\\s*\\n(\\s*)(<App\\s*\\/>)/,\n // <StrictMode>\\n <App />\n /(<StrictMode>)\\s*\\n(\\s*)(<App\\s*\\/>)/,\n // <React.StrictMode><App /></React.StrictMode> (inline)\n /(<React\\.StrictMode>)(<App\\s*\\/>)(<\\/React\\.StrictMode>)/,\n // <StrictMode><App /></StrictMode> (inline)\n /(<StrictMode>)(<App\\s*\\/>)(<\\/StrictMode>)/,\n ];\n\n let wrapped = false;\n for (const pattern of strictModePatterns) {\n if (pattern.test(content)) {\n if (pattern.source.includes('\\\\n')) {\n // Multiline pattern\n content = content.replace(pattern, (match, strictModeOpen, indent, appComponent) => {\n return `${strictModeOpen}\\n${indent}${claudeBridgeWrapper}\\n${indent} ${appComponent}\\n${indent}</ClaudeBridgeProvider>`;\n });\n } else {\n // Inline pattern\n content = content.replace(pattern, (match, strictModeOpen, appComponent, strictModeClose) => {\n return `${strictModeOpen}\\n ${claudeBridgeWrapper}\\n ${appComponent}\\n </ClaudeBridgeProvider>\\n ${strictModeClose}`;\n });\n }\n wrapped = true;\n break;\n }\n }\n\n // If no StrictMode pattern matched, try to wrap App directly in render\n if (!wrapped) {\n const renderAppPattern = /(\\.render\\s*\\(\\s*\\n?\\s*)(<App\\s*\\/>)/;\n if (renderAppPattern.test(content)) {\n content = content.replace(renderAppPattern, (match, renderPart, appComponent) => {\n return `${renderPart}${claudeBridgeWrapper}\\n ${appComponent}\\n </ClaudeBridgeProvider>`;\n });\n wrapped = true;\n }\n }\n\n if (!wrapped) {\n return {\n success: false,\n message: 'Could not find App component to wrap. Please add ClaudeBridgeProvider manually.'\n };\n }\n\n fs.writeFileSync(mainTsxPath, content);\n return { success: true, message: 'Main entry file updated with ClaudeBridgeProvider' };\n}\n\nasync function runSetup(options: SetupOptions): Promise<void> {\n const cwd = process.cwd();\n\n console.log(chalk.bold.cyan('\\nš Zed Controller / React Bridge Setup\\n'));\n\n const spinner = ora('Detecting project...').start();\n\n let projectInfo: ProjectInfo;\n try {\n projectInfo = await detectProject(cwd);\n } catch (error) {\n spinner.fail((error as Error).message);\n process.exit(1);\n }\n\n if (!projectInfo.hasReact) {\n spinner.fail('This does not appear to be a React project. React is required.');\n process.exit(1);\n }\n\n if (!projectInfo.hasVite) {\n spinner.warn('Vite not detected. LocatorJS setup will need to be done manually.');\n }\n\n spinner.succeed(`Detected ${projectInfo.packageManager} project with ${projectInfo.hasVite ? 'Vite + ' : ''}React`);\n\n // Gather configuration\n let serverUrl = options.serverUrl;\n let projectRoot = options.projectRoot;\n\n if (!serverUrl || !projectRoot) {\n const answers = await Enquirer.prompt<{ serverUrl: string; projectRoot: string }>([\n {\n type: 'input',\n name: 'serverUrl',\n message: 'Zed Controller server URL:',\n initial: serverUrl || 'https://localhost:3000',\n skip: !!serverUrl,\n },\n {\n type: 'input',\n name: 'projectRoot',\n message: 'Project root path (absolute):',\n initial: projectRoot || cwd,\n skip: !!projectRoot,\n },\n ]);\n serverUrl = serverUrl || answers.serverUrl;\n projectRoot = projectRoot || answers.projectRoot;\n }\n\n // Install dependencies\n if (!options.skipInstall) {\n spinner.start('Installing dependencies...');\n try {\n await installDependencies(projectInfo.packageManager, cwd, spinner);\n spinner.succeed('Dependencies installed');\n } catch (error) {\n spinner.fail('Failed to install dependencies');\n console.error(chalk.red((error as Error).message));\n process.exit(1);\n }\n }\n\n // Modify Vite config\n if (projectInfo.viteConfigPath) {\n spinner.start('Configuring Vite...');\n const result = modifyViteConfig(projectInfo.viteConfigPath);\n if (result.success) {\n spinner.succeed(result.message);\n } else {\n spinner.warn(result.message);\n }\n }\n\n // Create .env.local.example\n spinner.start('Creating .env.local.example...');\n createEnvExample(projectInfo.envExamplePath, serverUrl!, projectRoot!);\n spinner.succeed('Created .env.local.example');\n\n // Modify main.tsx to add ClaudeBridgeProvider\n if (projectInfo.mainTsxPath) {\n spinner.start('Configuring main entry file...');\n const result = modifyMainTsx(projectInfo.mainTsxPath);\n if (result.success) {\n spinner.succeed(result.message);\n } else {\n spinner.warn(result.message);\n }\n } else {\n console.log(chalk.yellow('\\nā ļø Could not find main entry file (main.tsx/main.jsx/index.tsx/index.jsx)'));\n console.log(chalk.gray('Please add ClaudeBridgeProvider manually to your entry file.'));\n }\n\n // Final instructions\n console.log(chalk.bold.green('\\nā
Setup Complete!\\n'));\n console.log(chalk.white('Next steps:'));\n console.log(chalk.gray(' 1. Copy .env.local.example to .env.local'));\n console.log(chalk.gray(' 2. Get your JWT token from zed-controller server'));\n console.log(chalk.gray(' 3. Update VITE_ZED_TOKEN in .env.local'));\n console.log(chalk.gray(' 4. Start your dev server and press Meta+Shift+L to test'));\n console.log();\n}\n\nprogram\n .name('@ibealec/create-zed-bridge')\n .description('Setup @zed-controller/react-bridge and LocatorJS in your React project')\n .version('1.0.0')\n .option('-s, --server-url <url>', 'Zed Controller server URL')\n .option('-p, --project-root <path>', 'Project root path')\n .option('--skip-install', 'Skip installing dependencies')\n .action(runSetup);\n\nprogram.parse();\n"],"mappings":"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","names":["match"]}
|