@willjackson/claude-code-bridge 0.7.0 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -22,10 +22,10 @@ Claude Code Bridge connects your local Claude Code to remote environments via We
22
22
  LOCAL MACHINE REMOTE MACHINE
23
23
  ┌──────────────────────┐ ┌──────────────────────┐
24
24
  │ │ │ │
25
- │ Claude Code │ │ Bridge Client │
26
- │ + │ WebSocket │ --with-handlers │
25
+ │ Claude Code │ ws:// or │ Bridge Client │
26
+ │ + │ wss:// │ --with-handlers │
27
27
  │ Bridge Host ────────────────────► │
28
- │ (port 8766) │ │ Executes commands │
28
+ │ (port 8766) │ (TLS) │ Executes commands │
29
29
  │ │ │ on your files │
30
30
  └──────────────────────┘ └──────────────────────┘
31
31
  ```
@@ -78,6 +78,46 @@ Replace `HOST_IP` with your local machine's IP address.
78
78
 
79
79
  That's it! Claude Code now has access to files on the remote machine.
80
80
 
81
+ ## Secure Connections (TLS + Auth)
82
+
83
+ For production or untrusted networks, enable TLS encryption and authentication.
84
+
85
+ ### Generate Certificates
86
+
87
+ ```bash
88
+ # Self-signed certificate (for testing)
89
+ openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes -subj "/CN=localhost"
90
+ ```
91
+
92
+ ### Start with TLS + Token Auth
93
+
94
+ **Local machine (host):**
95
+
96
+ ```bash
97
+ claude-bridge start --cert cert.pem --key key.pem --auth-token mysecret123
98
+ ```
99
+
100
+ **Remote machine (client):**
101
+
102
+ ```bash
103
+ claude-bridge start --with-handlers --connect wss://HOST_IP:8765 --ca cert.pem --auth-token mysecret123
104
+ ```
105
+
106
+ ### Authentication Options
107
+
108
+ | Option | Description |
109
+ |--------|-------------|
110
+ | `--auth-token <token>` | Require a shared secret token |
111
+ | `--auth-password <pw>` | Require password authentication |
112
+ | `--auth-ip <cidr>` | Allow only specific IPs (e.g., `192.168.0.0/16`) |
113
+ | `--auth-require-all` | Require ALL auth methods to pass (default: any) |
114
+
115
+ Combine methods for defense in depth:
116
+
117
+ ```bash
118
+ claude-bridge start --auth-token secret --auth-ip 10.0.0.0/8 --auth-require-all
119
+ ```
120
+
81
121
  ## What You Can Do
82
122
 
83
123
  Once connected, Claude Code gains these MCP tools:
@@ -112,12 +152,24 @@ claude-bridge start [--port 8765] [--launch-claude] [-- claude-args]
112
152
  # Client mode (remote machine)
113
153
  claude-bridge start --with-handlers --connect ws://HOST:PORT
114
154
 
155
+ # Secure connections
156
+ claude-bridge start --cert cert.pem --key key.pem --auth-token secret
157
+ claude-bridge start --with-handlers --connect wss://HOST:PORT --ca cert.pem --auth-token secret
158
+
115
159
  # Utilities
116
160
  claude-bridge status # Check if bridge is running
117
161
  claude-bridge stop # Stop the bridge daemon
118
162
  claude-bridge info # Show system info
119
163
  ```
120
164
 
165
+ ### TLS Options
166
+
167
+ | Option | Description |
168
+ |--------|-------------|
169
+ | `--cert <path>` | TLS certificate file |
170
+ | `--key <path>` | TLS private key file |
171
+ | `--ca <path>` | CA certificate (for verifying self-signed certs) |
172
+
121
173
  ## Configuration
122
174
 
123
175
  Create `~/.claude-bridge/config.yml` for persistent settings:
@@ -127,10 +179,28 @@ instanceName: my-bridge
127
179
  listen:
128
180
  port: 8765
129
181
  host: 0.0.0.0
182
+ tls:
183
+ cert: /path/to/cert.pem
184
+ key: /path/to/key.pem
185
+ auth:
186
+ type: token # none, token, password, ip, or combined
187
+ token: ${BRIDGE_AUTH_TOKEN} # use environment variable
130
188
  interaction:
131
189
  taskTimeout: 300000
132
190
  ```
133
191
 
192
+ For client connections:
193
+
194
+ ```yaml
195
+ connect:
196
+ url: wss://remote-host:8765
197
+ tls:
198
+ ca: /path/to/ca.pem
199
+ auth:
200
+ type: token
201
+ token: ${BRIDGE_AUTH_TOKEN}
202
+ ```
203
+
134
204
  ## Troubleshooting
135
205
 
136
206
  **Can't connect?**
@@ -138,6 +208,16 @@ interaction:
138
208
  - Check firewall allows port 8765
139
209
  - Confirm IP is reachable: `ping HOST_IP`
140
210
 
211
+ **TLS connection failing?**
212
+ - Ensure client uses `wss://` (not `ws://`) when connecting to TLS host
213
+ - For self-signed certs, client must use `--ca cert.pem`
214
+ - Check certificate hasn't expired
215
+
216
+ **Authentication failing?**
217
+ - Verify tokens match exactly on both sides
218
+ - For IP auth, ensure client IP is in allowed CIDR range
219
+ - Check with `-v` flag for detailed auth error messages
220
+
141
221
  **Commands not executing?**
142
222
  - Ensure client uses `--with-handlers`
143
223
  - Check client console for errors
@@ -1771,16 +1771,22 @@ var Bridge = class {
1771
1771
  if (!this.taskReceivedHandler) {
1772
1772
  const otherPeers = Array.from(this.peers.keys()).filter((id) => id !== peerId);
1773
1773
  if (otherPeers.length > 0) {
1774
- const targetPeerId = otherPeers[0];
1775
- logger4.info({ taskId: task.id, targetPeerId }, "Forwarding task to another peer");
1776
- try {
1777
- await this.sendToPeer(targetPeerId, message);
1778
- const forwardKey = `forward:${task.id}`;
1779
- this[forwardKey] = peerId;
1774
+ const forwardKey = `forward:${task.id}`;
1775
+ this[forwardKey] = peerId;
1776
+ let forwarded = false;
1777
+ for (const targetPeerId of otherPeers) {
1778
+ try {
1779
+ await this.sendToPeer(targetPeerId, message);
1780
+ logger4.info({ taskId: task.id, targetPeerId, totalTargets: otherPeers.length }, "Forwarding task to peer");
1781
+ forwarded = true;
1782
+ } catch (err) {
1783
+ logger4.error({ error: err.message, taskId: task.id, targetPeerId }, "Failed to forward task to peer");
1784
+ }
1785
+ }
1786
+ if (forwarded) {
1780
1787
  return;
1781
- } catch (err) {
1782
- logger4.error({ error: err.message, taskId: task.id }, "Failed to forward task");
1783
1788
  }
1789
+ delete this[forwardKey];
1784
1790
  }
1785
1791
  logger4.warn({ taskId: task.id }, "No task handler registered and no peers to forward to");
1786
1792
  const response = createTaskResponseMessage(
@@ -1830,6 +1836,10 @@ var Bridge = class {
1830
1836
  const forwardKey = `forward:${taskId}`;
1831
1837
  const originalSender = this[forwardKey];
1832
1838
  if (originalSender) {
1839
+ if (!message.result.success && message.result.error === "No task handler registered on peer") {
1840
+ logger4.debug({ taskId }, "Ignoring no-handler response from peer, waiting for handler peer");
1841
+ return;
1842
+ }
1833
1843
  delete this[forwardKey];
1834
1844
  logger4.info({ taskId, originalSender }, "Forwarding task response to original sender");
1835
1845
  await this.sendToPeer(originalSender, message).catch((err) => {
@@ -1872,16 +1882,22 @@ var Bridge = class {
1872
1882
  if (!this.contextRequestedHandler) {
1873
1883
  const otherPeers = Array.from(this.peers.keys()).filter((id) => id !== peerId);
1874
1884
  if (otherPeers.length > 0) {
1875
- const targetPeerId = otherPeers[0];
1876
- logger4.info({ messageId: message.id, targetPeerId }, "Forwarding context request to another peer");
1877
- try {
1878
- await this.sendToPeer(targetPeerId, message);
1879
- const forwardKey = `ctxfwd:${message.id}`;
1880
- this[forwardKey] = peerId;
1885
+ const forwardKey = `ctxfwd:${message.id}`;
1886
+ this[forwardKey] = peerId;
1887
+ let forwarded = false;
1888
+ for (const targetPeerId of otherPeers) {
1889
+ try {
1890
+ await this.sendToPeer(targetPeerId, message);
1891
+ logger4.info({ messageId: message.id, targetPeerId, totalTargets: otherPeers.length }, "Forwarding context request to peer");
1892
+ forwarded = true;
1893
+ } catch (err) {
1894
+ logger4.error({ error: err.message, messageId: message.id, targetPeerId }, "Failed to forward context request to peer");
1895
+ }
1896
+ }
1897
+ if (forwarded) {
1881
1898
  return;
1882
- } catch (err) {
1883
- logger4.error({ error: err.message, messageId: message.id }, "Failed to forward context request");
1884
1899
  }
1900
+ delete this[forwardKey];
1885
1901
  }
1886
1902
  logger4.warn({ messageId: message.id }, "No context request handler registered and no peers to forward to");
1887
1903
  const response = createContextSyncMessage(this.config.instanceName, { files: [] });
@@ -1942,6 +1958,12 @@ var Bridge = class {
1942
1958
  const forwardKey = `ctxfwd:${requestId}`;
1943
1959
  const originalSender = this[forwardKey];
1944
1960
  if (originalSender) {
1961
+ const files2 = message.context?.files ?? [];
1962
+ const hasError = !!message.context?.variables?.error;
1963
+ if (files2.length === 0 && !hasError) {
1964
+ logger4.debug({ requestId }, "Ignoring empty context response from non-handler peer, waiting for handler peer");
1965
+ return;
1966
+ }
1945
1967
  delete this[forwardKey];
1946
1968
  logger4.info({ requestId, originalSender }, "Forwarding context response to original sender");
1947
1969
  await this.sendToPeer(originalSender, message).catch((err) => {
@@ -2738,4 +2760,4 @@ export {
2738
2760
  BridgeMcpServer,
2739
2761
  startMcpServer
2740
2762
  };
2741
- //# sourceMappingURL=chunk-2O352EPO.js.map
2763
+ //# sourceMappingURL=chunk-OEEJEXXK.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/logger.ts","../src/bridge/protocol.ts","../src/transport/interface.ts","../src/utils/tls.ts","../src/transport/websocket.ts","../src/utils/auth.ts","../src/bridge/messages.ts","../src/bridge/core.ts","../src/utils/config.ts","../src/mcp/tools.ts","../src/mcp/server.ts"],"sourcesContent":["import pino from 'pino';\n\n/**\n * Log levels supported by the logger\n */\nexport type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';\n\n/**\n * Logger interface (subset of pino.Logger for public API)\n */\nexport type Logger = pino.Logger;\n\n/**\n * Determines if pretty printing should be used.\n * Only enabled when NODE_ENV is explicitly set to 'development'\n * to avoid errors when pino-pretty (a dev dependency) isn't installed.\n */\nfunction usePrettyPrint(): boolean {\n return process.env.NODE_ENV === 'development';\n}\n\n/**\n * Gets the default log level from environment or falls back to 'info'\n */\nfunction getDefaultLevel(): LogLevel {\n const envLevel = process.env.LOG_LEVEL?.toLowerCase() as LogLevel | undefined;\n const validLevels: LogLevel[] = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'];\n if (envLevel && validLevels.includes(envLevel)) {\n return envLevel;\n }\n return 'info';\n}\n\n/**\n * Creates a logger instance with the given component name\n *\n * @param name - Component name to include in log output\n * @param level - Optional log level override (defaults to LOG_LEVEL env var or 'info')\n * @returns A pino logger instance configured for the component\n *\n * @example\n * ```typescript\n * const logger = createLogger('bridge');\n * logger.info('Bridge started');\n * logger.error({ err }, 'Connection failed');\n * ```\n */\nexport function createLogger(name: string, level?: LogLevel): Logger {\n const logLevel = level ?? getDefaultLevel();\n\n const options: pino.LoggerOptions = {\n name,\n level: logLevel,\n };\n\n // Use pretty printing only when explicitly in development mode\n if (usePrettyPrint()) {\n options.transport = {\n target: 'pino-pretty',\n options: {\n colorize: true,\n translateTime: 'SYS:standard',\n ignore: 'pid,hostname',\n },\n };\n }\n\n return pino(options);\n}\n\n/**\n * Creates a child logger from an existing logger with additional context\n *\n * @param parent - Parent logger instance\n * @param bindings - Additional context to include in all log messages\n * @returns A child logger instance\n */\nexport function createChildLogger(parent: Logger, bindings: Record<string, unknown>): Logger {\n return parent.child(bindings);\n}\n","/**\n * Protocol definitions for Claude Code Bridge\n * Defines message types, schemas, and serialization utilities\n */\n\nimport { z } from 'zod';\nimport { v4 as uuidv4 } from 'uuid';\n\n// ============================================================================\n// Message Type Enum\n// ============================================================================\n\nexport const MessageType = z.enum([\n 'request',\n 'response',\n 'context_sync',\n 'task_delegate',\n 'notification',\n]);\n\nexport type MessageType = z.infer<typeof MessageType>;\n\n// ============================================================================\n// File and Directory Schemas\n// ============================================================================\n\nexport const FileChunkSchema = z.object({\n path: z.string(),\n content: z.string(),\n startLine: z.number().optional(),\n endLine: z.number().optional(),\n language: z.string().optional(),\n});\n\nexport type FileChunk = z.infer<typeof FileChunkSchema>;\n\nexport const DirectoryTreeSchema: z.ZodType<DirectoryTree> = z.lazy(() =>\n z.object({\n name: z.string(),\n type: z.enum(['file', 'directory']),\n children: z.array(DirectoryTreeSchema).optional(),\n })\n);\n\nexport interface DirectoryTree {\n name: string;\n type: 'file' | 'directory';\n children?: DirectoryTree[];\n}\n\n// ============================================================================\n// Artifact Schema\n// ============================================================================\n\nexport const ArtifactSchema = z.object({\n path: z.string(),\n action: z.enum(['created', 'modified', 'deleted']),\n diff: z.string().optional(),\n});\n\nexport type Artifact = z.infer<typeof ArtifactSchema>;\n\n// ============================================================================\n// Context Schema\n// ============================================================================\n\nexport const ContextSchema = z.object({\n files: z.array(FileChunkSchema).optional(),\n tree: DirectoryTreeSchema.optional(),\n summary: z.string().optional(),\n variables: z.record(z.any()).optional(),\n});\n\nexport type Context = z.infer<typeof ContextSchema>;\n\n// ============================================================================\n// Task Request Schema\n// ============================================================================\n\nexport const TaskRequestSchema = z.object({\n id: z.string(),\n description: z.string(),\n scope: z.enum(['execute', 'analyze', 'suggest']),\n constraints: z.array(z.string()).optional(),\n returnFormat: z.enum(['full', 'summary', 'diff']).optional(),\n timeout: z.number().optional(),\n data: z.record(z.unknown()).optional(),\n});\n\nexport type TaskRequest = z.infer<typeof TaskRequestSchema>;\n\n// ============================================================================\n// Task Result Schema\n// ============================================================================\n\nexport const TaskResultSchema = z.object({\n taskId: z.string().optional(),\n success: z.boolean(),\n data: z.any(),\n artifacts: z.array(ArtifactSchema).optional(),\n followUp: z.string().optional(),\n error: z.string().optional(),\n});\n\nexport type TaskResult = z.infer<typeof TaskResultSchema>;\n\n// ============================================================================\n// Bridge Message Schema\n// ============================================================================\n\nexport const BridgeMessageSchema = z.object({\n id: z.string().uuid(),\n type: MessageType,\n source: z.string(),\n timestamp: z.number(),\n context: ContextSchema.optional(),\n task: TaskRequestSchema.optional(),\n result: TaskResultSchema.optional(),\n});\n\nexport type BridgeMessage = z.infer<typeof BridgeMessageSchema>;\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Creates a base message with auto-generated UUID and timestamp\n * @param type The message type\n * @param source The source instance identifier\n * @returns A partial BridgeMessage with id, type, source, and timestamp\n */\nexport function createMessage(\n type: MessageType,\n source: string\n): BridgeMessage {\n return {\n id: uuidv4(),\n type,\n source,\n timestamp: Date.now(),\n };\n}\n\n/**\n * Validates a message against the BridgeMessage schema\n * @param data The data to validate\n * @returns The validated BridgeMessage or throws if invalid\n */\nexport function validateMessage(data: unknown): BridgeMessage {\n return BridgeMessageSchema.parse(data);\n}\n\n/**\n * Safe validation that returns a result object instead of throwing\n * @param data The data to validate\n * @returns A Zod SafeParseReturnType with success/error information\n */\nexport function safeValidateMessage(data: unknown) {\n return BridgeMessageSchema.safeParse(data);\n}\n\n/**\n * Serializes a BridgeMessage to JSON string\n * @param message The message to serialize\n * @returns JSON string representation\n */\nexport function serializeMessage(message: BridgeMessage): string {\n return JSON.stringify(message);\n}\n\n/**\n * Deserializes a JSON string to a validated BridgeMessage\n * @param json The JSON string to deserialize\n * @returns The validated BridgeMessage\n * @throws Error if JSON is invalid or message doesn't match schema\n */\nexport function deserializeMessage(json: string): BridgeMessage {\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch {\n throw new Error('Invalid JSON');\n }\n return validateMessage(parsed);\n}\n\n/**\n * Safe deserialization that returns a result object instead of throwing\n * @param json The JSON string to deserialize\n * @returns A Zod SafeParseReturnType with success/error information\n */\nexport function safeDeserializeMessage(json: string) {\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch {\n return {\n success: false as const,\n error: new z.ZodError([\n {\n code: 'custom',\n message: 'Invalid JSON',\n path: [],\n },\n ]),\n };\n }\n return BridgeMessageSchema.safeParse(parsed);\n}\n","/**\n * Transport layer interface and types for Claude Code Bridge\n * Defines the abstract transport interface for communication between bridge instances\n */\n\nimport type { BridgeMessage } from '../bridge/protocol.js';\n\n// ============================================================================\n// Connection State Enum\n// ============================================================================\n\n/**\n * Represents the current state of a transport connection\n */\nexport enum ConnectionState {\n /** Not connected to any peer */\n DISCONNECTED = 'DISCONNECTED',\n /** Currently attempting to establish connection */\n CONNECTING = 'CONNECTING',\n /** Successfully connected and ready for communication */\n CONNECTED = 'CONNECTED',\n /** Connection lost, attempting to reconnect */\n RECONNECTING = 'RECONNECTING',\n}\n\n// ============================================================================\n// TLS Configuration\n// ============================================================================\n\n/**\n * TLS configuration for secure connections\n */\nexport interface TLSConfig {\n /** Path to certificate PEM file (for server) */\n cert?: string;\n /** Path to private key PEM file (for server) */\n key?: string;\n /** Path to CA certificate PEM file (for client to verify server, or server to verify client) */\n ca?: string;\n /** Whether to reject unauthorized certificates (default: true) */\n rejectUnauthorized?: boolean;\n /** Passphrase for encrypted private key */\n passphrase?: string;\n}\n\n// ============================================================================\n// Connection Configuration\n// ============================================================================\n\n/**\n * Authentication type\n */\nexport type AuthType = 'none' | 'token' | 'password' | 'ip' | 'combined';\n\n/**\n * Authentication configuration for transport connections\n */\nexport interface AuthConfig {\n /** Authentication type */\n type: AuthType;\n /** Authentication token (for type: 'token' or 'combined') */\n token?: string;\n /** Authentication password (for type: 'password' or 'combined') */\n password?: string;\n /** Allowed IP addresses/ranges in CIDR notation (for type: 'ip' or 'combined') */\n allowedIps?: string[];\n /** If true, ALL configured methods must pass; if false, ANY passing method is sufficient */\n requireAll?: boolean;\n}\n\n/**\n * Configuration for establishing a transport connection\n */\nexport interface ConnectionConfig {\n /** Full WebSocket URL (e.g., ws://localhost:8765 or wss://localhost:8765) */\n url?: string;\n /** Host to connect to (used if url is not provided) */\n host?: string;\n /** Port to connect to (used if url is not provided) */\n port?: number;\n /** Enable automatic reconnection on disconnect */\n reconnect?: boolean;\n /** Interval between reconnection attempts in milliseconds */\n reconnectInterval?: number;\n /** Maximum number of reconnection attempts before giving up */\n maxReconnectAttempts?: number;\n /** Authentication configuration */\n auth?: AuthConfig;\n /** TLS configuration for secure connections */\n tls?: TLSConfig;\n}\n\n// ============================================================================\n// Event Handler Types\n// ============================================================================\n\n/**\n * Handler for incoming messages\n */\nexport type MessageHandler = (message: BridgeMessage) => void;\n\n/**\n * Handler for disconnect events\n */\nexport type DisconnectHandler = () => void;\n\n/**\n * Handler for error events\n */\nexport type ErrorHandler = (error: Error) => void;\n\n// ============================================================================\n// Transport Interface\n// ============================================================================\n\n/**\n * Abstract transport interface for bridge communication\n * Implementations handle the actual network protocol (WebSocket, TCP, etc.)\n */\nexport interface Transport {\n /**\n * Establish connection to a remote peer\n * @param config Connection configuration\n * @returns Promise that resolves when connection is established\n * @throws Error if connection fails\n */\n connect(config: ConnectionConfig): Promise<void>;\n\n /**\n * Cleanly close the current connection\n * @returns Promise that resolves when disconnection is complete\n */\n disconnect(): Promise<void>;\n\n /**\n * Send a message to the connected peer\n * @param message The message to send\n * @returns Promise that resolves when message is sent\n * @throws Error if not connected and message cannot be queued\n */\n send(message: BridgeMessage): Promise<void>;\n\n /**\n * Register a handler for incoming messages\n * @param handler Function to call when a message is received\n */\n onMessage(handler: MessageHandler): void;\n\n /**\n * Register a handler for disconnect events\n * @param handler Function to call when connection is lost\n */\n onDisconnect(handler: DisconnectHandler): void;\n\n /**\n * Register a handler for error events\n * @param handler Function to call when an error occurs\n */\n onError(handler: ErrorHandler): void;\n\n /**\n * Check if the transport is currently connected\n * @returns true if connected, false otherwise\n */\n isConnected(): boolean;\n\n /**\n * Get the current connection state\n * @returns The current ConnectionState\n */\n getState(): ConnectionState;\n}\n\n// ============================================================================\n// Transport Events (for EventEmitter pattern)\n// ============================================================================\n\n/**\n * Transport event types for EventEmitter-based implementations\n */\nexport interface TransportEvents {\n /** Emitted when a message is received */\n message: BridgeMessage;\n /** Emitted when connection is established */\n connect: void;\n /** Emitted when connection is closed */\n disconnect: void;\n /** Emitted when an error occurs */\n error: Error;\n /** Emitted when reconnection is attempted */\n reconnecting: { attempt: number; maxAttempts: number };\n}\n","/**\n * TLS utilities for Claude Code Bridge\n * Handles loading and validating TLS certificates for secure WebSocket connections\n */\n\nimport * as fs from 'fs';\nimport * as tls from 'tls';\nimport { createLogger } from './logger.js';\n\nconst logger = createLogger('tls');\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\n/**\n * TLS configuration for secure connections\n */\nexport interface TLSConfig {\n /** Path to certificate PEM file */\n cert?: string;\n /** Path to private key PEM file */\n key?: string;\n /** Path to CA certificate PEM file (for verifying client certs or self-signed server certs) */\n ca?: string;\n /** Whether to reject unauthorized certificates (default: true) */\n rejectUnauthorized?: boolean;\n /** Passphrase for encrypted private key */\n passphrase?: string;\n}\n\n/**\n * Result of TLS configuration validation\n */\nexport interface TLSValidationResult {\n /** Whether the configuration is valid */\n valid: boolean;\n /** List of validation errors */\n errors: string[];\n /** List of validation warnings */\n warnings: string[];\n}\n\n/**\n * Loaded TLS options ready for use with https/tls modules\n */\nexport interface LoadedTLSOptions {\n /** Certificate content */\n cert?: string | Buffer;\n /** Private key content */\n key?: string | Buffer;\n /** CA certificate content */\n ca?: string | Buffer;\n /** Whether to reject unauthorized certificates */\n rejectUnauthorized?: boolean;\n /** Passphrase for encrypted private key */\n passphrase?: string;\n}\n\n// ============================================================================\n// Certificate Loading\n// ============================================================================\n\n/**\n * Read a certificate or key file\n * @param filePath - Path to the file\n * @returns File contents as string\n * @throws Error if file cannot be read\n */\nfunction readCertFile(filePath: string): string {\n try {\n return fs.readFileSync(filePath, 'utf-8');\n } catch (error) {\n const err = error as NodeJS.ErrnoException;\n if (err.code === 'ENOENT') {\n throw new Error(`Certificate file not found: ${filePath}`);\n }\n if (err.code === 'EACCES') {\n throw new Error(`Permission denied reading certificate file: ${filePath}`);\n }\n throw new Error(`Failed to read certificate file ${filePath}: ${err.message}`);\n }\n}\n\n/**\n * Load TLS certificates from file paths\n * @param config - TLS configuration with file paths\n * @returns TLS options ready for use with https/tls modules\n * @throws Error if required certificates cannot be loaded\n */\nexport async function loadCertificates(config: TLSConfig): Promise<LoadedTLSOptions> {\n const options: LoadedTLSOptions = {};\n\n // Load certificate\n if (config.cert) {\n logger.debug({ path: config.cert }, 'Loading certificate');\n options.cert = readCertFile(config.cert);\n }\n\n // Load private key\n if (config.key) {\n logger.debug({ path: config.key }, 'Loading private key');\n options.key = readCertFile(config.key);\n }\n\n // Load CA certificate\n if (config.ca) {\n logger.debug({ path: config.ca }, 'Loading CA certificate');\n options.ca = readCertFile(config.ca);\n }\n\n // Set reject unauthorized (default: true)\n options.rejectUnauthorized = config.rejectUnauthorized ?? true;\n\n // Set passphrase if provided\n if (config.passphrase) {\n options.passphrase = config.passphrase;\n }\n\n logger.info(\n {\n hasCert: !!options.cert,\n hasKey: !!options.key,\n hasCa: !!options.ca,\n rejectUnauthorized: options.rejectUnauthorized,\n },\n 'TLS certificates loaded'\n );\n\n return options;\n}\n\n/**\n * Synchronous version of loadCertificates\n * @param config - TLS configuration with file paths\n * @returns TLS options ready for use with https/tls modules\n * @throws Error if required certificates cannot be loaded\n */\nexport function loadCertificatesSync(config: TLSConfig): LoadedTLSOptions {\n const options: LoadedTLSOptions = {};\n\n // Load certificate\n if (config.cert) {\n options.cert = readCertFile(config.cert);\n }\n\n // Load private key\n if (config.key) {\n options.key = readCertFile(config.key);\n }\n\n // Load CA certificate\n if (config.ca) {\n options.ca = readCertFile(config.ca);\n }\n\n // Set reject unauthorized (default: true)\n options.rejectUnauthorized = config.rejectUnauthorized ?? true;\n\n // Set passphrase if provided\n if (config.passphrase) {\n options.passphrase = config.passphrase;\n }\n\n return options;\n}\n\n// ============================================================================\n// Validation\n// ============================================================================\n\n/**\n * Check if a file exists and is readable\n * @param filePath - Path to check\n * @returns true if file exists and is readable\n */\nfunction isFileReadable(filePath: string): boolean {\n try {\n fs.accessSync(filePath, fs.constants.R_OK);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Validate TLS configuration\n * @param config - TLS configuration to validate\n * @returns Validation result with errors and warnings\n */\nexport function validateTLSConfig(config: TLSConfig): TLSValidationResult {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n // Check for server configuration (cert + key required together)\n if (config.cert && !config.key) {\n errors.push('Certificate provided without private key');\n }\n if (config.key && !config.cert) {\n errors.push('Private key provided without certificate');\n }\n\n // Validate file paths exist and are readable\n if (config.cert) {\n if (!isFileReadable(config.cert)) {\n errors.push(`Certificate file not readable: ${config.cert}`);\n }\n }\n\n if (config.key) {\n if (!isFileReadable(config.key)) {\n errors.push(`Private key file not readable: ${config.key}`);\n }\n }\n\n if (config.ca) {\n if (!isFileReadable(config.ca)) {\n errors.push(`CA certificate file not readable: ${config.ca}`);\n }\n }\n\n // Warn about disabled certificate verification\n if (config.rejectUnauthorized === false) {\n warnings.push('TLS certificate verification is disabled - this is insecure for production use');\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\n/**\n * Check if TLS is enabled in the configuration\n * @param config - TLS configuration to check\n * @returns true if TLS should be enabled (cert and key both provided)\n */\nexport function isTLSEnabled(config?: TLSConfig): boolean {\n if (!config) {\n return false;\n }\n return !!(config.cert && config.key);\n}\n\n/**\n * Create TLS secure context options for Node.js tls module\n * @param loaded - Loaded TLS options\n * @returns Options for tls.createSecureContext\n */\nexport function createSecureContextOptions(loaded: LoadedTLSOptions): tls.SecureContextOptions {\n const options: tls.SecureContextOptions = {};\n\n if (loaded.cert) {\n options.cert = loaded.cert;\n }\n if (loaded.key) {\n options.key = loaded.key;\n }\n if (loaded.ca) {\n options.ca = loaded.ca;\n }\n if (loaded.passphrase) {\n options.passphrase = loaded.passphrase;\n }\n\n return options;\n}\n","/**\n * WebSocket Transport implementation for Claude Code Bridge\n * Provides WebSocket-based communication between bridge instances\n */\n\nimport WebSocket from 'ws';\nimport * as https from 'https';\nimport type { BridgeMessage } from '../bridge/protocol.js';\nimport { serializeMessage, safeDeserializeMessage } from '../bridge/protocol.js';\nimport {\n ConnectionState,\n type ConnectionConfig,\n type Transport,\n type MessageHandler,\n type DisconnectHandler,\n type ErrorHandler,\n} from './interface.js';\nimport { createLogger } from '../utils/logger.js';\nimport { loadCertificatesSync, type LoadedTLSOptions } from '../utils/tls.js';\n\nconst logger = createLogger('websocket-transport');\n\n/** Default reconnection interval in milliseconds */\nconst DEFAULT_RECONNECT_INTERVAL = 1000;\n\n/** Default maximum reconnection attempts */\nconst DEFAULT_MAX_RECONNECT_ATTEMPTS = 10;\n\n/** Default heartbeat interval in milliseconds */\nconst DEFAULT_HEARTBEAT_INTERVAL = 30000;\n\n/** Heartbeat timeout - how long to wait for pong response */\nconst HEARTBEAT_TIMEOUT = 10000;\n\n/**\n * WebSocket-based transport implementation\n * Handles connection lifecycle, message sending/receiving, and event handling\n * Supports auto-reconnection, message queuing, and heartbeat monitoring\n */\nexport class WebSocketTransport implements Transport {\n private ws: WebSocket | null = null;\n private state: ConnectionState = ConnectionState.DISCONNECTED;\n private config: ConnectionConfig | null = null;\n\n // Reconnection state\n private reconnectAttempts: number = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private intentionalDisconnect: boolean = false;\n\n // Message queue for offline messages\n private messageQueue: BridgeMessage[] = [];\n\n // Heartbeat state\n private heartbeatInterval: ReturnType<typeof setInterval> | null = null;\n private heartbeatTimeout: ReturnType<typeof setTimeout> | null = null;\n private awaitingPong: boolean = false;\n\n // Event handlers\n private messageHandlers: MessageHandler[] = [];\n private disconnectHandlers: DisconnectHandler[] = [];\n private errorHandlers: ErrorHandler[] = [];\n private reconnectingHandlers: Array<(attempt: number, maxAttempts: number) => void> = [];\n\n /**\n * Build the WebSocket URL from the connection configuration\n * Uses wss:// if TLS is configured, ws:// otherwise\n */\n private buildUrl(config: ConnectionConfig): string {\n if (config.url) {\n // If URL provided, use it directly (may already be wss://)\n return config.url;\n }\n\n const host = config.host ?? 'localhost';\n const port = config.port ?? 8765;\n\n // Use wss:// if TLS config has CA cert (client wants to verify server)\n // or if rejectUnauthorized is explicitly set\n const useTls = config.tls?.ca || config.tls?.rejectUnauthorized !== undefined;\n const protocol = useTls ? 'wss' : 'ws';\n\n return `${protocol}://${host}:${port}`;\n }\n\n /**\n * Build WebSocket options including TLS and auth configuration\n */\n private buildWsOptions(config: ConnectionConfig): WebSocket.ClientOptions {\n const options: WebSocket.ClientOptions = {};\n\n // Add TLS options if configured\n if (config.tls) {\n try {\n const tlsOptions = loadCertificatesSync(config.tls);\n\n // Create HTTPS agent with TLS options\n const agentOptions: https.AgentOptions = {\n rejectUnauthorized: tlsOptions.rejectUnauthorized ?? true,\n };\n\n if (tlsOptions.ca) {\n agentOptions.ca = tlsOptions.ca;\n }\n if (tlsOptions.cert) {\n agentOptions.cert = tlsOptions.cert;\n }\n if (tlsOptions.key) {\n agentOptions.key = tlsOptions.key;\n }\n if (tlsOptions.passphrase) {\n agentOptions.passphrase = tlsOptions.passphrase;\n }\n\n options.agent = new https.Agent(agentOptions);\n\n // Also set these directly for older ws versions\n if (tlsOptions.rejectUnauthorized !== undefined) {\n options.rejectUnauthorized = tlsOptions.rejectUnauthorized;\n }\n if (tlsOptions.ca) {\n options.ca = tlsOptions.ca;\n }\n\n logger.debug(\n { hasCa: !!tlsOptions.ca, rejectUnauthorized: tlsOptions.rejectUnauthorized },\n 'TLS options configured for client'\n );\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Failed to load TLS certificates');\n throw error;\n }\n }\n\n // Add auth headers if configured\n if (config.auth && config.auth.type !== 'none') {\n options.headers = options.headers || {};\n\n if (config.auth.token) {\n options.headers['Authorization'] = `Bearer ${config.auth.token}`;\n }\n if (config.auth.password) {\n options.headers['X-Auth-Password'] = config.auth.password;\n }\n\n logger.debug(\n { hasToken: !!config.auth.token, hasPassword: !!config.auth.password },\n 'Auth headers configured'\n );\n }\n\n return options;\n }\n\n /**\n * Build URL with auth query parameters (fallback for servers that don't support headers)\n */\n private buildUrlWithAuth(baseUrl: string, config: ConnectionConfig): string {\n if (!config.auth || config.auth.type === 'none') {\n return baseUrl;\n }\n\n const url = new URL(baseUrl);\n\n if (config.auth.token) {\n url.searchParams.set('token', config.auth.token);\n }\n if (config.auth.password) {\n url.searchParams.set('password', config.auth.password);\n }\n\n return url.toString();\n }\n\n /**\n * Establish connection to a remote peer\n */\n async connect(config: ConnectionConfig): Promise<void> {\n if (this.state === ConnectionState.CONNECTED) {\n throw new Error('Already connected');\n }\n\n this.config = config;\n this.intentionalDisconnect = false;\n this.reconnectAttempts = 0;\n\n return this.establishConnection();\n }\n\n /**\n * Internal method to establish WebSocket connection\n * Used for both initial connection and reconnection attempts\n */\n private async establishConnection(): Promise<void> {\n if (!this.config) {\n throw new Error('No configuration set');\n }\n\n this.state = ConnectionState.CONNECTING;\n\n const baseUrl = this.buildUrl(this.config);\n const wsOptions = this.buildWsOptions(this.config);\n\n // Add auth to URL as query params (in addition to headers for compatibility)\n const url = this.buildUrlWithAuth(baseUrl, this.config);\n\n logger.debug(\n { url: baseUrl, attempt: this.reconnectAttempts, hasOptions: Object.keys(wsOptions).length > 0 },\n 'Connecting to WebSocket server'\n );\n\n return new Promise<void>((resolve, reject) => {\n try {\n // Create WebSocket with options if we have any, otherwise without\n this.ws = Object.keys(wsOptions).length > 0\n ? new WebSocket(url, wsOptions)\n : new WebSocket(url);\n\n // Handle connection open\n this.ws.on('open', () => {\n this.state = ConnectionState.CONNECTED;\n this.reconnectAttempts = 0;\n logger.info({ url }, 'WebSocket connection established');\n\n // Start heartbeat monitoring\n this.startHeartbeat();\n\n // Flush queued messages\n this.flushMessageQueue();\n\n resolve();\n });\n\n // Handle incoming messages\n this.ws.on('message', (data: WebSocket.RawData) => {\n this.handleIncomingMessage(data);\n });\n\n // Handle pong responses for heartbeat\n this.ws.on('pong', () => {\n this.handlePong();\n });\n\n // Handle connection close\n this.ws.on('close', (code, reason) => {\n const wasConnected = this.state === ConnectionState.CONNECTED;\n const wasReconnecting = this.state === ConnectionState.RECONNECTING;\n\n // Stop heartbeat\n this.stopHeartbeat();\n\n logger.info({ code, reason: reason.toString() }, 'WebSocket connection closed');\n\n // Notify disconnect handlers only if we were previously connected\n if (wasConnected) {\n this.notifyDisconnect();\n }\n\n // Attempt reconnection if enabled and not intentional disconnect\n if (!this.intentionalDisconnect && this.shouldReconnect()) {\n this.scheduleReconnect();\n } else if (!wasReconnecting) {\n this.state = ConnectionState.DISCONNECTED;\n }\n });\n\n // Handle errors\n this.ws.on('error', (error: Error) => {\n logger.error({ error: error.message }, 'WebSocket error');\n\n // If we're still connecting (initial connection), reject the promise\n if (this.state === ConnectionState.CONNECTING && this.reconnectAttempts === 0) {\n this.state = ConnectionState.DISCONNECTED;\n reject(error);\n return;\n }\n\n // Notify error handlers\n this.notifyError(error);\n });\n } catch (error) {\n this.state = ConnectionState.DISCONNECTED;\n reject(error);\n }\n });\n }\n\n /**\n * Cleanly close the current connection\n */\n async disconnect(): Promise<void> {\n // Mark as intentional to prevent reconnection\n this.intentionalDisconnect = true;\n\n // Clear any pending reconnection timer\n this.clearReconnectTimer();\n\n // Stop heartbeat\n this.stopHeartbeat();\n\n // Clear message queue on intentional disconnect\n this.messageQueue = [];\n\n if (!this.ws || this.state === ConnectionState.DISCONNECTED) {\n this.state = ConnectionState.DISCONNECTED;\n return;\n }\n\n logger.debug('Disconnecting WebSocket');\n\n return new Promise<void>((resolve) => {\n if (!this.ws) {\n this.state = ConnectionState.DISCONNECTED;\n resolve();\n return;\n }\n\n // Set up close handler before closing\n const onClose = () => {\n this.state = ConnectionState.DISCONNECTED;\n this.ws = null;\n resolve();\n };\n\n // If already closed, resolve immediately\n if (this.ws.readyState === WebSocket.CLOSED) {\n onClose();\n return;\n }\n\n // Set up timeout in case close doesn't happen\n const timeout = setTimeout(() => {\n this.state = ConnectionState.DISCONNECTED;\n this.ws = null;\n resolve();\n }, 5000);\n\n this.ws.once('close', () => {\n clearTimeout(timeout);\n onClose();\n });\n\n // Initiate close\n this.ws.close(1000, 'Disconnect requested');\n });\n }\n\n /**\n * Send a message to the connected peer\n * If disconnected and reconnection is enabled, queues the message for later delivery\n */\n async send(message: BridgeMessage): Promise<void> {\n // If connected, send immediately\n if (this.ws && this.state === ConnectionState.CONNECTED) {\n return this.sendImmediate(message);\n }\n\n // If reconnecting and reconnection is enabled, queue the message\n if (this.shouldReconnect() && (this.state === ConnectionState.RECONNECTING || this.state === ConnectionState.DISCONNECTED)) {\n this.queueMessage(message);\n return;\n }\n\n throw new Error('Not connected');\n }\n\n /**\n * Immediately send a message over the WebSocket\n */\n private async sendImmediate(message: BridgeMessage): Promise<void> {\n if (!this.ws || this.state !== ConnectionState.CONNECTED) {\n throw new Error('Not connected');\n }\n\n const serialized = serializeMessage(message);\n logger.debug({ messageId: message.id, type: message.type }, 'Sending message');\n\n return new Promise<void>((resolve, reject) => {\n this.ws!.send(serialized, (error) => {\n if (error) {\n logger.error({ error: error.message, messageId: message.id }, 'Failed to send message');\n reject(error);\n } else {\n resolve();\n }\n });\n });\n }\n\n /**\n * Queue a message for later delivery when reconnected\n */\n private queueMessage(message: BridgeMessage): void {\n this.messageQueue.push(message);\n logger.debug({ messageId: message.id, queueLength: this.messageQueue.length }, 'Message queued for delivery');\n }\n\n /**\n * Flush all queued messages after reconnection\n */\n private async flushMessageQueue(): Promise<void> {\n if (this.messageQueue.length === 0) {\n return;\n }\n\n logger.info({ queueLength: this.messageQueue.length }, 'Flushing message queue');\n\n const messages = [...this.messageQueue];\n this.messageQueue = [];\n\n for (const message of messages) {\n try {\n await this.sendImmediate(message);\n } catch (error) {\n logger.error({ error: (error as Error).message, messageId: message.id }, 'Failed to send queued message');\n // Re-queue the failed message\n this.messageQueue.unshift(message);\n break;\n }\n }\n }\n\n /**\n * Register a handler for incoming messages\n */\n onMessage(handler: MessageHandler): void {\n this.messageHandlers.push(handler);\n }\n\n /**\n * Register a handler for disconnect events\n */\n onDisconnect(handler: DisconnectHandler): void {\n this.disconnectHandlers.push(handler);\n }\n\n /**\n * Register a handler for error events\n */\n onError(handler: ErrorHandler): void {\n this.errorHandlers.push(handler);\n }\n\n /**\n * Register a handler for reconnecting events\n */\n onReconnecting(handler: (attempt: number, maxAttempts: number) => void): void {\n this.reconnectingHandlers.push(handler);\n }\n\n /**\n * Check if the transport is currently connected\n */\n isConnected(): boolean {\n return this.state === ConnectionState.CONNECTED;\n }\n\n /**\n * Get the current connection state\n */\n getState(): ConnectionState {\n return this.state;\n }\n\n /**\n * Handle incoming WebSocket messages\n */\n private handleIncomingMessage(data: WebSocket.RawData): void {\n const messageString = data.toString();\n logger.debug({ dataLength: messageString.length }, 'Received message');\n\n const result = safeDeserializeMessage(messageString);\n\n if (!result.success) {\n logger.warn({ error: result.error.message }, 'Failed to parse incoming message');\n this.notifyError(new Error(`Invalid message format: ${result.error.message}`));\n return;\n }\n\n const message = result.data;\n logger.debug({ messageId: message.id, type: message.type }, 'Parsed message');\n\n // Notify all message handlers\n for (const handler of this.messageHandlers) {\n try {\n handler(message);\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Message handler threw error');\n }\n }\n }\n\n /**\n * Notify all disconnect handlers\n */\n private notifyDisconnect(): void {\n for (const handler of this.disconnectHandlers) {\n try {\n handler();\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Disconnect handler threw error');\n }\n }\n }\n\n /**\n * Notify all error handlers\n */\n private notifyError(error: Error): void {\n for (const handler of this.errorHandlers) {\n try {\n handler(error);\n } catch (handlerError) {\n logger.error({ error: (handlerError as Error).message }, 'Error handler threw error');\n }\n }\n }\n\n /**\n * Notify all reconnecting handlers\n */\n private notifyReconnecting(attempt: number, maxAttempts: number): void {\n for (const handler of this.reconnectingHandlers) {\n try {\n handler(attempt, maxAttempts);\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Reconnecting handler threw error');\n }\n }\n }\n\n // ============================================================================\n // Reconnection Methods\n // ============================================================================\n\n /**\n * Check if reconnection should be attempted\n */\n private shouldReconnect(): boolean {\n if (!this.config?.reconnect) {\n return false;\n }\n\n const maxAttempts = this.config.maxReconnectAttempts ?? DEFAULT_MAX_RECONNECT_ATTEMPTS;\n return this.reconnectAttempts < maxAttempts;\n }\n\n /**\n * Schedule a reconnection attempt\n */\n private scheduleReconnect(): void {\n if (this.reconnectTimer) {\n return; // Already scheduled\n }\n\n this.state = ConnectionState.RECONNECTING;\n this.reconnectAttempts++;\n\n const maxAttempts = this.config?.maxReconnectAttempts ?? DEFAULT_MAX_RECONNECT_ATTEMPTS;\n const interval = this.config?.reconnectInterval ?? DEFAULT_RECONNECT_INTERVAL;\n\n logger.info(\n { attempt: this.reconnectAttempts, maxAttempts, interval },\n 'Scheduling reconnection attempt'\n );\n\n // Notify reconnecting handlers\n this.notifyReconnecting(this.reconnectAttempts, maxAttempts);\n\n this.reconnectTimer = setTimeout(async () => {\n this.reconnectTimer = null;\n\n try {\n await this.establishConnection();\n logger.info({ attempts: this.reconnectAttempts }, 'Reconnection successful');\n } catch (error) {\n logger.warn({ error: (error as Error).message }, 'Reconnection attempt failed');\n\n // Schedule another attempt if we haven't reached the limit\n if (this.shouldReconnect()) {\n this.scheduleReconnect();\n } else {\n logger.error({ maxAttempts }, 'Max reconnection attempts reached, giving up');\n this.state = ConnectionState.DISCONNECTED;\n this.notifyError(new Error(`Failed to reconnect after ${maxAttempts} attempts`));\n }\n }\n }, interval);\n }\n\n /**\n * Clear any pending reconnection timer\n */\n private clearReconnectTimer(): void {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n }\n\n // ============================================================================\n // Heartbeat Methods\n // ============================================================================\n\n /**\n * Start the heartbeat monitoring\n */\n private startHeartbeat(): void {\n this.stopHeartbeat(); // Clear any existing heartbeat\n\n this.heartbeatInterval = setInterval(() => {\n this.sendPing();\n }, DEFAULT_HEARTBEAT_INTERVAL);\n\n logger.debug({ interval: DEFAULT_HEARTBEAT_INTERVAL }, 'Heartbeat monitoring started');\n }\n\n /**\n * Stop the heartbeat monitoring\n */\n private stopHeartbeat(): void {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = null;\n }\n\n if (this.heartbeatTimeout) {\n clearTimeout(this.heartbeatTimeout);\n this.heartbeatTimeout = null;\n }\n\n this.awaitingPong = false;\n }\n\n /**\n * Send a ping to the peer\n */\n private sendPing(): void {\n if (!this.ws || this.state !== ConnectionState.CONNECTED) {\n return;\n }\n\n if (this.awaitingPong) {\n // We didn't receive a pong for the previous ping - connection may be dead\n logger.warn('No pong received, connection may be dead');\n this.handleHeartbeatTimeout();\n return;\n }\n\n this.awaitingPong = true;\n this.ws.ping();\n\n // Set timeout for pong response\n this.heartbeatTimeout = setTimeout(() => {\n if (this.awaitingPong) {\n this.handleHeartbeatTimeout();\n }\n }, HEARTBEAT_TIMEOUT);\n\n logger.debug('Ping sent');\n }\n\n /**\n * Handle pong response from peer\n */\n private handlePong(): void {\n this.awaitingPong = false;\n\n if (this.heartbeatTimeout) {\n clearTimeout(this.heartbeatTimeout);\n this.heartbeatTimeout = null;\n }\n\n logger.debug('Pong received');\n }\n\n /**\n * Handle heartbeat timeout (no pong received)\n */\n private handleHeartbeatTimeout(): void {\n logger.warn('Heartbeat timeout - closing connection');\n this.awaitingPong = false;\n\n if (this.heartbeatTimeout) {\n clearTimeout(this.heartbeatTimeout);\n this.heartbeatTimeout = null;\n }\n\n // Close the connection to trigger reconnection if enabled\n if (this.ws) {\n this.ws.terminate();\n }\n }\n\n // ============================================================================\n // Getters for testing/debugging\n // ============================================================================\n\n /**\n * Get the current message queue length (for testing)\n */\n getQueueLength(): number {\n return this.messageQueue.length;\n }\n\n /**\n * Get the number of reconnection attempts (for testing)\n */\n getReconnectAttempts(): number {\n return this.reconnectAttempts;\n }\n}\n","/**\n * Authentication utilities for Claude Code Bridge\n * Handles token, password, and IP-based authentication for WebSocket connections\n */\n\nimport * as crypto from 'crypto';\nimport { createLogger } from './logger.js';\nimport type { IncomingMessage } from 'http';\n\nconst logger = createLogger('auth');\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\n/**\n * Authentication type\n */\nexport type AuthType = 'none' | 'token' | 'password' | 'ip' | 'combined';\n\n/**\n * Authentication configuration\n */\nexport interface AuthConfig {\n /** Authentication type */\n type: AuthType;\n /** Authentication token (for type: 'token' or 'combined') */\n token?: string;\n /** Authentication password (for type: 'password' or 'combined') */\n password?: string;\n /** Allowed IP addresses/ranges in CIDR notation (for type: 'ip' or 'combined') */\n allowedIps?: string[];\n /** If true, ALL configured methods must pass; if false, ANY passing method is sufficient */\n requireAll?: boolean;\n}\n\n/**\n * Authentication result\n */\nexport interface AuthResult {\n /** Whether authentication succeeded */\n success: boolean;\n /** Error message if authentication failed */\n error?: string;\n /** Which authentication method succeeded (if any) */\n method?: 'token' | 'password' | 'ip';\n /** Client IP address */\n clientIp?: string;\n}\n\n/**\n * Credentials extracted from a request\n */\nexport interface ExtractedCredentials {\n /** Token from query string or Authorization header */\n token?: string;\n /** Password from query string or header */\n password?: string;\n /** Client IP address */\n clientIp: string;\n}\n\n// ============================================================================\n// IP/CIDR Utilities\n// ============================================================================\n\n/**\n * Parse an IPv4 address to a 32-bit integer\n */\nfunction ipv4ToInt(ip: string): number {\n const parts = ip.split('.').map(Number);\n if (parts.length !== 4 || parts.some(p => isNaN(p) || p < 0 || p > 255)) {\n return -1;\n }\n return (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8) | parts[3];\n}\n\n/**\n * Check if an IP address matches a CIDR range\n * @param clientIp - The IP address to check\n * @param cidr - The CIDR range (e.g., \"192.168.0.0/16\" or \"10.0.0.1\")\n * @returns true if the IP matches the range\n */\nfunction matchesCidr(clientIp: string, cidr: string): boolean {\n // Handle IPv6-mapped IPv4 addresses\n let normalizedIp = clientIp;\n if (normalizedIp.startsWith('::ffff:')) {\n normalizedIp = normalizedIp.substring(7);\n }\n\n // Parse CIDR\n const [network, prefixStr] = cidr.split('/');\n const prefix = prefixStr ? parseInt(prefixStr, 10) : 32;\n\n // Validate prefix\n if (prefix < 0 || prefix > 32) {\n return false;\n }\n\n // Parse IP addresses\n const clientInt = ipv4ToInt(normalizedIp);\n const networkInt = ipv4ToInt(network);\n\n if (clientInt === -1 || networkInt === -1) {\n // If either is invalid, try simple string match\n return normalizedIp === network || clientIp === cidr;\n }\n\n // Create mask from prefix\n const mask = prefix === 0 ? 0 : (-1 << (32 - prefix)) >>> 0;\n\n // Compare masked values (use >>> 0 to ensure unsigned comparison)\n return ((clientInt & mask) >>> 0) === ((networkInt & mask) >>> 0);\n}\n\n/**\n * Check if an IP address matches any of the allowed ranges\n * @param clientIp - The IP address to check\n * @param allowedCidrs - Array of CIDR ranges\n * @returns true if the IP matches any range\n */\nexport function validateIp(clientIp: string, allowedCidrs: string[]): boolean {\n if (!allowedCidrs || allowedCidrs.length === 0) {\n return false;\n }\n\n for (const cidr of allowedCidrs) {\n if (matchesCidr(clientIp, cidr)) {\n logger.debug({ clientIp, matchedCidr: cidr }, 'IP matched allowed range');\n return true;\n }\n }\n\n logger.debug({ clientIp, allowedCidrs }, 'IP did not match any allowed range');\n return false;\n}\n\n// ============================================================================\n// Token/Password Validation\n// ============================================================================\n\n/**\n * Compare two strings in constant time to prevent timing attacks\n * @param provided - The provided value\n * @param expected - The expected value\n * @returns true if the values match\n */\nfunction timingSafeCompare(provided: string, expected: string): boolean {\n // Ensure both strings have the same length to avoid timing differences\n const providedBuffer = Buffer.from(provided, 'utf-8');\n const expectedBuffer = Buffer.from(expected, 'utf-8');\n\n // If lengths differ, still do constant-time comparison to prevent timing attack\n // but return false\n if (providedBuffer.length !== expectedBuffer.length) {\n // Compare with expected to maintain constant time\n crypto.timingSafeEqual(expectedBuffer, expectedBuffer);\n return false;\n }\n\n return crypto.timingSafeEqual(providedBuffer, expectedBuffer);\n}\n\n/**\n * Validate a token using timing-safe comparison\n * @param provided - The provided token\n * @param expected - The expected token\n * @returns true if tokens match\n */\nexport function validateToken(provided: string | undefined, expected: string): boolean {\n if (!provided) {\n return false;\n }\n return timingSafeCompare(provided, expected);\n}\n\n/**\n * Validate a password using timing-safe comparison\n * @param provided - The provided password\n * @param expected - The expected password\n * @returns true if passwords match\n */\nexport function validatePassword(provided: string | undefined, expected: string): boolean {\n if (!provided) {\n return false;\n }\n return timingSafeCompare(provided, expected);\n}\n\n// ============================================================================\n// Credential Extraction\n// ============================================================================\n\n/**\n * Get the client IP address from a request\n * Handles X-Forwarded-For headers for proxied connections\n */\nfunction getClientIp(request: IncomingMessage): string {\n // Check for forwarded IP (from proxy)\n const forwarded = request.headers['x-forwarded-for'];\n if (forwarded) {\n const ips = Array.isArray(forwarded) ? forwarded[0] : forwarded;\n // Get the first IP (original client) from comma-separated list\n const clientIp = ips.split(',')[0].trim();\n if (clientIp) {\n return clientIp;\n }\n }\n\n // Fall back to socket remote address\n return request.socket.remoteAddress || 'unknown';\n}\n\n/**\n * Extract credentials from an HTTP request\n * Looks for token/password in query parameters and Authorization header\n */\nexport function extractCredentials(request: IncomingMessage): ExtractedCredentials {\n const credentials: ExtractedCredentials = {\n clientIp: getClientIp(request),\n };\n\n // Parse query parameters from URL\n const url = new URL(request.url || '/', `http://${request.headers.host || 'localhost'}`);\n\n // Extract token from query parameter\n const queryToken = url.searchParams.get('token');\n if (queryToken) {\n credentials.token = queryToken;\n }\n\n // Extract password from query parameter\n const queryPassword = url.searchParams.get('password');\n if (queryPassword) {\n credentials.password = queryPassword;\n }\n\n // Check Authorization header (Bearer token takes precedence)\n const authHeader = request.headers.authorization;\n if (authHeader) {\n if (authHeader.startsWith('Bearer ')) {\n credentials.token = authHeader.substring(7);\n } else if (authHeader.startsWith('Basic ')) {\n // Basic auth: base64(username:password) - we use password as auth\n try {\n const decoded = Buffer.from(authHeader.substring(6), 'base64').toString('utf-8');\n const [, password] = decoded.split(':');\n if (password) {\n credentials.password = password;\n }\n } catch {\n // Invalid base64, ignore\n }\n }\n }\n\n // Check X-Auth-Token header\n const tokenHeader = request.headers['x-auth-token'];\n if (tokenHeader && !credentials.token) {\n credentials.token = Array.isArray(tokenHeader) ? tokenHeader[0] : tokenHeader;\n }\n\n // Check X-Auth-Password header\n const passwordHeader = request.headers['x-auth-password'];\n if (passwordHeader && !credentials.password) {\n credentials.password = Array.isArray(passwordHeader) ? passwordHeader[0] : passwordHeader;\n }\n\n return credentials;\n}\n\n// ============================================================================\n// Authenticator Class\n// ============================================================================\n\n/**\n * Authenticator class for validating connection requests\n */\nexport class Authenticator {\n private config: AuthConfig;\n\n /**\n * Create a new Authenticator\n * @param config - Authentication configuration\n */\n constructor(config: AuthConfig) {\n this.config = config;\n }\n\n /**\n * Authenticate a request\n * @param request - The incoming HTTP request (WebSocket upgrade request)\n * @returns Authentication result\n */\n authenticate(request: IncomingMessage): AuthResult {\n // If auth is disabled, allow all connections\n if (this.config.type === 'none') {\n return { success: true };\n }\n\n // Extract credentials from request\n const credentials = extractCredentials(request);\n\n return this.authenticateWithCredentials(credentials);\n }\n\n /**\n * Authenticate with extracted credentials\n * @param credentials - The extracted credentials\n * @returns Authentication result\n */\n authenticateWithCredentials(credentials: ExtractedCredentials): AuthResult {\n const { clientIp } = credentials;\n\n // If auth is disabled, allow all connections\n if (this.config.type === 'none') {\n return { success: true, clientIp };\n }\n\n const results: { method: 'token' | 'password' | 'ip'; success: boolean }[] = [];\n\n // Check token authentication\n if (this.config.token) {\n const tokenValid = validateToken(credentials.token, this.config.token);\n results.push({ method: 'token', success: tokenValid });\n if (tokenValid) {\n logger.debug({ clientIp }, 'Token authentication succeeded');\n } else {\n logger.debug({ clientIp }, 'Token authentication failed');\n }\n }\n\n // Check password authentication\n if (this.config.password) {\n const passwordValid = validatePassword(credentials.password, this.config.password);\n results.push({ method: 'password', success: passwordValid });\n if (passwordValid) {\n logger.debug({ clientIp }, 'Password authentication succeeded');\n } else {\n logger.debug({ clientIp }, 'Password authentication failed');\n }\n }\n\n // Check IP authentication\n if (this.config.allowedIps && this.config.allowedIps.length > 0) {\n const ipValid = validateIp(clientIp, this.config.allowedIps);\n results.push({ method: 'ip', success: ipValid });\n if (ipValid) {\n logger.debug({ clientIp }, 'IP authentication succeeded');\n } else {\n logger.debug({ clientIp }, 'IP authentication failed');\n }\n }\n\n // If no auth methods configured but type is not 'none', reject\n if (results.length === 0) {\n logger.warn('Authentication configured but no methods available');\n return {\n success: false,\n error: 'Authentication required but not configured',\n clientIp,\n };\n }\n\n // Evaluate results based on requireAll setting\n if (this.config.requireAll) {\n // ALL methods must pass\n const allPassed = results.every(r => r.success);\n if (allPassed) {\n logger.info({ clientIp, methods: results.map(r => r.method) }, 'All authentication methods passed');\n return { success: true, clientIp };\n } else {\n const failed = results.filter(r => !r.success).map(r => r.method);\n logger.warn({ clientIp, failedMethods: failed }, 'Authentication failed (requireAll mode)');\n return {\n success: false,\n error: `Authentication failed for methods: ${failed.join(', ')}`,\n clientIp,\n };\n }\n } else {\n // ANY method passing is sufficient\n const passed = results.find(r => r.success);\n if (passed) {\n logger.info({ clientIp, method: passed.method }, 'Authentication succeeded');\n return { success: true, method: passed.method, clientIp };\n } else {\n logger.warn({ clientIp }, 'All authentication methods failed');\n return {\n success: false,\n error: 'Authentication failed',\n clientIp,\n };\n }\n }\n }\n\n /**\n * Get the configured authentication type\n */\n getType(): AuthType {\n return this.config.type;\n }\n\n /**\n * Check if authentication is required\n */\n isRequired(): boolean {\n return this.config.type !== 'none';\n }\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Create an AuthConfig from CLI options\n * @param options - CLI options object\n * @returns AuthConfig\n */\nexport function createAuthConfigFromOptions(options: {\n authToken?: string;\n authPassword?: string;\n authIp?: string[];\n authRequireAll?: boolean;\n}): AuthConfig {\n const hasToken = !!options.authToken;\n const hasPassword = !!options.authPassword;\n const hasIp = options.authIp && options.authIp.length > 0;\n\n // Determine auth type based on what's configured\n let type: AuthType = 'none';\n if (hasToken || hasPassword || hasIp) {\n const count = [hasToken, hasPassword, hasIp].filter(Boolean).length;\n if (count > 1) {\n type = 'combined';\n } else if (hasToken) {\n type = 'token';\n } else if (hasPassword) {\n type = 'password';\n } else if (hasIp) {\n type = 'ip';\n }\n }\n\n return {\n type,\n token: options.authToken,\n password: options.authPassword,\n allowedIps: options.authIp,\n requireAll: options.authRequireAll ?? false,\n };\n}\n\n/**\n * Validate an AuthConfig\n * @param config - AuthConfig to validate\n * @returns Validation result with errors and warnings\n */\nexport function validateAuthConfig(config: AuthConfig): { valid: boolean; errors: string[]; warnings: string[] } {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n // Check that required credentials are provided for the auth type\n if (config.type === 'token' && !config.token) {\n errors.push('Token authentication requires a token');\n }\n if (config.type === 'password' && !config.password) {\n errors.push('Password authentication requires a password');\n }\n if (config.type === 'ip' && (!config.allowedIps || config.allowedIps.length === 0)) {\n errors.push('IP authentication requires at least one allowed IP/CIDR');\n }\n\n // Validate CIDR formats\n if (config.allowedIps) {\n for (const cidr of config.allowedIps) {\n const [ip, prefix] = cidr.split('/');\n if (ipv4ToInt(ip) === -1) {\n warnings.push(`IP address may not be valid IPv4: ${ip}`);\n }\n if (prefix !== undefined) {\n const prefixNum = parseInt(prefix, 10);\n if (isNaN(prefixNum) || prefixNum < 0 || prefixNum > 32) {\n errors.push(`Invalid CIDR prefix: ${cidr}`);\n }\n }\n }\n }\n\n // Warn about weak authentication\n if (config.token && config.token.length < 16) {\n warnings.push('Token is shorter than 16 characters - consider using a longer token');\n }\n if (config.password && config.password.length < 8) {\n warnings.push('Password is shorter than 8 characters - consider using a longer password');\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n","/**\n * Message builder factory functions for Claude Code Bridge\n * Provides convenient functions to create specific message types\n */\n\nimport { createMessage, type BridgeMessage, type Context, type TaskRequest, type TaskResult } from './protocol.js';\n\n/**\n * Notification data structure for notification messages\n */\nexport interface NotificationData {\n type: string;\n message: string;\n data?: Record<string, unknown>;\n}\n\n/**\n * Creates a context synchronization message\n * Used to share context (files, tree, summary) with a peer\n * @param source The source instance identifier\n * @param context The context to synchronize\n * @returns A BridgeMessage with type 'context_sync'\n */\nexport function createContextSyncMessage(\n source: string,\n context: Context\n): BridgeMessage {\n const message = createMessage('context_sync', source);\n return {\n ...message,\n context,\n };\n}\n\n/**\n * Creates a task delegation message\n * Used to delegate a task to a peer instance\n * @param source The source instance identifier\n * @param task The task to delegate\n * @returns A BridgeMessage with type 'task_delegate'\n */\nexport function createTaskDelegateMessage(\n source: string,\n task: TaskRequest\n): BridgeMessage {\n const message = createMessage('task_delegate', source);\n return {\n ...message,\n task,\n };\n}\n\n/**\n * Creates a task response message\n * Used to respond to a delegated task\n * @param source The source instance identifier\n * @param taskId The ID of the task being responded to\n * @param result The result of the task execution\n * @returns A BridgeMessage with type 'response'\n */\nexport function createTaskResponseMessage(\n source: string,\n taskId: string,\n result: Omit<TaskResult, 'taskId'>\n): BridgeMessage {\n const message = createMessage('response', source);\n return {\n ...message,\n result: {\n ...result,\n taskId,\n },\n };\n}\n\n/**\n * Creates a context request message\n * Used to request specific context from a peer\n * @param source The source instance identifier\n * @param query A description of what context is being requested\n * @returns A BridgeMessage with type 'request'\n */\nexport function createContextRequestMessage(\n source: string,\n query: string\n): BridgeMessage {\n const message = createMessage('request', source);\n return {\n ...message,\n context: {\n summary: query,\n },\n };\n}\n\n/**\n * Creates a notification message\n * Used to send notifications to peers (events, status updates, etc.)\n * @param source The source instance identifier\n * @param notification The notification data\n * @returns A BridgeMessage with type 'notification'\n */\nexport function createNotificationMessage(\n source: string,\n notification: NotificationData\n): BridgeMessage {\n const message = createMessage('notification', source);\n return {\n ...message,\n context: {\n summary: notification.message,\n variables: {\n notificationType: notification.type,\n ...notification.data,\n },\n },\n };\n}\n","/**\n * Bridge Core - Main orchestration class for Claude Code Bridge\n * Handles peer connections, message routing, and lifecycle management\n */\n\nimport { WebSocketServer, WebSocket as WsWebSocket } from 'ws';\nimport type { IncomingMessage } from 'http';\nimport * as https from 'https';\nimport { v4 as uuidv4 } from 'uuid';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { createLogger } from '../utils/logger.js';\nimport { WebSocketTransport } from '../transport/websocket.js';\nimport { ConnectionState, type Transport, type TLSConfig, type AuthConfig } from '../transport/interface.js';\nimport { loadCertificatesSync, isTLSEnabled } from '../utils/tls.js';\nimport { Authenticator, extractCredentials } from '../utils/auth.js';\nimport {\n type BridgeMessage,\n type TaskRequest,\n type TaskResult,\n type Context,\n type FileChunk,\n safeDeserializeMessage,\n serializeMessage,\n} from './protocol.js';\nimport {\n createTaskDelegateMessage,\n createTaskResponseMessage,\n createContextSyncMessage,\n createContextRequestMessage,\n} from './messages.js';\n\nconst logger = createLogger('bridge');\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\n/**\n * Bridge operation mode\n * - 'host': Listen for incoming connections, sends commands via MCP\n * - 'client': Connect to host, receives and executes commands\n * - 'peer': Bidirectional mode - can both listen and connect\n */\nexport type BridgeMode = 'host' | 'client' | 'peer';\n\n/**\n * Configuration for the bridge's listening server\n */\nexport interface BridgeListenConfig {\n /** Port to listen on */\n port: number;\n /** Host to bind to (default: 0.0.0.0) */\n host?: string;\n /** TLS configuration for secure connections */\n tls?: TLSConfig;\n /** Authentication configuration */\n auth?: AuthConfig;\n}\n\n/**\n * Configuration for connecting to a remote bridge\n */\nexport interface BridgeConnectConfig {\n /** Full WebSocket URL (e.g., ws://localhost:8765 or wss://localhost:8765) */\n url?: string;\n /** Use host.docker.internal for container-to-host connection */\n hostGateway?: boolean;\n /** Port to connect to (used if url is not provided) */\n port?: number;\n /** TLS configuration for secure connections */\n tls?: TLSConfig;\n /** Authentication configuration */\n auth?: AuthConfig;\n}\n\n/**\n * Context sharing configuration\n */\nexport interface ContextSharingConfig {\n /** Enable automatic context synchronization */\n autoSync?: boolean;\n /** Interval in milliseconds for auto-sync (default: 5000) */\n syncInterval?: number;\n}\n\n/**\n * Full configuration for Bridge initialization\n */\nexport interface BridgeConfig {\n /** Operation mode: 'host' or 'client' */\n mode: BridgeMode;\n /** Unique identifier for this bridge instance */\n instanceName: string;\n /** Server configuration (required for 'host' mode) */\n listen?: BridgeListenConfig;\n /** Connection configuration (required for 'client' mode) */\n connect?: BridgeConnectConfig;\n /** Task timeout in milliseconds (default: 300000 / 5 minutes) */\n taskTimeout?: number;\n /** Context sharing configuration */\n contextSharing?: ContextSharingConfig;\n}\n\n/**\n * Information about a connected peer\n */\nexport interface PeerInfo {\n /** Unique identifier for the peer connection */\n id: string;\n /** Name of the peer instance */\n name: string;\n /** Environment type of the peer */\n environment?: string;\n /** Timestamp when the peer connected */\n connectedAt: number;\n /** Timestamp of last activity from the peer */\n lastActivity: number;\n}\n\n/**\n * Internal peer connection tracking\n */\ninterface PeerConnection {\n /** Peer information */\n info: PeerInfo;\n /** WebSocket connection (for server-side connections) */\n ws?: WsWebSocket;\n /** Transport instance (for client-side connections) */\n transport?: Transport;\n}\n\n/**\n * Handler for peer connection events\n */\nexport type PeerConnectedHandler = (peer: PeerInfo) => void;\n\n/**\n * Handler for peer disconnection events\n */\nexport type PeerDisconnectedHandler = (peer: PeerInfo) => void;\n\n/**\n * Handler for incoming messages from peers\n */\nexport type MessageReceivedHandler = (message: BridgeMessage, peerId: string) => void;\n\n/**\n * Handler for incoming task delegation requests\n * Returns a TaskResult or Promise<TaskResult>\n */\nexport type TaskReceivedHandler = (task: TaskRequest, peerId: string) => TaskResult | Promise<TaskResult>;\n\n/**\n * Handler for incoming context synchronization\n */\nexport type ContextReceivedHandler = (context: Context, peerId: string) => void;\n\n/**\n * Handler for incoming context requests\n * Returns FileChunk[] or Promise<FileChunk[]>\n */\nexport type ContextRequestedHandler = (query: string, peerId: string) => FileChunk[] | Promise<FileChunk[]>;\n\n/**\n * Pending task tracking for response correlation\n */\ninterface PendingTask {\n taskId: string;\n peerId: string;\n resolve: (result: TaskResult) => void;\n reject: (error: Error) => void;\n timeoutId: ReturnType<typeof setTimeout>;\n}\n\n/**\n * Pending context request tracking for response correlation\n */\ninterface PendingContextRequest {\n requestId: string;\n peerId: string;\n resolve: (chunks: FileChunk[]) => void;\n reject: (error: Error) => void;\n timeoutId: ReturnType<typeof setTimeout>;\n}\n\n// ============================================================================\n// Bridge Class\n// ============================================================================\n\n/**\n * Main Bridge class for host-client communication\n * Supports two modes of operation:\n * - 'host': Acts as a server, accepting client connections, sends commands via MCP\n * - 'client': Connects to a host, receives and executes commands with handlers\n */\nexport class Bridge {\n private config: BridgeConfig;\n private server: WebSocketServer | null = null;\n private httpsServer: https.Server | null = null;\n private clientTransport: WebSocketTransport | null = null;\n private peers: Map<string, PeerConnection> = new Map();\n private started: boolean = false;\n private authenticator: Authenticator | null = null;\n\n // Event handlers\n private peerConnectedHandlers: PeerConnectedHandler[] = [];\n private peerDisconnectedHandlers: PeerDisconnectedHandler[] = [];\n private messageReceivedHandlers: MessageReceivedHandler[] = [];\n private taskReceivedHandler: TaskReceivedHandler | null = null;\n private contextReceivedHandlers: ContextReceivedHandler[] = [];\n private contextRequestedHandler: ContextRequestedHandler | null = null;\n\n // Task correlation\n private pendingTasks: Map<string, PendingTask> = new Map();\n\n // Context request correlation\n private pendingContextRequests: Map<string, PendingContextRequest> = new Map();\n\n // Auto-sync interval timer\n private autoSyncIntervalId: ReturnType<typeof setInterval> | null = null;\n\n /**\n * Create a new Bridge instance\n * @param config Bridge configuration\n */\n constructor(config: BridgeConfig) {\n this.config = config;\n this.validateConfig();\n logger.info({ instanceName: config.instanceName, mode: config.mode }, 'Bridge instance created');\n }\n\n /**\n * Validate the configuration based on mode requirements\n */\n private validateConfig(): void {\n const { mode, listen, connect } = this.config;\n\n if (mode === 'host' && !listen) {\n throw new Error(\"'host' mode requires 'listen' configuration\");\n }\n\n if (mode === 'client' && !connect) {\n throw new Error(\"'client' mode requires 'connect' configuration\");\n }\n\n if (mode === 'peer' && !listen && !connect) {\n throw new Error(\"'peer' mode requires either 'listen' or 'connect' configuration\");\n }\n }\n\n /**\n * Start the bridge based on configured mode\n * - 'host': Starts WebSocket server, sends commands via MCP\n * - 'client': Connects to host, receives and executes commands\n * - 'peer': Starts server (if listen configured) and connects to remote (if connect configured)\n */\n async start(): Promise<void> {\n if (this.started) {\n throw new Error('Bridge is already started');\n }\n\n const { mode } = this.config;\n logger.info({ mode }, 'Starting bridge');\n\n try {\n // Start server if in host mode or peer mode with listen config\n if ((mode === 'host' || mode === 'peer') && this.config.listen) {\n await this.startServer();\n }\n\n // Connect to remote if in client mode or peer mode with connect config\n if ((mode === 'client' || mode === 'peer') && this.config.connect) {\n await this.connectToRemote();\n }\n\n this.started = true;\n this.writeStatusFile();\n logger.info({ mode, instanceName: this.config.instanceName }, 'Bridge started successfully');\n } catch (error) {\n // Cleanup on failure\n await this.cleanup();\n throw error;\n }\n }\n\n /**\n * Stop the bridge and close all connections\n */\n async stop(): Promise<void> {\n if (!this.started) {\n return;\n }\n\n logger.info('Stopping bridge');\n await this.cleanup();\n this.started = false;\n logger.info('Bridge stopped');\n }\n\n /**\n * Get list of connected peers\n */\n getPeers(): PeerInfo[] {\n return Array.from(this.peers.values()).map(p => p.info);\n }\n\n /**\n * Connect to a remote bridge\n * @param url WebSocket URL to connect to\n */\n async connectToPeer(url: string): Promise<void> {\n const transport = new WebSocketTransport();\n\n // Set up message handler\n transport.onMessage((message) => {\n this.handleMessage(message, transport);\n });\n\n // Set up disconnect handler\n transport.onDisconnect(() => {\n this.handleClientDisconnect(transport);\n });\n\n try {\n await transport.connect({\n url,\n reconnect: true,\n reconnectInterval: 1000,\n maxReconnectAttempts: 10,\n });\n\n // Create peer info for the connected remote\n const peerId = uuidv4();\n const peerInfo: PeerInfo = {\n id: peerId,\n name: 'remote', // Will be updated when we receive peer info\n connectedAt: Date.now(),\n lastActivity: Date.now(),\n };\n\n this.peers.set(peerId, {\n info: peerInfo,\n transport,\n });\n\n // Store peerId on transport for lookup\n (transport as WebSocketTransport & { _peerId?: string })._peerId = peerId;\n\n this.notifyPeerConnected(peerInfo);\n logger.info({ peerId, url }, 'Connected to remote peer');\n } catch (error) {\n logger.error({ error: (error as Error).message, url }, 'Failed to connect to remote peer');\n throw error;\n }\n }\n\n /**\n * Disconnect from a specific peer\n * @param peerId ID of the peer to disconnect from\n */\n async disconnectFromPeer(peerId: string): Promise<void> {\n const peer = this.peers.get(peerId);\n if (!peer) {\n throw new Error(`Peer not found: ${peerId}`);\n }\n\n if (peer.transport) {\n await peer.transport.disconnect();\n }\n\n if (peer.ws) {\n peer.ws.close(1000, 'Disconnect requested');\n }\n\n this.peers.delete(peerId);\n this.notifyPeerDisconnected(peer.info);\n logger.info({ peerId }, 'Disconnected from peer');\n }\n\n /**\n * Send a message to a specific peer\n * @param peerId ID of the peer to send to\n * @param message Message to send\n */\n async sendToPeer(peerId: string, message: BridgeMessage): Promise<void> {\n const peer = this.peers.get(peerId);\n if (!peer) {\n throw new Error(`Peer not found: ${peerId}`);\n }\n\n if (peer.transport) {\n await peer.transport.send(message);\n } else if (peer.ws) {\n const serialized = serializeMessage(message);\n await new Promise<void>((resolve, reject) => {\n peer.ws!.send(serialized, (error) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n } else {\n throw new Error('No transport available for peer');\n }\n\n logger.debug({ peerId, messageId: message.id, type: message.type }, 'Sent message to peer');\n }\n\n /**\n * Broadcast a message to all connected peers\n * @param message Message to broadcast\n */\n async broadcast(message: BridgeMessage): Promise<void> {\n const sendPromises = Array.from(this.peers.keys()).map(peerId =>\n this.sendToPeer(peerId, message).catch(error => {\n logger.error({ error: (error as Error).message, peerId }, 'Failed to send to peer');\n })\n );\n\n await Promise.all(sendPromises);\n logger.debug({ messageId: message.id, peerCount: this.peers.size }, 'Broadcast message sent');\n }\n\n // ============================================================================\n // Event Registration\n // ============================================================================\n\n /**\n * Register a handler for peer connection events\n */\n onPeerConnected(handler: PeerConnectedHandler): void {\n this.peerConnectedHandlers.push(handler);\n }\n\n /**\n * Register a handler for peer disconnection events\n */\n onPeerDisconnected(handler: PeerDisconnectedHandler): void {\n this.peerDisconnectedHandlers.push(handler);\n }\n\n /**\n * Register a handler for incoming messages\n */\n onMessage(handler: MessageReceivedHandler): void {\n this.messageReceivedHandlers.push(handler);\n }\n\n /**\n * Register a handler for incoming task delegation requests\n * Only one handler can be registered at a time\n * @param handler Function that receives a TaskRequest and returns a TaskResult\n */\n onTaskReceived(handler: TaskReceivedHandler): void {\n this.taskReceivedHandler = handler;\n }\n\n /**\n * Register a handler for incoming context synchronization\n * Multiple handlers can be registered\n * @param handler Function that receives context and peerId\n */\n onContextReceived(handler: ContextReceivedHandler): void {\n this.contextReceivedHandlers.push(handler);\n }\n\n /**\n * Register a handler for incoming context requests\n * Only one handler can be registered at a time\n * @param handler Function that receives a query and returns FileChunk[]\n */\n onContextRequested(handler: ContextRequestedHandler): void {\n this.contextRequestedHandler = handler;\n }\n\n // ============================================================================\n // Task Delegation\n // ============================================================================\n\n /**\n * Delegate a task to a peer and wait for the result\n * @param task The task request to delegate\n * @param peerId Optional peer ID to send to (defaults to first peer)\n * @returns Promise that resolves with the task result\n * @throws Error if no peers are connected or task times out\n */\n async delegateTask(task: TaskRequest, peerId?: string): Promise<TaskResult> {\n // Get target peer\n if (!peerId) {\n const peers = this.getPeers();\n if (peers.length === 0) {\n throw new Error('No peers connected to delegate task to');\n }\n peerId = peers[0].id;\n }\n\n // Validate peer exists\n if (!this.peers.has(peerId)) {\n throw new Error(`Peer not found: ${peerId}`);\n }\n\n // Determine timeout\n const timeout = task.timeout ?? this.config.taskTimeout ?? 300000; // Default 5 minutes\n\n // Create promise to track task completion\n return new Promise<TaskResult>((resolve, reject) => {\n // Create the task delegate message\n const message = createTaskDelegateMessage(this.config.instanceName, task);\n\n // Set up timeout\n const timeoutId = setTimeout(() => {\n const pending = this.pendingTasks.get(task.id);\n if (pending) {\n this.pendingTasks.delete(task.id);\n reject(new Error(`Task '${task.id}' timed out after ${timeout}ms`));\n }\n }, timeout);\n\n // Store pending task for correlation\n this.pendingTasks.set(task.id, {\n taskId: task.id,\n peerId,\n resolve,\n reject,\n timeoutId,\n });\n\n // Send the task\n this.sendToPeer(peerId, message).catch((error) => {\n // Clean up on send error\n clearTimeout(timeoutId);\n this.pendingTasks.delete(task.id);\n reject(error);\n });\n\n logger.debug({ taskId: task.id, peerId, timeout }, 'Task delegated');\n });\n }\n\n // ============================================================================\n // Context Synchronization\n // ============================================================================\n\n /**\n * Synchronize context with connected peers\n * @param context Optional context to sync. If not provided, broadcasts to all peers\n * @param peerId Optional peer ID to send to (defaults to all peers)\n */\n async syncContext(context?: Context, peerId?: string): Promise<void> {\n // Use empty context if not provided\n const contextToSync = context ?? {};\n\n // Create the context sync message\n const message = createContextSyncMessage(this.config.instanceName, contextToSync);\n\n if (peerId) {\n // Send to specific peer\n await this.sendToPeer(peerId, message);\n logger.debug({ peerId, messageId: message.id }, 'Context synced to peer');\n } else {\n // Broadcast to all peers\n await this.broadcast(message);\n logger.debug({ peerCount: this.peers.size, messageId: message.id }, 'Context synced to all peers');\n }\n }\n\n /**\n * Request context from a peer based on a query\n * @param query Description of what context is being requested\n * @param peerId Optional peer ID to request from (defaults to first peer)\n * @param timeout Optional timeout in milliseconds (default: 30000)\n * @returns Promise that resolves with FileChunk[] from the peer\n * @throws Error if no peers are connected or request times out\n */\n async requestContext(query: string, peerId?: string, timeout: number = 30000): Promise<FileChunk[]> {\n // Get target peer\n if (!peerId) {\n const peers = this.getPeers();\n if (peers.length === 0) {\n throw new Error('No peers connected to request context from');\n }\n peerId = peers[0].id;\n }\n\n // Validate peer exists\n if (!this.peers.has(peerId)) {\n throw new Error(`Peer not found: ${peerId}`);\n }\n\n // Create promise to track request completion\n return new Promise<FileChunk[]>((resolve, reject) => {\n // Create the context request message\n const message = createContextRequestMessage(this.config.instanceName, query);\n\n // Set up timeout\n const timeoutId = setTimeout(() => {\n const pending = this.pendingContextRequests.get(message.id);\n if (pending) {\n this.pendingContextRequests.delete(message.id);\n reject(new Error(`Context request timed out after ${timeout}ms`));\n }\n }, timeout);\n\n // Store pending request for correlation\n this.pendingContextRequests.set(message.id, {\n requestId: message.id,\n peerId,\n resolve,\n reject,\n timeoutId,\n });\n\n // Send the request\n this.sendToPeer(peerId, message).catch((error) => {\n // Clean up on send error\n clearTimeout(timeoutId);\n this.pendingContextRequests.delete(message.id);\n reject(error);\n });\n\n logger.debug({ requestId: message.id, peerId, query }, 'Context requested');\n });\n }\n\n /**\n * Start automatic context synchronization\n * Uses interval from config.contextSharing.syncInterval (default: 5000ms)\n * @param contextProvider Optional function that returns context to sync\n */\n startAutoSync(contextProvider?: () => Context | Promise<Context>): void {\n // Stop any existing auto-sync\n this.stopAutoSync();\n\n const interval = this.config.contextSharing?.syncInterval ?? 5000;\n\n this.autoSyncIntervalId = setInterval(async () => {\n try {\n // Get context from provider if available\n const context = contextProvider ? await contextProvider() : undefined;\n await this.syncContext(context);\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Auto-sync error');\n }\n }, interval);\n\n logger.info({ interval }, 'Auto-sync started');\n }\n\n /**\n * Stop automatic context synchronization\n */\n stopAutoSync(): void {\n if (this.autoSyncIntervalId) {\n clearInterval(this.autoSyncIntervalId);\n this.autoSyncIntervalId = null;\n logger.info('Auto-sync stopped');\n }\n }\n\n // ============================================================================\n // Private Methods - Server\n // ============================================================================\n\n /**\n * Start the WebSocket server\n * If TLS is configured, starts an HTTPS server with WebSocket upgrade\n * If auth is configured, validates connections before accepting\n */\n private async startServer(): Promise<void> {\n const { listen } = this.config;\n if (!listen) {\n throw new Error('Listen configuration is required');\n }\n\n const host = listen.host ?? '0.0.0.0';\n const port = listen.port;\n const useTls = isTLSEnabled(listen.tls);\n\n // Set up authenticator if auth is configured\n if (listen.auth && listen.auth.type !== 'none') {\n this.authenticator = new Authenticator(listen.auth);\n logger.info({ authType: listen.auth.type }, 'Authentication enabled');\n }\n\n return new Promise<void>((resolve, reject) => {\n logger.debug({ host, port, tls: useTls, auth: !!this.authenticator }, 'Starting WebSocket server');\n\n try {\n if (useTls && listen.tls) {\n // Load TLS certificates\n const tlsOptions = loadCertificatesSync(listen.tls);\n logger.info({ host, port }, 'Starting secure WebSocket server (wss://)');\n\n // Create HTTPS server\n this.httpsServer = https.createServer({\n cert: tlsOptions.cert,\n key: tlsOptions.key,\n ca: tlsOptions.ca,\n passphrase: tlsOptions.passphrase,\n });\n\n // Create WebSocket server attached to HTTPS server\n const wsOptions: import('ws').ServerOptions = {\n server: this.httpsServer,\n };\n\n // Add verifyClient for authentication\n if (this.authenticator) {\n wsOptions.verifyClient = (info, callback) => {\n this.verifyClient(info, callback);\n };\n }\n\n this.server = new WebSocketServer(wsOptions);\n\n // Start HTTPS server\n this.httpsServer.listen(port, host, () => {\n logger.info({ host, port, protocol: 'wss' }, 'Secure WebSocket server listening');\n resolve();\n });\n\n this.httpsServer.on('error', (error) => {\n logger.error({ error: (error as Error).message }, 'HTTPS server error');\n reject(error);\n });\n } else {\n // Create plain WebSocket server\n const wsOptions: import('ws').ServerOptions = {\n host,\n port,\n };\n\n // Add verifyClient for authentication\n if (this.authenticator) {\n wsOptions.verifyClient = (info, callback) => {\n this.verifyClient(info, callback);\n };\n }\n\n this.server = new WebSocketServer(wsOptions);\n\n this.server.on('listening', () => {\n logger.info({ host, port, protocol: 'ws' }, 'WebSocket server listening');\n resolve();\n });\n\n this.server.on('error', (error) => {\n logger.error({ error: (error as Error).message }, 'WebSocket server error');\n reject(error);\n });\n }\n\n this.server.on('connection', (ws, request) => {\n this.handleNewConnection(ws, request);\n });\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Failed to start server');\n reject(error);\n }\n });\n }\n\n /**\n * Verify client connection for authentication\n * Used as WebSocketServer verifyClient callback\n */\n private verifyClient(\n info: { origin: string; secure: boolean; req: IncomingMessage },\n callback: (res: boolean, code?: number, message?: string, headers?: Record<string, string>) => void\n ): void {\n if (!this.authenticator) {\n callback(true);\n return;\n }\n\n const result = this.authenticator.authenticate(info.req);\n\n if (result.success) {\n logger.info({ clientIp: result.clientIp, method: result.method }, 'Client authenticated');\n callback(true);\n } else {\n logger.warn({ clientIp: result.clientIp, error: result.error }, 'Client authentication failed');\n // Use custom close code 4001 for authentication failure\n callback(false, 4001, result.error || 'Authentication failed');\n }\n }\n\n /**\n * Handle a new incoming connection\n */\n private handleNewConnection(ws: WsWebSocket, request: { url?: string }): void {\n const peerId = uuidv4();\n const peerInfo: PeerInfo = {\n id: peerId,\n name: 'client', // Will be updated when we receive peer info\n connectedAt: Date.now(),\n lastActivity: Date.now(),\n };\n\n this.peers.set(peerId, {\n info: peerInfo,\n ws,\n });\n\n logger.info({ peerId, url: request.url }, 'New peer connected');\n\n // Set up message handler\n ws.on('message', (data) => {\n const messageString = data.toString();\n const result = safeDeserializeMessage(messageString);\n\n if (result.success) {\n peerInfo.lastActivity = Date.now();\n this.handleMessage(result.data, ws, peerId);\n } else {\n logger.warn({ peerId, error: result.error.message }, 'Invalid message received');\n }\n });\n\n // Set up close handler\n ws.on('close', (code, reason) => {\n logger.info({ peerId, code, reason: reason.toString() }, 'Peer disconnected');\n this.peers.delete(peerId);\n this.notifyPeerDisconnected(peerInfo);\n });\n\n // Set up error handler\n ws.on('error', (error) => {\n logger.error({ peerId, error: (error as Error).message }, 'Peer connection error');\n });\n\n // Notify peer connected handlers\n this.notifyPeerConnected(peerInfo);\n }\n\n // ============================================================================\n // Private Methods - Client\n // ============================================================================\n\n /**\n * Connect to a remote bridge as a client\n */\n private async connectToRemote(): Promise<void> {\n const { connect } = this.config;\n if (!connect) {\n throw new Error('Connect configuration is required');\n }\n\n // Build URL from config\n let url = connect.url;\n if (!url) {\n const host = connect.hostGateway ? 'host.docker.internal' : 'localhost';\n const port = connect.port ?? 8765;\n // Use wss:// if TLS is configured\n const protocol = isTLSEnabled(connect.tls) || connect.tls?.ca ? 'wss' : 'ws';\n url = `${protocol}://${host}:${port}`;\n }\n\n this.clientTransport = new WebSocketTransport();\n\n // Set up message handler\n this.clientTransport.onMessage((message) => {\n this.handleMessage(message, this.clientTransport!);\n });\n\n // Set up disconnect handler\n this.clientTransport.onDisconnect(() => {\n this.handleClientDisconnect(this.clientTransport!);\n });\n\n try {\n await this.clientTransport.connect({\n url,\n reconnect: true,\n reconnectInterval: 1000,\n maxReconnectAttempts: 10,\n tls: connect.tls,\n auth: connect.auth,\n });\n\n // Create peer info for the connected server\n const peerId = uuidv4();\n const peerInfo: PeerInfo = {\n id: peerId,\n name: 'server',\n connectedAt: Date.now(),\n lastActivity: Date.now(),\n };\n\n this.peers.set(peerId, {\n info: peerInfo,\n transport: this.clientTransport,\n });\n\n // Store peerId on transport for lookup\n (this.clientTransport as WebSocketTransport & { _peerId?: string })._peerId = peerId;\n\n this.notifyPeerConnected(peerInfo);\n logger.info({ peerId, url }, 'Connected to remote bridge');\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Failed to connect to remote bridge');\n this.clientTransport = null;\n throw error;\n }\n }\n\n /**\n * Handle client transport disconnect\n */\n private handleClientDisconnect(transport: Transport): void {\n // Find peer by transport\n const typedTransport = transport as WebSocketTransport & { _peerId?: string };\n const peerId = typedTransport._peerId;\n\n if (peerId) {\n const peer = this.peers.get(peerId);\n if (peer) {\n this.peers.delete(peerId);\n this.notifyPeerDisconnected(peer.info);\n logger.info({ peerId }, 'Client transport disconnected');\n }\n }\n }\n\n // ============================================================================\n // Private Methods - Message Handling\n // ============================================================================\n\n /**\n * Handle an incoming message\n */\n private handleMessage(\n message: BridgeMessage,\n source: WsWebSocket | Transport,\n peerId?: string\n ): void {\n // Find peerId if not provided\n if (!peerId) {\n const typedSource = source as WebSocketTransport & { _peerId?: string };\n peerId = typedSource._peerId;\n }\n\n if (!peerId) {\n // Try to find by ws reference\n for (const [id, peer] of this.peers) {\n if (peer.ws === source || peer.transport === source) {\n peerId = id;\n break;\n }\n }\n }\n\n if (!peerId) {\n logger.warn({ messageId: message.id }, 'Received message from unknown peer');\n return;\n }\n\n // Update last activity\n const peer = this.peers.get(peerId);\n if (peer) {\n peer.info.lastActivity = Date.now();\n }\n\n logger.debug({ peerId, messageId: message.id, type: message.type }, 'Received message');\n\n // Handle task delegation messages\n if (message.type === 'task_delegate' && message.task) {\n this.handleTaskDelegate(message, peerId);\n return;\n }\n\n // Handle task response messages\n if (message.type === 'response' && message.result?.taskId) {\n this.handleTaskResponse(message);\n return;\n }\n\n // Handle context sync messages\n if (message.type === 'context_sync' && message.context) {\n this.handleContextSync(message, peerId);\n return;\n }\n\n // Handle context request messages\n if (message.type === 'request' && message.context?.summary) {\n this.handleContextRequest(message, peerId);\n return;\n }\n\n // Handle context response messages (responses to context requests)\n if (message.type === 'response' && message.context?.files !== undefined) {\n this.handleContextResponse(message);\n return;\n }\n\n // Notify message handlers for other message types\n this.notifyMessageReceived(message, peerId);\n }\n\n /**\n * Handle incoming task delegation request\n */\n private async handleTaskDelegate(message: BridgeMessage, peerId: string): Promise<void> {\n const task = message.task!;\n logger.debug({ taskId: task.id, peerId }, 'Received task delegation');\n\n // If no handler registered, try to forward to another peer\n if (!this.taskReceivedHandler) {\n // Find another peer to forward to (not the sender)\n const otherPeers = Array.from(this.peers.keys()).filter(id => id !== peerId);\n\n if (otherPeers.length > 0) {\n // Forward to the first available peer\n const targetPeerId = otherPeers[0];\n logger.info({ taskId: task.id, targetPeerId }, 'Forwarding task to another peer');\n\n try {\n // Forward the original message\n await this.sendToPeer(targetPeerId, message);\n\n // Set up response forwarding - store the original sender\n const forwardKey = `forward:${task.id}`;\n (this as unknown as Record<string, string>)[forwardKey] = peerId;\n\n return;\n } catch (err) {\n logger.error({ error: (err as Error).message, taskId: task.id }, 'Failed to forward task');\n }\n }\n\n logger.warn({ taskId: task.id }, 'No task handler registered and no peers to forward to');\n const response = createTaskResponseMessage(\n this.config.instanceName,\n task.id,\n {\n success: false,\n data: null,\n error: 'No task handler registered on peer',\n }\n );\n await this.sendToPeer(peerId, response).catch((err) => {\n logger.error({ error: (err as Error).message, taskId: task.id }, 'Failed to send error response');\n });\n return;\n }\n\n try {\n // Execute the task handler\n const result = await this.taskReceivedHandler(task, peerId);\n\n // Send successful response\n const response = createTaskResponseMessage(\n this.config.instanceName,\n task.id,\n result\n );\n await this.sendToPeer(peerId, response);\n logger.debug({ taskId: task.id, success: result.success }, 'Task response sent');\n } catch (error) {\n // Send error response\n const response = createTaskResponseMessage(\n this.config.instanceName,\n task.id,\n {\n success: false,\n data: null,\n error: (error as Error).message,\n }\n );\n await this.sendToPeer(peerId, response).catch((err) => {\n logger.error({ error: (err as Error).message, taskId: task.id }, 'Failed to send error response');\n });\n logger.error({ taskId: task.id, error: (error as Error).message }, 'Task handler error');\n }\n }\n\n /**\n * Handle task response message (correlate with pending task)\n */\n private async handleTaskResponse(message: BridgeMessage): Promise<void> {\n const taskId = message.result!.taskId!;\n\n // Check if this is a forwarded response that needs to go back to original sender\n const forwardKey = `forward:${taskId}`;\n const originalSender = (this as unknown as Record<string, string>)[forwardKey];\n if (originalSender) {\n delete (this as unknown as Record<string, string>)[forwardKey];\n logger.info({ taskId, originalSender }, 'Forwarding task response to original sender');\n await this.sendToPeer(originalSender, message).catch((err) => {\n logger.error({ error: (err as Error).message, taskId }, 'Failed to forward response');\n });\n return;\n }\n\n const pending = this.pendingTasks.get(taskId);\n\n if (!pending) {\n logger.warn({ taskId }, 'Received response for unknown task');\n return;\n }\n\n // Clear timeout and remove from pending\n clearTimeout(pending.timeoutId);\n this.pendingTasks.delete(taskId);\n\n // Resolve the promise with the result\n const result: TaskResult = {\n taskId: message.result!.taskId,\n success: message.result!.success,\n data: message.result!.data,\n artifacts: message.result!.artifacts,\n followUp: message.result!.followUp,\n error: message.result!.error,\n };\n\n logger.debug({ taskId, success: result.success }, 'Task result received');\n pending.resolve(result);\n }\n\n /**\n * Handle incoming context sync message\n */\n private handleContextSync(message: BridgeMessage, peerId: string): void {\n const context = message.context!;\n logger.debug({ peerId, messageId: message.id }, 'Received context sync');\n\n // Notify all context received handlers\n this.notifyContextReceived(context, peerId);\n }\n\n /**\n * Handle incoming context request message\n */\n private async handleContextRequest(message: BridgeMessage, peerId: string): Promise<void> {\n const query = message.context!.summary!;\n logger.debug({ peerId, messageId: message.id, query }, 'Received context request');\n\n // If no handler registered, try to forward to another peer\n if (!this.contextRequestedHandler) {\n // Find another peer to forward to (not the sender)\n const otherPeers = Array.from(this.peers.keys()).filter(id => id !== peerId);\n\n if (otherPeers.length > 0) {\n // Forward to the first available peer\n const targetPeerId = otherPeers[0];\n logger.info({ messageId: message.id, targetPeerId }, 'Forwarding context request to another peer');\n\n try {\n // Forward the original message\n await this.sendToPeer(targetPeerId, message);\n\n // Set up response forwarding - store the original sender\n const forwardKey = `ctxfwd:${message.id}`;\n (this as unknown as Record<string, string>)[forwardKey] = peerId;\n\n return;\n } catch (err) {\n logger.error({ error: (err as Error).message, messageId: message.id }, 'Failed to forward context request');\n }\n }\n\n logger.warn({ messageId: message.id }, 'No context request handler registered and no peers to forward to');\n const response = createContextSyncMessage(this.config.instanceName, { files: [] });\n // Change type to response and add request ID for correlation\n const responseMessage: BridgeMessage = {\n ...response,\n type: 'response',\n context: {\n ...response.context,\n variables: { requestId: message.id },\n },\n };\n await this.sendToPeer(peerId, responseMessage).catch((err) => {\n logger.error({ error: (err as Error).message, messageId: message.id }, 'Failed to send empty context response');\n });\n return;\n }\n\n try {\n // Execute the context request handler\n const files = await this.contextRequestedHandler(query, peerId);\n\n // Create and send response\n const response = createContextSyncMessage(this.config.instanceName, { files });\n const responseMessage: BridgeMessage = {\n ...response,\n type: 'response',\n context: {\n ...response.context,\n variables: { requestId: message.id },\n },\n };\n await this.sendToPeer(peerId, responseMessage);\n logger.debug({ messageId: message.id, fileCount: files.length }, 'Context response sent');\n } catch (error) {\n // Send error response with empty files\n const response = createContextSyncMessage(this.config.instanceName, {\n files: [],\n summary: (error as Error).message,\n });\n const responseMessage: BridgeMessage = {\n ...response,\n type: 'response',\n context: {\n ...response.context,\n variables: { requestId: message.id, error: (error as Error).message },\n },\n };\n await this.sendToPeer(peerId, responseMessage).catch((err) => {\n logger.error({ error: (err as Error).message, messageId: message.id }, 'Failed to send error context response');\n });\n logger.error({ messageId: message.id, error: (error as Error).message }, 'Context request handler error');\n }\n }\n\n /**\n * Handle context response message (correlate with pending context request)\n */\n private async handleContextResponse(message: BridgeMessage): Promise<void> {\n const requestId = message.context?.variables?.requestId as string;\n if (!requestId) {\n logger.warn({ messageId: message.id }, 'Context response without requestId');\n return;\n }\n\n // Check if this is a forwarded response that needs to go back to original sender\n const forwardKey = `ctxfwd:${requestId}`;\n const originalSender = (this as unknown as Record<string, string>)[forwardKey];\n if (originalSender) {\n delete (this as unknown as Record<string, string>)[forwardKey];\n logger.info({ requestId, originalSender }, 'Forwarding context response to original sender');\n await this.sendToPeer(originalSender, message).catch((err) => {\n logger.error({ error: (err as Error).message, requestId }, 'Failed to forward context response');\n });\n return;\n }\n\n const pending = this.pendingContextRequests.get(requestId);\n if (!pending) {\n logger.warn({ requestId }, 'Received response for unknown context request');\n return;\n }\n\n // Clear timeout and remove from pending\n clearTimeout(pending.timeoutId);\n this.pendingContextRequests.delete(requestId);\n\n // Check for error\n const error = message.context?.variables?.error as string | undefined;\n if (error) {\n pending.reject(new Error(error));\n return;\n }\n\n // Resolve the promise with the files\n const files = message.context?.files ?? [];\n logger.debug({ requestId, fileCount: files.length }, 'Context response received');\n pending.resolve(files);\n }\n\n // ============================================================================\n // Private Methods - Event Notification\n // ============================================================================\n\n private notifyPeerConnected(peer: PeerInfo): void {\n // Update status file with new peer\n this.writeStatusFile();\n\n for (const handler of this.peerConnectedHandlers) {\n try {\n handler(peer);\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Peer connected handler error');\n }\n }\n }\n\n private notifyPeerDisconnected(peer: PeerInfo): void {\n // Reject any pending tasks for this peer\n for (const [taskId, pending] of this.pendingTasks) {\n if (pending.peerId === peer.id) {\n clearTimeout(pending.timeoutId);\n this.pendingTasks.delete(taskId);\n pending.reject(new Error(`Peer '${peer.id}' disconnected while task '${taskId}' was pending`));\n }\n }\n\n // Reject any pending context requests for this peer\n for (const [requestId, pending] of this.pendingContextRequests) {\n if (pending.peerId === peer.id) {\n clearTimeout(pending.timeoutId);\n this.pendingContextRequests.delete(requestId);\n pending.reject(new Error(`Peer '${peer.id}' disconnected while context request '${requestId}' was pending`));\n }\n }\n\n for (const handler of this.peerDisconnectedHandlers) {\n try {\n handler(peer);\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Peer disconnected handler error');\n }\n }\n\n // Update status file after peer removed\n this.writeStatusFile();\n }\n\n private notifyMessageReceived(message: BridgeMessage, peerId: string): void {\n for (const handler of this.messageReceivedHandlers) {\n try {\n handler(message, peerId);\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Message received handler error');\n }\n }\n }\n\n private notifyContextReceived(context: Context, peerId: string): void {\n for (const handler of this.contextReceivedHandlers) {\n try {\n handler(context, peerId);\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Context received handler error');\n }\n }\n }\n\n // ============================================================================\n // Private Methods - Cleanup\n // ============================================================================\n\n /**\n * Clean up all resources\n */\n private async cleanup(): Promise<void> {\n logger.debug('Starting cleanup');\n\n // Stop auto-sync\n this.stopAutoSync();\n logger.debug('Auto-sync stopped');\n\n // Reject all pending tasks\n const pendingTaskCount = this.pendingTasks.size;\n for (const [taskId, pending] of this.pendingTasks) {\n clearTimeout(pending.timeoutId);\n pending.reject(new Error('Bridge is shutting down'));\n }\n this.pendingTasks.clear();\n if (pendingTaskCount > 0) {\n logger.debug({ count: pendingTaskCount }, 'Pending tasks cancelled');\n }\n\n // Reject all pending context requests\n const pendingContextCount = this.pendingContextRequests.size;\n for (const [requestId, pending] of this.pendingContextRequests) {\n clearTimeout(pending.timeoutId);\n pending.reject(new Error('Bridge is shutting down'));\n }\n this.pendingContextRequests.clear();\n if (pendingContextCount > 0) {\n logger.debug({ count: pendingContextCount }, 'Pending context requests cancelled');\n }\n\n // Disconnect client transport\n if (this.clientTransport) {\n logger.debug('Disconnecting client transport');\n try {\n await this.clientTransport.disconnect();\n logger.debug('Client transport disconnected');\n } catch {\n // Ignore disconnect errors during cleanup\n }\n this.clientTransport = null;\n }\n\n // Close all peer WebSocket connections\n const peerCount = this.peers.size;\n if (peerCount > 0) {\n logger.debug({ count: peerCount }, 'Closing peer connections');\n }\n for (const [peerId, peer] of this.peers) {\n if (peer.ws) {\n try {\n peer.ws.close(1000, 'Bridge stopping');\n } catch {\n // Ignore close errors during cleanup\n }\n }\n if (peer.transport) {\n try {\n await peer.transport.disconnect();\n } catch {\n // Ignore disconnect errors during cleanup\n }\n }\n logger.debug({ peerId }, 'Peer disconnected');\n }\n this.peers.clear();\n\n // Close server\n if (this.server) {\n logger.debug('Closing WebSocket server');\n await new Promise<void>((resolve) => {\n this.server!.close(() => {\n resolve();\n });\n });\n this.server = null;\n logger.debug('WebSocket server closed');\n }\n\n // Close HTTPS server if it exists\n if (this.httpsServer) {\n logger.debug('Closing HTTPS server');\n await new Promise<void>((resolve) => {\n this.httpsServer!.close(() => {\n resolve();\n });\n });\n this.httpsServer = null;\n logger.debug('HTTPS server closed');\n }\n\n // Remove status file\n this.removeStatusFile();\n\n logger.debug('Cleanup complete');\n }\n\n // ============================================================================\n // Status File Management\n // ============================================================================\n\n /**\n * Get the status file path\n */\n private getStatusFilePath(): string {\n const bridgeDir = path.join(os.homedir(), '.claude-bridge');\n return path.join(bridgeDir, 'status.json');\n }\n\n /**\n * Ensure the .claude-bridge directory exists\n */\n private 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 current status to status file\n */\n private writeStatusFile(): void {\n try {\n this.ensureBridgeDir();\n const statusFile = this.getStatusFilePath();\n const status = {\n port: this.config.listen?.port,\n instanceName: this.config.instanceName,\n mode: this.config.mode,\n peers: this.getPeers().map(p => ({\n id: p.id,\n name: p.name,\n connectedAt: new Date(p.connectedAt).toISOString(),\n lastActivity: new Date(p.lastActivity).toISOString(),\n })),\n };\n fs.writeFileSync(statusFile, JSON.stringify(status, null, 2), 'utf-8');\n logger.debug({ statusFile }, 'Status file updated');\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Failed to write status file');\n }\n }\n\n /**\n * Remove the status file\n */\n private removeStatusFile(): void {\n try {\n const statusFile = this.getStatusFilePath();\n if (fs.existsSync(statusFile)) {\n fs.unlinkSync(statusFile);\n logger.debug({ statusFile }, 'Status file removed');\n }\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Failed to remove status file');\n }\n }\n\n // ============================================================================\n // Getters for State Inspection\n // ============================================================================\n\n /**\n * Check if the bridge is started\n */\n isStarted(): boolean {\n return this.started;\n }\n\n /**\n * Get the instance name\n */\n getInstanceName(): string {\n return this.config.instanceName;\n }\n\n /**\n * Get the operation mode\n */\n getMode(): BridgeMode {\n return this.config.mode;\n }\n\n /**\n * Get the number of connected peers\n */\n getPeerCount(): number {\n return this.peers.size;\n }\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { parse as parseYaml } from 'yaml';\n\n/**\n * TLS configuration for secure connections\n */\nexport interface TLSConfig {\n /** Path to certificate PEM file */\n cert?: string;\n /** Path to private key PEM file */\n key?: string;\n /** Path to CA certificate PEM file */\n ca?: string;\n /** Whether to reject unauthorized certificates (default: true) */\n rejectUnauthorized?: boolean;\n /** Passphrase for encrypted private key */\n passphrase?: string;\n}\n\n/**\n * Authentication type\n */\nexport type AuthType = 'none' | 'token' | 'password' | 'ip' | 'combined';\n\n/**\n * Authentication configuration\n */\nexport interface AuthConfig {\n /** Authentication type */\n type: AuthType;\n /** Authentication token */\n token?: string;\n /** Authentication password */\n password?: string;\n /** Allowed IP addresses/ranges in CIDR notation */\n allowedIps?: string[];\n /** If true, ALL configured methods must pass; if false, ANY passing method is sufficient */\n requireAll?: boolean;\n}\n\n/**\n * Configuration for the bridge's listening socket\n */\nexport interface ListenConfig {\n port: number;\n host: string;\n /** TLS configuration for secure connections */\n tls?: TLSConfig;\n /** Authentication configuration */\n auth?: AuthConfig;\n}\n\n/**\n * Configuration for connecting to a remote bridge\n */\nexport interface ConnectConfig {\n url?: string;\n hostGateway?: boolean;\n port?: number;\n /** TLS configuration for secure connections */\n tls?: TLSConfig;\n /** Authentication configuration */\n auth?: AuthConfig;\n}\n\n/**\n * Configuration for context sharing behavior\n */\nexport interface ContextSharingConfig {\n autoSync: boolean;\n syncInterval: number;\n maxChunkTokens: number;\n includePatterns: string[];\n excludePatterns: string[];\n}\n\n/**\n * Configuration for interaction behavior\n */\nexport interface InteractionConfig {\n requireConfirmation: boolean;\n notifyOnActivity: boolean;\n taskTimeout: number;\n}\n\n/**\n * Full bridge configuration\n */\nexport interface BridgeConfig {\n instanceName?: string;\n mode?: 'host' | 'client' | 'peer';\n listen: ListenConfig;\n connect?: ConnectConfig;\n contextSharing: ContextSharingConfig;\n interaction: InteractionConfig;\n}\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_CONFIG: BridgeConfig = {\n listen: {\n port: 8765,\n host: '0.0.0.0',\n },\n contextSharing: {\n autoSync: true,\n syncInterval: 5000,\n maxChunkTokens: 4000,\n includePatterns: ['src/**/*.ts', 'src/**/*.tsx', '*.json'],\n excludePatterns: ['node_modules/**', 'dist/**', '.git/**'],\n },\n interaction: {\n requireConfirmation: false,\n notifyOnActivity: true,\n taskTimeout: 300000, // 5 minutes\n },\n};\n\n/**\n * Deep merges a partial config with the default config\n *\n * @param partial - Partial configuration to merge\n * @returns Complete configuration with defaults for missing values\n */\nexport function mergeConfig(partial: Partial<BridgeConfig>): BridgeConfig {\n return {\n ...DEFAULT_CONFIG,\n ...partial,\n listen: {\n ...DEFAULT_CONFIG.listen,\n ...(partial.listen ?? {}),\n },\n connect: partial.connect\n ? {\n ...partial.connect,\n }\n : undefined,\n contextSharing: {\n ...DEFAULT_CONFIG.contextSharing,\n ...(partial.contextSharing ?? {}),\n },\n interaction: {\n ...DEFAULT_CONFIG.interaction,\n ...(partial.interaction ?? {}),\n },\n };\n}\n\n/**\n * Attempts to read and parse a YAML config file\n *\n * @param filePath - Path to the config file\n * @returns Parsed config or null if file doesn't exist\n */\nfunction readConfigFile(filePath: string): Partial<BridgeConfig> | null {\n try {\n if (!fs.existsSync(filePath)) {\n return null;\n }\n const content = fs.readFileSync(filePath, 'utf-8');\n const parsed = parseYaml(content);\n return parsed as Partial<BridgeConfig>;\n } catch {\n // Return null if file can't be read or parsed\n return null;\n }\n}\n\n/**\n * Gets the default config file paths to search\n *\n * @returns Array of config file paths in priority order\n */\nfunction getDefaultConfigPaths(): string[] {\n const homeDir = os.homedir();\n const cwd = process.cwd();\n\n return [\n // Project-local config takes priority\n path.join(cwd, '.claude-bridge.yml'),\n path.join(cwd, '.claude-bridge.yaml'),\n // User home config as fallback\n path.join(homeDir, '.claude-bridge', 'config.yml'),\n path.join(homeDir, '.claude-bridge', 'config.yaml'),\n ];\n}\n\n/**\n * Loads configuration from file(s) and merges with defaults\n *\n * Searches for config files in the following order:\n * 1. Explicit path (if provided)\n * 2. .claude-bridge.yml in current working directory\n * 3. ~/.claude-bridge/config.yml\n *\n * @param configPath - Optional explicit path to config file\n * @returns Complete configuration with defaults for missing values\n *\n * @example\n * ```typescript\n * // Load from default locations\n * const config = await loadConfig();\n *\n * // Load from specific path\n * const config = await loadConfig('/path/to/config.yml');\n * ```\n */\nexport async function loadConfig(configPath?: string): Promise<BridgeConfig> {\n // If explicit path provided, try to load it\n if (configPath) {\n const parsed = readConfigFile(configPath);\n if (parsed) {\n return mergeConfig(parsed);\n }\n // If explicit path doesn't exist, return defaults\n return { ...DEFAULT_CONFIG };\n }\n\n // Search default paths\n const searchPaths = getDefaultConfigPaths();\n\n for (const searchPath of searchPaths) {\n const parsed = readConfigFile(searchPath);\n if (parsed) {\n return mergeConfig(parsed);\n }\n }\n\n // No config file found, return defaults\n return { ...DEFAULT_CONFIG };\n}\n\n/**\n * Synchronous version of loadConfig for simpler usage patterns\n *\n * @param configPath - Optional explicit path to config file\n * @returns Complete configuration with defaults for missing values\n */\nexport function loadConfigSync(configPath?: string): BridgeConfig {\n // If explicit path provided, try to load it\n if (configPath) {\n const parsed = readConfigFile(configPath);\n if (parsed) {\n return mergeConfig(parsed);\n }\n // If explicit path doesn't exist, return defaults\n return { ...DEFAULT_CONFIG };\n }\n\n // Search default paths\n const searchPaths = getDefaultConfigPaths();\n\n for (const searchPath of searchPaths) {\n const parsed = readConfigFile(searchPath);\n if (parsed) {\n return mergeConfig(parsed);\n }\n }\n\n // No config file found, return defaults\n return { ...DEFAULT_CONFIG };\n}\n","/**\n * MCP Tool definitions for Claude Code Bridge\n * Defines input schemas and handler functions for all bridge tools\n */\n\nimport { z } from 'zod';\nimport type { Bridge } from '../bridge/core.js';\nimport type { TaskResult } from '../bridge/protocol.js';\nimport { createLogger } from '../utils/logger.js';\n\nconst logger = createLogger('mcp:tools');\n\n// ============================================================================\n// Tool Input Schemas\n// ============================================================================\n\nexport const ReadFileInputSchema = z.object({\n path: z.string().describe('Path to the file to read'),\n});\n\nexport const WriteFileInputSchema = z.object({\n path: z.string().describe('Path to the file to write'),\n content: z.string().describe('Content to write to the file'),\n});\n\nexport const DeleteFileInputSchema = z.object({\n path: z.string().describe('Path to the file to delete'),\n});\n\nexport const ListDirectoryInputSchema = z.object({\n path: z.string().describe('Path to the directory to list'),\n});\n\nexport const DelegateTaskInputSchema = z.object({\n description: z.string().describe('Description of the task to delegate'),\n scope: z.enum(['execute', 'analyze', 'suggest']).describe('Task scope'),\n data: z.record(z.unknown()).optional().describe('Additional task data'),\n});\n\nexport const RequestContextInputSchema = z.object({\n query: z.string().describe('Query describing what files to retrieve'),\n});\n\n// ============================================================================\n// Tool Definitions\n// ============================================================================\n\nexport interface ToolDefinition {\n name: string;\n description: string;\n inputSchema: z.ZodType<unknown>;\n}\n\nexport const TOOL_DEFINITIONS: ToolDefinition[] = [\n {\n name: 'bridge_read_file',\n description: 'Read a file from the remote connected instance',\n inputSchema: ReadFileInputSchema,\n },\n {\n name: 'bridge_write_file',\n description: 'Write a file to the remote connected instance',\n inputSchema: WriteFileInputSchema,\n },\n {\n name: 'bridge_delete_file',\n description: 'Delete a file on the remote connected instance',\n inputSchema: DeleteFileInputSchema,\n },\n {\n name: 'bridge_list_directory',\n description: 'List files and folders in a directory on the remote connected instance',\n inputSchema: ListDirectoryInputSchema,\n },\n {\n name: 'bridge_delegate_task',\n description: 'Delegate a custom task to the remote connected instance',\n inputSchema: DelegateTaskInputSchema,\n },\n {\n name: 'bridge_request_context',\n description: 'Request files matching a query from the remote connected instance',\n inputSchema: RequestContextInputSchema,\n },\n {\n name: 'bridge_status',\n description: 'Get bridge status and connected peers',\n inputSchema: z.object({}),\n },\n];\n\n// ============================================================================\n// Tool Content Response Types\n// ============================================================================\n\nexport interface TextContent {\n type: 'text';\n text: string;\n}\n\nexport interface ToolResponse {\n content: TextContent[];\n isError?: boolean;\n}\n\n// ============================================================================\n// Tool Handlers\n// ============================================================================\n\n/**\n * Create tool handlers bound to a bridge instance\n */\nexport function createToolHandlers(bridge: Bridge) {\n const handlers: Record<string, (args: Record<string, unknown>) => Promise<ToolResponse>> = {};\n\n /**\n * Helper to create error response\n */\n function errorResponse(message: string): ToolResponse {\n return {\n content: [{ type: 'text', text: `Error: ${message}` }],\n isError: true,\n };\n }\n\n /**\n * Helper to create success response\n */\n function successResponse(text: string): ToolResponse {\n return {\n content: [{ type: 'text', text }],\n };\n }\n\n /**\n * Delegate a task and handle the result\n */\n async function delegateFileTask(\n action: string,\n data: Record<string, unknown>,\n description: string\n ): Promise<TaskResult> {\n const taskId = `mcp-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\n\n return bridge.delegateTask({\n id: taskId,\n description,\n scope: 'execute',\n data: { action, ...data },\n });\n }\n\n // bridge_read_file\n handlers['bridge_read_file'] = async (args) => {\n const input = ReadFileInputSchema.parse(args);\n logger.debug({ path: input.path }, 'Reading file');\n\n try {\n const result = await delegateFileTask(\n 'read_file',\n { path: input.path },\n `Read file: ${input.path}`\n );\n\n if (!result.success) {\n return errorResponse(result.error || 'Failed to read file');\n }\n\n return successResponse(result.data.content);\n } catch (err) {\n logger.error({ error: (err as Error).message, path: input.path }, 'Failed to read file');\n return errorResponse((err as Error).message);\n }\n };\n\n // bridge_write_file\n handlers['bridge_write_file'] = async (args) => {\n const input = WriteFileInputSchema.parse(args);\n logger.debug({ path: input.path, contentLength: input.content.length }, 'Writing file');\n\n try {\n const result = await delegateFileTask(\n 'write_file',\n { path: input.path, content: input.content },\n `Write file: ${input.path}`\n );\n\n if (!result.success) {\n return errorResponse(result.error || 'Failed to write file');\n }\n\n return successResponse(`File written successfully: ${input.path} (${result.data.bytesWritten} bytes)`);\n } catch (err) {\n logger.error({ error: (err as Error).message, path: input.path }, 'Failed to write file');\n return errorResponse((err as Error).message);\n }\n };\n\n // bridge_delete_file\n handlers['bridge_delete_file'] = async (args) => {\n const input = DeleteFileInputSchema.parse(args);\n logger.debug({ path: input.path }, 'Deleting file');\n\n try {\n const result = await delegateFileTask(\n 'delete_file',\n { path: input.path },\n `Delete file: ${input.path}`\n );\n\n if (!result.success) {\n return errorResponse(result.error || 'Failed to delete file');\n }\n\n return successResponse(`File deleted successfully: ${input.path}`);\n } catch (err) {\n logger.error({ error: (err as Error).message, path: input.path }, 'Failed to delete file');\n return errorResponse((err as Error).message);\n }\n };\n\n // bridge_list_directory\n handlers['bridge_list_directory'] = async (args) => {\n const input = ListDirectoryInputSchema.parse(args);\n logger.debug({ path: input.path }, 'Listing directory');\n\n try {\n const result = await delegateFileTask(\n 'list_directory',\n { path: input.path },\n `List directory: ${input.path}`\n );\n\n if (!result.success) {\n return errorResponse(result.error || 'Failed to list directory');\n }\n\n // Format directory listing\n const entries = result.data.entries as Array<{ name: string; type: string }>;\n if (!entries || entries.length === 0) {\n return successResponse(`Directory is empty: ${input.path}`);\n }\n\n const listing = entries\n .map((e: { name: string; type: string }) => `${e.type === 'directory' ? '📁' : '📄'} ${e.name}`)\n .join('\\n');\n\n return successResponse(`Contents of ${input.path}:\\n${listing}`);\n } catch (err) {\n logger.error({ error: (err as Error).message, path: input.path }, 'Failed to list directory');\n return errorResponse((err as Error).message);\n }\n };\n\n // bridge_delegate_task\n handlers['bridge_delegate_task'] = async (args) => {\n const input = DelegateTaskInputSchema.parse(args);\n logger.debug({ description: input.description, scope: input.scope }, 'Delegating task');\n\n try {\n const taskId = `mcp-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\n\n const result = await bridge.delegateTask({\n id: taskId,\n description: input.description,\n scope: input.scope,\n data: input.data,\n });\n\n if (!result.success) {\n return errorResponse(result.error || 'Task failed');\n }\n\n return successResponse(JSON.stringify(result.data, null, 2));\n } catch (err) {\n logger.error({ error: (err as Error).message }, 'Failed to delegate task');\n return errorResponse((err as Error).message);\n }\n };\n\n // bridge_request_context\n handlers['bridge_request_context'] = async (args) => {\n const input = RequestContextInputSchema.parse(args);\n logger.debug({ query: input.query }, 'Requesting context');\n\n try {\n const files = await bridge.requestContext(input.query);\n\n if (files.length === 0) {\n return successResponse('No files found matching the query.');\n }\n\n // Format file results\n const fileResults = files.map(f => {\n const header = `=== ${f.path} ===`;\n const content = f.content;\n return `${header}\\n${content}`;\n }).join('\\n\\n');\n\n return successResponse(`Found ${files.length} file(s):\\n\\n${fileResults}`);\n } catch (err) {\n logger.error({ error: (err as Error).message }, 'Failed to request context');\n return errorResponse((err as Error).message);\n }\n };\n\n // bridge_status\n handlers['bridge_status'] = async () => {\n logger.debug('Getting bridge status');\n\n const peers = bridge.getPeers();\n const peerCount = bridge.getPeerCount();\n const isStarted = bridge.isStarted();\n const mode = bridge.getMode();\n const instanceName = bridge.getInstanceName();\n\n const status = {\n instanceName,\n mode,\n started: isStarted,\n peerCount,\n peers: peers.map(p => ({\n id: p.id,\n name: p.name,\n connectedAt: new Date(p.connectedAt).toISOString(),\n lastActivity: new Date(p.lastActivity).toISOString(),\n })),\n };\n\n return successResponse(JSON.stringify(status, null, 2));\n };\n\n return handlers;\n}\n\n/**\n * Get JSON schema representation for a Zod schema\n * This creates a simple JSON schema object for MCP tool registration\n */\nexport function zodToJsonSchema(schema: z.ZodType<unknown>): Record<string, unknown> {\n // Handle ZodObject\n if (schema instanceof z.ZodObject) {\n const shape = schema.shape;\n const properties: Record<string, unknown> = {};\n const required: string[] = [];\n\n for (const [key, value] of Object.entries(shape)) {\n const zodValue = value as z.ZodType<unknown>;\n properties[key] = zodToJsonSchema(zodValue);\n\n // Check if required (not optional)\n if (!(zodValue instanceof z.ZodOptional)) {\n required.push(key);\n }\n }\n\n return {\n type: 'object',\n properties,\n ...(required.length > 0 ? { required } : {}),\n };\n }\n\n // Handle ZodString\n if (schema instanceof z.ZodString) {\n const result: Record<string, unknown> = { type: 'string' };\n if (schema.description) {\n result.description = schema.description;\n }\n return result;\n }\n\n // Handle ZodEnum\n if (schema instanceof z.ZodEnum) {\n return {\n type: 'string',\n enum: schema.options,\n };\n }\n\n // Handle ZodOptional\n if (schema instanceof z.ZodOptional) {\n return zodToJsonSchema(schema.unwrap());\n }\n\n // Handle ZodRecord\n if (schema instanceof z.ZodRecord) {\n return {\n type: 'object',\n additionalProperties: true,\n };\n }\n\n // Handle ZodUnknown\n if (schema instanceof z.ZodUnknown) {\n return {};\n }\n\n // Default fallback\n return { type: 'string' };\n}\n","/**\n * MCP Server for Claude Code Bridge\n * Exposes bridge functionality as MCP tools for Claude Code integration\n */\n\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n type CallToolResult,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { Bridge, type BridgeConfig } from '../bridge/core.js';\nimport { createLogger } from '../utils/logger.js';\nimport type { TLSConfig, AuthConfig } from '../transport/interface.js';\nimport {\n TOOL_DEFINITIONS,\n createToolHandlers,\n zodToJsonSchema,\n} from './tools.js';\n\nconst logger = createLogger('mcp:server');\n\n// ============================================================================\n// MCP Server Configuration\n// ============================================================================\n\nexport interface McpServerConfig {\n /** Bridge WebSocket URL to connect to */\n bridgeUrl: string;\n /** MCP server name (default: claude-bridge) */\n name?: string;\n /** MCP server version */\n version?: string;\n /** Instance name for the bridge client */\n instanceName?: string;\n /** Task timeout in milliseconds */\n taskTimeout?: number;\n /** TLS configuration for secure connections */\n tls?: TLSConfig;\n /** Authentication configuration */\n auth?: AuthConfig;\n}\n\n// ============================================================================\n// Bridge MCP Server\n// ============================================================================\n\n/**\n * MCP Server that exposes bridge functionality as tools\n */\nexport class BridgeMcpServer {\n private server: Server;\n private bridge: Bridge;\n private config: McpServerConfig;\n private toolHandlers: ReturnType<typeof createToolHandlers> | null = null;\n\n constructor(config: McpServerConfig) {\n this.config = config;\n\n // Create MCP server\n this.server = new Server(\n {\n name: config.name ?? 'claude-bridge',\n version: config.version ?? '0.4.0',\n },\n {\n capabilities: {\n tools: {},\n },\n }\n );\n\n // Create bridge client to connect to daemon\n const bridgeConfig: BridgeConfig = {\n mode: 'client',\n instanceName: config.instanceName ?? `mcp-server-${process.pid}`,\n connect: {\n url: config.bridgeUrl,\n tls: config.tls,\n auth: config.auth,\n },\n taskTimeout: config.taskTimeout ?? 60000,\n };\n\n this.bridge = new Bridge(bridgeConfig);\n\n this.registerHandlers();\n }\n\n /**\n * Register MCP request handlers\n */\n private registerHandlers(): void {\n // List tools handler\n this.server.setRequestHandler(ListToolsRequestSchema, async () => {\n logger.debug('Listing tools');\n\n return {\n tools: TOOL_DEFINITIONS.map(tool => ({\n name: tool.name,\n description: tool.description,\n inputSchema: zodToJsonSchema(tool.inputSchema),\n })),\n };\n });\n\n // Call tool handler\n this.server.setRequestHandler(CallToolRequestSchema, async (request): Promise<CallToolResult> => {\n const { name, arguments: args } = request.params;\n logger.debug({ tool: name }, 'Tool call received');\n\n // Ensure tool handlers are created\n if (!this.toolHandlers) {\n this.toolHandlers = createToolHandlers(this.bridge);\n }\n\n const handler = this.toolHandlers[name];\n if (!handler) {\n logger.warn({ tool: name }, 'Unknown tool requested');\n return {\n content: [{ type: 'text', text: `Unknown tool: ${name}` }],\n isError: true,\n };\n }\n\n try {\n const result = await handler(args ?? {});\n logger.debug({ tool: name, isError: result.isError }, 'Tool call completed');\n return {\n content: result.content,\n isError: result.isError,\n };\n } catch (err) {\n logger.error({ tool: name, error: (err as Error).message }, 'Tool call failed');\n return {\n content: [{ type: 'text', text: `Error: ${(err as Error).message}` }],\n isError: true,\n };\n }\n });\n }\n\n /**\n * Start the MCP server\n * Connects to bridge daemon and starts listening on stdio\n */\n async start(): Promise<void> {\n // Log to stderr since stdout is for MCP protocol\n console.error('[MCP] Starting bridge MCP server...');\n console.error(`[MCP] Connecting to bridge at ${this.config.bridgeUrl}`);\n\n try {\n // Connect to bridge daemon\n await this.bridge.start();\n console.error('[MCP] Connected to bridge daemon');\n\n // Create tool handlers after bridge is connected\n this.toolHandlers = createToolHandlers(this.bridge);\n\n // Start MCP server on stdio\n const transport = new StdioServerTransport();\n await this.server.connect(transport);\n\n console.error('[MCP] MCP server started and listening on stdio');\n logger.info('MCP server started');\n } catch (err) {\n console.error(`[MCP] Failed to start: ${(err as Error).message}`);\n throw err;\n }\n }\n\n /**\n * Stop the MCP server\n */\n async stop(): Promise<void> {\n console.error('[MCP] Stopping MCP server...');\n\n try {\n await this.bridge.stop();\n await this.server.close();\n console.error('[MCP] MCP server stopped');\n logger.info('MCP server stopped');\n } catch (err) {\n console.error(`[MCP] Error during shutdown: ${(err as Error).message}`);\n }\n }\n\n /**\n * Get the bridge instance\n */\n getBridge(): Bridge {\n return this.bridge;\n }\n}\n\n/**\n * Create and start an MCP server\n */\nexport async function startMcpServer(config: McpServerConfig): Promise<BridgeMcpServer> {\n const server = new BridgeMcpServer(config);\n await server.start();\n return server;\n}\n"],"mappings":"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","names":["ConnectionState","logger","logger","https","uuidv4","fs","logger","uuidv4","peer","fs","path","os","z","logger","z","logger"]}
1
+ {"version":3,"sources":["../src/utils/logger.ts","../src/bridge/protocol.ts","../src/transport/interface.ts","../src/utils/tls.ts","../src/transport/websocket.ts","../src/utils/auth.ts","../src/bridge/messages.ts","../src/bridge/core.ts","../src/utils/config.ts","../src/mcp/tools.ts","../src/mcp/server.ts"],"sourcesContent":["import pino from 'pino';\n\n/**\n * Log levels supported by the logger\n */\nexport type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';\n\n/**\n * Logger interface (subset of pino.Logger for public API)\n */\nexport type Logger = pino.Logger;\n\n/**\n * Determines if pretty printing should be used.\n * Only enabled when NODE_ENV is explicitly set to 'development'\n * to avoid errors when pino-pretty (a dev dependency) isn't installed.\n */\nfunction usePrettyPrint(): boolean {\n return process.env.NODE_ENV === 'development';\n}\n\n/**\n * Gets the default log level from environment or falls back to 'info'\n */\nfunction getDefaultLevel(): LogLevel {\n const envLevel = process.env.LOG_LEVEL?.toLowerCase() as LogLevel | undefined;\n const validLevels: LogLevel[] = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'];\n if (envLevel && validLevels.includes(envLevel)) {\n return envLevel;\n }\n return 'info';\n}\n\n/**\n * Creates a logger instance with the given component name\n *\n * @param name - Component name to include in log output\n * @param level - Optional log level override (defaults to LOG_LEVEL env var or 'info')\n * @returns A pino logger instance configured for the component\n *\n * @example\n * ```typescript\n * const logger = createLogger('bridge');\n * logger.info('Bridge started');\n * logger.error({ err }, 'Connection failed');\n * ```\n */\nexport function createLogger(name: string, level?: LogLevel): Logger {\n const logLevel = level ?? getDefaultLevel();\n\n const options: pino.LoggerOptions = {\n name,\n level: logLevel,\n };\n\n // Use pretty printing only when explicitly in development mode\n if (usePrettyPrint()) {\n options.transport = {\n target: 'pino-pretty',\n options: {\n colorize: true,\n translateTime: 'SYS:standard',\n ignore: 'pid,hostname',\n },\n };\n }\n\n return pino(options);\n}\n\n/**\n * Creates a child logger from an existing logger with additional context\n *\n * @param parent - Parent logger instance\n * @param bindings - Additional context to include in all log messages\n * @returns A child logger instance\n */\nexport function createChildLogger(parent: Logger, bindings: Record<string, unknown>): Logger {\n return parent.child(bindings);\n}\n","/**\n * Protocol definitions for Claude Code Bridge\n * Defines message types, schemas, and serialization utilities\n */\n\nimport { z } from 'zod';\nimport { v4 as uuidv4 } from 'uuid';\n\n// ============================================================================\n// Message Type Enum\n// ============================================================================\n\nexport const MessageType = z.enum([\n 'request',\n 'response',\n 'context_sync',\n 'task_delegate',\n 'notification',\n]);\n\nexport type MessageType = z.infer<typeof MessageType>;\n\n// ============================================================================\n// File and Directory Schemas\n// ============================================================================\n\nexport const FileChunkSchema = z.object({\n path: z.string(),\n content: z.string(),\n startLine: z.number().optional(),\n endLine: z.number().optional(),\n language: z.string().optional(),\n});\n\nexport type FileChunk = z.infer<typeof FileChunkSchema>;\n\nexport const DirectoryTreeSchema: z.ZodType<DirectoryTree> = z.lazy(() =>\n z.object({\n name: z.string(),\n type: z.enum(['file', 'directory']),\n children: z.array(DirectoryTreeSchema).optional(),\n })\n);\n\nexport interface DirectoryTree {\n name: string;\n type: 'file' | 'directory';\n children?: DirectoryTree[];\n}\n\n// ============================================================================\n// Artifact Schema\n// ============================================================================\n\nexport const ArtifactSchema = z.object({\n path: z.string(),\n action: z.enum(['created', 'modified', 'deleted']),\n diff: z.string().optional(),\n});\n\nexport type Artifact = z.infer<typeof ArtifactSchema>;\n\n// ============================================================================\n// Context Schema\n// ============================================================================\n\nexport const ContextSchema = z.object({\n files: z.array(FileChunkSchema).optional(),\n tree: DirectoryTreeSchema.optional(),\n summary: z.string().optional(),\n variables: z.record(z.any()).optional(),\n});\n\nexport type Context = z.infer<typeof ContextSchema>;\n\n// ============================================================================\n// Task Request Schema\n// ============================================================================\n\nexport const TaskRequestSchema = z.object({\n id: z.string(),\n description: z.string(),\n scope: z.enum(['execute', 'analyze', 'suggest']),\n constraints: z.array(z.string()).optional(),\n returnFormat: z.enum(['full', 'summary', 'diff']).optional(),\n timeout: z.number().optional(),\n data: z.record(z.unknown()).optional(),\n});\n\nexport type TaskRequest = z.infer<typeof TaskRequestSchema>;\n\n// ============================================================================\n// Task Result Schema\n// ============================================================================\n\nexport const TaskResultSchema = z.object({\n taskId: z.string().optional(),\n success: z.boolean(),\n data: z.any(),\n artifacts: z.array(ArtifactSchema).optional(),\n followUp: z.string().optional(),\n error: z.string().optional(),\n});\n\nexport type TaskResult = z.infer<typeof TaskResultSchema>;\n\n// ============================================================================\n// Bridge Message Schema\n// ============================================================================\n\nexport const BridgeMessageSchema = z.object({\n id: z.string().uuid(),\n type: MessageType,\n source: z.string(),\n timestamp: z.number(),\n context: ContextSchema.optional(),\n task: TaskRequestSchema.optional(),\n result: TaskResultSchema.optional(),\n});\n\nexport type BridgeMessage = z.infer<typeof BridgeMessageSchema>;\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Creates a base message with auto-generated UUID and timestamp\n * @param type The message type\n * @param source The source instance identifier\n * @returns A partial BridgeMessage with id, type, source, and timestamp\n */\nexport function createMessage(\n type: MessageType,\n source: string\n): BridgeMessage {\n return {\n id: uuidv4(),\n type,\n source,\n timestamp: Date.now(),\n };\n}\n\n/**\n * Validates a message against the BridgeMessage schema\n * @param data The data to validate\n * @returns The validated BridgeMessage or throws if invalid\n */\nexport function validateMessage(data: unknown): BridgeMessage {\n return BridgeMessageSchema.parse(data);\n}\n\n/**\n * Safe validation that returns a result object instead of throwing\n * @param data The data to validate\n * @returns A Zod SafeParseReturnType with success/error information\n */\nexport function safeValidateMessage(data: unknown) {\n return BridgeMessageSchema.safeParse(data);\n}\n\n/**\n * Serializes a BridgeMessage to JSON string\n * @param message The message to serialize\n * @returns JSON string representation\n */\nexport function serializeMessage(message: BridgeMessage): string {\n return JSON.stringify(message);\n}\n\n/**\n * Deserializes a JSON string to a validated BridgeMessage\n * @param json The JSON string to deserialize\n * @returns The validated BridgeMessage\n * @throws Error if JSON is invalid or message doesn't match schema\n */\nexport function deserializeMessage(json: string): BridgeMessage {\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch {\n throw new Error('Invalid JSON');\n }\n return validateMessage(parsed);\n}\n\n/**\n * Safe deserialization that returns a result object instead of throwing\n * @param json The JSON string to deserialize\n * @returns A Zod SafeParseReturnType with success/error information\n */\nexport function safeDeserializeMessage(json: string) {\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch {\n return {\n success: false as const,\n error: new z.ZodError([\n {\n code: 'custom',\n message: 'Invalid JSON',\n path: [],\n },\n ]),\n };\n }\n return BridgeMessageSchema.safeParse(parsed);\n}\n","/**\n * Transport layer interface and types for Claude Code Bridge\n * Defines the abstract transport interface for communication between bridge instances\n */\n\nimport type { BridgeMessage } from '../bridge/protocol.js';\n\n// ============================================================================\n// Connection State Enum\n// ============================================================================\n\n/**\n * Represents the current state of a transport connection\n */\nexport enum ConnectionState {\n /** Not connected to any peer */\n DISCONNECTED = 'DISCONNECTED',\n /** Currently attempting to establish connection */\n CONNECTING = 'CONNECTING',\n /** Successfully connected and ready for communication */\n CONNECTED = 'CONNECTED',\n /** Connection lost, attempting to reconnect */\n RECONNECTING = 'RECONNECTING',\n}\n\n// ============================================================================\n// TLS Configuration\n// ============================================================================\n\n/**\n * TLS configuration for secure connections\n */\nexport interface TLSConfig {\n /** Path to certificate PEM file (for server) */\n cert?: string;\n /** Path to private key PEM file (for server) */\n key?: string;\n /** Path to CA certificate PEM file (for client to verify server, or server to verify client) */\n ca?: string;\n /** Whether to reject unauthorized certificates (default: true) */\n rejectUnauthorized?: boolean;\n /** Passphrase for encrypted private key */\n passphrase?: string;\n}\n\n// ============================================================================\n// Connection Configuration\n// ============================================================================\n\n/**\n * Authentication type\n */\nexport type AuthType = 'none' | 'token' | 'password' | 'ip' | 'combined';\n\n/**\n * Authentication configuration for transport connections\n */\nexport interface AuthConfig {\n /** Authentication type */\n type: AuthType;\n /** Authentication token (for type: 'token' or 'combined') */\n token?: string;\n /** Authentication password (for type: 'password' or 'combined') */\n password?: string;\n /** Allowed IP addresses/ranges in CIDR notation (for type: 'ip' or 'combined') */\n allowedIps?: string[];\n /** If true, ALL configured methods must pass; if false, ANY passing method is sufficient */\n requireAll?: boolean;\n}\n\n/**\n * Configuration for establishing a transport connection\n */\nexport interface ConnectionConfig {\n /** Full WebSocket URL (e.g., ws://localhost:8765 or wss://localhost:8765) */\n url?: string;\n /** Host to connect to (used if url is not provided) */\n host?: string;\n /** Port to connect to (used if url is not provided) */\n port?: number;\n /** Enable automatic reconnection on disconnect */\n reconnect?: boolean;\n /** Interval between reconnection attempts in milliseconds */\n reconnectInterval?: number;\n /** Maximum number of reconnection attempts before giving up */\n maxReconnectAttempts?: number;\n /** Authentication configuration */\n auth?: AuthConfig;\n /** TLS configuration for secure connections */\n tls?: TLSConfig;\n}\n\n// ============================================================================\n// Event Handler Types\n// ============================================================================\n\n/**\n * Handler for incoming messages\n */\nexport type MessageHandler = (message: BridgeMessage) => void;\n\n/**\n * Handler for disconnect events\n */\nexport type DisconnectHandler = () => void;\n\n/**\n * Handler for error events\n */\nexport type ErrorHandler = (error: Error) => void;\n\n// ============================================================================\n// Transport Interface\n// ============================================================================\n\n/**\n * Abstract transport interface for bridge communication\n * Implementations handle the actual network protocol (WebSocket, TCP, etc.)\n */\nexport interface Transport {\n /**\n * Establish connection to a remote peer\n * @param config Connection configuration\n * @returns Promise that resolves when connection is established\n * @throws Error if connection fails\n */\n connect(config: ConnectionConfig): Promise<void>;\n\n /**\n * Cleanly close the current connection\n * @returns Promise that resolves when disconnection is complete\n */\n disconnect(): Promise<void>;\n\n /**\n * Send a message to the connected peer\n * @param message The message to send\n * @returns Promise that resolves when message is sent\n * @throws Error if not connected and message cannot be queued\n */\n send(message: BridgeMessage): Promise<void>;\n\n /**\n * Register a handler for incoming messages\n * @param handler Function to call when a message is received\n */\n onMessage(handler: MessageHandler): void;\n\n /**\n * Register a handler for disconnect events\n * @param handler Function to call when connection is lost\n */\n onDisconnect(handler: DisconnectHandler): void;\n\n /**\n * Register a handler for error events\n * @param handler Function to call when an error occurs\n */\n onError(handler: ErrorHandler): void;\n\n /**\n * Check if the transport is currently connected\n * @returns true if connected, false otherwise\n */\n isConnected(): boolean;\n\n /**\n * Get the current connection state\n * @returns The current ConnectionState\n */\n getState(): ConnectionState;\n}\n\n// ============================================================================\n// Transport Events (for EventEmitter pattern)\n// ============================================================================\n\n/**\n * Transport event types for EventEmitter-based implementations\n */\nexport interface TransportEvents {\n /** Emitted when a message is received */\n message: BridgeMessage;\n /** Emitted when connection is established */\n connect: void;\n /** Emitted when connection is closed */\n disconnect: void;\n /** Emitted when an error occurs */\n error: Error;\n /** Emitted when reconnection is attempted */\n reconnecting: { attempt: number; maxAttempts: number };\n}\n","/**\n * TLS utilities for Claude Code Bridge\n * Handles loading and validating TLS certificates for secure WebSocket connections\n */\n\nimport * as fs from 'fs';\nimport * as tls from 'tls';\nimport { createLogger } from './logger.js';\n\nconst logger = createLogger('tls');\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\n/**\n * TLS configuration for secure connections\n */\nexport interface TLSConfig {\n /** Path to certificate PEM file */\n cert?: string;\n /** Path to private key PEM file */\n key?: string;\n /** Path to CA certificate PEM file (for verifying client certs or self-signed server certs) */\n ca?: string;\n /** Whether to reject unauthorized certificates (default: true) */\n rejectUnauthorized?: boolean;\n /** Passphrase for encrypted private key */\n passphrase?: string;\n}\n\n/**\n * Result of TLS configuration validation\n */\nexport interface TLSValidationResult {\n /** Whether the configuration is valid */\n valid: boolean;\n /** List of validation errors */\n errors: string[];\n /** List of validation warnings */\n warnings: string[];\n}\n\n/**\n * Loaded TLS options ready for use with https/tls modules\n */\nexport interface LoadedTLSOptions {\n /** Certificate content */\n cert?: string | Buffer;\n /** Private key content */\n key?: string | Buffer;\n /** CA certificate content */\n ca?: string | Buffer;\n /** Whether to reject unauthorized certificates */\n rejectUnauthorized?: boolean;\n /** Passphrase for encrypted private key */\n passphrase?: string;\n}\n\n// ============================================================================\n// Certificate Loading\n// ============================================================================\n\n/**\n * Read a certificate or key file\n * @param filePath - Path to the file\n * @returns File contents as string\n * @throws Error if file cannot be read\n */\nfunction readCertFile(filePath: string): string {\n try {\n return fs.readFileSync(filePath, 'utf-8');\n } catch (error) {\n const err = error as NodeJS.ErrnoException;\n if (err.code === 'ENOENT') {\n throw new Error(`Certificate file not found: ${filePath}`);\n }\n if (err.code === 'EACCES') {\n throw new Error(`Permission denied reading certificate file: ${filePath}`);\n }\n throw new Error(`Failed to read certificate file ${filePath}: ${err.message}`);\n }\n}\n\n/**\n * Load TLS certificates from file paths\n * @param config - TLS configuration with file paths\n * @returns TLS options ready for use with https/tls modules\n * @throws Error if required certificates cannot be loaded\n */\nexport async function loadCertificates(config: TLSConfig): Promise<LoadedTLSOptions> {\n const options: LoadedTLSOptions = {};\n\n // Load certificate\n if (config.cert) {\n logger.debug({ path: config.cert }, 'Loading certificate');\n options.cert = readCertFile(config.cert);\n }\n\n // Load private key\n if (config.key) {\n logger.debug({ path: config.key }, 'Loading private key');\n options.key = readCertFile(config.key);\n }\n\n // Load CA certificate\n if (config.ca) {\n logger.debug({ path: config.ca }, 'Loading CA certificate');\n options.ca = readCertFile(config.ca);\n }\n\n // Set reject unauthorized (default: true)\n options.rejectUnauthorized = config.rejectUnauthorized ?? true;\n\n // Set passphrase if provided\n if (config.passphrase) {\n options.passphrase = config.passphrase;\n }\n\n logger.info(\n {\n hasCert: !!options.cert,\n hasKey: !!options.key,\n hasCa: !!options.ca,\n rejectUnauthorized: options.rejectUnauthorized,\n },\n 'TLS certificates loaded'\n );\n\n return options;\n}\n\n/**\n * Synchronous version of loadCertificates\n * @param config - TLS configuration with file paths\n * @returns TLS options ready for use with https/tls modules\n * @throws Error if required certificates cannot be loaded\n */\nexport function loadCertificatesSync(config: TLSConfig): LoadedTLSOptions {\n const options: LoadedTLSOptions = {};\n\n // Load certificate\n if (config.cert) {\n options.cert = readCertFile(config.cert);\n }\n\n // Load private key\n if (config.key) {\n options.key = readCertFile(config.key);\n }\n\n // Load CA certificate\n if (config.ca) {\n options.ca = readCertFile(config.ca);\n }\n\n // Set reject unauthorized (default: true)\n options.rejectUnauthorized = config.rejectUnauthorized ?? true;\n\n // Set passphrase if provided\n if (config.passphrase) {\n options.passphrase = config.passphrase;\n }\n\n return options;\n}\n\n// ============================================================================\n// Validation\n// ============================================================================\n\n/**\n * Check if a file exists and is readable\n * @param filePath - Path to check\n * @returns true if file exists and is readable\n */\nfunction isFileReadable(filePath: string): boolean {\n try {\n fs.accessSync(filePath, fs.constants.R_OK);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Validate TLS configuration\n * @param config - TLS configuration to validate\n * @returns Validation result with errors and warnings\n */\nexport function validateTLSConfig(config: TLSConfig): TLSValidationResult {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n // Check for server configuration (cert + key required together)\n if (config.cert && !config.key) {\n errors.push('Certificate provided without private key');\n }\n if (config.key && !config.cert) {\n errors.push('Private key provided without certificate');\n }\n\n // Validate file paths exist and are readable\n if (config.cert) {\n if (!isFileReadable(config.cert)) {\n errors.push(`Certificate file not readable: ${config.cert}`);\n }\n }\n\n if (config.key) {\n if (!isFileReadable(config.key)) {\n errors.push(`Private key file not readable: ${config.key}`);\n }\n }\n\n if (config.ca) {\n if (!isFileReadable(config.ca)) {\n errors.push(`CA certificate file not readable: ${config.ca}`);\n }\n }\n\n // Warn about disabled certificate verification\n if (config.rejectUnauthorized === false) {\n warnings.push('TLS certificate verification is disabled - this is insecure for production use');\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\n/**\n * Check if TLS is enabled in the configuration\n * @param config - TLS configuration to check\n * @returns true if TLS should be enabled (cert and key both provided)\n */\nexport function isTLSEnabled(config?: TLSConfig): boolean {\n if (!config) {\n return false;\n }\n return !!(config.cert && config.key);\n}\n\n/**\n * Create TLS secure context options for Node.js tls module\n * @param loaded - Loaded TLS options\n * @returns Options for tls.createSecureContext\n */\nexport function createSecureContextOptions(loaded: LoadedTLSOptions): tls.SecureContextOptions {\n const options: tls.SecureContextOptions = {};\n\n if (loaded.cert) {\n options.cert = loaded.cert;\n }\n if (loaded.key) {\n options.key = loaded.key;\n }\n if (loaded.ca) {\n options.ca = loaded.ca;\n }\n if (loaded.passphrase) {\n options.passphrase = loaded.passphrase;\n }\n\n return options;\n}\n","/**\n * WebSocket Transport implementation for Claude Code Bridge\n * Provides WebSocket-based communication between bridge instances\n */\n\nimport WebSocket from 'ws';\nimport * as https from 'https';\nimport type { BridgeMessage } from '../bridge/protocol.js';\nimport { serializeMessage, safeDeserializeMessage } from '../bridge/protocol.js';\nimport {\n ConnectionState,\n type ConnectionConfig,\n type Transport,\n type MessageHandler,\n type DisconnectHandler,\n type ErrorHandler,\n} from './interface.js';\nimport { createLogger } from '../utils/logger.js';\nimport { loadCertificatesSync, type LoadedTLSOptions } from '../utils/tls.js';\n\nconst logger = createLogger('websocket-transport');\n\n/** Default reconnection interval in milliseconds */\nconst DEFAULT_RECONNECT_INTERVAL = 1000;\n\n/** Default maximum reconnection attempts */\nconst DEFAULT_MAX_RECONNECT_ATTEMPTS = 10;\n\n/** Default heartbeat interval in milliseconds */\nconst DEFAULT_HEARTBEAT_INTERVAL = 30000;\n\n/** Heartbeat timeout - how long to wait for pong response */\nconst HEARTBEAT_TIMEOUT = 10000;\n\n/**\n * WebSocket-based transport implementation\n * Handles connection lifecycle, message sending/receiving, and event handling\n * Supports auto-reconnection, message queuing, and heartbeat monitoring\n */\nexport class WebSocketTransport implements Transport {\n private ws: WebSocket | null = null;\n private state: ConnectionState = ConnectionState.DISCONNECTED;\n private config: ConnectionConfig | null = null;\n\n // Reconnection state\n private reconnectAttempts: number = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private intentionalDisconnect: boolean = false;\n\n // Message queue for offline messages\n private messageQueue: BridgeMessage[] = [];\n\n // Heartbeat state\n private heartbeatInterval: ReturnType<typeof setInterval> | null = null;\n private heartbeatTimeout: ReturnType<typeof setTimeout> | null = null;\n private awaitingPong: boolean = false;\n\n // Event handlers\n private messageHandlers: MessageHandler[] = [];\n private disconnectHandlers: DisconnectHandler[] = [];\n private errorHandlers: ErrorHandler[] = [];\n private reconnectingHandlers: Array<(attempt: number, maxAttempts: number) => void> = [];\n\n /**\n * Build the WebSocket URL from the connection configuration\n * Uses wss:// if TLS is configured, ws:// otherwise\n */\n private buildUrl(config: ConnectionConfig): string {\n if (config.url) {\n // If URL provided, use it directly (may already be wss://)\n return config.url;\n }\n\n const host = config.host ?? 'localhost';\n const port = config.port ?? 8765;\n\n // Use wss:// if TLS config has CA cert (client wants to verify server)\n // or if rejectUnauthorized is explicitly set\n const useTls = config.tls?.ca || config.tls?.rejectUnauthorized !== undefined;\n const protocol = useTls ? 'wss' : 'ws';\n\n return `${protocol}://${host}:${port}`;\n }\n\n /**\n * Build WebSocket options including TLS and auth configuration\n */\n private buildWsOptions(config: ConnectionConfig): WebSocket.ClientOptions {\n const options: WebSocket.ClientOptions = {};\n\n // Add TLS options if configured\n if (config.tls) {\n try {\n const tlsOptions = loadCertificatesSync(config.tls);\n\n // Create HTTPS agent with TLS options\n const agentOptions: https.AgentOptions = {\n rejectUnauthorized: tlsOptions.rejectUnauthorized ?? true,\n };\n\n if (tlsOptions.ca) {\n agentOptions.ca = tlsOptions.ca;\n }\n if (tlsOptions.cert) {\n agentOptions.cert = tlsOptions.cert;\n }\n if (tlsOptions.key) {\n agentOptions.key = tlsOptions.key;\n }\n if (tlsOptions.passphrase) {\n agentOptions.passphrase = tlsOptions.passphrase;\n }\n\n options.agent = new https.Agent(agentOptions);\n\n // Also set these directly for older ws versions\n if (tlsOptions.rejectUnauthorized !== undefined) {\n options.rejectUnauthorized = tlsOptions.rejectUnauthorized;\n }\n if (tlsOptions.ca) {\n options.ca = tlsOptions.ca;\n }\n\n logger.debug(\n { hasCa: !!tlsOptions.ca, rejectUnauthorized: tlsOptions.rejectUnauthorized },\n 'TLS options configured for client'\n );\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Failed to load TLS certificates');\n throw error;\n }\n }\n\n // Add auth headers if configured\n if (config.auth && config.auth.type !== 'none') {\n options.headers = options.headers || {};\n\n if (config.auth.token) {\n options.headers['Authorization'] = `Bearer ${config.auth.token}`;\n }\n if (config.auth.password) {\n options.headers['X-Auth-Password'] = config.auth.password;\n }\n\n logger.debug(\n { hasToken: !!config.auth.token, hasPassword: !!config.auth.password },\n 'Auth headers configured'\n );\n }\n\n return options;\n }\n\n /**\n * Build URL with auth query parameters (fallback for servers that don't support headers)\n */\n private buildUrlWithAuth(baseUrl: string, config: ConnectionConfig): string {\n if (!config.auth || config.auth.type === 'none') {\n return baseUrl;\n }\n\n const url = new URL(baseUrl);\n\n if (config.auth.token) {\n url.searchParams.set('token', config.auth.token);\n }\n if (config.auth.password) {\n url.searchParams.set('password', config.auth.password);\n }\n\n return url.toString();\n }\n\n /**\n * Establish connection to a remote peer\n */\n async connect(config: ConnectionConfig): Promise<void> {\n if (this.state === ConnectionState.CONNECTED) {\n throw new Error('Already connected');\n }\n\n this.config = config;\n this.intentionalDisconnect = false;\n this.reconnectAttempts = 0;\n\n return this.establishConnection();\n }\n\n /**\n * Internal method to establish WebSocket connection\n * Used for both initial connection and reconnection attempts\n */\n private async establishConnection(): Promise<void> {\n if (!this.config) {\n throw new Error('No configuration set');\n }\n\n this.state = ConnectionState.CONNECTING;\n\n const baseUrl = this.buildUrl(this.config);\n const wsOptions = this.buildWsOptions(this.config);\n\n // Add auth to URL as query params (in addition to headers for compatibility)\n const url = this.buildUrlWithAuth(baseUrl, this.config);\n\n logger.debug(\n { url: baseUrl, attempt: this.reconnectAttempts, hasOptions: Object.keys(wsOptions).length > 0 },\n 'Connecting to WebSocket server'\n );\n\n return new Promise<void>((resolve, reject) => {\n try {\n // Create WebSocket with options if we have any, otherwise without\n this.ws = Object.keys(wsOptions).length > 0\n ? new WebSocket(url, wsOptions)\n : new WebSocket(url);\n\n // Handle connection open\n this.ws.on('open', () => {\n this.state = ConnectionState.CONNECTED;\n this.reconnectAttempts = 0;\n logger.info({ url }, 'WebSocket connection established');\n\n // Start heartbeat monitoring\n this.startHeartbeat();\n\n // Flush queued messages\n this.flushMessageQueue();\n\n resolve();\n });\n\n // Handle incoming messages\n this.ws.on('message', (data: WebSocket.RawData) => {\n this.handleIncomingMessage(data);\n });\n\n // Handle pong responses for heartbeat\n this.ws.on('pong', () => {\n this.handlePong();\n });\n\n // Handle connection close\n this.ws.on('close', (code, reason) => {\n const wasConnected = this.state === ConnectionState.CONNECTED;\n const wasReconnecting = this.state === ConnectionState.RECONNECTING;\n\n // Stop heartbeat\n this.stopHeartbeat();\n\n logger.info({ code, reason: reason.toString() }, 'WebSocket connection closed');\n\n // Notify disconnect handlers only if we were previously connected\n if (wasConnected) {\n this.notifyDisconnect();\n }\n\n // Attempt reconnection if enabled and not intentional disconnect\n if (!this.intentionalDisconnect && this.shouldReconnect()) {\n this.scheduleReconnect();\n } else if (!wasReconnecting) {\n this.state = ConnectionState.DISCONNECTED;\n }\n });\n\n // Handle errors\n this.ws.on('error', (error: Error) => {\n logger.error({ error: error.message }, 'WebSocket error');\n\n // If we're still connecting (initial connection), reject the promise\n if (this.state === ConnectionState.CONNECTING && this.reconnectAttempts === 0) {\n this.state = ConnectionState.DISCONNECTED;\n reject(error);\n return;\n }\n\n // Notify error handlers\n this.notifyError(error);\n });\n } catch (error) {\n this.state = ConnectionState.DISCONNECTED;\n reject(error);\n }\n });\n }\n\n /**\n * Cleanly close the current connection\n */\n async disconnect(): Promise<void> {\n // Mark as intentional to prevent reconnection\n this.intentionalDisconnect = true;\n\n // Clear any pending reconnection timer\n this.clearReconnectTimer();\n\n // Stop heartbeat\n this.stopHeartbeat();\n\n // Clear message queue on intentional disconnect\n this.messageQueue = [];\n\n if (!this.ws || this.state === ConnectionState.DISCONNECTED) {\n this.state = ConnectionState.DISCONNECTED;\n return;\n }\n\n logger.debug('Disconnecting WebSocket');\n\n return new Promise<void>((resolve) => {\n if (!this.ws) {\n this.state = ConnectionState.DISCONNECTED;\n resolve();\n return;\n }\n\n // Set up close handler before closing\n const onClose = () => {\n this.state = ConnectionState.DISCONNECTED;\n this.ws = null;\n resolve();\n };\n\n // If already closed, resolve immediately\n if (this.ws.readyState === WebSocket.CLOSED) {\n onClose();\n return;\n }\n\n // Set up timeout in case close doesn't happen\n const timeout = setTimeout(() => {\n this.state = ConnectionState.DISCONNECTED;\n this.ws = null;\n resolve();\n }, 5000);\n\n this.ws.once('close', () => {\n clearTimeout(timeout);\n onClose();\n });\n\n // Initiate close\n this.ws.close(1000, 'Disconnect requested');\n });\n }\n\n /**\n * Send a message to the connected peer\n * If disconnected and reconnection is enabled, queues the message for later delivery\n */\n async send(message: BridgeMessage): Promise<void> {\n // If connected, send immediately\n if (this.ws && this.state === ConnectionState.CONNECTED) {\n return this.sendImmediate(message);\n }\n\n // If reconnecting and reconnection is enabled, queue the message\n if (this.shouldReconnect() && (this.state === ConnectionState.RECONNECTING || this.state === ConnectionState.DISCONNECTED)) {\n this.queueMessage(message);\n return;\n }\n\n throw new Error('Not connected');\n }\n\n /**\n * Immediately send a message over the WebSocket\n */\n private async sendImmediate(message: BridgeMessage): Promise<void> {\n if (!this.ws || this.state !== ConnectionState.CONNECTED) {\n throw new Error('Not connected');\n }\n\n const serialized = serializeMessage(message);\n logger.debug({ messageId: message.id, type: message.type }, 'Sending message');\n\n return new Promise<void>((resolve, reject) => {\n this.ws!.send(serialized, (error) => {\n if (error) {\n logger.error({ error: error.message, messageId: message.id }, 'Failed to send message');\n reject(error);\n } else {\n resolve();\n }\n });\n });\n }\n\n /**\n * Queue a message for later delivery when reconnected\n */\n private queueMessage(message: BridgeMessage): void {\n this.messageQueue.push(message);\n logger.debug({ messageId: message.id, queueLength: this.messageQueue.length }, 'Message queued for delivery');\n }\n\n /**\n * Flush all queued messages after reconnection\n */\n private async flushMessageQueue(): Promise<void> {\n if (this.messageQueue.length === 0) {\n return;\n }\n\n logger.info({ queueLength: this.messageQueue.length }, 'Flushing message queue');\n\n const messages = [...this.messageQueue];\n this.messageQueue = [];\n\n for (const message of messages) {\n try {\n await this.sendImmediate(message);\n } catch (error) {\n logger.error({ error: (error as Error).message, messageId: message.id }, 'Failed to send queued message');\n // Re-queue the failed message\n this.messageQueue.unshift(message);\n break;\n }\n }\n }\n\n /**\n * Register a handler for incoming messages\n */\n onMessage(handler: MessageHandler): void {\n this.messageHandlers.push(handler);\n }\n\n /**\n * Register a handler for disconnect events\n */\n onDisconnect(handler: DisconnectHandler): void {\n this.disconnectHandlers.push(handler);\n }\n\n /**\n * Register a handler for error events\n */\n onError(handler: ErrorHandler): void {\n this.errorHandlers.push(handler);\n }\n\n /**\n * Register a handler for reconnecting events\n */\n onReconnecting(handler: (attempt: number, maxAttempts: number) => void): void {\n this.reconnectingHandlers.push(handler);\n }\n\n /**\n * Check if the transport is currently connected\n */\n isConnected(): boolean {\n return this.state === ConnectionState.CONNECTED;\n }\n\n /**\n * Get the current connection state\n */\n getState(): ConnectionState {\n return this.state;\n }\n\n /**\n * Handle incoming WebSocket messages\n */\n private handleIncomingMessage(data: WebSocket.RawData): void {\n const messageString = data.toString();\n logger.debug({ dataLength: messageString.length }, 'Received message');\n\n const result = safeDeserializeMessage(messageString);\n\n if (!result.success) {\n logger.warn({ error: result.error.message }, 'Failed to parse incoming message');\n this.notifyError(new Error(`Invalid message format: ${result.error.message}`));\n return;\n }\n\n const message = result.data;\n logger.debug({ messageId: message.id, type: message.type }, 'Parsed message');\n\n // Notify all message handlers\n for (const handler of this.messageHandlers) {\n try {\n handler(message);\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Message handler threw error');\n }\n }\n }\n\n /**\n * Notify all disconnect handlers\n */\n private notifyDisconnect(): void {\n for (const handler of this.disconnectHandlers) {\n try {\n handler();\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Disconnect handler threw error');\n }\n }\n }\n\n /**\n * Notify all error handlers\n */\n private notifyError(error: Error): void {\n for (const handler of this.errorHandlers) {\n try {\n handler(error);\n } catch (handlerError) {\n logger.error({ error: (handlerError as Error).message }, 'Error handler threw error');\n }\n }\n }\n\n /**\n * Notify all reconnecting handlers\n */\n private notifyReconnecting(attempt: number, maxAttempts: number): void {\n for (const handler of this.reconnectingHandlers) {\n try {\n handler(attempt, maxAttempts);\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Reconnecting handler threw error');\n }\n }\n }\n\n // ============================================================================\n // Reconnection Methods\n // ============================================================================\n\n /**\n * Check if reconnection should be attempted\n */\n private shouldReconnect(): boolean {\n if (!this.config?.reconnect) {\n return false;\n }\n\n const maxAttempts = this.config.maxReconnectAttempts ?? DEFAULT_MAX_RECONNECT_ATTEMPTS;\n return this.reconnectAttempts < maxAttempts;\n }\n\n /**\n * Schedule a reconnection attempt\n */\n private scheduleReconnect(): void {\n if (this.reconnectTimer) {\n return; // Already scheduled\n }\n\n this.state = ConnectionState.RECONNECTING;\n this.reconnectAttempts++;\n\n const maxAttempts = this.config?.maxReconnectAttempts ?? DEFAULT_MAX_RECONNECT_ATTEMPTS;\n const interval = this.config?.reconnectInterval ?? DEFAULT_RECONNECT_INTERVAL;\n\n logger.info(\n { attempt: this.reconnectAttempts, maxAttempts, interval },\n 'Scheduling reconnection attempt'\n );\n\n // Notify reconnecting handlers\n this.notifyReconnecting(this.reconnectAttempts, maxAttempts);\n\n this.reconnectTimer = setTimeout(async () => {\n this.reconnectTimer = null;\n\n try {\n await this.establishConnection();\n logger.info({ attempts: this.reconnectAttempts }, 'Reconnection successful');\n } catch (error) {\n logger.warn({ error: (error as Error).message }, 'Reconnection attempt failed');\n\n // Schedule another attempt if we haven't reached the limit\n if (this.shouldReconnect()) {\n this.scheduleReconnect();\n } else {\n logger.error({ maxAttempts }, 'Max reconnection attempts reached, giving up');\n this.state = ConnectionState.DISCONNECTED;\n this.notifyError(new Error(`Failed to reconnect after ${maxAttempts} attempts`));\n }\n }\n }, interval);\n }\n\n /**\n * Clear any pending reconnection timer\n */\n private clearReconnectTimer(): void {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n }\n\n // ============================================================================\n // Heartbeat Methods\n // ============================================================================\n\n /**\n * Start the heartbeat monitoring\n */\n private startHeartbeat(): void {\n this.stopHeartbeat(); // Clear any existing heartbeat\n\n this.heartbeatInterval = setInterval(() => {\n this.sendPing();\n }, DEFAULT_HEARTBEAT_INTERVAL);\n\n logger.debug({ interval: DEFAULT_HEARTBEAT_INTERVAL }, 'Heartbeat monitoring started');\n }\n\n /**\n * Stop the heartbeat monitoring\n */\n private stopHeartbeat(): void {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = null;\n }\n\n if (this.heartbeatTimeout) {\n clearTimeout(this.heartbeatTimeout);\n this.heartbeatTimeout = null;\n }\n\n this.awaitingPong = false;\n }\n\n /**\n * Send a ping to the peer\n */\n private sendPing(): void {\n if (!this.ws || this.state !== ConnectionState.CONNECTED) {\n return;\n }\n\n if (this.awaitingPong) {\n // We didn't receive a pong for the previous ping - connection may be dead\n logger.warn('No pong received, connection may be dead');\n this.handleHeartbeatTimeout();\n return;\n }\n\n this.awaitingPong = true;\n this.ws.ping();\n\n // Set timeout for pong response\n this.heartbeatTimeout = setTimeout(() => {\n if (this.awaitingPong) {\n this.handleHeartbeatTimeout();\n }\n }, HEARTBEAT_TIMEOUT);\n\n logger.debug('Ping sent');\n }\n\n /**\n * Handle pong response from peer\n */\n private handlePong(): void {\n this.awaitingPong = false;\n\n if (this.heartbeatTimeout) {\n clearTimeout(this.heartbeatTimeout);\n this.heartbeatTimeout = null;\n }\n\n logger.debug('Pong received');\n }\n\n /**\n * Handle heartbeat timeout (no pong received)\n */\n private handleHeartbeatTimeout(): void {\n logger.warn('Heartbeat timeout - closing connection');\n this.awaitingPong = false;\n\n if (this.heartbeatTimeout) {\n clearTimeout(this.heartbeatTimeout);\n this.heartbeatTimeout = null;\n }\n\n // Close the connection to trigger reconnection if enabled\n if (this.ws) {\n this.ws.terminate();\n }\n }\n\n // ============================================================================\n // Getters for testing/debugging\n // ============================================================================\n\n /**\n * Get the current message queue length (for testing)\n */\n getQueueLength(): number {\n return this.messageQueue.length;\n }\n\n /**\n * Get the number of reconnection attempts (for testing)\n */\n getReconnectAttempts(): number {\n return this.reconnectAttempts;\n }\n}\n","/**\n * Authentication utilities for Claude Code Bridge\n * Handles token, password, and IP-based authentication for WebSocket connections\n */\n\nimport * as crypto from 'crypto';\nimport { createLogger } from './logger.js';\nimport type { IncomingMessage } from 'http';\n\nconst logger = createLogger('auth');\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\n/**\n * Authentication type\n */\nexport type AuthType = 'none' | 'token' | 'password' | 'ip' | 'combined';\n\n/**\n * Authentication configuration\n */\nexport interface AuthConfig {\n /** Authentication type */\n type: AuthType;\n /** Authentication token (for type: 'token' or 'combined') */\n token?: string;\n /** Authentication password (for type: 'password' or 'combined') */\n password?: string;\n /** Allowed IP addresses/ranges in CIDR notation (for type: 'ip' or 'combined') */\n allowedIps?: string[];\n /** If true, ALL configured methods must pass; if false, ANY passing method is sufficient */\n requireAll?: boolean;\n}\n\n/**\n * Authentication result\n */\nexport interface AuthResult {\n /** Whether authentication succeeded */\n success: boolean;\n /** Error message if authentication failed */\n error?: string;\n /** Which authentication method succeeded (if any) */\n method?: 'token' | 'password' | 'ip';\n /** Client IP address */\n clientIp?: string;\n}\n\n/**\n * Credentials extracted from a request\n */\nexport interface ExtractedCredentials {\n /** Token from query string or Authorization header */\n token?: string;\n /** Password from query string or header */\n password?: string;\n /** Client IP address */\n clientIp: string;\n}\n\n// ============================================================================\n// IP/CIDR Utilities\n// ============================================================================\n\n/**\n * Parse an IPv4 address to a 32-bit integer\n */\nfunction ipv4ToInt(ip: string): number {\n const parts = ip.split('.').map(Number);\n if (parts.length !== 4 || parts.some(p => isNaN(p) || p < 0 || p > 255)) {\n return -1;\n }\n return (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8) | parts[3];\n}\n\n/**\n * Check if an IP address matches a CIDR range\n * @param clientIp - The IP address to check\n * @param cidr - The CIDR range (e.g., \"192.168.0.0/16\" or \"10.0.0.1\")\n * @returns true if the IP matches the range\n */\nfunction matchesCidr(clientIp: string, cidr: string): boolean {\n // Handle IPv6-mapped IPv4 addresses\n let normalizedIp = clientIp;\n if (normalizedIp.startsWith('::ffff:')) {\n normalizedIp = normalizedIp.substring(7);\n }\n\n // Parse CIDR\n const [network, prefixStr] = cidr.split('/');\n const prefix = prefixStr ? parseInt(prefixStr, 10) : 32;\n\n // Validate prefix\n if (prefix < 0 || prefix > 32) {\n return false;\n }\n\n // Parse IP addresses\n const clientInt = ipv4ToInt(normalizedIp);\n const networkInt = ipv4ToInt(network);\n\n if (clientInt === -1 || networkInt === -1) {\n // If either is invalid, try simple string match\n return normalizedIp === network || clientIp === cidr;\n }\n\n // Create mask from prefix\n const mask = prefix === 0 ? 0 : (-1 << (32 - prefix)) >>> 0;\n\n // Compare masked values (use >>> 0 to ensure unsigned comparison)\n return ((clientInt & mask) >>> 0) === ((networkInt & mask) >>> 0);\n}\n\n/**\n * Check if an IP address matches any of the allowed ranges\n * @param clientIp - The IP address to check\n * @param allowedCidrs - Array of CIDR ranges\n * @returns true if the IP matches any range\n */\nexport function validateIp(clientIp: string, allowedCidrs: string[]): boolean {\n if (!allowedCidrs || allowedCidrs.length === 0) {\n return false;\n }\n\n for (const cidr of allowedCidrs) {\n if (matchesCidr(clientIp, cidr)) {\n logger.debug({ clientIp, matchedCidr: cidr }, 'IP matched allowed range');\n return true;\n }\n }\n\n logger.debug({ clientIp, allowedCidrs }, 'IP did not match any allowed range');\n return false;\n}\n\n// ============================================================================\n// Token/Password Validation\n// ============================================================================\n\n/**\n * Compare two strings in constant time to prevent timing attacks\n * @param provided - The provided value\n * @param expected - The expected value\n * @returns true if the values match\n */\nfunction timingSafeCompare(provided: string, expected: string): boolean {\n // Ensure both strings have the same length to avoid timing differences\n const providedBuffer = Buffer.from(provided, 'utf-8');\n const expectedBuffer = Buffer.from(expected, 'utf-8');\n\n // If lengths differ, still do constant-time comparison to prevent timing attack\n // but return false\n if (providedBuffer.length !== expectedBuffer.length) {\n // Compare with expected to maintain constant time\n crypto.timingSafeEqual(expectedBuffer, expectedBuffer);\n return false;\n }\n\n return crypto.timingSafeEqual(providedBuffer, expectedBuffer);\n}\n\n/**\n * Validate a token using timing-safe comparison\n * @param provided - The provided token\n * @param expected - The expected token\n * @returns true if tokens match\n */\nexport function validateToken(provided: string | undefined, expected: string): boolean {\n if (!provided) {\n return false;\n }\n return timingSafeCompare(provided, expected);\n}\n\n/**\n * Validate a password using timing-safe comparison\n * @param provided - The provided password\n * @param expected - The expected password\n * @returns true if passwords match\n */\nexport function validatePassword(provided: string | undefined, expected: string): boolean {\n if (!provided) {\n return false;\n }\n return timingSafeCompare(provided, expected);\n}\n\n// ============================================================================\n// Credential Extraction\n// ============================================================================\n\n/**\n * Get the client IP address from a request\n * Handles X-Forwarded-For headers for proxied connections\n */\nfunction getClientIp(request: IncomingMessage): string {\n // Check for forwarded IP (from proxy)\n const forwarded = request.headers['x-forwarded-for'];\n if (forwarded) {\n const ips = Array.isArray(forwarded) ? forwarded[0] : forwarded;\n // Get the first IP (original client) from comma-separated list\n const clientIp = ips.split(',')[0].trim();\n if (clientIp) {\n return clientIp;\n }\n }\n\n // Fall back to socket remote address\n return request.socket.remoteAddress || 'unknown';\n}\n\n/**\n * Extract credentials from an HTTP request\n * Looks for token/password in query parameters and Authorization header\n */\nexport function extractCredentials(request: IncomingMessage): ExtractedCredentials {\n const credentials: ExtractedCredentials = {\n clientIp: getClientIp(request),\n };\n\n // Parse query parameters from URL\n const url = new URL(request.url || '/', `http://${request.headers.host || 'localhost'}`);\n\n // Extract token from query parameter\n const queryToken = url.searchParams.get('token');\n if (queryToken) {\n credentials.token = queryToken;\n }\n\n // Extract password from query parameter\n const queryPassword = url.searchParams.get('password');\n if (queryPassword) {\n credentials.password = queryPassword;\n }\n\n // Check Authorization header (Bearer token takes precedence)\n const authHeader = request.headers.authorization;\n if (authHeader) {\n if (authHeader.startsWith('Bearer ')) {\n credentials.token = authHeader.substring(7);\n } else if (authHeader.startsWith('Basic ')) {\n // Basic auth: base64(username:password) - we use password as auth\n try {\n const decoded = Buffer.from(authHeader.substring(6), 'base64').toString('utf-8');\n const [, password] = decoded.split(':');\n if (password) {\n credentials.password = password;\n }\n } catch {\n // Invalid base64, ignore\n }\n }\n }\n\n // Check X-Auth-Token header\n const tokenHeader = request.headers['x-auth-token'];\n if (tokenHeader && !credentials.token) {\n credentials.token = Array.isArray(tokenHeader) ? tokenHeader[0] : tokenHeader;\n }\n\n // Check X-Auth-Password header\n const passwordHeader = request.headers['x-auth-password'];\n if (passwordHeader && !credentials.password) {\n credentials.password = Array.isArray(passwordHeader) ? passwordHeader[0] : passwordHeader;\n }\n\n return credentials;\n}\n\n// ============================================================================\n// Authenticator Class\n// ============================================================================\n\n/**\n * Authenticator class for validating connection requests\n */\nexport class Authenticator {\n private config: AuthConfig;\n\n /**\n * Create a new Authenticator\n * @param config - Authentication configuration\n */\n constructor(config: AuthConfig) {\n this.config = config;\n }\n\n /**\n * Authenticate a request\n * @param request - The incoming HTTP request (WebSocket upgrade request)\n * @returns Authentication result\n */\n authenticate(request: IncomingMessage): AuthResult {\n // If auth is disabled, allow all connections\n if (this.config.type === 'none') {\n return { success: true };\n }\n\n // Extract credentials from request\n const credentials = extractCredentials(request);\n\n return this.authenticateWithCredentials(credentials);\n }\n\n /**\n * Authenticate with extracted credentials\n * @param credentials - The extracted credentials\n * @returns Authentication result\n */\n authenticateWithCredentials(credentials: ExtractedCredentials): AuthResult {\n const { clientIp } = credentials;\n\n // If auth is disabled, allow all connections\n if (this.config.type === 'none') {\n return { success: true, clientIp };\n }\n\n const results: { method: 'token' | 'password' | 'ip'; success: boolean }[] = [];\n\n // Check token authentication\n if (this.config.token) {\n const tokenValid = validateToken(credentials.token, this.config.token);\n results.push({ method: 'token', success: tokenValid });\n if (tokenValid) {\n logger.debug({ clientIp }, 'Token authentication succeeded');\n } else {\n logger.debug({ clientIp }, 'Token authentication failed');\n }\n }\n\n // Check password authentication\n if (this.config.password) {\n const passwordValid = validatePassword(credentials.password, this.config.password);\n results.push({ method: 'password', success: passwordValid });\n if (passwordValid) {\n logger.debug({ clientIp }, 'Password authentication succeeded');\n } else {\n logger.debug({ clientIp }, 'Password authentication failed');\n }\n }\n\n // Check IP authentication\n if (this.config.allowedIps && this.config.allowedIps.length > 0) {\n const ipValid = validateIp(clientIp, this.config.allowedIps);\n results.push({ method: 'ip', success: ipValid });\n if (ipValid) {\n logger.debug({ clientIp }, 'IP authentication succeeded');\n } else {\n logger.debug({ clientIp }, 'IP authentication failed');\n }\n }\n\n // If no auth methods configured but type is not 'none', reject\n if (results.length === 0) {\n logger.warn('Authentication configured but no methods available');\n return {\n success: false,\n error: 'Authentication required but not configured',\n clientIp,\n };\n }\n\n // Evaluate results based on requireAll setting\n if (this.config.requireAll) {\n // ALL methods must pass\n const allPassed = results.every(r => r.success);\n if (allPassed) {\n logger.info({ clientIp, methods: results.map(r => r.method) }, 'All authentication methods passed');\n return { success: true, clientIp };\n } else {\n const failed = results.filter(r => !r.success).map(r => r.method);\n logger.warn({ clientIp, failedMethods: failed }, 'Authentication failed (requireAll mode)');\n return {\n success: false,\n error: `Authentication failed for methods: ${failed.join(', ')}`,\n clientIp,\n };\n }\n } else {\n // ANY method passing is sufficient\n const passed = results.find(r => r.success);\n if (passed) {\n logger.info({ clientIp, method: passed.method }, 'Authentication succeeded');\n return { success: true, method: passed.method, clientIp };\n } else {\n logger.warn({ clientIp }, 'All authentication methods failed');\n return {\n success: false,\n error: 'Authentication failed',\n clientIp,\n };\n }\n }\n }\n\n /**\n * Get the configured authentication type\n */\n getType(): AuthType {\n return this.config.type;\n }\n\n /**\n * Check if authentication is required\n */\n isRequired(): boolean {\n return this.config.type !== 'none';\n }\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Create an AuthConfig from CLI options\n * @param options - CLI options object\n * @returns AuthConfig\n */\nexport function createAuthConfigFromOptions(options: {\n authToken?: string;\n authPassword?: string;\n authIp?: string[];\n authRequireAll?: boolean;\n}): AuthConfig {\n const hasToken = !!options.authToken;\n const hasPassword = !!options.authPassword;\n const hasIp = options.authIp && options.authIp.length > 0;\n\n // Determine auth type based on what's configured\n let type: AuthType = 'none';\n if (hasToken || hasPassword || hasIp) {\n const count = [hasToken, hasPassword, hasIp].filter(Boolean).length;\n if (count > 1) {\n type = 'combined';\n } else if (hasToken) {\n type = 'token';\n } else if (hasPassword) {\n type = 'password';\n } else if (hasIp) {\n type = 'ip';\n }\n }\n\n return {\n type,\n token: options.authToken,\n password: options.authPassword,\n allowedIps: options.authIp,\n requireAll: options.authRequireAll ?? false,\n };\n}\n\n/**\n * Validate an AuthConfig\n * @param config - AuthConfig to validate\n * @returns Validation result with errors and warnings\n */\nexport function validateAuthConfig(config: AuthConfig): { valid: boolean; errors: string[]; warnings: string[] } {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n // Check that required credentials are provided for the auth type\n if (config.type === 'token' && !config.token) {\n errors.push('Token authentication requires a token');\n }\n if (config.type === 'password' && !config.password) {\n errors.push('Password authentication requires a password');\n }\n if (config.type === 'ip' && (!config.allowedIps || config.allowedIps.length === 0)) {\n errors.push('IP authentication requires at least one allowed IP/CIDR');\n }\n\n // Validate CIDR formats\n if (config.allowedIps) {\n for (const cidr of config.allowedIps) {\n const [ip, prefix] = cidr.split('/');\n if (ipv4ToInt(ip) === -1) {\n warnings.push(`IP address may not be valid IPv4: ${ip}`);\n }\n if (prefix !== undefined) {\n const prefixNum = parseInt(prefix, 10);\n if (isNaN(prefixNum) || prefixNum < 0 || prefixNum > 32) {\n errors.push(`Invalid CIDR prefix: ${cidr}`);\n }\n }\n }\n }\n\n // Warn about weak authentication\n if (config.token && config.token.length < 16) {\n warnings.push('Token is shorter than 16 characters - consider using a longer token');\n }\n if (config.password && config.password.length < 8) {\n warnings.push('Password is shorter than 8 characters - consider using a longer password');\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n","/**\n * Message builder factory functions for Claude Code Bridge\n * Provides convenient functions to create specific message types\n */\n\nimport { createMessage, type BridgeMessage, type Context, type TaskRequest, type TaskResult } from './protocol.js';\n\n/**\n * Notification data structure for notification messages\n */\nexport interface NotificationData {\n type: string;\n message: string;\n data?: Record<string, unknown>;\n}\n\n/**\n * Creates a context synchronization message\n * Used to share context (files, tree, summary) with a peer\n * @param source The source instance identifier\n * @param context The context to synchronize\n * @returns A BridgeMessage with type 'context_sync'\n */\nexport function createContextSyncMessage(\n source: string,\n context: Context\n): BridgeMessage {\n const message = createMessage('context_sync', source);\n return {\n ...message,\n context,\n };\n}\n\n/**\n * Creates a task delegation message\n * Used to delegate a task to a peer instance\n * @param source The source instance identifier\n * @param task The task to delegate\n * @returns A BridgeMessage with type 'task_delegate'\n */\nexport function createTaskDelegateMessage(\n source: string,\n task: TaskRequest\n): BridgeMessage {\n const message = createMessage('task_delegate', source);\n return {\n ...message,\n task,\n };\n}\n\n/**\n * Creates a task response message\n * Used to respond to a delegated task\n * @param source The source instance identifier\n * @param taskId The ID of the task being responded to\n * @param result The result of the task execution\n * @returns A BridgeMessage with type 'response'\n */\nexport function createTaskResponseMessage(\n source: string,\n taskId: string,\n result: Omit<TaskResult, 'taskId'>\n): BridgeMessage {\n const message = createMessage('response', source);\n return {\n ...message,\n result: {\n ...result,\n taskId,\n },\n };\n}\n\n/**\n * Creates a context request message\n * Used to request specific context from a peer\n * @param source The source instance identifier\n * @param query A description of what context is being requested\n * @returns A BridgeMessage with type 'request'\n */\nexport function createContextRequestMessage(\n source: string,\n query: string\n): BridgeMessage {\n const message = createMessage('request', source);\n return {\n ...message,\n context: {\n summary: query,\n },\n };\n}\n\n/**\n * Creates a notification message\n * Used to send notifications to peers (events, status updates, etc.)\n * @param source The source instance identifier\n * @param notification The notification data\n * @returns A BridgeMessage with type 'notification'\n */\nexport function createNotificationMessage(\n source: string,\n notification: NotificationData\n): BridgeMessage {\n const message = createMessage('notification', source);\n return {\n ...message,\n context: {\n summary: notification.message,\n variables: {\n notificationType: notification.type,\n ...notification.data,\n },\n },\n };\n}\n","/**\n * Bridge Core - Main orchestration class for Claude Code Bridge\n * Handles peer connections, message routing, and lifecycle management\n */\n\nimport { WebSocketServer, WebSocket as WsWebSocket } from 'ws';\nimport type { IncomingMessage } from 'http';\nimport * as https from 'https';\nimport { v4 as uuidv4 } from 'uuid';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { createLogger } from '../utils/logger.js';\nimport { WebSocketTransport } from '../transport/websocket.js';\nimport { ConnectionState, type Transport, type TLSConfig, type AuthConfig } from '../transport/interface.js';\nimport { loadCertificatesSync, isTLSEnabled } from '../utils/tls.js';\nimport { Authenticator, extractCredentials } from '../utils/auth.js';\nimport {\n type BridgeMessage,\n type TaskRequest,\n type TaskResult,\n type Context,\n type FileChunk,\n safeDeserializeMessage,\n serializeMessage,\n} from './protocol.js';\nimport {\n createTaskDelegateMessage,\n createTaskResponseMessage,\n createContextSyncMessage,\n createContextRequestMessage,\n} from './messages.js';\n\nconst logger = createLogger('bridge');\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\n/**\n * Bridge operation mode\n * - 'host': Listen for incoming connections, sends commands via MCP\n * - 'client': Connect to host, receives and executes commands\n * - 'peer': Bidirectional mode - can both listen and connect\n */\nexport type BridgeMode = 'host' | 'client' | 'peer';\n\n/**\n * Configuration for the bridge's listening server\n */\nexport interface BridgeListenConfig {\n /** Port to listen on */\n port: number;\n /** Host to bind to (default: 0.0.0.0) */\n host?: string;\n /** TLS configuration for secure connections */\n tls?: TLSConfig;\n /** Authentication configuration */\n auth?: AuthConfig;\n}\n\n/**\n * Configuration for connecting to a remote bridge\n */\nexport interface BridgeConnectConfig {\n /** Full WebSocket URL (e.g., ws://localhost:8765 or wss://localhost:8765) */\n url?: string;\n /** Use host.docker.internal for container-to-host connection */\n hostGateway?: boolean;\n /** Port to connect to (used if url is not provided) */\n port?: number;\n /** TLS configuration for secure connections */\n tls?: TLSConfig;\n /** Authentication configuration */\n auth?: AuthConfig;\n}\n\n/**\n * Context sharing configuration\n */\nexport interface ContextSharingConfig {\n /** Enable automatic context synchronization */\n autoSync?: boolean;\n /** Interval in milliseconds for auto-sync (default: 5000) */\n syncInterval?: number;\n}\n\n/**\n * Full configuration for Bridge initialization\n */\nexport interface BridgeConfig {\n /** Operation mode: 'host' or 'client' */\n mode: BridgeMode;\n /** Unique identifier for this bridge instance */\n instanceName: string;\n /** Server configuration (required for 'host' mode) */\n listen?: BridgeListenConfig;\n /** Connection configuration (required for 'client' mode) */\n connect?: BridgeConnectConfig;\n /** Task timeout in milliseconds (default: 300000 / 5 minutes) */\n taskTimeout?: number;\n /** Context sharing configuration */\n contextSharing?: ContextSharingConfig;\n}\n\n/**\n * Information about a connected peer\n */\nexport interface PeerInfo {\n /** Unique identifier for the peer connection */\n id: string;\n /** Name of the peer instance */\n name: string;\n /** Environment type of the peer */\n environment?: string;\n /** Timestamp when the peer connected */\n connectedAt: number;\n /** Timestamp of last activity from the peer */\n lastActivity: number;\n}\n\n/**\n * Internal peer connection tracking\n */\ninterface PeerConnection {\n /** Peer information */\n info: PeerInfo;\n /** WebSocket connection (for server-side connections) */\n ws?: WsWebSocket;\n /** Transport instance (for client-side connections) */\n transport?: Transport;\n}\n\n/**\n * Handler for peer connection events\n */\nexport type PeerConnectedHandler = (peer: PeerInfo) => void;\n\n/**\n * Handler for peer disconnection events\n */\nexport type PeerDisconnectedHandler = (peer: PeerInfo) => void;\n\n/**\n * Handler for incoming messages from peers\n */\nexport type MessageReceivedHandler = (message: BridgeMessage, peerId: string) => void;\n\n/**\n * Handler for incoming task delegation requests\n * Returns a TaskResult or Promise<TaskResult>\n */\nexport type TaskReceivedHandler = (task: TaskRequest, peerId: string) => TaskResult | Promise<TaskResult>;\n\n/**\n * Handler for incoming context synchronization\n */\nexport type ContextReceivedHandler = (context: Context, peerId: string) => void;\n\n/**\n * Handler for incoming context requests\n * Returns FileChunk[] or Promise<FileChunk[]>\n */\nexport type ContextRequestedHandler = (query: string, peerId: string) => FileChunk[] | Promise<FileChunk[]>;\n\n/**\n * Pending task tracking for response correlation\n */\ninterface PendingTask {\n taskId: string;\n peerId: string;\n resolve: (result: TaskResult) => void;\n reject: (error: Error) => void;\n timeoutId: ReturnType<typeof setTimeout>;\n}\n\n/**\n * Pending context request tracking for response correlation\n */\ninterface PendingContextRequest {\n requestId: string;\n peerId: string;\n resolve: (chunks: FileChunk[]) => void;\n reject: (error: Error) => void;\n timeoutId: ReturnType<typeof setTimeout>;\n}\n\n// ============================================================================\n// Bridge Class\n// ============================================================================\n\n/**\n * Main Bridge class for host-client communication\n * Supports two modes of operation:\n * - 'host': Acts as a server, accepting client connections, sends commands via MCP\n * - 'client': Connects to a host, receives and executes commands with handlers\n */\nexport class Bridge {\n private config: BridgeConfig;\n private server: WebSocketServer | null = null;\n private httpsServer: https.Server | null = null;\n private clientTransport: WebSocketTransport | null = null;\n private peers: Map<string, PeerConnection> = new Map();\n private started: boolean = false;\n private authenticator: Authenticator | null = null;\n\n // Event handlers\n private peerConnectedHandlers: PeerConnectedHandler[] = [];\n private peerDisconnectedHandlers: PeerDisconnectedHandler[] = [];\n private messageReceivedHandlers: MessageReceivedHandler[] = [];\n private taskReceivedHandler: TaskReceivedHandler | null = null;\n private contextReceivedHandlers: ContextReceivedHandler[] = [];\n private contextRequestedHandler: ContextRequestedHandler | null = null;\n\n // Task correlation\n private pendingTasks: Map<string, PendingTask> = new Map();\n\n // Context request correlation\n private pendingContextRequests: Map<string, PendingContextRequest> = new Map();\n\n // Auto-sync interval timer\n private autoSyncIntervalId: ReturnType<typeof setInterval> | null = null;\n\n /**\n * Create a new Bridge instance\n * @param config Bridge configuration\n */\n constructor(config: BridgeConfig) {\n this.config = config;\n this.validateConfig();\n logger.info({ instanceName: config.instanceName, mode: config.mode }, 'Bridge instance created');\n }\n\n /**\n * Validate the configuration based on mode requirements\n */\n private validateConfig(): void {\n const { mode, listen, connect } = this.config;\n\n if (mode === 'host' && !listen) {\n throw new Error(\"'host' mode requires 'listen' configuration\");\n }\n\n if (mode === 'client' && !connect) {\n throw new Error(\"'client' mode requires 'connect' configuration\");\n }\n\n if (mode === 'peer' && !listen && !connect) {\n throw new Error(\"'peer' mode requires either 'listen' or 'connect' configuration\");\n }\n }\n\n /**\n * Start the bridge based on configured mode\n * - 'host': Starts WebSocket server, sends commands via MCP\n * - 'client': Connects to host, receives and executes commands\n * - 'peer': Starts server (if listen configured) and connects to remote (if connect configured)\n */\n async start(): Promise<void> {\n if (this.started) {\n throw new Error('Bridge is already started');\n }\n\n const { mode } = this.config;\n logger.info({ mode }, 'Starting bridge');\n\n try {\n // Start server if in host mode or peer mode with listen config\n if ((mode === 'host' || mode === 'peer') && this.config.listen) {\n await this.startServer();\n }\n\n // Connect to remote if in client mode or peer mode with connect config\n if ((mode === 'client' || mode === 'peer') && this.config.connect) {\n await this.connectToRemote();\n }\n\n this.started = true;\n this.writeStatusFile();\n logger.info({ mode, instanceName: this.config.instanceName }, 'Bridge started successfully');\n } catch (error) {\n // Cleanup on failure\n await this.cleanup();\n throw error;\n }\n }\n\n /**\n * Stop the bridge and close all connections\n */\n async stop(): Promise<void> {\n if (!this.started) {\n return;\n }\n\n logger.info('Stopping bridge');\n await this.cleanup();\n this.started = false;\n logger.info('Bridge stopped');\n }\n\n /**\n * Get list of connected peers\n */\n getPeers(): PeerInfo[] {\n return Array.from(this.peers.values()).map(p => p.info);\n }\n\n /**\n * Connect to a remote bridge\n * @param url WebSocket URL to connect to\n */\n async connectToPeer(url: string): Promise<void> {\n const transport = new WebSocketTransport();\n\n // Set up message handler\n transport.onMessage((message) => {\n this.handleMessage(message, transport);\n });\n\n // Set up disconnect handler\n transport.onDisconnect(() => {\n this.handleClientDisconnect(transport);\n });\n\n try {\n await transport.connect({\n url,\n reconnect: true,\n reconnectInterval: 1000,\n maxReconnectAttempts: 10,\n });\n\n // Create peer info for the connected remote\n const peerId = uuidv4();\n const peerInfo: PeerInfo = {\n id: peerId,\n name: 'remote', // Will be updated when we receive peer info\n connectedAt: Date.now(),\n lastActivity: Date.now(),\n };\n\n this.peers.set(peerId, {\n info: peerInfo,\n transport,\n });\n\n // Store peerId on transport for lookup\n (transport as WebSocketTransport & { _peerId?: string })._peerId = peerId;\n\n this.notifyPeerConnected(peerInfo);\n logger.info({ peerId, url }, 'Connected to remote peer');\n } catch (error) {\n logger.error({ error: (error as Error).message, url }, 'Failed to connect to remote peer');\n throw error;\n }\n }\n\n /**\n * Disconnect from a specific peer\n * @param peerId ID of the peer to disconnect from\n */\n async disconnectFromPeer(peerId: string): Promise<void> {\n const peer = this.peers.get(peerId);\n if (!peer) {\n throw new Error(`Peer not found: ${peerId}`);\n }\n\n if (peer.transport) {\n await peer.transport.disconnect();\n }\n\n if (peer.ws) {\n peer.ws.close(1000, 'Disconnect requested');\n }\n\n this.peers.delete(peerId);\n this.notifyPeerDisconnected(peer.info);\n logger.info({ peerId }, 'Disconnected from peer');\n }\n\n /**\n * Send a message to a specific peer\n * @param peerId ID of the peer to send to\n * @param message Message to send\n */\n async sendToPeer(peerId: string, message: BridgeMessage): Promise<void> {\n const peer = this.peers.get(peerId);\n if (!peer) {\n throw new Error(`Peer not found: ${peerId}`);\n }\n\n if (peer.transport) {\n await peer.transport.send(message);\n } else if (peer.ws) {\n const serialized = serializeMessage(message);\n await new Promise<void>((resolve, reject) => {\n peer.ws!.send(serialized, (error) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n } else {\n throw new Error('No transport available for peer');\n }\n\n logger.debug({ peerId, messageId: message.id, type: message.type }, 'Sent message to peer');\n }\n\n /**\n * Broadcast a message to all connected peers\n * @param message Message to broadcast\n */\n async broadcast(message: BridgeMessage): Promise<void> {\n const sendPromises = Array.from(this.peers.keys()).map(peerId =>\n this.sendToPeer(peerId, message).catch(error => {\n logger.error({ error: (error as Error).message, peerId }, 'Failed to send to peer');\n })\n );\n\n await Promise.all(sendPromises);\n logger.debug({ messageId: message.id, peerCount: this.peers.size }, 'Broadcast message sent');\n }\n\n // ============================================================================\n // Event Registration\n // ============================================================================\n\n /**\n * Register a handler for peer connection events\n */\n onPeerConnected(handler: PeerConnectedHandler): void {\n this.peerConnectedHandlers.push(handler);\n }\n\n /**\n * Register a handler for peer disconnection events\n */\n onPeerDisconnected(handler: PeerDisconnectedHandler): void {\n this.peerDisconnectedHandlers.push(handler);\n }\n\n /**\n * Register a handler for incoming messages\n */\n onMessage(handler: MessageReceivedHandler): void {\n this.messageReceivedHandlers.push(handler);\n }\n\n /**\n * Register a handler for incoming task delegation requests\n * Only one handler can be registered at a time\n * @param handler Function that receives a TaskRequest and returns a TaskResult\n */\n onTaskReceived(handler: TaskReceivedHandler): void {\n this.taskReceivedHandler = handler;\n }\n\n /**\n * Register a handler for incoming context synchronization\n * Multiple handlers can be registered\n * @param handler Function that receives context and peerId\n */\n onContextReceived(handler: ContextReceivedHandler): void {\n this.contextReceivedHandlers.push(handler);\n }\n\n /**\n * Register a handler for incoming context requests\n * Only one handler can be registered at a time\n * @param handler Function that receives a query and returns FileChunk[]\n */\n onContextRequested(handler: ContextRequestedHandler): void {\n this.contextRequestedHandler = handler;\n }\n\n // ============================================================================\n // Task Delegation\n // ============================================================================\n\n /**\n * Delegate a task to a peer and wait for the result\n * @param task The task request to delegate\n * @param peerId Optional peer ID to send to (defaults to first peer)\n * @returns Promise that resolves with the task result\n * @throws Error if no peers are connected or task times out\n */\n async delegateTask(task: TaskRequest, peerId?: string): Promise<TaskResult> {\n // Get target peer\n if (!peerId) {\n const peers = this.getPeers();\n if (peers.length === 0) {\n throw new Error('No peers connected to delegate task to');\n }\n peerId = peers[0].id;\n }\n\n // Validate peer exists\n if (!this.peers.has(peerId)) {\n throw new Error(`Peer not found: ${peerId}`);\n }\n\n // Determine timeout\n const timeout = task.timeout ?? this.config.taskTimeout ?? 300000; // Default 5 minutes\n\n // Create promise to track task completion\n return new Promise<TaskResult>((resolve, reject) => {\n // Create the task delegate message\n const message = createTaskDelegateMessage(this.config.instanceName, task);\n\n // Set up timeout\n const timeoutId = setTimeout(() => {\n const pending = this.pendingTasks.get(task.id);\n if (pending) {\n this.pendingTasks.delete(task.id);\n reject(new Error(`Task '${task.id}' timed out after ${timeout}ms`));\n }\n }, timeout);\n\n // Store pending task for correlation\n this.pendingTasks.set(task.id, {\n taskId: task.id,\n peerId,\n resolve,\n reject,\n timeoutId,\n });\n\n // Send the task\n this.sendToPeer(peerId, message).catch((error) => {\n // Clean up on send error\n clearTimeout(timeoutId);\n this.pendingTasks.delete(task.id);\n reject(error);\n });\n\n logger.debug({ taskId: task.id, peerId, timeout }, 'Task delegated');\n });\n }\n\n // ============================================================================\n // Context Synchronization\n // ============================================================================\n\n /**\n * Synchronize context with connected peers\n * @param context Optional context to sync. If not provided, broadcasts to all peers\n * @param peerId Optional peer ID to send to (defaults to all peers)\n */\n async syncContext(context?: Context, peerId?: string): Promise<void> {\n // Use empty context if not provided\n const contextToSync = context ?? {};\n\n // Create the context sync message\n const message = createContextSyncMessage(this.config.instanceName, contextToSync);\n\n if (peerId) {\n // Send to specific peer\n await this.sendToPeer(peerId, message);\n logger.debug({ peerId, messageId: message.id }, 'Context synced to peer');\n } else {\n // Broadcast to all peers\n await this.broadcast(message);\n logger.debug({ peerCount: this.peers.size, messageId: message.id }, 'Context synced to all peers');\n }\n }\n\n /**\n * Request context from a peer based on a query\n * @param query Description of what context is being requested\n * @param peerId Optional peer ID to request from (defaults to first peer)\n * @param timeout Optional timeout in milliseconds (default: 30000)\n * @returns Promise that resolves with FileChunk[] from the peer\n * @throws Error if no peers are connected or request times out\n */\n async requestContext(query: string, peerId?: string, timeout: number = 30000): Promise<FileChunk[]> {\n // Get target peer\n if (!peerId) {\n const peers = this.getPeers();\n if (peers.length === 0) {\n throw new Error('No peers connected to request context from');\n }\n peerId = peers[0].id;\n }\n\n // Validate peer exists\n if (!this.peers.has(peerId)) {\n throw new Error(`Peer not found: ${peerId}`);\n }\n\n // Create promise to track request completion\n return new Promise<FileChunk[]>((resolve, reject) => {\n // Create the context request message\n const message = createContextRequestMessage(this.config.instanceName, query);\n\n // Set up timeout\n const timeoutId = setTimeout(() => {\n const pending = this.pendingContextRequests.get(message.id);\n if (pending) {\n this.pendingContextRequests.delete(message.id);\n reject(new Error(`Context request timed out after ${timeout}ms`));\n }\n }, timeout);\n\n // Store pending request for correlation\n this.pendingContextRequests.set(message.id, {\n requestId: message.id,\n peerId,\n resolve,\n reject,\n timeoutId,\n });\n\n // Send the request\n this.sendToPeer(peerId, message).catch((error) => {\n // Clean up on send error\n clearTimeout(timeoutId);\n this.pendingContextRequests.delete(message.id);\n reject(error);\n });\n\n logger.debug({ requestId: message.id, peerId, query }, 'Context requested');\n });\n }\n\n /**\n * Start automatic context synchronization\n * Uses interval from config.contextSharing.syncInterval (default: 5000ms)\n * @param contextProvider Optional function that returns context to sync\n */\n startAutoSync(contextProvider?: () => Context | Promise<Context>): void {\n // Stop any existing auto-sync\n this.stopAutoSync();\n\n const interval = this.config.contextSharing?.syncInterval ?? 5000;\n\n this.autoSyncIntervalId = setInterval(async () => {\n try {\n // Get context from provider if available\n const context = contextProvider ? await contextProvider() : undefined;\n await this.syncContext(context);\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Auto-sync error');\n }\n }, interval);\n\n logger.info({ interval }, 'Auto-sync started');\n }\n\n /**\n * Stop automatic context synchronization\n */\n stopAutoSync(): void {\n if (this.autoSyncIntervalId) {\n clearInterval(this.autoSyncIntervalId);\n this.autoSyncIntervalId = null;\n logger.info('Auto-sync stopped');\n }\n }\n\n // ============================================================================\n // Private Methods - Server\n // ============================================================================\n\n /**\n * Start the WebSocket server\n * If TLS is configured, starts an HTTPS server with WebSocket upgrade\n * If auth is configured, validates connections before accepting\n */\n private async startServer(): Promise<void> {\n const { listen } = this.config;\n if (!listen) {\n throw new Error('Listen configuration is required');\n }\n\n const host = listen.host ?? '0.0.0.0';\n const port = listen.port;\n const useTls = isTLSEnabled(listen.tls);\n\n // Set up authenticator if auth is configured\n if (listen.auth && listen.auth.type !== 'none') {\n this.authenticator = new Authenticator(listen.auth);\n logger.info({ authType: listen.auth.type }, 'Authentication enabled');\n }\n\n return new Promise<void>((resolve, reject) => {\n logger.debug({ host, port, tls: useTls, auth: !!this.authenticator }, 'Starting WebSocket server');\n\n try {\n if (useTls && listen.tls) {\n // Load TLS certificates\n const tlsOptions = loadCertificatesSync(listen.tls);\n logger.info({ host, port }, 'Starting secure WebSocket server (wss://)');\n\n // Create HTTPS server\n this.httpsServer = https.createServer({\n cert: tlsOptions.cert,\n key: tlsOptions.key,\n ca: tlsOptions.ca,\n passphrase: tlsOptions.passphrase,\n });\n\n // Create WebSocket server attached to HTTPS server\n const wsOptions: import('ws').ServerOptions = {\n server: this.httpsServer,\n };\n\n // Add verifyClient for authentication\n if (this.authenticator) {\n wsOptions.verifyClient = (info, callback) => {\n this.verifyClient(info, callback);\n };\n }\n\n this.server = new WebSocketServer(wsOptions);\n\n // Start HTTPS server\n this.httpsServer.listen(port, host, () => {\n logger.info({ host, port, protocol: 'wss' }, 'Secure WebSocket server listening');\n resolve();\n });\n\n this.httpsServer.on('error', (error) => {\n logger.error({ error: (error as Error).message }, 'HTTPS server error');\n reject(error);\n });\n } else {\n // Create plain WebSocket server\n const wsOptions: import('ws').ServerOptions = {\n host,\n port,\n };\n\n // Add verifyClient for authentication\n if (this.authenticator) {\n wsOptions.verifyClient = (info, callback) => {\n this.verifyClient(info, callback);\n };\n }\n\n this.server = new WebSocketServer(wsOptions);\n\n this.server.on('listening', () => {\n logger.info({ host, port, protocol: 'ws' }, 'WebSocket server listening');\n resolve();\n });\n\n this.server.on('error', (error) => {\n logger.error({ error: (error as Error).message }, 'WebSocket server error');\n reject(error);\n });\n }\n\n this.server.on('connection', (ws, request) => {\n this.handleNewConnection(ws, request);\n });\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Failed to start server');\n reject(error);\n }\n });\n }\n\n /**\n * Verify client connection for authentication\n * Used as WebSocketServer verifyClient callback\n */\n private verifyClient(\n info: { origin: string; secure: boolean; req: IncomingMessage },\n callback: (res: boolean, code?: number, message?: string, headers?: Record<string, string>) => void\n ): void {\n if (!this.authenticator) {\n callback(true);\n return;\n }\n\n const result = this.authenticator.authenticate(info.req);\n\n if (result.success) {\n logger.info({ clientIp: result.clientIp, method: result.method }, 'Client authenticated');\n callback(true);\n } else {\n logger.warn({ clientIp: result.clientIp, error: result.error }, 'Client authentication failed');\n // Use custom close code 4001 for authentication failure\n callback(false, 4001, result.error || 'Authentication failed');\n }\n }\n\n /**\n * Handle a new incoming connection\n */\n private handleNewConnection(ws: WsWebSocket, request: { url?: string }): void {\n const peerId = uuidv4();\n const peerInfo: PeerInfo = {\n id: peerId,\n name: 'client', // Will be updated when we receive peer info\n connectedAt: Date.now(),\n lastActivity: Date.now(),\n };\n\n this.peers.set(peerId, {\n info: peerInfo,\n ws,\n });\n\n logger.info({ peerId, url: request.url }, 'New peer connected');\n\n // Set up message handler\n ws.on('message', (data) => {\n const messageString = data.toString();\n const result = safeDeserializeMessage(messageString);\n\n if (result.success) {\n peerInfo.lastActivity = Date.now();\n this.handleMessage(result.data, ws, peerId);\n } else {\n logger.warn({ peerId, error: result.error.message }, 'Invalid message received');\n }\n });\n\n // Set up close handler\n ws.on('close', (code, reason) => {\n logger.info({ peerId, code, reason: reason.toString() }, 'Peer disconnected');\n this.peers.delete(peerId);\n this.notifyPeerDisconnected(peerInfo);\n });\n\n // Set up error handler\n ws.on('error', (error) => {\n logger.error({ peerId, error: (error as Error).message }, 'Peer connection error');\n });\n\n // Notify peer connected handlers\n this.notifyPeerConnected(peerInfo);\n }\n\n // ============================================================================\n // Private Methods - Client\n // ============================================================================\n\n /**\n * Connect to a remote bridge as a client\n */\n private async connectToRemote(): Promise<void> {\n const { connect } = this.config;\n if (!connect) {\n throw new Error('Connect configuration is required');\n }\n\n // Build URL from config\n let url = connect.url;\n if (!url) {\n const host = connect.hostGateway ? 'host.docker.internal' : 'localhost';\n const port = connect.port ?? 8765;\n // Use wss:// if TLS is configured\n const protocol = isTLSEnabled(connect.tls) || connect.tls?.ca ? 'wss' : 'ws';\n url = `${protocol}://${host}:${port}`;\n }\n\n this.clientTransport = new WebSocketTransport();\n\n // Set up message handler\n this.clientTransport.onMessage((message) => {\n this.handleMessage(message, this.clientTransport!);\n });\n\n // Set up disconnect handler\n this.clientTransport.onDisconnect(() => {\n this.handleClientDisconnect(this.clientTransport!);\n });\n\n try {\n await this.clientTransport.connect({\n url,\n reconnect: true,\n reconnectInterval: 1000,\n maxReconnectAttempts: 10,\n tls: connect.tls,\n auth: connect.auth,\n });\n\n // Create peer info for the connected server\n const peerId = uuidv4();\n const peerInfo: PeerInfo = {\n id: peerId,\n name: 'server',\n connectedAt: Date.now(),\n lastActivity: Date.now(),\n };\n\n this.peers.set(peerId, {\n info: peerInfo,\n transport: this.clientTransport,\n });\n\n // Store peerId on transport for lookup\n (this.clientTransport as WebSocketTransport & { _peerId?: string })._peerId = peerId;\n\n this.notifyPeerConnected(peerInfo);\n logger.info({ peerId, url }, 'Connected to remote bridge');\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Failed to connect to remote bridge');\n this.clientTransport = null;\n throw error;\n }\n }\n\n /**\n * Handle client transport disconnect\n */\n private handleClientDisconnect(transport: Transport): void {\n // Find peer by transport\n const typedTransport = transport as WebSocketTransport & { _peerId?: string };\n const peerId = typedTransport._peerId;\n\n if (peerId) {\n const peer = this.peers.get(peerId);\n if (peer) {\n this.peers.delete(peerId);\n this.notifyPeerDisconnected(peer.info);\n logger.info({ peerId }, 'Client transport disconnected');\n }\n }\n }\n\n // ============================================================================\n // Private Methods - Message Handling\n // ============================================================================\n\n /**\n * Handle an incoming message\n */\n private handleMessage(\n message: BridgeMessage,\n source: WsWebSocket | Transport,\n peerId?: string\n ): void {\n // Find peerId if not provided\n if (!peerId) {\n const typedSource = source as WebSocketTransport & { _peerId?: string };\n peerId = typedSource._peerId;\n }\n\n if (!peerId) {\n // Try to find by ws reference\n for (const [id, peer] of this.peers) {\n if (peer.ws === source || peer.transport === source) {\n peerId = id;\n break;\n }\n }\n }\n\n if (!peerId) {\n logger.warn({ messageId: message.id }, 'Received message from unknown peer');\n return;\n }\n\n // Update last activity\n const peer = this.peers.get(peerId);\n if (peer) {\n peer.info.lastActivity = Date.now();\n }\n\n logger.debug({ peerId, messageId: message.id, type: message.type }, 'Received message');\n\n // Handle task delegation messages\n if (message.type === 'task_delegate' && message.task) {\n this.handleTaskDelegate(message, peerId);\n return;\n }\n\n // Handle task response messages\n if (message.type === 'response' && message.result?.taskId) {\n this.handleTaskResponse(message);\n return;\n }\n\n // Handle context sync messages\n if (message.type === 'context_sync' && message.context) {\n this.handleContextSync(message, peerId);\n return;\n }\n\n // Handle context request messages\n if (message.type === 'request' && message.context?.summary) {\n this.handleContextRequest(message, peerId);\n return;\n }\n\n // Handle context response messages (responses to context requests)\n if (message.type === 'response' && message.context?.files !== undefined) {\n this.handleContextResponse(message);\n return;\n }\n\n // Notify message handlers for other message types\n this.notifyMessageReceived(message, peerId);\n }\n\n /**\n * Handle incoming task delegation request\n */\n private async handleTaskDelegate(message: BridgeMessage, peerId: string): Promise<void> {\n const task = message.task!;\n logger.debug({ taskId: task.id, peerId }, 'Received task delegation');\n\n // If no handler registered, try to forward to other peers\n if (!this.taskReceivedHandler) {\n // Find all other peers to forward to (not the sender)\n const otherPeers = Array.from(this.peers.keys()).filter(id => id !== peerId);\n\n if (otherPeers.length > 0) {\n // Set up response forwarding - store the original sender\n const forwardKey = `forward:${task.id}`;\n (this as unknown as Record<string, string>)[forwardKey] = peerId;\n\n // Forward to ALL other peers (broadcast) - the peer with handlers will respond\n let forwarded = false;\n for (const targetPeerId of otherPeers) {\n try {\n await this.sendToPeer(targetPeerId, message);\n logger.info({ taskId: task.id, targetPeerId, totalTargets: otherPeers.length }, 'Forwarding task to peer');\n forwarded = true;\n } catch (err) {\n logger.error({ error: (err as Error).message, taskId: task.id, targetPeerId }, 'Failed to forward task to peer');\n }\n }\n\n if (forwarded) {\n return;\n }\n\n // Clean up forward key if no peer accepted the message\n delete (this as unknown as Record<string, string>)[forwardKey];\n }\n\n logger.warn({ taskId: task.id }, 'No task handler registered and no peers to forward to');\n const response = createTaskResponseMessage(\n this.config.instanceName,\n task.id,\n {\n success: false,\n data: null,\n error: 'No task handler registered on peer',\n }\n );\n await this.sendToPeer(peerId, response).catch((err) => {\n logger.error({ error: (err as Error).message, taskId: task.id }, 'Failed to send error response');\n });\n return;\n }\n\n try {\n // Execute the task handler\n const result = await this.taskReceivedHandler(task, peerId);\n\n // Send successful response\n const response = createTaskResponseMessage(\n this.config.instanceName,\n task.id,\n result\n );\n await this.sendToPeer(peerId, response);\n logger.debug({ taskId: task.id, success: result.success }, 'Task response sent');\n } catch (error) {\n // Send error response\n const response = createTaskResponseMessage(\n this.config.instanceName,\n task.id,\n {\n success: false,\n data: null,\n error: (error as Error).message,\n }\n );\n await this.sendToPeer(peerId, response).catch((err) => {\n logger.error({ error: (err as Error).message, taskId: task.id }, 'Failed to send error response');\n });\n logger.error({ taskId: task.id, error: (error as Error).message }, 'Task handler error');\n }\n }\n\n /**\n * Handle task response message (correlate with pending task)\n */\n private async handleTaskResponse(message: BridgeMessage): Promise<void> {\n const taskId = message.result!.taskId!;\n\n // Check if this is a forwarded response that needs to go back to original sender\n const forwardKey = `forward:${taskId}`;\n const originalSender = (this as unknown as Record<string, string>)[forwardKey];\n if (originalSender) {\n // When broadcasting to multiple peers, ignore \"no handler\" errors\n // and wait for the peer that actually has a handler to respond\n if (!message.result!.success && message.result!.error === 'No task handler registered on peer') {\n logger.debug({ taskId }, 'Ignoring no-handler response from peer, waiting for handler peer');\n return;\n }\n\n delete (this as unknown as Record<string, string>)[forwardKey];\n logger.info({ taskId, originalSender }, 'Forwarding task response to original sender');\n await this.sendToPeer(originalSender, message).catch((err) => {\n logger.error({ error: (err as Error).message, taskId }, 'Failed to forward response');\n });\n return;\n }\n\n const pending = this.pendingTasks.get(taskId);\n\n if (!pending) {\n logger.warn({ taskId }, 'Received response for unknown task');\n return;\n }\n\n // Clear timeout and remove from pending\n clearTimeout(pending.timeoutId);\n this.pendingTasks.delete(taskId);\n\n // Resolve the promise with the result\n const result: TaskResult = {\n taskId: message.result!.taskId,\n success: message.result!.success,\n data: message.result!.data,\n artifacts: message.result!.artifacts,\n followUp: message.result!.followUp,\n error: message.result!.error,\n };\n\n logger.debug({ taskId, success: result.success }, 'Task result received');\n pending.resolve(result);\n }\n\n /**\n * Handle incoming context sync message\n */\n private handleContextSync(message: BridgeMessage, peerId: string): void {\n const context = message.context!;\n logger.debug({ peerId, messageId: message.id }, 'Received context sync');\n\n // Notify all context received handlers\n this.notifyContextReceived(context, peerId);\n }\n\n /**\n * Handle incoming context request message\n */\n private async handleContextRequest(message: BridgeMessage, peerId: string): Promise<void> {\n const query = message.context!.summary!;\n logger.debug({ peerId, messageId: message.id, query }, 'Received context request');\n\n // If no handler registered, try to forward to other peers\n if (!this.contextRequestedHandler) {\n // Find all other peers to forward to (not the sender)\n const otherPeers = Array.from(this.peers.keys()).filter(id => id !== peerId);\n\n if (otherPeers.length > 0) {\n // Set up response forwarding - store the original sender\n const forwardKey = `ctxfwd:${message.id}`;\n (this as unknown as Record<string, string>)[forwardKey] = peerId;\n\n // Forward to ALL other peers (broadcast)\n let forwarded = false;\n for (const targetPeerId of otherPeers) {\n try {\n await this.sendToPeer(targetPeerId, message);\n logger.info({ messageId: message.id, targetPeerId, totalTargets: otherPeers.length }, 'Forwarding context request to peer');\n forwarded = true;\n } catch (err) {\n logger.error({ error: (err as Error).message, messageId: message.id, targetPeerId }, 'Failed to forward context request to peer');\n }\n }\n\n if (forwarded) {\n return;\n }\n\n // Clean up forward key if no peer accepted the message\n delete (this as unknown as Record<string, string>)[forwardKey];\n }\n\n logger.warn({ messageId: message.id }, 'No context request handler registered and no peers to forward to');\n const response = createContextSyncMessage(this.config.instanceName, { files: [] });\n // Change type to response and add request ID for correlation\n const responseMessage: BridgeMessage = {\n ...response,\n type: 'response',\n context: {\n ...response.context,\n variables: { requestId: message.id },\n },\n };\n await this.sendToPeer(peerId, responseMessage).catch((err) => {\n logger.error({ error: (err as Error).message, messageId: message.id }, 'Failed to send empty context response');\n });\n return;\n }\n\n try {\n // Execute the context request handler\n const files = await this.contextRequestedHandler(query, peerId);\n\n // Create and send response\n const response = createContextSyncMessage(this.config.instanceName, { files });\n const responseMessage: BridgeMessage = {\n ...response,\n type: 'response',\n context: {\n ...response.context,\n variables: { requestId: message.id },\n },\n };\n await this.sendToPeer(peerId, responseMessage);\n logger.debug({ messageId: message.id, fileCount: files.length }, 'Context response sent');\n } catch (error) {\n // Send error response with empty files\n const response = createContextSyncMessage(this.config.instanceName, {\n files: [],\n summary: (error as Error).message,\n });\n const responseMessage: BridgeMessage = {\n ...response,\n type: 'response',\n context: {\n ...response.context,\n variables: { requestId: message.id, error: (error as Error).message },\n },\n };\n await this.sendToPeer(peerId, responseMessage).catch((err) => {\n logger.error({ error: (err as Error).message, messageId: message.id }, 'Failed to send error context response');\n });\n logger.error({ messageId: message.id, error: (error as Error).message }, 'Context request handler error');\n }\n }\n\n /**\n * Handle context response message (correlate with pending context request)\n */\n private async handleContextResponse(message: BridgeMessage): Promise<void> {\n const requestId = message.context?.variables?.requestId as string;\n if (!requestId) {\n logger.warn({ messageId: message.id }, 'Context response without requestId');\n return;\n }\n\n // Check if this is a forwarded response that needs to go back to original sender\n const forwardKey = `ctxfwd:${requestId}`;\n const originalSender = (this as unknown as Record<string, string>)[forwardKey];\n if (originalSender) {\n // When broadcasting to multiple peers, ignore empty responses from\n // non-handler peers and wait for the real handler to respond with files\n const files = message.context?.files ?? [];\n const hasError = !!message.context?.variables?.error;\n if (files.length === 0 && !hasError) {\n logger.debug({ requestId }, 'Ignoring empty context response from non-handler peer, waiting for handler peer');\n return;\n }\n\n delete (this as unknown as Record<string, string>)[forwardKey];\n logger.info({ requestId, originalSender }, 'Forwarding context response to original sender');\n await this.sendToPeer(originalSender, message).catch((err) => {\n logger.error({ error: (err as Error).message, requestId }, 'Failed to forward context response');\n });\n return;\n }\n\n const pending = this.pendingContextRequests.get(requestId);\n if (!pending) {\n logger.warn({ requestId }, 'Received response for unknown context request');\n return;\n }\n\n // Clear timeout and remove from pending\n clearTimeout(pending.timeoutId);\n this.pendingContextRequests.delete(requestId);\n\n // Check for error\n const error = message.context?.variables?.error as string | undefined;\n if (error) {\n pending.reject(new Error(error));\n return;\n }\n\n // Resolve the promise with the files\n const files = message.context?.files ?? [];\n logger.debug({ requestId, fileCount: files.length }, 'Context response received');\n pending.resolve(files);\n }\n\n // ============================================================================\n // Private Methods - Event Notification\n // ============================================================================\n\n private notifyPeerConnected(peer: PeerInfo): void {\n // Update status file with new peer\n this.writeStatusFile();\n\n for (const handler of this.peerConnectedHandlers) {\n try {\n handler(peer);\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Peer connected handler error');\n }\n }\n }\n\n private notifyPeerDisconnected(peer: PeerInfo): void {\n // Reject any pending tasks for this peer\n for (const [taskId, pending] of this.pendingTasks) {\n if (pending.peerId === peer.id) {\n clearTimeout(pending.timeoutId);\n this.pendingTasks.delete(taskId);\n pending.reject(new Error(`Peer '${peer.id}' disconnected while task '${taskId}' was pending`));\n }\n }\n\n // Reject any pending context requests for this peer\n for (const [requestId, pending] of this.pendingContextRequests) {\n if (pending.peerId === peer.id) {\n clearTimeout(pending.timeoutId);\n this.pendingContextRequests.delete(requestId);\n pending.reject(new Error(`Peer '${peer.id}' disconnected while context request '${requestId}' was pending`));\n }\n }\n\n for (const handler of this.peerDisconnectedHandlers) {\n try {\n handler(peer);\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Peer disconnected handler error');\n }\n }\n\n // Update status file after peer removed\n this.writeStatusFile();\n }\n\n private notifyMessageReceived(message: BridgeMessage, peerId: string): void {\n for (const handler of this.messageReceivedHandlers) {\n try {\n handler(message, peerId);\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Message received handler error');\n }\n }\n }\n\n private notifyContextReceived(context: Context, peerId: string): void {\n for (const handler of this.contextReceivedHandlers) {\n try {\n handler(context, peerId);\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Context received handler error');\n }\n }\n }\n\n // ============================================================================\n // Private Methods - Cleanup\n // ============================================================================\n\n /**\n * Clean up all resources\n */\n private async cleanup(): Promise<void> {\n logger.debug('Starting cleanup');\n\n // Stop auto-sync\n this.stopAutoSync();\n logger.debug('Auto-sync stopped');\n\n // Reject all pending tasks\n const pendingTaskCount = this.pendingTasks.size;\n for (const [taskId, pending] of this.pendingTasks) {\n clearTimeout(pending.timeoutId);\n pending.reject(new Error('Bridge is shutting down'));\n }\n this.pendingTasks.clear();\n if (pendingTaskCount > 0) {\n logger.debug({ count: pendingTaskCount }, 'Pending tasks cancelled');\n }\n\n // Reject all pending context requests\n const pendingContextCount = this.pendingContextRequests.size;\n for (const [requestId, pending] of this.pendingContextRequests) {\n clearTimeout(pending.timeoutId);\n pending.reject(new Error('Bridge is shutting down'));\n }\n this.pendingContextRequests.clear();\n if (pendingContextCount > 0) {\n logger.debug({ count: pendingContextCount }, 'Pending context requests cancelled');\n }\n\n // Disconnect client transport\n if (this.clientTransport) {\n logger.debug('Disconnecting client transport');\n try {\n await this.clientTransport.disconnect();\n logger.debug('Client transport disconnected');\n } catch {\n // Ignore disconnect errors during cleanup\n }\n this.clientTransport = null;\n }\n\n // Close all peer WebSocket connections\n const peerCount = this.peers.size;\n if (peerCount > 0) {\n logger.debug({ count: peerCount }, 'Closing peer connections');\n }\n for (const [peerId, peer] of this.peers) {\n if (peer.ws) {\n try {\n peer.ws.close(1000, 'Bridge stopping');\n } catch {\n // Ignore close errors during cleanup\n }\n }\n if (peer.transport) {\n try {\n await peer.transport.disconnect();\n } catch {\n // Ignore disconnect errors during cleanup\n }\n }\n logger.debug({ peerId }, 'Peer disconnected');\n }\n this.peers.clear();\n\n // Close server\n if (this.server) {\n logger.debug('Closing WebSocket server');\n await new Promise<void>((resolve) => {\n this.server!.close(() => {\n resolve();\n });\n });\n this.server = null;\n logger.debug('WebSocket server closed');\n }\n\n // Close HTTPS server if it exists\n if (this.httpsServer) {\n logger.debug('Closing HTTPS server');\n await new Promise<void>((resolve) => {\n this.httpsServer!.close(() => {\n resolve();\n });\n });\n this.httpsServer = null;\n logger.debug('HTTPS server closed');\n }\n\n // Remove status file\n this.removeStatusFile();\n\n logger.debug('Cleanup complete');\n }\n\n // ============================================================================\n // Status File Management\n // ============================================================================\n\n /**\n * Get the status file path\n */\n private getStatusFilePath(): string {\n const bridgeDir = path.join(os.homedir(), '.claude-bridge');\n return path.join(bridgeDir, 'status.json');\n }\n\n /**\n * Ensure the .claude-bridge directory exists\n */\n private 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 current status to status file\n */\n private writeStatusFile(): void {\n try {\n this.ensureBridgeDir();\n const statusFile = this.getStatusFilePath();\n const status = {\n port: this.config.listen?.port,\n instanceName: this.config.instanceName,\n mode: this.config.mode,\n peers: this.getPeers().map(p => ({\n id: p.id,\n name: p.name,\n connectedAt: new Date(p.connectedAt).toISOString(),\n lastActivity: new Date(p.lastActivity).toISOString(),\n })),\n };\n fs.writeFileSync(statusFile, JSON.stringify(status, null, 2), 'utf-8');\n logger.debug({ statusFile }, 'Status file updated');\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Failed to write status file');\n }\n }\n\n /**\n * Remove the status file\n */\n private removeStatusFile(): void {\n try {\n const statusFile = this.getStatusFilePath();\n if (fs.existsSync(statusFile)) {\n fs.unlinkSync(statusFile);\n logger.debug({ statusFile }, 'Status file removed');\n }\n } catch (error) {\n logger.error({ error: (error as Error).message }, 'Failed to remove status file');\n }\n }\n\n // ============================================================================\n // Getters for State Inspection\n // ============================================================================\n\n /**\n * Check if the bridge is started\n */\n isStarted(): boolean {\n return this.started;\n }\n\n /**\n * Get the instance name\n */\n getInstanceName(): string {\n return this.config.instanceName;\n }\n\n /**\n * Get the operation mode\n */\n getMode(): BridgeMode {\n return this.config.mode;\n }\n\n /**\n * Get the number of connected peers\n */\n getPeerCount(): number {\n return this.peers.size;\n }\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { parse as parseYaml } from 'yaml';\n\n/**\n * TLS configuration for secure connections\n */\nexport interface TLSConfig {\n /** Path to certificate PEM file */\n cert?: string;\n /** Path to private key PEM file */\n key?: string;\n /** Path to CA certificate PEM file */\n ca?: string;\n /** Whether to reject unauthorized certificates (default: true) */\n rejectUnauthorized?: boolean;\n /** Passphrase for encrypted private key */\n passphrase?: string;\n}\n\n/**\n * Authentication type\n */\nexport type AuthType = 'none' | 'token' | 'password' | 'ip' | 'combined';\n\n/**\n * Authentication configuration\n */\nexport interface AuthConfig {\n /** Authentication type */\n type: AuthType;\n /** Authentication token */\n token?: string;\n /** Authentication password */\n password?: string;\n /** Allowed IP addresses/ranges in CIDR notation */\n allowedIps?: string[];\n /** If true, ALL configured methods must pass; if false, ANY passing method is sufficient */\n requireAll?: boolean;\n}\n\n/**\n * Configuration for the bridge's listening socket\n */\nexport interface ListenConfig {\n port: number;\n host: string;\n /** TLS configuration for secure connections */\n tls?: TLSConfig;\n /** Authentication configuration */\n auth?: AuthConfig;\n}\n\n/**\n * Configuration for connecting to a remote bridge\n */\nexport interface ConnectConfig {\n url?: string;\n hostGateway?: boolean;\n port?: number;\n /** TLS configuration for secure connections */\n tls?: TLSConfig;\n /** Authentication configuration */\n auth?: AuthConfig;\n}\n\n/**\n * Configuration for context sharing behavior\n */\nexport interface ContextSharingConfig {\n autoSync: boolean;\n syncInterval: number;\n maxChunkTokens: number;\n includePatterns: string[];\n excludePatterns: string[];\n}\n\n/**\n * Configuration for interaction behavior\n */\nexport interface InteractionConfig {\n requireConfirmation: boolean;\n notifyOnActivity: boolean;\n taskTimeout: number;\n}\n\n/**\n * Full bridge configuration\n */\nexport interface BridgeConfig {\n instanceName?: string;\n mode?: 'host' | 'client' | 'peer';\n listen: ListenConfig;\n connect?: ConnectConfig;\n contextSharing: ContextSharingConfig;\n interaction: InteractionConfig;\n}\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_CONFIG: BridgeConfig = {\n listen: {\n port: 8765,\n host: '0.0.0.0',\n },\n contextSharing: {\n autoSync: true,\n syncInterval: 5000,\n maxChunkTokens: 4000,\n includePatterns: ['src/**/*.ts', 'src/**/*.tsx', '*.json'],\n excludePatterns: ['node_modules/**', 'dist/**', '.git/**'],\n },\n interaction: {\n requireConfirmation: false,\n notifyOnActivity: true,\n taskTimeout: 300000, // 5 minutes\n },\n};\n\n/**\n * Deep merges a partial config with the default config\n *\n * @param partial - Partial configuration to merge\n * @returns Complete configuration with defaults for missing values\n */\nexport function mergeConfig(partial: Partial<BridgeConfig>): BridgeConfig {\n return {\n ...DEFAULT_CONFIG,\n ...partial,\n listen: {\n ...DEFAULT_CONFIG.listen,\n ...(partial.listen ?? {}),\n },\n connect: partial.connect\n ? {\n ...partial.connect,\n }\n : undefined,\n contextSharing: {\n ...DEFAULT_CONFIG.contextSharing,\n ...(partial.contextSharing ?? {}),\n },\n interaction: {\n ...DEFAULT_CONFIG.interaction,\n ...(partial.interaction ?? {}),\n },\n };\n}\n\n/**\n * Attempts to read and parse a YAML config file\n *\n * @param filePath - Path to the config file\n * @returns Parsed config or null if file doesn't exist\n */\nfunction readConfigFile(filePath: string): Partial<BridgeConfig> | null {\n try {\n if (!fs.existsSync(filePath)) {\n return null;\n }\n const content = fs.readFileSync(filePath, 'utf-8');\n const parsed = parseYaml(content);\n return parsed as Partial<BridgeConfig>;\n } catch {\n // Return null if file can't be read or parsed\n return null;\n }\n}\n\n/**\n * Gets the default config file paths to search\n *\n * @returns Array of config file paths in priority order\n */\nfunction getDefaultConfigPaths(): string[] {\n const homeDir = os.homedir();\n const cwd = process.cwd();\n\n return [\n // Project-local config takes priority\n path.join(cwd, '.claude-bridge.yml'),\n path.join(cwd, '.claude-bridge.yaml'),\n // User home config as fallback\n path.join(homeDir, '.claude-bridge', 'config.yml'),\n path.join(homeDir, '.claude-bridge', 'config.yaml'),\n ];\n}\n\n/**\n * Loads configuration from file(s) and merges with defaults\n *\n * Searches for config files in the following order:\n * 1. Explicit path (if provided)\n * 2. .claude-bridge.yml in current working directory\n * 3. ~/.claude-bridge/config.yml\n *\n * @param configPath - Optional explicit path to config file\n * @returns Complete configuration with defaults for missing values\n *\n * @example\n * ```typescript\n * // Load from default locations\n * const config = await loadConfig();\n *\n * // Load from specific path\n * const config = await loadConfig('/path/to/config.yml');\n * ```\n */\nexport async function loadConfig(configPath?: string): Promise<BridgeConfig> {\n // If explicit path provided, try to load it\n if (configPath) {\n const parsed = readConfigFile(configPath);\n if (parsed) {\n return mergeConfig(parsed);\n }\n // If explicit path doesn't exist, return defaults\n return { ...DEFAULT_CONFIG };\n }\n\n // Search default paths\n const searchPaths = getDefaultConfigPaths();\n\n for (const searchPath of searchPaths) {\n const parsed = readConfigFile(searchPath);\n if (parsed) {\n return mergeConfig(parsed);\n }\n }\n\n // No config file found, return defaults\n return { ...DEFAULT_CONFIG };\n}\n\n/**\n * Synchronous version of loadConfig for simpler usage patterns\n *\n * @param configPath - Optional explicit path to config file\n * @returns Complete configuration with defaults for missing values\n */\nexport function loadConfigSync(configPath?: string): BridgeConfig {\n // If explicit path provided, try to load it\n if (configPath) {\n const parsed = readConfigFile(configPath);\n if (parsed) {\n return mergeConfig(parsed);\n }\n // If explicit path doesn't exist, return defaults\n return { ...DEFAULT_CONFIG };\n }\n\n // Search default paths\n const searchPaths = getDefaultConfigPaths();\n\n for (const searchPath of searchPaths) {\n const parsed = readConfigFile(searchPath);\n if (parsed) {\n return mergeConfig(parsed);\n }\n }\n\n // No config file found, return defaults\n return { ...DEFAULT_CONFIG };\n}\n","/**\n * MCP Tool definitions for Claude Code Bridge\n * Defines input schemas and handler functions for all bridge tools\n */\n\nimport { z } from 'zod';\nimport type { Bridge } from '../bridge/core.js';\nimport type { TaskResult } from '../bridge/protocol.js';\nimport { createLogger } from '../utils/logger.js';\n\nconst logger = createLogger('mcp:tools');\n\n// ============================================================================\n// Tool Input Schemas\n// ============================================================================\n\nexport const ReadFileInputSchema = z.object({\n path: z.string().describe('Path to the file to read'),\n});\n\nexport const WriteFileInputSchema = z.object({\n path: z.string().describe('Path to the file to write'),\n content: z.string().describe('Content to write to the file'),\n});\n\nexport const DeleteFileInputSchema = z.object({\n path: z.string().describe('Path to the file to delete'),\n});\n\nexport const ListDirectoryInputSchema = z.object({\n path: z.string().describe('Path to the directory to list'),\n});\n\nexport const DelegateTaskInputSchema = z.object({\n description: z.string().describe('Description of the task to delegate'),\n scope: z.enum(['execute', 'analyze', 'suggest']).describe('Task scope'),\n data: z.record(z.unknown()).optional().describe('Additional task data'),\n});\n\nexport const RequestContextInputSchema = z.object({\n query: z.string().describe('Query describing what files to retrieve'),\n});\n\n// ============================================================================\n// Tool Definitions\n// ============================================================================\n\nexport interface ToolDefinition {\n name: string;\n description: string;\n inputSchema: z.ZodType<unknown>;\n}\n\nexport const TOOL_DEFINITIONS: ToolDefinition[] = [\n {\n name: 'bridge_read_file',\n description: 'Read a file from the remote connected instance',\n inputSchema: ReadFileInputSchema,\n },\n {\n name: 'bridge_write_file',\n description: 'Write a file to the remote connected instance',\n inputSchema: WriteFileInputSchema,\n },\n {\n name: 'bridge_delete_file',\n description: 'Delete a file on the remote connected instance',\n inputSchema: DeleteFileInputSchema,\n },\n {\n name: 'bridge_list_directory',\n description: 'List files and folders in a directory on the remote connected instance',\n inputSchema: ListDirectoryInputSchema,\n },\n {\n name: 'bridge_delegate_task',\n description: 'Delegate a custom task to the remote connected instance',\n inputSchema: DelegateTaskInputSchema,\n },\n {\n name: 'bridge_request_context',\n description: 'Request files matching a query from the remote connected instance',\n inputSchema: RequestContextInputSchema,\n },\n {\n name: 'bridge_status',\n description: 'Get bridge status and connected peers',\n inputSchema: z.object({}),\n },\n];\n\n// ============================================================================\n// Tool Content Response Types\n// ============================================================================\n\nexport interface TextContent {\n type: 'text';\n text: string;\n}\n\nexport interface ToolResponse {\n content: TextContent[];\n isError?: boolean;\n}\n\n// ============================================================================\n// Tool Handlers\n// ============================================================================\n\n/**\n * Create tool handlers bound to a bridge instance\n */\nexport function createToolHandlers(bridge: Bridge) {\n const handlers: Record<string, (args: Record<string, unknown>) => Promise<ToolResponse>> = {};\n\n /**\n * Helper to create error response\n */\n function errorResponse(message: string): ToolResponse {\n return {\n content: [{ type: 'text', text: `Error: ${message}` }],\n isError: true,\n };\n }\n\n /**\n * Helper to create success response\n */\n function successResponse(text: string): ToolResponse {\n return {\n content: [{ type: 'text', text }],\n };\n }\n\n /**\n * Delegate a task and handle the result\n */\n async function delegateFileTask(\n action: string,\n data: Record<string, unknown>,\n description: string\n ): Promise<TaskResult> {\n const taskId = `mcp-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\n\n return bridge.delegateTask({\n id: taskId,\n description,\n scope: 'execute',\n data: { action, ...data },\n });\n }\n\n // bridge_read_file\n handlers['bridge_read_file'] = async (args) => {\n const input = ReadFileInputSchema.parse(args);\n logger.debug({ path: input.path }, 'Reading file');\n\n try {\n const result = await delegateFileTask(\n 'read_file',\n { path: input.path },\n `Read file: ${input.path}`\n );\n\n if (!result.success) {\n return errorResponse(result.error || 'Failed to read file');\n }\n\n return successResponse(result.data.content);\n } catch (err) {\n logger.error({ error: (err as Error).message, path: input.path }, 'Failed to read file');\n return errorResponse((err as Error).message);\n }\n };\n\n // bridge_write_file\n handlers['bridge_write_file'] = async (args) => {\n const input = WriteFileInputSchema.parse(args);\n logger.debug({ path: input.path, contentLength: input.content.length }, 'Writing file');\n\n try {\n const result = await delegateFileTask(\n 'write_file',\n { path: input.path, content: input.content },\n `Write file: ${input.path}`\n );\n\n if (!result.success) {\n return errorResponse(result.error || 'Failed to write file');\n }\n\n return successResponse(`File written successfully: ${input.path} (${result.data.bytesWritten} bytes)`);\n } catch (err) {\n logger.error({ error: (err as Error).message, path: input.path }, 'Failed to write file');\n return errorResponse((err as Error).message);\n }\n };\n\n // bridge_delete_file\n handlers['bridge_delete_file'] = async (args) => {\n const input = DeleteFileInputSchema.parse(args);\n logger.debug({ path: input.path }, 'Deleting file');\n\n try {\n const result = await delegateFileTask(\n 'delete_file',\n { path: input.path },\n `Delete file: ${input.path}`\n );\n\n if (!result.success) {\n return errorResponse(result.error || 'Failed to delete file');\n }\n\n return successResponse(`File deleted successfully: ${input.path}`);\n } catch (err) {\n logger.error({ error: (err as Error).message, path: input.path }, 'Failed to delete file');\n return errorResponse((err as Error).message);\n }\n };\n\n // bridge_list_directory\n handlers['bridge_list_directory'] = async (args) => {\n const input = ListDirectoryInputSchema.parse(args);\n logger.debug({ path: input.path }, 'Listing directory');\n\n try {\n const result = await delegateFileTask(\n 'list_directory',\n { path: input.path },\n `List directory: ${input.path}`\n );\n\n if (!result.success) {\n return errorResponse(result.error || 'Failed to list directory');\n }\n\n // Format directory listing\n const entries = result.data.entries as Array<{ name: string; type: string }>;\n if (!entries || entries.length === 0) {\n return successResponse(`Directory is empty: ${input.path}`);\n }\n\n const listing = entries\n .map((e: { name: string; type: string }) => `${e.type === 'directory' ? '📁' : '📄'} ${e.name}`)\n .join('\\n');\n\n return successResponse(`Contents of ${input.path}:\\n${listing}`);\n } catch (err) {\n logger.error({ error: (err as Error).message, path: input.path }, 'Failed to list directory');\n return errorResponse((err as Error).message);\n }\n };\n\n // bridge_delegate_task\n handlers['bridge_delegate_task'] = async (args) => {\n const input = DelegateTaskInputSchema.parse(args);\n logger.debug({ description: input.description, scope: input.scope }, 'Delegating task');\n\n try {\n const taskId = `mcp-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\n\n const result = await bridge.delegateTask({\n id: taskId,\n description: input.description,\n scope: input.scope,\n data: input.data,\n });\n\n if (!result.success) {\n return errorResponse(result.error || 'Task failed');\n }\n\n return successResponse(JSON.stringify(result.data, null, 2));\n } catch (err) {\n logger.error({ error: (err as Error).message }, 'Failed to delegate task');\n return errorResponse((err as Error).message);\n }\n };\n\n // bridge_request_context\n handlers['bridge_request_context'] = async (args) => {\n const input = RequestContextInputSchema.parse(args);\n logger.debug({ query: input.query }, 'Requesting context');\n\n try {\n const files = await bridge.requestContext(input.query);\n\n if (files.length === 0) {\n return successResponse('No files found matching the query.');\n }\n\n // Format file results\n const fileResults = files.map(f => {\n const header = `=== ${f.path} ===`;\n const content = f.content;\n return `${header}\\n${content}`;\n }).join('\\n\\n');\n\n return successResponse(`Found ${files.length} file(s):\\n\\n${fileResults}`);\n } catch (err) {\n logger.error({ error: (err as Error).message }, 'Failed to request context');\n return errorResponse((err as Error).message);\n }\n };\n\n // bridge_status\n handlers['bridge_status'] = async () => {\n logger.debug('Getting bridge status');\n\n const peers = bridge.getPeers();\n const peerCount = bridge.getPeerCount();\n const isStarted = bridge.isStarted();\n const mode = bridge.getMode();\n const instanceName = bridge.getInstanceName();\n\n const status = {\n instanceName,\n mode,\n started: isStarted,\n peerCount,\n peers: peers.map(p => ({\n id: p.id,\n name: p.name,\n connectedAt: new Date(p.connectedAt).toISOString(),\n lastActivity: new Date(p.lastActivity).toISOString(),\n })),\n };\n\n return successResponse(JSON.stringify(status, null, 2));\n };\n\n return handlers;\n}\n\n/**\n * Get JSON schema representation for a Zod schema\n * This creates a simple JSON schema object for MCP tool registration\n */\nexport function zodToJsonSchema(schema: z.ZodType<unknown>): Record<string, unknown> {\n // Handle ZodObject\n if (schema instanceof z.ZodObject) {\n const shape = schema.shape;\n const properties: Record<string, unknown> = {};\n const required: string[] = [];\n\n for (const [key, value] of Object.entries(shape)) {\n const zodValue = value as z.ZodType<unknown>;\n properties[key] = zodToJsonSchema(zodValue);\n\n // Check if required (not optional)\n if (!(zodValue instanceof z.ZodOptional)) {\n required.push(key);\n }\n }\n\n return {\n type: 'object',\n properties,\n ...(required.length > 0 ? { required } : {}),\n };\n }\n\n // Handle ZodString\n if (schema instanceof z.ZodString) {\n const result: Record<string, unknown> = { type: 'string' };\n if (schema.description) {\n result.description = schema.description;\n }\n return result;\n }\n\n // Handle ZodEnum\n if (schema instanceof z.ZodEnum) {\n return {\n type: 'string',\n enum: schema.options,\n };\n }\n\n // Handle ZodOptional\n if (schema instanceof z.ZodOptional) {\n return zodToJsonSchema(schema.unwrap());\n }\n\n // Handle ZodRecord\n if (schema instanceof z.ZodRecord) {\n return {\n type: 'object',\n additionalProperties: true,\n };\n }\n\n // Handle ZodUnknown\n if (schema instanceof z.ZodUnknown) {\n return {};\n }\n\n // Default fallback\n return { type: 'string' };\n}\n","/**\n * MCP Server for Claude Code Bridge\n * Exposes bridge functionality as MCP tools for Claude Code integration\n */\n\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n type CallToolResult,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { Bridge, type BridgeConfig } from '../bridge/core.js';\nimport { createLogger } from '../utils/logger.js';\nimport type { TLSConfig, AuthConfig } from '../transport/interface.js';\nimport {\n TOOL_DEFINITIONS,\n createToolHandlers,\n zodToJsonSchema,\n} from './tools.js';\n\nconst logger = createLogger('mcp:server');\n\n// ============================================================================\n// MCP Server Configuration\n// ============================================================================\n\nexport interface McpServerConfig {\n /** Bridge WebSocket URL to connect to */\n bridgeUrl: string;\n /** MCP server name (default: claude-bridge) */\n name?: string;\n /** MCP server version */\n version?: string;\n /** Instance name for the bridge client */\n instanceName?: string;\n /** Task timeout in milliseconds */\n taskTimeout?: number;\n /** TLS configuration for secure connections */\n tls?: TLSConfig;\n /** Authentication configuration */\n auth?: AuthConfig;\n}\n\n// ============================================================================\n// Bridge MCP Server\n// ============================================================================\n\n/**\n * MCP Server that exposes bridge functionality as tools\n */\nexport class BridgeMcpServer {\n private server: Server;\n private bridge: Bridge;\n private config: McpServerConfig;\n private toolHandlers: ReturnType<typeof createToolHandlers> | null = null;\n\n constructor(config: McpServerConfig) {\n this.config = config;\n\n // Create MCP server\n this.server = new Server(\n {\n name: config.name ?? 'claude-bridge',\n version: config.version ?? '0.4.0',\n },\n {\n capabilities: {\n tools: {},\n },\n }\n );\n\n // Create bridge client to connect to daemon\n const bridgeConfig: BridgeConfig = {\n mode: 'client',\n instanceName: config.instanceName ?? `mcp-server-${process.pid}`,\n connect: {\n url: config.bridgeUrl,\n tls: config.tls,\n auth: config.auth,\n },\n taskTimeout: config.taskTimeout ?? 60000,\n };\n\n this.bridge = new Bridge(bridgeConfig);\n\n this.registerHandlers();\n }\n\n /**\n * Register MCP request handlers\n */\n private registerHandlers(): void {\n // List tools handler\n this.server.setRequestHandler(ListToolsRequestSchema, async () => {\n logger.debug('Listing tools');\n\n return {\n tools: TOOL_DEFINITIONS.map(tool => ({\n name: tool.name,\n description: tool.description,\n inputSchema: zodToJsonSchema(tool.inputSchema),\n })),\n };\n });\n\n // Call tool handler\n this.server.setRequestHandler(CallToolRequestSchema, async (request): Promise<CallToolResult> => {\n const { name, arguments: args } = request.params;\n logger.debug({ tool: name }, 'Tool call received');\n\n // Ensure tool handlers are created\n if (!this.toolHandlers) {\n this.toolHandlers = createToolHandlers(this.bridge);\n }\n\n const handler = this.toolHandlers[name];\n if (!handler) {\n logger.warn({ tool: name }, 'Unknown tool requested');\n return {\n content: [{ type: 'text', text: `Unknown tool: ${name}` }],\n isError: true,\n };\n }\n\n try {\n const result = await handler(args ?? {});\n logger.debug({ tool: name, isError: result.isError }, 'Tool call completed');\n return {\n content: result.content,\n isError: result.isError,\n };\n } catch (err) {\n logger.error({ tool: name, error: (err as Error).message }, 'Tool call failed');\n return {\n content: [{ type: 'text', text: `Error: ${(err as Error).message}` }],\n isError: true,\n };\n }\n });\n }\n\n /**\n * Start the MCP server\n * Connects to bridge daemon and starts listening on stdio\n */\n async start(): Promise<void> {\n // Log to stderr since stdout is for MCP protocol\n console.error('[MCP] Starting bridge MCP server...');\n console.error(`[MCP] Connecting to bridge at ${this.config.bridgeUrl}`);\n\n try {\n // Connect to bridge daemon\n await this.bridge.start();\n console.error('[MCP] Connected to bridge daemon');\n\n // Create tool handlers after bridge is connected\n this.toolHandlers = createToolHandlers(this.bridge);\n\n // Start MCP server on stdio\n const transport = new StdioServerTransport();\n await this.server.connect(transport);\n\n console.error('[MCP] MCP server started and listening on stdio');\n logger.info('MCP server started');\n } catch (err) {\n console.error(`[MCP] Failed to start: ${(err as Error).message}`);\n throw err;\n }\n }\n\n /**\n * Stop the MCP server\n */\n async stop(): Promise<void> {\n console.error('[MCP] Stopping MCP server...');\n\n try {\n await this.bridge.stop();\n await this.server.close();\n console.error('[MCP] MCP server stopped');\n logger.info('MCP server stopped');\n } catch (err) {\n console.error(`[MCP] Error during shutdown: ${(err as Error).message}`);\n }\n }\n\n /**\n * Get the bridge instance\n */\n getBridge(): Bridge {\n return this.bridge;\n }\n}\n\n/**\n * Create and start an MCP server\n */\nexport async function startMcpServer(config: McpServerConfig): Promise<BridgeMcpServer> {\n const server = new BridgeMcpServer(config);\n await server.start();\n return server;\n}\n"],"mappings":"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","names":["ConnectionState","logger","logger","https","uuidv4","fs","logger","uuidv4","peer","files","fs","path","os","z","logger","z","logger"]}
package/dist/cli.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  loadConfigSync,
11
11
  validateAuthConfig,
12
12
  validateTLSConfig
13
- } from "./chunk-2O352EPO.js";
13
+ } from "./chunk-OEEJEXXK.js";
14
14
 
15
15
  // src/cli/index.ts
16
16
  import { Command as Command7 } from "commander";
package/dist/index.js CHANGED
@@ -43,7 +43,7 @@ import {
43
43
  validatePassword,
44
44
  validateTLSConfig,
45
45
  validateToken
46
- } from "./chunk-2O352EPO.js";
46
+ } from "./chunk-OEEJEXXK.js";
47
47
 
48
48
  // src/bridge/context.ts
49
49
  import { readdirSync, readFileSync, statSync, realpathSync } from "fs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@willjackson/claude-code-bridge",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "Bidirectional communication system for Claude Code instances across environments",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",