@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 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").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);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ibealec/create-zed-bridge",
3
- "version": "1.0.3",
3
+ "version": "1.0.6",
4
4
  "description": "Setup script for @zed-controller/react-bridge and LocatorJS integration",
5
5
  "type": "module",
6
6
  "bin": {
@@ -200,7 +200,7 @@ function captureContext(element) {
200
200
  selectedText: getSelectedText(),
201
201
  selectedElement: {
202
202
  tagName: element.tagName.toLowerCase(),
203
- className: element.className,
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 if (current.className) {
334
- const classes = current.className.split(/\s+/).filter((c) => c && !c.startsWith("__")).slice(0, 2).join(".");
335
- if (classes) {
336
- selector += `.${classes}`;
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 if (element.className) {
514
- const firstClass = element.className.split(/\s+/)[0];
515
- if (firstClass && !firstClass.startsWith("__")) {
516
- labelText += `.${firstClass}`;
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
- setTimeout(() => {
1753
- ws.close();
1754
- resolve();
1755
- }, 100);
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
- ws.close();
1759
- resolve();
1788
+ cleanup();
1760
1789
  };
1761
- setTimeout(() => {
1762
- if (ws.readyState !== WebSocket.CLOSED) {
1763
- ws.close();
1790
+ ws.onclose = () => {
1791
+ if (!resolved) {
1792
+ resolved = true;
1793
+ resolve();
1764
1794
  }
1765
- resolve();
1766
- }, 2e3);
1795
+ };
1796
+ setTimeout(cleanup, 3e3);
1767
1797
  });
1768
1798
  }, [serverUrl, token]);
1769
1799
  const handleDismiss = (0, import_react5.useCallback)(async () => {