@dolusoft/claude-collab 1.11.2 → 1.11.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/infrastructure/mesh/protocol.ts","../src/infrastructure/firewall/firewall.ts","../src/infrastructure/terminal-injector/windows-injector.ts","../src/infrastructure/terminal-injector/index.ts","../src/infrastructure/terminal-injector/injection-queue.ts","../src/infrastructure/mesh/mesh-node.ts","../src/presentation/mcp/tools/connect.tool.ts","../src/presentation/mcp/tools/ask.tool.ts","../src/presentation/mcp/tools/reply.tool.ts","../src/presentation/mcp/tools/history.tool.ts","../src/presentation/mcp/tools/status.tool.ts","../src/presentation/mcp/server.ts","../src/cli.ts"],"names":["uuidv4","z"],"mappings":"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","file":"cli.js","sourcesContent":["/**\r\n * Wire Protocol\r\n * Messages exchanged directly between peers.\r\n * @module infrastructure/mesh/protocol\r\n */\r\n\r\nexport type MessageFormat = 'plain' | 'markdown';\r\n\r\n// Sent when a peer connects (client → server, or outbound → inbound)\r\nexport interface HelloMsg {\r\n type: 'HELLO';\r\n name: string;\r\n}\r\n\r\n// Acknowledge the HELLO\r\nexport interface HelloAckMsg {\r\n type: 'HELLO_ACK';\r\n name: string;\r\n}\r\n\r\n// Sent after handshake — share known peers so the other side can complete the mesh\r\nexport interface PeerListMsg {\r\n type: 'PEER_LIST';\r\n peers: Array<{ name: string; ip: string }>;\r\n}\r\n\r\n// Broadcast to existing peers when a new peer connects — so they can connect directly\r\nexport interface PeerAnnounceMsg {\r\n type: 'PEER_ANNOUNCE';\r\n name: string;\r\n ip: string;\r\n}\r\n\r\n// Ask a question directly to the connected peer\r\nexport interface AskMsg {\r\n type: 'ASK';\r\n from: string;\r\n questionId: string;\r\n content: string;\r\n format: MessageFormat;\r\n}\r\n\r\n// Confirm question was received\r\nexport interface AskAckMsg {\r\n type: 'ASK_ACK';\r\n questionId: string;\r\n}\r\n\r\n// Push answer back to the asker\r\nexport interface AnswerMsg {\r\n type: 'ANSWER';\r\n from: string;\r\n questionId: string;\r\n content: string;\r\n format: MessageFormat;\r\n answeredAt: string;\r\n}\r\n\r\nexport type WireMsg = HelloMsg | HelloAckMsg | PeerListMsg | PeerAnnounceMsg | AskMsg | AskAckMsg | AnswerMsg;\r\n\r\nexport function serialize(msg: WireMsg): string {\r\n return JSON.stringify(msg);\r\n}\r\n\r\nexport function parse(data: string): WireMsg {\r\n return JSON.parse(data) as WireMsg;\r\n}\r\n","/**\r\n * Firewall helpers\r\n * Always elevated via UAC (PowerShell Start-Process -Verb RunAs) so the rule\r\n * is guaranteed to be applied. If the process is already elevated, Windows\r\n * skips the UAC prompt automatically.\r\n * @module infrastructure/firewall/firewall\r\n */\r\n\r\nimport { spawn } from 'child_process';\r\n\r\n/**\r\n * Run netsh via UAC elevation (PowerShell Start-Process -Verb RunAs).\r\n * If the calling process is already elevated, no prompt is shown.\r\n */\r\nfunction runNetshElevated(argArray: string[]): Promise<void> {\r\n const argList = argArray.map((a) => `\"${a}\"`).join(',');\r\n const psCommand = `Start-Process -FilePath \"netsh\" -ArgumentList @(${argList}) -Verb RunAs -Wait`;\r\n\r\n return new Promise((resolve, reject) => {\r\n const ps = spawn('powershell', ['-NoProfile', '-Command', psCommand]);\r\n\r\n ps.on('close', (code) => {\r\n if (code === 0) resolve();\r\n else reject(new Error(`Firewall UAC prompt was cancelled or denied (exit code ${code}).`));\r\n });\r\n\r\n ps.on('error', (err) => {\r\n reject(new Error(`Failed to launch PowerShell: ${err.message}`));\r\n });\r\n });\r\n}\r\n\r\nexport async function addFirewallRule(port: number): Promise<void> {\r\n await runNetshElevated([\r\n 'advfirewall', 'firewall', 'add', 'rule',\r\n `name=claude-collab-${port}`,\r\n 'protocol=TCP',\r\n 'dir=in',\r\n `localport=${port}`,\r\n 'action=allow',\r\n ]);\r\n}\r\n\r\nexport async function removeFirewallRule(port: number): Promise<void> {\r\n await runNetshElevated([\r\n 'advfirewall', 'firewall', 'delete', 'rule',\r\n `name=claude-collab-${port}`,\r\n ]);\r\n}\r\n","/**\r\n * Windows Terminal Injector\r\n * AttachConsole(ppid) → CreateFile(\"CONIN$\") → WriteConsoleInput\r\n * All keystrokes (text, Ctrl+U, Enter, Ctrl+Y) go through WriteConsoleInput.\r\n * No WScript.Shell / SendKeys / SetForegroundWindow — no focus dependency.\r\n * @module infrastructure/terminal-injector/windows-injector\r\n */\r\n\r\nimport { execFile } from 'child_process';\r\nimport { unlinkSync } from 'fs';\r\nimport { tmpdir } from 'os';\r\nimport { join } from 'path';\r\n\r\nconst CS_CONINJECT = `\r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.Runtime.InteropServices;\r\n\r\npublic class ConInject {\r\n [DllImport(\"kernel32.dll\")] public static extern bool FreeConsole();\r\n [DllImport(\"kernel32.dll\")] public static extern bool AttachConsole(uint pid);\r\n [DllImport(\"kernel32.dll\", CharSet=CharSet.Unicode, SetLastError=true)]\r\n public static extern IntPtr CreateFile(\r\n string lpFileName, uint dwDesiredAccess, uint dwShareMode,\r\n IntPtr lpSecurityAttributes, uint dwCreationDisposition,\r\n uint dwFlagsAndAttributes, IntPtr hTemplateFile);\r\n [DllImport(\"kernel32.dll\")] public static extern bool WriteConsoleInput(\r\n IntPtr hIn, INPUT_RECORD[] buf, uint len, out uint written);\r\n [DllImport(\"kernel32.dll\")] public static extern bool CloseHandle(IntPtr h);\r\n\r\n [StructLayout(LayoutKind.Explicit, Size=20)]\r\n public struct INPUT_RECORD {\r\n [FieldOffset(0)] public ushort EventType;\r\n [FieldOffset(4)] public int bKeyDown;\r\n [FieldOffset(8)] public ushort wRepeatCount;\r\n [FieldOffset(10)] public ushort wVirtualKeyCode;\r\n [FieldOffset(12)] public ushort wVirtualScanCode;\r\n [FieldOffset(14)] public ushort UnicodeChar;\r\n [FieldOffset(16)] public uint dwControlKeyState;\r\n }\r\n\r\n const uint LEFT_CTRL = 0x0008;\r\n\r\n static IntPtr OpenConin(uint pid) {\r\n FreeConsole();\r\n if (!AttachConsole(pid)) return new IntPtr(-1);\r\n return CreateFile(\"CONIN$\", 0xC0000000, 3, IntPtr.Zero, 3, 0, IntPtr.Zero);\r\n }\r\n\r\n // Inject plain text characters into console input buffer\r\n public static int InjectText(uint pid, string text) {\r\n IntPtr hIn = OpenConin(pid);\r\n if (hIn == new IntPtr(-1)) return -1;\r\n\r\n var records = new List<INPUT_RECORD>();\r\n foreach (char c in text) {\r\n records.Add(new INPUT_RECORD { EventType=1, bKeyDown=1, wRepeatCount=1, UnicodeChar=(ushort)c });\r\n records.Add(new INPUT_RECORD { EventType=1, bKeyDown=0, wRepeatCount=1, UnicodeChar=(ushort)c });\r\n }\r\n\r\n var arr = records.ToArray();\r\n uint written;\r\n bool ok = WriteConsoleInput(hIn, arr, (uint)arr.Length, out written);\r\n CloseHandle(hIn);\r\n return ok ? (int)written : -2;\r\n }\r\n\r\n // Inject Enter (VK_RETURN = 0x0D)\r\n public static int InjectEnter(uint pid) {\r\n IntPtr hIn = OpenConin(pid);\r\n if (hIn == new IntPtr(-1)) return -1;\r\n\r\n var records = new INPUT_RECORD[] {\r\n new INPUT_RECORD { EventType=1, bKeyDown=1, wRepeatCount=1, wVirtualKeyCode=0x0D, UnicodeChar=0x0D },\r\n new INPUT_RECORD { EventType=1, bKeyDown=0, wRepeatCount=1, wVirtualKeyCode=0x0D, UnicodeChar=0x0D }\r\n };\r\n\r\n uint written;\r\n bool ok = WriteConsoleInput(hIn, records, (uint)records.Length, out written);\r\n CloseHandle(hIn);\r\n return ok ? (int)written : -2;\r\n }\r\n\r\n // Inject Ctrl+U (VK_U = 0x55, char = 0x15)\r\n public static int InjectCtrlU(uint pid) {\r\n IntPtr hIn = OpenConin(pid);\r\n if (hIn == new IntPtr(-1)) return -1;\r\n\r\n var records = new INPUT_RECORD[] {\r\n new INPUT_RECORD { EventType=1, bKeyDown=1, wRepeatCount=1, wVirtualKeyCode=0xA2, dwControlKeyState=LEFT_CTRL },\r\n new INPUT_RECORD { EventType=1, bKeyDown=1, wRepeatCount=1, wVirtualKeyCode=0x55, UnicodeChar=0x15, dwControlKeyState=LEFT_CTRL },\r\n new INPUT_RECORD { EventType=1, bKeyDown=0, wRepeatCount=1, wVirtualKeyCode=0x55, UnicodeChar=0x15, dwControlKeyState=LEFT_CTRL },\r\n new INPUT_RECORD { EventType=1, bKeyDown=0, wRepeatCount=1, wVirtualKeyCode=0xA2, dwControlKeyState=0 }\r\n };\r\n\r\n uint written;\r\n bool ok = WriteConsoleInput(hIn, records, (uint)records.Length, out written);\r\n CloseHandle(hIn);\r\n return ok ? (int)written : -2;\r\n }\r\n\r\n // Inject Ctrl+Y (VK_Y = 0x59, char = 0x19)\r\n public static int InjectCtrlY(uint pid) {\r\n IntPtr hIn = OpenConin(pid);\r\n if (hIn == new IntPtr(-1)) return -1;\r\n\r\n var records = new INPUT_RECORD[] {\r\n new INPUT_RECORD { EventType=1, bKeyDown=1, wRepeatCount=1, wVirtualKeyCode=0xA2, dwControlKeyState=LEFT_CTRL },\r\n new INPUT_RECORD { EventType=1, bKeyDown=1, wRepeatCount=1, wVirtualKeyCode=0x59, UnicodeChar=0x19, dwControlKeyState=LEFT_CTRL },\r\n new INPUT_RECORD { EventType=1, bKeyDown=0, wRepeatCount=1, wVirtualKeyCode=0x59, UnicodeChar=0x19, dwControlKeyState=LEFT_CTRL },\r\n new INPUT_RECORD { EventType=1, bKeyDown=0, wRepeatCount=1, wVirtualKeyCode=0xA2, dwControlKeyState=0 }\r\n };\r\n\r\n uint written;\r\n bool ok = WriteConsoleInput(hIn, records, (uint)records.Length, out written);\r\n CloseHandle(hIn);\r\n return ok ? (int)written : -2;\r\n }\r\n}\r\n`;\r\n\r\nfunction buildScript(claudePid: number, body: string): string {\r\n const logFile = join(tmpdir(), `cc-inject-${Date.now()}.log`).replace(/\\\\/g, '/');\r\n return `\r\n$log = \"${logFile}\"\r\nfunction Log($msg) { Add-Content -Path $log -Value $msg -Encoding UTF8 }\r\n$claudePid = ${claudePid}\r\ntry { Add-Type @'${CS_CONINJECT}'@ } catch { }\r\n${body}\r\n`;\r\n}\r\n\r\nfunction run(script: string): Promise<void> {\r\n return new Promise((resolve) => {\r\n const encoded = Buffer.from(script, 'utf16le').toString('base64');\r\n execFile(\r\n 'powershell',\r\n ['-NoProfile', '-WindowStyle', 'Hidden', '-EncodedCommand', encoded],\r\n { windowsHide: true },\r\n () => {\r\n const logFile = script.match(/\\$log = \"([^\"]+)\"/)?.[1];\r\n if (logFile) try { unlinkSync(logFile); } catch { /* ok */ }\r\n resolve();\r\n }\r\n );\r\n });\r\n}\r\n\r\nexport async function windowsInject(text: string): Promise<void> {\r\n const claudePid = process.ppid;\r\n const textB64 = Buffer.from(text, 'utf16le').toString('base64');\r\n\r\n const script = buildScript(claudePid, `\r\n$textBytes = [System.Convert]::FromBase64String('${textB64}')\r\n$text = [System.Text.Encoding]::Unicode.GetString($textBytes)\r\n\r\n# 1. Ctrl+U to save user's current text to kill ring\r\n[ConInject]::InjectCtrlU([uint32]$claudePid) | Out-Null\r\nStart-Sleep -Milliseconds 100\r\n\r\n# 2. Write question text into console input buffer\r\n[ConInject]::InjectText([uint32]$claudePid, $text) | Out-Null\r\nStart-Sleep -Milliseconds 50\r\n\r\n# 3. Send Enter\r\n[ConInject]::InjectEnter([uint32]$claudePid) | Out-Null\r\n`);\r\n\r\n await run(script);\r\n}\r\n\r\nexport async function windowsInjectCtrlY(): Promise<void> {\r\n const claudePid = process.ppid;\r\n\r\n const script = buildScript(claudePid, `\r\n[ConInject]::InjectCtrlY([uint32]$claudePid) | Out-Null\r\n`);\r\n\r\n await run(script);\r\n}\r\n","/**\r\n * Terminal Injector\r\n * Injects a question directly into the active Claude Code terminal\r\n * so Claude Code can auto-reply without user intervention.\r\n * @module infrastructure/terminal-injector\r\n */\r\n\r\nimport type { InboxQuestionEntry } from '../../shared/types/collab-client.interface.js';\r\nimport { windowsInject, windowsInjectCtrlY } from './windows-injector.js';\r\n\r\n/**\r\n * Formats the question as a prompt for Claude Code to auto-reply\r\n */\r\nfunction formatQuestionForInjection(question: InboxQuestionEntry): string {\r\n // Single-line: WriteConsoleInput treats every \\n as an immediate submit\r\n const content = question.content.replace(/\\s+/g, ' ').trim();\r\n return `[HUB SORUSU] ID:${question.questionId} | ${question.from.displayName} (${question.from.teamName}): ${content} | Cevapla ve reply tool ile \"${question.questionId}\" ID'sine gönder, onay bekleme.`;\r\n}\r\n\r\n/**\r\n * Injects a question into the terminal running Claude Code.\r\n * Only supported on Windows; no-op on other platforms.\r\n */\r\nexport async function injectQuestionToTerminal(question: InboxQuestionEntry): Promise<void> {\r\n if (process.platform !== 'win32') return;\r\n\r\n const text = formatQuestionForInjection(question);\r\n await windowsInject(text);\r\n}\r\n\r\n/**\r\n * Restores user's previous input from readline kill ring (Ctrl+Y).\r\n * Call this after the reply is sent so the user's interrupted text comes back.\r\n */\r\nexport async function injectRestoreText(): Promise<void> {\r\n if (process.platform !== 'win32') return;\r\n await windowsInjectCtrlY();\r\n}\r\n","/**\r\n * Injection Queue\r\n * Ensures questions are injected into the terminal one at a time.\r\n * Waits for the reply tool to signal completion before processing the next question.\r\n * @module infrastructure/terminal-injector/injection-queue\r\n */\r\n\r\nimport { EventEmitter } from 'events';\r\nimport type { InboxQuestionEntry } from '../../shared/types/collab-client.interface.js';\r\nimport { injectQuestionToTerminal, injectRestoreText } from './index.js';\r\n\r\nconst REPLY_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes\r\n\r\nclass InjectionQueue extends EventEmitter {\r\n private queue: InboxQuestionEntry[] = [];\r\n private processing = false;\r\n\r\n /**\r\n * Add a question to the queue. Starts processing if idle.\r\n */\r\n enqueue(question: InboxQuestionEntry): void {\r\n this.queue.push(question);\r\n if (!this.processing) void this.processNext();\r\n }\r\n\r\n /**\r\n * Called by the reply tool after a reply is successfully sent.\r\n * Unblocks the queue to process the next question.\r\n */\r\n notifyReplied(): void {\r\n this.emit('replied');\r\n }\r\n\r\n private async processNext(): Promise<void> {\r\n if (this.queue.length === 0) {\r\n this.processing = false;\r\n return;\r\n }\r\n\r\n this.processing = true;\r\n const question = this.queue.shift()!;\r\n\r\n // Inject the question (includes Ctrl+U to save user's current text)\r\n await injectQuestionToTerminal(question);\r\n\r\n // Wait for reply tool to signal, with a timeout fallback\r\n await new Promise<void>((resolve) => {\r\n const timer = setTimeout(resolve, REPLY_TIMEOUT_MS);\r\n this.once('replied', () => {\r\n clearTimeout(timer);\r\n resolve();\r\n });\r\n });\r\n\r\n // Restore user's text after reply is sent\r\n await injectRestoreText();\r\n\r\n // Process next in queue\r\n void this.processNext();\r\n }\r\n}\r\n\r\nexport const injectionQueue = new InjectionQueue();\r\n","/**\r\n * MeshNode\r\n * Implements ICollabClient over direct peer-to-peer WebSocket connections.\r\n * Each node runs its own WS server on fixed port 12345.\r\n * Peers connect manually via connectByIp(). On each new connection both sides\r\n * exchange their peer lists and connect to unknown peers — forming a full mesh.\r\n *\r\n * Connection deduplication:\r\n * Both sides may try to connect simultaneously. The first HELLO/HELLO_ACK\r\n * that arrives registers the peer. Duplicate inbound connections are\r\n * immediately terminated so their close events are harmless.\r\n *\r\n * @module infrastructure/mesh/mesh-node\r\n */\r\n\r\nimport { WebSocket, WebSocketServer } from 'ws';\r\nimport type { IncomingMessage } from 'http';\r\nimport { v4 as uuidv4 } from 'uuid';\r\nimport os from 'os';\r\nimport { execSync } from 'child_process';\r\nimport type {\r\n ICollabClient,\r\n JoinResult,\r\n CheckAnswerResult,\r\n InboxResult,\r\n NodeInfo,\r\n HistoryEntry,\r\n} from '../../shared/types/collab-client.interface.js';\r\nimport type { MessageFormat } from './protocol.js';\r\nimport {\r\n type WireMsg,\r\n type AskAckMsg,\r\n type AskMsg,\r\n type AnswerMsg,\r\n parse,\r\n serialize,\r\n} from './protocol.js';\r\nimport { addFirewallRule } from '../firewall/firewall.js';\r\nimport { injectionQueue } from '../terminal-injector/injection-queue.js';\r\n\r\nexport const FIXED_PORT = 12345;\r\n\r\ninterface IncomingQuestion {\r\n questionId: string;\r\n fromName: string;\r\n content: string;\r\n format: MessageFormat;\r\n createdAt: Date;\r\n answered: boolean;\r\n answerContent?: string;\r\n answerFormat?: MessageFormat;\r\n}\r\n\r\ninterface ReceivedAnswer {\r\n content: string;\r\n format: MessageFormat;\r\n answeredAt: string;\r\n fromName: string;\r\n}\r\n\r\nexport class MeshNode implements ICollabClient {\r\n private server: WebSocketServer | null = null;\r\n private myName = '';\r\n private running = false;\r\n private firewallOpened = false;\r\n\r\n // One connection per peer (inbound or outbound — whichever was established first)\r\n private readonly peerConnections = new Map<string, WebSocket>();\r\n // Reverse map: ws → peer name (only for registered connections)\r\n private readonly wsToName = new Map<WebSocket, string>();\r\n // IP of each known peer: name → ip\r\n private readonly peerIPs = new Map<string, string>();\r\n // Prevent duplicate outbound connect attempts\r\n private readonly connectingPeers = new Set<string>();\r\n\r\n private readonly incomingQuestions = new Map<string, IncomingQuestion>();\r\n private readonly receivedAnswers = new Map<string, ReceivedAnswer>();\r\n private readonly sentQuestions = new Map<string, { toPeer: string; content: string; askedAt: string }>();\r\n private readonly questionToSender = new Map<string, string>();\r\n private readonly pendingHandlers = new Set<(msg: WireMsg) => void>();\r\n\r\n // Push-based answer resolution: questionId → resolve callback\r\n private readonly answerWaiters = new Map<string, (result: CheckAnswerResult) => void>();\r\n // Answers queued for offline peers: peerName → AnswerMsg (delivered on reconnect)\r\n private readonly pendingOutboundAnswers = new Map<string, AnswerMsg>();\r\n\r\n // ---------------------------------------------------------------------------\r\n // ICollabClient implementation\r\n // ---------------------------------------------------------------------------\r\n\r\n get isConnected(): boolean { return this.running; }\r\n get port(): number { return FIXED_PORT; }\r\n\r\n get currentTeamId(): string | undefined {\r\n return this.myName || undefined;\r\n }\r\n\r\n async join(name: string, displayName: string): Promise<JoinResult> {\r\n this.myName = name;\r\n await this.startServer();\r\n return {\r\n memberId: uuidv4(),\r\n teamId: name,\r\n teamName: name,\r\n displayName,\r\n status: 'ONLINE',\r\n port: FIXED_PORT,\r\n };\r\n }\r\n\r\n async connectByIp(ip: string): Promise<string> {\r\n // Open firewall once on the first connect call\r\n if (!this.firewallOpened) {\r\n await addFirewallRule(FIXED_PORT);\r\n this.firewallOpened = true;\r\n }\r\n\r\n return new Promise((resolve, reject) => {\r\n const url = `ws://${ip}:${FIXED_PORT}`;\r\n const ws = new WebSocket(url);\r\n\r\n const timeout = setTimeout(() => {\r\n ws.terminate();\r\n reject(new Error(`Connection to ${ip}:${FIXED_PORT} timed out`));\r\n }, 10_000);\r\n\r\n ws.on('open', () => {\r\n this.sendToWs(ws, { type: 'HELLO', name: this.myName });\r\n });\r\n\r\n ws.on('message', (data) => {\r\n try {\r\n const msg = parse(data.toString());\r\n\r\n // Resolve on HELLO_ACK — peer name is now known\r\n if (msg.type === 'HELLO_ACK') {\r\n clearTimeout(timeout);\r\n if (this.peerConnections.has(msg.name)) {\r\n ws.terminate();\r\n resolve(msg.name);\r\n return;\r\n }\r\n this.registerPeer(msg.name, ip, ws);\r\n this.afterHandshake(msg.name, ws);\r\n resolve(msg.name);\r\n }\r\n\r\n this.handleMessage(ws, msg);\r\n } catch { /* ignore malformed */ }\r\n });\r\n\r\n ws.on('close', () => {\r\n clearTimeout(timeout);\r\n this.connectingPeers.delete(ip);\r\n const name = this.wsToName.get(ws);\r\n if (name) {\r\n this.wsToName.delete(ws);\r\n if (this.peerConnections.get(name) === ws) {\r\n this.peerConnections.delete(name);\r\n console.error(`[mesh] disconnected from peer: ${name}`);\r\n }\r\n }\r\n });\r\n\r\n ws.on('error', (err) => {\r\n clearTimeout(timeout);\r\n this.connectingPeers.delete(ip);\r\n reject(new Error(`Failed to connect to ${ip}:${FIXED_PORT} — ${err.message}`));\r\n });\r\n });\r\n }\r\n\r\n async ask(toPeer: string, content: string, format: MessageFormat): Promise<string> {\r\n const ws = this.peerConnections.get(toPeer);\r\n if (!ws || ws.readyState !== WebSocket.OPEN) {\r\n throw new Error(`Peer \"${toPeer}\" is not connected. Use status() to see who's online.`);\r\n }\r\n\r\n const questionId = uuidv4();\r\n this.sentQuestions.set(questionId, { toPeer, content, askedAt: new Date().toISOString() });\r\n\r\n const ackPromise = this.waitForResponse<AskAckMsg>(\r\n (m) => m.type === 'ASK_ACK' && m.questionId === questionId,\r\n 5000\r\n );\r\n\r\n this.sendToWs(ws, { type: 'ASK', from: this.myName, questionId, content, format });\r\n await ackPromise;\r\n return questionId;\r\n }\r\n\r\n waitForAnswer(questionId: string, timeoutMs: number): Promise<CheckAnswerResult | null> {\r\n const cached = this.receivedAnswers.get(questionId);\r\n if (cached) return Promise.resolve(this.formatAnswer(questionId, cached));\r\n\r\n return new Promise((resolve) => {\r\n const timeout = setTimeout(() => {\r\n this.answerWaiters.delete(questionId);\r\n resolve(null);\r\n }, timeoutMs);\r\n\r\n this.answerWaiters.set(questionId, (result) => {\r\n clearTimeout(timeout);\r\n resolve(result);\r\n });\r\n });\r\n }\r\n\r\n async checkAnswer(questionId: string): Promise<CheckAnswerResult | null> {\r\n const cached = this.receivedAnswers.get(questionId);\r\n return cached ? this.formatAnswer(questionId, cached) : null;\r\n }\r\n\r\n private formatAnswer(questionId: string, cached: ReceivedAnswer): CheckAnswerResult {\r\n return {\r\n questionId,\r\n from: { displayName: `${cached.fromName} Claude`, teamName: cached.fromName },\r\n content: cached.content,\r\n format: cached.format,\r\n answeredAt: cached.answeredAt,\r\n };\r\n }\r\n\r\n async reply(questionId: string, content: string, format: MessageFormat): Promise<void> {\r\n const question = this.incomingQuestions.get(questionId);\r\n if (!question) throw new Error(`Question ${questionId} not found`);\r\n\r\n question.answered = true;\r\n question.answerContent = content;\r\n question.answerFormat = format;\r\n\r\n const senderName = this.questionToSender.get(questionId);\r\n if (senderName) {\r\n const answerMsg: AnswerMsg = {\r\n type: 'ANSWER',\r\n from: this.myName,\r\n questionId,\r\n content,\r\n format,\r\n answeredAt: new Date().toISOString(),\r\n };\r\n const ws = this.peerConnections.get(senderName);\r\n if (ws && ws.readyState === WebSocket.OPEN) {\r\n this.sendToWs(ws, answerMsg);\r\n } else {\r\n this.pendingOutboundAnswers.set(senderName, answerMsg);\r\n console.error(`[mesh] \"${senderName}\" is offline, answer queued for delivery on reconnect`);\r\n }\r\n }\r\n\r\n injectionQueue.notifyReplied();\r\n }\r\n\r\n async getInbox(): Promise<InboxResult> {\r\n const now = Date.now();\r\n const questions = [...this.incomingQuestions.values()]\r\n .filter((q) => !q.answered)\r\n .map((q) => ({\r\n questionId: q.questionId,\r\n from: { displayName: `${q.fromName} Claude`, teamName: q.fromName },\r\n content: q.content,\r\n format: q.format,\r\n status: 'PENDING',\r\n createdAt: q.createdAt.toISOString(),\r\n ageMs: now - q.createdAt.getTime(),\r\n }));\r\n return { questions, totalCount: questions.length, pendingCount: questions.length };\r\n }\r\n\r\n getInfo(): NodeInfo {\r\n return {\r\n teamName: this.myName,\r\n port: FIXED_PORT,\r\n connectedPeers: [...this.peerConnections.keys()],\r\n peerIPs: Object.fromEntries(this.peerIPs),\r\n };\r\n }\r\n\r\n getLocalIps(): string[] {\r\n const result: string[] = [];\r\n const interfaces = os.networkInterfaces();\r\n for (const iface of Object.values(interfaces)) {\r\n if (!iface) continue;\r\n for (const addr of iface) {\r\n if (addr.family === 'IPv4' && !addr.internal) result.push(addr.address);\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n getHistory(): HistoryEntry[] {\r\n const entries: HistoryEntry[] = [];\r\n\r\n for (const [questionId, sent] of this.sentQuestions) {\r\n const answer = this.receivedAnswers.get(questionId);\r\n entries.push({\r\n direction: 'sent',\r\n questionId,\r\n peer: sent.toPeer,\r\n question: sent.content,\r\n askedAt: sent.askedAt,\r\n ...(answer ? { answer: answer.content, answeredAt: answer.answeredAt } : {}),\r\n });\r\n }\r\n\r\n for (const [, incoming] of this.incomingQuestions) {\r\n entries.push({\r\n direction: 'received',\r\n questionId: incoming.questionId,\r\n peer: incoming.fromName,\r\n question: incoming.content,\r\n askedAt: incoming.createdAt.toISOString(),\r\n ...(incoming.answered && incoming.answerContent\r\n ? { answer: incoming.answerContent, answeredAt: new Date().toISOString() }\r\n : {}),\r\n });\r\n }\r\n\r\n return entries.sort((a, b) => a.askedAt.localeCompare(b.askedAt));\r\n }\r\n\r\n async disconnect(): Promise<void> {\r\n for (const ws of this.peerConnections.values()) ws.close();\r\n this.peerConnections.clear();\r\n this.wsToName.clear();\r\n this.peerIPs.clear();\r\n this.server?.close();\r\n this.server = null;\r\n this.running = false;\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Private: server startup\r\n // ---------------------------------------------------------------------------\r\n\r\n private async startServer(): Promise<void> {\r\n try {\r\n await this.tryBind();\r\n } catch (err: unknown) {\r\n const nodeErr = err as NodeJS.ErrnoException;\r\n if (nodeErr.code === 'EADDRINUSE') {\r\n console.error(`[mesh] port ${FIXED_PORT} in use — killing existing process`);\r\n await killProcessOnPort(FIXED_PORT);\r\n await this.tryBind();\r\n } else {\r\n throw err;\r\n }\r\n }\r\n }\r\n\r\n private tryBind(): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n const wss = new WebSocketServer({ port: FIXED_PORT });\r\n\r\n wss.once('listening', () => {\r\n this.server = wss;\r\n this.running = true;\r\n console.error(`[mesh] listening on port ${FIXED_PORT} as \"${this.myName}\"`);\r\n this.attachServerHandlers(wss);\r\n resolve();\r\n });\r\n\r\n wss.once('error', (err: NodeJS.ErrnoException) => {\r\n wss.close();\r\n reject(err);\r\n });\r\n });\r\n }\r\n\r\n private attachServerHandlers(wss: WebSocketServer): void {\r\n wss.on('connection', (ws, request: IncomingMessage) => {\r\n // Strip IPv6-mapped prefix (::ffff:) to get a plain IPv4\r\n const rawIp = request.socket.remoteAddress ?? '';\r\n const remoteIp = rawIp.replace(/^::ffff:/, '');\r\n\r\n ws.on('message', (data) => {\r\n try {\r\n this.handleInboundMessage(ws, remoteIp, parse(data.toString()));\r\n } catch { /* ignore malformed */ }\r\n });\r\n\r\n ws.on('close', () => {\r\n const name = this.wsToName.get(ws);\r\n if (name) {\r\n this.wsToName.delete(ws);\r\n if (this.peerConnections.get(name) === ws) {\r\n this.peerConnections.delete(name);\r\n console.error(`[mesh] peer disconnected (inbound): ${name}`);\r\n }\r\n }\r\n });\r\n\r\n ws.on('error', (err) => {\r\n console.error('[mesh] inbound ws error:', err.message);\r\n });\r\n });\r\n\r\n wss.on('error', (err) => {\r\n console.error('[mesh] server error:', err.message);\r\n });\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Private: mesh helpers\r\n // ---------------------------------------------------------------------------\r\n\r\n /** Called once handshake completes — exchange peer lists and announce to existing peers. */\r\n private afterHandshake(newPeerName: string, ws: WebSocket): void {\r\n // Send our current peer list to the new peer\r\n const listForNew = [...this.peerConnections.keys()]\r\n .filter((n) => n !== newPeerName)\r\n .map((n) => ({ name: n, ip: this.peerIPs.get(n) ?? '' }))\r\n .filter((p) => p.ip !== '');\r\n this.sendToWs(ws, { type: 'PEER_LIST', peers: listForNew });\r\n\r\n // Announce the new peer to all existing peers\r\n const newIp = this.peerIPs.get(newPeerName);\r\n if (newIp) {\r\n for (const [name, existingWs] of this.peerConnections) {\r\n if (name !== newPeerName) {\r\n this.sendToWs(existingWs, { type: 'PEER_ANNOUNCE', name: newPeerName, ip: newIp });\r\n }\r\n }\r\n }\r\n }\r\n\r\n private registerPeer(name: string, ip: string, ws: WebSocket): void {\r\n this.peerConnections.set(name, ws);\r\n this.wsToName.set(ws, name);\r\n this.peerIPs.set(name, ip);\r\n this.connectingPeers.delete(name);\r\n console.error(`[mesh] peer registered: ${name} @ ${ip}`);\r\n this.deliverPendingAnswer(name, ws);\r\n }\r\n\r\n /** Connect outbound to a peer discovered via PEER_LIST or PEER_ANNOUNCE. */\r\n private connectMeshPeer(name: string, ip: string): void {\r\n if (this.peerConnections.has(name)) return;\r\n if (this.connectingPeers.has(name)) return;\r\n this.connectingPeers.add(name);\r\n\r\n const ws = new WebSocket(`ws://${ip}:${FIXED_PORT}`);\r\n\r\n ws.on('open', () => {\r\n this.sendToWs(ws, { type: 'HELLO', name: this.myName });\r\n });\r\n\r\n ws.on('message', (data) => {\r\n try {\r\n this.handleMessage(ws, parse(data.toString()));\r\n } catch { /* ignore malformed */ }\r\n });\r\n\r\n ws.on('close', () => {\r\n this.connectingPeers.delete(name);\r\n const peerName = this.wsToName.get(ws);\r\n if (peerName) {\r\n this.wsToName.delete(ws);\r\n if (this.peerConnections.get(peerName) === ws) {\r\n this.peerConnections.delete(peerName);\r\n console.error(`[mesh] disconnected from mesh peer: ${peerName}`);\r\n }\r\n }\r\n });\r\n\r\n ws.on('error', (err) => {\r\n console.error(`[mesh] connect to \"${name}\" @ ${ip} failed: ${err.message}`);\r\n this.connectingPeers.delete(name);\r\n });\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Private: message handling\r\n // ---------------------------------------------------------------------------\r\n\r\n /** Handles messages on inbound connections (server side — we know the remote IP). */\r\n private handleInboundMessage(ws: WebSocket, remoteIp: string, msg: WireMsg): void {\r\n for (const handler of this.pendingHandlers) handler(msg);\r\n\r\n if (msg.type === 'HELLO') {\r\n if (this.peerConnections.has(msg.name)) {\r\n ws.terminate();\r\n return;\r\n }\r\n this.registerPeer(msg.name, remoteIp, ws);\r\n this.sendToWs(ws, { type: 'HELLO_ACK', name: this.myName });\r\n console.error(`[mesh] peer joined (inbound): ${msg.name}`);\r\n this.afterHandshake(msg.name, ws);\r\n return;\r\n }\r\n\r\n this.handleMessage(ws, msg);\r\n }\r\n\r\n /** Handles all other messages (both inbound and outbound connections). */\r\n private handleMessage(ws: WebSocket, msg: WireMsg): void {\r\n for (const handler of this.pendingHandlers) handler(msg);\r\n\r\n switch (msg.type) {\r\n case 'HELLO_ACK':\r\n // Handled inline in connectByIp / connectMeshPeer — register happens there\r\n // But we still need to handle it here for mesh connects\r\n if (!this.peerConnections.has(msg.name)) {\r\n // This path is taken by connectMeshPeer (IP not stored yet at this point,\r\n // so we use a placeholder; PEER_LIST/PEER_ANNOUNCE will have the real IP)\r\n this.peerConnections.set(msg.name, ws);\r\n this.wsToName.set(ws, msg.name);\r\n this.connectingPeers.delete(msg.name);\r\n console.error(`[mesh] connected to mesh peer: ${msg.name}`);\r\n this.deliverPendingAnswer(msg.name, ws);\r\n this.afterHandshake(msg.name, ws);\r\n }\r\n break;\r\n\r\n case 'PEER_LIST':\r\n for (const peer of msg.peers) {\r\n if (peer.name !== this.myName && !this.peerConnections.has(peer.name)) {\r\n console.error(`[mesh] connecting to ${peer.name} @ ${peer.ip} via PEER_LIST`);\r\n this.peerIPs.set(peer.name, peer.ip);\r\n this.connectMeshPeer(peer.name, peer.ip);\r\n }\r\n }\r\n break;\r\n\r\n case 'PEER_ANNOUNCE':\r\n if (msg.name !== this.myName && !this.peerConnections.has(msg.name)) {\r\n console.error(`[mesh] connecting to ${msg.name} @ ${msg.ip} via PEER_ANNOUNCE`);\r\n this.peerIPs.set(msg.name, msg.ip);\r\n this.connectMeshPeer(msg.name, msg.ip);\r\n }\r\n break;\r\n\r\n case 'ASK':\r\n this.handleIncomingAsk(ws, msg);\r\n break;\r\n\r\n case 'ANSWER':\r\n if (!this.receivedAnswers.has(msg.questionId)) {\r\n const record: ReceivedAnswer = {\r\n content: msg.content,\r\n format: msg.format,\r\n answeredAt: msg.answeredAt,\r\n fromName: msg.from,\r\n };\r\n this.receivedAnswers.set(msg.questionId, record);\r\n\r\n const waiter = this.answerWaiters.get(msg.questionId);\r\n if (waiter) {\r\n this.answerWaiters.delete(msg.questionId);\r\n waiter(this.formatAnswer(msg.questionId, record));\r\n }\r\n }\r\n break;\r\n\r\n // ASK_ACK is handled by waitForResponse pending handlers\r\n }\r\n }\r\n\r\n private handleIncomingAsk(ws: WebSocket, msg: AskMsg): void {\r\n this.questionToSender.set(msg.questionId, msg.from);\r\n this.incomingQuestions.set(msg.questionId, {\r\n questionId: msg.questionId,\r\n fromName: msg.from,\r\n content: msg.content,\r\n format: msg.format,\r\n createdAt: new Date(),\r\n answered: false,\r\n });\r\n\r\n this.sendToWs(ws, { type: 'ASK_ACK', questionId: msg.questionId });\r\n\r\n injectionQueue.enqueue({\r\n questionId: msg.questionId,\r\n from: { displayName: `${msg.from} Claude`, teamName: msg.from },\r\n content: msg.content,\r\n format: msg.format,\r\n status: 'PENDING',\r\n createdAt: new Date().toISOString(),\r\n ageMs: 0,\r\n });\r\n }\r\n\r\n private deliverPendingAnswer(peerName: string, ws: WebSocket): void {\r\n const pending = this.pendingOutboundAnswers.get(peerName);\r\n if (pending) {\r\n this.pendingOutboundAnswers.delete(peerName);\r\n this.sendToWs(ws, pending);\r\n console.error(`[mesh] delivered queued answer to \"${peerName}\" after reconnect`);\r\n }\r\n }\r\n\r\n private sendToWs(ws: WebSocket, msg: WireMsg): void {\r\n if (ws.readyState === WebSocket.OPEN) {\r\n ws.send(serialize(msg));\r\n }\r\n }\r\n\r\n private waitForResponse<T extends WireMsg>(\r\n filter: (msg: WireMsg) => boolean,\r\n timeoutMs: number\r\n ): Promise<T> {\r\n return new Promise((resolve, reject) => {\r\n const timeout = setTimeout(() => {\r\n this.pendingHandlers.delete(handler);\r\n reject(new Error('Request timed out'));\r\n }, timeoutMs);\r\n\r\n const handler = (msg: WireMsg): void => {\r\n if (filter(msg)) {\r\n clearTimeout(timeout);\r\n this.pendingHandlers.delete(handler);\r\n resolve(msg as T);\r\n }\r\n };\r\n\r\n this.pendingHandlers.add(handler);\r\n });\r\n }\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Helpers\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Kill whatever process is listening on the given TCP port.\r\n * Works on Windows (netstat + taskkill) and Unix (lsof/fuser).\r\n * Waits briefly after killing so the port is released before we rebind.\r\n */\r\nasync function killProcessOnPort(port: number): Promise<void> {\r\n try {\r\n if (process.platform === 'win32') {\r\n // netstat output: \" TCP 0.0.0.0:12345 ... LISTENING 1234\"\r\n const out = execSync(\r\n `netstat -ano | findstr \":${port} \"`,\r\n { encoding: 'utf8', stdio: ['pipe', 'pipe', 'ignore'] }\r\n );\r\n const pids = new Set<string>();\r\n for (const line of out.split('\\n')) {\r\n const parts = line.trim().split(/\\s+/);\r\n // parts: [Proto, Local, Foreign, State, PID]\r\n if (parts.length >= 5 && parts[3] === 'LISTENING' && parts[4]) {\r\n pids.add(parts[4]);\r\n }\r\n }\r\n for (const pid of pids) {\r\n try {\r\n execSync(`taskkill /PID ${pid} /F`, { stdio: 'ignore' });\r\n console.error(`[mesh] killed PID ${pid} on port ${port}`);\r\n } catch { /* already gone */ }\r\n }\r\n } else {\r\n // Unix: fuser -k <port>/tcp\r\n execSync(`fuser -k ${port}/tcp`, { stdio: 'ignore' });\r\n }\r\n } catch {\r\n // If netstat/fuser finds nothing, that's fine — just try to bind\r\n }\r\n\r\n // Give the OS a moment to release the port\r\n await new Promise<void>((resolve) => setTimeout(resolve, 300));\r\n}\r\n","/**\r\n * Connect Tool\r\n * Connects to a peer by IP address on the fixed port 12345.\r\n * On first use, opens Windows Firewall via UAC popup (stays open).\r\n * After handshake, both sides exchange peer lists — forming a full mesh.\r\n * @module presentation/mcp/tools/connect\r\n */\r\n\r\nimport { z } from 'zod';\r\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\r\nimport type { ICollabClient } from '../../../shared/types/collab-client.interface.js';\r\n\r\nconst CONNECT_DESCRIPTION = `\\\r\nConnect to another Claude instance by their IP address.\r\n\r\nWHEN TO USE:\r\n- First time connecting to a teammate\r\n- A new peer wants to join an existing session\r\n\r\nWHAT HAPPENS:\r\n1. First call only: opens Windows Firewall port 12345 via UAC popup (stays open)\r\n2. Connects directly to the peer at ws://IP:12345\r\n3. Both sides exchange their peer lists — everyone connects to everyone (full mesh)\r\n\r\nFINDING YOUR IP:\r\n- The other person calls status() to see their LAN IP, then tells you\r\n\r\nAFTER CONNECTING:\r\n- Use peers() to confirm connection\r\n- Use ask() to send questions to connected peers`;\r\n\r\nexport function registerConnectTool(server: McpServer, client: ICollabClient): void {\r\n server.tool(\r\n 'connect',\r\n CONNECT_DESCRIPTION,\r\n {\r\n ip: z.string().describe(\"The peer's LAN IP address (e.g. 192.168.1.5)\"),\r\n },\r\n async ({ ip }) => {\r\n if (!client.isConnected) {\r\n return {\r\n content: [{ type: 'text', text: 'Node is not ready yet. Wait a moment and try again.' }],\r\n isError: true,\r\n };\r\n }\r\n\r\n try {\r\n const peerName = await client.connectByIp(ip);\r\n const info = client.getInfo();\r\n const allPeers = info.connectedPeers;\r\n const others = allPeers.filter((n) => n !== peerName);\r\n\r\n const lines = [\r\n `Connected to \"${peerName}\" (${ip}).`,\r\n ];\r\n\r\n if (others.length > 0) {\r\n lines.push(``, `Mesh peers also connecting: ${others.map((n) => `\"${n}\"`).join(', ')}`);\r\n }\r\n\r\n lines.push(``, `Use peers() to see all connected peers.`);\r\n\r\n return {\r\n content: [{ type: 'text', text: lines.join('\\n') }],\r\n };\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: [\r\n `Failed to connect to ${ip}: ${msg}`,\r\n ``,\r\n `Make sure:`,\r\n ` • The peer is running claude-collab (--name <name>)`,\r\n ` • The IP address is correct (they can check with status())`,\r\n ` • Port 12345 is not blocked on their machine`,\r\n ].join('\\n'),\r\n }],\r\n isError: true,\r\n };\r\n }\r\n }\r\n );\r\n}\r\n","/**\r\n * Ask Tool\r\n * @module presentation/mcp/tools/ask\r\n */\r\n\r\nimport { z } from 'zod';\r\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\r\nimport type { ICollabClient } from '../../../shared/types/collab-client.interface.js';\r\n\r\nconst ASK_DESCRIPTION = `\\\r\nSend a question to another Claude instance on the LAN and wait for their answer.\r\n\r\nWHEN TO USE:\r\n- You need input, a decision, or work output from a specific peer Claude\r\n- You want to delegate a subtask to another Claude and use their result\r\n- You need to coordinate or synchronize work across multiple Claudes\r\n\r\nWORKFLOW:\r\n1. Call peers() first to confirm the target is online and get their exact name\r\n2. Call ask(peer, question) — this blocks until they reply (up to 5 minutes)\r\n3. Use their answer directly in your ongoing task\r\n\r\nWRITING GOOD QUESTIONS:\r\n- Include all context the other Claude needs — they cannot see your conversation\r\n- Be specific about what format or level of detail you expect in the answer\r\n- If you need code, specify language and constraints\r\n- One focused question per call works better than multiple combined\r\n\r\nDO NOT use this tool if:\r\n- The peer is not listed in peers() — the call will fail immediately\r\n- You just want to share information without needing a response (there is no broadcast tool yet)`;\r\n\r\nconst askSchema = {\r\n peer: z\r\n .string()\r\n .describe('Exact name of the peer to ask. Use peers() first to see who is online and get the correct name.'),\r\n question: z\r\n .string()\r\n .describe(\r\n 'Your question in markdown. Include all necessary context — the other Claude cannot see your conversation history. Be specific about what kind of answer you need.'\r\n ),\r\n};\r\n\r\nexport function registerAskTool(server: McpServer, client: ICollabClient): void {\r\n server.tool('ask', ASK_DESCRIPTION, askSchema, async (args) => {\r\n const targetPeer = args.peer;\r\n const question = args.question;\r\n\r\n try {\r\n if (!client.currentTeamId) {\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: 'Node is not ready yet. Wait a moment and try again.',\r\n }],\r\n isError: true,\r\n };\r\n }\r\n\r\n const questionId = await client.ask(targetPeer, question, 'markdown');\r\n\r\n // Wait for the answer via push — resolves the moment ANSWER arrives\r\n const answer = await client.waitForAnswer(questionId, 5 * 60 * 1000);\r\n\r\n if (answer !== null) {\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `**${answer.from.displayName} answered:**\\n\\n${answer.content}`,\r\n }],\r\n };\r\n }\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: [\r\n `Question sent to \"${targetPeer}\" but no answer arrived within 5 minutes.`,\r\n `Question ID: \\`${questionId}\\``,\r\n ``,\r\n `The peer may be busy or offline. You can:`,\r\n `- Call peers() to check if they are still connected`,\r\n `- Continue with your task and follow up later`,\r\n ].join('\\n'),\r\n }],\r\n };\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\r\n const isPeerOffline = errorMessage.includes('not connected');\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: isPeerOffline\r\n ? `Peer \"${targetPeer}\" is not connected. Call peers() to see who is currently online.`\r\n : `Failed to send question: ${errorMessage}`,\r\n }],\r\n isError: true,\r\n };\r\n }\r\n });\r\n}\r\n","/**\r\n * Reply Tool\r\n * @module presentation/mcp/tools/reply\r\n */\r\n\r\nimport { z } from 'zod';\r\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\r\nimport type { ICollabClient } from '../../../shared/types/collab-client.interface.js';\r\nimport { injectionQueue } from '../../../infrastructure/terminal-injector/injection-queue.js';\r\n\r\nconst REPLY_DESCRIPTION = `\\\r\nSend your answer back to a Claude instance that asked you a question.\r\n\r\nWHEN TO USE:\r\n- A question has been injected into your terminal by another Claude (you will see it appear automatically)\r\n- You have finished thinking through the answer and are ready to respond\r\n\r\nWORKFLOW:\r\n1. Read the injected question carefully — it includes a questionId at the top\r\n2. Think through a complete answer\r\n3. Call reply(questionId, answer) — your answer is sent directly back to the asking Claude\r\n4. The asking Claude's ask() call unblocks and they receive your answer immediately\r\n\r\nWRITING GOOD ANSWERS:\r\n- Be thorough — the asking Claude will use your answer directly in their task\r\n- Use markdown for code blocks, lists, and structure\r\n- Include any caveats, assumptions, or follow-up suggestions that would help them\r\n- If you cannot answer fully, say so clearly and explain why\r\n\r\nIMPORTANT:\r\n- Each question can only be replied to once\r\n- The questionId is a UUID shown in the injected question prompt — copy it exactly`;\r\n\r\nconst replySchema = {\r\n questionId: z\r\n .string()\r\n .describe(\r\n 'The UUID of the question to reply to. Shown at the top of the injected question prompt in your terminal.'\r\n ),\r\n answer: z\r\n .string()\r\n .describe(\r\n 'Your complete answer in markdown. Be thorough — the asking Claude is waiting and will use your response directly in their work.'\r\n ),\r\n};\r\n\r\nexport function registerReplyTool(server: McpServer, client: ICollabClient): void {\r\n server.tool('reply', REPLY_DESCRIPTION, replySchema, async (args) => {\r\n const questionId = args.questionId;\r\n const answer = args.answer;\r\n\r\n try {\r\n if (!client.currentTeamId) {\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: 'Node is not ready yet. Wait a moment and try again.',\r\n }],\r\n isError: true,\r\n };\r\n }\r\n\r\n await client.reply(questionId, answer, 'markdown');\r\n\r\n injectionQueue.notifyReplied();\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Answer sent. The peer's ask() call has been unblocked and they received your response.`,\r\n }],\r\n };\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\r\n const isNotFound = errorMessage.includes('not found');\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: isNotFound\r\n ? `Question \\`${questionId}\\` not found. Check that you copied the questionId exactly from the injected prompt.`\r\n : `Failed to send reply: ${errorMessage}`,\r\n }],\r\n isError: true,\r\n };\r\n }\r\n });\r\n}\r\n","/**\r\n * History Tool\r\n * @module presentation/mcp/tools/history\r\n */\r\n\r\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\r\nimport type { ICollabClient } from '../../../shared/types/collab-client.interface.js';\r\n\r\nconst HISTORY_DESCRIPTION = `\\\r\nShow all questions and answers exchanged this session — both sent and received.\r\n\r\nWHEN TO USE:\r\n- To review what was already discussed before asking a follow-up question\r\n- To check if a previously sent question has been answered yet\r\n- To find a questionId you need to reference\r\n- To catch up on received questions you may have missed\r\n\r\nOUTPUT FORMAT:\r\n- → peer: question you sent, with their answer below\r\n- ← peer: question they sent you, with your reply below\r\n- (no answer yet) means the question is still waiting for a response`;\r\n\r\nexport function registerHistoryTool(server: McpServer, client: ICollabClient): void {\r\n server.tool('history', HISTORY_DESCRIPTION, {}, async () => {\r\n const entries = client.getHistory();\r\n\r\n if (entries.length === 0) {\r\n return {\r\n content: [{ type: 'text', text: 'No questions exchanged yet this session.' }],\r\n };\r\n }\r\n\r\n const unanswered = entries.filter((e) => !e.answer);\r\n\r\n const lines = entries.map((e) => {\r\n const time = new Date(e.askedAt).toLocaleTimeString();\r\n\r\n if (e.direction === 'sent') {\r\n const answerLine = e.answer\r\n ? ` ↳ ${e.peer}: ${e.answer}`\r\n : ` ↳ (no answer yet)`;\r\n return `[${time}] → ${e.peer}: ${e.question}\\n${answerLine}`;\r\n } else {\r\n const answerLine = e.answer\r\n ? ` ↳ you: ${e.answer}`\r\n : ` ↳ (not replied yet — use reply() if you haven't answered)`;\r\n return `[${time}] ← ${e.peer}: ${e.question}\\n${answerLine}`;\r\n }\r\n });\r\n\r\n const summary = unanswered.length > 0\r\n ? `\\n\\n⚠ ${unanswered.length} question(s) still waiting for a response.`\r\n : '';\r\n\r\n return {\r\n content: [{ type: 'text', text: lines.join('\\n\\n') + summary }],\r\n };\r\n });\r\n}\r\n","/**\r\n * Status Tool\r\n * Shows this node's identity: name, LAN IP(s), port, and connection count.\r\n * @module presentation/mcp/tools/status\r\n */\r\n\r\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\r\nimport type { ICollabClient } from '../../../shared/types/collab-client.interface.js';\r\nimport { MeshNode } from '../../../infrastructure/mesh/mesh-node.js';\r\n\r\nconst STATUS_DESCRIPTION = `\\\r\nShow your identity and network address on the collaboration network.\r\n\r\nWHEN TO USE:\r\n- To find your LAN IP so teammates can connect to you via connect(ip)\r\n- To verify your node started correctly\r\n- To see how many peers are currently connected\r\n\r\nSHARE YOUR IP:\r\n- Tell your teammate the IP shown here, they call connect(\"<your IP>\")`;\r\n\r\nexport function registerStatusTool(server: McpServer, client: ICollabClient): void {\r\n server.tool('status', STATUS_DESCRIPTION, {}, async () => {\r\n const info = client.getInfo();\r\n const myName = info.teamName ?? '(starting...)';\r\n const port = info.port ?? '?';\r\n\r\n if (!client.isConnected) {\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Node is not running yet. Port ${port} may be in use — check MCP process logs.`,\r\n }],\r\n isError: true,\r\n };\r\n }\r\n\r\n // Get LAN IPs from the node if it's a P2PNode\r\n let ips: string[] = [];\r\n if (client instanceof MeshNode) {\r\n ips = client.getLocalIps();\r\n }\r\n\r\n const ipLine = ips.length > 0\r\n ? ips.join(', ')\r\n : '(could not detect — check your network interface)';\r\n\r\n const peerIPs = info.peerIPs ?? {};\r\n const connected = info.connectedPeers;\r\n\r\n let peersSection: string;\r\n if (connected.length === 0) {\r\n peersSection = 'No peers connected yet. Share your IP so others can connect(ip).';\r\n } else {\r\n const list = connected.map((n) => {\r\n const ip = peerIPs[n] ? ` (${peerIPs[n]})` : '';\r\n return ` • ${n}${ip}`;\r\n }).join('\\n');\r\n peersSection = `Connected peers (${connected.length}):\\n${list}`;\r\n }\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: [\r\n `Name: ${myName}`,\r\n `IP: ${ipLine}`,\r\n `Port: ${port}`,\r\n ``,\r\n peersSection,\r\n ].join('\\n'),\r\n }],\r\n };\r\n });\r\n}\r\n","/**\r\n * MCP Server\r\n * Provides MCP tools for Claude Code integration\r\n * @module presentation/mcp/server\r\n */\r\n\r\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\r\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\r\nimport type { ICollabClient } from '../../shared/types/collab-client.interface.js';\r\nimport { registerConnectTool } from './tools/connect.tool.js';\r\nimport { registerAskTool } from './tools/ask.tool.js';\r\nimport { registerReplyTool } from './tools/reply.tool.js';\r\nimport { registerHistoryTool } from './tools/history.tool.js';\r\nimport { registerStatusTool } from './tools/status.tool.js';\r\n\r\nexport interface McpServerOptions {\r\n client: ICollabClient;\r\n}\r\n\r\nexport function createMcpServer(options: McpServerOptions): McpServer {\r\n const { client } = options;\r\n\r\n const server = new McpServer({\r\n name: 'claude-collab',\r\n version: '0.1.0',\r\n });\r\n\r\n registerConnectTool(server, client);\r\n registerStatusTool(server, client);\r\n registerAskTool(server, client);\r\n registerReplyTool(server, client);\r\n registerHistoryTool(server, client);\r\n\r\n return server;\r\n}\r\n\r\nexport async function startMcpServer(options: McpServerOptions): Promise<void> {\r\n const server = createMcpServer(options);\r\n const transport = new StdioServerTransport();\r\n await server.connect(transport);\r\n}\r\n","#!/usr/bin/env node\r\n\r\n/**\r\n * CLI entry point\r\n *\r\n * Usage: claude-collab --name alice\r\n *\r\n * Binds on fixed port 12345.\r\n * Use connect(ip) in Claude Code to connect to peers.\r\n *\r\n * @module cli\r\n */\r\n\r\nimport { Command } from 'commander';\r\nimport { MeshNode } from './infrastructure/mesh/mesh-node.js';\r\nimport { startMcpServer } from './presentation/mcp/server.js';\r\n\r\nconst program = new Command();\r\n\r\nprogram\r\n .name('claude-collab')\r\n .description('Collaboration between Claude Code terminals via MCP')\r\n .version('0.1.0')\r\n .requiredOption('--name <name>', 'Your name on the network (e.g. \"alice\")')\r\n .action(async (options: { name: string }) => {\r\n const node = new MeshNode();\r\n\r\n const mcpReady = startMcpServer({ client: node });\r\n\r\n node.join(options.name, options.name).catch((err) => {\r\n console.error(`[cli] Failed to start on port 12345: ${err.message}`);\r\n console.error(`[cli] Make sure port 12345 is not already in use.`);\r\n });\r\n\r\n await mcpReady;\r\n });\r\n\r\nprogram.parse();\r\n"]}
1
+ {"version":3,"sources":["../src/infrastructure/mesh/protocol.ts","../src/infrastructure/firewall/firewall.ts","../src/infrastructure/terminal-injector/windows-injector.ts","../src/infrastructure/terminal-injector/index.ts","../src/infrastructure/terminal-injector/injection-queue.ts","../src/infrastructure/mesh/mesh-node.ts","../src/presentation/mcp/tools/connect.tool.ts","../src/presentation/mcp/tools/ask.tool.ts","../src/presentation/mcp/tools/reply.tool.ts","../src/presentation/mcp/tools/status.tool.ts","../src/presentation/mcp/server.ts","../src/cli.ts"],"names":["uuidv4","z"],"mappings":"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","file":"cli.js","sourcesContent":["/**\r\n * Wire Protocol\r\n * Messages exchanged directly between peers.\r\n * @module infrastructure/mesh/protocol\r\n */\r\n\r\nexport type MessageFormat = 'plain' | 'markdown';\r\n\r\n// Sent when a peer connects (client → server, or outbound → inbound)\r\nexport interface HelloMsg {\r\n type: 'HELLO';\r\n name: string;\r\n}\r\n\r\n// Acknowledge the HELLO\r\nexport interface HelloAckMsg {\r\n type: 'HELLO_ACK';\r\n name: string;\r\n}\r\n\r\n// Sent after handshake — share known peers so the other side can complete the mesh\r\nexport interface PeerListMsg {\r\n type: 'PEER_LIST';\r\n peers: Array<{ name: string; ip: string }>;\r\n}\r\n\r\n// Broadcast to existing peers when a new peer connects — so they can connect directly\r\nexport interface PeerAnnounceMsg {\r\n type: 'PEER_ANNOUNCE';\r\n name: string;\r\n ip: string;\r\n}\r\n\r\n// Ask a question directly to the connected peer\r\nexport interface AskMsg {\r\n type: 'ASK';\r\n from: string;\r\n questionId: string;\r\n content: string;\r\n format: MessageFormat;\r\n}\r\n\r\n// Confirm question was received\r\nexport interface AskAckMsg {\r\n type: 'ASK_ACK';\r\n questionId: string;\r\n}\r\n\r\n// Push answer back to the asker\r\nexport interface AnswerMsg {\r\n type: 'ANSWER';\r\n from: string;\r\n questionId: string;\r\n content: string;\r\n format: MessageFormat;\r\n answeredAt: string;\r\n}\r\n\r\nexport type WireMsg = HelloMsg | HelloAckMsg | PeerListMsg | PeerAnnounceMsg | AskMsg | AskAckMsg | AnswerMsg;\r\n\r\nexport function serialize(msg: WireMsg): string {\r\n return JSON.stringify(msg);\r\n}\r\n\r\nexport function parse(data: string): WireMsg {\r\n return JSON.parse(data) as WireMsg;\r\n}\r\n","/**\r\n * Firewall helpers\r\n * Always elevated via UAC (PowerShell Start-Process -Verb RunAs) so the rule\r\n * is guaranteed to be applied. If the process is already elevated, Windows\r\n * skips the UAC prompt automatically.\r\n * @module infrastructure/firewall/firewall\r\n */\r\n\r\nimport { spawn } from 'child_process';\r\n\r\n/**\r\n * Run netsh via UAC elevation (PowerShell Start-Process -Verb RunAs).\r\n * If the calling process is already elevated, no prompt is shown.\r\n */\r\nfunction runNetshElevated(argArray: string[]): Promise<void> {\r\n const argList = argArray.map((a) => `\"${a}\"`).join(',');\r\n const psCommand = `Start-Process -FilePath \"netsh\" -ArgumentList @(${argList}) -Verb RunAs -Wait`;\r\n\r\n return new Promise((resolve, reject) => {\r\n const ps = spawn('powershell', ['-NoProfile', '-Command', psCommand]);\r\n\r\n ps.on('close', (code) => {\r\n if (code === 0) resolve();\r\n else reject(new Error(`Firewall UAC prompt was cancelled or denied (exit code ${code}).`));\r\n });\r\n\r\n ps.on('error', (err) => {\r\n reject(new Error(`Failed to launch PowerShell: ${err.message}`));\r\n });\r\n });\r\n}\r\n\r\nexport async function addFirewallRule(port: number): Promise<void> {\r\n await runNetshElevated([\r\n 'advfirewall', 'firewall', 'add', 'rule',\r\n `name=claude-collab-${port}`,\r\n 'protocol=TCP',\r\n 'dir=in',\r\n `localport=${port}`,\r\n 'action=allow',\r\n ]);\r\n}\r\n\r\nexport async function removeFirewallRule(port: number): Promise<void> {\r\n await runNetshElevated([\r\n 'advfirewall', 'firewall', 'delete', 'rule',\r\n `name=claude-collab-${port}`,\r\n ]);\r\n}\r\n","/**\r\n * Windows Terminal Injector\r\n * AttachConsole(ppid) → CreateFile(\"CONIN$\") → WriteConsoleInput\r\n * All keystrokes (text, Ctrl+U, Enter, Ctrl+Y) go through WriteConsoleInput.\r\n * No WScript.Shell / SendKeys / SetForegroundWindow — no focus dependency.\r\n * @module infrastructure/terminal-injector/windows-injector\r\n */\r\n\r\nimport { execFile } from 'child_process';\r\nimport { unlinkSync } from 'fs';\r\nimport { tmpdir } from 'os';\r\nimport { join } from 'path';\r\n\r\nconst CS_CONINJECT = `\r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.Runtime.InteropServices;\r\n\r\npublic class ConInject {\r\n [DllImport(\"kernel32.dll\")] public static extern bool FreeConsole();\r\n [DllImport(\"kernel32.dll\")] public static extern bool AttachConsole(uint pid);\r\n [DllImport(\"kernel32.dll\", CharSet=CharSet.Unicode, SetLastError=true)]\r\n public static extern IntPtr CreateFile(\r\n string lpFileName, uint dwDesiredAccess, uint dwShareMode,\r\n IntPtr lpSecurityAttributes, uint dwCreationDisposition,\r\n uint dwFlagsAndAttributes, IntPtr hTemplateFile);\r\n [DllImport(\"kernel32.dll\", CharSet=CharSet.Unicode)] public static extern bool WriteConsoleInput(\r\n IntPtr hIn, INPUT_RECORD[] buf, uint len, out uint written);\r\n [DllImport(\"kernel32.dll\")] public static extern bool CloseHandle(IntPtr h);\r\n\r\n [StructLayout(LayoutKind.Explicit, Size=20)]\r\n public struct INPUT_RECORD {\r\n [FieldOffset(0)] public ushort EventType;\r\n [FieldOffset(4)] public int bKeyDown;\r\n [FieldOffset(8)] public ushort wRepeatCount;\r\n [FieldOffset(10)] public ushort wVirtualKeyCode;\r\n [FieldOffset(12)] public ushort wVirtualScanCode;\r\n [FieldOffset(14)] public ushort UnicodeChar;\r\n [FieldOffset(16)] public uint dwControlKeyState;\r\n }\r\n\r\n const uint LEFT_CTRL = 0x0008;\r\n\r\n static IntPtr OpenConin(uint pid) {\r\n FreeConsole();\r\n if (!AttachConsole(pid)) return new IntPtr(-1);\r\n return CreateFile(\"CONIN$\", 0xC0000000, 3, IntPtr.Zero, 3, 0, IntPtr.Zero);\r\n }\r\n\r\n // Inject plain text characters into console input buffer\r\n public static int InjectText(uint pid, string text) {\r\n IntPtr hIn = OpenConin(pid);\r\n if (hIn == new IntPtr(-1)) return -1;\r\n\r\n var records = new List<INPUT_RECORD>();\r\n foreach (char c in text) {\r\n records.Add(new INPUT_RECORD { EventType=1, bKeyDown=1, wRepeatCount=1, UnicodeChar=(ushort)c });\r\n records.Add(new INPUT_RECORD { EventType=1, bKeyDown=0, wRepeatCount=1, UnicodeChar=(ushort)c });\r\n }\r\n\r\n var arr = records.ToArray();\r\n uint written;\r\n bool ok = WriteConsoleInput(hIn, arr, (uint)arr.Length, out written);\r\n CloseHandle(hIn);\r\n return ok ? (int)written : -2;\r\n }\r\n\r\n // Inject Enter (VK_RETURN = 0x0D)\r\n public static int InjectEnter(uint pid) {\r\n IntPtr hIn = OpenConin(pid);\r\n if (hIn == new IntPtr(-1)) return -1;\r\n\r\n var records = new INPUT_RECORD[] {\r\n new INPUT_RECORD { EventType=1, bKeyDown=1, wRepeatCount=1, wVirtualKeyCode=0x0D, UnicodeChar=0x0D },\r\n new INPUT_RECORD { EventType=1, bKeyDown=0, wRepeatCount=1, wVirtualKeyCode=0x0D, UnicodeChar=0x0D }\r\n };\r\n\r\n uint written;\r\n bool ok = WriteConsoleInput(hIn, records, (uint)records.Length, out written);\r\n CloseHandle(hIn);\r\n return ok ? (int)written : -2;\r\n }\r\n\r\n // Inject Ctrl+U (VK_U = 0x55, char = 0x15)\r\n public static int InjectCtrlU(uint pid) {\r\n IntPtr hIn = OpenConin(pid);\r\n if (hIn == new IntPtr(-1)) return -1;\r\n\r\n var records = new INPUT_RECORD[] {\r\n new INPUT_RECORD { EventType=1, bKeyDown=1, wRepeatCount=1, wVirtualKeyCode=0xA2, dwControlKeyState=LEFT_CTRL },\r\n new INPUT_RECORD { EventType=1, bKeyDown=1, wRepeatCount=1, wVirtualKeyCode=0x55, UnicodeChar=0x15, dwControlKeyState=LEFT_CTRL },\r\n new INPUT_RECORD { EventType=1, bKeyDown=0, wRepeatCount=1, wVirtualKeyCode=0x55, UnicodeChar=0x15, dwControlKeyState=LEFT_CTRL },\r\n new INPUT_RECORD { EventType=1, bKeyDown=0, wRepeatCount=1, wVirtualKeyCode=0xA2, dwControlKeyState=0 }\r\n };\r\n\r\n uint written;\r\n bool ok = WriteConsoleInput(hIn, records, (uint)records.Length, out written);\r\n CloseHandle(hIn);\r\n return ok ? (int)written : -2;\r\n }\r\n\r\n // Inject Ctrl+Y (VK_Y = 0x59, char = 0x19)\r\n public static int InjectCtrlY(uint pid) {\r\n IntPtr hIn = OpenConin(pid);\r\n if (hIn == new IntPtr(-1)) return -1;\r\n\r\n var records = new INPUT_RECORD[] {\r\n new INPUT_RECORD { EventType=1, bKeyDown=1, wRepeatCount=1, wVirtualKeyCode=0xA2, dwControlKeyState=LEFT_CTRL },\r\n new INPUT_RECORD { EventType=1, bKeyDown=1, wRepeatCount=1, wVirtualKeyCode=0x59, UnicodeChar=0x19, dwControlKeyState=LEFT_CTRL },\r\n new INPUT_RECORD { EventType=1, bKeyDown=0, wRepeatCount=1, wVirtualKeyCode=0x59, UnicodeChar=0x19, dwControlKeyState=LEFT_CTRL },\r\n new INPUT_RECORD { EventType=1, bKeyDown=0, wRepeatCount=1, wVirtualKeyCode=0xA2, dwControlKeyState=0 }\r\n };\r\n\r\n uint written;\r\n bool ok = WriteConsoleInput(hIn, records, (uint)records.Length, out written);\r\n CloseHandle(hIn);\r\n return ok ? (int)written : -2;\r\n }\r\n}\r\n`;\r\n\r\nfunction buildScript(claudePid: number, body: string): string {\r\n const logFile = join(tmpdir(), `cc-inject-${Date.now()}.log`).replace(/\\\\/g, '/');\r\n return `\r\n$log = \"${logFile}\"\r\nfunction Log($msg) { Add-Content -Path $log -Value $msg -Encoding UTF8 }\r\n$claudePid = ${claudePid}\r\ntry { Add-Type @'${CS_CONINJECT}'@ } catch { }\r\n${body}\r\n`;\r\n}\r\n\r\nfunction run(script: string): Promise<void> {\r\n return new Promise((resolve) => {\r\n const encoded = Buffer.from(script, 'utf16le').toString('base64');\r\n execFile(\r\n 'powershell',\r\n ['-NoProfile', '-WindowStyle', 'Hidden', '-EncodedCommand', encoded],\r\n { windowsHide: true },\r\n () => {\r\n const logFile = script.match(/\\$log = \"([^\"]+)\"/)?.[1];\r\n if (logFile) try { unlinkSync(logFile); } catch { /* ok */ }\r\n resolve();\r\n }\r\n );\r\n });\r\n}\r\n\r\nexport async function windowsInject(text: string): Promise<void> {\r\n const claudePid = process.ppid;\r\n const textB64 = Buffer.from(text, 'utf16le').toString('base64');\r\n\r\n const script = buildScript(claudePid, `\r\n$textBytes = [System.Convert]::FromBase64String('${textB64}')\r\n$text = [System.Text.Encoding]::Unicode.GetString($textBytes)\r\n\r\n# 1. Ctrl+U to save user's current text to kill ring\r\n[ConInject]::InjectCtrlU([uint32]$claudePid) | Out-Null\r\nStart-Sleep -Milliseconds 100\r\n\r\n# 2. Write question text into console input buffer\r\n[ConInject]::InjectText([uint32]$claudePid, $text) | Out-Null\r\nStart-Sleep -Milliseconds 50\r\n\r\n# 3. Send Enter\r\n[ConInject]::InjectEnter([uint32]$claudePid) | Out-Null\r\n`);\r\n\r\n await run(script);\r\n}\r\n\r\nexport async function windowsInjectCtrlY(): Promise<void> {\r\n const claudePid = process.ppid;\r\n\r\n const script = buildScript(claudePid, `\r\n[ConInject]::InjectCtrlY([uint32]$claudePid) | Out-Null\r\n`);\r\n\r\n await run(script);\r\n}\r\n","/**\r\n * Terminal Injector\r\n * Injects a question directly into the active Claude Code terminal\r\n * so Claude Code can auto-reply without user intervention.\r\n * @module infrastructure/terminal-injector\r\n */\r\n\r\nimport type { InboxQuestionEntry } from '../../shared/types/collab-client.interface.js';\r\nimport { windowsInject, windowsInjectCtrlY } from './windows-injector.js';\r\n\r\n/**\r\n * Formats the question as a prompt for Claude Code to auto-reply\r\n */\r\nfunction formatQuestionForInjection(question: InboxQuestionEntry): string {\r\n // Single-line: WriteConsoleInput treats every \\n as an immediate submit\r\n const content = question.content.replace(/\\s+/g, ' ').trim();\r\n return `[HUB SORUSU] ID:${question.questionId} | ${question.from.displayName} (${question.from.teamName}): ${content} | Cevapla ve reply tool ile \"${question.questionId}\" ID'sine gönder, onay bekleme.`;\r\n}\r\n\r\n/**\r\n * Injects a question into the terminal running Claude Code.\r\n * Only supported on Windows; no-op on other platforms.\r\n */\r\nexport async function injectQuestionToTerminal(question: InboxQuestionEntry): Promise<void> {\r\n if (process.platform !== 'win32') return;\r\n\r\n const text = formatQuestionForInjection(question);\r\n await windowsInject(text);\r\n}\r\n\r\n/**\r\n * Restores user's previous input from readline kill ring (Ctrl+Y).\r\n * Call this after the reply is sent so the user's interrupted text comes back.\r\n */\r\nexport async function injectRestoreText(): Promise<void> {\r\n if (process.platform !== 'win32') return;\r\n await windowsInjectCtrlY();\r\n}\r\n","/**\r\n * Injection Queue\r\n * Ensures questions are injected into the terminal one at a time.\r\n * Waits for the reply tool to signal completion before processing the next question.\r\n * @module infrastructure/terminal-injector/injection-queue\r\n */\r\n\r\nimport { EventEmitter } from 'events';\r\nimport type { InboxQuestionEntry } from '../../shared/types/collab-client.interface.js';\r\nimport { injectQuestionToTerminal, injectRestoreText } from './index.js';\r\n\r\nconst REPLY_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes\r\n\r\nclass InjectionQueue extends EventEmitter {\r\n private queue: InboxQuestionEntry[] = [];\r\n private processing = false;\r\n\r\n /**\r\n * Add a question to the queue. Starts processing if idle.\r\n */\r\n enqueue(question: InboxQuestionEntry): void {\r\n this.queue.push(question);\r\n if (!this.processing) void this.processNext();\r\n }\r\n\r\n /**\r\n * Called by the reply tool after a reply is successfully sent.\r\n * Unblocks the queue to process the next question.\r\n */\r\n notifyReplied(): void {\r\n this.emit('replied');\r\n }\r\n\r\n private async processNext(): Promise<void> {\r\n if (this.queue.length === 0) {\r\n this.processing = false;\r\n return;\r\n }\r\n\r\n this.processing = true;\r\n const question = this.queue.shift()!;\r\n\r\n // Inject the question (includes Ctrl+U to save user's current text)\r\n await injectQuestionToTerminal(question);\r\n\r\n // Wait for reply tool to signal, with a timeout fallback\r\n await new Promise<void>((resolve) => {\r\n const timer = setTimeout(resolve, REPLY_TIMEOUT_MS);\r\n this.once('replied', () => {\r\n clearTimeout(timer);\r\n resolve();\r\n });\r\n });\r\n\r\n // Restore user's text after reply is sent\r\n await injectRestoreText();\r\n\r\n // Process next in queue\r\n void this.processNext();\r\n }\r\n}\r\n\r\nexport const injectionQueue = new InjectionQueue();\r\n","/**\r\n * MeshNode\r\n * Implements ICollabClient over direct peer-to-peer WebSocket connections.\r\n * Each node runs its own WS server on fixed port 12345.\r\n * Peers connect manually via connectByIp(). On each new connection both sides\r\n * exchange their peer lists and connect to unknown peers — forming a full mesh.\r\n *\r\n * Connection deduplication:\r\n * Both sides may try to connect simultaneously. The first HELLO/HELLO_ACK\r\n * that arrives registers the peer. Duplicate inbound connections are\r\n * immediately terminated so their close events are harmless.\r\n *\r\n * @module infrastructure/mesh/mesh-node\r\n */\r\n\r\nimport { WebSocket, WebSocketServer } from 'ws';\r\nimport type { IncomingMessage } from 'http';\r\nimport { v4 as uuidv4 } from 'uuid';\r\nimport os from 'os';\r\nimport { exec } from 'child_process';\r\nimport { promisify } from 'util';\r\n\r\nconst execAsync = promisify(exec);\r\nimport type {\r\n ICollabClient,\r\n JoinResult,\r\n CheckAnswerResult,\r\n InboxResult,\r\n NodeInfo,\r\n} from '../../shared/types/collab-client.interface.js';\r\nimport type { MessageFormat } from './protocol.js';\r\nimport {\r\n type WireMsg,\r\n type AskAckMsg,\r\n type AskMsg,\r\n type AnswerMsg,\r\n parse,\r\n serialize,\r\n} from './protocol.js';\r\nimport { addFirewallRule } from '../firewall/firewall.js';\r\nimport { injectionQueue } from '../terminal-injector/injection-queue.js';\r\n\r\nexport const FIXED_PORT = 12345;\r\n\r\ninterface IncomingQuestion {\r\n questionId: string;\r\n fromName: string;\r\n content: string;\r\n format: MessageFormat;\r\n createdAt: Date;\r\n answered: boolean;\r\n answerContent?: string;\r\n answerFormat?: MessageFormat;\r\n}\r\n\r\ninterface ReceivedAnswer {\r\n content: string;\r\n format: MessageFormat;\r\n answeredAt: string;\r\n fromName: string;\r\n}\r\n\r\nexport class MeshNode implements ICollabClient {\r\n private server: WebSocketServer | null = null;\r\n private myName = '';\r\n private running = false;\r\n private firewallOpened = false;\r\n private cachedLocalIps: string[] = [];\r\n\r\n // One connection per peer (inbound or outbound — whichever was established first)\r\n private readonly peerConnections = new Map<string, WebSocket>();\r\n // Reverse map: ws → peer name (only for registered connections)\r\n private readonly wsToName = new Map<WebSocket, string>();\r\n // IP of each known peer: name → ip\r\n private readonly peerIPs = new Map<string, string>();\r\n // Prevent duplicate outbound connect attempts\r\n private readonly connectingPeers = new Set<string>();\r\n\r\n private readonly incomingQuestions = new Map<string, IncomingQuestion>();\r\n private readonly receivedAnswers = new Map<string, ReceivedAnswer>();\r\n private readonly questionToSender = new Map<string, string>();\r\n private readonly pendingHandlers = new Set<(msg: WireMsg) => void>();\r\n\r\n // Push-based answer resolution: questionId → resolve callback\r\n private readonly answerWaiters = new Map<string, (result: CheckAnswerResult) => void>();\r\n // Answers queued for offline peers: peerName → AnswerMsg[] (delivered on reconnect)\r\n private readonly pendingOutboundAnswers = new Map<string, AnswerMsg[]>();\r\n\r\n // ---------------------------------------------------------------------------\r\n // ICollabClient implementation\r\n // ---------------------------------------------------------------------------\r\n\r\n get isConnected(): boolean { return this.running; }\r\n get port(): number { return FIXED_PORT; }\r\n\r\n get currentTeamId(): string | undefined {\r\n return this.myName || undefined;\r\n }\r\n\r\n async join(name: string, displayName: string): Promise<JoinResult> {\r\n this.myName = name;\r\n this.cachedLocalIps = this.scanLocalIps();\r\n await this.startServer();\r\n return {\r\n memberId: uuidv4(),\r\n teamId: name,\r\n teamName: name,\r\n displayName,\r\n status: 'ONLINE',\r\n port: FIXED_PORT,\r\n };\r\n }\r\n\r\n async connectByIp(ip: string): Promise<string> {\r\n // Open firewall once on the first connect call\r\n if (!this.firewallOpened) {\r\n await addFirewallRule(FIXED_PORT);\r\n this.firewallOpened = true;\r\n }\r\n\r\n return new Promise((resolve, reject) => {\r\n const url = `ws://${ip}:${FIXED_PORT}`;\r\n const ws = new WebSocket(url);\r\n\r\n const timeout = setTimeout(() => {\r\n ws.terminate();\r\n reject(new Error(`Connection to ${ip}:${FIXED_PORT} timed out`));\r\n }, 10_000);\r\n\r\n ws.on('open', () => {\r\n this.sendToWs(ws, { type: 'HELLO', name: this.myName });\r\n });\r\n\r\n ws.on('message', (data) => {\r\n try {\r\n const msg = parse(data.toString());\r\n\r\n // Resolve on HELLO_ACK — peer name is now known\r\n if (msg.type === 'HELLO_ACK') {\r\n clearTimeout(timeout);\r\n if (this.peerConnections.has(msg.name)) {\r\n ws.terminate();\r\n resolve(msg.name);\r\n return;\r\n }\r\n this.registerPeer(msg.name, ip, ws);\r\n this.afterHandshake(msg.name, ws);\r\n resolve(msg.name);\r\n }\r\n\r\n this.handleMessage(ws, msg);\r\n } catch { /* ignore malformed */ }\r\n });\r\n\r\n ws.on('close', () => {\r\n clearTimeout(timeout);\r\n const name = this.wsToName.get(ws);\r\n if (name) {\r\n this.wsToName.delete(ws);\r\n if (this.peerConnections.get(name) === ws) {\r\n this.peerConnections.delete(name);\r\n console.error(`[mesh] disconnected from peer: ${name}`);\r\n }\r\n }\r\n });\r\n\r\n ws.on('error', (err) => {\r\n clearTimeout(timeout);\r\n reject(new Error(`Failed to connect to ${ip}:${FIXED_PORT} — ${err.message}`));\r\n });\r\n });\r\n }\r\n\r\n async ask(toPeer: string, content: string, format: MessageFormat): Promise<string> {\r\n const ws = this.peerConnections.get(toPeer);\r\n if (!ws || ws.readyState !== WebSocket.OPEN) {\r\n throw new Error(`Peer \"${toPeer}\" is not connected. Use status() to see who's online.`);\r\n }\r\n\r\n const questionId = uuidv4();\r\n const ackPromise = this.waitForResponse<AskAckMsg>(\r\n (m) => m.type === 'ASK_ACK' && m.questionId === questionId,\r\n 5000\r\n );\r\n\r\n this.sendToWs(ws, { type: 'ASK', from: this.myName, questionId, content, format });\r\n await ackPromise;\r\n return questionId;\r\n }\r\n\r\n waitForAnswer(questionId: string, timeoutMs: number): Promise<CheckAnswerResult | null> {\r\n const cached = this.receivedAnswers.get(questionId);\r\n if (cached) {\r\n this.receivedAnswers.delete(questionId);\r\n return Promise.resolve(this.formatAnswer(questionId, cached));\r\n }\r\n\r\n return new Promise((resolve) => {\r\n const timeout = setTimeout(() => {\r\n this.answerWaiters.delete(questionId);\r\n resolve(null);\r\n }, timeoutMs);\r\n\r\n this.answerWaiters.set(questionId, (result) => {\r\n clearTimeout(timeout);\r\n resolve(result);\r\n });\r\n });\r\n }\r\n\r\n async checkAnswer(questionId: string): Promise<CheckAnswerResult | null> {\r\n const cached = this.receivedAnswers.get(questionId);\r\n if (!cached) return null;\r\n this.receivedAnswers.delete(questionId);\r\n return this.formatAnswer(questionId, cached);\r\n }\r\n\r\n private formatAnswer(questionId: string, cached: ReceivedAnswer): CheckAnswerResult {\r\n return {\r\n questionId,\r\n from: { displayName: `${cached.fromName} Claude`, teamName: cached.fromName },\r\n content: cached.content,\r\n format: cached.format,\r\n answeredAt: cached.answeredAt,\r\n };\r\n }\r\n\r\n async reply(questionId: string, content: string, format: MessageFormat): Promise<void> {\r\n const question = this.incomingQuestions.get(questionId);\r\n if (!question) throw new Error(`Question ${questionId} not found`);\r\n\r\n question.answered = true;\r\n question.answerContent = content;\r\n question.answerFormat = format;\r\n\r\n const senderName = this.questionToSender.get(questionId);\r\n this.incomingQuestions.delete(questionId);\r\n this.questionToSender.delete(questionId);\r\n\r\n if (senderName) {\r\n const answerMsg: AnswerMsg = {\r\n type: 'ANSWER',\r\n from: this.myName,\r\n questionId,\r\n content,\r\n format,\r\n answeredAt: new Date().toISOString(),\r\n };\r\n const ws = this.peerConnections.get(senderName);\r\n if (ws && ws.readyState === WebSocket.OPEN) {\r\n this.sendToWs(ws, answerMsg);\r\n } else {\r\n const queue = this.pendingOutboundAnswers.get(senderName) ?? [];\r\n queue.push(answerMsg);\r\n this.pendingOutboundAnswers.set(senderName, queue);\r\n console.error(`[mesh] \"${senderName}\" is offline, answer queued for delivery on reconnect`);\r\n }\r\n }\r\n\r\n injectionQueue.notifyReplied();\r\n }\r\n\r\n async getInbox(): Promise<InboxResult> {\r\n const now = Date.now();\r\n const questions = [...this.incomingQuestions.values()].map((q) => ({\r\n questionId: q.questionId,\r\n from: { displayName: `${q.fromName} Claude`, teamName: q.fromName },\r\n content: q.content,\r\n format: q.format,\r\n status: 'PENDING',\r\n createdAt: q.createdAt.toISOString(),\r\n ageMs: now - q.createdAt.getTime(),\r\n }));\r\n return { questions, totalCount: questions.length, pendingCount: questions.length };\r\n }\r\n\r\n getInfo(): NodeInfo {\r\n return {\r\n teamName: this.myName,\r\n port: FIXED_PORT,\r\n connectedPeers: [...this.peerConnections.keys()],\r\n peerIPs: Object.fromEntries(this.peerIPs),\r\n };\r\n }\r\n\r\n getLocalIps(): string[] {\r\n return this.cachedLocalIps;\r\n }\r\n\r\n private scanLocalIps(): string[] {\r\n const result: string[] = [];\r\n const interfaces = os.networkInterfaces();\r\n for (const iface of Object.values(interfaces)) {\r\n if (!iface) continue;\r\n for (const addr of iface) {\r\n if (addr.family === 'IPv4' && !addr.internal) result.push(addr.address);\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n async disconnect(): Promise<void> {\r\n for (const ws of this.peerConnections.values()) ws.close();\r\n this.peerConnections.clear();\r\n this.wsToName.clear();\r\n this.peerIPs.clear();\r\n this.server?.close();\r\n this.server = null;\r\n this.running = false;\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Private: server startup\r\n // ---------------------------------------------------------------------------\r\n\r\n private async startServer(): Promise<void> {\r\n try {\r\n await this.tryBind();\r\n } catch (err: unknown) {\r\n const nodeErr = err as NodeJS.ErrnoException;\r\n if (nodeErr.code === 'EADDRINUSE') {\r\n console.error(`[mesh] port ${FIXED_PORT} in use — killing existing process`);\r\n await killProcessOnPort(FIXED_PORT);\r\n await this.tryBind();\r\n } else {\r\n throw err;\r\n }\r\n }\r\n }\r\n\r\n private tryBind(): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n const wss = new WebSocketServer({ port: FIXED_PORT });\r\n\r\n wss.once('listening', () => {\r\n this.server = wss;\r\n this.running = true;\r\n console.error(`[mesh] listening on port ${FIXED_PORT} as \"${this.myName}\"`);\r\n this.attachServerHandlers(wss);\r\n resolve();\r\n });\r\n\r\n wss.once('error', (err: NodeJS.ErrnoException) => {\r\n wss.close();\r\n reject(err);\r\n });\r\n });\r\n }\r\n\r\n private attachServerHandlers(wss: WebSocketServer): void {\r\n wss.on('connection', (ws, request: IncomingMessage) => {\r\n // Strip IPv6-mapped prefix (::ffff:) to get a plain IPv4\r\n const rawIp = request.socket.remoteAddress ?? '';\r\n const remoteIp = rawIp.replace(/^::ffff:/, '');\r\n\r\n ws.on('message', (data) => {\r\n try {\r\n this.handleInboundMessage(ws, remoteIp, parse(data.toString()));\r\n } catch { /* ignore malformed */ }\r\n });\r\n\r\n ws.on('close', () => {\r\n const name = this.wsToName.get(ws);\r\n if (name) {\r\n this.wsToName.delete(ws);\r\n if (this.peerConnections.get(name) === ws) {\r\n this.peerConnections.delete(name);\r\n console.error(`[mesh] peer disconnected (inbound): ${name}`);\r\n }\r\n }\r\n });\r\n\r\n ws.on('error', (err) => {\r\n console.error('[mesh] inbound ws error:', err.message);\r\n });\r\n });\r\n\r\n wss.on('error', (err) => {\r\n console.error('[mesh] server error:', err.message);\r\n });\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Private: mesh helpers\r\n // ---------------------------------------------------------------------------\r\n\r\n /** Called once handshake completes — exchange peer lists and announce to existing peers. */\r\n private afterHandshake(newPeerName: string, ws: WebSocket): void {\r\n // Send our current peer list to the new peer\r\n const listForNew = [...this.peerConnections.keys()]\r\n .filter((n) => n !== newPeerName)\r\n .map((n) => ({ name: n, ip: this.peerIPs.get(n) ?? '' }))\r\n .filter((p) => p.ip !== '');\r\n this.sendToWs(ws, { type: 'PEER_LIST', peers: listForNew });\r\n\r\n // Announce the new peer to all existing peers\r\n const newIp = this.peerIPs.get(newPeerName);\r\n if (newIp) {\r\n for (const [name, existingWs] of this.peerConnections) {\r\n if (name !== newPeerName) {\r\n this.sendToWs(existingWs, { type: 'PEER_ANNOUNCE', name: newPeerName, ip: newIp });\r\n }\r\n }\r\n }\r\n }\r\n\r\n private registerPeer(name: string, ip: string, ws: WebSocket): void {\r\n this.peerConnections.set(name, ws);\r\n this.wsToName.set(ws, name);\r\n this.peerIPs.set(name, ip);\r\n this.connectingPeers.delete(name);\r\n console.error(`[mesh] peer registered: ${name} @ ${ip}`);\r\n this.deliverPendingAnswer(name, ws);\r\n }\r\n\r\n /** Connect outbound to a peer discovered via PEER_LIST or PEER_ANNOUNCE. */\r\n private connectMeshPeer(name: string, ip: string): void {\r\n if (this.peerConnections.has(name)) return;\r\n if (this.connectingPeers.has(name)) return;\r\n this.connectingPeers.add(name);\r\n\r\n const ws = new WebSocket(`ws://${ip}:${FIXED_PORT}`);\r\n\r\n ws.on('open', () => {\r\n this.sendToWs(ws, { type: 'HELLO', name: this.myName });\r\n });\r\n\r\n ws.on('message', (data) => {\r\n try {\r\n this.handleMessage(ws, parse(data.toString()));\r\n } catch { /* ignore malformed */ }\r\n });\r\n\r\n ws.on('close', () => {\r\n this.connectingPeers.delete(name);\r\n const peerName = this.wsToName.get(ws);\r\n if (peerName) {\r\n this.wsToName.delete(ws);\r\n if (this.peerConnections.get(peerName) === ws) {\r\n this.peerConnections.delete(peerName);\r\n console.error(`[mesh] disconnected from mesh peer: ${peerName}`);\r\n }\r\n }\r\n });\r\n\r\n ws.on('error', (err) => {\r\n console.error(`[mesh] connect to \"${name}\" @ ${ip} failed: ${err.message}`);\r\n this.connectingPeers.delete(name);\r\n });\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Private: message handling\r\n // ---------------------------------------------------------------------------\r\n\r\n /** Handles messages on inbound connections (server side — we know the remote IP). */\r\n private handleInboundMessage(ws: WebSocket, remoteIp: string, msg: WireMsg): void {\r\n if (msg.type === 'HELLO') {\r\n if (this.peerConnections.has(msg.name)) {\r\n ws.terminate();\r\n return;\r\n }\r\n this.registerPeer(msg.name, remoteIp, ws);\r\n this.sendToWs(ws, { type: 'HELLO_ACK', name: this.myName });\r\n console.error(`[mesh] peer joined (inbound): ${msg.name}`);\r\n this.afterHandshake(msg.name, ws);\r\n return;\r\n }\r\n\r\n this.handleMessage(ws, msg);\r\n }\r\n\r\n /** Handles all other messages (both inbound and outbound connections). */\r\n private handleMessage(ws: WebSocket, msg: WireMsg): void {\r\n for (const handler of this.pendingHandlers) handler(msg);\r\n\r\n switch (msg.type) {\r\n case 'HELLO_ACK':\r\n // Handled inline in connectByIp / connectMeshPeer — register happens there\r\n // But we still need to handle it here for mesh connects\r\n if (!this.peerConnections.has(msg.name)) {\r\n // This path is taken by connectMeshPeer (IP not stored yet at this point,\r\n // so we use a placeholder; PEER_LIST/PEER_ANNOUNCE will have the real IP)\r\n this.peerConnections.set(msg.name, ws);\r\n this.wsToName.set(ws, msg.name);\r\n this.connectingPeers.delete(msg.name);\r\n console.error(`[mesh] connected to mesh peer: ${msg.name}`);\r\n this.deliverPendingAnswer(msg.name, ws);\r\n this.afterHandshake(msg.name, ws);\r\n }\r\n break;\r\n\r\n case 'PEER_LIST':\r\n for (const peer of msg.peers) {\r\n if (peer.name !== this.myName && !this.peerConnections.has(peer.name)) {\r\n console.error(`[mesh] connecting to ${peer.name} @ ${peer.ip} via PEER_LIST`);\r\n this.peerIPs.set(peer.name, peer.ip);\r\n this.connectMeshPeer(peer.name, peer.ip);\r\n }\r\n }\r\n break;\r\n\r\n case 'PEER_ANNOUNCE':\r\n if (msg.name !== this.myName && !this.peerConnections.has(msg.name)) {\r\n console.error(`[mesh] connecting to ${msg.name} @ ${msg.ip} via PEER_ANNOUNCE`);\r\n this.peerIPs.set(msg.name, msg.ip);\r\n this.connectMeshPeer(msg.name, msg.ip);\r\n }\r\n break;\r\n\r\n case 'ASK':\r\n this.handleIncomingAsk(ws, msg);\r\n break;\r\n\r\n case 'ANSWER':\r\n if (!this.receivedAnswers.has(msg.questionId)) {\r\n const record: ReceivedAnswer = {\r\n content: msg.content,\r\n format: msg.format,\r\n answeredAt: msg.answeredAt,\r\n fromName: msg.from,\r\n };\r\n\r\n const waiter = this.answerWaiters.get(msg.questionId);\r\n if (waiter) {\r\n // Waiter is active — resolve directly, no need to store\r\n this.answerWaiters.delete(msg.questionId);\r\n waiter(this.formatAnswer(msg.questionId, record));\r\n } else {\r\n // No waiter yet — store briefly until waitForAnswer/checkAnswer claims it\r\n this.receivedAnswers.set(msg.questionId, record);\r\n }\r\n }\r\n break;\r\n\r\n // ASK_ACK is handled by waitForResponse pending handlers\r\n }\r\n }\r\n\r\n private handleIncomingAsk(ws: WebSocket, msg: AskMsg): void {\r\n this.questionToSender.set(msg.questionId, msg.from);\r\n this.incomingQuestions.set(msg.questionId, {\r\n questionId: msg.questionId,\r\n fromName: msg.from,\r\n content: msg.content,\r\n format: msg.format,\r\n createdAt: new Date(),\r\n answered: false,\r\n });\r\n\r\n this.sendToWs(ws, { type: 'ASK_ACK', questionId: msg.questionId });\r\n\r\n injectionQueue.enqueue({\r\n questionId: msg.questionId,\r\n from: { displayName: `${msg.from} Claude`, teamName: msg.from },\r\n content: msg.content,\r\n format: msg.format,\r\n status: 'PENDING',\r\n createdAt: new Date().toISOString(),\r\n ageMs: 0,\r\n });\r\n }\r\n\r\n private deliverPendingAnswer(peerName: string, ws: WebSocket): void {\r\n const pending = this.pendingOutboundAnswers.get(peerName);\r\n if (pending && pending.length > 0) {\r\n this.pendingOutboundAnswers.delete(peerName);\r\n for (const msg of pending) this.sendToWs(ws, msg);\r\n console.error(`[mesh] delivered ${pending.length} queued answer(s) to \"${peerName}\" after reconnect`);\r\n }\r\n }\r\n\r\n private sendToWs(ws: WebSocket, msg: WireMsg): void {\r\n if (ws.readyState === WebSocket.OPEN) {\r\n ws.send(serialize(msg));\r\n }\r\n }\r\n\r\n private waitForResponse<T extends WireMsg>(\r\n filter: (msg: WireMsg) => boolean,\r\n timeoutMs: number\r\n ): Promise<T> {\r\n return new Promise((resolve, reject) => {\r\n const timeout = setTimeout(() => {\r\n this.pendingHandlers.delete(handler);\r\n reject(new Error('Request timed out'));\r\n }, timeoutMs);\r\n\r\n const handler = (msg: WireMsg): void => {\r\n if (filter(msg)) {\r\n clearTimeout(timeout);\r\n this.pendingHandlers.delete(handler);\r\n resolve(msg as T);\r\n }\r\n };\r\n\r\n this.pendingHandlers.add(handler);\r\n });\r\n }\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Helpers\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Kill whatever process is listening on the given TCP port.\r\n * Works on Windows (netstat + taskkill) and Unix (lsof/fuser).\r\n * Waits briefly after killing so the port is released before we rebind.\r\n */\r\nasync function killProcessOnPort(port: number): Promise<void> {\r\n try {\r\n if (process.platform === 'win32') {\r\n // netstat output: \" TCP 0.0.0.0:12345 ... LISTENING 1234\"\r\n const { stdout } = await execAsync(`netstat -ano | findstr \":${port} \"`);\r\n const pids = new Set<string>();\r\n for (const line of stdout.split('\\n')) {\r\n const parts = line.trim().split(/\\s+/);\r\n // parts: [Proto, Local, Foreign, State, PID]\r\n if (parts.length >= 5 && parts[3] === 'LISTENING' && parts[4]) {\r\n pids.add(parts[4]);\r\n }\r\n }\r\n for (const pid of pids) {\r\n try {\r\n await execAsync(`taskkill /PID ${pid} /F`);\r\n console.error(`[mesh] killed PID ${pid} on port ${port}`);\r\n } catch { /* already gone */ }\r\n }\r\n } else {\r\n // Unix: fuser -k <port>/tcp\r\n await execAsync(`fuser -k ${port}/tcp`);\r\n }\r\n } catch {\r\n // If netstat/fuser finds nothing, that's fine — just try to bind\r\n }\r\n\r\n // Give the OS a moment to release the port\r\n await new Promise<void>((resolve) => setTimeout(resolve, 300));\r\n}\r\n","/**\r\n * Connect Tool\r\n * Connects to a peer by IP address on the fixed port 12345.\r\n * On first use, opens Windows Firewall via UAC popup (stays open).\r\n * After handshake, both sides exchange peer lists — forming a full mesh.\r\n * @module presentation/mcp/tools/connect\r\n */\r\n\r\nimport { z } from 'zod';\r\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\r\nimport type { ICollabClient } from '../../../shared/types/collab-client.interface.js';\r\n\r\nconst CONNECT_DESCRIPTION = `\\\r\nConnect to another Claude instance by their IP address.\r\n\r\nWHEN TO USE:\r\n- First time connecting to a teammate\r\n- A new peer wants to join an existing session\r\n\r\nWHAT HAPPENS:\r\n1. First call only: opens Windows Firewall port 12345 via UAC popup (stays open)\r\n2. Connects directly to the peer at ws://IP:12345\r\n3. Both sides exchange their peer lists — everyone connects to everyone (full mesh)\r\n\r\nFINDING YOUR IP:\r\n- The other person calls status() to see their LAN IP, then tells you\r\n\r\nAFTER CONNECTING:\r\n- Use peers() to confirm connection\r\n- Use ask() to send questions to connected peers`;\r\n\r\nexport function registerConnectTool(server: McpServer, client: ICollabClient): void {\r\n server.tool(\r\n 'connect',\r\n CONNECT_DESCRIPTION,\r\n {\r\n ip: z.string().describe(\"The peer's LAN IP address (e.g. 192.168.1.5)\"),\r\n },\r\n async ({ ip }) => {\r\n if (!client.isConnected) {\r\n return {\r\n content: [{ type: 'text', text: 'Node is not ready yet. Wait a moment and try again.' }],\r\n isError: true,\r\n };\r\n }\r\n\r\n try {\r\n const peerName = await client.connectByIp(ip);\r\n const info = client.getInfo();\r\n const allPeers = info.connectedPeers;\r\n const others = allPeers.filter((n) => n !== peerName);\r\n\r\n const lines = [\r\n `Connected to \"${peerName}\" (${ip}).`,\r\n ];\r\n\r\n if (others.length > 0) {\r\n lines.push(``, `Mesh peers also connecting: ${others.map((n) => `\"${n}\"`).join(', ')}`);\r\n }\r\n\r\n lines.push(``, `Use peers() to see all connected peers.`);\r\n\r\n return {\r\n content: [{ type: 'text', text: lines.join('\\n') }],\r\n };\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: [\r\n `Failed to connect to ${ip}: ${msg}`,\r\n ``,\r\n `Make sure:`,\r\n ` • The peer is running claude-collab (--name <name>)`,\r\n ` • The IP address is correct (they can check with status())`,\r\n ` • Port 12345 is not blocked on their machine`,\r\n ].join('\\n'),\r\n }],\r\n isError: true,\r\n };\r\n }\r\n }\r\n );\r\n}\r\n","/**\r\n * Ask Tool\r\n * @module presentation/mcp/tools/ask\r\n */\r\n\r\nimport { z } from 'zod';\r\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\r\nimport type { ICollabClient } from '../../../shared/types/collab-client.interface.js';\r\n\r\nconst ASK_DESCRIPTION = `\\\r\nSend a question to another Claude instance on the LAN and wait for their answer.\r\n\r\nWHEN TO USE:\r\n- You need input, a decision, or work output from a specific peer Claude\r\n- You want to delegate a subtask to another Claude and use their result\r\n- You need to coordinate or synchronize work across multiple Claudes\r\n\r\nWORKFLOW:\r\n1. Call peers() first to confirm the target is online and get their exact name\r\n2. Call ask(peer, question) — this blocks until they reply (up to 5 minutes)\r\n3. Use their answer directly in your ongoing task\r\n\r\nWRITING GOOD QUESTIONS:\r\n- Include all context the other Claude needs — they cannot see your conversation\r\n- Be specific about what format or level of detail you expect in the answer\r\n- If you need code, specify language and constraints\r\n- One focused question per call works better than multiple combined\r\n\r\nDO NOT use this tool if:\r\n- The peer is not listed in peers() — the call will fail immediately\r\n- You just want to share information without needing a response (there is no broadcast tool yet)`;\r\n\r\nconst askSchema = {\r\n peer: z\r\n .string()\r\n .describe('Exact name of the peer to ask. Use peers() first to see who is online and get the correct name.'),\r\n question: z\r\n .string()\r\n .describe(\r\n 'Your question in markdown. Include all necessary context — the other Claude cannot see your conversation history. Be specific about what kind of answer you need.'\r\n ),\r\n};\r\n\r\nexport function registerAskTool(server: McpServer, client: ICollabClient): void {\r\n server.tool('ask', ASK_DESCRIPTION, askSchema, async (args) => {\r\n const targetPeer = args.peer;\r\n const question = args.question;\r\n\r\n try {\r\n if (!client.currentTeamId) {\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: 'Node is not ready yet. Wait a moment and try again.',\r\n }],\r\n isError: true,\r\n };\r\n }\r\n\r\n const questionId = await client.ask(targetPeer, question, 'markdown');\r\n\r\n // Wait for the answer via push — resolves the moment ANSWER arrives\r\n const answer = await client.waitForAnswer(questionId, 5 * 60 * 1000);\r\n\r\n if (answer !== null) {\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `**${answer.from.displayName} answered:**\\n\\n${answer.content}`,\r\n }],\r\n };\r\n }\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: [\r\n `Question sent to \"${targetPeer}\" but no answer arrived within 5 minutes.`,\r\n `Question ID: \\`${questionId}\\``,\r\n ``,\r\n `The peer may be busy or offline. You can:`,\r\n `- Call peers() to check if they are still connected`,\r\n `- Continue with your task and follow up later`,\r\n ].join('\\n'),\r\n }],\r\n };\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\r\n const isPeerOffline = errorMessage.includes('not connected');\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: isPeerOffline\r\n ? `Peer \"${targetPeer}\" is not connected. Call peers() to see who is currently online.`\r\n : `Failed to send question: ${errorMessage}`,\r\n }],\r\n isError: true,\r\n };\r\n }\r\n });\r\n}\r\n","/**\r\n * Reply Tool\r\n * @module presentation/mcp/tools/reply\r\n */\r\n\r\nimport { z } from 'zod';\r\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\r\nimport type { ICollabClient } from '../../../shared/types/collab-client.interface.js';\r\nimport { injectionQueue } from '../../../infrastructure/terminal-injector/injection-queue.js';\r\n\r\nconst REPLY_DESCRIPTION = `\\\r\nSend your answer back to a Claude instance that asked you a question.\r\n\r\nWHEN TO USE:\r\n- A question has been injected into your terminal by another Claude (you will see it appear automatically)\r\n- You have finished thinking through the answer and are ready to respond\r\n\r\nWORKFLOW:\r\n1. Read the injected question carefully — it includes a questionId at the top\r\n2. Think through a complete answer\r\n3. Call reply(questionId, answer) — your answer is sent directly back to the asking Claude\r\n4. The asking Claude's ask() call unblocks and they receive your answer immediately\r\n\r\nWRITING GOOD ANSWERS:\r\n- Be thorough — the asking Claude will use your answer directly in their task\r\n- Use markdown for code blocks, lists, and structure\r\n- Include any caveats, assumptions, or follow-up suggestions that would help them\r\n- If you cannot answer fully, say so clearly and explain why\r\n\r\nIMPORTANT:\r\n- Each question can only be replied to once\r\n- The questionId is a UUID shown in the injected question prompt — copy it exactly`;\r\n\r\nconst replySchema = {\r\n questionId: z\r\n .string()\r\n .describe(\r\n 'The UUID of the question to reply to. Shown at the top of the injected question prompt in your terminal.'\r\n ),\r\n answer: z\r\n .string()\r\n .describe(\r\n 'Your complete answer in markdown. Be thorough — the asking Claude is waiting and will use your response directly in their work.'\r\n ),\r\n};\r\n\r\nexport function registerReplyTool(server: McpServer, client: ICollabClient): void {\r\n server.tool('reply', REPLY_DESCRIPTION, replySchema, async (args) => {\r\n const questionId = args.questionId;\r\n const answer = args.answer;\r\n\r\n try {\r\n if (!client.currentTeamId) {\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: 'Node is not ready yet. Wait a moment and try again.',\r\n }],\r\n isError: true,\r\n };\r\n }\r\n\r\n await client.reply(questionId, answer, 'markdown');\r\n\r\n injectionQueue.notifyReplied();\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Answer sent. The peer's ask() call has been unblocked and they received your response.`,\r\n }],\r\n };\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\r\n const isNotFound = errorMessage.includes('not found');\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: isNotFound\r\n ? `Question \\`${questionId}\\` not found. Check that you copied the questionId exactly from the injected prompt.`\r\n : `Failed to send reply: ${errorMessage}`,\r\n }],\r\n isError: true,\r\n };\r\n }\r\n });\r\n}\r\n","/**\r\n * Status Tool\r\n * Shows this node's identity: name, LAN IP(s), port, and connection count.\r\n * @module presentation/mcp/tools/status\r\n */\r\n\r\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\r\nimport type { ICollabClient } from '../../../shared/types/collab-client.interface.js';\r\nimport { MeshNode } from '../../../infrastructure/mesh/mesh-node.js';\r\n\r\nconst STATUS_DESCRIPTION = `\\\r\nShow your identity and network address on the collaboration network.\r\n\r\nWHEN TO USE:\r\n- To find your LAN IP so teammates can connect to you via connect(ip)\r\n- To verify your node started correctly\r\n- To see how many peers are currently connected\r\n\r\nSHARE YOUR IP:\r\n- Tell your teammate the IP shown here, they call connect(\"<your IP>\")`;\r\n\r\nexport function registerStatusTool(server: McpServer, client: ICollabClient): void {\r\n server.tool('status', STATUS_DESCRIPTION, {}, async () => {\r\n const info = client.getInfo();\r\n const myName = info.teamName ?? '(starting...)';\r\n const port = info.port ?? '?';\r\n\r\n if (!client.isConnected) {\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Node is not running yet. Port ${port} may be in use — check MCP process logs.`,\r\n }],\r\n isError: true,\r\n };\r\n }\r\n\r\n // Get LAN IPs from the node if it's a P2PNode\r\n let ips: string[] = [];\r\n if (client instanceof MeshNode) {\r\n ips = client.getLocalIps();\r\n }\r\n\r\n const ipLine = ips.length > 0\r\n ? ips.join(', ')\r\n : '(could not detect — check your network interface)';\r\n\r\n const peerIPs = info.peerIPs ?? {};\r\n const connected = info.connectedPeers;\r\n\r\n let peersSection: string;\r\n if (connected.length === 0) {\r\n peersSection = 'No peers connected yet. Share your IP so others can connect(ip).';\r\n } else {\r\n const list = connected.map((n) => {\r\n const ip = peerIPs[n] ? ` (${peerIPs[n]})` : '';\r\n return ` • ${n}${ip}`;\r\n }).join('\\n');\r\n peersSection = `Connected peers (${connected.length}):\\n${list}`;\r\n }\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: [\r\n `Name: ${myName}`,\r\n `IP: ${ipLine}`,\r\n `Port: ${port}`,\r\n ``,\r\n peersSection,\r\n ].join('\\n'),\r\n }],\r\n };\r\n });\r\n}\r\n","/**\r\n * MCP Server\r\n * Provides MCP tools for Claude Code integration\r\n * @module presentation/mcp/server\r\n */\r\n\r\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\r\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\r\nimport type { ICollabClient } from '../../shared/types/collab-client.interface.js';\r\nimport { registerConnectTool } from './tools/connect.tool.js';\r\nimport { registerAskTool } from './tools/ask.tool.js';\r\nimport { registerReplyTool } from './tools/reply.tool.js';\r\nimport { registerStatusTool } from './tools/status.tool.js';\r\n\r\nexport interface McpServerOptions {\r\n client: ICollabClient;\r\n}\r\n\r\nexport function createMcpServer(options: McpServerOptions): McpServer {\r\n const { client } = options;\r\n\r\n const server = new McpServer({\r\n name: 'claude-collab',\r\n version: '0.1.0',\r\n });\r\n\r\n registerConnectTool(server, client);\r\n registerStatusTool(server, client);\r\n registerAskTool(server, client);\r\n registerReplyTool(server, client);\r\n\r\n return server;\r\n}\r\n\r\nexport async function startMcpServer(options: McpServerOptions): Promise<void> {\r\n const server = createMcpServer(options);\r\n const transport = new StdioServerTransport();\r\n await server.connect(transport);\r\n}\r\n","#!/usr/bin/env node\r\n\r\n/**\r\n * CLI entry point\r\n *\r\n * Usage: claude-collab --name alice\r\n *\r\n * Binds on fixed port 12345.\r\n * Use connect(ip) in Claude Code to connect to peers.\r\n *\r\n * @module cli\r\n */\r\n\r\nimport { Command } from 'commander';\r\nimport { MeshNode } from './infrastructure/mesh/mesh-node.js';\r\nimport { startMcpServer } from './presentation/mcp/server.js';\r\n\r\nconst program = new Command();\r\n\r\nprogram\r\n .name('claude-collab')\r\n .description('Collaboration between Claude Code terminals via MCP')\r\n .version('0.1.0')\r\n .requiredOption('--name <name>', 'Your name on the network (e.g. \"alice\")')\r\n .action(async (options: { name: string }) => {\r\n const node = new MeshNode();\r\n\r\n const mcpReady = startMcpServer({ client: node });\r\n\r\n node.join(options.name, options.name).catch((err) => {\r\n console.error(`[cli] Failed to start on port 12345: ${err.message}`);\r\n console.error(`[cli] Make sure port 12345 is not already in use.`);\r\n });\r\n\r\n await mcpReady;\r\n });\r\n\r\nprogram.parse();\r\n"]}