@openbuilder/cli 0.31.11

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.
Files changed (78) hide show
  1. package/README.md +1053 -0
  2. package/bin/openbuilder.js +31 -0
  3. package/dist/chunks/Banner-D4tqKfzA.js +113 -0
  4. package/dist/chunks/Banner-D4tqKfzA.js.map +1 -0
  5. package/dist/chunks/auto-update-Dj3lWPWO.js +350 -0
  6. package/dist/chunks/auto-update-Dj3lWPWO.js.map +1 -0
  7. package/dist/chunks/build-D0qYqIq0.js +116 -0
  8. package/dist/chunks/build-D0qYqIq0.js.map +1 -0
  9. package/dist/chunks/cleanup-qVTsA3tk.js +141 -0
  10. package/dist/chunks/cleanup-qVTsA3tk.js.map +1 -0
  11. package/dist/chunks/cli-error-BjQwvWtK.js +140 -0
  12. package/dist/chunks/cli-error-BjQwvWtK.js.map +1 -0
  13. package/dist/chunks/config-BGP1jZJ4.js +167 -0
  14. package/dist/chunks/config-BGP1jZJ4.js.map +1 -0
  15. package/dist/chunks/config-manager-BkbjtN-H.js +133 -0
  16. package/dist/chunks/config-manager-BkbjtN-H.js.map +1 -0
  17. package/dist/chunks/database-BvAbD4sP.js +68 -0
  18. package/dist/chunks/database-BvAbD4sP.js.map +1 -0
  19. package/dist/chunks/database-setup-BYjIRAmT.js +253 -0
  20. package/dist/chunks/database-setup-BYjIRAmT.js.map +1 -0
  21. package/dist/chunks/exports-ij9sv4UM.js +7793 -0
  22. package/dist/chunks/exports-ij9sv4UM.js.map +1 -0
  23. package/dist/chunks/init-CZoN6soU.js +468 -0
  24. package/dist/chunks/init-CZoN6soU.js.map +1 -0
  25. package/dist/chunks/init-tui-BNzk_7Yx.js +1127 -0
  26. package/dist/chunks/init-tui-BNzk_7Yx.js.map +1 -0
  27. package/dist/chunks/logger-ZpJi7chw.js +38 -0
  28. package/dist/chunks/logger-ZpJi7chw.js.map +1 -0
  29. package/dist/chunks/main-tui-Cq1hLCx-.js +644 -0
  30. package/dist/chunks/main-tui-Cq1hLCx-.js.map +1 -0
  31. package/dist/chunks/manager-CvGX9qqe.js +1161 -0
  32. package/dist/chunks/manager-CvGX9qqe.js.map +1 -0
  33. package/dist/chunks/port-allocator-BRFzgH9b.js +749 -0
  34. package/dist/chunks/port-allocator-BRFzgH9b.js.map +1 -0
  35. package/dist/chunks/process-killer-CaUL7Kpl.js +87 -0
  36. package/dist/chunks/process-killer-CaUL7Kpl.js.map +1 -0
  37. package/dist/chunks/prompts-1QbE_bRr.js +128 -0
  38. package/dist/chunks/prompts-1QbE_bRr.js.map +1 -0
  39. package/dist/chunks/repo-cloner-CpOQjFSo.js +219 -0
  40. package/dist/chunks/repo-cloner-CpOQjFSo.js.map +1 -0
  41. package/dist/chunks/repo-detector-B_oj696o.js +66 -0
  42. package/dist/chunks/repo-detector-B_oj696o.js.map +1 -0
  43. package/dist/chunks/run-D23hg4xy.js +630 -0
  44. package/dist/chunks/run-D23hg4xy.js.map +1 -0
  45. package/dist/chunks/runner-logger-instance-nDWv2h2T.js +899 -0
  46. package/dist/chunks/runner-logger-instance-nDWv2h2T.js.map +1 -0
  47. package/dist/chunks/spinner-BJL9zWAJ.js +53 -0
  48. package/dist/chunks/spinner-BJL9zWAJ.js.map +1 -0
  49. package/dist/chunks/start-BygPCbvw.js +1708 -0
  50. package/dist/chunks/start-BygPCbvw.js.map +1 -0
  51. package/dist/chunks/start-traditional-uoLZXdxm.js +255 -0
  52. package/dist/chunks/start-traditional-uoLZXdxm.js.map +1 -0
  53. package/dist/chunks/status-cS8YwtUx.js +97 -0
  54. package/dist/chunks/status-cS8YwtUx.js.map +1 -0
  55. package/dist/chunks/theme-DhorI2Hb.js +44 -0
  56. package/dist/chunks/theme-DhorI2Hb.js.map +1 -0
  57. package/dist/chunks/upgrade-CT6w0lKp.js +323 -0
  58. package/dist/chunks/upgrade-CT6w0lKp.js.map +1 -0
  59. package/dist/chunks/useBuildState-CdBSu9y_.js +331 -0
  60. package/dist/chunks/useBuildState-CdBSu9y_.js.map +1 -0
  61. package/dist/cli/index.js +694 -0
  62. package/dist/cli/index.js.map +1 -0
  63. package/dist/index.js +14358 -0
  64. package/dist/index.js.map +1 -0
  65. package/dist/instrument.js +64226 -0
  66. package/dist/instrument.js.map +1 -0
  67. package/dist/templates.json +295 -0
  68. package/package.json +98 -0
  69. package/scripts/install-vendor-deps.js +34 -0
  70. package/scripts/install-vendor.js +167 -0
  71. package/scripts/prepare-release.js +71 -0
  72. package/templates/config.template.json +18 -0
  73. package/templates.json +295 -0
  74. package/vendor/ai-sdk-provider-claude-code-LOCAL.tgz +0 -0
  75. package/vendor/sentry-core-LOCAL.tgz +0 -0
  76. package/vendor/sentry-nextjs-LOCAL.tgz +0 -0
  77. package/vendor/sentry-node-LOCAL.tgz +0 -0
  78. package/vendor/sentry-node-core-LOCAL.tgz +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager-CvGX9qqe.js","sources":["../../src/lib/tunnel/auto-install.ts","../../../../packages/agent-core/dist/lib/selection/injector.js","../../src/lib/injection-proxy.ts","../../src/lib/tunnel/manager.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { platform, arch } from 'node:os';\nimport { existsSync, mkdirSync, chmodSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nconst CLOUDFLARED_GITHUB = 'https://github.com/cloudflare/cloudflared/releases/latest/download';\n\n/**\n * Get the local bin directory for cloudflared installation\n */\nfunction getBinDir(): string {\n const homeDir = process.env.HOME || process.env.USERPROFILE || '/tmp';\n const binDir = resolve(homeDir, '.openbuilder', 'bin');\n\n if (!existsSync(binDir)) {\n mkdirSync(binDir, { recursive: true });\n }\n\n return binDir;\n}\n\n/**\n * Detect the appropriate cloudflared binary name for this platform\n */\nfunction getCloudflaredBinaryName(): string {\n const plat = platform();\n const architecture = arch();\n\n if (plat === 'darwin') {\n if (architecture === 'arm64') {\n return 'cloudflared-darwin-arm64.tgz';\n }\n return 'cloudflared-darwin-amd64.tgz';\n } else if (plat === 'linux') {\n if (architecture === 'arm64') {\n return 'cloudflared-linux-arm64';\n }\n return 'cloudflared-linux-amd64';\n } else if (plat === 'win32') {\n return 'cloudflared-windows-amd64.exe';\n }\n\n throw new Error(`Unsupported platform: ${plat} ${architecture}`);\n}\n\n/**\n * Check if cloudflared is already installed (globally or locally)\n */\nfunction checkExistingInstallation(): string | null {\n // Check global installation\n try {\n execSync('cloudflared --version', { stdio: 'ignore' });\n return 'cloudflared';\n } catch {\n // Not installed globally\n }\n\n // Check local installation\n const binDir = getBinDir();\n const localPath = resolve(binDir, 'cloudflared');\n\n if (existsSync(localPath)) {\n return localPath;\n }\n\n return null;\n}\n\n/**\n * Download and install cloudflared binary\n */\nasync function downloadCloudflared(): Promise<string> {\n const binDir = getBinDir();\n const binaryName = getCloudflaredBinaryName();\n const downloadUrl = `${CLOUDFLARED_GITHUB}/${binaryName}`;\n const plat = platform();\n\n console.log(`📦 Downloading cloudflared from ${downloadUrl}...`);\n\n if (plat === 'darwin') {\n // macOS - download and extract tarball\n const tarPath = resolve(binDir, 'cloudflared.tgz');\n const extractDir = resolve(binDir, 'cloudflared-extract');\n\n execSync(`curl -L \"${downloadUrl}\" -o \"${tarPath}\"`, { stdio: 'inherit' });\n\n // Create extraction directory\n if (!existsSync(extractDir)) {\n mkdirSync(extractDir, { recursive: true });\n }\n\n // Extract\n execSync(`tar -xzf \"${tarPath}\" -C \"${extractDir}\"`, { stdio: 'inherit' });\n\n // Find the cloudflared binary in extracted files\n const extractedBinary = resolve(extractDir, 'cloudflared');\n const targetPath = resolve(binDir, 'cloudflared');\n\n // Move to bin directory\n execSync(`mv \"${extractedBinary}\" \"${targetPath}\"`, { stdio: 'inherit' });\n\n // Cleanup\n execSync(`rm -rf \"${tarPath}\" \"${extractDir}\"`, { stdio: 'ignore' });\n\n // Make executable\n chmodSync(targetPath, 0o755);\n\n return targetPath;\n } else if (plat === 'linux') {\n // Linux - download binary directly\n const targetPath = resolve(binDir, 'cloudflared');\n\n execSync(`curl -L \"${downloadUrl}\" -o \"${targetPath}\"`, { stdio: 'inherit' });\n chmodSync(targetPath, 0o755);\n\n return targetPath;\n } else if (plat === 'win32') {\n // Windows - download .exe\n const targetPath = resolve(binDir, 'cloudflared.exe');\n\n execSync(`curl -L \"${downloadUrl}\" -o \"${targetPath}\"`, { stdio: 'inherit' });\n\n return targetPath;\n }\n\n throw new Error(`Unsupported platform: ${plat}`);\n}\n\n/**\n * Ensure cloudflared is installed and return the path to the binary\n */\nexport async function ensureCloudflared(silent: boolean = false): Promise<string> {\n // Check if already installed\n const existing = checkExistingInstallation();\n if (existing) {\n if (!silent) {\n console.log(`✅ cloudflared found: ${existing}`);\n }\n return existing;\n }\n\n if (!silent) {\n console.log('📦 cloudflared not found, installing...');\n }\n\n try {\n const path = await downloadCloudflared();\n if (!silent) {\n console.log(`✅ cloudflared installed to: ${path}`);\n }\n return path;\n } catch (error) {\n console.error('❌ Failed to install cloudflared:', error);\n throw new Error('Failed to install cloudflared. Please install manually: https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/installation/');\n }\n}\n","// src/lib/selection/hmr-proxy-script.ts\nvar HMR_PROXY_SCRIPT = `\n(function() {\n // Only run in iframe context\n if (window === window.parent) {\n return;\n }\n\n // Track if we've initialized\n if (window.__openbuilderHmrProxyInit) {\n return;\n }\n window.__openbuilderHmrProxyInit = true;\n\n // Store original WebSocket constructor\n const OriginalWebSocket = window.WebSocket;\n \n // Track active fake WebSocket connections\n const activeConnections = new Map();\n \n // Dev server port - set by parent via postMessage\n // null means we haven't received config yet\n let devServerPort = null;\n \n // Queue of connections waiting for port config\n const pendingConnections = [];\n\n /**\n * FakeWebSocket - Mimics WebSocket API but uses postMessage\n */\n class FakeWebSocket {\n constructor(url, protocols) {\n this.url = url;\n this.protocols = protocols;\n this.readyState = WebSocket.CONNECTING;\n this.bufferedAmount = 0;\n this.extensions = '';\n this.protocol = Array.isArray(protocols) ? protocols[0] : (protocols || '');\n this.binaryType = 'blob';\n \n // Event handlers\n this.onopen = null;\n this.onclose = null;\n this.onmessage = null;\n this.onerror = null;\n \n // Event listeners\n this._listeners = {\n open: [],\n close: [],\n message: [],\n error: [],\n };\n \n // Generate connection ID\n this._connectionId = 'hmr-' + Math.random().toString(36).substring(2, 11);\n \n // Store in active connections\n activeConnections.set(this._connectionId, this);\n \n // Request connection from parent\n this._requestConnect();\n }\n \n _requestConnect() {\n // Try to get port: first from parent config, then from URL\n let port = devServerPort;\n \n if (port === null) {\n // Try to extract from URL\n try {\n const urlObj = new URL(this.url);\n const urlPort = parseInt(urlObj.port, 10);\n // Only use URL port if it's a valid dev server port (not 80/443)\n if (urlPort && urlPort !== 80 && urlPort !== 443) {\n port = urlPort;\n }\n } catch (e) {}\n }\n \n // If we still don't have a valid port, HMR is disabled\n if (port === null || port === 80 || port === 443) {\n console.warn('[HMR Proxy] Cannot determine dev server port - HMR disabled for remote preview. URL:', this.url);\n // Queue for later in case parent sends config\n pendingConnections.push(this);\n return;\n }\n \n // Send connect request to parent\n window.parent.postMessage({\n type: 'openbuilder:hmr:connect',\n connectionId: this._connectionId,\n port: port,\n protocol: this.protocol,\n }, '*');\n }\n \n send(data) {\n if (this.readyState !== WebSocket.OPEN) {\n throw new DOMException('WebSocket is not open', 'InvalidStateError');\n }\n \n // Forward message to parent\n window.parent.postMessage({\n type: 'openbuilder:hmr:send',\n connectionId: this._connectionId,\n message: typeof data === 'string' ? data : JSON.stringify(data),\n }, '*');\n }\n \n close(code = 1000, reason = '') {\n if (this.readyState === WebSocket.CLOSING || this.readyState === WebSocket.CLOSED) {\n return;\n }\n \n this.readyState = WebSocket.CLOSING;\n \n // Tell parent to close connection\n window.parent.postMessage({\n type: 'openbuilder:hmr:disconnect',\n connectionId: this._connectionId,\n code: code,\n reason: reason,\n }, '*');\n \n // Clean up\n activeConnections.delete(this._connectionId);\n }\n \n addEventListener(type, listener) {\n if (this._listeners[type]) {\n this._listeners[type].push(listener);\n }\n }\n \n removeEventListener(type, listener) {\n if (this._listeners[type]) {\n const idx = this._listeners[type].indexOf(listener);\n if (idx !== -1) {\n this._listeners[type].splice(idx, 1);\n }\n }\n }\n \n dispatchEvent(event) {\n const listeners = this._listeners[event.type] || [];\n for (const listener of listeners) {\n listener.call(this, event);\n }\n \n // Also call on* handler if set\n const handler = this['on' + event.type];\n if (typeof handler === 'function') {\n handler.call(this, event);\n }\n \n return true;\n }\n \n // Called when connection is established (from parent message)\n _onConnected() {\n this.readyState = WebSocket.OPEN;\n \n const event = new Event('open');\n this.dispatchEvent(event);\n }\n \n // Called when message received (from parent message)\n _onMessage(data) {\n const event = new MessageEvent('message', { data });\n this.dispatchEvent(event);\n }\n \n // Called when connection closed (from parent message)\n _onClosed(code, reason) {\n this.readyState = WebSocket.CLOSED;\n activeConnections.delete(this._connectionId);\n \n const event = new CloseEvent('close', { code, reason, wasClean: code === 1000 });\n this.dispatchEvent(event);\n }\n \n // Called when error occurs (from parent message)\n _onError(message) {\n const event = new Event('error');\n this.dispatchEvent(event);\n }\n }\n \n // Add static properties\n FakeWebSocket.CONNECTING = 0;\n FakeWebSocket.OPEN = 1;\n FakeWebSocket.CLOSING = 2;\n FakeWebSocket.CLOSED = 3;\n\n /**\n * Check if this WebSocket connection should be intercepted\n * We intercept Vite HMR connections (protocol 'vite-hmr' or URL pattern)\n */\n function shouldIntercept(url, protocols) {\n // Check for vite-hmr protocol\n if (protocols) {\n const protocolList = Array.isArray(protocols) ? protocols : [protocols];\n if (protocolList.includes('vite-hmr')) {\n return true;\n }\n }\n \n // Check URL patterns for common dev server WebSocket endpoints\n try {\n const urlObj = new URL(url, window.location.href);\n \n // Vite HMR typically connects to localhost or 127.0.0.1\n const isLocalhost = urlObj.hostname === 'localhost' || \n urlObj.hostname === '127.0.0.1' ||\n urlObj.hostname === '0.0.0.0';\n \n // Check for common HMR paths\n const isHmrPath = urlObj.pathname === '/' || \n urlObj.pathname.includes('/__vite') ||\n urlObj.pathname.includes('/ws');\n \n // Common dev server ports\n const isDevPort = [3000, 3001, 5173, 5174, 8080, 8081].includes(parseInt(urlObj.port, 10));\n \n return isLocalhost && (isHmrPath || isDevPort);\n } catch (e) {\n return false;\n }\n }\n\n /**\n * Proxy WebSocket constructor\n */\n const ProxiedWebSocket = function(url, protocols) {\n if (shouldIntercept(url, protocols)) {\n return new FakeWebSocket(url, protocols);\n }\n \n // Let non-HMR connections through (shouldn't happen in proxy mode)\n return new OriginalWebSocket(url, protocols);\n };\n \n // Copy static properties\n ProxiedWebSocket.CONNECTING = WebSocket.CONNECTING;\n ProxiedWebSocket.OPEN = WebSocket.OPEN;\n ProxiedWebSocket.CLOSING = WebSocket.CLOSING;\n ProxiedWebSocket.CLOSED = WebSocket.CLOSED;\n ProxiedWebSocket.prototype = OriginalWebSocket.prototype;\n \n // Override global WebSocket\n window.WebSocket = ProxiedWebSocket;\n \n /**\n * Listen for messages from parent window (HMR events and config)\n */\n window.addEventListener('message', function(event) {\n // Only handle messages from parent\n if (event.source !== window.parent) return;\n \n const { type, connectionId, message, code, reason, error, port } = event.data || {};\n \n if (!type || !type.startsWith('openbuilder:hmr:')) return;\n \n // Handle config message to set dev server port\n if (type === 'openbuilder:hmr:config') {\n if (port && typeof port === 'number') {\n devServerPort = port;\n \n // Process any queued connections\n while (pendingConnections.length > 0) {\n const conn = pendingConnections.shift();\n conn._requestConnect();\n }\n }\n return;\n }\n \n const conn = activeConnections.get(connectionId);\n if (!conn) {\n return;\n }\n \n switch (type) {\n case 'openbuilder:hmr:connected':\n conn._onConnected();\n break;\n \n case 'openbuilder:hmr:message':\n conn._onMessage(message);\n break;\n \n case 'openbuilder:hmr:closed':\n conn._onClosed(code || 1000, reason || '');\n break;\n \n case 'openbuilder:hmr:error':\n conn._onError(error || 'Unknown error');\n break;\n }\n });\n \n // Announce ready to parent\n window.parent.postMessage({ type: 'openbuilder:hmr:ready' }, '*');\n})();\n`;\n\n// src/lib/selection/injector.ts\nvar USE_WS_PROXY = typeof window !== \"undefined\" && window.__OPENBUILDER_USE_WS_PROXY === true;\nvar SELECTION_SCRIPT = `\n(function() {\n\n // Selection state - DORMANT by default\n let isInspectorActive = false;\n let inspectorStyle = null;\n let highlightedElement = null;\n let highlightOverlay = null;\n let mouseHandler = null;\n let clickHandler = null;\n\n function getProxyPrefix() {\n try {\n var parts = window.location.pathname.split('/').filter(Boolean);\n var projectsIndex = parts.indexOf('projects');\n if (projectsIndex === -1) {\n return null;\n }\n\n var projectId = parts[projectsIndex + 1];\n if (!projectId) {\n return null;\n }\n\n return '/api/projects/' + projectId + '/proxy?path=';\n } catch (error) {\n console.warn('\\u26A0\\uFE0F [OpenBuilder CSS] Unable to derive proxy prefix:', error);\n return null;\n }\n }\n\n var proxyPrefix = getProxyPrefix();\n\n function rewriteStylesheetHref(link) {\n if (!proxyPrefix || !link) {\n return false;\n }\n\n var href = link.getAttribute('href');\n if (!href) {\n return false;\n }\n\n var trimmed = href.trim();\n\n if (\n trimmed.indexOf('proxy?path=') !== -1 ||\n trimmed.indexOf('http://') === 0 ||\n trimmed.indexOf('https://') === 0 ||\n trimmed.indexOf('//') === 0 ||\n trimmed.indexOf('data:') === 0\n ) {\n return false;\n }\n\n if (trimmed.charAt(0) === '/') {\n var proxiedHref = proxyPrefix + encodeURIComponent(trimmed);\n if (link.getAttribute('href') !== proxiedHref) {\n link.setAttribute('href', proxiedHref);\n console.log('\\u{1F3A8} [OpenBuilder CSS] rewrote stylesheet href to proxy:', proxiedHref);\n return true;\n }\n }\n\n return false;\n }\n\n // Debug helper: track when stylesheets are added/loaded inside the iframe\n function monitorStylesheets() {\n const loggedLinks = new WeakSet();\n const loggedStyles = new WeakSet();\n\n const logLink = (link, phase) => {\n if (!link) return;\n const href = link.getAttribute('href') || '(no href)';\n console.log('\\u{1F3A8} [OpenBuilder CSS]', phase + ' stylesheet:', href);\n };\n\n const logStyle = (style, phase) => {\n if (!style) return;\n const sample = (style.textContent || '')\n .replace(/s+/g, ' ')\n .trim()\n .slice(0, 140);\n console.log('\\u{1F3A8} [OpenBuilder CSS]', phase + ' inline style', sample);\n };\n\n const attachLinkListeners = (link, phase) => {\n if (!link || loggedLinks.has(link)) return;\n loggedLinks.add(link);\n const rewritten = rewriteStylesheetHref(link);\n const phaseLabel = rewritten ? phase + ' (rewritten)' : phase;\n logLink(link, phaseLabel);\n\n link.addEventListener(\n 'load',\n () => {\n rewriteStylesheetHref(link);\n logLink(link, 'loaded');\n },\n { once: true }\n );\n\n link.addEventListener(\n 'error',\n () => {\n rewriteStylesheetHref(link);\n logLink(link, 'error loading');\n },\n { once: true }\n );\n };\n\n const recordStyleElement = (style, phase) => {\n if (!style || loggedStyles.has(style)) return;\n loggedStyles.add(style);\n logStyle(style, phase);\n };\n\n // Observe new link/style nodes appended to the document\n const observer = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n mutation.addedNodes.forEach((node) => {\n if (!(node instanceof HTMLElement)) return;\n\n if (node.tagName === 'LINK' && (node.getAttribute('rel') || '').includes('stylesheet')) {\n attachLinkListeners(node, 'added');\n }\n\n if (node.tagName === 'STYLE') {\n recordStyleElement(node, 'added');\n }\n });\n });\n });\n\n try {\n const head = document.head || document.documentElement;\n if (head) {\n observer.observe(head, { childList: true, subtree: true });\n }\n } catch (e) {\n console.warn('\\u26A0\\uFE0F [OpenBuilder CSS] Failed to observe stylesheet mutations:', e);\n }\n\n // Log existing stylesheet/link elements when script runs\n document\n .querySelectorAll('link[rel~=\"stylesheet\"], style')\n .forEach((node) => {\n if (node.tagName === 'LINK') {\n attachLinkListeners(node, 'existing');\n } else if (node.tagName === 'STYLE') {\n recordStyleElement(node, 'existing');\n }\n });\n\n // Capture late load events (when link is in DOM before listener added)\n document.addEventListener(\n 'load',\n (event) => {\n const target = event.target;\n if (\n target instanceof HTMLLinkElement &&\n (target.getAttribute('rel') || '').includes('stylesheet')\n ) {\n attachLinkListeners(target, 'load event');\n }\n },\n true\n );\n }\n\n monitorStylesheets();\n\n // Create highlight overlay\n function createHighlightOverlay() {\n if (highlightOverlay) return highlightOverlay;\n\n const overlay = document.createElement('div');\n overlay.id = '__openbuilder-highlight';\n overlay.style.cssText = \\`\n position: absolute;\n pointer-events: none;\n border: 2px solid #7553FF;\n background: rgba(117, 83, 255, 0.1);\n z-index: 999999;\n transition: all 0.1s ease;\n box-shadow: 0 0 0 1px rgba(117, 83, 255, 0.3), 0 0 20px rgba(117, 83, 255, 0.4);\n \\`;\n document.body.appendChild(overlay);\n highlightOverlay = overlay;\n return overlay;\n }\n\n // Remove highlight overlay\n function removeHighlightOverlay() {\n if (highlightOverlay) {\n highlightOverlay.remove();\n highlightOverlay = null;\n }\n }\n\n // Highlight element on hover\n function highlightElement(element) {\n if (!element || !isInspectorActive) {\n removeHighlightOverlay();\n return;\n }\n\n const rect = element.getBoundingClientRect();\n const overlay = createHighlightOverlay();\n\n overlay.style.left = rect.left + window.scrollX + 'px';\n overlay.style.top = rect.top + window.scrollY + 'px';\n overlay.style.width = rect.width + 'px';\n overlay.style.height = rect.height + 'px';\n\n highlightedElement = element;\n }\n\n // Generate unique CSS selector for element\n function generateSelector(element) {\n // Strategy 1: data-testid (best)\n const testId = element.getAttribute('data-testid');\n if (testId) {\n return \\`[data-testid=\"\\${testId}\"]\\`;\n }\n\n // Strategy 2: ID (good)\n if (element.id) {\n return \\`#\\${element.id}\\`;\n }\n\n // Strategy 3: Class + tag (ok) - but skip classes with colons (Tailwind responsive)\n const classes = Array.from(element.classList)\n .filter(c => !c.match(/^(hover:|focus:|active:|group-|animate-|transition-)/))\n .filter(c => !c.includes(':')) // Skip Tailwind responsive classes\n .slice(0, 3) // Limit to first 3 classes\n .join('.');\n\n if (classes) {\n const tagName = element.tagName.toLowerCase();\n\n try {\n // Check if unique enough\n const selector = \\`\\${tagName}.\\${classes}\\`;\n const matches = document.querySelectorAll(selector);\n\n if (matches.length === 1) {\n return selector;\n }\n\n // Add nth-child if multiple matches\n const parent = element.parentElement;\n if (parent) {\n const siblings = Array.from(parent.children);\n const index = siblings.indexOf(element) + 1;\n return \\`\\${selector}:nth-child(\\${index})\\`;\n }\n\n return selector;\n } catch (err) {\n console.warn('Invalid selector, falling back to path:', err);\n }\n }\n\n // Strategy 4: Full path (fallback)\n return getFullPath(element);\n }\n\n // Get full CSS path to element\n function getFullPath(element) {\n const path = [];\n let current = element;\n\n while (current && current !== document.body) {\n let selector = current.tagName.toLowerCase();\n\n if (current.id) {\n selector += \\`#\\${current.id}\\`;\n path.unshift(selector);\n break;\n }\n\n const parent = current.parentElement;\n if (parent) {\n const siblings = Array.from(parent.children).filter(\n child => child.tagName === current.tagName\n );\n\n if (siblings.length > 1) {\n const index = siblings.indexOf(current) + 1;\n selector += \\`:nth-of-type(\\${index})\\`;\n }\n }\n\n path.unshift(selector);\n current = current.parentElement;\n }\n\n return path.join(' > ');\n }\n\n // Capture element data and click position\n function captureElementData(element, clickEvent) {\n const rect = element.getBoundingClientRect();\n\n return {\n selector: generateSelector(element),\n tagName: element.tagName.toLowerCase(),\n className: element.className,\n id: element.id,\n textContent: element.textContent?.trim().slice(0, 100),\n innerHTML: element.innerHTML?.slice(0, 200),\n attributes: Array.from(element.attributes).reduce((acc, attr) => {\n acc[attr.name] = attr.value;\n return acc;\n }, {}),\n boundingRect: {\n top: rect.top,\n left: rect.left,\n width: rect.width,\n height: rect.height,\n },\n clickPosition: {\n x: clickEvent.clientX,\n y: clickEvent.clientY,\n },\n computedStyles: {\n backgroundColor: window.getComputedStyle(element).backgroundColor,\n color: window.getComputedStyle(element).color,\n fontSize: window.getComputedStyle(element).fontSize,\n fontFamily: window.getComputedStyle(element).fontFamily,\n }\n };\n }\n\n // Mouse move handler (hover preview)\n function handleMouseMove(e) {\n if (!isInspectorActive) return;\n\n const element = e.target;\n if (element && element !== highlightedElement) {\n highlightElement(element);\n }\n }\n\n // Click handler (select element)\n function handleClick(e) {\n console.log('\\u{1F5B1}\\uFE0F Click detected, selection mode:', isInspectorActive);\n\n if (!isInspectorActive) return;\n\n e.preventDefault();\n e.stopPropagation();\n\n const element = e.target;\n const data = captureElementData(element, e);\n\n console.log('\\u{1F3AF} Element captured:', data);\n console.log(' Click position:', data.clickPosition);\n console.log('\\u{1F4E4} Sending postMessage to parent...');\n\n // Send to parent window\n window.parent.postMessage({\n type: 'openbuilder:element-selected',\n data,\n }, '*');\n\n console.log('\\u2705 Message sent to parent');\n\n // Disable selection mode after selection\n setInspectorActive(false);\n }\n\n // Activate/deactivate inspector (DORMANT PATTERN)\n function setInspectorActive(active) {\n isInspectorActive = active;\n\n if (active) {\n // Add inspector styles ONLY when activated\n if (!inspectorStyle) {\n inspectorStyle = document.createElement('style');\n inspectorStyle.textContent = \\`\n .inspector-active * {\n cursor: crosshair !important;\n }\n .inspector-highlight {\n outline: 2px solid #7553FF !important;\n outline-offset: -2px !important;\n background-color: rgba(117, 83, 255, 0.1) !important;\n }\n \\`;\n document.head.appendChild(inspectorStyle);\n }\n\n document.body.classList.add('inspector-active');\n\n // Add event listeners ONLY when activated\n if (!mouseHandler) {\n mouseHandler = handleMouseMove;\n clickHandler = handleClick;\n document.addEventListener('mousemove', mouseHandler, true);\n document.addEventListener('click', clickHandler, true);\n console.log('\\u2705 Inspector event listeners attached');\n }\n } else {\n document.body.classList.remove('inspector-active');\n\n // Remove highlight\n if (highlightedElement) {\n highlightedElement = null;\n }\n removeHighlightOverlay();\n\n // Remove event listeners when deactivated\n if (mouseHandler) {\n document.removeEventListener('mousemove', mouseHandler, true);\n document.removeEventListener('click', clickHandler, true);\n mouseHandler = null;\n clickHandler = null;\n console.log('\\u{1F9F9} Inspector event listeners removed');\n }\n\n // Remove styles\n if (inspectorStyle) {\n inspectorStyle.remove();\n inspectorStyle = null;\n }\n }\n\n }\n\n // Listen for activation/deactivation from parent\n window.addEventListener('message', (e) => {\n if (e.data.type === 'openbuilder:toggle-selection-mode') {\n setInspectorActive(e.data.enabled);\n }\n });\n\n // Announce ready to parent\n window.parent.postMessage({ type: 'openbuilder:ready' }, '*');\n})();\n`;\nfunction injectSelectionScript(iframe, options) {\n try {\n const iframeWindow = iframe.contentWindow;\n if (!iframeWindow) {\n console.error(\"\\u274C Cannot access iframe window\");\n return false;\n }\n const iframeDoc = iframeWindow.document;\n if (!iframeDoc) {\n console.error(\"\\u274C Cannot access iframe document\");\n return false;\n }\n if (iframeDoc.getElementById(\"__openbuilder-selection-script\")) {\n console.log(\"\\u26A0\\uFE0F Selection script already injected\");\n return true;\n }\n if (options?.enableHmrProxy) {\n if (!iframeDoc.getElementById(\"__openbuilder-hmr-proxy-script\")) {\n const hmrScript = iframeDoc.createElement(\"script\");\n hmrScript.id = \"__openbuilder-hmr-proxy-script\";\n hmrScript.textContent = HMR_PROXY_SCRIPT;\n if (iframeDoc.head) {\n iframeDoc.head.insertBefore(hmrScript, iframeDoc.head.firstChild);\n } else if (iframeDoc.body) {\n iframeDoc.body.insertBefore(hmrScript, iframeDoc.body.firstChild);\n }\n console.log(\"\\u2705 HMR proxy script injected into iframe\");\n }\n }\n const script = iframeDoc.createElement(\"script\");\n script.id = \"__openbuilder-selection-script\";\n script.textContent = SELECTION_SCRIPT;\n iframeDoc.body.appendChild(script);\n console.log(\"\\u2705 Selection script injected into iframe\");\n return true;\n } catch (error) {\n console.error(\"\\u274C Failed to inject selection script:\", error);\n return false;\n }\n}\nfunction toggleSelectionMode(iframe, enabled) {\n const iframeWindow = iframe.contentWindow;\n if (!iframeWindow) {\n console.error(\"\\u274C Cannot access iframe window\");\n return;\n }\n iframeWindow.postMessage({\n type: \"openbuilder:toggle-selection-mode\",\n enabled\n }, \"*\");\n}\nexport {\n HMR_PROXY_SCRIPT,\n SELECTION_SCRIPT,\n injectSelectionScript,\n toggleSelectionMode\n};\n//# sourceMappingURL=injector.js.map","/**\n * Injection Proxy for Remote Runner Support\n * \n * This proxy sits between the dev server and the Cloudflare tunnel,\n * injecting the element selection script into HTML responses.\n * \n * This enables the \"select element\" feature to work when:\n * - Frontend is hosted remotely (e.g., Vercel)\n * - Runner is running locally on user's machine\n * - Traffic flows through Cloudflare tunnel\n * \n * Without this proxy, the selection script can't be injected because\n * the iframe loads from a different origin (the tunnel URL).\n */\n\nimport http from 'http';\nimport https from 'https';\nimport httpProxy from 'http-proxy';\nimport zlib from 'zlib';\nimport { SELECTION_SCRIPT } from '@openbuilder/agent-core/lib/selection/injector';\n\nexport interface InjectionProxyOptions {\n /** Dev server port to proxy to (e.g., 3000) */\n targetPort: number;\n /** Port for this proxy to listen on (default: 4000) */\n proxyPort?: number;\n /** Optional error handler */\n onError?: (err: Error) => void;\n /** Optional log function */\n log?: (...args: unknown[]) => void;\n}\n\nexport interface InjectionProxy {\n /** Port the proxy is listening on */\n port: number;\n /** The HTTP server instance */\n server: http.Server;\n /** Close the proxy server */\n close: () => Promise<void>;\n}\n\nconst DEFAULT_PROXY_PORT = 4000;\n\n/**\n * Create an injection proxy that forwards requests to a dev server\n * while injecting the selection script into HTML responses.\n */\nexport async function createInjectionProxy(options: InjectionProxyOptions): Promise<InjectionProxy> {\n const { \n targetPort, \n proxyPort = DEFAULT_PROXY_PORT, \n onError,\n log = console.log \n } = options;\n\n const targetUrl = `http://localhost:${targetPort}`;\n\n // Create proxy with WebSocket support\n const proxy = httpProxy.createProxyServer({\n target: targetUrl,\n ws: true,\n selfHandleResponse: true, // We need to modify HTML responses\n changeOrigin: true,\n });\n\n const server = http.createServer((req, res) => {\n // Forward the request through proxy\n proxy.web(req, res, {}, (err) => {\n if (err) {\n onError?.(err);\n // Try to send error response if headers not sent\n if (!res.headersSent) {\n res.writeHead(502, { 'Content-Type': 'text/plain' });\n res.end(`Proxy error: ${err.message}`);\n }\n }\n });\n });\n\n // Handle WebSocket upgrades (critical for HMR in Vite/Next.js/etc)\n server.on('upgrade', (req, socket, head) => {\n proxy.ws(req, socket, head, {}, (err) => {\n if (err) {\n onError?.(err);\n socket.destroy();\n }\n });\n });\n\n // Intercept responses to inject script into HTML\n proxy.on('proxyRes', (proxyRes, req, res) => {\n const contentType = proxyRes.headers['content-type'] || '';\n const isHtml = contentType.includes('text/html');\n\n if (!isHtml) {\n // Pass through non-HTML responses unchanged\n // Copy all headers\n res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);\n proxyRes.pipe(res);\n return;\n }\n\n // Handle HTML - collect chunks and inject script\n const chunks: Buffer[] = [];\n const encoding = proxyRes.headers['content-encoding'];\n\n proxyRes.on('data', (chunk: Buffer) => {\n chunks.push(chunk);\n });\n\n proxyRes.on('end', () => {\n try {\n let body = Buffer.concat(chunks);\n\n // Decompress if needed\n if (encoding === 'gzip') {\n try {\n body = zlib.gunzipSync(body);\n } catch {\n // If decompression fails, pass through unchanged\n const headers = { ...proxyRes.headers };\n res.writeHead(proxyRes.statusCode || 200, headers);\n res.end(Buffer.concat(chunks));\n return;\n }\n } else if (encoding === 'deflate') {\n try {\n body = zlib.inflateSync(body);\n } catch {\n const headers = { ...proxyRes.headers };\n res.writeHead(proxyRes.statusCode || 200, headers);\n res.end(Buffer.concat(chunks));\n return;\n }\n } else if (encoding === 'br') {\n try {\n body = zlib.brotliDecompressSync(body);\n } catch {\n const headers = { ...proxyRes.headers };\n res.writeHead(proxyRes.statusCode || 200, headers);\n res.end(Buffer.concat(chunks));\n return;\n }\n }\n\n let html = body.toString('utf-8');\n\n // Inject selection script before </body> or </html> or at end\n const scriptTag = `<script>${SELECTION_SCRIPT}</script>`;\n \n if (html.toLowerCase().includes('</body>')) {\n html = html.replace(/<\\/body>/i, `${scriptTag}</body>`);\n } else if (html.toLowerCase().includes('</html>')) {\n html = html.replace(/<\\/html>/i, `${scriptTag}</html>`);\n } else {\n // Fallback: append at end\n html += scriptTag;\n }\n\n // Prepare response\n const responseBody = Buffer.from(html, 'utf-8');\n \n // Copy headers, update content-length, remove encoding (we decompressed)\n const headers: Record<string, string | number | string[] | undefined> = { ...proxyRes.headers };\n delete headers['content-encoding'];\n delete headers['transfer-encoding'];\n headers['content-length'] = responseBody.length;\n\n res.writeHead(proxyRes.statusCode || 200, headers);\n res.end(responseBody);\n } catch (err) {\n onError?.(err instanceof Error ? err : new Error(String(err)));\n // On error, try to pass through original response\n if (!res.headersSent) {\n res.writeHead(proxyRes.statusCode || 500, proxyRes.headers);\n res.end(Buffer.concat(chunks));\n }\n }\n });\n\n proxyRes.on('error', (err) => {\n onError?.(err);\n if (!res.headersSent) {\n res.writeHead(502, { 'Content-Type': 'text/plain' });\n res.end(`Proxy response error: ${err.message}`);\n }\n });\n });\n\n // Handle proxy errors\n proxy.on('error', (err, req, res) => {\n onError?.(err);\n if (res && 'writeHead' in res && !res.headersSent) {\n (res as http.ServerResponse).writeHead(502, { 'Content-Type': 'text/plain' });\n (res as http.ServerResponse).end(`Proxy error: ${err.message}`);\n }\n });\n\n // Start server and return promise\n return new Promise((resolve, reject) => {\n server.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n reject(new Error(`Injection proxy port ${proxyPort} is already in use`));\n } else {\n reject(err);\n }\n });\n\n server.listen(proxyPort, '127.0.0.1', () => {\n log(`[injection-proxy] Started on port ${proxyPort} → localhost:${targetPort}`);\n \n resolve({\n port: proxyPort,\n server,\n close: () => new Promise<void>((resolveClose) => {\n // Add timeout to prevent hanging if connections don't close\n const CLOSE_TIMEOUT_MS = 2000;\n let resolved = false;\n \n const timeoutId = setTimeout(() => {\n if (!resolved) {\n resolved = true;\n log(`[injection-proxy] Force closing after ${CLOSE_TIMEOUT_MS}ms timeout`);\n // Force destroy the server if it hasn't closed\n try {\n server.closeAllConnections?.();\n } catch {\n // closeAllConnections may not be available in older Node versions\n }\n resolveClose();\n }\n }, CLOSE_TIMEOUT_MS);\n \n proxy.close(() => {\n server.close(() => {\n if (!resolved) {\n resolved = true;\n clearTimeout(timeoutId);\n log(`[injection-proxy] Stopped`);\n }\n resolveClose();\n });\n });\n }),\n });\n });\n });\n}\n\n/**\n * Check if a port is available\n */\nexport async function isPortAvailable(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const server = http.createServer();\n server.once('error', () => resolve(false));\n server.once('listening', () => {\n server.close(() => resolve(true));\n });\n server.listen(port, '127.0.0.1');\n });\n}\n\n/**\n * Find an available port starting from the given port\n */\nexport async function findAvailablePort(startPort: number, maxAttempts = 10): Promise<number> {\n for (let i = 0; i < maxAttempts; i++) {\n const port = startPort + i;\n if (await isPortAvailable(port)) {\n return port;\n }\n }\n throw new Error(`No available port found starting from ${startPort}`);\n}\n","import { spawn, ChildProcess } from 'node:child_process';\nimport { EventEmitter } from 'node:events';\nimport { ensureCloudflared } from './auto-install.js';\nimport { createInjectionProxy, findAvailablePort, type InjectionProxy } from '../injection-proxy.js';\n\n/** Default port for the injection proxy */\nconst DEFAULT_INJECTION_PROXY_PORT = 4000;\n\ninterface TunnelInfo {\n url: string;\n /** Original dev server port */\n port: number;\n /** Injection proxy port (tunnel connects to this) */\n proxyPort: number;\n process: ChildProcess;\n /** Injection proxy instance (for cleanup) */\n injectionProxy?: InjectionProxy;\n}\n\nexport class TunnelManager extends EventEmitter {\n private tunnels = new Map<number, TunnelInfo>();\n private cloudflaredPath: string | null = null;\n private silent = false; // Suppress console output\n\n /**\n * Set silent mode (for TUI)\n */\n setSilent(silent: boolean): void {\n this.silent = silent;\n }\n\n /**\n * Conditional logging\n */\n private log(...args: unknown[]): void {\n if (!this.silent) {\n console.log(...args);\n }\n }\n\n /**\n * Create a tunnel for a specific port\n * Returns the public tunnel URL\n * \n * The tunnel is created through an injection proxy that adds the element\n * selection script to HTML responses. This enables the \"select element\"\n * feature to work when the frontend is hosted remotely.\n */\n async createTunnel(port: number, maxRetries = 5): Promise<string> {\n // Check if tunnel already exists for this port\n if (this.tunnels.has(port)) {\n const existing = this.tunnels.get(port)!;\n this.log(`🔗 Tunnel already exists for port ${port}: ${existing.url}`);\n return existing.url;\n }\n\n // Ensure cloudflared is installed\n if (!this.cloudflaredPath) {\n this.cloudflaredPath = await ensureCloudflared(this.silent);\n }\n\n // Step 1: Start injection proxy\n // This proxy injects the element selection script into HTML responses\n let injectionProxy: InjectionProxy | undefined;\n let proxyPort = DEFAULT_INJECTION_PROXY_PORT;\n\n try {\n // Find an available port for the proxy\n proxyPort = await findAvailablePort(DEFAULT_INJECTION_PROXY_PORT);\n \n injectionProxy = await createInjectionProxy({\n targetPort: port,\n proxyPort,\n onError: (err) => this.log(`[injection-proxy] Error: ${err.message}`),\n log: (...args) => this.log(...args),\n });\n \n this.log(`✅ Injection proxy started: localhost:${proxyPort} → localhost:${port}`);\n } catch (err) {\n // Fallback: tunnel directly to dev server (selection won't work but preview will)\n this.log(`⚠️ Injection proxy failed to start: ${err instanceof Error ? err.message : String(err)}`);\n this.log(`⚠️ Falling back to direct tunnel (element selection will not work)`);\n proxyPort = port; // Fall back to direct connection\n }\n\n // Step 2: Create tunnel to proxy port (or dev server if proxy failed)\n const tunnelTargetPort = injectionProxy ? proxyPort : port;\n\n // Try creating tunnel with smart retries\n const errors: string[] = [];\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n return await this._createTunnelAttempt(port, tunnelTargetPort, injectionProxy);\n } catch (error: any) {\n const errorMsg = error?.message || String(error);\n errors.push(errorMsg);\n console.error(`Tunnel creation attempt ${attempt}/${maxRetries} failed:`, errorMsg);\n\n // Check if this is a permanent error (fail fast)\n if (this._isPermanentError(errorMsg)) {\n // Clean up injection proxy on permanent failure\n if (injectionProxy) {\n await injectionProxy.close().catch(() => {});\n }\n throw new Error(`Permanent failure: ${errorMsg}`);\n }\n\n if (attempt === maxRetries) {\n // Clean up injection proxy on final failure\n if (injectionProxy) {\n await injectionProxy.close().catch(() => {});\n }\n throw new Error(`Failed to create tunnel after ${maxRetries} attempts: ${errors.join('; ')}`);\n }\n\n // Exponential backoff with jitter to prevent thundering herd\n const baseDelay = Math.pow(2, attempt) * 1000; // 2s, 4s, 8s, 16s\n const jitter = Math.random() * 1000; // 0-1s random jitter\n const delay = baseDelay + jitter;\n this.log(`Retrying in ${Math.round(delay)}ms...`);\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n\n // Clean up injection proxy on failure\n if (injectionProxy) {\n await injectionProxy.close().catch(() => {});\n }\n throw new Error('Tunnel creation failed after all retries');\n }\n\n /**\n * Check if an error is permanent (no point retrying)\n */\n private _isPermanentError(errorMsg: string): boolean {\n const permanentErrors = [\n 'port already in use',\n 'cloudflared not found',\n 'permission denied',\n 'cannot find',\n 'enoent',\n 'eacces',\n ];\n\n const lowerMsg = errorMsg.toLowerCase();\n return permanentErrors.some(err => lowerMsg.includes(err));\n }\n\n /**\n * Extract tunnel URL from cloudflared output\n */\n private _extractTunnelUrl(output: string): string | null {\n // Format: \"Your quick Tunnel has been created! Visit it at: https://xxx.trycloudflare.com\"\n // Or just: \"https://xxx.trycloudflare.com\"\n const match = output.match(/https:\\/\\/[a-zA-Z0-9-]+\\.trycloudflare\\.com/);\n return match ? match[0] : null;\n }\n\n /**\n * Verify tunnel is actually responding (async, non-blocking)\n * This runs in background and only logs results\n */\n private async _verifyTunnelReady(url: string, maxWaitMs = 15000): Promise<boolean> {\n const startTime = Date.now();\n const checkInterval = 1000; // Check every 1 second (less aggressive)\n\n this.log(`🔍 [Background] Verifying tunnel is ready: ${url}`);\n\n while (Date.now() - startTime < maxWaitMs) {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 2000);\n\n const response = await fetch(url, {\n method: 'HEAD',\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n // Any response (even errors) means tunnel is connected\n // We just need to verify it's resolving and routing\n if (response.status < 500 || response.ok) {\n const elapsed = Date.now() - startTime;\n this.log(`✅ [Background] Tunnel verified in ${elapsed}ms`);\n return true;\n }\n } catch (error) {\n // Expected while DNS propagates or tunnel initializes\n // Will keep retrying silently\n }\n\n await new Promise(resolve => setTimeout(resolve, checkInterval));\n }\n\n this.log(`⏱️ [Background] Verification timeout after ${maxWaitMs}ms (tunnel may still work)`);\n return false;\n }\n\n /**\n * Single attempt to create a tunnel\n * @param devServerPort - The original dev server port (used as key in tunnels map)\n * @param tunnelTargetPort - The port to tunnel to (proxy port or dev server port if proxy failed)\n * @param injectionProxy - Optional injection proxy instance for cleanup\n */\n private async _createTunnelAttempt(\n devServerPort: number, \n tunnelTargetPort: number,\n injectionProxy?: InjectionProxy\n ): Promise<string> {\n return new Promise((resolve, reject) => {\n const isUsingProxy = tunnelTargetPort !== devServerPort;\n this.log(`[tunnel] Creating tunnel for port ${tunnelTargetPort}${isUsingProxy ? ` (proxy for dev server on ${devServerPort})` : ''}...`);\n\n // Direct binary execution with unbuffered streams\n const proc = spawn(this.cloudflaredPath!, [\n 'tunnel',\n '--url', `http://localhost:${tunnelTargetPort}`,\n '--no-autoupdate',\n ], {\n cwd: process.cwd(),\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n // Set streams to unbuffered mode immediately for responsive output\n if (proc.stdout) {\n proc.stdout.setEncoding('utf8');\n proc.stdout.resume();\n }\n if (proc.stderr) {\n proc.stderr.setEncoding('utf8');\n proc.stderr.resume();\n }\n\n this.log(`[tunnel] Cloudflared spawned with PID: ${proc.pid}`);\n\n let resolved = false;\n let tunnelUrl: string | null = null;\n let tunnelRegistered = false;\n\n const timeout = setTimeout(() => {\n if (!resolved) {\n proc.kill();\n reject(new Error('Tunnel creation timeout (30s)'));\n }\n }, 30000);\n\n // Shared handler for both stdout and stderr\n const handleOutput = async (data: Buffer) => {\n const output = data.toString();\n\n // Step 1: Extract URL\n if (!tunnelUrl) {\n const url = this._extractTunnelUrl(output);\n if (url) {\n tunnelUrl = url;\n this.log(`✅ Tunnel URL received: ${url} → localhost:${tunnelTargetPort}${isUsingProxy ? ` → localhost:${devServerPort}` : ''}`);\n // Store with dev server port as key, but include proxy info\n this.tunnels.set(devServerPort, { \n url, \n port: devServerPort, \n proxyPort: tunnelTargetPort,\n process: proc,\n injectionProxy,\n });\n }\n }\n\n // Step 2: Wait for tunnel registration (edge connection established)\n if (tunnelUrl && !tunnelRegistered && output.includes('Registered tunnel connection')) {\n tunnelRegistered = true;\n this.log(`✅ Tunnel registered with Cloudflare edge (DNS propagating)`);\n\n // Wait 3 seconds after registration for DNS to propagate\n this.log(`⏳ Waiting 3 seconds for DNS to fully propagate...`);\n await new Promise(r => setTimeout(r, 3000));\n\n // Step 3: Return only after registration + 3 second buffer\n if (!resolved) {\n resolved = true;\n clearTimeout(timeout);\n\n this.log(`✅ Tunnel ready: ${tunnelUrl}`);\n if (isUsingProxy) {\n this.log(`✅ Element selection enabled via injection proxy`);\n }\n\n // Note: Backend verification skipped for localhost tunnels\n // The tunnel connects localhost to Cloudflare - backend can't verify it\n // Frontend will verify DNS before loading in iframe\n\n resolve(tunnelUrl);\n }\n }\n };\n\n proc.stdout.on('data', handleOutput);\n\n proc.stderr.on('data', (data: Buffer) => {\n const output = data.toString();\n\n // Log errors (cloudflared uses stderr for all output)\n // Only show real errors, not shutdown messages\n const lower = output.toLowerCase();\n if ((lower.includes('error') || lower.includes('fatal')) &&\n !lower.includes('context canceled') &&\n !lower.includes('connection terminated') &&\n !lower.includes('no more connections active')) {\n this.log(`[cloudflared:${devServerPort}] ${output.trim()}`);\n }\n\n // Check for tunnel URL in stderr too\n handleOutput(data);\n });\n\n proc.on('exit', (code, signal) => {\n this.log(`Tunnel exited for port ${devServerPort} with code ${code} signal ${signal}`);\n // Clean up injection proxy when tunnel exits\n const tunnel = this.tunnels.get(devServerPort);\n if (tunnel?.injectionProxy) {\n tunnel.injectionProxy.close().catch(() => {});\n }\n this.tunnels.delete(devServerPort);\n this.emit('tunnel-closed', devServerPort);\n });\n\n proc.on('error', (error) => {\n if (!resolved) {\n clearTimeout(timeout);\n reject(error);\n }\n });\n });\n }\n\n /**\n * Close tunnel for a specific port\n */\n async closeTunnel(port: number): Promise<void> {\n const tunnel = this.tunnels.get(port);\n if (!tunnel) {\n this.log(`No tunnel found for port ${port}`);\n return;\n }\n\n this.log(`🔗 Closing tunnel for port ${port}...`);\n\n // Close injection proxy first (if exists) with timeout\n if (tunnel.injectionProxy) {\n try {\n // Use Promise.race to enforce timeout - injection proxy close can hang\n // if there are active HTTP keep-alive connections\n const PROXY_CLOSE_TIMEOUT_MS = 3000;\n await Promise.race([\n tunnel.injectionProxy.close(),\n new Promise<void>((resolve) => setTimeout(() => {\n this.log(`⚠️ Injection proxy close timed out after ${PROXY_CLOSE_TIMEOUT_MS}ms, continuing...`);\n resolve();\n }, PROXY_CLOSE_TIMEOUT_MS))\n ]);\n this.log(`✅ Injection proxy closed for port ${port}`);\n } catch (err) {\n this.log(`⚠️ Error closing injection proxy: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n return new Promise((resolve) => {\n const timeout = setTimeout(() => {\n // Force kill if not dead after 1 second\n if (!tunnel.process.killed) {\n tunnel.process.kill('SIGKILL');\n }\n this.tunnels.delete(port);\n resolve();\n }, 1000);\n\n tunnel.process.once('exit', () => {\n clearTimeout(timeout);\n this.tunnels.delete(port);\n resolve();\n });\n\n // Send SIGTERM\n tunnel.process.kill('SIGTERM');\n });\n }\n\n /**\n * Close all active tunnels\n */\n async closeAll(): Promise<void> {\n this.log(`🔗 Closing ${this.tunnels.size} active tunnel(s)...`);\n\n const ports = Array.from(this.tunnels.keys());\n await Promise.all(ports.map(port => this.closeTunnel(port)));\n }\n\n /**\n * Get tunnel URL for a specific port (if exists)\n */\n getTunnelUrl(port: number): string | null {\n const tunnel = this.tunnels.get(port);\n return tunnel ? tunnel.url : null;\n }\n\n /**\n * Get all active tunnels\n */\n getActiveTunnels(): Array<{ port: number; url: string }> {\n return Array.from(this.tunnels.values()).map(({ port, url }) => ({ port, url }));\n }\n}\n\n// Singleton instance\nexport const tunnelManager = new TunnelManager();\n"],"names":[],"mappings":"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;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,CAAC;;AChvBD;;;;;;;;;;;;;AAaG;AA4BH,MAAM,kBAAkB,GAAG,IAAI;AAE/B;;;AAGG;AACI,eAAe,oBAAoB,CAAC,OAA8B,EAAA;AACvE,IAAA,MAAM,EACJ,UAAU,EACV,SAAS,GAAG,kBAAkB,EAC9B,OAAO,EACP,GAAG,GAAG,OAAO,CAAC,GAAG,EAClB,GAAG,OAAO;AAEX,IAAA,MAAM,SAAS,GAAG,CAAA,iBAAA,EAAoB,UAAU,EAAE;;AAGlD,IAAA,MAAM,KAAK,GAAG,SAAS,CAAC,iBAAiB,CAAC;AACxC,QAAA,MAAM,EAAE,SAAS;AACjB,QAAA,EAAE,EAAE,IAAI;QACR,kBAAkB,EAAE,IAAI;AACxB,QAAA,YAAY,EAAE,IAAI;AACnB,KAAA,CAAC;IAEF,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,EAAE,GAAG,KAAI;;AAE5C,QAAA,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,GAA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"}