claude-dev-server 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server/pty.ts","../src/server/source-map.ts","../src/server/websocket.ts","../src/client/injection.js","../src/universal/index.ts"],"names":["resolve","__filename","spawn"],"mappings":"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AA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAoOtB,IAAM,aAAA,GAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;A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","file":"chunk-DOLSA776.js","sourcesContent":["import { spawn } from 'child_process'\nimport { randomBytes } from 'crypto'\n\nexport interface PtyOptions {\n cwd: string\n claudePath: string\n args: string[]\n env?: Record<string, string>\n}\n\nexport function spawnClaudeCode(options: PtyOptions) {\n // Generate a random port for ttyd\n const port = 50000 + Math.floor(Math.random() * 10000)\n\n // Start ttyd with claude command\n const ttydProc = spawn('ttyd', [\n '--port', String(port),\n '--interface', '127.0.0.1',\n '--writable',\n options.claudePath,\n ...options.args,\n ], {\n cwd: options.cwd,\n env: {\n ...process.env,\n ...options.env,\n TERM: 'xterm-256color',\n FORCE_COLOR: '1',\n },\n })\n\n ttydProc.on('exit', (code) => {\n console.log(`[claude-dev-server] ttyd exited - code: ${code}`)\n })\n\n ttydProc.on('error', (err) => {\n console.error(`[claude-dev-server] ttyd error: ${err.message}`)\n })\n\n // Wait a bit for ttyd to start, then return the WebSocket URL\n return new Promise<{ wsUrl: string; process: typeof ttydProc; port: number }>((resolve, reject) => {\n ttydProc.stdout?.on('data', (data: Buffer) => {\n const msg = data.toString()\n console.log(`[ttyd] ${msg}`)\n })\n\n ttydProc.stderr?.on('data', (data: Buffer) => {\n const msg = data.toString()\n console.error(`[ttyd stderr] ${msg}`)\n })\n\n // Give ttyd a moment to start\n setTimeout(() => {\n resolve({\n wsUrl: `ws://127.0.0.1:${port}`,\n process: ttydProc,\n port,\n })\n }, 500)\n\n ttydProc.on('error', reject)\n })\n}\n","import { SourceMapConsumer } from 'source-map'\n\nexport interface SourcePosition {\n source: string\n line: number\n column: number\n name?: string\n}\n\nexport interface CodeLocation {\n file: string\n line: number\n column: number\n content?: string\n}\n\n// Store source maps by generated file path\nconst sourceMapCache = new Map<string, SourceMapConsumer>()\n\nexport async function parseSourceMap(sourceMapUrl: string, content: string): Promise<void> {\n try {\n const consumer = await new SourceMapConsumer(content)\n sourceMapCache.set(sourceMapUrl, consumer)\n } catch (err) {\n console.error('Failed to parse source map:', err)\n }\n}\n\nexport async function findOriginalPosition(\n generatedFile: string,\n line: number,\n column: number\n): Promise<SourcePosition | null> {\n const consumer = sourceMapCache.get(generatedFile)\n if (!consumer) {\n return null\n }\n\n try {\n const position = consumer.originalPositionFor({ line, column })\n if (position.source) {\n return {\n source: position.source,\n line: position.line || 1,\n column: position.column || 0,\n name: position.name,\n }\n }\n } catch (err) {\n console.error('Failed to find original position:', err)\n }\n\n return null\n}\n\nexport function generateVSCodeURI(location: CodeLocation): string {\n // Generate VS Code URI scheme for opening files\n // vscode://file/{path}:{line}:{col}\n const filePath = location.file.replace(/\\\\/g, '/')\n return `vscode://file/${filePath}:${location.line}:${location.column}`\n}\n\nexport function formatCodeContext(location: CodeLocation): string {\n return `\nšŸ“ Code Location:\n File: ${location.file}\n Line: ${location.line}\n Column: ${location.column}\n`\n}\n\nexport function clearCache() {\n sourceMapCache.clear()\n}\n","import { WebSocketServer, WebSocket } from 'ws'\nimport { spawnClaudeCode } from './pty.js'\nimport { findOriginalPosition, parseSourceMap, CodeLocation, formatCodeContext } from './source-map.js'\nimport { readFile } from 'fs/promises'\nimport { resolve } from 'path'\n\nexport interface WebSocketServerOptions {\n port?: number\n projectRoot: string\n claudePath: string\n claudeArgs: string[]\n}\n\nexport function createWebSocketServer(options: WebSocketServerOptions) {\n let wss: WebSocketServer | null = null\n let port = options.port || 0\n let ttydInfo: { wsUrl: string; process: any; port: number } | null = null\n\n const start = async (): Promise<{ wsPort: number; ttydPort: number }> => {\n // Start ttyd first\n console.log('[claude-dev-server] Starting ttyd...')\n ttydInfo = await spawnClaudeCode({\n cwd: options.projectRoot,\n claudePath: options.claudePath,\n args: options.claudeArgs,\n })\n console.log(`[claude-dev-server] ttyd running at ${ttydInfo.wsUrl}`)\n\n // Also start a simple WebSocket server for inspect functionality\n return new Promise((resolve, reject) => {\n wss = new WebSocketServer({ port, host: '127.0.0.1' })\n\n wss.on('listening', () => {\n const address = wss!.address()\n if (address && typeof address === 'object') {\n port = address.port\n resolve({ wsPort: port, ttydPort: ttydInfo!.port })\n }\n })\n\n wss.on('error', (err) => {\n reject(err)\n })\n\n wss.on('connection', (ws: WebSocket) => {\n ws.on('message', async (message: Buffer) => {\n try {\n const msg = JSON.parse(message.toString())\n\n if (msg.type === 'inspect') {\n await handleInspect(msg, ws, options.projectRoot)\n } else if (msg.type === 'loadSourceMap') {\n await handleLoadSourceMap(msg, ws, options.projectRoot)\n }\n } catch (err) {\n // Ignore\n }\n })\n\n // Send ready message with ttyd URL\n ws.send(JSON.stringify({\n type: 'ready',\n ttydUrl: ttydInfo!.wsUrl\n }))\n })\n })\n }\n\n const stop = () => {\n ttydInfo?.process.kill()\n wss?.close()\n }\n\n return { start, stop }\n}\n\nasync function handleLoadSourceMap(\n msg: any,\n ws: WebSocket,\n projectRoot: string\n) {\n const { sourceMapUrl } = msg\n try {\n const mapPath = resolve(projectRoot, sourceMapUrl.replace(/^\\//, ''))\n const content = await readFile(mapPath, 'utf-8')\n await parseSourceMap(sourceMapUrl, content)\n ws.send(JSON.stringify({\n type: 'sourceMapLoaded',\n sourceMapUrl,\n success: true\n }))\n } catch (err) {\n ws.send(JSON.stringify({\n type: 'sourceMapLoaded',\n sourceMapUrl,\n success: false,\n error: (err as Error).message\n }))\n }\n}\n\nasync function handleInspect(\n msg: any,\n ws: WebSocket,\n projectRoot: string\n) {\n const { url, line, column, sourceMapUrl } = msg\n\n let location: CodeLocation | null = null\n\n if (sourceMapUrl) {\n const original = await findOriginalPosition(sourceMapUrl, line, column)\n if (original) {\n location = {\n file: resolve(projectRoot, original.source),\n line: original.line,\n column: original.column,\n }\n }\n }\n\n if (!location) {\n const match = url.match(/\\/@fs\\/(.+?)(?:\\?|$)|\\/@vite\\/(.+?)(?:\\?|$)/)\n if (match) {\n location = {\n file: decodeURIComponent(match[1] || match[2]),\n line,\n column,\n }\n }\n }\n\n ws.send(JSON.stringify({\n type: 'inspectResult',\n location: location ? {\n file: location.file,\n line: location.line,\n column: location.column,\n context: formatCodeContext(location)\n } : null\n }))\n}\n","// Client-side script - pure JavaScript (no TypeScript)\n// This file will be injected into the browser\n\nexport const CLIENT_STYLES = `\n<style id=\"claude-dev-server-styles\">\n.claude-dev-server-toggle {\n position: fixed;\n top: 20px;\n right: 20px;\n width: 44px;\n height: 44px;\n background: #1e1e1e;\n border: none;\n border-radius: 50%;\n box-shadow: 0 2px 12px rgba(0,0,0,0.3);\n cursor: pointer;\n z-index: 999999;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 20px;\n transition: transform 0.2s, background 0.2s;\n}\n.claude-dev-server-toggle:hover {\n transform: scale(1.1);\n background: #2d2d2d;\n}\n.claude-dev-server-toggle.hidden {\n display: none;\n}\n.claude-dev-server-inspect-btn {\n position: fixed;\n top: 74px;\n right: 20px;\n width: 44px;\n height: 44px;\n background: #1e1e1e;\n border: none;\n border-radius: 50%;\n box-shadow: 0 2px 12px rgba(0,0,0,0.3);\n cursor: pointer;\n z-index: 999999;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n transition: transform 0.2s, background 0.2s;\n}\n.claude-dev-server-inspect-btn:hover {\n transform: scale(1.1);\n background: #2d2d2d;\n}\n.claude-dev-server-inspect-btn.active {\n background: #007acc;\n}\n.claude-dev-server-inspect-btn.hidden {\n display: none;\n}\n.claude-dev-server-toggle svg,\n.claude-dev-server-inspect-btn svg {\n width: 20px;\n height: 20px;\n flex-shrink: 0;\n}\n.claude-dev-server-panel {\n position: fixed;\n top: 0;\n right: 0;\n width: 650px;\n height: 100vh;\n background: #1e1e1e;\n color: #d4d4d4;\n font-family: 'SF Mono', 'Monaco', 'Cascadia Code', 'Consolas', monospace;\n font-size: 13px;\n box-shadow: -4px 0 20px rgba(0,0,0,0.3);\n transform: translateX(100%);\n transition: transform 0.2s ease;\n z-index: 999999;\n display: flex;\n flex-direction: column;\n}\n.claude-dev-server-panel.open {\n transform: translateX(0);\n}\n.claude-dev-server-header {\n padding: 8px 12px;\n background: #2d2d2d;\n border-bottom: 1px solid #3e3e3e;\n display: flex;\n justify-content: space-between;\n align-items: center;\n user-select: none;\n}\n.claude-dev-server-title {\n font-weight: 600;\n color: #fff;\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n}\n.claude-dev-server-title::before {\n content: 'šŸ¤–';\n font-size: 14px;\n}\n.claude-dev-server-actions {\n display: flex;\n gap: 6px;\n}\n.claude-dev-server-btn {\n background: #3e3e3e;\n border: none;\n color: #d4d4d4;\n cursor: pointer;\n font-family: inherit;\n font-size: 11px;\n padding: 4px 10px;\n border-radius: 3px;\n transition: background 0.15s;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n.claude-dev-server-btn:hover {\n background: #4e4e4e;\n}\n.claude-dev-server-btn.active {\n background: #007acc;\n color: #fff;\n}\n.claude-dev-server-close {\n background: none;\n border: none;\n color: #858585;\n cursor: pointer;\n font-size: 18px;\n padding: 0;\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 3px;\n transition: background 0.15s, color 0.15s;\n}\n.claude-dev-server-close:hover {\n background: #3e3e3e;\n color: #fff;\n}\n.claude-dev-server-terminal {\n flex: 1;\n overflow: hidden;\n position: relative;\n background: #000;\n}\n.claude-dev-server-terminal iframe {\n width: 100%;\n height: 100%;\n border: none;\n}\n.claude-dev-server-inspect-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n pointer-events: none;\n z-index: 999998;\n display: none;\n}\n.claude-dev-server-inspect-overlay.active {\n display: block;\n}\n.claude-dev-server-highlight {\n position: absolute;\n border: 2px solid #007acc;\n background: rgba(0, 122, 204, 0.1);\n pointer-events: none;\n transition: all 0.1s ease;\n}\n.claude-dev-server-highlight::after {\n content: attr(data-element);\n position: absolute;\n top: -20px;\n left: 0;\n background: #007acc;\n color: #fff;\n font-size: 10px;\n padding: 2px 4px;\n border-radius: 2px 2px 0 0;\n font-family: monospace;\n white-space: nowrap;\n}\n/* Responsive layout for portrait mode */\n@media (orientation: portrait) {\n .claude-dev-server-toggle {\n top: auto;\n bottom: 20px;\n right: 10px;\n width: 36px;\n height: 36px;\n }\n .claude-dev-server-inspect-btn {\n top: auto;\n bottom: 66px;\n right: 10px;\n width: 36px;\n height: 36px;\n }\n .claude-dev-server-panel {\n top: auto;\n bottom: 0;\n right: 0;\n left: 0;\n width: 100%;\n height: 80vh;\n transform: translateY(100%);\n box-shadow: 0 -4px 20px rgba(0,0,0,0.3);\n }\n .claude-dev-server-panel.open {\n transform: translateY(0);\n }\n .claude-dev-server-toggle svg,\n .claude-dev-server-inspect-btn svg {\n width: 16px;\n height: 16px;\n }\n}\n</style>\n`\n\nexport const CLIENT_SCRIPT = `\n(() => {\n let ws = null\n let panel = null\n let toggleBtn = null\n let inspectBtn = null // ꂬ굮 inspect ęŒ‰é’®\n let terminalContainer = null\n let terminalIframe = null\n let overlay = null\n let isOpen = false\n let isInspectMode = false\n let ttydWsUrl = null\n\n // Fetch the WebSocket port from the server\n async function getWsPort() {\n const res = await fetch('/@claude-port')\n const data = await res.json()\n return data.port\n }\n\n async function initWhenReady() {\n try {\n const port = await getWsPort()\n connect(port)\n } catch (err) {\n console.error('[Claude Dev Server] Failed to get port:', err)\n // Retry after 1 second\n setTimeout(initWhenReady, 1000)\n return\n }\n createToggleBtn()\n createInspectBtn()\n createOverlay()\n createPanel()\n }\n\n function createToggleBtn() {\n if (toggleBtn) return\n toggleBtn = document.createElement('button')\n toggleBtn.className = 'claude-dev-server-toggle'\n toggleBtn.innerHTML = '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M11.376 24L10.776 23.544L10.44 22.8L10.776 21.312L11.16 19.392L11.472 17.856L11.76 15.96L11.928 15.336L11.904 15.288L11.784 15.312L10.344 17.28L8.16 20.232L6.432 22.056L6.024 22.224L5.304 21.864L5.376 21.192L5.784 20.616L8.16 17.568L9.6 15.672L10.536 14.592L10.512 14.448H10.464L4.128 18.576L3 18.72L2.496 18.264L2.568 17.52L2.808 17.28L4.704 15.96L9.432 13.32L9.504 13.08L9.432 12.96H9.192L8.4 12.912L5.712 12.84L3.384 12.744L1.104 12.624L0.528 12.504L0 11.784L0.048 11.424L0.528 11.112L1.224 11.16L2.736 11.28L5.016 11.424L6.672 11.52L9.12 11.784H9.504L9.552 11.616L9.432 11.52L9.336 11.424L6.96 9.84L4.416 8.16L3.072 7.176L2.352 6.672L1.992 6.216L1.848 5.208L2.496 4.488L3.384 4.56L3.6 4.608L4.488 5.304L6.384 6.768L8.88 8.616L9.24 8.904L9.408 8.808V8.736L9.24 8.472L7.896 6.024L6.456 3.528L5.808 2.496L5.64 1.872C5.576 1.656 5.544 1.416 5.544 1.152L6.288 0.144001L6.696 0L7.704 0.144001L8.112 0.504001L8.736 1.92L9.72 4.152L11.28 7.176L11.736 8.088L11.976 8.904L12.072 9.168H12.24V9.024L12.36 7.296L12.6 5.208L12.84 2.52L12.912 1.752L13.296 0.840001L14.04 0.360001L14.616 0.624001L15.096 1.32L15.024 1.752L14.76 3.6L14.184 6.504L13.824 8.472H14.04L14.28 8.208L15.264 6.912L16.92 4.848L17.64 4.032L18.504 3.12L19.056 2.688H20.088L20.832 3.816L20.496 4.992L19.44 6.336L18.552 7.464L17.28 9.168L16.512 10.536L16.584 10.632H16.752L19.608 10.008L21.168 9.744L22.992 9.432L23.832 9.816L23.928 10.2L23.592 11.016L21.624 11.496L19.32 11.952L15.888 12.768L15.84 12.792L15.888 12.864L17.424 13.008L18.096 13.056H19.728L22.752 13.272L23.544 13.8L24 14.424L23.928 14.928L22.704 15.528L21.072 15.144L17.232 14.232L15.936 13.92H15.744V14.016L16.848 15.096L18.84 16.896L21.36 19.224L21.48 19.8L21.168 20.28L20.832 20.232L18.624 18.552L17.76 17.808L15.84 16.2H15.72V16.368L16.152 17.016L18.504 20.544L18.624 21.624L18.456 21.96L17.832 22.176L17.184 22.056L15.792 20.136L14.376 17.952L13.224 16.008L13.104 16.104L12.408 23.352L12.096 23.712L11.376 24Z\" fill=\"#d97757\"/></svg>'\n toggleBtn.title = 'Open Claude Code (Cmd/Ctrl + \\`)'\n toggleBtn.setAttribute('data-dev-tool', 'true')\n toggleBtn.addEventListener('click', () => togglePanel(true))\n document.body.appendChild(toggleBtn)\n }\n\n function createInspectBtn() {\n if (inspectBtn) return\n inspectBtn = document.createElement('button')\n inspectBtn.className = 'claude-dev-server-inspect-btn'\n inspectBtn.innerHTML = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#fff\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M19 11V4a2 2 0 00-2-2H4a2 2 0 00-2 2v13a2 2 0 002 2h7\"/><path d=\"M12 12l4.166 10 1.48-4.355L22 16.166 12 12z\"/><path d=\"M18 18l3 3\"/></svg>'\n inspectBtn.title = 'Inspect Element (Cmd/Ctrl + Shift + I)'\n inspectBtn.setAttribute('data-dev-tool', 'true')\n inspectBtn.addEventListener('click', () => {\n if (isInspectMode) {\n disableInspectMode()\n } else {\n // 点击 Inspect ę—¶å…ˆę”¶čµ·é¢ęæ\n if (isOpen) {\n togglePanel(false)\n }\n enableInspectMode()\n }\n })\n document.body.appendChild(inspectBtn)\n }\n\n function createOverlay() {\n if (overlay) return\n overlay = document.createElement('div')\n overlay.className = 'claude-dev-server-inspect-overlay'\n document.body.appendChild(overlay)\n }\n\n function highlightElement(el) {\n if (!overlay) return\n overlay.innerHTML = ''\n const rect = el.getBoundingClientRect()\n const highlight = document.createElement('div')\n highlight.className = 'claude-dev-server-highlight'\n highlight.style.top = rect.top + 'px'\n highlight.style.left = rect.left + 'px'\n highlight.style.width = rect.width + 'px'\n highlight.style.height = rect.height + 'px'\n const className = el.className ? String(el.className) : ''\n highlight.dataset.element = el.tagName.toLowerCase() +\n (el.id ? '#' + el.id : '') +\n (className ? '.' + className.split(' ').join('.') : '')\n overlay.appendChild(highlight)\n }\n\n async function getSourceLocation(el) {\n let sourceFile = null\n let sourceLine = 1\n let sourceColumn = 1\n\n // Try to get original line number using source map\n async function getOriginalLine(generatedFile, generatedLine, generatedColumn) {\n try {\n // Find the script tag that corresponds to this file\n const scripts = Array.from(document.querySelectorAll('script[src]'))\n for (const script of scripts) {\n const src = script.getAttribute('src')\n if (src && (src.includes('/src/') || src.includes('/app.') || src.includes('/main.'))) {\n // Try to fetch and parse the source map\n const response = await fetch(src + '.map')\n if (response.ok) {\n const map = await response.json()\n // Use the source map to find the original position\n const consumer = await new (window.SourceMap || window.sourceMap).SourceMapConsumer(map)\n const original = consumer.originalPositionFor({\n line: generatedLine,\n column: generatedColumn\n })\n consumer.destroy()\n if (original.source && original.line !== null) {\n return { line: original.line, column: original.column || 1 }\n }\n }\n }\n }\n } catch (e) {\n console.log('[Claude Dev Server] Source map lookup failed:', e.message)\n }\n return null\n }\n\n // Try React DevTools - handle React 18's randomized suffix\n const elKeys = Object.keys(el)\n let fiberKey = elKeys.find(k => k === '__reactFiber__' || k === '__reactInternalInstance' || k.indexOf('__reactFiber') === 0)\n let propsKey = elKeys.find(k => k === '__reactProps__' || k.indexOf('__reactProps') === 0)\n\n if (fiberKey) {\n const fiber = el[fiberKey]\n console.log('[Claude Dev Server] Found fiber at key:', fiberKey)\n\n // Try to get _debugSource from different locations\n const debugSource = fiber._debugSource || fiber.elementType?._debugSource || fiber.type?._debugSource || fiber.alternate?._debugSource\n if (debugSource && debugSource.fileName) {\n sourceFile = debugSource.fileName\n sourceLine = debugSource.lineNumber || 1\n sourceColumn = debugSource.columnNumber || 1\n\n // Try to use source map to get the original line number\n const original = await getOriginalLine(sourceFile, sourceLine, sourceColumn)\n if (original) {\n sourceLine = original.line\n sourceColumn = original.column\n console.log('[Claude Dev Server] Original line from source map:', sourceLine)\n }\n\n // Convert absolute path to relative path using project root\n if (sourceFile.startsWith('/')) {\n const projectRoot = window.__CLAUDE_PROJECT_ROOT__\n if (projectRoot && sourceFile.startsWith(projectRoot)) {\n sourceFile = sourceFile.substring(projectRoot.length + 1)\n if (sourceFile.startsWith('/')) {\n sourceFile = sourceFile.substring(1)\n }\n }\n }\n console.log('[Claude Dev Server] Found React source:', sourceFile, sourceLine)\n } else {\n // Try going up the fiber tree\n let currentFiber = fiber\n let depth = 0\n while (currentFiber && depth < 20) {\n const ds = currentFiber._debugSource || currentFiber.elementType?._debugSource || currentFiber.type?._debugSource\n if (ds && ds.fileName) {\n sourceFile = ds.fileName\n sourceLine = ds.lineNumber || 1\n sourceColumn = ds.columnNumber || 1\n // Convert absolute path to relative path using project root\n if (sourceFile.startsWith('/')) {\n const projectRoot = window.__CLAUDE_PROJECT_ROOT__\n if (projectRoot && sourceFile.startsWith(projectRoot)) {\n sourceFile = sourceFile.substring(projectRoot.length + 1)\n if (sourceFile.startsWith('/')) {\n sourceFile = sourceFile.substring(1)\n }\n }\n }\n console.log('[Claude Dev Server] Found React source at depth', depth, ':', sourceFile, sourceLine)\n break\n }\n currentFiber = currentFiber.return || currentFiber.alternate\n depth++\n }\n }\n }\n\n // Try Vue component\n if (!sourceFile) {\n const vueComponent = el.__vueParentComponent || el.__vnode\n if (vueComponent) {\n const type = vueComponent.type || vueComponent.component\n if (type && type.__file) {\n sourceFile = type.__file\n console.log('[Claude Dev Server] Found Vue source:', sourceFile)\n }\n }\n }\n\n // Try Vite's HMR source map\n if (!sourceFile) {\n // Look for data-vite-dev-id or similar attributes\n const viteId = el.getAttribute('data-vite-dev-id')\n if (viteId) {\n // Extract file path from viteId (remove query params if any)\n const queryIndex = viteId.indexOf('?')\n sourceFile = '/' + (queryIndex >= 0 ? viteId.substring(0, queryIndex) : viteId)\n console.log('[Claude Dev Server] Found Vite ID:', viteId)\n }\n }\n\n // Check for inline script\n if (!sourceFile) {\n const inlineScripts = document.querySelectorAll('script:not([src])')\n if (inlineScripts.length > 0) {\n const pathParts = window.location.pathname.split('/')\n const fileName = pathParts[pathParts.length - 1] || 'index.html'\n sourceFile = '/' + fileName\n\n const html = document.documentElement.outerHTML\n const elId = el.id ? el.id : ''\n const elClass = el.className ? el.className : ''\n let elPattern\n if (elId) {\n elPattern = 'id=\"' + elId + '\"'\n } else if (elClass) {\n elPattern = 'class=\"' + elClass.split(' ')[0] + '\"'\n } else {\n elPattern = el.tagName.toLowerCase()\n }\n\n const matchIndex = html.indexOf(elPattern)\n if (matchIndex !== -1) {\n const beforeElement = html.substring(0, matchIndex)\n sourceLine = beforeElement.split('\\\\n').length\n }\n }\n }\n\n // Find main script\n if (!sourceFile) {\n const scripts = document.querySelectorAll('script[src]')\n for (const script of scripts) {\n const src = script.getAttribute('src')\n if (src && !src.includes('cdn') && !src.includes('node_modules') &&\n (src.includes('/src/') || src.includes('/app.') || src.includes('/main.'))) {\n sourceFile = src\n break\n }\n }\n }\n\n // Fallback\n if (!sourceFile) {\n const pathParts = window.location.pathname.split('/')\n const fileName = pathParts[pathParts.length - 1] || 'index.html'\n sourceFile = '/' + fileName\n }\n\n const elClassName = el.className ? String(el.className) : ''\n const selector = el.tagName.toLowerCase() +\n (el.id ? '#' + el.id : '') +\n (elClassName ? '.' + elClassName.split(' ').filter(c => c).join('.') : '')\n\n return {\n url: sourceFile,\n line: sourceLine,\n column: sourceColumn,\n selector: selector,\n hint: sourceFile ? 'File: ' + sourceFile : 'Element: ' + selector\n }\n }\n\n function enableInspectMode() {\n isInspectMode = true\n overlay && overlay.classList.add('active')\n document.body.style.cursor = 'crosshair'\n\n // ꛓꖰꂬ굮 inspect ęŒ‰é’®ēŠ¶ę€\n if (inspectBtn) inspectBtn.classList.add('active')\n\n // ę£€ęŸ„å…ƒē“ ę˜Æå¦å±žäŗŽ dev tools\n function isDevToolElement(el) {\n if (!el) return false\n // ę£€ęŸ„å…ƒē“ ęœ¬čŗ«\n if (el.dataset && el.dataset.devTool === 'true') return true\n // ę£€ęŸ„ēˆ¶å…ƒē“ \n let parent = el.parentElement\n while (parent) {\n if (parent.dataset && parent.dataset.devTool === 'true') return true\n parent = parent.parentElement\n }\n return false\n }\n\n const onMouseMove = async (e) => {\n if (!isInspectMode) return\n const el = document.elementFromPoint(e.clientX, e.clientY)\n // 忽畄 dev tools å…ƒē“ å’Œ overlay\n if (el && el !== overlay && !isDevToolElement(el) && (!overlay || !overlay.contains(el))) {\n highlightElement(el)\n }\n }\n\n const onClick = async (e) => {\n if (!isInspectMode) return\n e.preventDefault()\n e.stopPropagation()\n\n const el = document.elementFromPoint(e.clientX, e.clientY)\n // 忽畄 dev tools å…ƒē“ å’Œ overlay\n if (el && el !== overlay && !isDevToolElement(el) && (!overlay || !overlay.contains(el))) {\n const location = await getSourceLocation(el)\n if (location) {\n await inspectElement(location, el)\n }\n disableInspectMode()\n }\n }\n\n document.addEventListener('mousemove', onMouseMove, true)\n document.addEventListener('click', onClick, true)\n\n if (overlay) overlay._inspectHandlers = { onMouseMove, onClick }\n }\n\n function disableInspectMode() {\n isInspectMode = false\n if (overlay) overlay.classList.remove('active')\n document.body.style.cursor = ''\n if (overlay) overlay.innerHTML = ''\n\n // ꛓꖰꂬ굮 inspect ęŒ‰é’®ēŠ¶ę€\n if (inspectBtn) inspectBtn.classList.remove('active')\n\n const btn = panel && panel.querySelector('.claude-dev-server-btn-inspect')\n if (btn) btn.classList.remove('active')\n\n const handlers = overlay && overlay._inspectHandlers\n if (handlers) {\n document.removeEventListener('mousemove', handlers.onMouseMove, true)\n document.removeEventListener('click', handlers.onClick, true)\n }\n }\n\n async function inspectElement(location, el) {\n // ęž„å»ŗę ¼å¼åŒ–ēš„ prompt\n const filePath = location.url || location.file || 'unknown'\n const tagName = el.tagName ? el.tagName.toLowerCase() : ''\n const id = el.id ? '#' + el.id : ''\n const className = el.className ? '.' + String(el.className).split(' ').filter(c => c).join('.') : ''\n const selector = tagName + id + className\n\n // čŽ·å–å…ƒē“ ēš„ę–‡ęœ¬å†…å®¹ļ¼ˆå¦‚ęžœę˜Æę–‡ęœ¬čŠ‚ē‚¹ęˆ–ēŸ­ę–‡ęœ¬å…ƒē“ ļ¼‰\n let textContent = ''\n if (el.nodeType === Node.TEXT_NODE) {\n textContent = el.textContent ? el.textContent.trim().substring(0, 50) : ''\n } else if (el.childNodes.length === 1 && el.childNodes[0].nodeType === Node.TEXT_NODE) {\n textContent = el.childNodes[0].textContent ? el.childNodes[0].textContent.trim().substring(0, 50) : ''\n }\n\n // ę ¼å¼: @filename:line <selector> \"text content\"\n let prompt = \\`@\\${filePath}:\\${location.line} <\\${selector}>\\`\n if (textContent) {\n prompt += \\` \"\\${textContent}\"\\`\n }\n\n // å‘é€ęˆåŠŸåŽå±•å¼€é¢ęæ\n const sendToTerminal = () => {\n if (!terminalIframe || !terminalIframe.contentWindow) {\n return false\n }\n\n const win = terminalIframe.contentWindow\n\n // Check if sendToTerminal function is available\n if (win.sendToTerminal) {\n win.sendToTerminal(prompt)\n console.log('[Claude Dev Server] Sent via sendToTerminal:', prompt)\n // å‘é€ęˆåŠŸåŽå±•å¼€é¢ęæ\n setTimeout(() => togglePanel(true), 100)\n return true\n }\n\n return false\n }\n\n // Try immediately\n if (sendToTerminal()) {\n return\n }\n\n // If not ready, wait and retry\n let attempts = 0\n const maxAttempts = 50\n const retryInterval = setInterval(() => {\n attempts++\n if (sendToTerminal() || attempts >= maxAttempts) {\n clearInterval(retryInterval)\n if (attempts >= maxAttempts) {\n console.warn('[Claude Dev Server] Could not send to terminal after retries')\n }\n }\n }, 100)\n }\n\n function loadTerminalIframe(ttydUrl) {\n if (!terminalContainer || terminalIframe) return\n ttydWsUrl = ttydUrl\n\n // Create iframe pointing to ttyd/index.html with ttyd WebSocket URL\n terminalIframe = document.createElement('iframe')\n // Pass the ttyd WebSocket URL as query param\n terminalIframe.src = '/ttyd/index.html?ws=' + encodeURIComponent(ttydUrl)\n terminalIframe.allow = 'clipboard-read; clipboard-write'\n\n // Load event - iframe is ready\n terminalIframe.onload = () => {\n console.log('[Claude Dev Server] Terminal iframe loaded')\n }\n\n terminalContainer.appendChild(terminalIframe)\n }\n\n function createPanel() {\n if (panel) return\n\n panel = document.createElement('div')\n panel.className = 'claude-dev-server-panel'\n panel.innerHTML = \\`\n <div class=\"claude-dev-server-header\">\n <span class=\"claude-dev-server-title\">Claude Code</span>\n <div class=\"claude-dev-server-actions\">\n <button class=\"claude-dev-server-btn claude-dev-server-btn-inspect\" title=\"Inspect Element\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M2 12h20M12 2v20M4.93 4.93l14.14 14.14M19.07 4.93L4.93 19.07\"/>\n </svg>\n Inspect\n </button>\n </div>\n <button class=\"claude-dev-server-close\" aria-label=\"Close\" title=\"Minimize to icon\">&times;</button>\n </div>\n <div class=\"claude-dev-server-terminal\"></div>\n \\`\n\n document.body.appendChild(panel)\n\n terminalContainer = panel.querySelector('.claude-dev-server-terminal')\n const closeBtn = panel.querySelector('.claude-dev-server-close')\n const inspectBtn = panel.querySelector('.claude-dev-server-btn-inspect')\n\n closeBtn && closeBtn.addEventListener('click', () => togglePanel(false))\n\n inspectBtn && inspectBtn.addEventListener('click', () => {\n if (isInspectMode) {\n disableInspectMode()\n } else {\n // 点击 Inspect ę—¶å…ˆę”¶čµ·é¢ęæ\n if (isOpen) {\n togglePanel(false)\n }\n enableInspectMode()\n }\n })\n }\n\n function togglePanel(force) {\n createPanel()\n if (typeof force === 'boolean') {\n isOpen = force\n } else {\n isOpen = !isOpen\n }\n\n if (panel) panel.classList.toggle('open', isOpen)\n if (toggleBtn) toggleBtn.classList.toggle('hidden', isOpen)\n\n if (isOpen) {\n // Focus iframe when panel opens\n if (terminalIframe && terminalIframe.contentWindow) {\n setTimeout(() => {\n if (terminalIframe.contentWindow.terminalInstance) {\n terminalIframe.contentWindow.terminalInstance.focus()\n }\n }, 100)\n }\n }\n }\n\n function connect(port) {\n const WS_URL = 'ws://localhost:' + port\n ws = new WebSocket(WS_URL)\n\n ws.onopen = () => {\n console.log('[Claude Dev Server] Connected to control server')\n }\n\n ws.onmessage = (e) => {\n try {\n const msg = JSON.parse(e.data)\n console.log('[Claude Dev Server] Received message:', msg.type, msg)\n if (msg.type === 'ready' && msg.ttydUrl) {\n loadTerminalIframe(msg.ttydUrl)\n } else if (msg.type === 'inspectResult') {\n if (msg.location) {\n showContextPanel(msg.location, null, false)\n }\n }\n } catch (err) {\n console.error('[Claude Dev Server] Message parse error:', err)\n }\n }\n\n ws.onclose = () => {\n console.log('[Claude Dev Server] Control WebSocket disconnected, reconnecting...')\n setTimeout(() => connect(port), 2000)\n }\n\n ws.onerror = (err) => {\n console.error('[Claude Dev Server] Control WebSocket error:', err)\n }\n }\n\n initWhenReady()\n\n document.addEventListener('keydown', (e) => {\n if ((e.metaKey || e.ctrlKey) && e.code === 'Backquote') {\n e.preventDefault()\n togglePanel()\n }\n if (e.key === 'Escape' && isOpen) {\n togglePanel(false)\n }\n if (e.key === 'Escape' && isInspectMode) {\n disableInspectMode()\n }\n })\n})()\n`\n","import { spawn } from 'child_process'\nimport { existsSync, readFileSync } from 'fs'\nimport { join, dirname } from 'path'\nimport http from 'http'\nimport { fileURLToPath } from 'url'\nimport { createProxyMiddleware } from 'http-proxy-middleware'\nimport { WebSocketServer } from 'ws'\nimport { createWebSocketServer } from '../server/websocket.js'\nimport { CLIENT_SCRIPT, CLIENT_STYLES } from '../client/injection.js'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = dirname(__filename)\n\nexport interface UniversalServerOptions {\n port?: number\n claudePath?: string\n claudeArgs?: string[]\n cwd?: string\n server?: {\n type?: 'vite' | 'next' | 'webpack' | 'custom'\n command?: string\n port?: number\n }\n}\n\nexport async function startUniversalServer(options: UniversalServerOptions = {}) {\n const cwd = options.cwd || process.cwd()\n const port = options.port || 3000\n\n // 1. ę£€ęµ‹é”¹ē›®ē±»åž‹\n const projectType = options.server?.type || detectProjectType(cwd)\n const targetCommand = options.server?.command || getDefaultCommand(projectType)\n\n console.log(`[Claude Dev Server] Detected project type: ${projectType}`)\n console.log(`[Claude Dev Server] Starting target server...`)\n\n // 2. åÆåŠØē›®ę ‡ dev serverļ¼ˆäøé¢„č®¾ē«Æå£ļ¼‰\n const targetServer = spawnTargetServer(targetCommand, cwd)\n\n // 3. ē­‰å¾…å¹¶ę£€ęµ‹ē›®ę ‡ęœåŠ”å™Øå®žé™…ē›‘å¬ēš„ē«Æå£\n console.log(`[Claude Dev Server] Waiting for target server to start (PID: ${targetServer.pid})...`)\n const targetPort = await detectServerPort(targetServer, 30000)\n\n if (!targetPort) {\n throw new Error('Failed to detect target server port. Please check if the dev server started successfully.')\n }\n\n console.log(`[Claude Dev Server] Target server is running on port ${targetPort}`)\n\n // 4. åÆåŠØęŽ§åˆ¶ WebSocket ęœåŠ”å™Øļ¼ˆttyd + Claude)\n const wsServer = createWebSocketServer({\n port: 0, // č‡ŖåŠØåˆ†é…ē«Æå£\n projectRoot: cwd,\n claudePath: options.claudePath || 'claude',\n claudeArgs: options.claudeArgs || [],\n })\n\n const { wsPort, ttydPort } = await wsServer.start()\n console.log(`[Claude Dev Server] Control server running on ws://localhost:${wsPort}`)\n console.log(`[Claude Dev Server] ttyd running on ws://localhost:${ttydPort}`)\n\n // 5. 启动 HTTP ä»£ē†ęœåŠ”å™Ø\n const proxyServer = createProxyServer(targetPort, wsPort, cwd)\n proxyServer.listen(port)\n console.log(`[Claude Dev Server] Proxy server running on http://localhost:${port}`)\n console.log(`\\nšŸš€ Ready! Open http://localhost:${port} in your browser`)\n\n // 清理处理\n const cleanup = () => {\n console.log('[Claude Dev Server] Shutting down...')\n targetServer.kill()\n wsServer.stop()\n proxyServer.close()\n process.exit(0)\n }\n\n process.on('SIGINT', cleanup)\n process.on('SIGTERM', cleanup)\n\n return { proxyServer, targetServer, wsServer }\n}\n\nfunction detectProjectType(cwd: string): 'vite' | 'next' | 'webpack' | 'custom' {\n if (existsSync(join(cwd, 'vite.config.ts')) || existsSync(join(cwd, 'vite.config.js'))) {\n return 'vite'\n }\n if (existsSync(join(cwd, 'next.config.js')) || existsSync(join(cwd, 'next.config.mjs'))) {\n return 'next'\n }\n if (existsSync(join(cwd, 'webpack.config.js')) || existsSync(join(cwd, 'webpack.config.ts'))) {\n return 'webpack'\n }\n return 'custom'\n}\n\nfunction getDefaultCommand(projectType: string): string {\n switch (projectType) {\n case 'vite': return 'npm run dev'\n case 'next': return 'npm run dev'\n case 'webpack': return 'npm run dev'\n default: return 'npm run dev'\n }\n}\n\nfunction spawnTargetServer(command: string, cwd: string) {\n const [cmd, ...args] = command.split(' ')\n const child = spawn(cmd, args, {\n cwd,\n stdio: 'pipe',\n env: process.env,\n })\n\n // Forward child's stdout/stderr to parent so user can see dev server output\n child.stdout?.pipe(process.stdout)\n child.stderr?.pipe(process.stderr)\n\n return child\n}\n\n/**\n * Detect the port that the dev server is listening on by parsing stdout.\n * Most dev servers announce their port on startup like: \"Local: http://localhost:5173\"\n */\nasync function detectServerPort(childProcess: any, timeout: number): Promise<number | null> {\n return new Promise((resolve) => {\n const timeoutId = setTimeout(() => {\n cleanup()\n resolve(null)\n }, timeout)\n\n let stdout = ''\n\n const onData = (chunk: Buffer) => {\n stdout += chunk.toString()\n\n // Match common port announcement patterns:\n // Vite: \"Local: http://localhost:5173/\"\n // Next.js: \"Local: http://localhost:3000\"\n // Webpack: \"http://localhost:8080/\"\n const patterns = [\n /localhost:(\\d{4,5})/,\n /127\\.0\\.0\\.1:(\\d{4,5})/,\n /0\\.0\\.0\\.0:(\\d{4,5})/,\n ]\n\n for (const pattern of patterns) {\n const match = stdout.match(pattern)\n if (match) {\n const port = parseInt(match[1], 10)\n console.log(`[Claude Dev Server] Detected port from stdout: ${port}`)\n cleanup()\n resolve(port)\n return\n }\n }\n }\n\n const cleanup = () => {\n clearTimeout(timeoutId)\n childProcess.stdout?.off('data', onData)\n }\n\n childProcess.stdout?.on('data', onData)\n })\n}\n\nfunction createProxyServer(targetPort: number, wsPort: number, projectRoot: string) {\n // čÆ»å– ttyd 资源文件\n // ä»Žå½“å‰ęØ”å—č·Æå¾„č®”ē®— assets 目录\n // moduleDir 是 /Users/lloyd/moox/claude-dev-server/dist\n // ę‰€ä»„éœ€č¦ assets 是 /Users/lloyd/moox/claude-dev-server/dist/assets\n const moduleDir = dirname(fileURLToPath(import.meta.url))\n const assetsPath = join(moduleDir, 'assets')\n\n let ttydHtml: string\n let ttydBridgeJs: string\n\n try {\n ttydHtml = readFileSync(join(assetsPath, 'ttyd-terminal.html'), 'utf-8')\n ttydBridgeJs = readFileSync(join(assetsPath, 'ttyd-bridge.js'), 'utf-8')\n } catch (e: any) {\n console.error('[Claude Dev Server] Failed to read ttyd assets from', assetsPath)\n console.error('[Claude Dev Server] moduleDir:', moduleDir)\n console.error('[Claude Dev Server] Error:', e.message)\n throw new Error('ttyd assets not found. Please run `npm run build` first.')\n }\n\n return http.createServer((req, res) => {\n // 处理 @claude-port 端点\n if (req.url === '/@claude-port') {\n res.setHeader('Content-Type', 'application/json')\n res.end(JSON.stringify({ port: wsPort }))\n return\n }\n\n // 处理 /ttyd/* č·Æē”±\n if (req.url?.startsWith('/ttyd/')) {\n const urlPath = req.url.split('?')[0] // ē§»é™¤ęŸ„čÆ¢å‚ę•°\n\n if (urlPath === '/ttyd/index.html' || urlPath === '/ttyd/') {\n res.setHeader('Content-Type', 'text/html')\n res.end(ttydHtml)\n return\n }\n\n if (urlPath === '/ttyd/ttyd-bridge.js') {\n res.setHeader('Content-Type', 'application/javascript')\n res.end(ttydBridgeJs)\n return\n }\n\n // 其他 /ttyd/* č·Æē”±čæ”å›ž 404\n res.statusCode = 404\n res.end('Not found')\n return\n }\n\n // ä»£ē†åˆ°ē›®ę ‡ęœåŠ”å™Øå¹¶ę³Øå…„č„šęœ¬\n const options = {\n hostname: 'localhost',\n port: targetPort,\n path: req.url,\n method: req.method,\n headers: req.headers,\n }\n\n const proxyReq = http.request(options, (proxyRes) => {\n // ę³Øå…„č„šęœ¬åˆ° HTML\n if (proxyRes.headers['content-type']?.includes('text/html')) {\n const body: Buffer[] = []\n proxyRes.on('data', (chunk) => body.push(chunk))\n proxyRes.on('end', () => {\n const html = Buffer.concat(body).toString('utf8')\n const injected = injectScripts(html, wsPort, projectRoot)\n const statusCode = proxyRes.statusCode || 200\n res.writeHead(statusCode, {\n ...proxyRes.headers,\n 'content-length': Buffer.byteLength(injected),\n })\n res.end(injected)\n })\n } else {\n const statusCode = proxyRes.statusCode || 200\n res.writeHead(statusCode, proxyRes.headers)\n proxyRes.pipe(res)\n }\n })\n\n proxyReq.on('error', (err) => {\n console.error('[Claude Dev Server] Proxy error:', err)\n res.statusCode = 502\n res.end('Bad Gateway')\n })\n\n req.pipe(proxyReq)\n })\n}\n\nfunction injectScripts(html: string, wsPort: number, projectRoot: string): string {\n const projectRootScript = `<script>window.__CLAUDE_PROJECT_ROOT__ = ${JSON.stringify(projectRoot)}</script>`\n\n return html.replace(\n '</head>',\n `<!-- Claude Dev Server -->\\n${CLIENT_STYLES}\\n${projectRootScript}\\n<script type=\"module\">${CLIENT_SCRIPT}</script>\\n</head>`\n ).replace(\n /wsPort:\\s*\\d+/,\n `wsPort: ${wsPort}`\n )\n}\n"]}
package/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/cli.js ADDED
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env node
2
+ import { startUniversalServer } from './chunk-DOLSA776.js';
3
+ import { execSync } from 'child_process';
4
+
5
+ async function checkTtyd() {
6
+ try {
7
+ execSync("which ttyd", { stdio: "ignore" });
8
+ return true;
9
+ } catch {
10
+ return false;
11
+ }
12
+ }
13
+ async function main() {
14
+ const args = process.argv.slice(2);
15
+ const options = {
16
+ port: 3e3,
17
+ claudePath: "claude"
18
+ };
19
+ for (let i = 0; i < args.length; i++) {
20
+ if (args[i] === "-p" || args[i] === "--port") {
21
+ options.port = parseInt(args[++i]);
22
+ } else if (args[i] === "--claude-path") {
23
+ options.claudePath = args[++i];
24
+ } else if (args[i] === "-h" || args[i] === "--help") {
25
+ console.log(`
26
+ Claude Dev Server - Universal dev server wrapper with Claude Code AI
27
+
28
+ Usage:
29
+ npx claude-dev-server [options]
30
+
31
+ Options:
32
+ -p, --port <port> Port for the proxy server (default: 3000)
33
+ --claude-path <path> Path to Claude executable (default: claude)
34
+ -h, --help Show this help
35
+
36
+ Examples:
37
+ npx claude-dev-server
38
+ npx claude-dev-server --port 4000
39
+ `);
40
+ process.exit(0);
41
+ }
42
+ }
43
+ const hasTtyd = await checkTtyd();
44
+ if (!hasTtyd) {
45
+ console.error("\u274C ttyd is not installed. Please install it first:");
46
+ console.error(" macOS: brew install ttyd");
47
+ console.error(" Linux: sudo apt install ttyd # Debian/Ubuntu");
48
+ console.error(" or build from source: https://github.com/tsl0922/ttyd");
49
+ process.exit(1);
50
+ }
51
+ try {
52
+ await startUniversalServer(options);
53
+ } catch (error) {
54
+ console.error("Failed to start server:", error);
55
+ process.exit(1);
56
+ }
57
+ }
58
+ main();
59
+ //# sourceMappingURL=cli.js.map
60
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/universal/cli.ts"],"names":[],"mappings":";;;;AAIA,eAAe,SAAA,GAA8B;AAC3C,EAAA,IAAI;AACF,IAAA,QAAA,CAAS,YAAA,EAAc,EAAE,KAAA,EAAO,QAAA,EAAU,CAAA;AAC1C,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAEA,eAAe,IAAA,GAAO;AACpB,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA;AAGjC,EAAA,MAAM,OAAA,GAAU;AAAA,IACd,IAAA,EAAM,GAAA;AAAA,IACN,UAAA,EAAY;AAAA,GACd;AAEA,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,QAAQ,CAAA,EAAA,EAAK;AACpC,IAAA,IAAI,KAAK,CAAC,CAAA,KAAM,QAAQ,IAAA,CAAK,CAAC,MAAM,QAAA,EAAU;AAC5C,MAAA,OAAA,CAAQ,IAAA,GAAO,QAAA,CAAS,IAAA,CAAK,EAAE,CAAC,CAAC,CAAA;AAAA,IACnC,CAAA,MAAA,IAAW,IAAA,CAAK,CAAC,CAAA,KAAM,eAAA,EAAiB;AACtC,MAAA,OAAA,CAAQ,UAAA,GAAa,IAAA,CAAK,EAAE,CAAC,CAAA;AAAA,IAC/B,CAAA,MAAA,IAAW,KAAK,CAAC,CAAA,KAAM,QAAQ,IAAA,CAAK,CAAC,MAAM,QAAA,EAAU;AACnD,MAAA,OAAA,CAAQ,GAAA,CAAI;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA,MAAA,CAcX,CAAA;AACD,MAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAChB;AAAA,EACF;AAGA,EAAA,MAAM,OAAA,GAAU,MAAM,SAAA,EAAU;AAChC,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,OAAA,CAAQ,MAAM,wDAAmD,CAAA;AACjE,IAAA,OAAA,CAAQ,MAAM,6BAA6B,CAAA;AAC3C,IAAA,OAAA,CAAQ,MAAM,kDAAkD,CAAA;AAChE,IAAA,OAAA,CAAQ,MAAM,iEAAiE,CAAA;AAC/E,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAGA,EAAA,IAAI;AACF,IAAA,MAAM,qBAAqB,OAAO,CAAA;AAAA,EACpC,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,2BAA2B,KAAK,CAAA;AAC9C,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AACF;AAEA,IAAA,EAAK","file":"cli.js","sourcesContent":["#!/usr/bin/env node\nimport { startUniversalServer } from './index.js'\nimport { execSync } from 'child_process'\n\nasync function checkTtyd(): Promise<boolean> {\n try {\n execSync('which ttyd', { stdio: 'ignore' })\n return true\n } catch {\n return false\n }\n}\n\nasync function main() {\n const args = process.argv.slice(2)\n\n // Parse args\n const options = {\n port: 3000,\n claudePath: 'claude',\n }\n\n for (let i = 0; i < args.length; i++) {\n if (args[i] === '-p' || args[i] === '--port') {\n options.port = parseInt(args[++i])\n } else if (args[i] === '--claude-path') {\n options.claudePath = args[++i]\n } else if (args[i] === '-h' || args[i] === '--help') {\n console.log(`\nClaude Dev Server - Universal dev server wrapper with Claude Code AI\n\nUsage:\n npx claude-dev-server [options]\n\nOptions:\n -p, --port <port> Port for the proxy server (default: 3000)\n --claude-path <path> Path to Claude executable (default: claude)\n -h, --help Show this help\n\nExamples:\n npx claude-dev-server\n npx claude-dev-server --port 4000\n `)\n process.exit(0)\n }\n }\n\n // Check if ttyd is installed\n const hasTtyd = await checkTtyd()\n if (!hasTtyd) {\n console.error('āŒ ttyd is not installed. Please install it first:')\n console.error(' macOS: brew install ttyd')\n console.error(' Linux: sudo apt install ttyd # Debian/Ubuntu')\n console.error(' or build from source: https://github.com/tsl0922/ttyd')\n process.exit(1)\n }\n\n // Start the universal dev server\n try {\n await startUniversalServer(options)\n } catch (error) {\n console.error('Failed to start server:', error)\n process.exit(1)\n }\n}\n\nmain()\n"]}
@@ -0,0 +1,27 @@
1
+ import * as child_process from 'child_process';
2
+ import http from 'http';
3
+
4
+ interface UniversalServerOptions {
5
+ port?: number;
6
+ claudePath?: string;
7
+ claudeArgs?: string[];
8
+ cwd?: string;
9
+ server?: {
10
+ type?: 'vite' | 'next' | 'webpack' | 'custom';
11
+ command?: string;
12
+ port?: number;
13
+ };
14
+ }
15
+ declare function startUniversalServer(options?: UniversalServerOptions): Promise<{
16
+ proxyServer: http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>;
17
+ targetServer: child_process.ChildProcessWithoutNullStreams;
18
+ wsServer: {
19
+ start: () => Promise<{
20
+ wsPort: number;
21
+ ttydPort: number;
22
+ }>;
23
+ stop: () => void;
24
+ };
25
+ }>;
26
+
27
+ export { type UniversalServerOptions, startUniversalServer };
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { startUniversalServer } from './chunk-DOLSA776.js';
2
+ //# sourceMappingURL=index.js.map
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "claude-dev-server",
3
+ "version": "1.0.2",
4
+ "description": "Universal dev server wrapper with Claude Code AI assistant - works with Vite, Next.js, Webpack and more",
5
+ "author": "lloydzhou",
6
+ "license": "MIT",
7
+ "email": "lloydzhou@qq.com",
8
+ "type": "module",
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "bin": {
12
+ "claude-dev-server": "./dist/cli.js"
13
+ },
14
+ "exports": {
15
+ ".": {
16
+ "import": "./dist/index.js",
17
+ "types": "./dist/index.d.ts"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "dist/assets"
23
+ ],
24
+ "scripts": {
25
+ "build": "tsup",
26
+ "dev": "tsup --watch",
27
+ "typecheck": "tsc --noEmit",
28
+ "prepublishOnly": "npm run build"
29
+ },
30
+ "keywords": [
31
+ "claude",
32
+ "claude-code",
33
+ "ai-assistant",
34
+ "developer-tools",
35
+ "cli",
36
+ "terminal",
37
+ "ttyd",
38
+ "dev-server",
39
+ "vite",
40
+ "nextjs",
41
+ "webpack"
42
+ ],
43
+ "dependencies": {
44
+ "ws": "^8.18.0",
45
+ "http-proxy-middleware": "^2.0.6"
46
+ },
47
+ "devDependencies": {
48
+ "@types/node": "^20.14.11",
49
+ "@types/ws": "^8.5.12",
50
+ "tsup": "^8.2.4",
51
+ "typescript": "^5.5.3"
52
+ },
53
+ "engines": {
54
+ "node": ">=18.0.0"
55
+ }
56
+ }