@ibealec/create-zed-bridge 1.0.3 ā 1.0.6
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 +46 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/@zed-controller/react-bridge/dist/index.cjs +50 -20
- package/templates/@zed-controller/react-bridge/dist/index.cjs.map +1 -1
- package/templates/@zed-controller/react-bridge/dist/index.js +50 -20
- package/templates/@zed-controller/react-bridge/dist/index.js.map +1 -1
- package/templates/@zed-controller/react-bridge/package.json +16 -0
- package/templates/@zed-controller/shared/package.json +10 -1
package/dist/index.js
CHANGED
|
@@ -292,6 +292,49 @@ ${indent}</ClaudeBridgeProvider>`;
|
|
|
292
292
|
fs.writeFileSync(mainTsxPath, content);
|
|
293
293
|
return { success: true, message: "Main entry file updated with ClaudeBridgeProvider" };
|
|
294
294
|
}
|
|
295
|
+
async function runUpdate() {
|
|
296
|
+
const cwd = process.cwd();
|
|
297
|
+
console.log(chalk.bold.cyan("\n\u{1F504} Updating @zed-controller packages\n"));
|
|
298
|
+
const spinner = ora("Detecting project...").start();
|
|
299
|
+
const localPkgDir = path.join(cwd, ".zed-controller");
|
|
300
|
+
if (!fs.existsSync(localPkgDir)) {
|
|
301
|
+
spinner.fail("No .zed-controller directory found. Run setup first: npx @ibealec/create-zed-bridge");
|
|
302
|
+
process.exit(1);
|
|
303
|
+
}
|
|
304
|
+
let packageManager = "npm";
|
|
305
|
+
if (fs.existsSync(path.join(cwd, "bun.lockb"))) packageManager = "bun";
|
|
306
|
+
else if (fs.existsSync(path.join(cwd, "pnpm-lock.yaml"))) packageManager = "pnpm";
|
|
307
|
+
else if (fs.existsSync(path.join(cwd, "yarn.lock"))) packageManager = "yarn";
|
|
308
|
+
spinner.succeed(`Detected ${packageManager} project`);
|
|
309
|
+
const templatesDir = path.join(__dirname, "..", "templates");
|
|
310
|
+
spinner.start("Updating @zed-controller/shared...");
|
|
311
|
+
await fs.remove(path.join(localPkgDir, "shared"));
|
|
312
|
+
await fs.copy(
|
|
313
|
+
path.join(templatesDir, "@zed-controller", "shared"),
|
|
314
|
+
path.join(localPkgDir, "shared")
|
|
315
|
+
);
|
|
316
|
+
spinner.succeed("Updated @zed-controller/shared");
|
|
317
|
+
spinner.start("Updating @zed-controller/react-bridge...");
|
|
318
|
+
await fs.remove(path.join(localPkgDir, "react-bridge"));
|
|
319
|
+
await fs.copy(
|
|
320
|
+
path.join(templatesDir, "@zed-controller", "react-bridge"),
|
|
321
|
+
path.join(localPkgDir, "react-bridge")
|
|
322
|
+
);
|
|
323
|
+
const reactBridgePkgPath = path.join(localPkgDir, "react-bridge", "package.json");
|
|
324
|
+
const reactBridgePkg = await fs.readJson(reactBridgePkgPath);
|
|
325
|
+
reactBridgePkg.dependencies["@zed-controller/shared"] = "file:../shared";
|
|
326
|
+
await fs.writeJson(reactBridgePkgPath, reactBridgePkg, { spaces: 2 });
|
|
327
|
+
spinner.succeed("Updated @zed-controller/react-bridge");
|
|
328
|
+
spinner.start("Reinstalling packages...");
|
|
329
|
+
try {
|
|
330
|
+
const installCmd = packageManager === "npm" ? "npm install" : `${packageManager} install`;
|
|
331
|
+
execSync(installCmd, { cwd, stdio: "pipe" });
|
|
332
|
+
spinner.succeed("Packages reinstalled");
|
|
333
|
+
} catch (error) {
|
|
334
|
+
spinner.warn("Could not reinstall automatically. Please run your package manager's install command.");
|
|
335
|
+
}
|
|
336
|
+
console.log(chalk.bold.green("\n\u2705 Update Complete!\n"));
|
|
337
|
+
}
|
|
295
338
|
async function runSetup(options) {
|
|
296
339
|
const cwd = process.cwd();
|
|
297
340
|
console.log(chalk.bold.cyan("\n\u{1F680} Zed Controller / React Bridge Setup\n"));
|
|
@@ -376,6 +419,8 @@ async function runSetup(options) {
|
|
|
376
419
|
console.log(chalk.gray(" 4. Start your dev server and press Meta+Shift+L to test"));
|
|
377
420
|
console.log();
|
|
378
421
|
}
|
|
379
|
-
program.name("@ibealec/create-zed-bridge").description("Setup @zed-controller/react-bridge and LocatorJS in your React project").version("1.0.0")
|
|
422
|
+
program.name("@ibealec/create-zed-bridge").description("Setup @zed-controller/react-bridge and LocatorJS in your React project").version("1.0.0");
|
|
423
|
+
program.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);
|
|
424
|
+
program.command("update").description("Update @zed-controller packages to the latest version").action(runUpdate);
|
|
380
425
|
program.parse();
|
|
381
426
|
//# sourceMappingURL=index.js.map
|
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';\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"]}
|
|
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 runUpdate(): Promise<void> {\n const cwd = process.cwd();\n\n console.log(chalk.bold.cyan('\\nš Updating @zed-controller packages\\n'));\n\n const spinner = ora('Detecting project...').start();\n\n // Check if this is a project with zed-bridge installed\n const localPkgDir = path.join(cwd, '.zed-controller');\n if (!fs.existsSync(localPkgDir)) {\n spinner.fail('No .zed-controller directory found. Run setup first: npx @ibealec/create-zed-bridge');\n process.exit(1);\n }\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 spinner.succeed(`Detected ${packageManager} project`);\n\n // Path to bundled templates\n const templatesDir = path.join(__dirname, '..', 'templates');\n\n // Update packages\n spinner.start('Updating @zed-controller/shared...');\n await fs.remove(path.join(localPkgDir, 'shared'));\n await fs.copy(\n path.join(templatesDir, '@zed-controller', 'shared'),\n path.join(localPkgDir, 'shared')\n );\n spinner.succeed('Updated @zed-controller/shared');\n\n spinner.start('Updating @zed-controller/react-bridge...');\n await fs.remove(path.join(localPkgDir, 'react-bridge'));\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 spinner.succeed('Updated @zed-controller/react-bridge');\n\n // Reinstall to update node_modules\n spinner.start('Reinstalling packages...');\n try {\n const installCmd = packageManager === 'npm' ? 'npm install' : `${packageManager} install`;\n execSync(installCmd, { cwd, stdio: 'pipe' });\n spinner.succeed('Packages reinstalled');\n } catch (error) {\n spinner.warn('Could not reinstall automatically. Please run your package manager\\'s install command.');\n }\n\n console.log(chalk.bold.green('\\nā
Update Complete!\\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 // 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\n// Default command (setup)\nprogram\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\n// Update command\nprogram\n .command('update')\n .description('Update @zed-controller packages to the latest version')\n .action(runUpdate);\n\nprogram.parse();\n"],"mappings":"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","names":["match"]}
|
package/package.json
CHANGED
|
@@ -200,7 +200,7 @@ function captureContext(element) {
|
|
|
200
200
|
selectedText: getSelectedText(),
|
|
201
201
|
selectedElement: {
|
|
202
202
|
tagName: element.tagName.toLowerCase(),
|
|
203
|
-
className: element
|
|
203
|
+
className: getClassNameString(element),
|
|
204
204
|
id: element.id || void 0,
|
|
205
205
|
innerText: truncateText(element.innerText, 200)
|
|
206
206
|
},
|
|
@@ -222,12 +222,22 @@ function getSelectedText() {
|
|
|
222
222
|
return void 0;
|
|
223
223
|
}
|
|
224
224
|
function truncateText(text, maxLength) {
|
|
225
|
+
if (!text) return "";
|
|
225
226
|
const cleaned = text.replace(/\s+/g, " ").trim();
|
|
226
227
|
if (cleaned.length <= maxLength) {
|
|
227
228
|
return cleaned;
|
|
228
229
|
}
|
|
229
230
|
return cleaned.slice(0, maxLength) + "...";
|
|
230
231
|
}
|
|
232
|
+
function getClassNameString(element) {
|
|
233
|
+
if (typeof element.className === "string") {
|
|
234
|
+
return element.className;
|
|
235
|
+
}
|
|
236
|
+
if (element.className && typeof element.className.baseVal === "string") {
|
|
237
|
+
return element.className.baseVal;
|
|
238
|
+
}
|
|
239
|
+
return "";
|
|
240
|
+
}
|
|
231
241
|
function getSourceFile(element) {
|
|
232
242
|
let current = element;
|
|
233
243
|
while (current) {
|
|
@@ -330,10 +340,13 @@ function getDomPath(element) {
|
|
|
330
340
|
let selector = current.tagName.toLowerCase();
|
|
331
341
|
if (current.id) {
|
|
332
342
|
selector += `#${current.id}`;
|
|
333
|
-
} else
|
|
334
|
-
const
|
|
335
|
-
if (
|
|
336
|
-
|
|
343
|
+
} else {
|
|
344
|
+
const classNameStr = getClassNameString(current);
|
|
345
|
+
if (classNameStr) {
|
|
346
|
+
const classes = classNameStr.split(/\s+/).filter((c) => c && !c.startsWith("__")).slice(0, 2).join(".");
|
|
347
|
+
if (classes) {
|
|
348
|
+
selector += `.${classes}`;
|
|
349
|
+
}
|
|
337
350
|
}
|
|
338
351
|
}
|
|
339
352
|
path.unshift(selector);
|
|
@@ -510,10 +523,14 @@ function createHighlightOverlay() {
|
|
|
510
523
|
let labelText = element.tagName.toLowerCase();
|
|
511
524
|
if (element.id) {
|
|
512
525
|
labelText += `#${element.id}`;
|
|
513
|
-
} else
|
|
514
|
-
const
|
|
515
|
-
|
|
516
|
-
|
|
526
|
+
} else {
|
|
527
|
+
const className = element.className;
|
|
528
|
+
const classNameStr = typeof className === "string" ? className : className?.baseVal || "";
|
|
529
|
+
if (classNameStr) {
|
|
530
|
+
const firstClass = classNameStr.split(/\s+/)[0];
|
|
531
|
+
if (firstClass && !firstClass.startsWith("__")) {
|
|
532
|
+
labelText += `.${firstClass}`;
|
|
533
|
+
}
|
|
517
534
|
}
|
|
518
535
|
}
|
|
519
536
|
label.textContent = labelText;
|
|
@@ -1744,26 +1761,39 @@ function TaskStatusToast({
|
|
|
1744
1761
|
return new Promise((resolve) => {
|
|
1745
1762
|
const wsUrl = serverUrl.replace(/^http/, "ws").replace(/\/$/, "");
|
|
1746
1763
|
const ws = new WebSocket(`${wsUrl}/ws/bridge?token=${encodeURIComponent(token)}`);
|
|
1764
|
+
let resolved = false;
|
|
1765
|
+
const cleanup = () => {
|
|
1766
|
+
if (!resolved) {
|
|
1767
|
+
resolved = true;
|
|
1768
|
+
ws.close();
|
|
1769
|
+
resolve();
|
|
1770
|
+
}
|
|
1771
|
+
};
|
|
1747
1772
|
ws.onopen = () => {
|
|
1748
1773
|
ws.send(JSON.stringify({
|
|
1749
1774
|
type: "kill_session",
|
|
1750
1775
|
sessionId
|
|
1751
1776
|
}));
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1777
|
+
};
|
|
1778
|
+
ws.onmessage = (event) => {
|
|
1779
|
+
try {
|
|
1780
|
+
const message = JSON.parse(event.data);
|
|
1781
|
+
if (message.type === "session_killed" || message.type === "error") {
|
|
1782
|
+
cleanup();
|
|
1783
|
+
}
|
|
1784
|
+
} catch {
|
|
1785
|
+
}
|
|
1756
1786
|
};
|
|
1757
1787
|
ws.onerror = () => {
|
|
1758
|
-
|
|
1759
|
-
resolve();
|
|
1788
|
+
cleanup();
|
|
1760
1789
|
};
|
|
1761
|
-
|
|
1762
|
-
if (
|
|
1763
|
-
|
|
1790
|
+
ws.onclose = () => {
|
|
1791
|
+
if (!resolved) {
|
|
1792
|
+
resolved = true;
|
|
1793
|
+
resolve();
|
|
1764
1794
|
}
|
|
1765
|
-
|
|
1766
|
-
|
|
1795
|
+
};
|
|
1796
|
+
setTimeout(cleanup, 3e3);
|
|
1767
1797
|
});
|
|
1768
1798
|
}, [serverUrl, token]);
|
|
1769
1799
|
const handleDismiss = (0, import_react5.useCallback)(async () => {
|