@willjackson/claude-code-bridge 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -116,6 +116,14 @@ claude-bridge start --port 8766 --launch-claude
116
116
 
117
117
  This starts the bridge daemon and launches Claude Code with access to the remote bridge MCP tools.
118
118
 
119
+ **With Claude flags** (e.g., skip permissions):
120
+
121
+ ```bash
122
+ claude-bridge start --port 8766 --launch-claude -- --dangerously-skip-permissions
123
+ ```
124
+
125
+ Any arguments after `--` are passed directly to the `claude` command.
126
+
119
127
  ### Step 4: Start the Client on Remote Machine
120
128
 
121
129
  On the **remote machine** (server, container, VM):
@@ -172,7 +180,7 @@ Options:
172
180
  #### `start` - Start the Bridge Server
173
181
 
174
182
  ```bash
175
- claude-bridge start [options]
183
+ claude-bridge start [options] [-- claude-args...]
176
184
 
177
185
  Options:
178
186
  -p, --port <port> Port to listen on (default: 8765)
@@ -181,6 +189,8 @@ Options:
181
189
  -d, --daemon Run in background
182
190
  --with-handlers Enable file operations and task handling (read/write/delete files)
183
191
  --launch-claude Start bridge daemon and launch Claude Code
192
+
193
+ Arguments after -- are passed to the claude command when using --launch-claude.
184
194
  ```
185
195
 
186
196
  **Examples:**
@@ -189,19 +199,22 @@ Options:
189
199
  # Start bridge and launch Claude Code (recommended for local use)
190
200
  claude-bridge start --port 8766 --launch-claude
191
201
 
202
+ # Start bridge and launch Claude with --dangerously-skip-permissions
203
+ claude-bridge start --port 8766 --launch-claude -- --dangerously-skip-permissions
204
+
192
205
  # Start with default settings
193
206
  claude-bridge start
194
207
 
195
208
  # Start on specific port
196
209
  claude-bridge start --port 9000
197
210
 
198
- # Start and connect to remote bridge
199
- claude-bridge start --connect ws://192.168.1.100:8765
211
+ # Start and connect to host (client mode)
212
+ claude-bridge start --connect ws://192.168.1.100:8766
200
213
 
201
214
  # Start in daemon mode
202
215
  claude-bridge start --daemon
203
216
 
204
- # Start with file operation handlers enabled (for remote machines)
217
+ # Start with file operation handlers enabled (for remote/client machines)
205
218
  claude-bridge start --with-handlers --connect ws://192.168.1.100:8766
206
219
  ```
207
220
 
package/dist/cli.js CHANGED
@@ -492,9 +492,13 @@ async function startBridge(options, globalOptions) {
492
492
  const { running, pid } = isAlreadyRunning();
493
493
  if (running) {
494
494
  if (options.launchClaude) {
495
+ const claudeArgs = options.claudeArgs || [];
495
496
  console.log(`Bridge already running (PID: ${pid}), launching Claude Code...`);
497
+ if (claudeArgs.length > 0) {
498
+ console.log(` Claude args: ${claudeArgs.join(" ")}`);
499
+ }
496
500
  const { spawnSync } = await import("child_process");
497
- const result = spawnSync("claude", [], {
501
+ const result = spawnSync("claude", claudeArgs, {
498
502
  stdio: "inherit",
499
503
  shell: true
500
504
  });
@@ -532,10 +536,14 @@ async function startBridge(options, globalOptions) {
532
536
  console.log(` Use 'claude-bridge status' to check status`);
533
537
  console.log(` Use 'claude-bridge stop' to stop the bridge`);
534
538
  if (options.launchClaude) {
539
+ const claudeArgs = options.claudeArgs || [];
535
540
  console.log("\nLaunching Claude Code...");
541
+ if (claudeArgs.length > 0) {
542
+ console.log(` Claude args: ${claudeArgs.join(" ")}`);
543
+ }
536
544
  await new Promise((resolve2) => setTimeout(resolve2, 500));
537
545
  const { spawnSync } = await import("child_process");
538
- const result = spawnSync("claude", [], {
546
+ const result = spawnSync("claude", claudeArgs, {
539
547
  stdio: "inherit",
540
548
  shell: true
541
549
  });
@@ -591,7 +599,8 @@ To connect from another bridge:`);
591
599
  }
592
600
  function createStartCommand() {
593
601
  const command = new Command("start");
594
- command.description("Start the bridge server").option("-p, --port <port>", "Port to listen on (default: 8765)").option("-h, --host <host>", "Host to bind to (default: 0.0.0.0)").option("-c, --connect <url>", "URL to connect to on startup (e.g., ws://localhost:8765)").option("-d, --daemon", "Run in background").option("--with-handlers", "Enable file reading and task handling capabilities").option("--launch-claude", "Start bridge daemon and launch Claude Code").action(async (options) => {
602
+ command.description("Start the bridge server").option("-p, --port <port>", "Port to listen on (default: 8765)").option("-h, --host <host>", "Host to bind to (default: 0.0.0.0)").option("-c, --connect <url>", "URL to connect to on startup (e.g., ws://localhost:8765)").option("-d, --daemon", "Run in background").option("--with-handlers", "Enable file reading and task handling capabilities").option("--launch-claude", "Start bridge daemon and launch Claude Code").argument("[claude-args...]", "Arguments to pass to Claude Code (use after --)").action(async (claudeArgs, options) => {
603
+ options.claudeArgs = claudeArgs;
595
604
  if (options.launchClaude) {
596
605
  options.daemon = true;
597
606
  }
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/index.ts","../src/cli/commands/start.ts","../src/cli/utils.ts","../src/cli/commands/stop.ts","../src/cli/commands/status.ts","../src/cli/commands/connect.ts","../src/cli/commands/info.ts","../src/cli/commands/mcp-server.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * CLI entry point for claude-code-bridge\n *\n * Commands:\n * start Start the bridge server\n * stop Stop the running bridge\n * status Show bridge status and connected peers\n * connect Connect to a remote bridge\n * info Show system and configuration info\n *\n * Global options:\n * --verbose, -v Enable verbose logging\n * --config Path to config file\n */\n\nimport { Command } from 'commander';\nimport { createLogger } from '../utils/logger.js';\nimport { createStartCommand } from './commands/start.js';\nimport { createStopCommand } from './commands/stop.js';\nimport { createStatusCommand } from './commands/status.js';\nimport { createConnectCommand } from './commands/connect.js';\nimport { createInfoCommand } from './commands/info.js';\nimport { createMcpServerCommand } from './commands/mcp-server.js';\n\n// Read version from package.json\n// Since we're building with tsup, we import it directly\nconst VERSION = '0.1.0';\n\nconst logger = createLogger('cli');\n\n/**\n * Global options interface\n */\nexport interface GlobalOptions {\n verbose?: boolean;\n config?: string;\n}\n\n/**\n * Create and configure the CLI program\n */\nexport function createProgram(): Command {\n const program = new Command();\n\n program\n .name('claude-bridge')\n .description('Bidirectional communication system for Claude Code instances across environments')\n .version(VERSION, '-V, --version', 'Output the version number')\n .option('-v, --verbose', 'Enable verbose logging')\n .option('--config <path>', 'Path to config file');\n\n // Hook to process global options before commands\n program.hook('preAction', (thisCommand) => {\n const opts = thisCommand.opts() as GlobalOptions;\n if (opts.verbose) {\n // Set log level to debug when verbose is enabled\n process.env.LOG_LEVEL = 'debug';\n }\n });\n\n return program;\n}\n\n/**\n * Get global options from the program\n */\nexport function getGlobalOptions(program: Command): GlobalOptions {\n return program.opts() as GlobalOptions;\n}\n\n/**\n * Main CLI entry point\n */\nexport async function main(): Promise<void> {\n const program = createProgram();\n\n // Add commands\n program.addCommand(createStartCommand());\n program.addCommand(createStopCommand());\n program.addCommand(createStatusCommand());\n program.addCommand(createConnectCommand());\n program.addCommand(createInfoCommand());\n program.addCommand(createMcpServerCommand());\n\n // Parse arguments and execute\n await program.parseAsync(process.argv);\n}\n\n// Run CLI if executed directly\nmain().catch((error: Error) => {\n logger.error({ err: error }, 'CLI error');\n process.exit(1);\n});\n\n// Export for programmatic use\nexport { createProgram as createCLI };\n","/**\n * CLI start command - Start the bridge server\n *\n * Options:\n * --port, -p Port to listen on (default: 8765)\n * --host, -h Host to bind to (default: 0.0.0.0)\n * --connect, -c URL to connect to on startup\n * --daemon, -d Run in background\n * --with-handlers Enable file reading and task handling capabilities\n * --launch-claude Start bridge daemon and launch Claude Code\n */\n\nimport { Command } from 'commander';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { spawn } from 'child_process';\nimport { minimatch } from 'minimatch';\nimport { createLogger } from '../../utils/logger.js';\nimport { loadConfigSync, type BridgeConfig as UtilsBridgeConfig } from '../../utils/config.js';\nimport { Bridge, type BridgeConfig, type BridgeMode, type TaskRequest, type FileChunk } from '../../bridge/core.js';\nimport { setupGracefulShutdown, handleUnhandledRejections } from '../utils.js';\nimport type { GlobalOptions } from '../index.js';\n\nconst logger = createLogger('cli:start');\n\n/**\n * Options for the start command\n */\nexport interface StartCommandOptions {\n port?: string;\n host?: string;\n connect?: string;\n daemon?: boolean;\n withHandlers?: boolean;\n launchClaude?: boolean;\n}\n\n/**\n * Get the PID file path\n */\nfunction getPidFilePath(): string {\n const bridgeDir = path.join(os.homedir(), '.claude-bridge');\n return path.join(bridgeDir, 'bridge.pid');\n}\n\n/**\n * Ensure the .claude-bridge directory exists\n */\nfunction ensureBridgeDir(): void {\n const bridgeDir = path.join(os.homedir(), '.claude-bridge');\n if (!fs.existsSync(bridgeDir)) {\n fs.mkdirSync(bridgeDir, { recursive: true });\n }\n}\n\n/**\n * Write PID file for daemon mode\n */\nfunction writePidFile(pid: number): void {\n ensureBridgeDir();\n const pidFile = getPidFilePath();\n fs.writeFileSync(pidFile, pid.toString(), 'utf-8');\n}\n\n/**\n * Remove PID file on shutdown\n */\nfunction removePidFile(): void {\n const pidFile = getPidFilePath();\n if (fs.existsSync(pidFile)) {\n fs.unlinkSync(pidFile);\n }\n}\n\n/**\n * Check if a bridge is already running by checking the PID file\n */\nfunction isAlreadyRunning(): { running: boolean; pid?: number } {\n const pidFile = getPidFilePath();\n if (!fs.existsSync(pidFile)) {\n return { running: false };\n }\n\n try {\n const pid = parseInt(fs.readFileSync(pidFile, 'utf-8').trim(), 10);\n // Check if process is still running\n process.kill(pid, 0); // Signal 0 checks existence without killing\n return { running: true, pid };\n } catch {\n // Process doesn't exist, clean up stale PID file\n removePidFile();\n return { running: false };\n }\n}\n\n/**\n * Get all files in a directory recursively\n */\nfunction getFilesRecursively(dir: string, baseDir: string = dir): string[] {\n const files: string[] = [];\n\n try {\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n const relativePath = path.relative(baseDir, fullPath);\n\n if (entry.isDirectory()) {\n // Skip common directories\n if (['node_modules', '.git', 'dist', 'build', '.next', 'coverage'].includes(entry.name)) {\n continue;\n }\n files.push(...getFilesRecursively(fullPath, baseDir));\n } else if (entry.isFile()) {\n files.push(relativePath);\n }\n }\n } catch {\n // Ignore permission errors\n }\n\n return files;\n}\n\n/**\n * Check if a file matches any of the patterns\n */\nfunction matchesPatterns(filePath: string, patterns: string[]): boolean {\n return patterns.some(pattern => minimatch(filePath, pattern, { dot: true }));\n}\n\n/**\n * Read file contents safely\n */\nfunction readFileSafe(filePath: string, maxSize: number = 100000): string | null {\n try {\n const stats = fs.statSync(filePath);\n if (stats.size > maxSize) {\n return `[File too large: ${stats.size} bytes]`;\n }\n return fs.readFileSync(filePath, 'utf-8');\n } catch {\n return null;\n }\n}\n\n/**\n * Register handlers for file reading and task processing\n */\nfunction registerHandlers(\n bridge: Bridge,\n config: { includePatterns: string[]; excludePatterns: string[] }\n): void {\n const cwd = process.cwd();\n\n // Handler for context requests - find and return relevant files\n bridge.onContextRequested(async (query: string, peerId: string): Promise<FileChunk[]> => {\n logger.info({ query, peerId }, 'Context requested');\n\n const files = getFilesRecursively(cwd);\n const chunks: FileChunk[] = [];\n const queryLower = query.toLowerCase();\n const queryTerms = queryLower.split(/\\s+/).filter(t => t.length > 2);\n\n for (const file of files) {\n // Check exclude patterns\n if (matchesPatterns(file, config.excludePatterns)) {\n continue;\n }\n\n // Check if file matches query or include patterns\n const fileLower = file.toLowerCase();\n const matchesQuery = queryTerms.some(term => fileLower.includes(term));\n const matchesInclude = matchesPatterns(file, config.includePatterns);\n\n if (matchesQuery || matchesInclude) {\n const fullPath = path.join(cwd, file);\n const content = readFileSafe(fullPath);\n\n if (content !== null) {\n chunks.push({\n path: file,\n content,\n language: path.extname(file).slice(1) || undefined,\n });\n }\n\n // Limit number of files returned\n if (chunks.length >= 20) {\n break;\n }\n }\n }\n\n logger.info({ fileCount: chunks.length, query }, 'Context response prepared');\n return chunks;\n });\n\n // Handler for incoming tasks\n bridge.onTaskReceived(async (task: TaskRequest, peerId: string) => {\n logger.info({ taskId: task.id, description: task.description, peerId }, 'Task received');\n\n // Check for file operations in task data\n const taskData = task.data as Record<string, unknown> | undefined;\n const action = taskData?.action as string | undefined;\n\n // Log incoming command details to console\n console.log('\\n┌─────────────────────────────────────────────────────────────');\n console.log(`│ 📥 INCOMING TASK: ${task.description}`);\n console.log(`│ ID: ${task.id}`);\n console.log(`│ Scope: ${task.scope}`);\n if (action) {\n console.log(`│ Action: ${action}`);\n if (taskData?.path) {\n console.log(`│ Path: ${taskData.path}`);\n }\n }\n console.log('└─────────────────────────────────────────────────────────────\\n');\n\n // Handle file write action\n if (taskData?.action === 'write_file') {\n const filePath = taskData.path as string;\n const content = taskData.content as string;\n\n if (!filePath || content === undefined) {\n console.log(' ❌ RESULT: write_file requires path and content');\n return {\n success: false,\n data: { error: 'write_file requires path and content' },\n };\n }\n\n // Resolve path relative to cwd\n const fullPath = path.isAbsolute(filePath) ? filePath : path.join(cwd, filePath);\n\n // Security: ensure path is within cwd\n const resolvedPath = path.resolve(fullPath);\n const resolvedCwd = path.resolve(cwd);\n if (!resolvedPath.startsWith(resolvedCwd)) {\n console.log(' ❌ RESULT: Cannot write files outside project directory');\n return {\n success: false,\n data: { error: 'Cannot write files outside project directory' },\n };\n }\n\n try {\n // Ensure parent directory exists\n const parentDir = path.dirname(resolvedPath);\n if (!fs.existsSync(parentDir)) {\n fs.mkdirSync(parentDir, { recursive: true });\n }\n\n fs.writeFileSync(resolvedPath, content, 'utf-8');\n const bytesWritten = Buffer.byteLength(content, 'utf-8');\n logger.info({ path: filePath }, 'File written successfully');\n console.log(` ✅ RESULT: Wrote ${bytesWritten} bytes to ${filePath}`);\n\n return {\n success: true,\n data: {\n action: 'write_file',\n path: filePath,\n bytesWritten,\n },\n };\n } catch (err) {\n logger.error({ error: (err as Error).message, path: filePath }, 'Failed to write file');\n console.log(` ❌ RESULT: Failed to write file: ${(err as Error).message}`);\n return {\n success: false,\n data: { error: `Failed to write file: ${(err as Error).message}` },\n };\n }\n }\n\n // Handle file read action\n if (taskData?.action === 'read_file') {\n const filePath = taskData.path as string;\n\n if (!filePath) {\n console.log(' ❌ RESULT: read_file requires path');\n return {\n success: false,\n data: { error: 'read_file requires path' },\n };\n }\n\n const fullPath = path.isAbsolute(filePath) ? filePath : path.join(cwd, filePath);\n const content = readFileSafe(fullPath);\n\n if (content === null) {\n console.log(` ❌ RESULT: Cannot read file: ${filePath}`);\n return {\n success: false,\n data: { error: `Cannot read file: ${filePath}` },\n };\n }\n\n console.log(` ✅ RESULT: Read ${content.length} chars from ${filePath}`);\n return {\n success: true,\n data: {\n action: 'read_file',\n path: filePath,\n content,\n },\n };\n }\n\n // Handle delete file action\n if (taskData?.action === 'delete_file') {\n const filePath = taskData.path as string;\n\n if (!filePath) {\n console.log(' ❌ RESULT: delete_file requires path');\n return {\n success: false,\n data: { error: 'delete_file requires path' },\n };\n }\n\n const fullPath = path.isAbsolute(filePath) ? filePath : path.join(cwd, filePath);\n\n // Security: ensure path is within cwd\n const resolvedPath = path.resolve(fullPath);\n const resolvedCwd = path.resolve(cwd);\n if (!resolvedPath.startsWith(resolvedCwd)) {\n console.log(' ❌ RESULT: Cannot delete files outside project directory');\n return {\n success: false,\n data: { error: 'Cannot delete files outside project directory' },\n };\n }\n\n try {\n if (!fs.existsSync(resolvedPath)) {\n console.log(` ❌ RESULT: File not found: ${filePath}`);\n return {\n success: false,\n data: { error: `File not found: ${filePath}` },\n };\n }\n\n fs.unlinkSync(resolvedPath);\n logger.info({ path: filePath }, 'File deleted successfully');\n console.log(` ✅ RESULT: Deleted ${filePath}`);\n\n return {\n success: true,\n data: {\n action: 'delete_file',\n path: filePath,\n },\n };\n } catch (err) {\n logger.error({ error: (err as Error).message, path: filePath }, 'Failed to delete file');\n console.log(` ❌ RESULT: Failed to delete file: ${(err as Error).message}`);\n return {\n success: false,\n data: { error: `Failed to delete file: ${(err as Error).message}` },\n };\n }\n }\n\n // Handle list directory action\n if (taskData?.action === 'list_directory') {\n const dirPath = taskData.path as string;\n\n if (!dirPath) {\n console.log(' ❌ RESULT: list_directory requires path');\n return {\n success: false,\n data: { error: 'list_directory requires path' },\n };\n }\n\n const fullPath = path.isAbsolute(dirPath) ? dirPath : path.join(cwd, dirPath);\n\n // Security: ensure path is within cwd\n const resolvedPath = path.resolve(fullPath);\n const resolvedCwd = path.resolve(cwd);\n if (!resolvedPath.startsWith(resolvedCwd)) {\n console.log(' ❌ RESULT: Cannot list directories outside project directory');\n return {\n success: false,\n data: { error: 'Cannot list directories outside project directory' },\n };\n }\n\n try {\n if (!fs.existsSync(resolvedPath)) {\n console.log(` ❌ RESULT: Directory not found: ${dirPath}`);\n return {\n success: false,\n data: { error: `Directory not found: ${dirPath}` },\n };\n }\n\n const stats = fs.statSync(resolvedPath);\n if (!stats.isDirectory()) {\n console.log(` ❌ RESULT: Not a directory: ${dirPath}`);\n return {\n success: false,\n data: { error: `Not a directory: ${dirPath}` },\n };\n }\n\n const entries = fs.readdirSync(resolvedPath, { withFileTypes: true });\n const listing = entries.map(entry => ({\n name: entry.name,\n type: entry.isDirectory() ? 'directory' : 'file',\n }));\n\n logger.info({ path: dirPath, count: listing.length }, 'Directory listed successfully');\n console.log(` ✅ RESULT: Listed ${listing.length} entries in ${dirPath}`);\n\n return {\n success: true,\n data: {\n action: 'list_directory',\n path: dirPath,\n entries: listing,\n },\n };\n } catch (err) {\n logger.error({ error: (err as Error).message, path: dirPath }, 'Failed to list directory');\n console.log(` ❌ RESULT: Failed to list directory: ${(err as Error).message}`);\n return {\n success: false,\n data: { error: `Failed to list directory: ${(err as Error).message}` },\n };\n }\n }\n\n // Default: Get project info for the response\n const projectInfo: Record<string, unknown> = {\n cwd,\n platform: process.platform,\n nodeVersion: process.version,\n };\n\n // Try to read package.json for project details\n const pkgPath = path.join(cwd, 'package.json');\n if (fs.existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));\n projectInfo.name = pkg.name;\n projectInfo.version = pkg.version;\n projectInfo.description = pkg.description;\n projectInfo.dependencies = Object.keys(pkg.dependencies || {});\n projectInfo.devDependencies = Object.keys(pkg.devDependencies || {});\n } catch {\n // Ignore parse errors\n }\n }\n\n // List top-level files and directories\n try {\n const entries = fs.readdirSync(cwd, { withFileTypes: true });\n projectInfo.structure = entries\n .filter(e => !e.name.startsWith('.') && e.name !== 'node_modules')\n .map(e => ({\n name: e.name,\n type: e.isDirectory() ? 'directory' : 'file',\n }));\n } catch {\n // Ignore errors\n }\n\n // Get source files summary\n const allFiles = getFilesRecursively(cwd);\n const sourceFiles = allFiles.filter(f =>\n matchesPatterns(f, config.includePatterns) &&\n !matchesPatterns(f, config.excludePatterns)\n );\n projectInfo.sourceFileCount = sourceFiles.length;\n projectInfo.sourceFiles = sourceFiles.slice(0, 50); // First 50 files\n\n return {\n success: true,\n data: {\n message: `Task received and analyzed: ${task.description}`,\n scope: task.scope,\n projectInfo,\n },\n };\n });\n\n // Handler for incoming context sync\n bridge.onContextReceived((context, peerId) => {\n logger.info(\n {\n peerId,\n fileCount: context.files?.length || 0,\n summary: context.summary\n },\n 'Context received from peer'\n );\n\n if (context.files) {\n for (const file of context.files) {\n console.log(` 📄 Received: ${file.path} (${file.content?.length || 0} chars)`);\n }\n }\n if (context.summary) {\n console.log(` 📝 Summary: ${context.summary}`);\n }\n });\n\n logger.info('Handlers registered for context requests, tasks, and context sync');\n console.log(' Handlers: enabled (file reading & task processing)');\n}\n\n/**\n * Build bridge configuration from CLI options and config file\n */\nfunction buildBridgeConfig(\n options: StartCommandOptions,\n globalOptions: GlobalOptions\n): BridgeConfig {\n // Load config file first\n const fileConfig = loadConfigSync(globalOptions.config);\n\n // CLI options override everything\n const cliConfig: Partial<BridgeConfig> = {};\n\n if (options.port) {\n cliConfig.listen = {\n ...cliConfig.listen,\n port: parseInt(options.port, 10),\n host: options.host ?? '0.0.0.0',\n };\n }\n\n if (options.host && !cliConfig.listen) {\n cliConfig.listen = {\n port: fileConfig.listen.port,\n host: options.host,\n };\n }\n\n if (options.connect) {\n cliConfig.connect = {\n url: options.connect,\n };\n }\n\n // Determine mode based on configuration\n // If connecting to a remote, we're a client; otherwise we're a host\n const hasConnect = cliConfig.connect || fileConfig.connect;\n const mode: BridgeMode = hasConnect ? 'client' : 'host';\n\n // Build final config with priority: CLI > file config > defaults\n const finalConfig: BridgeConfig = {\n mode: cliConfig.mode ?? fileConfig.mode ?? mode,\n instanceName: cliConfig.instanceName ?? fileConfig.instanceName ?? `bridge-${process.pid}`,\n listen: {\n port: cliConfig.listen?.port ?? fileConfig.listen.port,\n host: cliConfig.listen?.host ?? fileConfig.listen.host,\n },\n taskTimeout: fileConfig.interaction.taskTimeout,\n contextSharing: {\n autoSync: fileConfig.contextSharing.autoSync,\n syncInterval: fileConfig.contextSharing.syncInterval,\n },\n };\n\n // Add connect config if present\n const connectUrl = cliConfig.connect?.url ?? fileConfig.connect?.url;\n if (connectUrl) {\n finalConfig.connect = {\n url: connectUrl,\n };\n }\n\n return finalConfig;\n}\n\n/**\n * Start the bridge server\n */\nasync function startBridge(\n options: StartCommandOptions,\n globalOptions: GlobalOptions\n): Promise<void> {\n // Check if already running (skip check if we're the daemon child)\n if (!process.env.CLAUDE_BRIDGE_DAEMON_CHILD) {\n const { running, pid } = isAlreadyRunning();\n if (running) {\n // If --launch-claude is set, just launch Claude Code and attach to existing bridge\n if (options.launchClaude) {\n console.log(`Bridge already running (PID: ${pid}), launching Claude Code...`);\n const { spawnSync } = await import('child_process');\n const result = spawnSync('claude', [], {\n stdio: 'inherit',\n shell: true,\n });\n process.exit(result.status ?? 0);\n }\n console.error(`Bridge is already running (PID: ${pid})`);\n process.exit(1);\n }\n }\n\n // Build configuration\n const config = buildBridgeConfig(options, globalOptions);\n\n // Log startup info\n console.log('Starting Claude Code Bridge...');\n console.log(` Instance: ${config.instanceName}`);\n console.log(` Mode: ${config.mode}`);\n\n if (config.listen) {\n console.log(` Listening: ${config.listen.host}:${config.listen.port}`);\n }\n\n if (config.connect) {\n console.log(` Connecting to: ${config.connect.url}`);\n }\n\n // Handle daemon mode - spawn detached child process\n if (options.daemon && !process.env.CLAUDE_BRIDGE_DAEMON_CHILD) {\n const logFile = path.join(os.homedir(), '.claude-bridge', 'bridge.log');\n ensureBridgeDir();\n\n // Build args for child process (exclude --daemon to prevent infinite loop)\n const args = process.argv.slice(2).filter(arg => arg !== '-d' && arg !== '--daemon');\n\n // Spawn detached child process\n const out = fs.openSync(logFile, 'a');\n const err = fs.openSync(logFile, 'a');\n\n const child = spawn(process.execPath, [process.argv[1], ...args], {\n detached: true,\n stdio: ['ignore', out, err],\n env: { ...process.env, CLAUDE_BRIDGE_DAEMON_CHILD: '1' },\n });\n\n child.unref();\n\n // Write child PID to file\n writePidFile(child.pid!);\n\n console.log(` Running in background (PID: ${child.pid})`);\n console.log(` Log file: ${logFile}`);\n console.log(` Use 'claude-bridge status' to check status`);\n console.log(` Use 'claude-bridge stop' to stop the bridge`);\n\n // Launch Claude Code if requested\n if (options.launchClaude) {\n console.log('\\nLaunching Claude Code...');\n\n // Give the daemon a moment to start\n await new Promise(resolve => setTimeout(resolve, 500));\n\n // Launch claude in the foreground (replaces this process)\n const { spawnSync } = await import('child_process');\n const result = spawnSync('claude', [], {\n stdio: 'inherit',\n shell: true,\n });\n\n process.exit(result.status ?? 0);\n }\n\n // Parent exits immediately\n process.exit(0);\n }\n\n // Create and start bridge\n const bridge = new Bridge(config);\n\n // Set up graceful shutdown handling\n setupGracefulShutdown({\n cleanup: async () => {\n logger.info('Stopping bridge...');\n await bridge.stop();\n logger.info('Bridge stopped');\n },\n afterCleanup: process.env.CLAUDE_BRIDGE_DAEMON_CHILD ? removePidFile : undefined,\n verbose: true,\n timeout: 10000,\n });\n\n // Handle unhandled promise rejections\n handleUnhandledRejections({\n exit: false,\n logger: (msg, err) => logger.error({ error: err.message }, msg),\n });\n\n // Load config for handler patterns\n const fileConfig = loadConfigSync(globalOptions.config);\n\n try {\n await bridge.start();\n\n // Register handlers if --with-handlers is enabled\n if (options.withHandlers) {\n registerHandlers(bridge, {\n includePatterns: fileConfig.contextSharing.includePatterns,\n excludePatterns: fileConfig.contextSharing.excludePatterns,\n });\n }\n\n // Write PID file if running as daemon child (parent already wrote it, but update to confirm startup)\n if (process.env.CLAUDE_BRIDGE_DAEMON_CHILD) {\n writePidFile(process.pid);\n }\n\n console.log('Bridge started successfully.');\n console.log(`Connected peers: ${bridge.getPeerCount()}`);\n\n // Log connection info for users\n if (config.listen) {\n console.log(`\\nTo connect from another bridge:`);\n console.log(` claude-bridge connect ws://localhost:${config.listen.port}`);\n }\n\n // Keep the process running\n if (!process.env.CLAUDE_BRIDGE_DAEMON_CHILD) {\n console.log('\\nPress Ctrl+C to stop.');\n }\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Failed to start bridge');\n console.error(`Failed to start bridge: ${(error as Error).message}`);\n if (process.env.CLAUDE_BRIDGE_DAEMON_CHILD) {\n removePidFile();\n }\n process.exit(1);\n }\n}\n\n/**\n * Create the start command\n */\nexport function createStartCommand(): Command {\n const command = new Command('start');\n\n command\n .description('Start the bridge server')\n .option('-p, --port <port>', 'Port to listen on (default: 8765)')\n .option('-h, --host <host>', 'Host to bind to (default: 0.0.0.0)')\n .option('-c, --connect <url>', 'URL to connect to on startup (e.g., ws://localhost:8765)')\n .option('-d, --daemon', 'Run in background')\n .option('--with-handlers', 'Enable file reading and task handling capabilities')\n .option('--launch-claude', 'Start bridge daemon and launch Claude Code')\n .action(async (options: StartCommandOptions) => {\n // --launch-claude implies --daemon\n if (options.launchClaude) {\n options.daemon = true;\n }\n // Get global options from parent command\n const globalOptions = command.parent?.opts() as GlobalOptions;\n await startBridge(options, globalOptions);\n });\n\n return command;\n}\n\n/**\n * Export the command for use in CLI\n */\nexport { createStartCommand as startCommand };\n","/**\n * CLI output formatting utilities\n *\n * Provides helpers for colored output, table formatting, progress spinners,\n * and option parsing/validation.\n */\n\n/**\n * ANSI color codes for terminal output\n */\nexport const colors = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n\n // Foreground colors\n red: '\\x1b[31m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[34m',\n magenta: '\\x1b[35m',\n cyan: '\\x1b[36m',\n white: '\\x1b[37m',\n gray: '\\x1b[90m',\n} as const;\n\n/**\n * Check if terminal supports colors\n */\nexport function supportsColor(): boolean {\n // Disable colors if NO_COLOR env var is set\n if (process.env.NO_COLOR !== undefined) {\n return false;\n }\n\n // Enable colors if FORCE_COLOR is set\n if (process.env.FORCE_COLOR !== undefined) {\n return true;\n }\n\n // Check if stdout is a TTY\n if (typeof process.stdout.isTTY !== 'undefined' && process.stdout.isTTY) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Apply color to text (only if terminal supports it)\n */\nexport function colorize(text: string, color: keyof typeof colors): string {\n if (!supportsColor()) {\n return text;\n }\n return `${colors[color]}${text}${colors.reset}`;\n}\n\n/**\n * Print success message (green)\n */\nexport function success(message: string): void {\n console.log(colorize('✓ ' + message, 'green'));\n}\n\n/**\n * Print error message (red)\n */\nexport function error(message: string): void {\n console.error(colorize('✗ ' + message, 'red'));\n}\n\n/**\n * Print warning message (yellow)\n */\nexport function warning(message: string): void {\n console.log(colorize('⚠ ' + message, 'yellow'));\n}\n\n/**\n * Print info message (blue)\n */\nexport function info(message: string): void {\n console.log(colorize('ℹ ' + message, 'blue'));\n}\n\n/**\n * Print debug message (gray)\n */\nexport function debug(message: string): void {\n console.log(colorize('⋯ ' + message, 'gray'));\n}\n\n/**\n * Table column configuration\n */\nexport interface TableColumn {\n title: string;\n width: number;\n align?: 'left' | 'right' | 'center';\n}\n\n/**\n * Table row data (key-value pairs matching column titles)\n */\nexport type TableRow = Record<string, string | number | undefined>;\n\n/**\n * Pad a string to a specific width with alignment\n */\nexport function padToWidth(\n text: string,\n width: number,\n align: 'left' | 'right' | 'center' = 'left'\n): string {\n const str = String(text).slice(0, width);\n const padding = width - str.length;\n\n if (align === 'right') {\n return ' '.repeat(padding) + str;\n } else if (align === 'center') {\n const leftPad = Math.floor(padding / 2);\n const rightPad = padding - leftPad;\n return ' '.repeat(leftPad) + str + ' '.repeat(rightPad);\n } else {\n return str + ' '.repeat(padding);\n }\n}\n\n/**\n * Print a formatted table\n */\nexport function printTable(\n columns: TableColumn[],\n rows: TableRow[],\n options: { indent?: number; borderStyle?: 'simple' | 'none' } = {}\n): void {\n const indent = ' '.repeat(options.indent ?? 0);\n const borderStyle = options.borderStyle ?? 'simple';\n\n // Print header\n const headerRow = columns\n .map((col) => padToWidth(col.title, col.width, col.align))\n .join(' ');\n console.log(indent + colorize(headerRow, 'bold'));\n\n // Print separator\n if (borderStyle === 'simple') {\n const separator = columns\n .map((col) => '-'.repeat(col.width))\n .join(' ');\n console.log(indent + separator);\n }\n\n // Print rows\n for (const row of rows) {\n const rowText = columns\n .map((col) => {\n // Find matching key case-insensitively\n const key = Object.keys(row).find(\n (k) => k.toLowerCase() === col.title.toLowerCase()\n );\n const value = key ? String(row[key] ?? '') : '';\n return padToWidth(value, col.width, col.align);\n })\n .join(' ');\n console.log(indent + rowText);\n }\n}\n\n/**\n * Spinner frames for progress indication\n */\nconst SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n\n/**\n * Progress spinner for long operations\n */\nexport class Spinner {\n private message: string;\n private intervalId: ReturnType<typeof setInterval> | null = null;\n private frameIndex = 0;\n private stream = process.stdout;\n\n constructor(message: string) {\n this.message = message;\n }\n\n /**\n * Start the spinner animation\n */\n start(): void {\n if (!supportsColor() || !this.stream.isTTY) {\n // Non-TTY: just print the message once\n console.log(`... ${this.message}`);\n return;\n }\n\n // Hide cursor\n this.stream.write('\\x1b[?25l');\n\n this.intervalId = setInterval(() => {\n const frame = SPINNER_FRAMES[this.frameIndex];\n this.stream.write(\n `\\r${colorize(frame, 'cyan')} ${this.message}`\n );\n this.frameIndex = (this.frameIndex + 1) % SPINNER_FRAMES.length;\n }, 80);\n }\n\n /**\n * Update the spinner message\n */\n update(message: string): void {\n this.message = message;\n }\n\n /**\n * Stop the spinner with a success message\n */\n succeed(message?: string): void {\n this.stop();\n success(message ?? this.message);\n }\n\n /**\n * Stop the spinner with an error message\n */\n fail(message?: string): void {\n this.stop();\n error(message ?? this.message);\n }\n\n /**\n * Stop the spinner with a warning message\n */\n warn(message?: string): void {\n this.stop();\n warning(message ?? this.message);\n }\n\n /**\n * Stop the spinner (no message)\n */\n stop(): void {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n\n if (supportsColor() && this.stream.isTTY) {\n // Clear line and show cursor\n this.stream.write('\\r\\x1b[K');\n this.stream.write('\\x1b[?25h');\n }\n }\n}\n\n/**\n * Create and start a new spinner\n */\nexport function spinner(message: string): Spinner {\n const s = new Spinner(message);\n s.start();\n return s;\n}\n\n/**\n * Parsed start command options\n */\nexport interface ParsedStartOptions {\n listen?: {\n port: number;\n host: string;\n };\n connect?: {\n url: string;\n };\n daemon: boolean;\n}\n\n/**\n * Parse and validate start command options\n */\nexport function parseStartOptions(options: {\n port?: string;\n host?: string;\n connect?: string;\n daemon?: boolean;\n}): ParsedStartOptions {\n const result: ParsedStartOptions = {\n daemon: options.daemon ?? false,\n };\n\n // Parse port\n if (options.port) {\n const port = parseInt(options.port, 10);\n if (isNaN(port) || port < 1 || port > 65535) {\n throw new Error(`Invalid port: ${options.port}. Must be between 1 and 65535.`);\n }\n result.listen = {\n port,\n host: options.host ?? '0.0.0.0',\n };\n } else if (options.host) {\n // Host specified without port, use default port\n result.listen = {\n port: 8765,\n host: options.host,\n };\n }\n\n // Parse connect URL\n if (options.connect) {\n validateWebSocketUrl(options.connect);\n result.connect = {\n url: options.connect,\n };\n }\n\n return result;\n}\n\n/**\n * Validate a WebSocket URL\n */\nexport function validateWebSocketUrl(url: string): void {\n if (!url.startsWith('ws://') && !url.startsWith('wss://')) {\n throw new Error(\n `Invalid URL protocol. Expected ws:// or wss://, got: ${url}`\n );\n }\n\n try {\n const parsed = new URL(url);\n if (!parsed.hostname) {\n throw new Error('URL must include a hostname');\n }\n } catch (e) {\n if (e instanceof Error && e.message.includes('Invalid URL')) {\n throw new Error(`Invalid URL format: ${url}`);\n }\n throw e;\n }\n}\n\n/**\n * Parsed connect command options\n */\nexport interface ParsedConnectOptions {\n url: string;\n}\n\n/**\n * Parse and validate connect command options\n */\nexport function parseConnectOptions(options: {\n url?: string;\n}): ParsedConnectOptions {\n if (!options.url) {\n throw new Error('URL is required');\n }\n\n validateWebSocketUrl(options.url);\n\n return {\n url: options.url,\n };\n}\n\n/**\n * Format duration in human-readable form\n */\nexport function formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n }\n if (ms < 60000) {\n return `${(ms / 1000).toFixed(1)}s`;\n }\n if (ms < 3600000) {\n const minutes = Math.floor(ms / 60000);\n const seconds = Math.round((ms % 60000) / 1000);\n return `${minutes}m ${seconds}s`;\n }\n const hours = Math.floor(ms / 3600000);\n const minutes = Math.round((ms % 3600000) / 60000);\n return `${hours}h ${minutes}m`;\n}\n\n/**\n * Format bytes in human-readable form\n */\nexport function formatBytes(bytes: number): string {\n const units = ['B', 'KB', 'MB', 'GB', 'TB'];\n let unitIndex = 0;\n let value = bytes;\n\n while (value >= 1024 && unitIndex < units.length - 1) {\n value /= 1024;\n unitIndex++;\n }\n\n return `${value.toFixed(unitIndex === 0 ? 0 : 1)} ${units[unitIndex]}`;\n}\n\n/**\n * Shutdown handler type\n */\nexport type ShutdownHandler = (signal: string) => Promise<void>;\n\n/**\n * Options for setting up graceful shutdown\n */\nexport interface GracefulShutdownOptions {\n /**\n * Cleanup function to call on shutdown\n */\n cleanup: () => Promise<void>;\n\n /**\n * Additional cleanup to call after main cleanup (e.g., removing PID file)\n */\n afterCleanup?: () => void;\n\n /**\n * Whether to show shutdown messages\n * @default true\n */\n verbose?: boolean;\n\n /**\n * Timeout in milliseconds before forcing exit\n * @default 10000\n */\n timeout?: number;\n}\n\n/**\n * Set up graceful shutdown handlers for SIGTERM and SIGINT\n *\n * Handles process signals to ensure clean shutdown of bridges and connections.\n * - SIGTERM: Sent by `kill` command or process managers\n * - SIGINT: Sent by Ctrl+C in terminal\n *\n * @param options Shutdown configuration options\n * @returns Function to remove the handlers (for testing)\n */\nexport function setupGracefulShutdown(options: GracefulShutdownOptions): () => void {\n const {\n cleanup,\n afterCleanup,\n verbose = true,\n timeout = 10000,\n } = options;\n\n let isShuttingDown = false;\n\n const handler: ShutdownHandler = async (signal: string) => {\n // Prevent multiple shutdown attempts\n if (isShuttingDown) {\n if (verbose) {\n console.log('Shutdown already in progress...');\n }\n return;\n }\n isShuttingDown = true;\n\n if (verbose) {\n console.log(`\\nReceived ${signal}, shutting down gracefully...`);\n }\n\n // Set up force exit timeout\n const forceExitTimeout = setTimeout(() => {\n if (verbose) {\n console.error('Shutdown timeout - forcing exit');\n }\n process.exit(1);\n }, timeout);\n\n try {\n await cleanup();\n\n if (afterCleanup) {\n afterCleanup();\n }\n\n clearTimeout(forceExitTimeout);\n\n if (verbose) {\n console.log('Shutdown complete.');\n }\n process.exit(0);\n } catch (error) {\n clearTimeout(forceExitTimeout);\n if (verbose) {\n console.error(`Error during shutdown: ${(error as Error).message}`);\n }\n process.exit(1);\n }\n };\n\n // Register handlers\n const sigintHandler = () => handler('SIGINT');\n const sigtermHandler = () => handler('SIGTERM');\n\n process.on('SIGINT', sigintHandler);\n process.on('SIGTERM', sigtermHandler);\n\n // Return cleanup function\n return () => {\n process.off('SIGINT', sigintHandler);\n process.off('SIGTERM', sigtermHandler);\n };\n}\n\n/**\n * Handle unhandled promise rejections\n *\n * Logs unhandled rejections and optionally exits the process.\n *\n * @param options Configuration options\n */\nexport function handleUnhandledRejections(options: {\n exit?: boolean;\n logger?: (message: string, error: Error) => void;\n} = {}): void {\n const { exit = false, logger = console.error } = options;\n\n process.on('unhandledRejection', (reason, promise) => {\n const error = reason instanceof Error ? reason : new Error(String(reason));\n logger('Unhandled promise rejection:', error);\n\n if (exit) {\n process.exit(1);\n }\n });\n}\n","/**\n * CLI stop command - Stop the running bridge\n *\n * Reads the PID from ~/.claude-bridge/bridge.pid and sends SIGTERM\n * to gracefully stop the running bridge process.\n */\n\nimport { Command } from 'commander';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { createLogger } from '../../utils/logger.js';\n\nconst logger = createLogger('cli:stop');\n\n/**\n * Get the PID file path\n */\nfunction getPidFilePath(): string {\n const bridgeDir = path.join(os.homedir(), '.claude-bridge');\n return path.join(bridgeDir, 'bridge.pid');\n}\n\n/**\n * Remove PID file\n */\nfunction removePidFile(): void {\n const pidFile = getPidFilePath();\n if (fs.existsSync(pidFile)) {\n fs.unlinkSync(pidFile);\n }\n}\n\n/**\n * Read PID from file\n * Returns null if file doesn't exist or is invalid\n */\nfunction readPidFile(): number | null {\n const pidFile = getPidFilePath();\n if (!fs.existsSync(pidFile)) {\n return null;\n }\n\n try {\n const content = fs.readFileSync(pidFile, 'utf-8').trim();\n const pid = parseInt(content, 10);\n if (isNaN(pid) || pid <= 0) {\n logger.warn({ content }, 'Invalid PID file content');\n return null;\n }\n return pid;\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Failed to read PID file');\n return null;\n }\n}\n\n/**\n * Check if a process is running\n */\nfunction isProcessRunning(pid: number): boolean {\n try {\n // Signal 0 checks if the process exists without sending a signal\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Wait for a process to exit with timeout\n */\nasync function waitForProcessExit(\n pid: number,\n timeoutMs: number = 5000\n): Promise<boolean> {\n const startTime = Date.now();\n const checkInterval = 100;\n\n while (Date.now() - startTime < timeoutMs) {\n if (!isProcessRunning(pid)) {\n return true;\n }\n await new Promise((resolve) => setTimeout(resolve, checkInterval));\n }\n\n return false;\n}\n\n/**\n * Stop the bridge process\n */\nasync function stopBridge(): Promise<void> {\n const pid = readPidFile();\n\n if (pid === null) {\n console.log('Bridge is not running (no PID file found).');\n return;\n }\n\n // Check if process is actually running\n if (!isProcessRunning(pid)) {\n console.log(`Bridge is not running (stale PID file, process ${pid} not found).`);\n // Clean up stale PID file\n removePidFile();\n return;\n }\n\n console.log(`Stopping bridge (PID: ${pid})...`);\n\n try {\n // Send SIGTERM for graceful shutdown\n process.kill(pid, 'SIGTERM');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ESRCH') {\n // Process doesn't exist\n console.log('Bridge process not found.');\n removePidFile();\n return;\n }\n if ((error as NodeJS.ErrnoException).code === 'EPERM') {\n console.error(`Permission denied: cannot stop bridge (PID: ${pid}).`);\n console.error('Try running with elevated privileges.');\n process.exit(1);\n }\n throw error;\n }\n\n // Wait for process to exit\n const exited = await waitForProcessExit(pid);\n\n if (exited) {\n console.log('Bridge stopped successfully.');\n // Clean up PID file if the process didn't do it\n removePidFile();\n } else {\n console.log('Bridge is still shutting down. Check status with: claude-bridge status');\n // Optionally could try SIGKILL here, but we'll leave that to the user\n console.log(`To force stop: kill -9 ${pid}`);\n }\n}\n\n/**\n * Create the stop command\n */\nexport function createStopCommand(): Command {\n const command = new Command('stop');\n\n command\n .description('Stop the running bridge')\n .action(async () => {\n try {\n await stopBridge();\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Failed to stop bridge');\n console.error(`Failed to stop bridge: ${(error as Error).message}`);\n process.exit(1);\n }\n });\n\n return command;\n}\n\n/**\n * Export for use in CLI\n */\nexport { createStopCommand as stopCommand };\n","/**\n * CLI status command - Show bridge status and connected peers\n *\n * Displays whether the bridge is running, what port it's on,\n * and lists connected peers in a formatted table.\n *\n * Options:\n * --port Check status for a specific port\n */\n\nimport { Command } from 'commander';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { createLogger } from '../../utils/logger.js';\n\nconst logger = createLogger('cli:status');\n\n/**\n * Options for the status command\n */\nexport interface StatusCommandOptions {\n port?: string;\n}\n\n/**\n * Bridge status information\n */\nexport interface BridgeStatus {\n running: boolean;\n pid?: number;\n port?: number;\n peers?: PeerStatus[];\n}\n\n/**\n * Peer status information\n */\nexport interface PeerStatus {\n id: string;\n name: string;\n connectedAt: string;\n lastActivity: string;\n}\n\n/**\n * Get the PID file path\n */\nfunction getPidFilePath(): string {\n const bridgeDir = path.join(os.homedir(), '.claude-bridge');\n return path.join(bridgeDir, 'bridge.pid');\n}\n\n/**\n * Get the status file path (where bridge writes current status)\n */\nfunction getStatusFilePath(): string {\n const bridgeDir = path.join(os.homedir(), '.claude-bridge');\n return path.join(bridgeDir, 'status.json');\n}\n\n/**\n * Read PID from file\n */\nfunction readPidFile(): number | null {\n const pidFile = getPidFilePath();\n if (!fs.existsSync(pidFile)) {\n return null;\n }\n\n try {\n const content = fs.readFileSync(pidFile, 'utf-8').trim();\n const pid = parseInt(content, 10);\n if (isNaN(pid) || pid <= 0) {\n return null;\n }\n return pid;\n } catch {\n return null;\n }\n}\n\n/**\n * Check if a process is running\n */\nfunction isProcessRunning(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Read status file written by the bridge\n */\nfunction readStatusFile(): { port?: number; peers?: PeerStatus[] } | null {\n const statusFile = getStatusFilePath();\n if (!fs.existsSync(statusFile)) {\n return null;\n }\n\n try {\n const content = fs.readFileSync(statusFile, 'utf-8');\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\n/**\n * Format a date for display\n */\nfunction formatDate(dateStr: string): string {\n try {\n const date = new Date(dateStr);\n return date.toLocaleString();\n } catch {\n return dateStr;\n }\n}\n\n/**\n * Pad a string to a specific width\n */\nfunction padRight(str: string, width: number): string {\n return str.padEnd(width);\n}\n\n/**\n * Print peer table\n */\nfunction printPeerTable(peers: PeerStatus[]): void {\n if (peers.length === 0) {\n console.log(' No peers connected.');\n return;\n }\n\n // Column headers and widths\n const cols = {\n id: { title: 'ID', width: 38 },\n name: { title: 'Name', width: 20 },\n connected: { title: 'Connected', width: 22 },\n lastActivity: { title: 'Last Activity', width: 22 },\n };\n\n // Print header\n console.log('');\n console.log(\n ' ' +\n padRight(cols.id.title, cols.id.width) +\n padRight(cols.name.title, cols.name.width) +\n padRight(cols.connected.title, cols.connected.width) +\n padRight(cols.lastActivity.title, cols.lastActivity.width)\n );\n\n // Print separator\n const separator =\n ' ' +\n '-'.repeat(cols.id.width - 1) +\n ' ' +\n '-'.repeat(cols.name.width - 1) +\n ' ' +\n '-'.repeat(cols.connected.width - 1) +\n ' ' +\n '-'.repeat(cols.lastActivity.width - 1);\n console.log(separator);\n\n // Print rows\n for (const peer of peers) {\n const row =\n ' ' +\n padRight(peer.id, cols.id.width) +\n padRight(peer.name.slice(0, cols.name.width - 1), cols.name.width) +\n padRight(formatDate(peer.connectedAt), cols.connected.width) +\n padRight(formatDate(peer.lastActivity), cols.lastActivity.width);\n console.log(row);\n }\n\n console.log('');\n}\n\n/**\n * Get bridge status\n */\nfunction getBridgeStatus(): BridgeStatus {\n const pid = readPidFile();\n\n if (pid === null) {\n return { running: false };\n }\n\n if (!isProcessRunning(pid)) {\n // PID file exists but process is not running\n return { running: false };\n }\n\n // Process is running, try to get more details\n const statusInfo = readStatusFile();\n\n return {\n running: true,\n pid,\n port: statusInfo?.port,\n peers: statusInfo?.peers,\n };\n}\n\n/**\n * Show bridge status\n */\nfunction showStatus(options: StatusCommandOptions): void {\n console.log('Claude Code Bridge Status');\n console.log('='.repeat(26));\n console.log('');\n\n const status = getBridgeStatus();\n\n if (!status.running) {\n console.log('Status: stopped');\n console.log('');\n console.log('To start the bridge:');\n console.log(' claude-bridge start');\n return;\n }\n\n console.log('Status: running');\n console.log(`PID: ${status.pid}`);\n\n if (status.port !== undefined) {\n console.log(`Port: ${status.port}`);\n }\n\n console.log('');\n console.log('Connected Peers:');\n\n if (status.peers) {\n printPeerTable(status.peers);\n } else {\n console.log(' Unable to retrieve peer information.');\n console.log(' (Status file not found or unreadable)');\n }\n\n console.log('To stop the bridge:');\n console.log(' claude-bridge stop');\n}\n\n/**\n * Create the status command\n */\nexport function createStatusCommand(): Command {\n const command = new Command('status');\n\n command\n .description('Show bridge status and connected peers')\n .option('-p, --port <port>', 'Check status for a specific port')\n .action((options: StatusCommandOptions) => {\n try {\n showStatus(options);\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Failed to get status');\n console.error(`Failed to get status: ${(error as Error).message}`);\n process.exit(1);\n }\n });\n\n return command;\n}\n\n/**\n * Export for use in CLI\n */\nexport { createStatusCommand as statusCommand };\n","/**\n * CLI connect command - Connect to a remote bridge\n *\n * Takes a WebSocket URL and initiates a connection to a remote bridge.\n * This is a one-time connection test that verifies connectivity.\n *\n * Usage:\n * claude-bridge connect ws://localhost:8765\n */\n\nimport { Command } from 'commander';\nimport { createLogger } from '../../utils/logger.js';\nimport { WebSocketTransport } from '../../transport/websocket.js';\nimport { ConnectionState } from '../../transport/interface.js';\n\nconst logger = createLogger('cli:connect');\n\n/**\n * Validate WebSocket URL format\n * Returns true if valid, throws Error if invalid\n */\nexport function validateWebSocketUrl(url: string): boolean {\n // Check for ws:// or wss:// protocol\n if (!url.startsWith('ws://') && !url.startsWith('wss://')) {\n throw new Error(`Invalid URL protocol. Expected ws:// or wss://, got: ${url}`);\n }\n\n try {\n const parsed = new URL(url);\n\n // Ensure we have a valid hostname\n if (!parsed.hostname) {\n throw new Error('URL must include a hostname');\n }\n\n // Ensure we have a port (for WebSocket connections)\n if (!parsed.port) {\n // Default ports\n const defaultPort = parsed.protocol === 'wss:' ? '443' : '80';\n logger.debug(`No port specified, will use default: ${defaultPort}`);\n }\n\n return true;\n } catch (error) {\n if (error instanceof Error && error.message.includes('Invalid URL')) {\n throw new Error(`Invalid URL format: ${url}`);\n }\n throw error;\n }\n}\n\n/**\n * Connect to a remote bridge\n */\nasync function connectToBridge(url: string): Promise<void> {\n // Validate URL format\n try {\n validateWebSocketUrl(url);\n } catch (error) {\n console.error(`Error: ${(error as Error).message}`);\n process.exit(1);\n }\n\n console.log(`Connecting to bridge at ${url}...`);\n\n const transport = new WebSocketTransport();\n\n // Set up connection timeout\n const timeoutMs = 10000;\n const timeout = setTimeout(() => {\n console.error(`Error: Connection timeout after ${timeoutMs / 1000} seconds`);\n transport.disconnect().catch(() => {});\n process.exit(1);\n }, timeoutMs);\n\n try {\n // Attempt connection\n await transport.connect({\n url,\n reconnect: false, // Don't auto-reconnect for this test\n });\n\n clearTimeout(timeout);\n\n if (transport.getState() === ConnectionState.CONNECTED) {\n console.log('Successfully connected to bridge!');\n console.log('');\n console.log('Connection details:');\n console.log(` URL: ${url}`);\n console.log(` State: ${ConnectionState[transport.getState()]}`);\n console.log('');\n console.log('To start a bridge that auto-connects on startup:');\n console.log(` claude-bridge start --connect ${url}`);\n } else {\n console.error(`Connection failed. State: ${ConnectionState[transport.getState()]}`);\n process.exit(1);\n }\n\n // Clean up - disconnect after successful test\n await transport.disconnect();\n console.log('\\nConnection test complete. Disconnected.');\n } catch (error) {\n clearTimeout(timeout);\n const errorMessage = (error as Error).message;\n console.error(`Error: Failed to connect - ${errorMessage}`);\n\n // Provide helpful suggestions\n if (errorMessage.includes('ECONNREFUSED')) {\n console.log('');\n console.log('Suggestions:');\n console.log(' - Ensure a bridge is running at the specified address');\n console.log(' - Check the port number is correct');\n console.log(' - Verify no firewall is blocking the connection');\n } else if (errorMessage.includes('ENOTFOUND')) {\n console.log('');\n console.log('Suggestions:');\n console.log(' - Check the hostname is correct');\n console.log(' - Ensure DNS resolution is working');\n }\n\n process.exit(1);\n }\n}\n\n/**\n * Create the connect command\n */\nexport function createConnectCommand(): Command {\n const command = new Command('connect');\n\n command\n .description('Connect to a remote bridge')\n .argument('<url>', 'WebSocket URL to connect to (e.g., ws://localhost:8765)')\n .action(async (url: string) => {\n try {\n await connectToBridge(url);\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Connect command failed');\n console.error(`Error: ${(error as Error).message}`);\n process.exit(1);\n }\n });\n\n return command;\n}\n\n/**\n * Export for use in CLI\n */\nexport { createConnectCommand as connectCommand };\n","/**\n * CLI info command - Show system and configuration info\n *\n * Displays information about the current system, network configuration,\n * and loaded config values.\n */\n\nimport { Command } from 'commander';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { createLogger } from '../../utils/logger.js';\nimport { loadConfigSync } from '../../utils/config.js';\nimport type { GlobalOptions } from '../index.js';\n\nconst logger = createLogger('cli:info');\n\n/**\n * Get the config file path that would be loaded\n */\nfunction getConfigFilePath(): string | null {\n // Check project local config first\n const localConfig = path.join(process.cwd(), '.claude-bridge.yml');\n if (fs.existsSync(localConfig)) {\n return localConfig;\n }\n\n // Check home directory\n const homeConfig = path.join(os.homedir(), '.claude-bridge', 'config.yml');\n if (fs.existsSync(homeConfig)) {\n return homeConfig;\n }\n\n return null;\n}\n\n/**\n * Format a value for display (handle undefined, objects, etc.)\n */\nfunction formatValue(value: unknown): string {\n if (value === undefined) {\n return '(not set)';\n }\n if (value === null) {\n return '(null)';\n }\n if (typeof value === 'object') {\n return JSON.stringify(value);\n }\n return String(value);\n}\n\n/**\n * Print a section header\n */\nfunction printSection(title: string): void {\n console.log('');\n console.log(title);\n console.log('-'.repeat(title.length));\n}\n\n/**\n * Print a key-value pair\n */\nfunction printKeyValue(key: string, value: unknown, indent: number = 0): void {\n const prefix = ' '.repeat(indent);\n console.log(`${prefix}${key}: ${formatValue(value)}`);\n}\n\n/**\n * Show system and configuration info\n */\nfunction showInfo(globalOptions: GlobalOptions): void {\n console.log('Claude Code Bridge - System Information');\n console.log('='.repeat(40));\n\n // System Info\n printSection('System');\n printKeyValue('Node Version', process.version);\n printKeyValue('OS', `${os.type()} ${os.release()}`);\n printKeyValue('Platform', process.platform);\n printKeyValue('Arch', os.arch());\n printKeyValue('Home Directory', os.homedir());\n printKeyValue('Working Directory', process.cwd());\n\n // Network\n printSection('Network');\n const interfaces = os.networkInterfaces();\n for (const [name, addrs] of Object.entries(interfaces)) {\n if (addrs) {\n for (const addr of addrs) {\n if (addr.family === 'IPv4' && !addr.internal) {\n printKeyValue(name, addr.address);\n }\n }\n }\n }\n\n // Configuration\n printSection('Configuration');\n const configPath = globalOptions.config || getConfigFilePath();\n printKeyValue('Config File', configPath || '(using defaults)');\n\n const config = loadConfigSync(globalOptions.config);\n\n console.log('');\n console.log(' Current Settings:');\n printKeyValue('Mode', config.mode, 2);\n printKeyValue('Instance Name', config.instanceName, 2);\n\n console.log('');\n console.log(' Listen:');\n printKeyValue('Port', config.listen.port, 2);\n printKeyValue('Host', config.listen.host, 2);\n\n console.log('');\n console.log(' Connect:');\n printKeyValue('URL', config.connect?.url, 2);\n\n console.log('');\n console.log(' Context Sharing:');\n printKeyValue('Auto Sync', config.contextSharing.autoSync, 2);\n printKeyValue('Sync Interval', `${config.contextSharing.syncInterval}ms`, 2);\n printKeyValue('Max Chunk Tokens', config.contextSharing.maxChunkTokens, 2);\n\n if (config.contextSharing.includePatterns.length > 0) {\n console.log(' Include Patterns:');\n for (const pattern of config.contextSharing.includePatterns) {\n console.log(` - ${pattern}`);\n }\n }\n\n if (config.contextSharing.excludePatterns.length > 0) {\n console.log(' Exclude Patterns:');\n for (const pattern of config.contextSharing.excludePatterns) {\n console.log(` - ${pattern}`);\n }\n }\n\n console.log('');\n console.log(' Interaction:');\n printKeyValue('Require Confirmation', config.interaction.requireConfirmation, 2);\n printKeyValue('Notify On Activity', config.interaction.notifyOnActivity, 2);\n printKeyValue('Task Timeout', `${config.interaction.taskTimeout}ms`, 2);\n\n console.log('');\n}\n\n/**\n * Create the info command\n */\nexport function createInfoCommand(): Command {\n const command = new Command('info');\n\n command\n .description('Show system and configuration info')\n .action(() => {\n try {\n // Get global options from parent command\n const globalOptions = command.parent?.opts() as GlobalOptions ?? {};\n showInfo(globalOptions);\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Info command failed');\n console.error(`Error: ${(error as Error).message}`);\n process.exit(1);\n }\n });\n\n return command;\n}\n\n/**\n * Export for use in CLI\n */\nexport { createInfoCommand as infoCommand };\n","/**\n * CLI mcp-server command - Start the MCP server for Claude Code integration\n *\n * Options:\n * --connect, -c Bridge WebSocket URL to connect to (default: ws://localhost:8766)\n * --name MCP server name (default: claude-bridge)\n */\n\nimport { Command } from 'commander';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { spawn } from 'child_process';\nimport { createLogger } from '../../utils/logger.js';\nimport { BridgeMcpServer, type McpServerConfig } from '../../mcp/server.js';\nimport { setupGracefulShutdown, handleUnhandledRejections } from '../utils.js';\nimport type { GlobalOptions } from '../index.js';\n\nconst logger = createLogger('cli:mcp-server');\n\n/**\n * Options for the mcp-server command\n */\nexport interface McpServerCommandOptions {\n connect?: string;\n name?: string;\n}\n\n/**\n * Default bridge daemon port\n */\nconst DEFAULT_DAEMON_PORT = 8766;\n\n/**\n * Get the status file path\n */\nfunction getStatusFilePath(): string {\n const bridgeDir = path.join(os.homedir(), '.claude-bridge');\n return path.join(bridgeDir, 'status.json');\n}\n\n/**\n * Get the PID file path\n */\nfunction getPidFilePath(): string {\n const bridgeDir = path.join(os.homedir(), '.claude-bridge');\n return path.join(bridgeDir, 'bridge.pid');\n}\n\n/**\n * Check if bridge daemon is running\n */\nfunction isDaemonRunning(): { running: boolean; pid?: number; port?: number } {\n const pidFile = getPidFilePath();\n\n if (!fs.existsSync(pidFile)) {\n return { running: false };\n }\n\n try {\n const pid = parseInt(fs.readFileSync(pidFile, 'utf-8').trim(), 10);\n // Check if process is still running\n process.kill(pid, 0); // Signal 0 checks existence without killing\n\n // Try to read port from status file\n const statusFile = getStatusFilePath();\n if (fs.existsSync(statusFile)) {\n const status = JSON.parse(fs.readFileSync(statusFile, 'utf-8'));\n return { running: true, pid, port: status.port };\n }\n\n return { running: true, pid };\n } catch {\n // Process doesn't exist or status file invalid\n return { running: false };\n }\n}\n\n/**\n * Wait for daemon to be ready\n */\nasync function waitForDaemon(port: number, timeoutMs: number): Promise<void> {\n const startTime = Date.now();\n\n while (Date.now() - startTime < timeoutMs) {\n const { running, port: runningPort } = isDaemonRunning();\n if (running && (runningPort === port || runningPort === undefined)) {\n // Give it a moment to be fully ready\n await new Promise(resolve => setTimeout(resolve, 500));\n return;\n }\n await new Promise(resolve => setTimeout(resolve, 200));\n }\n\n throw new Error(`Daemon did not start within ${timeoutMs}ms`);\n}\n\n/**\n * Ensure the .claude-bridge directory exists\n */\nfunction ensureBridgeDir(): void {\n const bridgeDir = path.join(os.homedir(), '.claude-bridge');\n if (!fs.existsSync(bridgeDir)) {\n fs.mkdirSync(bridgeDir, { recursive: true });\n }\n}\n\n/**\n * Start bridge daemon if not running\n */\nasync function ensureDaemonRunning(port: number): Promise<number> {\n const { running, pid, port: runningPort } = isDaemonRunning();\n\n if (running) {\n const effectivePort = runningPort ?? port;\n console.error(`[MCP] Bridge daemon already running (PID: ${pid}, port: ${effectivePort})`);\n return effectivePort;\n }\n\n console.error('[MCP] Starting bridge daemon...');\n ensureBridgeDir();\n\n const logFile = path.join(os.homedir(), '.claude-bridge', 'bridge.log');\n\n // Spawn daemon process\n const out = fs.openSync(logFile, 'a');\n const err = fs.openSync(logFile, 'a');\n\n // Find the CLI entry point\n // When running from npx or installed globally, process.argv[1] is the CLI script\n const cliPath = process.argv[1];\n\n const child = spawn(process.execPath, [cliPath, 'start', '--daemon', '--port', String(port)], {\n detached: true,\n stdio: ['ignore', out, err],\n });\n\n child.unref();\n\n console.error(`[MCP] Daemon starting (PID: ${child.pid})`);\n\n // Wait for daemon to be ready\n try {\n await waitForDaemon(port, 5000);\n console.error(`[MCP] Daemon ready on port ${port}`);\n return port;\n } catch (error) {\n console.error(`[MCP] Warning: Could not verify daemon is ready: ${(error as Error).message}`);\n // Continue anyway, the bridge connection will fail if daemon isn't running\n return port;\n }\n}\n\n/**\n * Start the MCP server\n */\nasync function startMcpServer(\n options: McpServerCommandOptions,\n _globalOptions: GlobalOptions\n): Promise<void> {\n // Parse connection URL\n let bridgeUrl = options.connect ?? `ws://localhost:${DEFAULT_DAEMON_PORT}`;\n\n // If no explicit URL provided, try to auto-start daemon\n if (!options.connect) {\n try {\n const port = await ensureDaemonRunning(DEFAULT_DAEMON_PORT);\n bridgeUrl = `ws://localhost:${port}`;\n } catch (error) {\n console.error(`[MCP] Warning: Could not ensure daemon is running: ${(error as Error).message}`);\n }\n }\n\n // Build MCP server config\n const config: McpServerConfig = {\n bridgeUrl,\n name: options.name ?? 'claude-bridge',\n version: '0.4.0',\n instanceName: `mcp-server-${process.pid}`,\n taskTimeout: 60000,\n };\n\n // Create and start MCP server\n const server = new BridgeMcpServer(config);\n\n // Set up graceful shutdown handling\n setupGracefulShutdown({\n cleanup: async () => {\n console.error('[MCP] Shutting down...');\n await server.stop();\n },\n verbose: false,\n timeout: 5000,\n });\n\n // Handle unhandled promise rejections\n handleUnhandledRejections({\n exit: true,\n logger: (msg, err) => {\n console.error(`[MCP] ${msg}: ${err.message}`);\n logger.error({ error: err.message }, msg);\n },\n });\n\n try {\n await server.start();\n // Server is now running and listening on stdio\n // It will keep running until interrupted\n } catch (error) {\n console.error(`[MCP] Failed to start MCP server: ${(error as Error).message}`);\n process.exit(1);\n }\n}\n\n/**\n * Create the mcp-server command\n */\nexport function createMcpServerCommand(): Command {\n const command = new Command('mcp-server');\n\n command\n .description('Start the MCP server for Claude Code integration')\n .option('-c, --connect <url>', `Bridge WebSocket URL (default: ws://localhost:${DEFAULT_DAEMON_PORT})`)\n .option('--name <name>', 'MCP server name (default: claude-bridge)')\n .action(async (options: McpServerCommandOptions) => {\n // Get global options from parent command\n const globalOptions = command.parent?.opts() as GlobalOptions;\n await startMcpServer(options, globalOptions);\n });\n\n return command;\n}\n\n/**\n * Export the command for use in CLI\n */\nexport { createMcpServerCommand as mcpServerCommand };\n"],"mappings":"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","names":["Command","logger","resolve","Command","fs","path","os","logger","getPidFilePath","removePidFile","resolve","Command","Command","fs","path","os","logger","getPidFilePath","readPidFile","isProcessRunning","Command","Command","logger","Command","Command","fs","path","os","logger","Command","Command","fs","path","os","spawn","logger","getStatusFilePath","getPidFilePath","resolve","ensureBridgeDir","spawn","Command","logger","Command"]}
1
+ {"version":3,"sources":["../src/cli/index.ts","../src/cli/commands/start.ts","../src/cli/utils.ts","../src/cli/commands/stop.ts","../src/cli/commands/status.ts","../src/cli/commands/connect.ts","../src/cli/commands/info.ts","../src/cli/commands/mcp-server.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * CLI entry point for claude-code-bridge\n *\n * Commands:\n * start Start the bridge server\n * stop Stop the running bridge\n * status Show bridge status and connected peers\n * connect Connect to a remote bridge\n * info Show system and configuration info\n *\n * Global options:\n * --verbose, -v Enable verbose logging\n * --config Path to config file\n */\n\nimport { Command } from 'commander';\nimport { createLogger } from '../utils/logger.js';\nimport { createStartCommand } from './commands/start.js';\nimport { createStopCommand } from './commands/stop.js';\nimport { createStatusCommand } from './commands/status.js';\nimport { createConnectCommand } from './commands/connect.js';\nimport { createInfoCommand } from './commands/info.js';\nimport { createMcpServerCommand } from './commands/mcp-server.js';\n\n// Read version from package.json\n// Since we're building with tsup, we import it directly\nconst VERSION = '0.1.0';\n\nconst logger = createLogger('cli');\n\n/**\n * Global options interface\n */\nexport interface GlobalOptions {\n verbose?: boolean;\n config?: string;\n}\n\n/**\n * Create and configure the CLI program\n */\nexport function createProgram(): Command {\n const program = new Command();\n\n program\n .name('claude-bridge')\n .description('Bidirectional communication system for Claude Code instances across environments')\n .version(VERSION, '-V, --version', 'Output the version number')\n .option('-v, --verbose', 'Enable verbose logging')\n .option('--config <path>', 'Path to config file');\n\n // Hook to process global options before commands\n program.hook('preAction', (thisCommand) => {\n const opts = thisCommand.opts() as GlobalOptions;\n if (opts.verbose) {\n // Set log level to debug when verbose is enabled\n process.env.LOG_LEVEL = 'debug';\n }\n });\n\n return program;\n}\n\n/**\n * Get global options from the program\n */\nexport function getGlobalOptions(program: Command): GlobalOptions {\n return program.opts() as GlobalOptions;\n}\n\n/**\n * Main CLI entry point\n */\nexport async function main(): Promise<void> {\n const program = createProgram();\n\n // Add commands\n program.addCommand(createStartCommand());\n program.addCommand(createStopCommand());\n program.addCommand(createStatusCommand());\n program.addCommand(createConnectCommand());\n program.addCommand(createInfoCommand());\n program.addCommand(createMcpServerCommand());\n\n // Parse arguments and execute\n await program.parseAsync(process.argv);\n}\n\n// Run CLI if executed directly\nmain().catch((error: Error) => {\n logger.error({ err: error }, 'CLI error');\n process.exit(1);\n});\n\n// Export for programmatic use\nexport { createProgram as createCLI };\n","/**\n * CLI start command - Start the bridge server\n *\n * Options:\n * --port, -p Port to listen on (default: 8765)\n * --host, -h Host to bind to (default: 0.0.0.0)\n * --connect, -c URL to connect to on startup\n * --daemon, -d Run in background\n * --with-handlers Enable file reading and task handling capabilities\n * --launch-claude Start bridge daemon and launch Claude Code\n * [claude-args...] Arguments to pass to Claude Code (after --)\n *\n * Example:\n * claude-bridge start --port 8766 --launch-claude -- --dangerously-skip-permissions\n */\n\nimport { Command } from 'commander';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { spawn } from 'child_process';\nimport { minimatch } from 'minimatch';\nimport { createLogger } from '../../utils/logger.js';\nimport { loadConfigSync, type BridgeConfig as UtilsBridgeConfig } from '../../utils/config.js';\nimport { Bridge, type BridgeConfig, type BridgeMode, type TaskRequest, type FileChunk } from '../../bridge/core.js';\nimport { setupGracefulShutdown, handleUnhandledRejections } from '../utils.js';\nimport type { GlobalOptions } from '../index.js';\n\nconst logger = createLogger('cli:start');\n\n/**\n * Options for the start command\n */\nexport interface StartCommandOptions {\n port?: string;\n host?: string;\n connect?: string;\n daemon?: boolean;\n withHandlers?: boolean;\n launchClaude?: boolean;\n claudeArgs?: string[];\n}\n\n/**\n * Get the PID file path\n */\nfunction getPidFilePath(): string {\n const bridgeDir = path.join(os.homedir(), '.claude-bridge');\n return path.join(bridgeDir, 'bridge.pid');\n}\n\n/**\n * Ensure the .claude-bridge directory exists\n */\nfunction ensureBridgeDir(): void {\n const bridgeDir = path.join(os.homedir(), '.claude-bridge');\n if (!fs.existsSync(bridgeDir)) {\n fs.mkdirSync(bridgeDir, { recursive: true });\n }\n}\n\n/**\n * Write PID file for daemon mode\n */\nfunction writePidFile(pid: number): void {\n ensureBridgeDir();\n const pidFile = getPidFilePath();\n fs.writeFileSync(pidFile, pid.toString(), 'utf-8');\n}\n\n/**\n * Remove PID file on shutdown\n */\nfunction removePidFile(): void {\n const pidFile = getPidFilePath();\n if (fs.existsSync(pidFile)) {\n fs.unlinkSync(pidFile);\n }\n}\n\n/**\n * Check if a bridge is already running by checking the PID file\n */\nfunction isAlreadyRunning(): { running: boolean; pid?: number } {\n const pidFile = getPidFilePath();\n if (!fs.existsSync(pidFile)) {\n return { running: false };\n }\n\n try {\n const pid = parseInt(fs.readFileSync(pidFile, 'utf-8').trim(), 10);\n // Check if process is still running\n process.kill(pid, 0); // Signal 0 checks existence without killing\n return { running: true, pid };\n } catch {\n // Process doesn't exist, clean up stale PID file\n removePidFile();\n return { running: false };\n }\n}\n\n/**\n * Get all files in a directory recursively\n */\nfunction getFilesRecursively(dir: string, baseDir: string = dir): string[] {\n const files: string[] = [];\n\n try {\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n const relativePath = path.relative(baseDir, fullPath);\n\n if (entry.isDirectory()) {\n // Skip common directories\n if (['node_modules', '.git', 'dist', 'build', '.next', 'coverage'].includes(entry.name)) {\n continue;\n }\n files.push(...getFilesRecursively(fullPath, baseDir));\n } else if (entry.isFile()) {\n files.push(relativePath);\n }\n }\n } catch {\n // Ignore permission errors\n }\n\n return files;\n}\n\n/**\n * Check if a file matches any of the patterns\n */\nfunction matchesPatterns(filePath: string, patterns: string[]): boolean {\n return patterns.some(pattern => minimatch(filePath, pattern, { dot: true }));\n}\n\n/**\n * Read file contents safely\n */\nfunction readFileSafe(filePath: string, maxSize: number = 100000): string | null {\n try {\n const stats = fs.statSync(filePath);\n if (stats.size > maxSize) {\n return `[File too large: ${stats.size} bytes]`;\n }\n return fs.readFileSync(filePath, 'utf-8');\n } catch {\n return null;\n }\n}\n\n/**\n * Register handlers for file reading and task processing\n */\nfunction registerHandlers(\n bridge: Bridge,\n config: { includePatterns: string[]; excludePatterns: string[] }\n): void {\n const cwd = process.cwd();\n\n // Handler for context requests - find and return relevant files\n bridge.onContextRequested(async (query: string, peerId: string): Promise<FileChunk[]> => {\n logger.info({ query, peerId }, 'Context requested');\n\n const files = getFilesRecursively(cwd);\n const chunks: FileChunk[] = [];\n const queryLower = query.toLowerCase();\n const queryTerms = queryLower.split(/\\s+/).filter(t => t.length > 2);\n\n for (const file of files) {\n // Check exclude patterns\n if (matchesPatterns(file, config.excludePatterns)) {\n continue;\n }\n\n // Check if file matches query or include patterns\n const fileLower = file.toLowerCase();\n const matchesQuery = queryTerms.some(term => fileLower.includes(term));\n const matchesInclude = matchesPatterns(file, config.includePatterns);\n\n if (matchesQuery || matchesInclude) {\n const fullPath = path.join(cwd, file);\n const content = readFileSafe(fullPath);\n\n if (content !== null) {\n chunks.push({\n path: file,\n content,\n language: path.extname(file).slice(1) || undefined,\n });\n }\n\n // Limit number of files returned\n if (chunks.length >= 20) {\n break;\n }\n }\n }\n\n logger.info({ fileCount: chunks.length, query }, 'Context response prepared');\n return chunks;\n });\n\n // Handler for incoming tasks\n bridge.onTaskReceived(async (task: TaskRequest, peerId: string) => {\n logger.info({ taskId: task.id, description: task.description, peerId }, 'Task received');\n\n // Check for file operations in task data\n const taskData = task.data as Record<string, unknown> | undefined;\n const action = taskData?.action as string | undefined;\n\n // Log incoming command details to console\n console.log('\\n┌─────────────────────────────────────────────────────────────');\n console.log(`│ 📥 INCOMING TASK: ${task.description}`);\n console.log(`│ ID: ${task.id}`);\n console.log(`│ Scope: ${task.scope}`);\n if (action) {\n console.log(`│ Action: ${action}`);\n if (taskData?.path) {\n console.log(`│ Path: ${taskData.path}`);\n }\n }\n console.log('└─────────────────────────────────────────────────────────────\\n');\n\n // Handle file write action\n if (taskData?.action === 'write_file') {\n const filePath = taskData.path as string;\n const content = taskData.content as string;\n\n if (!filePath || content === undefined) {\n console.log(' ❌ RESULT: write_file requires path and content');\n return {\n success: false,\n data: { error: 'write_file requires path and content' },\n };\n }\n\n // Resolve path relative to cwd\n const fullPath = path.isAbsolute(filePath) ? filePath : path.join(cwd, filePath);\n\n // Security: ensure path is within cwd\n const resolvedPath = path.resolve(fullPath);\n const resolvedCwd = path.resolve(cwd);\n if (!resolvedPath.startsWith(resolvedCwd)) {\n console.log(' ❌ RESULT: Cannot write files outside project directory');\n return {\n success: false,\n data: { error: 'Cannot write files outside project directory' },\n };\n }\n\n try {\n // Ensure parent directory exists\n const parentDir = path.dirname(resolvedPath);\n if (!fs.existsSync(parentDir)) {\n fs.mkdirSync(parentDir, { recursive: true });\n }\n\n fs.writeFileSync(resolvedPath, content, 'utf-8');\n const bytesWritten = Buffer.byteLength(content, 'utf-8');\n logger.info({ path: filePath }, 'File written successfully');\n console.log(` ✅ RESULT: Wrote ${bytesWritten} bytes to ${filePath}`);\n\n return {\n success: true,\n data: {\n action: 'write_file',\n path: filePath,\n bytesWritten,\n },\n };\n } catch (err) {\n logger.error({ error: (err as Error).message, path: filePath }, 'Failed to write file');\n console.log(` ❌ RESULT: Failed to write file: ${(err as Error).message}`);\n return {\n success: false,\n data: { error: `Failed to write file: ${(err as Error).message}` },\n };\n }\n }\n\n // Handle file read action\n if (taskData?.action === 'read_file') {\n const filePath = taskData.path as string;\n\n if (!filePath) {\n console.log(' ❌ RESULT: read_file requires path');\n return {\n success: false,\n data: { error: 'read_file requires path' },\n };\n }\n\n const fullPath = path.isAbsolute(filePath) ? filePath : path.join(cwd, filePath);\n const content = readFileSafe(fullPath);\n\n if (content === null) {\n console.log(` ❌ RESULT: Cannot read file: ${filePath}`);\n return {\n success: false,\n data: { error: `Cannot read file: ${filePath}` },\n };\n }\n\n console.log(` ✅ RESULT: Read ${content.length} chars from ${filePath}`);\n return {\n success: true,\n data: {\n action: 'read_file',\n path: filePath,\n content,\n },\n };\n }\n\n // Handle delete file action\n if (taskData?.action === 'delete_file') {\n const filePath = taskData.path as string;\n\n if (!filePath) {\n console.log(' ❌ RESULT: delete_file requires path');\n return {\n success: false,\n data: { error: 'delete_file requires path' },\n };\n }\n\n const fullPath = path.isAbsolute(filePath) ? filePath : path.join(cwd, filePath);\n\n // Security: ensure path is within cwd\n const resolvedPath = path.resolve(fullPath);\n const resolvedCwd = path.resolve(cwd);\n if (!resolvedPath.startsWith(resolvedCwd)) {\n console.log(' ❌ RESULT: Cannot delete files outside project directory');\n return {\n success: false,\n data: { error: 'Cannot delete files outside project directory' },\n };\n }\n\n try {\n if (!fs.existsSync(resolvedPath)) {\n console.log(` ❌ RESULT: File not found: ${filePath}`);\n return {\n success: false,\n data: { error: `File not found: ${filePath}` },\n };\n }\n\n fs.unlinkSync(resolvedPath);\n logger.info({ path: filePath }, 'File deleted successfully');\n console.log(` ✅ RESULT: Deleted ${filePath}`);\n\n return {\n success: true,\n data: {\n action: 'delete_file',\n path: filePath,\n },\n };\n } catch (err) {\n logger.error({ error: (err as Error).message, path: filePath }, 'Failed to delete file');\n console.log(` ❌ RESULT: Failed to delete file: ${(err as Error).message}`);\n return {\n success: false,\n data: { error: `Failed to delete file: ${(err as Error).message}` },\n };\n }\n }\n\n // Handle list directory action\n if (taskData?.action === 'list_directory') {\n const dirPath = taskData.path as string;\n\n if (!dirPath) {\n console.log(' ❌ RESULT: list_directory requires path');\n return {\n success: false,\n data: { error: 'list_directory requires path' },\n };\n }\n\n const fullPath = path.isAbsolute(dirPath) ? dirPath : path.join(cwd, dirPath);\n\n // Security: ensure path is within cwd\n const resolvedPath = path.resolve(fullPath);\n const resolvedCwd = path.resolve(cwd);\n if (!resolvedPath.startsWith(resolvedCwd)) {\n console.log(' ❌ RESULT: Cannot list directories outside project directory');\n return {\n success: false,\n data: { error: 'Cannot list directories outside project directory' },\n };\n }\n\n try {\n if (!fs.existsSync(resolvedPath)) {\n console.log(` ❌ RESULT: Directory not found: ${dirPath}`);\n return {\n success: false,\n data: { error: `Directory not found: ${dirPath}` },\n };\n }\n\n const stats = fs.statSync(resolvedPath);\n if (!stats.isDirectory()) {\n console.log(` ❌ RESULT: Not a directory: ${dirPath}`);\n return {\n success: false,\n data: { error: `Not a directory: ${dirPath}` },\n };\n }\n\n const entries = fs.readdirSync(resolvedPath, { withFileTypes: true });\n const listing = entries.map(entry => ({\n name: entry.name,\n type: entry.isDirectory() ? 'directory' : 'file',\n }));\n\n logger.info({ path: dirPath, count: listing.length }, 'Directory listed successfully');\n console.log(` ✅ RESULT: Listed ${listing.length} entries in ${dirPath}`);\n\n return {\n success: true,\n data: {\n action: 'list_directory',\n path: dirPath,\n entries: listing,\n },\n };\n } catch (err) {\n logger.error({ error: (err as Error).message, path: dirPath }, 'Failed to list directory');\n console.log(` ❌ RESULT: Failed to list directory: ${(err as Error).message}`);\n return {\n success: false,\n data: { error: `Failed to list directory: ${(err as Error).message}` },\n };\n }\n }\n\n // Default: Get project info for the response\n const projectInfo: Record<string, unknown> = {\n cwd,\n platform: process.platform,\n nodeVersion: process.version,\n };\n\n // Try to read package.json for project details\n const pkgPath = path.join(cwd, 'package.json');\n if (fs.existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));\n projectInfo.name = pkg.name;\n projectInfo.version = pkg.version;\n projectInfo.description = pkg.description;\n projectInfo.dependencies = Object.keys(pkg.dependencies || {});\n projectInfo.devDependencies = Object.keys(pkg.devDependencies || {});\n } catch {\n // Ignore parse errors\n }\n }\n\n // List top-level files and directories\n try {\n const entries = fs.readdirSync(cwd, { withFileTypes: true });\n projectInfo.structure = entries\n .filter(e => !e.name.startsWith('.') && e.name !== 'node_modules')\n .map(e => ({\n name: e.name,\n type: e.isDirectory() ? 'directory' : 'file',\n }));\n } catch {\n // Ignore errors\n }\n\n // Get source files summary\n const allFiles = getFilesRecursively(cwd);\n const sourceFiles = allFiles.filter(f =>\n matchesPatterns(f, config.includePatterns) &&\n !matchesPatterns(f, config.excludePatterns)\n );\n projectInfo.sourceFileCount = sourceFiles.length;\n projectInfo.sourceFiles = sourceFiles.slice(0, 50); // First 50 files\n\n return {\n success: true,\n data: {\n message: `Task received and analyzed: ${task.description}`,\n scope: task.scope,\n projectInfo,\n },\n };\n });\n\n // Handler for incoming context sync\n bridge.onContextReceived((context, peerId) => {\n logger.info(\n {\n peerId,\n fileCount: context.files?.length || 0,\n summary: context.summary\n },\n 'Context received from peer'\n );\n\n if (context.files) {\n for (const file of context.files) {\n console.log(` 📄 Received: ${file.path} (${file.content?.length || 0} chars)`);\n }\n }\n if (context.summary) {\n console.log(` 📝 Summary: ${context.summary}`);\n }\n });\n\n logger.info('Handlers registered for context requests, tasks, and context sync');\n console.log(' Handlers: enabled (file reading & task processing)');\n}\n\n/**\n * Build bridge configuration from CLI options and config file\n */\nfunction buildBridgeConfig(\n options: StartCommandOptions,\n globalOptions: GlobalOptions\n): BridgeConfig {\n // Load config file first\n const fileConfig = loadConfigSync(globalOptions.config);\n\n // CLI options override everything\n const cliConfig: Partial<BridgeConfig> = {};\n\n if (options.port) {\n cliConfig.listen = {\n ...cliConfig.listen,\n port: parseInt(options.port, 10),\n host: options.host ?? '0.0.0.0',\n };\n }\n\n if (options.host && !cliConfig.listen) {\n cliConfig.listen = {\n port: fileConfig.listen.port,\n host: options.host,\n };\n }\n\n if (options.connect) {\n cliConfig.connect = {\n url: options.connect,\n };\n }\n\n // Determine mode based on configuration\n // If connecting to a remote, we're a client; otherwise we're a host\n const hasConnect = cliConfig.connect || fileConfig.connect;\n const mode: BridgeMode = hasConnect ? 'client' : 'host';\n\n // Build final config with priority: CLI > file config > defaults\n const finalConfig: BridgeConfig = {\n mode: cliConfig.mode ?? fileConfig.mode ?? mode,\n instanceName: cliConfig.instanceName ?? fileConfig.instanceName ?? `bridge-${process.pid}`,\n listen: {\n port: cliConfig.listen?.port ?? fileConfig.listen.port,\n host: cliConfig.listen?.host ?? fileConfig.listen.host,\n },\n taskTimeout: fileConfig.interaction.taskTimeout,\n contextSharing: {\n autoSync: fileConfig.contextSharing.autoSync,\n syncInterval: fileConfig.contextSharing.syncInterval,\n },\n };\n\n // Add connect config if present\n const connectUrl = cliConfig.connect?.url ?? fileConfig.connect?.url;\n if (connectUrl) {\n finalConfig.connect = {\n url: connectUrl,\n };\n }\n\n return finalConfig;\n}\n\n/**\n * Start the bridge server\n */\nasync function startBridge(\n options: StartCommandOptions,\n globalOptions: GlobalOptions\n): Promise<void> {\n // Check if already running (skip check if we're the daemon child)\n if (!process.env.CLAUDE_BRIDGE_DAEMON_CHILD) {\n const { running, pid } = isAlreadyRunning();\n if (running) {\n // If --launch-claude is set, just launch Claude Code and attach to existing bridge\n if (options.launchClaude) {\n const claudeArgs = options.claudeArgs || [];\n console.log(`Bridge already running (PID: ${pid}), launching Claude Code...`);\n if (claudeArgs.length > 0) {\n console.log(` Claude args: ${claudeArgs.join(' ')}`);\n }\n const { spawnSync } = await import('child_process');\n const result = spawnSync('claude', claudeArgs, {\n stdio: 'inherit',\n shell: true,\n });\n process.exit(result.status ?? 0);\n }\n console.error(`Bridge is already running (PID: ${pid})`);\n process.exit(1);\n }\n }\n\n // Build configuration\n const config = buildBridgeConfig(options, globalOptions);\n\n // Log startup info\n console.log('Starting Claude Code Bridge...');\n console.log(` Instance: ${config.instanceName}`);\n console.log(` Mode: ${config.mode}`);\n\n if (config.listen) {\n console.log(` Listening: ${config.listen.host}:${config.listen.port}`);\n }\n\n if (config.connect) {\n console.log(` Connecting to: ${config.connect.url}`);\n }\n\n // Handle daemon mode - spawn detached child process\n if (options.daemon && !process.env.CLAUDE_BRIDGE_DAEMON_CHILD) {\n const logFile = path.join(os.homedir(), '.claude-bridge', 'bridge.log');\n ensureBridgeDir();\n\n // Build args for child process (exclude --daemon to prevent infinite loop)\n const args = process.argv.slice(2).filter(arg => arg !== '-d' && arg !== '--daemon');\n\n // Spawn detached child process\n const out = fs.openSync(logFile, 'a');\n const err = fs.openSync(logFile, 'a');\n\n const child = spawn(process.execPath, [process.argv[1], ...args], {\n detached: true,\n stdio: ['ignore', out, err],\n env: { ...process.env, CLAUDE_BRIDGE_DAEMON_CHILD: '1' },\n });\n\n child.unref();\n\n // Write child PID to file\n writePidFile(child.pid!);\n\n console.log(` Running in background (PID: ${child.pid})`);\n console.log(` Log file: ${logFile}`);\n console.log(` Use 'claude-bridge status' to check status`);\n console.log(` Use 'claude-bridge stop' to stop the bridge`);\n\n // Launch Claude Code if requested\n if (options.launchClaude) {\n const claudeArgs = options.claudeArgs || [];\n console.log('\\nLaunching Claude Code...');\n if (claudeArgs.length > 0) {\n console.log(` Claude args: ${claudeArgs.join(' ')}`);\n }\n\n // Give the daemon a moment to start\n await new Promise(resolve => setTimeout(resolve, 500));\n\n // Launch claude in the foreground (replaces this process)\n const { spawnSync } = await import('child_process');\n const result = spawnSync('claude', claudeArgs, {\n stdio: 'inherit',\n shell: true,\n });\n\n process.exit(result.status ?? 0);\n }\n\n // Parent exits immediately\n process.exit(0);\n }\n\n // Create and start bridge\n const bridge = new Bridge(config);\n\n // Set up graceful shutdown handling\n setupGracefulShutdown({\n cleanup: async () => {\n logger.info('Stopping bridge...');\n await bridge.stop();\n logger.info('Bridge stopped');\n },\n afterCleanup: process.env.CLAUDE_BRIDGE_DAEMON_CHILD ? removePidFile : undefined,\n verbose: true,\n timeout: 10000,\n });\n\n // Handle unhandled promise rejections\n handleUnhandledRejections({\n exit: false,\n logger: (msg, err) => logger.error({ error: err.message }, msg),\n });\n\n // Load config for handler patterns\n const fileConfig = loadConfigSync(globalOptions.config);\n\n try {\n await bridge.start();\n\n // Register handlers if --with-handlers is enabled\n if (options.withHandlers) {\n registerHandlers(bridge, {\n includePatterns: fileConfig.contextSharing.includePatterns,\n excludePatterns: fileConfig.contextSharing.excludePatterns,\n });\n }\n\n // Write PID file if running as daemon child (parent already wrote it, but update to confirm startup)\n if (process.env.CLAUDE_BRIDGE_DAEMON_CHILD) {\n writePidFile(process.pid);\n }\n\n console.log('Bridge started successfully.');\n console.log(`Connected peers: ${bridge.getPeerCount()}`);\n\n // Log connection info for users\n if (config.listen) {\n console.log(`\\nTo connect from another bridge:`);\n console.log(` claude-bridge connect ws://localhost:${config.listen.port}`);\n }\n\n // Keep the process running\n if (!process.env.CLAUDE_BRIDGE_DAEMON_CHILD) {\n console.log('\\nPress Ctrl+C to stop.');\n }\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Failed to start bridge');\n console.error(`Failed to start bridge: ${(error as Error).message}`);\n if (process.env.CLAUDE_BRIDGE_DAEMON_CHILD) {\n removePidFile();\n }\n process.exit(1);\n }\n}\n\n/**\n * Create the start command\n */\nexport function createStartCommand(): Command {\n const command = new Command('start');\n\n command\n .description('Start the bridge server')\n .option('-p, --port <port>', 'Port to listen on (default: 8765)')\n .option('-h, --host <host>', 'Host to bind to (default: 0.0.0.0)')\n .option('-c, --connect <url>', 'URL to connect to on startup (e.g., ws://localhost:8765)')\n .option('-d, --daemon', 'Run in background')\n .option('--with-handlers', 'Enable file reading and task handling capabilities')\n .option('--launch-claude', 'Start bridge daemon and launch Claude Code')\n .argument('[claude-args...]', 'Arguments to pass to Claude Code (use after --)')\n .action(async (claudeArgs: string[], options: StartCommandOptions) => {\n // Store claude args in options\n options.claudeArgs = claudeArgs;\n\n // --launch-claude implies --daemon\n if (options.launchClaude) {\n options.daemon = true;\n }\n // Get global options from parent command\n const globalOptions = command.parent?.opts() as GlobalOptions;\n await startBridge(options, globalOptions);\n });\n\n return command;\n}\n\n/**\n * Export the command for use in CLI\n */\nexport { createStartCommand as startCommand };\n","/**\n * CLI output formatting utilities\n *\n * Provides helpers for colored output, table formatting, progress spinners,\n * and option parsing/validation.\n */\n\n/**\n * ANSI color codes for terminal output\n */\nexport const colors = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n\n // Foreground colors\n red: '\\x1b[31m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[34m',\n magenta: '\\x1b[35m',\n cyan: '\\x1b[36m',\n white: '\\x1b[37m',\n gray: '\\x1b[90m',\n} as const;\n\n/**\n * Check if terminal supports colors\n */\nexport function supportsColor(): boolean {\n // Disable colors if NO_COLOR env var is set\n if (process.env.NO_COLOR !== undefined) {\n return false;\n }\n\n // Enable colors if FORCE_COLOR is set\n if (process.env.FORCE_COLOR !== undefined) {\n return true;\n }\n\n // Check if stdout is a TTY\n if (typeof process.stdout.isTTY !== 'undefined' && process.stdout.isTTY) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Apply color to text (only if terminal supports it)\n */\nexport function colorize(text: string, color: keyof typeof colors): string {\n if (!supportsColor()) {\n return text;\n }\n return `${colors[color]}${text}${colors.reset}`;\n}\n\n/**\n * Print success message (green)\n */\nexport function success(message: string): void {\n console.log(colorize('✓ ' + message, 'green'));\n}\n\n/**\n * Print error message (red)\n */\nexport function error(message: string): void {\n console.error(colorize('✗ ' + message, 'red'));\n}\n\n/**\n * Print warning message (yellow)\n */\nexport function warning(message: string): void {\n console.log(colorize('⚠ ' + message, 'yellow'));\n}\n\n/**\n * Print info message (blue)\n */\nexport function info(message: string): void {\n console.log(colorize('ℹ ' + message, 'blue'));\n}\n\n/**\n * Print debug message (gray)\n */\nexport function debug(message: string): void {\n console.log(colorize('⋯ ' + message, 'gray'));\n}\n\n/**\n * Table column configuration\n */\nexport interface TableColumn {\n title: string;\n width: number;\n align?: 'left' | 'right' | 'center';\n}\n\n/**\n * Table row data (key-value pairs matching column titles)\n */\nexport type TableRow = Record<string, string | number | undefined>;\n\n/**\n * Pad a string to a specific width with alignment\n */\nexport function padToWidth(\n text: string,\n width: number,\n align: 'left' | 'right' | 'center' = 'left'\n): string {\n const str = String(text).slice(0, width);\n const padding = width - str.length;\n\n if (align === 'right') {\n return ' '.repeat(padding) + str;\n } else if (align === 'center') {\n const leftPad = Math.floor(padding / 2);\n const rightPad = padding - leftPad;\n return ' '.repeat(leftPad) + str + ' '.repeat(rightPad);\n } else {\n return str + ' '.repeat(padding);\n }\n}\n\n/**\n * Print a formatted table\n */\nexport function printTable(\n columns: TableColumn[],\n rows: TableRow[],\n options: { indent?: number; borderStyle?: 'simple' | 'none' } = {}\n): void {\n const indent = ' '.repeat(options.indent ?? 0);\n const borderStyle = options.borderStyle ?? 'simple';\n\n // Print header\n const headerRow = columns\n .map((col) => padToWidth(col.title, col.width, col.align))\n .join(' ');\n console.log(indent + colorize(headerRow, 'bold'));\n\n // Print separator\n if (borderStyle === 'simple') {\n const separator = columns\n .map((col) => '-'.repeat(col.width))\n .join(' ');\n console.log(indent + separator);\n }\n\n // Print rows\n for (const row of rows) {\n const rowText = columns\n .map((col) => {\n // Find matching key case-insensitively\n const key = Object.keys(row).find(\n (k) => k.toLowerCase() === col.title.toLowerCase()\n );\n const value = key ? String(row[key] ?? '') : '';\n return padToWidth(value, col.width, col.align);\n })\n .join(' ');\n console.log(indent + rowText);\n }\n}\n\n/**\n * Spinner frames for progress indication\n */\nconst SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n\n/**\n * Progress spinner for long operations\n */\nexport class Spinner {\n private message: string;\n private intervalId: ReturnType<typeof setInterval> | null = null;\n private frameIndex = 0;\n private stream = process.stdout;\n\n constructor(message: string) {\n this.message = message;\n }\n\n /**\n * Start the spinner animation\n */\n start(): void {\n if (!supportsColor() || !this.stream.isTTY) {\n // Non-TTY: just print the message once\n console.log(`... ${this.message}`);\n return;\n }\n\n // Hide cursor\n this.stream.write('\\x1b[?25l');\n\n this.intervalId = setInterval(() => {\n const frame = SPINNER_FRAMES[this.frameIndex];\n this.stream.write(\n `\\r${colorize(frame, 'cyan')} ${this.message}`\n );\n this.frameIndex = (this.frameIndex + 1) % SPINNER_FRAMES.length;\n }, 80);\n }\n\n /**\n * Update the spinner message\n */\n update(message: string): void {\n this.message = message;\n }\n\n /**\n * Stop the spinner with a success message\n */\n succeed(message?: string): void {\n this.stop();\n success(message ?? this.message);\n }\n\n /**\n * Stop the spinner with an error message\n */\n fail(message?: string): void {\n this.stop();\n error(message ?? this.message);\n }\n\n /**\n * Stop the spinner with a warning message\n */\n warn(message?: string): void {\n this.stop();\n warning(message ?? this.message);\n }\n\n /**\n * Stop the spinner (no message)\n */\n stop(): void {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n\n if (supportsColor() && this.stream.isTTY) {\n // Clear line and show cursor\n this.stream.write('\\r\\x1b[K');\n this.stream.write('\\x1b[?25h');\n }\n }\n}\n\n/**\n * Create and start a new spinner\n */\nexport function spinner(message: string): Spinner {\n const s = new Spinner(message);\n s.start();\n return s;\n}\n\n/**\n * Parsed start command options\n */\nexport interface ParsedStartOptions {\n listen?: {\n port: number;\n host: string;\n };\n connect?: {\n url: string;\n };\n daemon: boolean;\n}\n\n/**\n * Parse and validate start command options\n */\nexport function parseStartOptions(options: {\n port?: string;\n host?: string;\n connect?: string;\n daemon?: boolean;\n}): ParsedStartOptions {\n const result: ParsedStartOptions = {\n daemon: options.daemon ?? false,\n };\n\n // Parse port\n if (options.port) {\n const port = parseInt(options.port, 10);\n if (isNaN(port) || port < 1 || port > 65535) {\n throw new Error(`Invalid port: ${options.port}. Must be between 1 and 65535.`);\n }\n result.listen = {\n port,\n host: options.host ?? '0.0.0.0',\n };\n } else if (options.host) {\n // Host specified without port, use default port\n result.listen = {\n port: 8765,\n host: options.host,\n };\n }\n\n // Parse connect URL\n if (options.connect) {\n validateWebSocketUrl(options.connect);\n result.connect = {\n url: options.connect,\n };\n }\n\n return result;\n}\n\n/**\n * Validate a WebSocket URL\n */\nexport function validateWebSocketUrl(url: string): void {\n if (!url.startsWith('ws://') && !url.startsWith('wss://')) {\n throw new Error(\n `Invalid URL protocol. Expected ws:// or wss://, got: ${url}`\n );\n }\n\n try {\n const parsed = new URL(url);\n if (!parsed.hostname) {\n throw new Error('URL must include a hostname');\n }\n } catch (e) {\n if (e instanceof Error && e.message.includes('Invalid URL')) {\n throw new Error(`Invalid URL format: ${url}`);\n }\n throw e;\n }\n}\n\n/**\n * Parsed connect command options\n */\nexport interface ParsedConnectOptions {\n url: string;\n}\n\n/**\n * Parse and validate connect command options\n */\nexport function parseConnectOptions(options: {\n url?: string;\n}): ParsedConnectOptions {\n if (!options.url) {\n throw new Error('URL is required');\n }\n\n validateWebSocketUrl(options.url);\n\n return {\n url: options.url,\n };\n}\n\n/**\n * Format duration in human-readable form\n */\nexport function formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n }\n if (ms < 60000) {\n return `${(ms / 1000).toFixed(1)}s`;\n }\n if (ms < 3600000) {\n const minutes = Math.floor(ms / 60000);\n const seconds = Math.round((ms % 60000) / 1000);\n return `${minutes}m ${seconds}s`;\n }\n const hours = Math.floor(ms / 3600000);\n const minutes = Math.round((ms % 3600000) / 60000);\n return `${hours}h ${minutes}m`;\n}\n\n/**\n * Format bytes in human-readable form\n */\nexport function formatBytes(bytes: number): string {\n const units = ['B', 'KB', 'MB', 'GB', 'TB'];\n let unitIndex = 0;\n let value = bytes;\n\n while (value >= 1024 && unitIndex < units.length - 1) {\n value /= 1024;\n unitIndex++;\n }\n\n return `${value.toFixed(unitIndex === 0 ? 0 : 1)} ${units[unitIndex]}`;\n}\n\n/**\n * Shutdown handler type\n */\nexport type ShutdownHandler = (signal: string) => Promise<void>;\n\n/**\n * Options for setting up graceful shutdown\n */\nexport interface GracefulShutdownOptions {\n /**\n * Cleanup function to call on shutdown\n */\n cleanup: () => Promise<void>;\n\n /**\n * Additional cleanup to call after main cleanup (e.g., removing PID file)\n */\n afterCleanup?: () => void;\n\n /**\n * Whether to show shutdown messages\n * @default true\n */\n verbose?: boolean;\n\n /**\n * Timeout in milliseconds before forcing exit\n * @default 10000\n */\n timeout?: number;\n}\n\n/**\n * Set up graceful shutdown handlers for SIGTERM and SIGINT\n *\n * Handles process signals to ensure clean shutdown of bridges and connections.\n * - SIGTERM: Sent by `kill` command or process managers\n * - SIGINT: Sent by Ctrl+C in terminal\n *\n * @param options Shutdown configuration options\n * @returns Function to remove the handlers (for testing)\n */\nexport function setupGracefulShutdown(options: GracefulShutdownOptions): () => void {\n const {\n cleanup,\n afterCleanup,\n verbose = true,\n timeout = 10000,\n } = options;\n\n let isShuttingDown = false;\n\n const handler: ShutdownHandler = async (signal: string) => {\n // Prevent multiple shutdown attempts\n if (isShuttingDown) {\n if (verbose) {\n console.log('Shutdown already in progress...');\n }\n return;\n }\n isShuttingDown = true;\n\n if (verbose) {\n console.log(`\\nReceived ${signal}, shutting down gracefully...`);\n }\n\n // Set up force exit timeout\n const forceExitTimeout = setTimeout(() => {\n if (verbose) {\n console.error('Shutdown timeout - forcing exit');\n }\n process.exit(1);\n }, timeout);\n\n try {\n await cleanup();\n\n if (afterCleanup) {\n afterCleanup();\n }\n\n clearTimeout(forceExitTimeout);\n\n if (verbose) {\n console.log('Shutdown complete.');\n }\n process.exit(0);\n } catch (error) {\n clearTimeout(forceExitTimeout);\n if (verbose) {\n console.error(`Error during shutdown: ${(error as Error).message}`);\n }\n process.exit(1);\n }\n };\n\n // Register handlers\n const sigintHandler = () => handler('SIGINT');\n const sigtermHandler = () => handler('SIGTERM');\n\n process.on('SIGINT', sigintHandler);\n process.on('SIGTERM', sigtermHandler);\n\n // Return cleanup function\n return () => {\n process.off('SIGINT', sigintHandler);\n process.off('SIGTERM', sigtermHandler);\n };\n}\n\n/**\n * Handle unhandled promise rejections\n *\n * Logs unhandled rejections and optionally exits the process.\n *\n * @param options Configuration options\n */\nexport function handleUnhandledRejections(options: {\n exit?: boolean;\n logger?: (message: string, error: Error) => void;\n} = {}): void {\n const { exit = false, logger = console.error } = options;\n\n process.on('unhandledRejection', (reason, promise) => {\n const error = reason instanceof Error ? reason : new Error(String(reason));\n logger('Unhandled promise rejection:', error);\n\n if (exit) {\n process.exit(1);\n }\n });\n}\n","/**\n * CLI stop command - Stop the running bridge\n *\n * Reads the PID from ~/.claude-bridge/bridge.pid and sends SIGTERM\n * to gracefully stop the running bridge process.\n */\n\nimport { Command } from 'commander';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { createLogger } from '../../utils/logger.js';\n\nconst logger = createLogger('cli:stop');\n\n/**\n * Get the PID file path\n */\nfunction getPidFilePath(): string {\n const bridgeDir = path.join(os.homedir(), '.claude-bridge');\n return path.join(bridgeDir, 'bridge.pid');\n}\n\n/**\n * Remove PID file\n */\nfunction removePidFile(): void {\n const pidFile = getPidFilePath();\n if (fs.existsSync(pidFile)) {\n fs.unlinkSync(pidFile);\n }\n}\n\n/**\n * Read PID from file\n * Returns null if file doesn't exist or is invalid\n */\nfunction readPidFile(): number | null {\n const pidFile = getPidFilePath();\n if (!fs.existsSync(pidFile)) {\n return null;\n }\n\n try {\n const content = fs.readFileSync(pidFile, 'utf-8').trim();\n const pid = parseInt(content, 10);\n if (isNaN(pid) || pid <= 0) {\n logger.warn({ content }, 'Invalid PID file content');\n return null;\n }\n return pid;\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Failed to read PID file');\n return null;\n }\n}\n\n/**\n * Check if a process is running\n */\nfunction isProcessRunning(pid: number): boolean {\n try {\n // Signal 0 checks if the process exists without sending a signal\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Wait for a process to exit with timeout\n */\nasync function waitForProcessExit(\n pid: number,\n timeoutMs: number = 5000\n): Promise<boolean> {\n const startTime = Date.now();\n const checkInterval = 100;\n\n while (Date.now() - startTime < timeoutMs) {\n if (!isProcessRunning(pid)) {\n return true;\n }\n await new Promise((resolve) => setTimeout(resolve, checkInterval));\n }\n\n return false;\n}\n\n/**\n * Stop the bridge process\n */\nasync function stopBridge(): Promise<void> {\n const pid = readPidFile();\n\n if (pid === null) {\n console.log('Bridge is not running (no PID file found).');\n return;\n }\n\n // Check if process is actually running\n if (!isProcessRunning(pid)) {\n console.log(`Bridge is not running (stale PID file, process ${pid} not found).`);\n // Clean up stale PID file\n removePidFile();\n return;\n }\n\n console.log(`Stopping bridge (PID: ${pid})...`);\n\n try {\n // Send SIGTERM for graceful shutdown\n process.kill(pid, 'SIGTERM');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ESRCH') {\n // Process doesn't exist\n console.log('Bridge process not found.');\n removePidFile();\n return;\n }\n if ((error as NodeJS.ErrnoException).code === 'EPERM') {\n console.error(`Permission denied: cannot stop bridge (PID: ${pid}).`);\n console.error('Try running with elevated privileges.');\n process.exit(1);\n }\n throw error;\n }\n\n // Wait for process to exit\n const exited = await waitForProcessExit(pid);\n\n if (exited) {\n console.log('Bridge stopped successfully.');\n // Clean up PID file if the process didn't do it\n removePidFile();\n } else {\n console.log('Bridge is still shutting down. Check status with: claude-bridge status');\n // Optionally could try SIGKILL here, but we'll leave that to the user\n console.log(`To force stop: kill -9 ${pid}`);\n }\n}\n\n/**\n * Create the stop command\n */\nexport function createStopCommand(): Command {\n const command = new Command('stop');\n\n command\n .description('Stop the running bridge')\n .action(async () => {\n try {\n await stopBridge();\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Failed to stop bridge');\n console.error(`Failed to stop bridge: ${(error as Error).message}`);\n process.exit(1);\n }\n });\n\n return command;\n}\n\n/**\n * Export for use in CLI\n */\nexport { createStopCommand as stopCommand };\n","/**\n * CLI status command - Show bridge status and connected peers\n *\n * Displays whether the bridge is running, what port it's on,\n * and lists connected peers in a formatted table.\n *\n * Options:\n * --port Check status for a specific port\n */\n\nimport { Command } from 'commander';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { createLogger } from '../../utils/logger.js';\n\nconst logger = createLogger('cli:status');\n\n/**\n * Options for the status command\n */\nexport interface StatusCommandOptions {\n port?: string;\n}\n\n/**\n * Bridge status information\n */\nexport interface BridgeStatus {\n running: boolean;\n pid?: number;\n port?: number;\n peers?: PeerStatus[];\n}\n\n/**\n * Peer status information\n */\nexport interface PeerStatus {\n id: string;\n name: string;\n connectedAt: string;\n lastActivity: string;\n}\n\n/**\n * Get the PID file path\n */\nfunction getPidFilePath(): string {\n const bridgeDir = path.join(os.homedir(), '.claude-bridge');\n return path.join(bridgeDir, 'bridge.pid');\n}\n\n/**\n * Get the status file path (where bridge writes current status)\n */\nfunction getStatusFilePath(): string {\n const bridgeDir = path.join(os.homedir(), '.claude-bridge');\n return path.join(bridgeDir, 'status.json');\n}\n\n/**\n * Read PID from file\n */\nfunction readPidFile(): number | null {\n const pidFile = getPidFilePath();\n if (!fs.existsSync(pidFile)) {\n return null;\n }\n\n try {\n const content = fs.readFileSync(pidFile, 'utf-8').trim();\n const pid = parseInt(content, 10);\n if (isNaN(pid) || pid <= 0) {\n return null;\n }\n return pid;\n } catch {\n return null;\n }\n}\n\n/**\n * Check if a process is running\n */\nfunction isProcessRunning(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Read status file written by the bridge\n */\nfunction readStatusFile(): { port?: number; peers?: PeerStatus[] } | null {\n const statusFile = getStatusFilePath();\n if (!fs.existsSync(statusFile)) {\n return null;\n }\n\n try {\n const content = fs.readFileSync(statusFile, 'utf-8');\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\n/**\n * Format a date for display\n */\nfunction formatDate(dateStr: string): string {\n try {\n const date = new Date(dateStr);\n return date.toLocaleString();\n } catch {\n return dateStr;\n }\n}\n\n/**\n * Pad a string to a specific width\n */\nfunction padRight(str: string, width: number): string {\n return str.padEnd(width);\n}\n\n/**\n * Print peer table\n */\nfunction printPeerTable(peers: PeerStatus[]): void {\n if (peers.length === 0) {\n console.log(' No peers connected.');\n return;\n }\n\n // Column headers and widths\n const cols = {\n id: { title: 'ID', width: 38 },\n name: { title: 'Name', width: 20 },\n connected: { title: 'Connected', width: 22 },\n lastActivity: { title: 'Last Activity', width: 22 },\n };\n\n // Print header\n console.log('');\n console.log(\n ' ' +\n padRight(cols.id.title, cols.id.width) +\n padRight(cols.name.title, cols.name.width) +\n padRight(cols.connected.title, cols.connected.width) +\n padRight(cols.lastActivity.title, cols.lastActivity.width)\n );\n\n // Print separator\n const separator =\n ' ' +\n '-'.repeat(cols.id.width - 1) +\n ' ' +\n '-'.repeat(cols.name.width - 1) +\n ' ' +\n '-'.repeat(cols.connected.width - 1) +\n ' ' +\n '-'.repeat(cols.lastActivity.width - 1);\n console.log(separator);\n\n // Print rows\n for (const peer of peers) {\n const row =\n ' ' +\n padRight(peer.id, cols.id.width) +\n padRight(peer.name.slice(0, cols.name.width - 1), cols.name.width) +\n padRight(formatDate(peer.connectedAt), cols.connected.width) +\n padRight(formatDate(peer.lastActivity), cols.lastActivity.width);\n console.log(row);\n }\n\n console.log('');\n}\n\n/**\n * Get bridge status\n */\nfunction getBridgeStatus(): BridgeStatus {\n const pid = readPidFile();\n\n if (pid === null) {\n return { running: false };\n }\n\n if (!isProcessRunning(pid)) {\n // PID file exists but process is not running\n return { running: false };\n }\n\n // Process is running, try to get more details\n const statusInfo = readStatusFile();\n\n return {\n running: true,\n pid,\n port: statusInfo?.port,\n peers: statusInfo?.peers,\n };\n}\n\n/**\n * Show bridge status\n */\nfunction showStatus(options: StatusCommandOptions): void {\n console.log('Claude Code Bridge Status');\n console.log('='.repeat(26));\n console.log('');\n\n const status = getBridgeStatus();\n\n if (!status.running) {\n console.log('Status: stopped');\n console.log('');\n console.log('To start the bridge:');\n console.log(' claude-bridge start');\n return;\n }\n\n console.log('Status: running');\n console.log(`PID: ${status.pid}`);\n\n if (status.port !== undefined) {\n console.log(`Port: ${status.port}`);\n }\n\n console.log('');\n console.log('Connected Peers:');\n\n if (status.peers) {\n printPeerTable(status.peers);\n } else {\n console.log(' Unable to retrieve peer information.');\n console.log(' (Status file not found or unreadable)');\n }\n\n console.log('To stop the bridge:');\n console.log(' claude-bridge stop');\n}\n\n/**\n * Create the status command\n */\nexport function createStatusCommand(): Command {\n const command = new Command('status');\n\n command\n .description('Show bridge status and connected peers')\n .option('-p, --port <port>', 'Check status for a specific port')\n .action((options: StatusCommandOptions) => {\n try {\n showStatus(options);\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Failed to get status');\n console.error(`Failed to get status: ${(error as Error).message}`);\n process.exit(1);\n }\n });\n\n return command;\n}\n\n/**\n * Export for use in CLI\n */\nexport { createStatusCommand as statusCommand };\n","/**\n * CLI connect command - Connect to a remote bridge\n *\n * Takes a WebSocket URL and initiates a connection to a remote bridge.\n * This is a one-time connection test that verifies connectivity.\n *\n * Usage:\n * claude-bridge connect ws://localhost:8765\n */\n\nimport { Command } from 'commander';\nimport { createLogger } from '../../utils/logger.js';\nimport { WebSocketTransport } from '../../transport/websocket.js';\nimport { ConnectionState } from '../../transport/interface.js';\n\nconst logger = createLogger('cli:connect');\n\n/**\n * Validate WebSocket URL format\n * Returns true if valid, throws Error if invalid\n */\nexport function validateWebSocketUrl(url: string): boolean {\n // Check for ws:// or wss:// protocol\n if (!url.startsWith('ws://') && !url.startsWith('wss://')) {\n throw new Error(`Invalid URL protocol. Expected ws:// or wss://, got: ${url}`);\n }\n\n try {\n const parsed = new URL(url);\n\n // Ensure we have a valid hostname\n if (!parsed.hostname) {\n throw new Error('URL must include a hostname');\n }\n\n // Ensure we have a port (for WebSocket connections)\n if (!parsed.port) {\n // Default ports\n const defaultPort = parsed.protocol === 'wss:' ? '443' : '80';\n logger.debug(`No port specified, will use default: ${defaultPort}`);\n }\n\n return true;\n } catch (error) {\n if (error instanceof Error && error.message.includes('Invalid URL')) {\n throw new Error(`Invalid URL format: ${url}`);\n }\n throw error;\n }\n}\n\n/**\n * Connect to a remote bridge\n */\nasync function connectToBridge(url: string): Promise<void> {\n // Validate URL format\n try {\n validateWebSocketUrl(url);\n } catch (error) {\n console.error(`Error: ${(error as Error).message}`);\n process.exit(1);\n }\n\n console.log(`Connecting to bridge at ${url}...`);\n\n const transport = new WebSocketTransport();\n\n // Set up connection timeout\n const timeoutMs = 10000;\n const timeout = setTimeout(() => {\n console.error(`Error: Connection timeout after ${timeoutMs / 1000} seconds`);\n transport.disconnect().catch(() => {});\n process.exit(1);\n }, timeoutMs);\n\n try {\n // Attempt connection\n await transport.connect({\n url,\n reconnect: false, // Don't auto-reconnect for this test\n });\n\n clearTimeout(timeout);\n\n if (transport.getState() === ConnectionState.CONNECTED) {\n console.log('Successfully connected to bridge!');\n console.log('');\n console.log('Connection details:');\n console.log(` URL: ${url}`);\n console.log(` State: ${ConnectionState[transport.getState()]}`);\n console.log('');\n console.log('To start a bridge that auto-connects on startup:');\n console.log(` claude-bridge start --connect ${url}`);\n } else {\n console.error(`Connection failed. State: ${ConnectionState[transport.getState()]}`);\n process.exit(1);\n }\n\n // Clean up - disconnect after successful test\n await transport.disconnect();\n console.log('\\nConnection test complete. Disconnected.');\n } catch (error) {\n clearTimeout(timeout);\n const errorMessage = (error as Error).message;\n console.error(`Error: Failed to connect - ${errorMessage}`);\n\n // Provide helpful suggestions\n if (errorMessage.includes('ECONNREFUSED')) {\n console.log('');\n console.log('Suggestions:');\n console.log(' - Ensure a bridge is running at the specified address');\n console.log(' - Check the port number is correct');\n console.log(' - Verify no firewall is blocking the connection');\n } else if (errorMessage.includes('ENOTFOUND')) {\n console.log('');\n console.log('Suggestions:');\n console.log(' - Check the hostname is correct');\n console.log(' - Ensure DNS resolution is working');\n }\n\n process.exit(1);\n }\n}\n\n/**\n * Create the connect command\n */\nexport function createConnectCommand(): Command {\n const command = new Command('connect');\n\n command\n .description('Connect to a remote bridge')\n .argument('<url>', 'WebSocket URL to connect to (e.g., ws://localhost:8765)')\n .action(async (url: string) => {\n try {\n await connectToBridge(url);\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Connect command failed');\n console.error(`Error: ${(error as Error).message}`);\n process.exit(1);\n }\n });\n\n return command;\n}\n\n/**\n * Export for use in CLI\n */\nexport { createConnectCommand as connectCommand };\n","/**\n * CLI info command - Show system and configuration info\n *\n * Displays information about the current system, network configuration,\n * and loaded config values.\n */\n\nimport { Command } from 'commander';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { createLogger } from '../../utils/logger.js';\nimport { loadConfigSync } from '../../utils/config.js';\nimport type { GlobalOptions } from '../index.js';\n\nconst logger = createLogger('cli:info');\n\n/**\n * Get the config file path that would be loaded\n */\nfunction getConfigFilePath(): string | null {\n // Check project local config first\n const localConfig = path.join(process.cwd(), '.claude-bridge.yml');\n if (fs.existsSync(localConfig)) {\n return localConfig;\n }\n\n // Check home directory\n const homeConfig = path.join(os.homedir(), '.claude-bridge', 'config.yml');\n if (fs.existsSync(homeConfig)) {\n return homeConfig;\n }\n\n return null;\n}\n\n/**\n * Format a value for display (handle undefined, objects, etc.)\n */\nfunction formatValue(value: unknown): string {\n if (value === undefined) {\n return '(not set)';\n }\n if (value === null) {\n return '(null)';\n }\n if (typeof value === 'object') {\n return JSON.stringify(value);\n }\n return String(value);\n}\n\n/**\n * Print a section header\n */\nfunction printSection(title: string): void {\n console.log('');\n console.log(title);\n console.log('-'.repeat(title.length));\n}\n\n/**\n * Print a key-value pair\n */\nfunction printKeyValue(key: string, value: unknown, indent: number = 0): void {\n const prefix = ' '.repeat(indent);\n console.log(`${prefix}${key}: ${formatValue(value)}`);\n}\n\n/**\n * Show system and configuration info\n */\nfunction showInfo(globalOptions: GlobalOptions): void {\n console.log('Claude Code Bridge - System Information');\n console.log('='.repeat(40));\n\n // System Info\n printSection('System');\n printKeyValue('Node Version', process.version);\n printKeyValue('OS', `${os.type()} ${os.release()}`);\n printKeyValue('Platform', process.platform);\n printKeyValue('Arch', os.arch());\n printKeyValue('Home Directory', os.homedir());\n printKeyValue('Working Directory', process.cwd());\n\n // Network\n printSection('Network');\n const interfaces = os.networkInterfaces();\n for (const [name, addrs] of Object.entries(interfaces)) {\n if (addrs) {\n for (const addr of addrs) {\n if (addr.family === 'IPv4' && !addr.internal) {\n printKeyValue(name, addr.address);\n }\n }\n }\n }\n\n // Configuration\n printSection('Configuration');\n const configPath = globalOptions.config || getConfigFilePath();\n printKeyValue('Config File', configPath || '(using defaults)');\n\n const config = loadConfigSync(globalOptions.config);\n\n console.log('');\n console.log(' Current Settings:');\n printKeyValue('Mode', config.mode, 2);\n printKeyValue('Instance Name', config.instanceName, 2);\n\n console.log('');\n console.log(' Listen:');\n printKeyValue('Port', config.listen.port, 2);\n printKeyValue('Host', config.listen.host, 2);\n\n console.log('');\n console.log(' Connect:');\n printKeyValue('URL', config.connect?.url, 2);\n\n console.log('');\n console.log(' Context Sharing:');\n printKeyValue('Auto Sync', config.contextSharing.autoSync, 2);\n printKeyValue('Sync Interval', `${config.contextSharing.syncInterval}ms`, 2);\n printKeyValue('Max Chunk Tokens', config.contextSharing.maxChunkTokens, 2);\n\n if (config.contextSharing.includePatterns.length > 0) {\n console.log(' Include Patterns:');\n for (const pattern of config.contextSharing.includePatterns) {\n console.log(` - ${pattern}`);\n }\n }\n\n if (config.contextSharing.excludePatterns.length > 0) {\n console.log(' Exclude Patterns:');\n for (const pattern of config.contextSharing.excludePatterns) {\n console.log(` - ${pattern}`);\n }\n }\n\n console.log('');\n console.log(' Interaction:');\n printKeyValue('Require Confirmation', config.interaction.requireConfirmation, 2);\n printKeyValue('Notify On Activity', config.interaction.notifyOnActivity, 2);\n printKeyValue('Task Timeout', `${config.interaction.taskTimeout}ms`, 2);\n\n console.log('');\n}\n\n/**\n * Create the info command\n */\nexport function createInfoCommand(): Command {\n const command = new Command('info');\n\n command\n .description('Show system and configuration info')\n .action(() => {\n try {\n // Get global options from parent command\n const globalOptions = command.parent?.opts() as GlobalOptions ?? {};\n showInfo(globalOptions);\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Info command failed');\n console.error(`Error: ${(error as Error).message}`);\n process.exit(1);\n }\n });\n\n return command;\n}\n\n/**\n * Export for use in CLI\n */\nexport { createInfoCommand as infoCommand };\n","/**\n * CLI mcp-server command - Start the MCP server for Claude Code integration\n *\n * Options:\n * --connect, -c Bridge WebSocket URL to connect to (default: ws://localhost:8766)\n * --name MCP server name (default: claude-bridge)\n */\n\nimport { Command } from 'commander';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { spawn } from 'child_process';\nimport { createLogger } from '../../utils/logger.js';\nimport { BridgeMcpServer, type McpServerConfig } from '../../mcp/server.js';\nimport { setupGracefulShutdown, handleUnhandledRejections } from '../utils.js';\nimport type { GlobalOptions } from '../index.js';\n\nconst logger = createLogger('cli:mcp-server');\n\n/**\n * Options for the mcp-server command\n */\nexport interface McpServerCommandOptions {\n connect?: string;\n name?: string;\n}\n\n/**\n * Default bridge daemon port\n */\nconst DEFAULT_DAEMON_PORT = 8766;\n\n/**\n * Get the status file path\n */\nfunction getStatusFilePath(): string {\n const bridgeDir = path.join(os.homedir(), '.claude-bridge');\n return path.join(bridgeDir, 'status.json');\n}\n\n/**\n * Get the PID file path\n */\nfunction getPidFilePath(): string {\n const bridgeDir = path.join(os.homedir(), '.claude-bridge');\n return path.join(bridgeDir, 'bridge.pid');\n}\n\n/**\n * Check if bridge daemon is running\n */\nfunction isDaemonRunning(): { running: boolean; pid?: number; port?: number } {\n const pidFile = getPidFilePath();\n\n if (!fs.existsSync(pidFile)) {\n return { running: false };\n }\n\n try {\n const pid = parseInt(fs.readFileSync(pidFile, 'utf-8').trim(), 10);\n // Check if process is still running\n process.kill(pid, 0); // Signal 0 checks existence without killing\n\n // Try to read port from status file\n const statusFile = getStatusFilePath();\n if (fs.existsSync(statusFile)) {\n const status = JSON.parse(fs.readFileSync(statusFile, 'utf-8'));\n return { running: true, pid, port: status.port };\n }\n\n return { running: true, pid };\n } catch {\n // Process doesn't exist or status file invalid\n return { running: false };\n }\n}\n\n/**\n * Wait for daemon to be ready\n */\nasync function waitForDaemon(port: number, timeoutMs: number): Promise<void> {\n const startTime = Date.now();\n\n while (Date.now() - startTime < timeoutMs) {\n const { running, port: runningPort } = isDaemonRunning();\n if (running && (runningPort === port || runningPort === undefined)) {\n // Give it a moment to be fully ready\n await new Promise(resolve => setTimeout(resolve, 500));\n return;\n }\n await new Promise(resolve => setTimeout(resolve, 200));\n }\n\n throw new Error(`Daemon did not start within ${timeoutMs}ms`);\n}\n\n/**\n * Ensure the .claude-bridge directory exists\n */\nfunction ensureBridgeDir(): void {\n const bridgeDir = path.join(os.homedir(), '.claude-bridge');\n if (!fs.existsSync(bridgeDir)) {\n fs.mkdirSync(bridgeDir, { recursive: true });\n }\n}\n\n/**\n * Start bridge daemon if not running\n */\nasync function ensureDaemonRunning(port: number): Promise<number> {\n const { running, pid, port: runningPort } = isDaemonRunning();\n\n if (running) {\n const effectivePort = runningPort ?? port;\n console.error(`[MCP] Bridge daemon already running (PID: ${pid}, port: ${effectivePort})`);\n return effectivePort;\n }\n\n console.error('[MCP] Starting bridge daemon...');\n ensureBridgeDir();\n\n const logFile = path.join(os.homedir(), '.claude-bridge', 'bridge.log');\n\n // Spawn daemon process\n const out = fs.openSync(logFile, 'a');\n const err = fs.openSync(logFile, 'a');\n\n // Find the CLI entry point\n // When running from npx or installed globally, process.argv[1] is the CLI script\n const cliPath = process.argv[1];\n\n const child = spawn(process.execPath, [cliPath, 'start', '--daemon', '--port', String(port)], {\n detached: true,\n stdio: ['ignore', out, err],\n });\n\n child.unref();\n\n console.error(`[MCP] Daemon starting (PID: ${child.pid})`);\n\n // Wait for daemon to be ready\n try {\n await waitForDaemon(port, 5000);\n console.error(`[MCP] Daemon ready on port ${port}`);\n return port;\n } catch (error) {\n console.error(`[MCP] Warning: Could not verify daemon is ready: ${(error as Error).message}`);\n // Continue anyway, the bridge connection will fail if daemon isn't running\n return port;\n }\n}\n\n/**\n * Start the MCP server\n */\nasync function startMcpServer(\n options: McpServerCommandOptions,\n _globalOptions: GlobalOptions\n): Promise<void> {\n // Parse connection URL\n let bridgeUrl = options.connect ?? `ws://localhost:${DEFAULT_DAEMON_PORT}`;\n\n // If no explicit URL provided, try to auto-start daemon\n if (!options.connect) {\n try {\n const port = await ensureDaemonRunning(DEFAULT_DAEMON_PORT);\n bridgeUrl = `ws://localhost:${port}`;\n } catch (error) {\n console.error(`[MCP] Warning: Could not ensure daemon is running: ${(error as Error).message}`);\n }\n }\n\n // Build MCP server config\n const config: McpServerConfig = {\n bridgeUrl,\n name: options.name ?? 'claude-bridge',\n version: '0.4.0',\n instanceName: `mcp-server-${process.pid}`,\n taskTimeout: 60000,\n };\n\n // Create and start MCP server\n const server = new BridgeMcpServer(config);\n\n // Set up graceful shutdown handling\n setupGracefulShutdown({\n cleanup: async () => {\n console.error('[MCP] Shutting down...');\n await server.stop();\n },\n verbose: false,\n timeout: 5000,\n });\n\n // Handle unhandled promise rejections\n handleUnhandledRejections({\n exit: true,\n logger: (msg, err) => {\n console.error(`[MCP] ${msg}: ${err.message}`);\n logger.error({ error: err.message }, msg);\n },\n });\n\n try {\n await server.start();\n // Server is now running and listening on stdio\n // It will keep running until interrupted\n } catch (error) {\n console.error(`[MCP] Failed to start MCP server: ${(error as Error).message}`);\n process.exit(1);\n }\n}\n\n/**\n * Create the mcp-server command\n */\nexport function createMcpServerCommand(): Command {\n const command = new Command('mcp-server');\n\n command\n .description('Start the MCP server for Claude Code integration')\n .option('-c, --connect <url>', `Bridge WebSocket URL (default: ws://localhost:${DEFAULT_DAEMON_PORT})`)\n .option('--name <name>', 'MCP server name (default: claude-bridge)')\n .action(async (options: McpServerCommandOptions) => {\n // Get global options from parent command\n const globalOptions = command.parent?.opts() as GlobalOptions;\n await startMcpServer(options, globalOptions);\n });\n\n return command;\n}\n\n/**\n * Export the command for use in CLI\n */\nexport { createMcpServerCommand as mcpServerCommand };\n"],"mappings":"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","names":["Command","logger","resolve","Command","fs","path","os","logger","getPidFilePath","removePidFile","resolve","Command","Command","fs","path","os","logger","getPidFilePath","readPidFile","isProcessRunning","Command","Command","logger","Command","Command","fs","path","os","logger","Command","Command","fs","path","os","spawn","logger","getStatusFilePath","getPidFilePath","resolve","ensureBridgeDir","spawn","Command","logger","Command"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@willjackson/claude-code-bridge",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "Bidirectional communication system for Claude Code instances across environments",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",