@dolusoft/claude-collab 1.8.2 → 1.8.3

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 CHANGED
@@ -704,10 +704,17 @@ var HubManager = class {
704
704
  server.start(port);
705
705
  this.hubServer = server;
706
706
  this.currentPort = port;
707
- await addFirewallRule(port);
708
707
  const advertiser = new MdnsAdvertiser();
709
708
  advertiser.start(port);
710
709
  this.advertiser = advertiser;
710
+ let firewallAdded = false;
711
+ try {
712
+ await addFirewallRule(port);
713
+ firewallAdded = true;
714
+ } catch (err) {
715
+ console.error("[hub-manager] firewall rule failed:", err);
716
+ }
717
+ return { firewallAdded };
711
718
  }
712
719
  async stop() {
713
720
  if (!this.isRunning) throw new Error("Hub is not running");
@@ -719,34 +726,51 @@ var HubManager = class {
719
726
  this.hubServer.stop();
720
727
  this.hubServer = null;
721
728
  this.currentPort = null;
722
- await removeFirewallRule(port);
729
+ let firewallRemoved = false;
730
+ try {
731
+ await removeFirewallRule(port);
732
+ firewallRemoved = true;
733
+ } catch (err) {
734
+ console.error("[hub-manager] firewall rule removal failed:", err);
735
+ }
736
+ return { firewallRemoved };
723
737
  }
724
738
  };
725
- function runElevated(netshArgs) {
739
+ function runElevated(argArray) {
740
+ const argList = argArray.map((a) => `"${a}"`).join(",");
741
+ const psCommand = `Start-Process -FilePath "netsh" -ArgumentList @(${argList}) -Verb RunAs -Wait`;
726
742
  return new Promise((resolve, reject) => {
727
- const ps = spawn("powershell", [
728
- "-NoProfile",
729
- "-Command",
730
- `Start-Process -FilePath "netsh" -ArgumentList "${netshArgs}" -Verb RunAs -Wait`
731
- ]);
743
+ const ps = spawn("powershell", ["-NoProfile", "-Command", psCommand]);
732
744
  ps.on("close", (code) => {
733
745
  if (code === 0) resolve();
734
- else reject(new Error(`Firewall command failed (exit code ${code}). User may have cancelled the UAC prompt.`));
746
+ else reject(new Error(`Firewall UAC prompt was cancelled or denied (exit code ${code}).`));
735
747
  });
736
748
  ps.on("error", (err) => {
737
- reject(new Error(`Failed to launch PowerShell for firewall elevation: ${err.message}`));
749
+ reject(new Error(`Failed to launch PowerShell: ${err.message}`));
738
750
  });
739
751
  });
740
752
  }
741
753
  async function addFirewallRule(port) {
742
- await runElevated(
743
- `advfirewall firewall add rule name="claude-collab-${port}" protocol=TCP dir=in localport=${port} action=allow`
744
- );
754
+ await runElevated([
755
+ "advfirewall",
756
+ "firewall",
757
+ "add",
758
+ "rule",
759
+ `name=claude-collab-${port}`,
760
+ "protocol=TCP",
761
+ "dir=in",
762
+ `localport=${port}`,
763
+ "action=allow"
764
+ ]);
745
765
  }
746
766
  async function removeFirewallRule(port) {
747
- await runElevated(
748
- `advfirewall firewall delete rule name="claude-collab-${port}"`
749
- );
767
+ await runElevated([
768
+ "advfirewall",
769
+ "firewall",
770
+ "delete",
771
+ "rule",
772
+ `name=claude-collab-${port}`
773
+ ]);
750
774
  }
751
775
  var askSchema = {
752
776
  peer: z.string().describe('Name of the peer to ask (e.g., "alice", "backend")'),
@@ -923,15 +947,14 @@ function registerStartHubTool(server, client, hubManager) {
923
947
  }]
924
948
  };
925
949
  }
950
+ let firewallAdded = false;
926
951
  try {
927
- await hubManager.start(port);
952
+ const result = await hubManager.start(port);
953
+ firewallAdded = result.firewallAdded;
928
954
  } catch (err) {
929
955
  const msg = err instanceof Error ? err.message : String(err);
930
956
  return {
931
- content: [{
932
- type: "text",
933
- text: `Failed to start hub: ${msg}`
934
- }]
957
+ content: [{ type: "text", text: `Failed to start hub: ${msg}` }]
935
958
  };
936
959
  }
937
960
  try {
@@ -939,22 +962,17 @@ function registerStartHubTool(server, client, hubManager) {
939
962
  } catch (err) {
940
963
  const msg = err instanceof Error ? err.message : String(err);
941
964
  return {
942
- content: [{
943
- type: "text",
944
- text: `Hub started on port ${port}, but failed to self-connect: ${msg}`
945
- }]
965
+ content: [{ type: "text", text: `Hub started on port ${port}, but failed to self-connect: ${msg}` }]
946
966
  };
947
967
  }
968
+ const lines = [
969
+ `Hub started on port ${port}.`,
970
+ firewallAdded ? `Firewall rule added (claude-collab-${port}) \u2014 LAN peers can connect.` : `WARNING: Firewall rule could not be added (UAC was cancelled or denied). Peers on other machines may be blocked by Windows Firewall. Run start_hub again and accept the UAC prompt to fix this.`,
971
+ `Others on the LAN will auto-discover and connect via mDNS.`,
972
+ `Use stop_hub when you are done.`
973
+ ];
948
974
  return {
949
- content: [{
950
- type: "text",
951
- text: [
952
- `Hub started on port ${port}.`,
953
- `Firewall rule added (claude-collab-${port}).`,
954
- `Others on the LAN will auto-discover and connect \u2014 no IP sharing needed.`,
955
- `Use stop_hub when you are done to close the hub and remove the firewall rule.`
956
- ].join("\n")
957
- }]
975
+ content: [{ type: "text", text: lines.join("\n") }]
958
976
  };
959
977
  }
960
978
  );
@@ -976,26 +994,23 @@ function registerStopHubTool(server, hubManager) {
976
994
  };
977
995
  }
978
996
  const port = hubManager.port;
997
+ let firewallRemoved = false;
979
998
  try {
980
- await hubManager.stop();
999
+ const result = await hubManager.stop();
1000
+ firewallRemoved = result.firewallRemoved;
981
1001
  } catch (err) {
982
1002
  const msg = err instanceof Error ? err.message : String(err);
983
1003
  return {
984
- content: [{
985
- type: "text",
986
- text: `Failed to stop hub: ${msg}`
987
- }]
1004
+ content: [{ type: "text", text: `Failed to stop hub: ${msg}` }]
988
1005
  };
989
1006
  }
1007
+ const lines = [
1008
+ `Hub stopped (was on port ${port}).`,
1009
+ firewallRemoved ? `Firewall rule removed (claude-collab-${port}).` : `WARNING: Firewall rule could not be removed (UAC was cancelled). Remove it manually: netsh advfirewall firewall delete rule name="claude-collab-${port}"`,
1010
+ `All peers have been disconnected.`
1011
+ ];
990
1012
  return {
991
- content: [{
992
- type: "text",
993
- text: [
994
- `Hub stopped (was on port ${port}).`,
995
- `Firewall rule removed (claude-collab-${port}).`,
996
- `All peers have been disconnected.`
997
- ].join("\n")
998
- }]
1013
+ content: [{ type: "text", text: lines.join("\n") }]
999
1014
  };
1000
1015
  }
1001
1016
  );
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/infrastructure/hub/hub-protocol.ts","../src/infrastructure/hub/hub-server.ts","../src/infrastructure/terminal-injector/windows-injector.ts","../src/infrastructure/terminal-injector/index.ts","../src/infrastructure/terminal-injector/injection-queue.ts","../src/infrastructure/hub/hub-client.ts","../src/infrastructure/mdns/mdns-advertiser.ts","../src/infrastructure/hub/hub-manager.ts","../src/presentation/mcp/tools/ask.tool.ts","../src/presentation/mcp/tools/reply.tool.ts","../src/presentation/mcp/tools/peers.tool.ts","../src/presentation/mcp/tools/history.tool.ts","../src/presentation/mcp/tools/start-hub.tool.ts","../src/presentation/mcp/tools/stop-hub.tool.ts","../src/presentation/mcp/server.ts","../src/infrastructure/mdns/mdns-discovery.ts","../src/cli.ts"],"names":["WebSocket","uuidv4","z","SERVICE_TYPE","Bonjour"],"mappings":"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","file":"cli.js","sourcesContent":["/**\r\n * Hub Wire Protocol\r\n * Messages exchanged between hub server and clients.\r\n * @module infrastructure/hub/hub-protocol\r\n */\r\n\r\nimport type { MessageFormat } from '../../domain/value-objects/message-content.vo.js';\r\n\r\n// Client → Hub: identify yourself\r\nexport interface HelloMsg {\r\n type: 'HELLO';\r\n name: string;\r\n}\r\n\r\n// Hub → Client: welcome + current peer list\r\nexport interface HelloAckMsg {\r\n type: 'HELLO_ACK';\r\n peers: string[];\r\n}\r\n\r\n// Hub → Client: broadcast when someone joins\r\nexport interface PeerJoinedMsg {\r\n type: 'PEER_JOINED';\r\n name: string;\r\n}\r\n\r\n// Hub → Client: broadcast when someone leaves\r\nexport interface PeerLeftMsg {\r\n type: 'PEER_LEFT';\r\n name: string;\r\n}\r\n\r\n// Client → Hub: ask a question (hub routes to `to`)\r\nexport interface AskMsg {\r\n type: 'ASK';\r\n from: string;\r\n to: string;\r\n questionId: string;\r\n requestId: string;\r\n content: string;\r\n format: MessageFormat;\r\n}\r\n\r\n// Hub → Client: question delivered acknowledgement\r\nexport interface AskAckMsg {\r\n type: 'ASK_ACK';\r\n questionId: string;\r\n requestId: string;\r\n}\r\n\r\n// Client → Hub: poll for answer (hub routes to `to`)\r\nexport interface GetAnswerMsg {\r\n type: 'GET_ANSWER';\r\n from: string;\r\n to: string;\r\n questionId: string;\r\n requestId: string;\r\n}\r\n\r\n// Client → Hub: deliver answer (hub routes to `to`)\r\nexport interface AnswerMsg {\r\n type: 'ANSWER';\r\n from: string;\r\n to: string;\r\n questionId: string;\r\n content: string;\r\n format: MessageFormat;\r\n answeredAt: string;\r\n requestId?: string;\r\n}\r\n\r\n// Client → Hub: answer not ready yet (hub routes to `to`)\r\nexport interface AnswerPendingMsg {\r\n type: 'ANSWER_PENDING';\r\n to: string;\r\n questionId: string;\r\n requestId: string;\r\n}\r\n\r\n// Hub → Client: error\r\nexport interface HubErrorMsg {\r\n type: 'HUB_ERROR';\r\n code: string;\r\n message: string;\r\n}\r\n\r\nexport type HubMsg =\r\n | HelloMsg\r\n | HelloAckMsg\r\n | PeerJoinedMsg\r\n | PeerLeftMsg\r\n | AskMsg\r\n | AskAckMsg\r\n | GetAnswerMsg\r\n | AnswerMsg\r\n | AnswerPendingMsg\r\n | HubErrorMsg;\r\n\r\nexport function serialize(msg: HubMsg): string {\r\n return JSON.stringify(msg);\r\n}\r\n\r\nexport function parse(data: string): HubMsg {\r\n return JSON.parse(data) as HubMsg;\r\n}\r\n","/**\r\n * HubServer\r\n * Central WebSocket server that routes messages between clients by name.\r\n * One instance runs per team — everyone else connects to it outbound.\r\n * @module infrastructure/hub/hub-server\r\n */\r\n\r\nimport { WebSocketServer, WebSocket } from 'ws';\r\nimport {\r\n type HubMsg,\r\n type HelloAckMsg,\r\n type AskAckMsg,\r\n type HubErrorMsg,\r\n parse,\r\n serialize,\r\n} from './hub-protocol.js';\r\n\r\nexport class HubServer {\r\n private wss: WebSocketServer | null = null;\r\n private readonly clients = new Map<string, WebSocket>(); // name → ws\r\n private readonly wsToName = new Map<WebSocket, string>(); // ws → name\r\n\r\n start(port: number): void {\r\n this.wss = new WebSocketServer({ port });\r\n\r\n this.wss.on('listening', () => {\r\n console.log(`claude-collab hub running on port ${port}`);\r\n console.log('Waiting for peers...\\n');\r\n });\r\n\r\n this.wss.on('connection', (ws) => {\r\n ws.on('message', (data) => {\r\n try {\r\n const msg = parse(data.toString());\r\n this.handleMessage(ws, msg);\r\n } catch {\r\n // ignore malformed messages\r\n }\r\n });\r\n\r\n ws.on('close', () => {\r\n const name = this.wsToName.get(ws);\r\n if (name) {\r\n this.clients.delete(name);\r\n this.wsToName.delete(ws);\r\n this.broadcast({ type: 'PEER_LEFT', name });\r\n console.log(`← ${name} left (${this.clients.size} online: ${[...this.clients.keys()].join(', ') || 'none'})`);\r\n }\r\n });\r\n\r\n ws.on('error', (err) => {\r\n console.error('[hub] ws error:', err.message);\r\n });\r\n });\r\n\r\n this.wss.on('error', (err) => {\r\n console.error('[hub] server error:', err.message);\r\n });\r\n }\r\n\r\n stop(): void {\r\n if (!this.wss) return;\r\n for (const ws of this.clients.values()) ws.terminate();\r\n this.clients.clear();\r\n this.wsToName.clear();\r\n this.wss.close();\r\n this.wss = null;\r\n console.log('claude-collab hub stopped');\r\n }\r\n\r\n private handleMessage(ws: WebSocket, msg: HubMsg): void {\r\n switch (msg.type) {\r\n case 'HELLO': {\r\n const existing = this.clients.get(msg.name);\r\n const isReconnect = existing != null && existing !== ws;\r\n\r\n if (isReconnect) {\r\n // Remove from tracking BEFORE closing so the close event won't broadcast PEER_LEFT\r\n this.wsToName.delete(existing!);\r\n existing!.close();\r\n }\r\n\r\n this.clients.set(msg.name, ws);\r\n this.wsToName.set(ws, msg.name);\r\n\r\n const peers = [...this.clients.keys()].filter((n) => n !== msg.name);\r\n const ack: HelloAckMsg = { type: 'HELLO_ACK', peers };\r\n this.send(ws, ack);\r\n\r\n if (!isReconnect) {\r\n this.broadcast({ type: 'PEER_JOINED', name: msg.name }, ws);\r\n }\r\n\r\n console.log(`→ ${msg.name} joined (${this.clients.size} online: ${[...this.clients.keys()].join(', ')})`);\r\n break;\r\n }\r\n\r\n case 'ASK': {\r\n const target = this.clients.get(msg.to);\r\n if (!target) {\r\n const err: HubErrorMsg = {\r\n type: 'HUB_ERROR',\r\n code: 'PEER_NOT_FOUND',\r\n message: `'${msg.to}' is not connected to the hub`,\r\n };\r\n this.send(ws, err);\r\n return;\r\n }\r\n this.send(target, msg);\r\n const ack: AskAckMsg = { type: 'ASK_ACK', questionId: msg.questionId, requestId: msg.requestId };\r\n this.send(ws, ack);\r\n break;\r\n }\r\n\r\n case 'GET_ANSWER': {\r\n const target = this.clients.get(msg.to);\r\n if (!target) {\r\n this.send(ws, { type: 'ANSWER_PENDING', to: msg.from, questionId: msg.questionId, requestId: msg.requestId });\r\n return;\r\n }\r\n this.send(target, msg);\r\n break;\r\n }\r\n\r\n case 'ANSWER':\r\n case 'ANSWER_PENDING': {\r\n const target = this.clients.get(msg.to);\r\n if (target) this.send(target, msg);\r\n break;\r\n }\r\n\r\n // HELLO_ACK, ASK_ACK, PEER_JOINED, PEER_LEFT, HUB_ERROR are hub→client only — ignore if received\r\n }\r\n }\r\n\r\n private send(ws: WebSocket, msg: HubMsg): void {\r\n if (ws.readyState === WebSocket.OPEN) {\r\n ws.send(serialize(msg));\r\n }\r\n }\r\n\r\n private broadcast(msg: HubMsg, except?: WebSocket): void {\r\n for (const ws of this.clients.values()) {\r\n if (ws !== except) this.send(ws, msg);\r\n }\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 * HubClient\r\n * Connects outbound to a hub server and implements ICollabClient.\r\n * No local WebSocket server — no inbound port needed.\r\n * @module infrastructure/hub/hub-client\r\n */\r\n\r\nimport { WebSocket } from 'ws';\r\nimport { v4 as uuidv4 } from 'uuid';\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 '../../domain/value-objects/message-content.vo.js';\r\nimport {\r\n type HubMsg,\r\n type HelloAckMsg,\r\n type AskAckMsg,\r\n type AskMsg,\r\n type AnswerMsg,\r\n type AnswerPendingMsg,\r\n type GetAnswerMsg,\r\n parse,\r\n serialize,\r\n} from './hub-protocol.js';\r\nimport { injectionQueue } from '../terminal-injector/injection-queue.js';\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 HubClient implements ICollabClient {\r\n private ws: WebSocket | null = null;\r\n private myName = '';\r\n private serverUrl = '';\r\n private reconnectTimer: NodeJS.Timeout | null = null;\r\n\r\n private readonly connectedPeers = new Set<string>();\r\n private readonly incomingQuestions = new Map<string, IncomingQuestion>();\r\n private readonly receivedAnswers = new Map<string, ReceivedAnswer>();\r\n private readonly questionToName = new Map<string, string>();\r\n private readonly questionToSender = new Map<string, string>();\r\n private readonly sentQuestions = new Map<string, { toPeer: string; content: string; askedAt: string }>();\r\n private readonly pendingHandlers = new Set<(msg: HubMsg) => void>();\r\n\r\n setServerUrl(url: string): void {\r\n this.serverUrl = url;\r\n }\r\n\r\n get isConnected(): boolean {\r\n return this.ws?.readyState === WebSocket.OPEN;\r\n }\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 // Only connect immediately if a server URL was already set.\r\n // If not (e.g. auto-discover mode), connection happens later via connectToHub().\r\n if (this.serverUrl) {\r\n await this.connectAndHello();\r\n }\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: 0,\r\n };\r\n }\r\n\r\n async connectToHub(url: string): Promise<void> {\r\n this.serverUrl = url;\r\n await this.connectAndHello();\r\n }\r\n\r\n async ask(toPeer: string, content: string, format: MessageFormat): Promise<string> {\r\n const questionId = uuidv4();\r\n const requestId = uuidv4();\r\n\r\n this.questionToName.set(questionId, toPeer);\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.requestId === requestId,\r\n 5000\r\n );\r\n\r\n this.sendToHub({ type: 'ASK', from: this.myName, to: toPeer, questionId, requestId, content, format });\r\n\r\n await ackPromise;\r\n return questionId;\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) {\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 const toPeer = this.questionToName.get(questionId);\r\n if (!toPeer || !this.isConnected) return null;\r\n\r\n const requestId = uuidv4();\r\n const responsePromise = this.waitForResponse<AnswerMsg | AnswerPendingMsg>(\r\n (m) =>\r\n (m.type === 'ANSWER' && m.questionId === questionId) ||\r\n (m.type === 'ANSWER_PENDING' && m.requestId === requestId),\r\n 5000\r\n );\r\n\r\n this.sendToHub({ type: 'GET_ANSWER', from: this.myName, to: toPeer, questionId, requestId });\r\n\r\n const response = await responsePromise;\r\n if (response.type === 'ANSWER_PENDING') return null;\r\n\r\n const answer = response as AnswerMsg;\r\n this.receivedAnswers.set(questionId, {\r\n content: answer.content,\r\n format: answer.format,\r\n answeredAt: answer.answeredAt,\r\n fromName: answer.from,\r\n });\r\n\r\n return {\r\n questionId,\r\n from: { displayName: `${answer.from} Claude`, teamName: answer.from },\r\n content: answer.content,\r\n format: answer.format,\r\n answeredAt: answer.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 this.sendToHub({\r\n type: 'ANSWER',\r\n from: this.myName,\r\n to: senderName,\r\n questionId,\r\n content,\r\n format,\r\n answeredAt: new Date().toISOString(),\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\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: undefined,\r\n connectedPeers: [...this.connectedPeers],\r\n };\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 answer: answer?.content,\r\n askedAt: sent.askedAt,\r\n answeredAt: answer?.answeredAt,\r\n });\r\n }\r\n\r\n for (const [questionId, incoming] of this.incomingQuestions) {\r\n entries.push({\r\n direction: 'received',\r\n questionId,\r\n peer: incoming.fromName,\r\n question: incoming.content,\r\n answer: incoming.answered ? incoming.answerContent : undefined,\r\n askedAt: incoming.createdAt.toISOString(),\r\n answeredAt: incoming.answered ? new Date().toISOString() : undefined,\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 if (this.reconnectTimer) {\r\n clearTimeout(this.reconnectTimer);\r\n this.reconnectTimer = null;\r\n }\r\n this.ws?.close();\r\n this.ws = null;\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Private: connection management\r\n // ---------------------------------------------------------------------------\r\n\r\n private async connectAndHello(): Promise<void> {\r\n const ws = new WebSocket(this.serverUrl);\r\n this.ws = ws;\r\n\r\n ws.on('message', (data) => {\r\n try {\r\n const msg = parse(data.toString());\r\n this.handleMessage(msg);\r\n } catch {\r\n // ignore malformed messages\r\n }\r\n });\r\n\r\n ws.on('close', () => {\r\n this.connectedPeers.clear();\r\n this.scheduleReconnect();\r\n });\r\n\r\n ws.on('error', (err) => {\r\n console.error('[hub-client] error:', err.message);\r\n });\r\n\r\n await new Promise<void>((resolve, reject) => {\r\n const timeout = setTimeout(\r\n () => reject(new Error(`Cannot connect to hub at ${this.serverUrl}`)),\r\n 10000\r\n );\r\n ws.on('open', () => {\r\n clearTimeout(timeout);\r\n ws.send(serialize({ type: 'HELLO', name: this.myName }));\r\n resolve();\r\n });\r\n ws.on('error', (err) => {\r\n clearTimeout(timeout);\r\n reject(err);\r\n });\r\n });\r\n\r\n const ack = await this.waitForResponse<HelloAckMsg>(\r\n (m) => m.type === 'HELLO_ACK',\r\n 10000\r\n );\r\n\r\n for (const peer of ack.peers) this.connectedPeers.add(peer);\r\n console.error(`[hub-client] connected as \"${this.myName}\", peers: [${ack.peers.join(', ')}]`);\r\n }\r\n\r\n private scheduleReconnect(): void {\r\n if (this.reconnectTimer) return;\r\n this.reconnectTimer = setTimeout(async () => {\r\n this.reconnectTimer = null;\r\n try {\r\n await this.connectAndHello();\r\n console.error('[hub-client] reconnected to hub');\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n console.error(`[hub-client] reconnect failed: ${msg}, retrying in 5s...`);\r\n this.scheduleReconnect();\r\n }\r\n }, 5000);\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Private: message handling\r\n // ---------------------------------------------------------------------------\r\n\r\n private handleMessage(msg: HubMsg): void {\r\n for (const handler of this.pendingHandlers) handler(msg);\r\n\r\n switch (msg.type) {\r\n case 'PEER_JOINED':\r\n this.connectedPeers.add(msg.name);\r\n console.error(`[hub-client] peer joined: ${msg.name}`);\r\n break;\r\n\r\n case 'PEER_LEFT':\r\n this.connectedPeers.delete(msg.name);\r\n console.error(`[hub-client] peer left: ${msg.name}`);\r\n break;\r\n\r\n case 'ASK':\r\n this.handleIncomingAsk(msg);\r\n break;\r\n\r\n case 'GET_ANSWER':\r\n this.handleGetAnswer(msg);\r\n break;\r\n\r\n case 'ANSWER':\r\n if (!this.receivedAnswers.has(msg.questionId)) {\r\n this.receivedAnswers.set(msg.questionId, {\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 break;\r\n\r\n case 'HUB_ERROR':\r\n console.error(`[hub-client] hub error: ${msg.message}`);\r\n break;\r\n }\r\n }\r\n\r\n private handleIncomingAsk(msg: AskMsg): void {\r\n this.questionToSender.set(msg.questionId, msg.from);\r\n\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 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 handleGetAnswer(msg: GetAnswerMsg): void {\r\n const question = this.incomingQuestions.get(msg.questionId);\r\n\r\n if (!question?.answered) {\r\n this.sendToHub({\r\n type: 'ANSWER_PENDING',\r\n to: msg.from,\r\n questionId: msg.questionId,\r\n requestId: msg.requestId,\r\n });\r\n return;\r\n }\r\n\r\n this.sendToHub({\r\n type: 'ANSWER',\r\n from: this.myName,\r\n to: msg.from,\r\n questionId: msg.questionId,\r\n content: question.answerContent!,\r\n format: question.answerFormat!,\r\n answeredAt: new Date().toISOString(),\r\n requestId: msg.requestId,\r\n });\r\n }\r\n\r\n private sendToHub(msg: HubMsg): void {\r\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\r\n throw new Error('Not connected to hub. Will retry automatically.');\r\n }\r\n this.ws.send(serialize(msg));\r\n }\r\n\r\n private waitForResponse<T extends HubMsg>(\r\n filter: (msg: HubMsg) => 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('Hub request timed out'));\r\n }, timeoutMs);\r\n\r\n const handler = (msg: HubMsg): 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 * MdnsAdvertiser\r\n * Broadcasts the hub's presence on the LAN via mDNS so clients can auto-discover it.\r\n * @module infrastructure/mdns/mdns-advertiser\r\n */\r\n\r\nimport { Bonjour } from 'bonjour-service';\r\n\r\nconst SERVICE_TYPE = 'claude-collab';\r\n\r\nexport class MdnsAdvertiser {\r\n private bonjour: Bonjour | null = null;\r\n\r\n start(port: number): void {\r\n this.bonjour = new Bonjour();\r\n this.bonjour.publish({ name: 'claude-collab-hub', type: SERVICE_TYPE, port });\r\n console.error(`[mdns] advertising hub on port ${port}`);\r\n }\r\n\r\n stop(): void {\r\n if (!this.bonjour) return;\r\n this.bonjour.unpublishAll(() => {\r\n this.bonjour?.destroy();\r\n });\r\n this.bonjour = null;\r\n console.error('[mdns] stopped advertising');\r\n }\r\n}\r\n","/**\r\n * HubManager\r\n * Orchestrates hub lifecycle: starts/stops HubServer, manages Windows firewall rules\r\n * via UAC elevation, and controls mDNS advertising.\r\n * @module infrastructure/hub/hub-manager\r\n */\r\n\r\nimport { spawn } from 'child_process';\r\nimport { HubServer } from './hub-server.js';\r\nimport { MdnsAdvertiser } from '../mdns/mdns-advertiser.js';\r\n\r\nexport class HubManager {\r\n private hubServer: HubServer | null = null;\r\n private advertiser: MdnsAdvertiser | null = null;\r\n private currentPort: number | null = null;\r\n\r\n get isRunning(): boolean {\r\n return this.hubServer !== null;\r\n }\r\n\r\n get port(): number | null {\r\n return this.currentPort;\r\n }\r\n\r\n async start(port: number): Promise<void> {\r\n if (this.isRunning) throw new Error('Hub is already running');\r\n\r\n const server = new HubServer();\r\n server.start(port);\r\n this.hubServer = server;\r\n this.currentPort = port;\r\n\r\n // Add firewall rule (UAC prompt shown to user — one click)\r\n await addFirewallRule(port);\r\n\r\n // Advertise on LAN via mDNS\r\n const advertiser = new MdnsAdvertiser();\r\n advertiser.start(port);\r\n this.advertiser = advertiser;\r\n }\r\n\r\n async stop(): Promise<void> {\r\n if (!this.isRunning) throw new Error('Hub is not running');\r\n\r\n if (this.advertiser) {\r\n this.advertiser.stop();\r\n this.advertiser = null;\r\n }\r\n\r\n const port = this.currentPort!;\r\n this.hubServer!.stop();\r\n this.hubServer = null;\r\n this.currentPort = null;\r\n\r\n // Remove firewall rule (UAC prompt shown to user — one click)\r\n await removeFirewallRule(port);\r\n }\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Firewall helpers — elevated via UAC (PowerShell Start-Process -Verb RunAs)\r\n// ---------------------------------------------------------------------------\r\n\r\nfunction runElevated(netshArgs: string): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n // PowerShell spawns a new admin cmd process via UAC and waits for it to exit.\r\n const ps = spawn('powershell', [\r\n '-NoProfile',\r\n '-Command',\r\n `Start-Process -FilePath \"netsh\" -ArgumentList \"${netshArgs}\" -Verb RunAs -Wait`,\r\n ]);\r\n\r\n ps.on('close', (code) => {\r\n if (code === 0) resolve();\r\n else reject(new Error(`Firewall command failed (exit code ${code}). User may have cancelled the UAC prompt.`));\r\n });\r\n\r\n ps.on('error', (err) => {\r\n reject(new Error(`Failed to launch PowerShell for firewall elevation: ${err.message}`));\r\n });\r\n });\r\n}\r\n\r\nasync function addFirewallRule(port: number): Promise<void> {\r\n await runElevated(\r\n `advfirewall firewall add rule name=\"claude-collab-${port}\" protocol=TCP dir=in localport=${port} action=allow`\r\n );\r\n}\r\n\r\nasync function removeFirewallRule(port: number): Promise<void> {\r\n await runElevated(\r\n `advfirewall firewall delete rule name=\"claude-collab-${port}\"`\r\n );\r\n}\r\n","/**\r\n * Ask Tool\r\n * Sends a question to another team and returns a question ID immediately.\r\n * Use the \"check_answer\" tool with the question ID to retrieve the answer later.\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\n/**\r\n * Ask tool input schema\r\n */\r\nconst askSchema = {\r\n peer: z.string().describe('Name of the peer to ask (e.g., \"alice\", \"backend\")'),\r\n question: z.string().describe('The question to ask (supports markdown)'),\r\n};\r\n\r\n/**\r\n * Registers the ask tool with the MCP server\r\n */\r\nexport function registerAskTool(server: McpServer, client: ICollabClient): void {\r\n server.tool('ask', 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 {\r\n type: 'text',\r\n text: 'Node is not ready yet. Wait a moment and try again.',\r\n },\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 // Poll until answer arrives (max 5 minutes, every 5 seconds)\r\n const POLL_INTERVAL_MS = 5_000;\r\n const MAX_WAIT_MS = 5 * 60 * 1000;\r\n const deadline = Date.now() + MAX_WAIT_MS;\r\n\r\n while (Date.now() < deadline) {\r\n await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));\r\n const answer = await client.checkAnswer(questionId);\r\n if (answer !== null) {\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: `**${answer.from.displayName} (${answer.from.teamName}) cevapladı:**\\n\\n${answer.content}`,\r\n },\r\n ],\r\n };\r\n }\r\n }\r\n\r\n // Timed out — return question ID for manual follow-up\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: `Soru gönderildi ancak 5 dakika içinde cevap gelmedi.\\nQuestion ID: \\`${questionId}\\`\\n\\nManuel kontrol için \"check_answer\" tool'unu kullanabilirsin.`,\r\n },\r\n ],\r\n };\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: `Failed to send question: ${errorMessage}`,\r\n },\r\n ],\r\n isError: true,\r\n };\r\n }\r\n });\r\n}\r\n","/**\r\n * Reply Tool\r\n * Replies to a pending question\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\n/**\r\n * Reply tool input schema\r\n */\r\nconst replySchema = {\r\n questionId: z.string().describe('The ID of the question to reply to (from inbox)'),\r\n answer: z.string().describe('Your answer to the question (supports markdown)'),\r\n};\r\n\r\n/**\r\n * Registers the reply tool with the MCP server\r\n */\r\nexport function registerReplyTool(server: McpServer, client: ICollabClient): void {\r\n server.tool('reply', 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 {\r\n type: 'text',\r\n text: 'You must join a team first. Use the \"join\" tool to join a team.',\r\n },\r\n ],\r\n isError: true,\r\n };\r\n }\r\n\r\n await client.reply(questionId, answer, 'markdown');\r\n\r\n // Signal queue: this question is done, process next\r\n injectionQueue.notifyReplied();\r\n\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: `Reply sent successfully to question \\`${questionId}\\`.`,\r\n },\r\n ],\r\n };\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: `Failed to send reply: ${errorMessage}`,\r\n },\r\n ],\r\n isError: true,\r\n };\r\n }\r\n });\r\n}\r\n","/**\r\n * Peers Tool\r\n * Lists currently connected peers on the collaboration network.\r\n * @module presentation/mcp/tools/peers\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\nexport function registerPeersTool(server: McpServer, client: ICollabClient): void {\r\n server.tool('peers', {}, async () => {\r\n const info = client.getInfo();\r\n const myName = info.teamName ?? '(starting...)';\r\n const connected = info.connectedPeers;\r\n\r\n if (connected.length === 0) {\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `You are \"${myName}\". No peers connected yet — they will appear automatically when they come online.`,\r\n }],\r\n };\r\n }\r\n\r\n const list = connected.map((name) => ` • ${name}`).join('\\n');\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `You are \"${myName}\". Connected peers (${connected.length}):\\n${list}`,\r\n }],\r\n };\r\n });\r\n}\r\n","/**\r\n * History Tool\r\n * Shows past questions and answers from this session.\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\nexport function registerHistoryTool(server: McpServer, client: ICollabClient): void {\r\n server.tool('history', {}, 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 yet this session.' }],\r\n };\r\n }\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)`;\r\n return `[${time}] ← ${e.peer}: ${e.question}\\n${answerLine}`;\r\n }\r\n });\r\n\r\n return {\r\n content: [{ type: 'text', text: lines.join('\\n\\n') }],\r\n };\r\n });\r\n}\r\n","/**\r\n * StartHub Tool\r\n * Starts a hub server on this machine, opens a Windows firewall rule via UAC,\r\n * and advertises the hub on the LAN via mDNS so peers auto-discover it.\r\n * @module presentation/mcp/tools/start-hub\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 type { HubManager } from '../../../infrastructure/hub/hub-manager.js';\r\n\r\nexport function registerStartHubTool(\r\n server: McpServer,\r\n client: ICollabClient,\r\n hubManager: HubManager\r\n): void {\r\n server.tool(\r\n 'start_hub',\r\n 'Start a hub server on this machine. Opens a firewall rule (UAC prompt) and advertises on LAN via mDNS — peers connect automatically, no IP sharing needed.',\r\n { port: z.number().min(1024).max(65535).optional().describe('Port to listen on (default: 9999)') },\r\n async ({ port = 9999 }) => {\r\n if (hubManager.isRunning) {\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Hub is already running on port ${hubManager.port}.`,\r\n }],\r\n };\r\n }\r\n\r\n try {\r\n await hubManager.start(port);\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: `Failed to start hub: ${msg}`,\r\n }],\r\n };\r\n }\r\n\r\n // Connect this instance to the local hub so it can use all tools\r\n try {\r\n await client.connectToHub(`ws://localhost:${port}`);\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: `Hub started on port ${port}, but failed to self-connect: ${msg}`,\r\n }],\r\n };\r\n }\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: [\r\n `Hub started on port ${port}.`,\r\n `Firewall rule added (claude-collab-${port}).`,\r\n `Others on the LAN will auto-discover and connect — no IP sharing needed.`,\r\n `Use stop_hub when you are done to close the hub and remove the firewall rule.`,\r\n ].join('\\n'),\r\n }],\r\n };\r\n }\r\n );\r\n}\r\n","/**\r\n * StopHub Tool\r\n * Stops the running hub server, removes the Windows firewall rule via UAC,\r\n * and ceases mDNS advertising.\r\n * @module presentation/mcp/tools/stop-hub\r\n */\r\n\r\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\r\nimport type { HubManager } from '../../../infrastructure/hub/hub-manager.js';\r\n\r\nexport function registerStopHubTool(server: McpServer, hubManager: HubManager): void {\r\n server.tool(\r\n 'stop_hub',\r\n 'Stop the running hub server. Removes the firewall rule (UAC prompt) and stops LAN advertising. Connected peers will be disconnected.',\r\n {},\r\n async () => {\r\n if (!hubManager.isRunning) {\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: 'No hub is currently running on this machine.',\r\n }],\r\n };\r\n }\r\n\r\n const port = hubManager.port;\r\n\r\n try {\r\n await hubManager.stop();\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: `Failed to stop hub: ${msg}`,\r\n }],\r\n };\r\n }\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: [\r\n `Hub stopped (was on port ${port}).`,\r\n `Firewall rule removed (claude-collab-${port}).`,\r\n `All peers have been disconnected.`,\r\n ].join('\\n'),\r\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 type { HubManager } from '../../infrastructure/hub/hub-manager.js';\r\nimport { registerAskTool } from './tools/ask.tool.js';\r\nimport { registerReplyTool } from './tools/reply.tool.js';\r\nimport { registerPeersTool } from './tools/peers.tool.js';\r\nimport { registerHistoryTool } from './tools/history.tool.js';\r\nimport { registerStartHubTool } from './tools/start-hub.tool.js';\r\nimport { registerStopHubTool } from './tools/stop-hub.tool.js';\r\n\r\nexport interface McpServerOptions {\r\n client: ICollabClient;\r\n hubManager: HubManager;\r\n}\r\n\r\nexport function createMcpServer(options: McpServerOptions): McpServer {\r\n const { client, hubManager } = 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 registerAskTool(server, client);\r\n registerReplyTool(server, client);\r\n registerPeersTool(server, client);\r\n registerHistoryTool(server, client);\r\n registerStartHubTool(server, client, hubManager);\r\n registerStopHubTool(server, hubManager);\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","/**\r\n * MdnsDiscovery\r\n * Discovers a claude-collab hub on the LAN via mDNS.\r\n * @module infrastructure/mdns/mdns-discovery\r\n */\r\n\r\nimport { Bonjour } from 'bonjour-service';\r\n\r\nconst SERVICE_TYPE = 'claude-collab';\r\n\r\nexport interface DiscoveredHub {\r\n host: string;\r\n port: number;\r\n}\r\n\r\n/**\r\n * One-shot discovery: resolves with hub info if found within timeoutMs, otherwise null.\r\n */\r\nexport function discoverHub(timeoutMs = 5000): Promise<DiscoveredHub | null> {\r\n return new Promise((resolve) => {\r\n const bonjour = new Bonjour();\r\n const browser = bonjour.find({ type: SERVICE_TYPE });\r\n\r\n let settled = false;\r\n\r\n const finish = (result: DiscoveredHub | null) => {\r\n if (settled) return;\r\n settled = true;\r\n clearTimeout(timer);\r\n browser.stop();\r\n bonjour.destroy();\r\n resolve(result);\r\n };\r\n\r\n const timer = setTimeout(() => finish(null), timeoutMs);\r\n\r\n browser.on('up', (svc) => {\r\n finish({ host: svc.host, port: svc.port });\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * Continuous watcher: calls onFound whenever a hub appears on the LAN.\r\n * Returns a stop function — call it to cancel watching.\r\n */\r\nexport function watchForHub(onFound: (hub: DiscoveredHub) => void): () => void {\r\n const bonjour = new Bonjour();\r\n const browser = bonjour.find({ type: SERVICE_TYPE });\r\n\r\n browser.on('up', (svc) => {\r\n onFound({ host: svc.host, port: svc.port });\r\n });\r\n\r\n return () => {\r\n browser.stop();\r\n bonjour.destroy();\r\n };\r\n}\r\n","#!/usr/bin/env node\r\n\r\n/**\r\n * CLI entry point\r\n *\r\n * Hub mode: claude-collab --hub [--port 9999]\r\n * Client mode: claude-collab --name alice --server 192.168.1.5:9999\r\n *\r\n * @module cli\r\n */\r\n\r\nimport { Command } from 'commander';\r\nimport { HubServer } from './infrastructure/hub/hub-server.js';\r\nimport { HubClient } from './infrastructure/hub/hub-client.js';\r\nimport { HubManager } from './infrastructure/hub/hub-manager.js';\r\nimport { startMcpServer } from './presentation/mcp/server.js';\r\nimport { discoverHub, watchForHub } from './infrastructure/mdns/mdns-discovery.js';\r\n\r\nconst program = new Command();\r\n\r\nprogram\r\n .name('claude-collab')\r\n .description('P2P collaboration between Claude Code terminals via a shared hub')\r\n .version('0.1.0')\r\n .option('--hub', 'Run as hub server (one machine per team)')\r\n .option('--port <port>', 'Hub server port (hub mode, default: 9999)', '9999')\r\n .option('--name <name>', 'Your name on the network (client mode, e.g. \"alice\")')\r\n .option('--server <address>', 'Hub address to connect to (client mode, e.g. \"192.168.1.5:9999\")')\r\n .action(async (options: { hub?: boolean; port: string; name?: string; server?: string }) => {\r\n if (options.hub) {\r\n // --- Hub mode ---\r\n const port = parseInt(options.port, 10);\r\n if (isNaN(port)) {\r\n console.error(`Invalid port: ${options.port}`);\r\n process.exit(1);\r\n }\r\n const hub = new HubServer();\r\n hub.start(port);\r\n // Keep the process alive\r\n process.on('SIGINT', () => {\r\n console.log('\\nHub stopped.');\r\n process.exit(0);\r\n });\r\n } else {\r\n // --- Client / MCP mode ---\r\n if (!options.name) {\r\n console.error('--name is required');\r\n process.exit(1);\r\n }\r\n\r\n const client = new HubClient();\r\n const hubManager = new HubManager();\r\n\r\n if (options.server) {\r\n // Direct mode: connect to specified hub immediately\r\n const url = options.server.startsWith('ws') ? options.server : `ws://${options.server}`;\r\n client.setServerUrl(url);\r\n await client.join(options.name, options.name);\r\n } else {\r\n // Auto-discover mode: start MCP immediately, connect in background\r\n await client.join(options.name, options.name);\r\n }\r\n\r\n const mcpReady = startMcpServer({ client, hubManager });\r\n\r\n if (!options.server) {\r\n discoverHub(5000).then(async (hub) => {\r\n if (!hub || client.isConnected) return;\r\n try {\r\n await client.connectToHub(`ws://${hub.host}:${hub.port}`);\r\n } catch { /* background watcher will retry */ }\r\n });\r\n\r\n const stopWatch = watchForHub(async (hub) => {\r\n if (client.isConnected) { stopWatch(); return; }\r\n try {\r\n await client.connectToHub(`ws://${hub.host}:${hub.port}`);\r\n stopWatch();\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n console.error(`[cli] auto-connect failed: ${msg}`);\r\n }\r\n });\r\n }\r\n\r\n await mcpReady;\r\n }\r\n });\r\n\r\nprogram.parse();\r\n"]}
1
+ {"version":3,"sources":["../src/infrastructure/hub/hub-protocol.ts","../src/infrastructure/hub/hub-server.ts","../src/infrastructure/terminal-injector/windows-injector.ts","../src/infrastructure/terminal-injector/index.ts","../src/infrastructure/terminal-injector/injection-queue.ts","../src/infrastructure/hub/hub-client.ts","../src/infrastructure/mdns/mdns-advertiser.ts","../src/infrastructure/hub/hub-manager.ts","../src/presentation/mcp/tools/ask.tool.ts","../src/presentation/mcp/tools/reply.tool.ts","../src/presentation/mcp/tools/peers.tool.ts","../src/presentation/mcp/tools/history.tool.ts","../src/presentation/mcp/tools/start-hub.tool.ts","../src/presentation/mcp/tools/stop-hub.tool.ts","../src/presentation/mcp/server.ts","../src/infrastructure/mdns/mdns-discovery.ts","../src/cli.ts"],"names":["WebSocket","uuidv4","z","SERVICE_TYPE","Bonjour"],"mappings":"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","file":"cli.js","sourcesContent":["/**\r\n * Hub Wire Protocol\r\n * Messages exchanged between hub server and clients.\r\n * @module infrastructure/hub/hub-protocol\r\n */\r\n\r\nimport type { MessageFormat } from '../../domain/value-objects/message-content.vo.js';\r\n\r\n// Client → Hub: identify yourself\r\nexport interface HelloMsg {\r\n type: 'HELLO';\r\n name: string;\r\n}\r\n\r\n// Hub → Client: welcome + current peer list\r\nexport interface HelloAckMsg {\r\n type: 'HELLO_ACK';\r\n peers: string[];\r\n}\r\n\r\n// Hub → Client: broadcast when someone joins\r\nexport interface PeerJoinedMsg {\r\n type: 'PEER_JOINED';\r\n name: string;\r\n}\r\n\r\n// Hub → Client: broadcast when someone leaves\r\nexport interface PeerLeftMsg {\r\n type: 'PEER_LEFT';\r\n name: string;\r\n}\r\n\r\n// Client → Hub: ask a question (hub routes to `to`)\r\nexport interface AskMsg {\r\n type: 'ASK';\r\n from: string;\r\n to: string;\r\n questionId: string;\r\n requestId: string;\r\n content: string;\r\n format: MessageFormat;\r\n}\r\n\r\n// Hub → Client: question delivered acknowledgement\r\nexport interface AskAckMsg {\r\n type: 'ASK_ACK';\r\n questionId: string;\r\n requestId: string;\r\n}\r\n\r\n// Client → Hub: poll for answer (hub routes to `to`)\r\nexport interface GetAnswerMsg {\r\n type: 'GET_ANSWER';\r\n from: string;\r\n to: string;\r\n questionId: string;\r\n requestId: string;\r\n}\r\n\r\n// Client → Hub: deliver answer (hub routes to `to`)\r\nexport interface AnswerMsg {\r\n type: 'ANSWER';\r\n from: string;\r\n to: string;\r\n questionId: string;\r\n content: string;\r\n format: MessageFormat;\r\n answeredAt: string;\r\n requestId?: string;\r\n}\r\n\r\n// Client → Hub: answer not ready yet (hub routes to `to`)\r\nexport interface AnswerPendingMsg {\r\n type: 'ANSWER_PENDING';\r\n to: string;\r\n questionId: string;\r\n requestId: string;\r\n}\r\n\r\n// Hub → Client: error\r\nexport interface HubErrorMsg {\r\n type: 'HUB_ERROR';\r\n code: string;\r\n message: string;\r\n}\r\n\r\nexport type HubMsg =\r\n | HelloMsg\r\n | HelloAckMsg\r\n | PeerJoinedMsg\r\n | PeerLeftMsg\r\n | AskMsg\r\n | AskAckMsg\r\n | GetAnswerMsg\r\n | AnswerMsg\r\n | AnswerPendingMsg\r\n | HubErrorMsg;\r\n\r\nexport function serialize(msg: HubMsg): string {\r\n return JSON.stringify(msg);\r\n}\r\n\r\nexport function parse(data: string): HubMsg {\r\n return JSON.parse(data) as HubMsg;\r\n}\r\n","/**\r\n * HubServer\r\n * Central WebSocket server that routes messages between clients by name.\r\n * One instance runs per team — everyone else connects to it outbound.\r\n * @module infrastructure/hub/hub-server\r\n */\r\n\r\nimport { WebSocketServer, WebSocket } from 'ws';\r\nimport {\r\n type HubMsg,\r\n type HelloAckMsg,\r\n type AskAckMsg,\r\n type HubErrorMsg,\r\n parse,\r\n serialize,\r\n} from './hub-protocol.js';\r\n\r\nexport class HubServer {\r\n private wss: WebSocketServer | null = null;\r\n private readonly clients = new Map<string, WebSocket>(); // name → ws\r\n private readonly wsToName = new Map<WebSocket, string>(); // ws → name\r\n\r\n start(port: number): void {\r\n this.wss = new WebSocketServer({ port });\r\n\r\n this.wss.on('listening', () => {\r\n console.log(`claude-collab hub running on port ${port}`);\r\n console.log('Waiting for peers...\\n');\r\n });\r\n\r\n this.wss.on('connection', (ws) => {\r\n ws.on('message', (data) => {\r\n try {\r\n const msg = parse(data.toString());\r\n this.handleMessage(ws, msg);\r\n } catch {\r\n // ignore malformed messages\r\n }\r\n });\r\n\r\n ws.on('close', () => {\r\n const name = this.wsToName.get(ws);\r\n if (name) {\r\n this.clients.delete(name);\r\n this.wsToName.delete(ws);\r\n this.broadcast({ type: 'PEER_LEFT', name });\r\n console.log(`← ${name} left (${this.clients.size} online: ${[...this.clients.keys()].join(', ') || 'none'})`);\r\n }\r\n });\r\n\r\n ws.on('error', (err) => {\r\n console.error('[hub] ws error:', err.message);\r\n });\r\n });\r\n\r\n this.wss.on('error', (err) => {\r\n console.error('[hub] server error:', err.message);\r\n });\r\n }\r\n\r\n stop(): void {\r\n if (!this.wss) return;\r\n for (const ws of this.clients.values()) ws.terminate();\r\n this.clients.clear();\r\n this.wsToName.clear();\r\n this.wss.close();\r\n this.wss = null;\r\n console.log('claude-collab hub stopped');\r\n }\r\n\r\n private handleMessage(ws: WebSocket, msg: HubMsg): void {\r\n switch (msg.type) {\r\n case 'HELLO': {\r\n const existing = this.clients.get(msg.name);\r\n const isReconnect = existing != null && existing !== ws;\r\n\r\n if (isReconnect) {\r\n // Remove from tracking BEFORE closing so the close event won't broadcast PEER_LEFT\r\n this.wsToName.delete(existing!);\r\n existing!.close();\r\n }\r\n\r\n this.clients.set(msg.name, ws);\r\n this.wsToName.set(ws, msg.name);\r\n\r\n const peers = [...this.clients.keys()].filter((n) => n !== msg.name);\r\n const ack: HelloAckMsg = { type: 'HELLO_ACK', peers };\r\n this.send(ws, ack);\r\n\r\n if (!isReconnect) {\r\n this.broadcast({ type: 'PEER_JOINED', name: msg.name }, ws);\r\n }\r\n\r\n console.log(`→ ${msg.name} joined (${this.clients.size} online: ${[...this.clients.keys()].join(', ')})`);\r\n break;\r\n }\r\n\r\n case 'ASK': {\r\n const target = this.clients.get(msg.to);\r\n if (!target) {\r\n const err: HubErrorMsg = {\r\n type: 'HUB_ERROR',\r\n code: 'PEER_NOT_FOUND',\r\n message: `'${msg.to}' is not connected to the hub`,\r\n };\r\n this.send(ws, err);\r\n return;\r\n }\r\n this.send(target, msg);\r\n const ack: AskAckMsg = { type: 'ASK_ACK', questionId: msg.questionId, requestId: msg.requestId };\r\n this.send(ws, ack);\r\n break;\r\n }\r\n\r\n case 'GET_ANSWER': {\r\n const target = this.clients.get(msg.to);\r\n if (!target) {\r\n this.send(ws, { type: 'ANSWER_PENDING', to: msg.from, questionId: msg.questionId, requestId: msg.requestId });\r\n return;\r\n }\r\n this.send(target, msg);\r\n break;\r\n }\r\n\r\n case 'ANSWER':\r\n case 'ANSWER_PENDING': {\r\n const target = this.clients.get(msg.to);\r\n if (target) this.send(target, msg);\r\n break;\r\n }\r\n\r\n // HELLO_ACK, ASK_ACK, PEER_JOINED, PEER_LEFT, HUB_ERROR are hub→client only — ignore if received\r\n }\r\n }\r\n\r\n private send(ws: WebSocket, msg: HubMsg): void {\r\n if (ws.readyState === WebSocket.OPEN) {\r\n ws.send(serialize(msg));\r\n }\r\n }\r\n\r\n private broadcast(msg: HubMsg, except?: WebSocket): void {\r\n for (const ws of this.clients.values()) {\r\n if (ws !== except) this.send(ws, msg);\r\n }\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 * HubClient\r\n * Connects outbound to a hub server and implements ICollabClient.\r\n * No local WebSocket server — no inbound port needed.\r\n * @module infrastructure/hub/hub-client\r\n */\r\n\r\nimport { WebSocket } from 'ws';\r\nimport { v4 as uuidv4 } from 'uuid';\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 '../../domain/value-objects/message-content.vo.js';\r\nimport {\r\n type HubMsg,\r\n type HelloAckMsg,\r\n type AskAckMsg,\r\n type AskMsg,\r\n type AnswerMsg,\r\n type AnswerPendingMsg,\r\n type GetAnswerMsg,\r\n parse,\r\n serialize,\r\n} from './hub-protocol.js';\r\nimport { injectionQueue } from '../terminal-injector/injection-queue.js';\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 HubClient implements ICollabClient {\r\n private ws: WebSocket | null = null;\r\n private myName = '';\r\n private serverUrl = '';\r\n private reconnectTimer: NodeJS.Timeout | null = null;\r\n\r\n private readonly connectedPeers = new Set<string>();\r\n private readonly incomingQuestions = new Map<string, IncomingQuestion>();\r\n private readonly receivedAnswers = new Map<string, ReceivedAnswer>();\r\n private readonly questionToName = new Map<string, string>();\r\n private readonly questionToSender = new Map<string, string>();\r\n private readonly sentQuestions = new Map<string, { toPeer: string; content: string; askedAt: string }>();\r\n private readonly pendingHandlers = new Set<(msg: HubMsg) => void>();\r\n\r\n setServerUrl(url: string): void {\r\n this.serverUrl = url;\r\n }\r\n\r\n get isConnected(): boolean {\r\n return this.ws?.readyState === WebSocket.OPEN;\r\n }\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 // Only connect immediately if a server URL was already set.\r\n // If not (e.g. auto-discover mode), connection happens later via connectToHub().\r\n if (this.serverUrl) {\r\n await this.connectAndHello();\r\n }\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: 0,\r\n };\r\n }\r\n\r\n async connectToHub(url: string): Promise<void> {\r\n this.serverUrl = url;\r\n await this.connectAndHello();\r\n }\r\n\r\n async ask(toPeer: string, content: string, format: MessageFormat): Promise<string> {\r\n const questionId = uuidv4();\r\n const requestId = uuidv4();\r\n\r\n this.questionToName.set(questionId, toPeer);\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.requestId === requestId,\r\n 5000\r\n );\r\n\r\n this.sendToHub({ type: 'ASK', from: this.myName, to: toPeer, questionId, requestId, content, format });\r\n\r\n await ackPromise;\r\n return questionId;\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) {\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 const toPeer = this.questionToName.get(questionId);\r\n if (!toPeer || !this.isConnected) return null;\r\n\r\n const requestId = uuidv4();\r\n const responsePromise = this.waitForResponse<AnswerMsg | AnswerPendingMsg>(\r\n (m) =>\r\n (m.type === 'ANSWER' && m.questionId === questionId) ||\r\n (m.type === 'ANSWER_PENDING' && m.requestId === requestId),\r\n 5000\r\n );\r\n\r\n this.sendToHub({ type: 'GET_ANSWER', from: this.myName, to: toPeer, questionId, requestId });\r\n\r\n const response = await responsePromise;\r\n if (response.type === 'ANSWER_PENDING') return null;\r\n\r\n const answer = response as AnswerMsg;\r\n this.receivedAnswers.set(questionId, {\r\n content: answer.content,\r\n format: answer.format,\r\n answeredAt: answer.answeredAt,\r\n fromName: answer.from,\r\n });\r\n\r\n return {\r\n questionId,\r\n from: { displayName: `${answer.from} Claude`, teamName: answer.from },\r\n content: answer.content,\r\n format: answer.format,\r\n answeredAt: answer.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 this.sendToHub({\r\n type: 'ANSWER',\r\n from: this.myName,\r\n to: senderName,\r\n questionId,\r\n content,\r\n format,\r\n answeredAt: new Date().toISOString(),\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\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: undefined,\r\n connectedPeers: [...this.connectedPeers],\r\n };\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 answer: answer?.content,\r\n askedAt: sent.askedAt,\r\n answeredAt: answer?.answeredAt,\r\n });\r\n }\r\n\r\n for (const [questionId, incoming] of this.incomingQuestions) {\r\n entries.push({\r\n direction: 'received',\r\n questionId,\r\n peer: incoming.fromName,\r\n question: incoming.content,\r\n answer: incoming.answered ? incoming.answerContent : undefined,\r\n askedAt: incoming.createdAt.toISOString(),\r\n answeredAt: incoming.answered ? new Date().toISOString() : undefined,\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 if (this.reconnectTimer) {\r\n clearTimeout(this.reconnectTimer);\r\n this.reconnectTimer = null;\r\n }\r\n this.ws?.close();\r\n this.ws = null;\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Private: connection management\r\n // ---------------------------------------------------------------------------\r\n\r\n private async connectAndHello(): Promise<void> {\r\n const ws = new WebSocket(this.serverUrl);\r\n this.ws = ws;\r\n\r\n ws.on('message', (data) => {\r\n try {\r\n const msg = parse(data.toString());\r\n this.handleMessage(msg);\r\n } catch {\r\n // ignore malformed messages\r\n }\r\n });\r\n\r\n ws.on('close', () => {\r\n this.connectedPeers.clear();\r\n this.scheduleReconnect();\r\n });\r\n\r\n ws.on('error', (err) => {\r\n console.error('[hub-client] error:', err.message);\r\n });\r\n\r\n await new Promise<void>((resolve, reject) => {\r\n const timeout = setTimeout(\r\n () => reject(new Error(`Cannot connect to hub at ${this.serverUrl}`)),\r\n 10000\r\n );\r\n ws.on('open', () => {\r\n clearTimeout(timeout);\r\n ws.send(serialize({ type: 'HELLO', name: this.myName }));\r\n resolve();\r\n });\r\n ws.on('error', (err) => {\r\n clearTimeout(timeout);\r\n reject(err);\r\n });\r\n });\r\n\r\n const ack = await this.waitForResponse<HelloAckMsg>(\r\n (m) => m.type === 'HELLO_ACK',\r\n 10000\r\n );\r\n\r\n for (const peer of ack.peers) this.connectedPeers.add(peer);\r\n console.error(`[hub-client] connected as \"${this.myName}\", peers: [${ack.peers.join(', ')}]`);\r\n }\r\n\r\n private scheduleReconnect(): void {\r\n if (this.reconnectTimer) return;\r\n this.reconnectTimer = setTimeout(async () => {\r\n this.reconnectTimer = null;\r\n try {\r\n await this.connectAndHello();\r\n console.error('[hub-client] reconnected to hub');\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n console.error(`[hub-client] reconnect failed: ${msg}, retrying in 5s...`);\r\n this.scheduleReconnect();\r\n }\r\n }, 5000);\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Private: message handling\r\n // ---------------------------------------------------------------------------\r\n\r\n private handleMessage(msg: HubMsg): void {\r\n for (const handler of this.pendingHandlers) handler(msg);\r\n\r\n switch (msg.type) {\r\n case 'PEER_JOINED':\r\n this.connectedPeers.add(msg.name);\r\n console.error(`[hub-client] peer joined: ${msg.name}`);\r\n break;\r\n\r\n case 'PEER_LEFT':\r\n this.connectedPeers.delete(msg.name);\r\n console.error(`[hub-client] peer left: ${msg.name}`);\r\n break;\r\n\r\n case 'ASK':\r\n this.handleIncomingAsk(msg);\r\n break;\r\n\r\n case 'GET_ANSWER':\r\n this.handleGetAnswer(msg);\r\n break;\r\n\r\n case 'ANSWER':\r\n if (!this.receivedAnswers.has(msg.questionId)) {\r\n this.receivedAnswers.set(msg.questionId, {\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 break;\r\n\r\n case 'HUB_ERROR':\r\n console.error(`[hub-client] hub error: ${msg.message}`);\r\n break;\r\n }\r\n }\r\n\r\n private handleIncomingAsk(msg: AskMsg): void {\r\n this.questionToSender.set(msg.questionId, msg.from);\r\n\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 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 handleGetAnswer(msg: GetAnswerMsg): void {\r\n const question = this.incomingQuestions.get(msg.questionId);\r\n\r\n if (!question?.answered) {\r\n this.sendToHub({\r\n type: 'ANSWER_PENDING',\r\n to: msg.from,\r\n questionId: msg.questionId,\r\n requestId: msg.requestId,\r\n });\r\n return;\r\n }\r\n\r\n this.sendToHub({\r\n type: 'ANSWER',\r\n from: this.myName,\r\n to: msg.from,\r\n questionId: msg.questionId,\r\n content: question.answerContent!,\r\n format: question.answerFormat!,\r\n answeredAt: new Date().toISOString(),\r\n requestId: msg.requestId,\r\n });\r\n }\r\n\r\n private sendToHub(msg: HubMsg): void {\r\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\r\n throw new Error('Not connected to hub. Will retry automatically.');\r\n }\r\n this.ws.send(serialize(msg));\r\n }\r\n\r\n private waitForResponse<T extends HubMsg>(\r\n filter: (msg: HubMsg) => 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('Hub request timed out'));\r\n }, timeoutMs);\r\n\r\n const handler = (msg: HubMsg): 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 * MdnsAdvertiser\r\n * Broadcasts the hub's presence on the LAN via mDNS so clients can auto-discover it.\r\n * @module infrastructure/mdns/mdns-advertiser\r\n */\r\n\r\nimport { Bonjour } from 'bonjour-service';\r\n\r\nconst SERVICE_TYPE = 'claude-collab';\r\n\r\nexport class MdnsAdvertiser {\r\n private bonjour: Bonjour | null = null;\r\n\r\n start(port: number): void {\r\n this.bonjour = new Bonjour();\r\n this.bonjour.publish({ name: 'claude-collab-hub', type: SERVICE_TYPE, port });\r\n console.error(`[mdns] advertising hub on port ${port}`);\r\n }\r\n\r\n stop(): void {\r\n if (!this.bonjour) return;\r\n this.bonjour.unpublishAll(() => {\r\n this.bonjour?.destroy();\r\n });\r\n this.bonjour = null;\r\n console.error('[mdns] stopped advertising');\r\n }\r\n}\r\n","/**\r\n * HubManager\r\n * Orchestrates hub lifecycle: starts/stops HubServer, manages Windows firewall rules\r\n * via UAC elevation, and controls mDNS advertising.\r\n * @module infrastructure/hub/hub-manager\r\n */\r\n\r\nimport { spawn } from 'child_process';\r\nimport { HubServer } from './hub-server.js';\r\nimport { MdnsAdvertiser } from '../mdns/mdns-advertiser.js';\r\n\r\nexport class HubManager {\r\n private hubServer: HubServer | null = null;\r\n private advertiser: MdnsAdvertiser | null = null;\r\n private currentPort: number | null = null;\r\n\r\n get isRunning(): boolean {\r\n return this.hubServer !== null;\r\n }\r\n\r\n get port(): number | null {\r\n return this.currentPort;\r\n }\r\n\r\n async start(port: number): Promise<{ firewallAdded: boolean }> {\r\n if (this.isRunning) throw new Error('Hub is already running');\r\n\r\n const server = new HubServer();\r\n server.start(port);\r\n this.hubServer = server;\r\n this.currentPort = port;\r\n\r\n // Advertise on LAN via mDNS (regardless of firewall outcome)\r\n const advertiser = new MdnsAdvertiser();\r\n advertiser.start(port);\r\n this.advertiser = advertiser;\r\n\r\n // Add firewall rule via UAC — hub runs even if this fails\r\n let firewallAdded = false;\r\n try {\r\n await addFirewallRule(port);\r\n firewallAdded = true;\r\n } catch (err) {\r\n console.error('[hub-manager] firewall rule failed:', err);\r\n }\r\n\r\n return { firewallAdded };\r\n }\r\n\r\n async stop(): Promise<{ firewallRemoved: boolean }> {\r\n if (!this.isRunning) throw new Error('Hub is not running');\r\n\r\n if (this.advertiser) {\r\n this.advertiser.stop();\r\n this.advertiser = null;\r\n }\r\n\r\n const port = this.currentPort!;\r\n this.hubServer!.stop();\r\n this.hubServer = null;\r\n this.currentPort = null;\r\n\r\n let firewallRemoved = false;\r\n try {\r\n await removeFirewallRule(port);\r\n firewallRemoved = true;\r\n } catch (err) {\r\n console.error('[hub-manager] firewall rule removal failed:', err);\r\n }\r\n\r\n return { firewallRemoved };\r\n }\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Firewall helpers — elevated via UAC (PowerShell Start-Process -Verb RunAs)\r\n// ---------------------------------------------------------------------------\r\n\r\nfunction runElevated(argArray: string[]): Promise<void> {\r\n // Pass arguments as a PowerShell array to avoid quote escaping issues.\r\n // e.g. @(\"advfirewall\",\"firewall\",\"add\",\"rule\",\"name=claude-collab-9999\",...)\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\nasync function addFirewallRule(port: number): Promise<void> {\r\n await runElevated([\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\nasync function removeFirewallRule(port: number): Promise<void> {\r\n await runElevated([\r\n 'advfirewall', 'firewall', 'delete', 'rule',\r\n `name=claude-collab-${port}`,\r\n ]);\r\n}\r\n","/**\r\n * Ask Tool\r\n * Sends a question to another team and returns a question ID immediately.\r\n * Use the \"check_answer\" tool with the question ID to retrieve the answer later.\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\n/**\r\n * Ask tool input schema\r\n */\r\nconst askSchema = {\r\n peer: z.string().describe('Name of the peer to ask (e.g., \"alice\", \"backend\")'),\r\n question: z.string().describe('The question to ask (supports markdown)'),\r\n};\r\n\r\n/**\r\n * Registers the ask tool with the MCP server\r\n */\r\nexport function registerAskTool(server: McpServer, client: ICollabClient): void {\r\n server.tool('ask', 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 {\r\n type: 'text',\r\n text: 'Node is not ready yet. Wait a moment and try again.',\r\n },\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 // Poll until answer arrives (max 5 minutes, every 5 seconds)\r\n const POLL_INTERVAL_MS = 5_000;\r\n const MAX_WAIT_MS = 5 * 60 * 1000;\r\n const deadline = Date.now() + MAX_WAIT_MS;\r\n\r\n while (Date.now() < deadline) {\r\n await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));\r\n const answer = await client.checkAnswer(questionId);\r\n if (answer !== null) {\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: `**${answer.from.displayName} (${answer.from.teamName}) cevapladı:**\\n\\n${answer.content}`,\r\n },\r\n ],\r\n };\r\n }\r\n }\r\n\r\n // Timed out — return question ID for manual follow-up\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: `Soru gönderildi ancak 5 dakika içinde cevap gelmedi.\\nQuestion ID: \\`${questionId}\\`\\n\\nManuel kontrol için \"check_answer\" tool'unu kullanabilirsin.`,\r\n },\r\n ],\r\n };\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: `Failed to send question: ${errorMessage}`,\r\n },\r\n ],\r\n isError: true,\r\n };\r\n }\r\n });\r\n}\r\n","/**\r\n * Reply Tool\r\n * Replies to a pending question\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\n/**\r\n * Reply tool input schema\r\n */\r\nconst replySchema = {\r\n questionId: z.string().describe('The ID of the question to reply to (from inbox)'),\r\n answer: z.string().describe('Your answer to the question (supports markdown)'),\r\n};\r\n\r\n/**\r\n * Registers the reply tool with the MCP server\r\n */\r\nexport function registerReplyTool(server: McpServer, client: ICollabClient): void {\r\n server.tool('reply', 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 {\r\n type: 'text',\r\n text: 'You must join a team first. Use the \"join\" tool to join a team.',\r\n },\r\n ],\r\n isError: true,\r\n };\r\n }\r\n\r\n await client.reply(questionId, answer, 'markdown');\r\n\r\n // Signal queue: this question is done, process next\r\n injectionQueue.notifyReplied();\r\n\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: `Reply sent successfully to question \\`${questionId}\\`.`,\r\n },\r\n ],\r\n };\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: `Failed to send reply: ${errorMessage}`,\r\n },\r\n ],\r\n isError: true,\r\n };\r\n }\r\n });\r\n}\r\n","/**\r\n * Peers Tool\r\n * Lists currently connected peers on the collaboration network.\r\n * @module presentation/mcp/tools/peers\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\nexport function registerPeersTool(server: McpServer, client: ICollabClient): void {\r\n server.tool('peers', {}, async () => {\r\n const info = client.getInfo();\r\n const myName = info.teamName ?? '(starting...)';\r\n const connected = info.connectedPeers;\r\n\r\n if (connected.length === 0) {\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `You are \"${myName}\". No peers connected yet — they will appear automatically when they come online.`,\r\n }],\r\n };\r\n }\r\n\r\n const list = connected.map((name) => ` • ${name}`).join('\\n');\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `You are \"${myName}\". Connected peers (${connected.length}):\\n${list}`,\r\n }],\r\n };\r\n });\r\n}\r\n","/**\r\n * History Tool\r\n * Shows past questions and answers from this session.\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\nexport function registerHistoryTool(server: McpServer, client: ICollabClient): void {\r\n server.tool('history', {}, 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 yet this session.' }],\r\n };\r\n }\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)`;\r\n return `[${time}] ← ${e.peer}: ${e.question}\\n${answerLine}`;\r\n }\r\n });\r\n\r\n return {\r\n content: [{ type: 'text', text: lines.join('\\n\\n') }],\r\n };\r\n });\r\n}\r\n","/**\r\n * StartHub Tool\r\n * Starts a hub server on this machine, opens a Windows firewall rule via UAC,\r\n * and advertises the hub on the LAN via mDNS so peers auto-discover it.\r\n * @module presentation/mcp/tools/start-hub\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 type { HubManager } from '../../../infrastructure/hub/hub-manager.js';\r\n\r\nexport function registerStartHubTool(\r\n server: McpServer,\r\n client: ICollabClient,\r\n hubManager: HubManager\r\n): void {\r\n server.tool(\r\n 'start_hub',\r\n 'Start a hub server on this machine. Opens a firewall rule (UAC prompt) and advertises on LAN via mDNS — peers connect automatically, no IP sharing needed.',\r\n { port: z.number().min(1024).max(65535).optional().describe('Port to listen on (default: 9999)') },\r\n async ({ port = 9999 }) => {\r\n if (hubManager.isRunning) {\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Hub is already running on port ${hubManager.port}.`,\r\n }],\r\n };\r\n }\r\n\r\n let firewallAdded = false;\r\n try {\r\n const result = await hubManager.start(port);\r\n firewallAdded = result.firewallAdded;\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n return {\r\n content: [{ type: 'text', text: `Failed to start hub: ${msg}` }],\r\n };\r\n }\r\n\r\n // Connect this instance to the local hub so it can use all tools\r\n try {\r\n await client.connectToHub(`ws://localhost:${port}`);\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n return {\r\n content: [{ type: 'text', text: `Hub started on port ${port}, but failed to self-connect: ${msg}` }],\r\n };\r\n }\r\n\r\n const lines = [\r\n `Hub started on port ${port}.`,\r\n firewallAdded\r\n ? `Firewall rule added (claude-collab-${port}) — LAN peers can connect.`\r\n : `WARNING: Firewall rule could not be added (UAC was cancelled or denied). Peers on other machines may be blocked by Windows Firewall. Run start_hub again and accept the UAC prompt to fix this.`,\r\n `Others on the LAN will auto-discover and connect via mDNS.`,\r\n `Use stop_hub when you are done.`,\r\n ];\r\n\r\n return {\r\n content: [{ type: 'text', text: lines.join('\\n') }],\r\n };\r\n }\r\n );\r\n}\r\n","/**\r\n * StopHub Tool\r\n * Stops the running hub server, removes the Windows firewall rule via UAC,\r\n * and ceases mDNS advertising.\r\n * @module presentation/mcp/tools/stop-hub\r\n */\r\n\r\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\r\nimport type { HubManager } from '../../../infrastructure/hub/hub-manager.js';\r\n\r\nexport function registerStopHubTool(server: McpServer, hubManager: HubManager): void {\r\n server.tool(\r\n 'stop_hub',\r\n 'Stop the running hub server. Removes the firewall rule (UAC prompt) and stops LAN advertising. Connected peers will be disconnected.',\r\n {},\r\n async () => {\r\n if (!hubManager.isRunning) {\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: 'No hub is currently running on this machine.',\r\n }],\r\n };\r\n }\r\n\r\n const port = hubManager.port;\r\n\r\n let firewallRemoved = false;\r\n try {\r\n const result = await hubManager.stop();\r\n firewallRemoved = result.firewallRemoved;\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n return {\r\n content: [{ type: 'text', text: `Failed to stop hub: ${msg}` }],\r\n };\r\n }\r\n\r\n const lines = [\r\n `Hub stopped (was on port ${port}).`,\r\n firewallRemoved\r\n ? `Firewall rule removed (claude-collab-${port}).`\r\n : `WARNING: Firewall rule could not be removed (UAC was cancelled). Remove it manually: netsh advfirewall firewall delete rule name=\"claude-collab-${port}\"`,\r\n `All peers have been disconnected.`,\r\n ];\r\n\r\n return {\r\n content: [{ type: 'text', text: lines.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 type { HubManager } from '../../infrastructure/hub/hub-manager.js';\r\nimport { registerAskTool } from './tools/ask.tool.js';\r\nimport { registerReplyTool } from './tools/reply.tool.js';\r\nimport { registerPeersTool } from './tools/peers.tool.js';\r\nimport { registerHistoryTool } from './tools/history.tool.js';\r\nimport { registerStartHubTool } from './tools/start-hub.tool.js';\r\nimport { registerStopHubTool } from './tools/stop-hub.tool.js';\r\n\r\nexport interface McpServerOptions {\r\n client: ICollabClient;\r\n hubManager: HubManager;\r\n}\r\n\r\nexport function createMcpServer(options: McpServerOptions): McpServer {\r\n const { client, hubManager } = 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 registerAskTool(server, client);\r\n registerReplyTool(server, client);\r\n registerPeersTool(server, client);\r\n registerHistoryTool(server, client);\r\n registerStartHubTool(server, client, hubManager);\r\n registerStopHubTool(server, hubManager);\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","/**\r\n * MdnsDiscovery\r\n * Discovers a claude-collab hub on the LAN via mDNS.\r\n * @module infrastructure/mdns/mdns-discovery\r\n */\r\n\r\nimport { Bonjour } from 'bonjour-service';\r\n\r\nconst SERVICE_TYPE = 'claude-collab';\r\n\r\nexport interface DiscoveredHub {\r\n host: string;\r\n port: number;\r\n}\r\n\r\n/**\r\n * One-shot discovery: resolves with hub info if found within timeoutMs, otherwise null.\r\n */\r\nexport function discoverHub(timeoutMs = 5000): Promise<DiscoveredHub | null> {\r\n return new Promise((resolve) => {\r\n const bonjour = new Bonjour();\r\n const browser = bonjour.find({ type: SERVICE_TYPE });\r\n\r\n let settled = false;\r\n\r\n const finish = (result: DiscoveredHub | null) => {\r\n if (settled) return;\r\n settled = true;\r\n clearTimeout(timer);\r\n browser.stop();\r\n bonjour.destroy();\r\n resolve(result);\r\n };\r\n\r\n const timer = setTimeout(() => finish(null), timeoutMs);\r\n\r\n browser.on('up', (svc) => {\r\n finish({ host: svc.host, port: svc.port });\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * Continuous watcher: calls onFound whenever a hub appears on the LAN.\r\n * Returns a stop function — call it to cancel watching.\r\n */\r\nexport function watchForHub(onFound: (hub: DiscoveredHub) => void): () => void {\r\n const bonjour = new Bonjour();\r\n const browser = bonjour.find({ type: SERVICE_TYPE });\r\n\r\n browser.on('up', (svc) => {\r\n onFound({ host: svc.host, port: svc.port });\r\n });\r\n\r\n return () => {\r\n browser.stop();\r\n bonjour.destroy();\r\n };\r\n}\r\n","#!/usr/bin/env node\r\n\r\n/**\r\n * CLI entry point\r\n *\r\n * Hub mode: claude-collab --hub [--port 9999]\r\n * Client mode: claude-collab --name alice --server 192.168.1.5:9999\r\n *\r\n * @module cli\r\n */\r\n\r\nimport { Command } from 'commander';\r\nimport { HubServer } from './infrastructure/hub/hub-server.js';\r\nimport { HubClient } from './infrastructure/hub/hub-client.js';\r\nimport { HubManager } from './infrastructure/hub/hub-manager.js';\r\nimport { startMcpServer } from './presentation/mcp/server.js';\r\nimport { discoverHub, watchForHub } from './infrastructure/mdns/mdns-discovery.js';\r\n\r\nconst program = new Command();\r\n\r\nprogram\r\n .name('claude-collab')\r\n .description('P2P collaboration between Claude Code terminals via a shared hub')\r\n .version('0.1.0')\r\n .option('--hub', 'Run as hub server (one machine per team)')\r\n .option('--port <port>', 'Hub server port (hub mode, default: 9999)', '9999')\r\n .option('--name <name>', 'Your name on the network (client mode, e.g. \"alice\")')\r\n .option('--server <address>', 'Hub address to connect to (client mode, e.g. \"192.168.1.5:9999\")')\r\n .action(async (options: { hub?: boolean; port: string; name?: string; server?: string }) => {\r\n if (options.hub) {\r\n // --- Hub mode ---\r\n const port = parseInt(options.port, 10);\r\n if (isNaN(port)) {\r\n console.error(`Invalid port: ${options.port}`);\r\n process.exit(1);\r\n }\r\n const hub = new HubServer();\r\n hub.start(port);\r\n // Keep the process alive\r\n process.on('SIGINT', () => {\r\n console.log('\\nHub stopped.');\r\n process.exit(0);\r\n });\r\n } else {\r\n // --- Client / MCP mode ---\r\n if (!options.name) {\r\n console.error('--name is required');\r\n process.exit(1);\r\n }\r\n\r\n const client = new HubClient();\r\n const hubManager = new HubManager();\r\n\r\n if (options.server) {\r\n // Direct mode: connect to specified hub immediately\r\n const url = options.server.startsWith('ws') ? options.server : `ws://${options.server}`;\r\n client.setServerUrl(url);\r\n await client.join(options.name, options.name);\r\n } else {\r\n // Auto-discover mode: start MCP immediately, connect in background\r\n await client.join(options.name, options.name);\r\n }\r\n\r\n const mcpReady = startMcpServer({ client, hubManager });\r\n\r\n if (!options.server) {\r\n discoverHub(5000).then(async (hub) => {\r\n if (!hub || client.isConnected) return;\r\n try {\r\n await client.connectToHub(`ws://${hub.host}:${hub.port}`);\r\n } catch { /* background watcher will retry */ }\r\n });\r\n\r\n const stopWatch = watchForHub(async (hub) => {\r\n if (client.isConnected) { stopWatch(); return; }\r\n try {\r\n await client.connectToHub(`ws://${hub.host}:${hub.port}`);\r\n stopWatch();\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n console.error(`[cli] auto-connect failed: ${msg}`);\r\n }\r\n });\r\n }\r\n\r\n await mcpReady;\r\n }\r\n });\r\n\r\nprogram.parse();\r\n"]}
package/dist/mcp-main.js CHANGED
@@ -701,10 +701,17 @@ var HubManager = class {
701
701
  server.start(port);
702
702
  this.hubServer = server;
703
703
  this.currentPort = port;
704
- await addFirewallRule(port);
705
704
  const advertiser = new MdnsAdvertiser();
706
705
  advertiser.start(port);
707
706
  this.advertiser = advertiser;
707
+ let firewallAdded = false;
708
+ try {
709
+ await addFirewallRule(port);
710
+ firewallAdded = true;
711
+ } catch (err) {
712
+ console.error("[hub-manager] firewall rule failed:", err);
713
+ }
714
+ return { firewallAdded };
708
715
  }
709
716
  async stop() {
710
717
  if (!this.isRunning) throw new Error("Hub is not running");
@@ -716,34 +723,51 @@ var HubManager = class {
716
723
  this.hubServer.stop();
717
724
  this.hubServer = null;
718
725
  this.currentPort = null;
719
- await removeFirewallRule(port);
726
+ let firewallRemoved = false;
727
+ try {
728
+ await removeFirewallRule(port);
729
+ firewallRemoved = true;
730
+ } catch (err) {
731
+ console.error("[hub-manager] firewall rule removal failed:", err);
732
+ }
733
+ return { firewallRemoved };
720
734
  }
721
735
  };
722
- function runElevated(netshArgs) {
736
+ function runElevated(argArray) {
737
+ const argList = argArray.map((a) => `"${a}"`).join(",");
738
+ const psCommand = `Start-Process -FilePath "netsh" -ArgumentList @(${argList}) -Verb RunAs -Wait`;
723
739
  return new Promise((resolve, reject) => {
724
- const ps = spawn("powershell", [
725
- "-NoProfile",
726
- "-Command",
727
- `Start-Process -FilePath "netsh" -ArgumentList "${netshArgs}" -Verb RunAs -Wait`
728
- ]);
740
+ const ps = spawn("powershell", ["-NoProfile", "-Command", psCommand]);
729
741
  ps.on("close", (code) => {
730
742
  if (code === 0) resolve();
731
- else reject(new Error(`Firewall command failed (exit code ${code}). User may have cancelled the UAC prompt.`));
743
+ else reject(new Error(`Firewall UAC prompt was cancelled or denied (exit code ${code}).`));
732
744
  });
733
745
  ps.on("error", (err) => {
734
- reject(new Error(`Failed to launch PowerShell for firewall elevation: ${err.message}`));
746
+ reject(new Error(`Failed to launch PowerShell: ${err.message}`));
735
747
  });
736
748
  });
737
749
  }
738
750
  async function addFirewallRule(port) {
739
- await runElevated(
740
- `advfirewall firewall add rule name="claude-collab-${port}" protocol=TCP dir=in localport=${port} action=allow`
741
- );
751
+ await runElevated([
752
+ "advfirewall",
753
+ "firewall",
754
+ "add",
755
+ "rule",
756
+ `name=claude-collab-${port}`,
757
+ "protocol=TCP",
758
+ "dir=in",
759
+ `localport=${port}`,
760
+ "action=allow"
761
+ ]);
742
762
  }
743
763
  async function removeFirewallRule(port) {
744
- await runElevated(
745
- `advfirewall firewall delete rule name="claude-collab-${port}"`
746
- );
764
+ await runElevated([
765
+ "advfirewall",
766
+ "firewall",
767
+ "delete",
768
+ "rule",
769
+ `name=claude-collab-${port}`
770
+ ]);
747
771
  }
748
772
  var askSchema = {
749
773
  peer: z.string().describe('Name of the peer to ask (e.g., "alice", "backend")'),
@@ -920,15 +944,14 @@ function registerStartHubTool(server, client, hubManager) {
920
944
  }]
921
945
  };
922
946
  }
947
+ let firewallAdded = false;
923
948
  try {
924
- await hubManager.start(port);
949
+ const result = await hubManager.start(port);
950
+ firewallAdded = result.firewallAdded;
925
951
  } catch (err) {
926
952
  const msg = err instanceof Error ? err.message : String(err);
927
953
  return {
928
- content: [{
929
- type: "text",
930
- text: `Failed to start hub: ${msg}`
931
- }]
954
+ content: [{ type: "text", text: `Failed to start hub: ${msg}` }]
932
955
  };
933
956
  }
934
957
  try {
@@ -936,22 +959,17 @@ function registerStartHubTool(server, client, hubManager) {
936
959
  } catch (err) {
937
960
  const msg = err instanceof Error ? err.message : String(err);
938
961
  return {
939
- content: [{
940
- type: "text",
941
- text: `Hub started on port ${port}, but failed to self-connect: ${msg}`
942
- }]
962
+ content: [{ type: "text", text: `Hub started on port ${port}, but failed to self-connect: ${msg}` }]
943
963
  };
944
964
  }
965
+ const lines = [
966
+ `Hub started on port ${port}.`,
967
+ firewallAdded ? `Firewall rule added (claude-collab-${port}) \u2014 LAN peers can connect.` : `WARNING: Firewall rule could not be added (UAC was cancelled or denied). Peers on other machines may be blocked by Windows Firewall. Run start_hub again and accept the UAC prompt to fix this.`,
968
+ `Others on the LAN will auto-discover and connect via mDNS.`,
969
+ `Use stop_hub when you are done.`
970
+ ];
945
971
  return {
946
- content: [{
947
- type: "text",
948
- text: [
949
- `Hub started on port ${port}.`,
950
- `Firewall rule added (claude-collab-${port}).`,
951
- `Others on the LAN will auto-discover and connect \u2014 no IP sharing needed.`,
952
- `Use stop_hub when you are done to close the hub and remove the firewall rule.`
953
- ].join("\n")
954
- }]
972
+ content: [{ type: "text", text: lines.join("\n") }]
955
973
  };
956
974
  }
957
975
  );
@@ -973,26 +991,23 @@ function registerStopHubTool(server, hubManager) {
973
991
  };
974
992
  }
975
993
  const port = hubManager.port;
994
+ let firewallRemoved = false;
976
995
  try {
977
- await hubManager.stop();
996
+ const result = await hubManager.stop();
997
+ firewallRemoved = result.firewallRemoved;
978
998
  } catch (err) {
979
999
  const msg = err instanceof Error ? err.message : String(err);
980
1000
  return {
981
- content: [{
982
- type: "text",
983
- text: `Failed to stop hub: ${msg}`
984
- }]
1001
+ content: [{ type: "text", text: `Failed to stop hub: ${msg}` }]
985
1002
  };
986
1003
  }
1004
+ const lines = [
1005
+ `Hub stopped (was on port ${port}).`,
1006
+ firewallRemoved ? `Firewall rule removed (claude-collab-${port}).` : `WARNING: Firewall rule could not be removed (UAC was cancelled). Remove it manually: netsh advfirewall firewall delete rule name="claude-collab-${port}"`,
1007
+ `All peers have been disconnected.`
1008
+ ];
987
1009
  return {
988
- content: [{
989
- type: "text",
990
- text: [
991
- `Hub stopped (was on port ${port}).`,
992
- `Firewall rule removed (claude-collab-${port}).`,
993
- `All peers have been disconnected.`
994
- ].join("\n")
995
- }]
1010
+ content: [{ type: "text", text: lines.join("\n") }]
996
1011
  };
997
1012
  }
998
1013
  );
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/infrastructure/hub/hub-protocol.ts","../src/infrastructure/terminal-injector/windows-injector.ts","../src/infrastructure/terminal-injector/index.ts","../src/infrastructure/terminal-injector/injection-queue.ts","../src/infrastructure/hub/hub-client.ts","../src/infrastructure/hub/hub-server.ts","../src/infrastructure/mdns/mdns-advertiser.ts","../src/infrastructure/hub/hub-manager.ts","../src/presentation/mcp/tools/ask.tool.ts","../src/presentation/mcp/tools/reply.tool.ts","../src/presentation/mcp/tools/peers.tool.ts","../src/presentation/mcp/tools/history.tool.ts","../src/presentation/mcp/tools/start-hub.tool.ts","../src/presentation/mcp/tools/stop-hub.tool.ts","../src/presentation/mcp/server.ts","../src/infrastructure/mdns/mdns-discovery.ts","../src/mcp-main.ts"],"names":["uuidv4","WebSocket","z","SERVICE_TYPE","Bonjour"],"mappings":";;;;;;;;;;;;;;AAkGO,SAAS,UAAU,GAAA,EAAqB;AAC7C,EAAA,OAAO,IAAA,CAAK,UAAU,GAAG,CAAA;AAC3B;AAEO,SAAS,MAAM,IAAA,EAAsB;AAC1C,EAAA,OAAO,IAAA,CAAK,MAAM,IAAI,CAAA;AACxB;AC3FA,IAAM,YAAA,GAAe;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AA4GrB,SAAS,WAAA,CAAY,WAAmB,IAAA,EAAsB;AAC5D,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,MAAA,EAAO,EAAG,CAAA,UAAA,EAAa,IAAA,CAAK,GAAA,EAAK,CAAA,IAAA,CAAM,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA;AAChF,EAAA,OAAO;AAAA,QAAA,EACC,OAAO,CAAA;AAAA;AAAA,aAAA,EAEF,SAAS;AAAA,iBAAA,EACL,YAAY,CAAA;AAAA,EAC7B,IAAI;AAAA,CAAA;AAEN;AAEA,SAAS,IAAI,MAAA,EAA+B;AAC1C,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC9B,IAAA,MAAM,UAAU,MAAA,CAAO,IAAA,CAAK,QAAQ,SAAS,CAAA,CAAE,SAAS,QAAQ,CAAA;AAChE,IAAA,QAAA;AAAA,MACE,YAAA;AAAA,MACA,CAAC,YAAA,EAAc,cAAA,EAAgB,QAAA,EAAU,mBAAmB,OAAO,CAAA;AAAA,MACnE,EAAE,aAAa,IAAA,EAAK;AAAA,MACpB,MAAM;AACJ,QAAA,MAAM,OAAA,GAAU,MAAA,CAAO,KAAA,CAAM,mBAAmB,IAAI,CAAC,CAAA;AACrD,QAAA,IAAI,SAAS,IAAI;AAAE,UAAA,UAAA,CAAW,OAAO,CAAA;AAAA,QAAG,CAAA,CAAA,MAAQ;AAAA,QAAW;AAC3D,QAAA,OAAA,EAAQ;AAAA,MACV;AAAA,KACF;AAAA,EACF,CAAC,CAAA;AACH;AAEA,eAAsB,cAAc,IAAA,EAA6B;AAC/D,EAAA,MAAM,YAAY,OAAA,CAAQ,IAAA;AAC1B,EAAA,MAAM,UAAU,MAAA,CAAO,IAAA,CAAK,MAAM,SAAS,CAAA,CAAE,SAAS,QAAQ,CAAA;AAE9D,EAAA,MAAM,MAAA,GAAS,YAAY,SAAA,EAAW;AAAA,iDAAA,EACW,OAAO,CAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA,CAazD,CAAA;AAEC,EAAA,MAAM,IAAI,MAAM,CAAA;AAClB;AAEA,eAAsB,kBAAA,GAAoC;AACxD,EAAA,MAAM,YAAY,OAAA,CAAQ,IAAA;AAE1B,EAAA,MAAM,MAAA,GAAS,YAAY,SAAA,EAAW;AAAA;AAAA,CAEvC,CAAA;AAEC,EAAA,MAAM,IAAI,MAAM,CAAA;AAClB;;;ACtKA,SAAS,2BAA2B,QAAA,EAAsC;AAExE,EAAA,MAAM,UAAU,QAAA,CAAS,OAAA,CAAQ,QAAQ,MAAA,EAAQ,GAAG,EAAE,IAAA,EAAK;AAC3D,EAAA,OAAO,CAAA,gBAAA,EAAmB,QAAA,CAAS,UAAU,CAAA,GAAA,EAAM,SAAS,IAAA,CAAK,WAAW,CAAA,EAAA,EAAK,QAAA,CAAS,KAAK,QAAQ,CAAA,GAAA,EAAM,OAAO,CAAA,8BAAA,EAAiC,SAAS,UAAU,CAAA,kCAAA,CAAA;AAC1K;AAMA,eAAsB,yBAAyB,QAAA,EAA6C;AAC1F,EAAA,IAAI,OAAA,CAAQ,aAAa,OAAA,EAAS;AAElC,EAAA,MAAM,IAAA,GAAO,2BAA2B,QAAQ,CAAA;AAChD,EAAA,MAAM,cAAc,IAAI,CAAA;AAC1B;AAMA,eAAsB,iBAAA,GAAmC;AACvD,EAAA,IAAI,OAAA,CAAQ,aAAa,OAAA,EAAS;AAClC,EAAA,MAAM,kBAAA,EAAmB;AAC3B;;;AC1BA,IAAM,gBAAA,GAAmB,IAAI,EAAA,GAAK,GAAA;AAElC,IAAM,cAAA,GAAN,cAA6B,YAAA,CAAa;AAAA,EAChC,QAA8B,EAAC;AAAA,EAC/B,UAAA,GAAa,KAAA;AAAA;AAAA;AAAA;AAAA,EAKrB,QAAQ,QAAA,EAAoC;AAC1C,IAAA,IAAA,CAAK,KAAA,CAAM,KAAK,QAAQ,CAAA;AACxB,IAAA,IAAI,CAAC,IAAA,CAAK,UAAA,EAAY,KAAK,KAAK,WAAA,EAAY;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAA,GAAsB;AACpB,IAAA,IAAA,CAAK,KAAK,SAAS,CAAA;AAAA,EACrB;AAAA,EAEA,MAAc,WAAA,GAA6B;AACzC,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG;AAC3B,MAAA,IAAA,CAAK,UAAA,GAAa,KAAA;AAClB,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAClB,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,KAAA,EAAM;AAGlC,IAAA,MAAM,yBAAyB,QAAQ,CAAA;AAGvC,IAAA,MAAM,IAAI,OAAA,CAAc,CAAC,OAAA,KAAY;AACnC,MAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,OAAA,EAAS,gBAAgB,CAAA;AAClD,MAAA,IAAA,CAAK,IAAA,CAAK,WAAW,MAAM;AACzB,QAAA,YAAA,CAAa,KAAK,CAAA;AAClB,QAAA,OAAA,EAAQ;AAAA,MACV,CAAC,CAAA;AAAA,IACH,CAAC,CAAA;AAGD,IAAA,MAAM,iBAAA,EAAkB;AAGxB,IAAA,KAAK,KAAK,WAAA,EAAY;AAAA,EACxB;AACF,CAAA;AAEO,IAAM,cAAA,GAAiB,IAAI,cAAA,EAAe;;;ACb1C,IAAM,YAAN,MAAyC;AAAA,EACtC,EAAA,GAAuB,IAAA;AAAA,EACvB,MAAA,GAAS,EAAA;AAAA,EACT,SAAA,GAAY,EAAA;AAAA,EACZ,cAAA,GAAwC,IAAA;AAAA,EAE/B,cAAA,uBAAqB,GAAA,EAAY;AAAA,EACjC,iBAAA,uBAAwB,GAAA,EAA8B;AAAA,EACtD,eAAA,uBAAsB,GAAA,EAA4B;AAAA,EAClD,cAAA,uBAAqB,GAAA,EAAoB;AAAA,EACzC,gBAAA,uBAAuB,GAAA,EAAoB;AAAA,EAC3C,aAAA,uBAAoB,GAAA,EAAkE;AAAA,EACtF,eAAA,uBAAsB,GAAA,EAA2B;AAAA,EAElE,aAAa,GAAA,EAAmB;AAC9B,IAAA,IAAA,CAAK,SAAA,GAAY,GAAA;AAAA,EACnB;AAAA,EAEA,IAAI,WAAA,GAAuB;AACzB,IAAA,OAAO,IAAA,CAAK,EAAA,EAAI,UAAA,KAAe,SAAA,CAAU,IAAA;AAAA,EAC3C;AAAA,EAEA,IAAI,aAAA,GAAoC;AACtC,IAAA,OAAO,KAAK,MAAA,IAAU,MAAA;AAAA,EACxB;AAAA,EAEA,MAAM,IAAA,CAAK,IAAA,EAAc,WAAA,EAA0C;AACjE,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AAGd,IAAA,IAAI,KAAK,SAAA,EAAW;AAClB,MAAA,MAAM,KAAK,eAAA,EAAgB;AAAA,IAC7B;AACA,IAAA,OAAO;AAAA,MACL,UAAUA,EAAA,EAAO;AAAA,MACjB,MAAA,EAAQ,IAAA;AAAA,MACR,QAAA,EAAU,IAAA;AAAA,MACV,WAAA;AAAA,MACA,MAAA,EAAQ,QAAA;AAAA,MACR,IAAA,EAAM;AAAA,KACR;AAAA,EACF;AAAA,EAEA,MAAM,aAAa,GAAA,EAA4B;AAC7C,IAAA,IAAA,CAAK,SAAA,GAAY,GAAA;AACjB,IAAA,MAAM,KAAK,eAAA,EAAgB;AAAA,EAC7B;AAAA,EAEA,MAAM,GAAA,CAAI,MAAA,EAAgB,OAAA,EAAiB,MAAA,EAAwC;AACjF,IAAA,MAAM,aAAaA,EAAA,EAAO;AAC1B,IAAA,MAAM,YAAYA,EAAA,EAAO;AAEzB,IAAA,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,UAAA,EAAY,MAAM,CAAA;AAC1C,IAAA,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,UAAA,EAAY,EAAE,MAAA,EAAQ,OAAA,EAAS,OAAA,EAAA,iBAAS,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY,EAAG,CAAA;AAEzF,IAAA,MAAM,aAAa,IAAA,CAAK,eAAA;AAAA,MACtB,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,SAAA,IAAa,EAAE,SAAA,KAAc,SAAA;AAAA,MAC/C;AAAA,KACF;AAEA,IAAA,IAAA,CAAK,SAAA,CAAU,EAAE,IAAA,EAAM,KAAA,EAAO,IAAA,EAAM,IAAA,CAAK,MAAA,EAAQ,EAAA,EAAI,MAAA,EAAQ,UAAA,EAAY,SAAA,EAAW,OAAA,EAAS,QAAQ,CAAA;AAErG,IAAA,MAAM,UAAA;AACN,IAAA,OAAO,UAAA;AAAA,EACT;AAAA,EAEA,MAAM,YAAY,UAAA,EAAuD;AACvE,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,eAAA,CAAgB,GAAA,CAAI,UAAU,CAAA;AAClD,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,OAAO;AAAA,QACL,UAAA;AAAA,QACA,IAAA,EAAM,EAAE,WAAA,EAAa,CAAA,EAAG,OAAO,QAAQ,CAAA,OAAA,CAAA,EAAW,QAAA,EAAU,MAAA,CAAO,QAAA,EAAS;AAAA,QAC5E,SAAS,MAAA,CAAO,OAAA;AAAA,QAChB,QAAQ,MAAA,CAAO,MAAA;AAAA,QACf,YAAY,MAAA,CAAO;AAAA,OACrB;AAAA,IACF;AAEA,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,UAAU,CAAA;AACjD,IAAA,IAAI,CAAC,MAAA,IAAU,CAAC,IAAA,CAAK,aAAa,OAAO,IAAA;AAEzC,IAAA,MAAM,YAAYA,EAAA,EAAO;AACzB,IAAA,MAAM,kBAAkB,IAAA,CAAK,eAAA;AAAA,MAC3B,CAAC,CAAA,KACE,CAAA,CAAE,IAAA,KAAS,QAAA,IAAY,CAAA,CAAE,UAAA,KAAe,UAAA,IACxC,CAAA,CAAE,IAAA,KAAS,gBAAA,IAAoB,CAAA,CAAE,SAAA,KAAc,SAAA;AAAA,MAClD;AAAA,KACF;AAEA,IAAA,IAAA,CAAK,SAAA,CAAU,EAAE,IAAA,EAAM,YAAA,EAAc,IAAA,EAAM,IAAA,CAAK,MAAA,EAAQ,EAAA,EAAI,MAAA,EAAQ,UAAA,EAAY,SAAA,EAAW,CAAA;AAE3F,IAAA,MAAM,WAAW,MAAM,eAAA;AACvB,IAAA,IAAI,QAAA,CAAS,IAAA,KAAS,gBAAA,EAAkB,OAAO,IAAA;AAE/C,IAAA,MAAM,MAAA,GAAS,QAAA;AACf,IAAA,IAAA,CAAK,eAAA,CAAgB,IAAI,UAAA,EAAY;AAAA,MACnC,SAAS,MAAA,CAAO,OAAA;AAAA,MAChB,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,YAAY,MAAA,CAAO,UAAA;AAAA,MACnB,UAAU,MAAA,CAAO;AAAA,KAClB,CAAA;AAED,IAAA,OAAO;AAAA,MACL,UAAA;AAAA,MACA,IAAA,EAAM,EAAE,WAAA,EAAa,CAAA,EAAG,OAAO,IAAI,CAAA,OAAA,CAAA,EAAW,QAAA,EAAU,MAAA,CAAO,IAAA,EAAK;AAAA,MACpE,SAAS,MAAA,CAAO,OAAA;AAAA,MAChB,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,YAAY,MAAA,CAAO;AAAA,KACrB;AAAA,EACF;AAAA,EAEA,MAAM,KAAA,CAAM,UAAA,EAAoB,OAAA,EAAiB,MAAA,EAAsC;AACrF,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,iBAAA,CAAkB,GAAA,CAAI,UAAU,CAAA;AACtD,IAAA,IAAI,CAAC,QAAA,EAAU,MAAM,IAAI,KAAA,CAAM,CAAA,SAAA,EAAY,UAAU,CAAA,UAAA,CAAY,CAAA;AAEjE,IAAA,QAAA,CAAS,QAAA,GAAW,IAAA;AACpB,IAAA,QAAA,CAAS,aAAA,GAAgB,OAAA;AACzB,IAAA,QAAA,CAAS,YAAA,GAAe,MAAA;AAExB,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,gBAAA,CAAiB,GAAA,CAAI,UAAU,CAAA;AACvD,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,IAAA,CAAK,SAAA,CAAU;AAAA,QACb,IAAA,EAAM,QAAA;AAAA,QACN,MAAM,IAAA,CAAK,MAAA;AAAA,QACX,EAAA,EAAI,UAAA;AAAA,QACJ,UAAA;AAAA,QACA,OAAA;AAAA,QACA,MAAA;AAAA,QACA,UAAA,EAAA,iBAAY,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,OACpC,CAAA;AAAA,IACH;AAEA,IAAA,cAAA,CAAe,aAAA,EAAc;AAAA,EAC/B;AAAA,EAEA,MAAM,QAAA,GAAiC;AACrC,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,MAAM,YAAY,CAAC,GAAG,IAAA,CAAK,iBAAA,CAAkB,QAAQ,CAAA,CAClD,MAAA,CAAO,CAAC,MAAM,CAAC,CAAA,CAAE,QAAQ,CAAA,CACzB,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,MACX,YAAY,CAAA,CAAE,UAAA;AAAA,MACd,IAAA,EAAM,EAAE,WAAA,EAAa,CAAA,EAAG,EAAE,QAAQ,CAAA,OAAA,CAAA,EAAW,QAAA,EAAU,CAAA,CAAE,QAAA,EAAS;AAAA,MAClE,SAAS,CAAA,CAAE,OAAA;AAAA,MACX,QAAQ,CAAA,CAAE,MAAA;AAAA,MACV,MAAA,EAAQ,SAAA;AAAA,MACR,SAAA,EAAW,CAAA,CAAE,SAAA,CAAU,WAAA,EAAY;AAAA,MACnC,KAAA,EAAO,GAAA,GAAM,CAAA,CAAE,SAAA,CAAU,OAAA;AAAQ,KACnC,CAAE,CAAA;AAEJ,IAAA,OAAO,EAAE,SAAA,EAAW,UAAA,EAAY,UAAU,MAAA,EAAQ,YAAA,EAAc,UAAU,MAAA,EAAO;AAAA,EACnF;AAAA,EAEA,OAAA,GAAoB;AAClB,IAAA,OAAO;AAAA,MACL,UAAU,IAAA,CAAK,MAAA;AAAA,MACf,IAAA,EAAM,MAAA;AAAA,MACN,cAAA,EAAgB,CAAC,GAAG,IAAA,CAAK,cAAc;AAAA,KACzC;AAAA,EACF;AAAA,EAEA,UAAA,GAA6B;AAC3B,IAAA,MAAM,UAA0B,EAAC;AAEjC,IAAA,KAAA,MAAW,CAAC,UAAA,EAAY,IAAI,CAAA,IAAK,KAAK,aAAA,EAAe;AACnD,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,eAAA,CAAgB,GAAA,CAAI,UAAU,CAAA;AAClD,MAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,QACX,SAAA,EAAW,MAAA;AAAA,QACX,UAAA;AAAA,QACA,MAAM,IAAA,CAAK,MAAA;AAAA,QACX,UAAU,IAAA,CAAK,OAAA;AAAA,QACf,QAAQ,MAAA,EAAQ,OAAA;AAAA,QAChB,SAAS,IAAA,CAAK,OAAA;AAAA,QACd,YAAY,MAAA,EAAQ;AAAA,OACrB,CAAA;AAAA,IACH;AAEA,IAAA,KAAA,MAAW,CAAC,UAAA,EAAY,QAAQ,CAAA,IAAK,KAAK,iBAAA,EAAmB;AAC3D,MAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,QACX,SAAA,EAAW,UAAA;AAAA,QACX,UAAA;AAAA,QACA,MAAM,QAAA,CAAS,QAAA;AAAA,QACf,UAAU,QAAA,CAAS,OAAA;AAAA,QACnB,MAAA,EAAQ,QAAA,CAAS,QAAA,GAAW,QAAA,CAAS,aAAA,GAAgB,MAAA;AAAA,QACrD,OAAA,EAAS,QAAA,CAAS,SAAA,CAAU,WAAA,EAAY;AAAA,QACxC,YAAY,QAAA,CAAS,QAAA,GAAA,qBAAe,IAAA,EAAK,EAAE,aAAY,GAAI;AAAA,OAC5D,CAAA;AAAA,IACH;AAEA,IAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,OAAA,CAAQ,aAAA,CAAc,CAAA,CAAE,OAAO,CAAC,CAAA;AAAA,EAClE;AAAA,EAEA,MAAM,UAAA,GAA4B;AAChC,IAAA,IAAI,KAAK,cAAA,EAAgB;AACvB,MAAA,YAAA,CAAa,KAAK,cAAc,CAAA;AAChC,MAAA,IAAA,CAAK,cAAA,GAAiB,IAAA;AAAA,IACxB;AACA,IAAA,IAAA,CAAK,IAAI,KAAA,EAAM;AACf,IAAA,IAAA,CAAK,EAAA,GAAK,IAAA;AAAA,EACZ;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,eAAA,GAAiC;AAC7C,IAAA,MAAM,EAAA,GAAK,IAAI,SAAA,CAAU,IAAA,CAAK,SAAS,CAAA;AACvC,IAAA,IAAA,CAAK,EAAA,GAAK,EAAA;AAEV,IAAA,EAAA,CAAG,EAAA,CAAG,SAAA,EAAW,CAAC,IAAA,KAAS;AACzB,MAAA,IAAI;AACF,QAAA,MAAM,GAAA,GAAM,KAAA,CAAM,IAAA,CAAK,QAAA,EAAU,CAAA;AACjC,QAAA,IAAA,CAAK,cAAc,GAAG,CAAA;AAAA,MACxB,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF,CAAC,CAAA;AAED,IAAA,EAAA,CAAG,EAAA,CAAG,SAAS,MAAM;AACnB,MAAA,IAAA,CAAK,eAAe,KAAA,EAAM;AAC1B,MAAA,IAAA,CAAK,iBAAA,EAAkB;AAAA,IACzB,CAAC,CAAA;AAED,IAAA,EAAA,CAAG,EAAA,CAAG,OAAA,EAAS,CAAC,GAAA,KAAQ;AACtB,MAAA,OAAA,CAAQ,KAAA,CAAM,qBAAA,EAAuB,GAAA,CAAI,OAAO,CAAA;AAAA,IAClD,CAAC,CAAA;AAED,IAAA,MAAM,IAAI,OAAA,CAAc,CAAC,OAAA,EAAS,MAAA,KAAW;AAC3C,MAAA,MAAM,OAAA,GAAU,UAAA;AAAA,QACd,MAAM,OAAO,IAAI,KAAA,CAAM,4BAA4B,IAAA,CAAK,SAAS,EAAE,CAAC,CAAA;AAAA,QACpE;AAAA,OACF;AACA,MAAA,EAAA,CAAG,EAAA,CAAG,QAAQ,MAAM;AAClB,QAAA,YAAA,CAAa,OAAO,CAAA;AACpB,QAAA,EAAA,CAAG,IAAA,CAAK,UAAU,EAAE,IAAA,EAAM,SAAS,IAAA,EAAM,IAAA,CAAK,MAAA,EAAQ,CAAC,CAAA;AACvD,QAAA,OAAA,EAAQ;AAAA,MACV,CAAC,CAAA;AACD,MAAA,EAAA,CAAG,EAAA,CAAG,OAAA,EAAS,CAAC,GAAA,KAAQ;AACtB,QAAA,YAAA,CAAa,OAAO,CAAA;AACpB,QAAA,MAAA,CAAO,GAAG,CAAA;AAAA,MACZ,CAAC,CAAA;AAAA,IACH,CAAC,CAAA;AAED,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,eAAA;AAAA,MACrB,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,WAAA;AAAA,MAClB;AAAA,KACF;AAEA,IAAA,KAAA,MAAW,QAAQ,GAAA,CAAI,KAAA,EAAO,IAAA,CAAK,cAAA,CAAe,IAAI,IAAI,CAAA;AAC1D,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,2BAAA,EAA8B,IAAA,CAAK,MAAM,CAAA,WAAA,EAAc,IAAI,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAG,CAAA;AAAA,EAC9F;AAAA,EAEQ,iBAAA,GAA0B;AAChC,IAAA,IAAI,KAAK,cAAA,EAAgB;AACzB,IAAA,IAAA,CAAK,cAAA,GAAiB,WAAW,YAAY;AAC3C,MAAA,IAAA,CAAK,cAAA,GAAiB,IAAA;AACtB,MAAA,IAAI;AACF,QAAA,MAAM,KAAK,eAAA,EAAgB;AAC3B,QAAA,OAAA,CAAQ,MAAM,iCAAiC,CAAA;AAAA,MACjD,SAAS,GAAA,EAAK;AACZ,QAAA,MAAM,MAAM,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC3D,QAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,+BAAA,EAAkC,GAAG,CAAA,mBAAA,CAAqB,CAAA;AACxE,QAAA,IAAA,CAAK,iBAAA,EAAkB;AAAA,MACzB;AAAA,IACF,GAAG,GAAI,CAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAMQ,cAAc,GAAA,EAAmB;AACvC,IAAA,KAAA,MAAW,OAAA,IAAW,IAAA,CAAK,eAAA,EAAiB,OAAA,CAAQ,GAAG,CAAA;AAEvD,IAAA,QAAQ,IAAI,IAAA;AAAM,MAChB,KAAK,aAAA;AACH,QAAA,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,GAAA,CAAI,IAAI,CAAA;AAChC,QAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,0BAAA,EAA6B,GAAA,CAAI,IAAI,CAAA,CAAE,CAAA;AACrD,QAAA;AAAA,MAEF,KAAK,WAAA;AACH,QAAA,IAAA,CAAK,cAAA,CAAe,MAAA,CAAO,GAAA,CAAI,IAAI,CAAA;AACnC,QAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,wBAAA,EAA2B,GAAA,CAAI,IAAI,CAAA,CAAE,CAAA;AACnD,QAAA;AAAA,MAEF,KAAK,KAAA;AACH,QAAA,IAAA,CAAK,kBAAkB,GAAG,CAAA;AAC1B,QAAA;AAAA,MAEF,KAAK,YAAA;AACH,QAAA,IAAA,CAAK,gBAAgB,GAAG,CAAA;AACxB,QAAA;AAAA,MAEF,KAAK,QAAA;AACH,QAAA,IAAI,CAAC,IAAA,CAAK,eAAA,CAAgB,GAAA,CAAI,GAAA,CAAI,UAAU,CAAA,EAAG;AAC7C,UAAA,IAAA,CAAK,eAAA,CAAgB,GAAA,CAAI,GAAA,CAAI,UAAA,EAAY;AAAA,YACvC,SAAS,GAAA,CAAI,OAAA;AAAA,YACb,QAAQ,GAAA,CAAI,MAAA;AAAA,YACZ,YAAY,GAAA,CAAI,UAAA;AAAA,YAChB,UAAU,GAAA,CAAI;AAAA,WACf,CAAA;AAAA,QACH;AACA,QAAA;AAAA,MAEF,KAAK,WAAA;AACH,QAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,wBAAA,EAA2B,GAAA,CAAI,OAAO,CAAA,CAAE,CAAA;AACtD,QAAA;AAAA;AACJ,EACF;AAAA,EAEQ,kBAAkB,GAAA,EAAmB;AAC3C,IAAA,IAAA,CAAK,gBAAA,CAAiB,GAAA,CAAI,GAAA,CAAI,UAAA,EAAY,IAAI,IAAI,CAAA;AAElD,IAAA,IAAA,CAAK,iBAAA,CAAkB,GAAA,CAAI,GAAA,CAAI,UAAA,EAAY;AAAA,MACzC,YAAY,GAAA,CAAI,UAAA;AAAA,MAChB,UAAU,GAAA,CAAI,IAAA;AAAA,MACd,SAAS,GAAA,CAAI,OAAA;AAAA,MACb,QAAQ,GAAA,CAAI,MAAA;AAAA,MACZ,SAAA,sBAAe,IAAA,EAAK;AAAA,MACpB,QAAA,EAAU;AAAA,KACX,CAAA;AAED,IAAA,cAAA,CAAe,OAAA,CAAQ;AAAA,MACrB,YAAY,GAAA,CAAI,UAAA;AAAA,MAChB,IAAA,EAAM,EAAE,WAAA,EAAa,CAAA,EAAG,IAAI,IAAI,CAAA,OAAA,CAAA,EAAW,QAAA,EAAU,GAAA,CAAI,IAAA,EAAK;AAAA,MAC9D,SAAS,GAAA,CAAI,OAAA;AAAA,MACb,QAAQ,GAAA,CAAI,MAAA;AAAA,MACZ,MAAA,EAAQ,SAAA;AAAA,MACR,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,MAClC,KAAA,EAAO;AAAA,KACR,CAAA;AAAA,EACH;AAAA,EAEQ,gBAAgB,GAAA,EAAyB;AAC/C,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,iBAAA,CAAkB,GAAA,CAAI,IAAI,UAAU,CAAA;AAE1D,IAAA,IAAI,CAAC,UAAU,QAAA,EAAU;AACvB,MAAA,IAAA,CAAK,SAAA,CAAU;AAAA,QACb,IAAA,EAAM,gBAAA;AAAA,QACN,IAAI,GAAA,CAAI,IAAA;AAAA,QACR,YAAY,GAAA,CAAI,UAAA;AAAA,QAChB,WAAW,GAAA,CAAI;AAAA,OAChB,CAAA;AACD,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,SAAA,CAAU;AAAA,MACb,IAAA,EAAM,QAAA;AAAA,MACN,MAAM,IAAA,CAAK,MAAA;AAAA,MACX,IAAI,GAAA,CAAI,IAAA;AAAA,MACR,YAAY,GAAA,CAAI,UAAA;AAAA,MAChB,SAAS,QAAA,CAAS,aAAA;AAAA,MAClB,QAAQ,QAAA,CAAS,YAAA;AAAA,MACjB,UAAA,EAAA,iBAAY,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,MACnC,WAAW,GAAA,CAAI;AAAA,KAChB,CAAA;AAAA,EACH;AAAA,EAEQ,UAAU,GAAA,EAAmB;AACnC,IAAA,IAAI,CAAC,IAAA,CAAK,EAAA,IAAM,KAAK,EAAA,CAAG,UAAA,KAAe,UAAU,IAAA,EAAM;AACrD,MAAA,MAAM,IAAI,MAAM,iDAAiD,CAAA;AAAA,IACnE;AACA,IAAA,IAAA,CAAK,EAAA,CAAG,IAAA,CAAK,SAAA,CAAU,GAAG,CAAC,CAAA;AAAA,EAC7B;AAAA,EAEQ,eAAA,CACN,QACA,SAAA,EACY;AACZ,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,MAAA,MAAM,OAAA,GAAU,WAAW,MAAM;AAC/B,QAAA,IAAA,CAAK,eAAA,CAAgB,OAAO,OAAO,CAAA;AACnC,QAAA,MAAA,CAAO,IAAI,KAAA,CAAM,uBAAuB,CAAC,CAAA;AAAA,MAC3C,GAAG,SAAS,CAAA;AAEZ,MAAA,MAAM,OAAA,GAAU,CAAC,GAAA,KAAsB;AACrC,QAAA,IAAI,MAAA,CAAO,GAAG,CAAA,EAAG;AACf,UAAA,YAAA,CAAa,OAAO,CAAA;AACpB,UAAA,IAAA,CAAK,eAAA,CAAgB,OAAO,OAAO,CAAA;AACnC,UAAA,OAAA,CAAQ,GAAQ,CAAA;AAAA,QAClB;AAAA,MACF,CAAA;AAEA,MAAA,IAAA,CAAK,eAAA,CAAgB,IAAI,OAAO,CAAA;AAAA,IAClC,CAAC,CAAA;AAAA,EACH;AACF,CAAA;ACjaO,IAAM,YAAN,MAAgB;AAAA,EACb,GAAA,GAA8B,IAAA;AAAA,EACrB,OAAA,uBAAc,GAAA,EAAuB;AAAA;AAAA,EACrC,QAAA,uBAAe,GAAA,EAAuB;AAAA;AAAA,EAEvD,MAAM,IAAA,EAAoB;AACxB,IAAA,IAAA,CAAK,GAAA,GAAM,IAAI,eAAA,CAAgB,EAAE,MAAM,CAAA;AAEvC,IAAA,IAAA,CAAK,GAAA,CAAI,EAAA,CAAG,WAAA,EAAa,MAAM;AAC7B,MAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,kCAAA,EAAqC,IAAI,CAAA,CAAE,CAAA;AACvD,MAAA,OAAA,CAAQ,IAAI,wBAAwB,CAAA;AAAA,IACtC,CAAC,CAAA;AAED,IAAA,IAAA,CAAK,GAAA,CAAI,EAAA,CAAG,YAAA,EAAc,CAAC,EAAA,KAAO;AAChC,MAAA,EAAA,CAAG,EAAA,CAAG,SAAA,EAAW,CAAC,IAAA,KAAS;AACzB,QAAA,IAAI;AACF,UAAA,MAAM,GAAA,GAAM,KAAA,CAAM,IAAA,CAAK,QAAA,EAAU,CAAA;AACjC,UAAA,IAAA,CAAK,aAAA,CAAc,IAAI,GAAG,CAAA;AAAA,QAC5B,CAAA,CAAA,MAAQ;AAAA,QAER;AAAA,MACF,CAAC,CAAA;AAED,MAAA,EAAA,CAAG,EAAA,CAAG,SAAS,MAAM;AACnB,QAAA,MAAM,IAAA,GAAO,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,EAAE,CAAA;AACjC,QAAA,IAAI,IAAA,EAAM;AACR,UAAA,IAAA,CAAK,OAAA,CAAQ,OAAO,IAAI,CAAA;AACxB,UAAA,IAAA,CAAK,QAAA,CAAS,OAAO,EAAE,CAAA;AACvB,UAAA,IAAA,CAAK,SAAA,CAAU,EAAE,IAAA,EAAM,WAAA,EAAa,MAAM,CAAA;AAC1C,UAAA,OAAA,CAAQ,IAAI,CAAA,OAAA,EAAK,IAAI,WAAW,IAAA,CAAK,OAAA,CAAQ,IAAI,CAAA,SAAA,EAAY,CAAC,GAAG,IAAA,CAAK,OAAA,CAAQ,MAAM,CAAA,CAAE,KAAK,IAAI,CAAA,IAAK,MAAM,CAAA,CAAA,CAAG,CAAA;AAAA,QAC/G;AAAA,MACF,CAAC,CAAA;AAED,MAAA,EAAA,CAAG,EAAA,CAAG,OAAA,EAAS,CAAC,GAAA,KAAQ;AACtB,QAAA,OAAA,CAAQ,KAAA,CAAM,iBAAA,EAAmB,GAAA,CAAI,OAAO,CAAA;AAAA,MAC9C,CAAC,CAAA;AAAA,IACH,CAAC,CAAA;AAED,IAAA,IAAA,CAAK,GAAA,CAAI,EAAA,CAAG,OAAA,EAAS,CAAC,GAAA,KAAQ;AAC5B,MAAA,OAAA,CAAQ,KAAA,CAAM,qBAAA,EAAuB,GAAA,CAAI,OAAO,CAAA;AAAA,IAClD,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,IAAA,GAAa;AACX,IAAA,IAAI,CAAC,KAAK,GAAA,EAAK;AACf,IAAA,KAAA,MAAW,MAAM,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAO,KAAM,SAAA,EAAU;AACrD,IAAA,IAAA,CAAK,QAAQ,KAAA,EAAM;AACnB,IAAA,IAAA,CAAK,SAAS,KAAA,EAAM;AACpB,IAAA,IAAA,CAAK,IAAI,KAAA,EAAM;AACf,IAAA,IAAA,CAAK,GAAA,GAAM,IAAA;AACX,IAAA,OAAA,CAAQ,IAAI,2BAA2B,CAAA;AAAA,EACzC;AAAA,EAEQ,aAAA,CAAc,IAAe,GAAA,EAAmB;AACtD,IAAA,QAAQ,IAAI,IAAA;AAAM,MAChB,KAAK,OAAA,EAAS;AACZ,QAAA,MAAM,QAAA,GAAW,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,IAAI,IAAI,CAAA;AAC1C,QAAA,MAAM,WAAA,GAAc,QAAA,IAAY,IAAA,IAAQ,QAAA,KAAa,EAAA;AAErD,QAAA,IAAI,WAAA,EAAa;AAEf,UAAA,IAAA,CAAK,QAAA,CAAS,OAAO,QAAS,CAAA;AAC9B,UAAA,QAAA,CAAU,KAAA,EAAM;AAAA,QAClB;AAEA,QAAA,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,IAAA,EAAM,EAAE,CAAA;AAC7B,QAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,EAAA,EAAI,GAAA,CAAI,IAAI,CAAA;AAE9B,QAAA,MAAM,KAAA,GAAQ,CAAC,GAAG,IAAA,CAAK,OAAA,CAAQ,IAAA,EAAM,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,KAAM,IAAI,IAAI,CAAA;AACnE,QAAA,MAAM,GAAA,GAAmB,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAM;AACpD,QAAA,IAAA,CAAK,IAAA,CAAK,IAAI,GAAG,CAAA;AAEjB,QAAA,IAAI,CAAC,WAAA,EAAa;AAChB,UAAA,IAAA,CAAK,SAAA,CAAU,EAAE,IAAA,EAAM,aAAA,EAAe,MAAM,GAAA,CAAI,IAAA,IAAQ,EAAE,CAAA;AAAA,QAC5D;AAEA,QAAA,OAAA,CAAQ,IAAI,CAAA,OAAA,EAAK,GAAA,CAAI,IAAI,CAAA,SAAA,EAAY,IAAA,CAAK,QAAQ,IAAI,CAAA,SAAA,EAAY,CAAC,GAAG,IAAA,CAAK,QAAQ,IAAA,EAAM,EAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAG,CAAA;AACxG,QAAA;AAAA,MACF;AAAA,MAEA,KAAK,KAAA,EAAO;AACV,QAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,IAAI,EAAE,CAAA;AACtC,QAAA,IAAI,CAAC,MAAA,EAAQ;AACX,UAAA,MAAM,GAAA,GAAmB;AAAA,YACvB,IAAA,EAAM,WAAA;AAAA,YACN,IAAA,EAAM,gBAAA;AAAA,YACN,OAAA,EAAS,CAAA,CAAA,EAAI,GAAA,CAAI,EAAE,CAAA,6BAAA;AAAA,WACrB;AACA,UAAA,IAAA,CAAK,IAAA,CAAK,IAAI,GAAG,CAAA;AACjB,UAAA;AAAA,QACF;AACA,QAAA,IAAA,CAAK,IAAA,CAAK,QAAQ,GAAG,CAAA;AACrB,QAAA,MAAM,GAAA,GAAiB,EAAE,IAAA,EAAM,SAAA,EAAW,YAAY,GAAA,CAAI,UAAA,EAAY,SAAA,EAAW,GAAA,CAAI,SAAA,EAAU;AAC/F,QAAA,IAAA,CAAK,IAAA,CAAK,IAAI,GAAG,CAAA;AACjB,QAAA;AAAA,MACF;AAAA,MAEA,KAAK,YAAA,EAAc;AACjB,QAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,IAAI,EAAE,CAAA;AACtC,QAAA,IAAI,CAAC,MAAA,EAAQ;AACX,UAAA,IAAA,CAAK,IAAA,CAAK,EAAA,EAAI,EAAE,IAAA,EAAM,kBAAkB,EAAA,EAAI,GAAA,CAAI,IAAA,EAAM,UAAA,EAAY,GAAA,CAAI,UAAA,EAAY,SAAA,EAAW,GAAA,CAAI,WAAW,CAAA;AAC5G,UAAA;AAAA,QACF;AACA,QAAA,IAAA,CAAK,IAAA,CAAK,QAAQ,GAAG,CAAA;AACrB,QAAA;AAAA,MACF;AAAA,MAEA,KAAK,QAAA;AAAA,MACL,KAAK,gBAAA,EAAkB;AACrB,QAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,IAAI,EAAE,CAAA;AACtC,QAAA,IAAI,MAAA,EAAQ,IAAA,CAAK,IAAA,CAAK,MAAA,EAAQ,GAAG,CAAA;AACjC,QAAA;AAAA,MACF;AAAA;AAGF,EACF;AAAA,EAEQ,IAAA,CAAK,IAAe,GAAA,EAAmB;AAC7C,IAAA,IAAI,EAAA,CAAG,UAAA,KAAeC,SAAAA,CAAU,IAAA,EAAM;AACpC,MAAA,EAAA,CAAG,IAAA,CAAK,SAAA,CAAU,GAAG,CAAC,CAAA;AAAA,IACxB;AAAA,EACF;AAAA,EAEQ,SAAA,CAAU,KAAa,MAAA,EAA0B;AACvD,IAAA,KAAA,MAAW,EAAA,IAAM,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAO,EAAG;AACtC,MAAA,IAAI,EAAA,KAAO,MAAA,EAAQ,IAAA,CAAK,IAAA,CAAK,IAAI,GAAG,CAAA;AAAA,IACtC;AAAA,EACF;AACF,CAAA;AC1IA,IAAM,YAAA,GAAe,eAAA;AAEd,IAAM,iBAAN,MAAqB;AAAA,EAClB,OAAA,GAA0B,IAAA;AAAA,EAElC,MAAM,IAAA,EAAoB;AACxB,IAAA,IAAA,CAAK,OAAA,GAAU,IAAI,OAAA,EAAQ;AAC3B,IAAA,IAAA,CAAK,OAAA,CAAQ,QAAQ,EAAE,IAAA,EAAM,qBAAqB,IAAA,EAAM,YAAA,EAAc,MAAM,CAAA;AAC5E,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,+BAAA,EAAkC,IAAI,CAAA,CAAE,CAAA;AAAA,EACxD;AAAA,EAEA,IAAA,GAAa;AACX,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AACnB,IAAA,IAAA,CAAK,OAAA,CAAQ,aAAa,MAAM;AAC9B,MAAA,IAAA,CAAK,SAAS,OAAA,EAAQ;AAAA,IACxB,CAAC,CAAA;AACD,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AACf,IAAA,OAAA,CAAQ,MAAM,4BAA4B,CAAA;AAAA,EAC5C;AACF,CAAA;;;AChBO,IAAM,aAAN,MAAiB;AAAA,EACd,SAAA,GAA8B,IAAA;AAAA,EAC9B,UAAA,GAAoC,IAAA;AAAA,EACpC,WAAA,GAA6B,IAAA;AAAA,EAErC,IAAI,SAAA,GAAqB;AACvB,IAAA,OAAO,KAAK,SAAA,KAAc,IAAA;AAAA,EAC5B;AAAA,EAEA,IAAI,IAAA,GAAsB;AACxB,IAAA,OAAO,IAAA,CAAK,WAAA;AAAA,EACd;AAAA,EAEA,MAAM,MAAM,IAAA,EAA6B;AACvC,IAAA,IAAI,IAAA,CAAK,SAAA,EAAW,MAAM,IAAI,MAAM,wBAAwB,CAAA;AAE5D,IAAA,MAAM,MAAA,GAAS,IAAI,SAAA,EAAU;AAC7B,IAAA,MAAA,CAAO,MAAM,IAAI,CAAA;AACjB,IAAA,IAAA,CAAK,SAAA,GAAY,MAAA;AACjB,IAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AAGnB,IAAA,MAAM,gBAAgB,IAAI,CAAA;AAG1B,IAAA,MAAM,UAAA,GAAa,IAAI,cAAA,EAAe;AACtC,IAAA,UAAA,CAAW,MAAM,IAAI,CAAA;AACrB,IAAA,IAAA,CAAK,UAAA,GAAa,UAAA;AAAA,EACpB;AAAA,EAEA,MAAM,IAAA,GAAsB;AAC1B,IAAA,IAAI,CAAC,IAAA,CAAK,SAAA,EAAW,MAAM,IAAI,MAAM,oBAAoB,CAAA;AAEzD,IAAA,IAAI,KAAK,UAAA,EAAY;AACnB,MAAA,IAAA,CAAK,WAAW,IAAA,EAAK;AACrB,MAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAAA,IACpB;AAEA,IAAA,MAAM,OAAO,IAAA,CAAK,WAAA;AAClB,IAAA,IAAA,CAAK,UAAW,IAAA,EAAK;AACrB,IAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AACjB,IAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AAGnB,IAAA,MAAM,mBAAmB,IAAI,CAAA;AAAA,EAC/B;AACF,CAAA;AAMA,SAAS,YAAY,SAAA,EAAkC;AACrD,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AAEtC,IAAA,MAAM,EAAA,GAAK,MAAM,YAAA,EAAc;AAAA,MAC7B,YAAA;AAAA,MACA,UAAA;AAAA,MACA,kDAAkD,SAAS,CAAA,mBAAA;AAAA,KAC5D,CAAA;AAED,IAAA,EAAA,CAAG,EAAA,CAAG,OAAA,EAAS,CAAC,IAAA,KAAS;AACvB,MAAA,IAAI,IAAA,KAAS,GAAG,OAAA,EAAQ;AAAA,kBACZ,IAAI,KAAA,CAAM,CAAA,mCAAA,EAAsC,IAAI,4CAA4C,CAAC,CAAA;AAAA,IAC/G,CAAC,CAAA;AAED,IAAA,EAAA,CAAG,EAAA,CAAG,OAAA,EAAS,CAAC,GAAA,KAAQ;AACtB,MAAA,MAAA,CAAO,IAAI,KAAA,CAAM,CAAA,oDAAA,EAAuD,GAAA,CAAI,OAAO,EAAE,CAAC,CAAA;AAAA,IACxF,CAAC,CAAA;AAAA,EACH,CAAC,CAAA;AACH;AAEA,eAAe,gBAAgB,IAAA,EAA6B;AAC1D,EAAA,MAAM,WAAA;AAAA,IACJ,CAAA,kDAAA,EAAqD,IAAI,CAAA,gCAAA,EAAmC,IAAI,CAAA,aAAA;AAAA,GAClG;AACF;AAEA,eAAe,mBAAmB,IAAA,EAA6B;AAC7D,EAAA,MAAM,WAAA;AAAA,IACJ,wDAAwD,IAAI,CAAA,CAAA;AAAA,GAC9D;AACF;AC/EA,IAAM,SAAA,GAAY;AAAA,EAChB,IAAA,EAAM,CAAA,CAAE,MAAA,EAAO,CAAE,SAAS,oDAAoD,CAAA;AAAA,EAC9E,QAAA,EAAU,CAAA,CAAE,MAAA,EAAO,CAAE,SAAS,yCAAyC;AACzE,CAAA;AAKO,SAAS,eAAA,CAAgB,QAAmB,MAAA,EAA6B;AAC9E,EAAA,MAAA,CAAO,IAAA,CAAK,KAAA,EAAO,SAAA,EAAW,OAAO,IAAA,KAAS;AAC5C,IAAA,MAAM,aAAa,IAAA,CAAK,IAAA;AACxB,IAAA,MAAM,WAAW,IAAA,CAAK,QAAA;AAEtB,IAAA,IAAI;AACF,MAAA,IAAI,CAAC,OAAO,aAAA,EAAe;AACzB,QAAA,OAAO;AAAA,UACL,OAAA,EAAS;AAAA,YACP;AAAA,cACE,IAAA,EAAM,MAAA;AAAA,cACN,IAAA,EAAM;AAAA;AACR,WACF;AAAA,UACA,OAAA,EAAS;AAAA,SACX;AAAA,MACF;AAEA,MAAA,MAAM,aAAa,MAAM,MAAA,CAAO,GAAA,CAAI,UAAA,EAAY,UAAU,UAAU,CAAA;AAGpE,MAAA,MAAM,gBAAA,GAAmB,GAAA;AACzB,MAAA,MAAM,WAAA,GAAc,IAAI,EAAA,GAAK,GAAA;AAC7B,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,EAAI,GAAI,WAAA;AAE9B,MAAA,OAAO,IAAA,CAAK,GAAA,EAAI,GAAI,QAAA,EAAU;AAC5B,QAAA,MAAM,IAAI,OAAA,CAAQ,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,gBAAgB,CAAC,CAAA;AACpE,QAAA,MAAM,MAAA,GAAS,MAAM,MAAA,CAAO,WAAA,CAAY,UAAU,CAAA;AAClD,QAAA,IAAI,WAAW,IAAA,EAAM;AACnB,UAAA,OAAO;AAAA,YACL,OAAA,EAAS;AAAA,cACP;AAAA,gBACE,IAAA,EAAM,MAAA;AAAA,gBACN,IAAA,EAAM,KAAK,MAAA,CAAO,IAAA,CAAK,WAAW,CAAA,EAAA,EAAK,MAAA,CAAO,KAAK,QAAQ,CAAA;;AAAA,EAAqB,OAAO,OAAO,CAAA;AAAA;AAChG;AACF,WACF;AAAA,QACF;AAAA,MACF;AAGA,MAAA,OAAO;AAAA,QACL,OAAA,EAAS;AAAA,UACP;AAAA,YACE,IAAA,EAAM,MAAA;AAAA,YACN,IAAA,EAAM,CAAA;AAAA,eAAA,EAAwE,UAAU,CAAA;;AAAA,+DAAA;AAAA;AAC1F;AACF,OACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,YAAA,GAAe,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,eAAA;AAC9D,MAAA,OAAO;AAAA,QACL,OAAA,EAAS;AAAA,UACP;AAAA,YACE,IAAA,EAAM,MAAA;AAAA,YACN,IAAA,EAAM,4BAA4B,YAAY,CAAA;AAAA;AAChD,SACF;AAAA,QACA,OAAA,EAAS;AAAA,OACX;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AACH;ACtEA,IAAM,WAAA,GAAc;AAAA,EAClB,UAAA,EAAYC,CAAAA,CAAE,MAAA,EAAO,CAAE,SAAS,iDAAiD,CAAA;AAAA,EACjF,MAAA,EAAQA,CAAAA,CAAE,MAAA,EAAO,CAAE,SAAS,iDAAiD;AAC/E,CAAA;AAKO,SAAS,iBAAA,CAAkB,QAAmB,MAAA,EAA6B;AAChF,EAAA,MAAA,CAAO,IAAA,CAAK,OAAA,EAAS,WAAA,EAAa,OAAO,IAAA,KAAS;AAChD,IAAA,MAAM,aAAa,IAAA,CAAK,UAAA;AACxB,IAAA,MAAM,SAAS,IAAA,CAAK,MAAA;AAEpB,IAAA,IAAI;AACF,MAAA,IAAI,CAAC,OAAO,aAAA,EAAe;AACzB,QAAA,OAAO;AAAA,UACL,OAAA,EAAS;AAAA,YACP;AAAA,cACE,IAAA,EAAM,MAAA;AAAA,cACN,IAAA,EAAM;AAAA;AACR,WACF;AAAA,UACA,OAAA,EAAS;AAAA,SACX;AAAA,MACF;AAEA,MAAA,MAAM,MAAA,CAAO,KAAA,CAAM,UAAA,EAAY,MAAA,EAAQ,UAAU,CAAA;AAGjD,MAAA,cAAA,CAAe,aAAA,EAAc;AAE7B,MAAA,OAAO;AAAA,QACL,OAAA,EAAS;AAAA,UACP;AAAA,YACE,IAAA,EAAM,MAAA;AAAA,YACN,IAAA,EAAM,yCAAyC,UAAU,CAAA,GAAA;AAAA;AAC3D;AACF,OACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,YAAA,GAAe,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,eAAA;AAC9D,MAAA,OAAO;AAAA,QACL,OAAA,EAAS;AAAA,UACP;AAAA,YACE,IAAA,EAAM,MAAA;AAAA,YACN,IAAA,EAAM,yBAAyB,YAAY,CAAA;AAAA;AAC7C,SACF;AAAA,QACA,OAAA,EAAS;AAAA,OACX;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AACH;;;ACzDO,SAAS,iBAAA,CAAkB,QAAmB,MAAA,EAA6B;AAChF,EAAA,MAAA,CAAO,IAAA,CAAK,OAAA,EAAS,EAAC,EAAG,YAAY;AACnC,IAAA,MAAM,IAAA,GAAO,OAAO,OAAA,EAAQ;AAC5B,IAAA,MAAM,MAAA,GAAS,KAAK,QAAA,IAAY,eAAA;AAChC,IAAA,MAAM,YAAY,IAAA,CAAK,cAAA;AAEvB,IAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG;AAC1B,MAAA,OAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,IAAA,EAAM,MAAA;AAAA,UACN,IAAA,EAAM,YAAY,MAAM,CAAA,sFAAA;AAAA,SACzB;AAAA,OACH;AAAA,IACF;AAEA,IAAA,MAAM,IAAA,GAAO,SAAA,CAAU,GAAA,CAAI,CAAC,IAAA,KAAS,YAAO,IAAI,CAAA,CAAE,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AAC7D,IAAA,OAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,IAAA,EAAM,MAAA;AAAA,QACN,IAAA,EAAM,CAAA,SAAA,EAAY,MAAM,CAAA,oBAAA,EAAuB,UAAU,MAAM,CAAA;AAAA,EAAO,IAAI,CAAA;AAAA,OAC3E;AAAA,KACH;AAAA,EACF,CAAC,CAAA;AACH;;;ACvBO,SAAS,mBAAA,CAAoB,QAAmB,MAAA,EAA6B;AAClF,EAAA,MAAA,CAAO,IAAA,CAAK,SAAA,EAAW,EAAC,EAAG,YAAY;AACrC,IAAA,MAAM,OAAA,GAAU,OAAO,UAAA,EAAW;AAElC,IAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,MAAA,OAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,MAAA,EAAQ,IAAA,EAAM,kCAAkC;AAAA,OACpE;AAAA,IACF;AAEA,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAM;AAC/B,MAAA,MAAM,OAAO,IAAI,IAAA,CAAK,CAAA,CAAE,OAAO,EAAE,kBAAA,EAAmB;AAEpD,MAAA,IAAI,CAAA,CAAE,cAAc,MAAA,EAAQ;AAC1B,QAAA,MAAM,UAAA,GAAa,EAAE,MAAA,GACjB,CAAA,SAAA,EAAO,EAAE,IAAI,CAAA,EAAA,EAAK,CAAA,CAAE,MAAM,CAAA,CAAA,GAC1B,CAAA,wBAAA,CAAA;AACJ,QAAA,OAAO,IAAI,IAAI,CAAA,SAAA,EAAO,EAAE,IAAI,CAAA,EAAA,EAAK,EAAE,QAAQ;AAAA,EAAK,UAAU,CAAA,CAAA;AAAA,MAC5D,CAAA,MAAO;AACL,QAAA,MAAM,aAAa,CAAA,CAAE,MAAA,GACjB,CAAA,cAAA,EAAY,CAAA,CAAE,MAAM,CAAA,CAAA,GACpB,CAAA,0BAAA,CAAA;AACJ,QAAA,OAAO,IAAI,IAAI,CAAA,SAAA,EAAO,EAAE,IAAI,CAAA,EAAA,EAAK,EAAE,QAAQ;AAAA,EAAK,UAAU,CAAA,CAAA;AAAA,MAC5D;AAAA,IACF,CAAC,CAAA;AAED,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,CAAC,EAAE,IAAA,EAAM,MAAA,EAAQ,MAAM,KAAA,CAAM,IAAA,CAAK,MAAM,CAAA,EAAG;AAAA,KACtD;AAAA,EACF,CAAC,CAAA;AACH;AC3BO,SAAS,oBAAA,CACd,MAAA,EACA,MAAA,EACA,UAAA,EACM;AACN,EAAA,MAAA,CAAO,IAAA;AAAA,IACL,WAAA;AAAA,IACA,iKAAA;AAAA,IACA,EAAE,IAAA,EAAMA,CAAAA,CAAE,MAAA,GAAS,GAAA,CAAI,IAAI,CAAA,CAAE,GAAA,CAAI,KAAK,CAAA,CAAE,QAAA,EAAS,CAAE,QAAA,CAAS,mCAAmC,CAAA,EAAE;AAAA,IACjG,OAAO,EAAE,IAAA,GAAO,IAAA,EAAK,KAAM;AACzB,MAAA,IAAI,WAAW,SAAA,EAAW;AACxB,QAAA,OAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,IAAA,EAAM,MAAA;AAAA,YACN,IAAA,EAAM,CAAA,+BAAA,EAAkC,UAAA,CAAW,IAAI,CAAA,CAAA;AAAA,WACxD;AAAA,SACH;AAAA,MACF;AAEA,MAAA,IAAI;AACF,QAAA,MAAM,UAAA,CAAW,MAAM,IAAI,CAAA;AAAA,MAC7B,SAAS,GAAA,EAAK;AACZ,QAAA,MAAM,MAAM,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC3D,QAAA,OAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,IAAA,EAAM,MAAA;AAAA,YACN,IAAA,EAAM,wBAAwB,GAAG,CAAA;AAAA,WAClC;AAAA,SACH;AAAA,MACF;AAGA,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,CAAO,YAAA,CAAa,CAAA,eAAA,EAAkB,IAAI,CAAA,CAAE,CAAA;AAAA,MACpD,SAAS,GAAA,EAAK;AACZ,QAAA,MAAM,MAAM,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC3D,QAAA,OAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,IAAA,EAAM,MAAA;AAAA,YACN,IAAA,EAAM,CAAA,oBAAA,EAAuB,IAAI,CAAA,8BAAA,EAAiC,GAAG,CAAA;AAAA,WACtE;AAAA,SACH;AAAA,MACF;AAEA,MAAA,OAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,IAAA,EAAM,MAAA;AAAA,UACN,IAAA,EAAM;AAAA,YACJ,uBAAuB,IAAI,CAAA,CAAA,CAAA;AAAA,YAC3B,sCAAsC,IAAI,CAAA,EAAA,CAAA;AAAA,YAC1C,CAAA,6EAAA,CAAA;AAAA,YACA,CAAA,6EAAA;AAAA,WACF,CAAE,KAAK,IAAI;AAAA,SACZ;AAAA,OACH;AAAA,IACF;AAAA,GACF;AACF;;;AC3DO,SAAS,mBAAA,CAAoB,QAAmB,UAAA,EAA8B;AACnF,EAAA,MAAA,CAAO,IAAA;AAAA,IACL,UAAA;AAAA,IACA,sIAAA;AAAA,IACA,EAAC;AAAA,IACD,YAAY;AACV,MAAA,IAAI,CAAC,WAAW,SAAA,EAAW;AACzB,QAAA,OAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,IAAA,EAAM,MAAA;AAAA,YACN,IAAA,EAAM;AAAA,WACP;AAAA,SACH;AAAA,MACF;AAEA,MAAA,MAAM,OAAO,UAAA,CAAW,IAAA;AAExB,MAAA,IAAI;AACF,QAAA,MAAM,WAAW,IAAA,EAAK;AAAA,MACxB,SAAS,GAAA,EAAK;AACZ,QAAA,MAAM,MAAM,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC3D,QAAA,OAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,IAAA,EAAM,MAAA;AAAA,YACN,IAAA,EAAM,uBAAuB,GAAG,CAAA;AAAA,WACjC;AAAA,SACH;AAAA,MACF;AAEA,MAAA,OAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,IAAA,EAAM,MAAA;AAAA,UACN,IAAA,EAAM;AAAA,YACJ,4BAA4B,IAAI,CAAA,EAAA,CAAA;AAAA,YAChC,wCAAwC,IAAI,CAAA,EAAA,CAAA;AAAA,YAC5C,CAAA,iCAAA;AAAA,WACF,CAAE,KAAK,IAAI;AAAA,SACZ;AAAA,OACH;AAAA,IACF;AAAA,GACF;AACF;;;AC7BO,SAAS,gBAAgB,OAAA,EAAsC;AACpE,EAAA,MAAM,EAAE,MAAA,EAAQ,UAAA,EAAW,GAAI,OAAA;AAE/B,EAAA,MAAM,MAAA,GAAS,IAAI,SAAA,CAAU;AAAA,IAC3B,IAAA,EAAM,eAAA;AAAA,IACN,OAAA,EAAS;AAAA,GACV,CAAA;AAED,EAAA,eAAA,CAAgB,QAAQ,MAAM,CAAA;AAC9B,EAAA,iBAAA,CAAkB,QAAQ,MAAM,CAAA;AAChC,EAAA,iBAAA,CAAkB,QAAQ,MAAM,CAAA;AAChC,EAAA,mBAAA,CAAoB,QAAQ,MAAM,CAAA;AAClC,EAAA,oBAAA,CAAqB,MAAA,EAAQ,QAAQ,UAAU,CAAA;AAC/C,EAAA,mBAAA,CAAoB,QAAQ,UAAU,CAAA;AAEtC,EAAA,OAAO,MAAA;AACT;AAEA,eAAsB,eAAe,OAAA,EAA0C;AAC7E,EAAA,MAAM,MAAA,GAAS,gBAAgB,OAAO,CAAA;AACtC,EAAA,MAAM,SAAA,GAAY,IAAI,oBAAA,EAAqB;AAC3C,EAAA,MAAM,MAAA,CAAO,QAAQ,SAAS,CAAA;AAChC;ACpCA,IAAMC,aAAAA,GAAe,eAAA;AAUd,SAAS,WAAA,CAAY,YAAY,GAAA,EAAqC;AAC3E,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC9B,IAAA,MAAM,OAAA,GAAU,IAAIC,OAAAA,EAAQ;AAC5B,IAAA,MAAM,UAAU,OAAA,CAAQ,IAAA,CAAK,EAAE,IAAA,EAAMD,eAAc,CAAA;AAEnD,IAAA,IAAI,OAAA,GAAU,KAAA;AAEd,IAAA,MAAM,MAAA,GAAS,CAAC,MAAA,KAAiC;AAC/C,MAAA,IAAI,OAAA,EAAS;AACb,MAAA,OAAA,GAAU,IAAA;AACV,MAAA,YAAA,CAAa,KAAK,CAAA;AAClB,MAAA,OAAA,CAAQ,IAAA,EAAK;AACb,MAAA,OAAA,CAAQ,OAAA,EAAQ;AAChB,MAAA,OAAA,CAAQ,MAAM,CAAA;AAAA,IAChB,CAAA;AAEA,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,MAAA,CAAO,IAAI,GAAG,SAAS,CAAA;AAEtD,IAAA,OAAA,CAAQ,EAAA,CAAG,IAAA,EAAM,CAAC,GAAA,KAAQ;AACxB,MAAA,MAAA,CAAO,EAAE,IAAA,EAAM,GAAA,CAAI,MAAM,IAAA,EAAM,GAAA,CAAI,MAAM,CAAA;AAAA,IAC3C,CAAC,CAAA;AAAA,EACH,CAAC,CAAA;AACH;AAMO,SAAS,YAAY,OAAA,EAAmD;AAC7E,EAAA,MAAM,OAAA,GAAU,IAAIC,OAAAA,EAAQ;AAC5B,EAAA,MAAM,UAAU,OAAA,CAAQ,IAAA,CAAK,EAAE,IAAA,EAAMD,eAAc,CAAA;AAEnD,EAAA,OAAA,CAAQ,EAAA,CAAG,IAAA,EAAM,CAAC,GAAA,KAAQ;AACxB,IAAA,OAAA,CAAQ,EAAE,IAAA,EAAM,GAAA,CAAI,MAAM,IAAA,EAAM,GAAA,CAAI,MAAM,CAAA;AAAA,EAC5C,CAAC,CAAA;AAED,EAAA,OAAO,MAAM;AACX,IAAA,OAAA,CAAQ,IAAA,EAAK;AACb,IAAA,OAAA,CAAQ,OAAA,EAAQ;AAAA,EAClB,CAAA;AACF;;;AC5CA,SAAS,OAAO,IAAA,EAAkC;AAChD,EAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,IAAA,CAAK,OAAA,CAAQ,IAAI,CAAA;AACrC,EAAA,OAAO,QAAQ,EAAA,GAAK,OAAA,CAAQ,IAAA,CAAK,GAAA,GAAM,CAAC,CAAA,GAAI,MAAA;AAC9C;AAEA,eAAe,IAAA,GAAsB;AACnC,EAAA,MAAM,IAAA,GAAO,OAAO,QAAQ,CAAA;AAC5B,EAAA,MAAM,MAAA,GAAS,OAAO,UAAU,CAAA;AAEhC,EAAA,IAAI,CAAC,IAAA,EAAM;AAAE,IAAA,OAAA,CAAQ,MAAM,oBAAoB,CAAA;AAAG,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAAG;AAEnE,EAAA,MAAM,UAAA,GAAa,IAAI,UAAA,EAAW;AAClC,EAAA,MAAM,MAAA,GAAS,IAAI,SAAA,EAAU;AAE7B,EAAA,IAAI,MAAA,EAAQ;AAEV,IAAA,MAAM,MAAM,MAAA,CAAO,UAAA,CAAW,IAAI,CAAA,GAAI,MAAA,GAAS,QAAQ,MAAM,CAAA,CAAA;AAC7D,IAAA,MAAA,CAAO,aAAa,GAAG,CAAA;AACvB,IAAA,MAAM,MAAA,CAAO,IAAA,CAAK,IAAA,EAAM,IAAI,CAAA;AAAA,EAC9B,CAAA,MAAO;AAEL,IAAA,MAAM,MAAA,CAAO,IAAA,CAAK,IAAA,EAAM,IAAI,CAAA;AAAA,EAC9B;AAIA,EAAA,MAAM,QAAA,GAAW,cAAA,CAAe,EAAE,MAAA,EAAQ,YAAY,CAAA;AAEtD,EAAA,IAAI,CAAC,MAAA,EAAQ;AAEX,IAAA,WAAA,CAAY,GAAI,CAAA,CAAE,IAAA,CAAK,OAAO,GAAA,KAAQ;AACpC,MAAA,IAAI,CAAC,GAAA,IAAO,MAAA,CAAO,WAAA,EAAa;AAChC,MAAA,IAAI;AACF,QAAA,OAAA,CAAQ,MAAM,CAAA,wBAAA,EAA2B,GAAA,CAAI,IAAI,CAAA,CAAA,EAAI,GAAA,CAAI,IAAI,CAAA,eAAA,CAAiB,CAAA;AAC9E,QAAA,MAAM,MAAA,CAAO,aAAa,CAAA,KAAA,EAAQ,GAAA,CAAI,IAAI,CAAA,CAAA,EAAI,GAAA,CAAI,IAAI,CAAA,CAAE,CAAA;AAAA,MAC1D,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF,CAAC,CAAA;AAGD,IAAA,MAAM,SAAA,GAAY,WAAA,CAAY,OAAO,GAAA,KAAQ;AAC3C,MAAA,IAAI,OAAO,WAAA,EAAa;AAAE,QAAA,SAAA,EAAU;AAAG,QAAA;AAAA,MAAQ;AAC/C,MAAA,IAAI;AACF,QAAA,OAAA,CAAQ,MAAM,CAAA,2BAAA,EAA8B,GAAA,CAAI,IAAI,CAAA,CAAA,EAAI,GAAA,CAAI,IAAI,CAAA,eAAA,CAAiB,CAAA;AACjF,QAAA,MAAM,MAAA,CAAO,aAAa,CAAA,KAAA,EAAQ,GAAA,CAAI,IAAI,CAAA,CAAA,EAAI,GAAA,CAAI,IAAI,CAAA,CAAE,CAAA;AACxD,QAAA,SAAA,EAAU;AAAA,MACZ,SAAS,GAAA,EAAK;AACZ,QAAA,MAAM,MAAM,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC3D,QAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,gCAAA,EAAmC,GAAG,CAAA,CAAE,CAAA;AAAA,MACxD;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,QAAA;AACR;AAEA,IAAA,EAAK,CAAE,KAAA,CAAM,CAAC,KAAA,KAAU;AACtB,EAAA,OAAA,CAAQ,KAAA,CAAM,qBAAqB,KAAK,CAAA;AACxC,EAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAChB,CAAC,CAAA","file":"mcp-main.js","sourcesContent":["/**\r\n * Hub Wire Protocol\r\n * Messages exchanged between hub server and clients.\r\n * @module infrastructure/hub/hub-protocol\r\n */\r\n\r\nimport type { MessageFormat } from '../../domain/value-objects/message-content.vo.js';\r\n\r\n// Client → Hub: identify yourself\r\nexport interface HelloMsg {\r\n type: 'HELLO';\r\n name: string;\r\n}\r\n\r\n// Hub → Client: welcome + current peer list\r\nexport interface HelloAckMsg {\r\n type: 'HELLO_ACK';\r\n peers: string[];\r\n}\r\n\r\n// Hub → Client: broadcast when someone joins\r\nexport interface PeerJoinedMsg {\r\n type: 'PEER_JOINED';\r\n name: string;\r\n}\r\n\r\n// Hub → Client: broadcast when someone leaves\r\nexport interface PeerLeftMsg {\r\n type: 'PEER_LEFT';\r\n name: string;\r\n}\r\n\r\n// Client → Hub: ask a question (hub routes to `to`)\r\nexport interface AskMsg {\r\n type: 'ASK';\r\n from: string;\r\n to: string;\r\n questionId: string;\r\n requestId: string;\r\n content: string;\r\n format: MessageFormat;\r\n}\r\n\r\n// Hub → Client: question delivered acknowledgement\r\nexport interface AskAckMsg {\r\n type: 'ASK_ACK';\r\n questionId: string;\r\n requestId: string;\r\n}\r\n\r\n// Client → Hub: poll for answer (hub routes to `to`)\r\nexport interface GetAnswerMsg {\r\n type: 'GET_ANSWER';\r\n from: string;\r\n to: string;\r\n questionId: string;\r\n requestId: string;\r\n}\r\n\r\n// Client → Hub: deliver answer (hub routes to `to`)\r\nexport interface AnswerMsg {\r\n type: 'ANSWER';\r\n from: string;\r\n to: string;\r\n questionId: string;\r\n content: string;\r\n format: MessageFormat;\r\n answeredAt: string;\r\n requestId?: string;\r\n}\r\n\r\n// Client → Hub: answer not ready yet (hub routes to `to`)\r\nexport interface AnswerPendingMsg {\r\n type: 'ANSWER_PENDING';\r\n to: string;\r\n questionId: string;\r\n requestId: string;\r\n}\r\n\r\n// Hub → Client: error\r\nexport interface HubErrorMsg {\r\n type: 'HUB_ERROR';\r\n code: string;\r\n message: string;\r\n}\r\n\r\nexport type HubMsg =\r\n | HelloMsg\r\n | HelloAckMsg\r\n | PeerJoinedMsg\r\n | PeerLeftMsg\r\n | AskMsg\r\n | AskAckMsg\r\n | GetAnswerMsg\r\n | AnswerMsg\r\n | AnswerPendingMsg\r\n | HubErrorMsg;\r\n\r\nexport function serialize(msg: HubMsg): string {\r\n return JSON.stringify(msg);\r\n}\r\n\r\nexport function parse(data: string): HubMsg {\r\n return JSON.parse(data) as HubMsg;\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 * HubClient\r\n * Connects outbound to a hub server and implements ICollabClient.\r\n * No local WebSocket server — no inbound port needed.\r\n * @module infrastructure/hub/hub-client\r\n */\r\n\r\nimport { WebSocket } from 'ws';\r\nimport { v4 as uuidv4 } from 'uuid';\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 '../../domain/value-objects/message-content.vo.js';\r\nimport {\r\n type HubMsg,\r\n type HelloAckMsg,\r\n type AskAckMsg,\r\n type AskMsg,\r\n type AnswerMsg,\r\n type AnswerPendingMsg,\r\n type GetAnswerMsg,\r\n parse,\r\n serialize,\r\n} from './hub-protocol.js';\r\nimport { injectionQueue } from '../terminal-injector/injection-queue.js';\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 HubClient implements ICollabClient {\r\n private ws: WebSocket | null = null;\r\n private myName = '';\r\n private serverUrl = '';\r\n private reconnectTimer: NodeJS.Timeout | null = null;\r\n\r\n private readonly connectedPeers = new Set<string>();\r\n private readonly incomingQuestions = new Map<string, IncomingQuestion>();\r\n private readonly receivedAnswers = new Map<string, ReceivedAnswer>();\r\n private readonly questionToName = new Map<string, string>();\r\n private readonly questionToSender = new Map<string, string>();\r\n private readonly sentQuestions = new Map<string, { toPeer: string; content: string; askedAt: string }>();\r\n private readonly pendingHandlers = new Set<(msg: HubMsg) => void>();\r\n\r\n setServerUrl(url: string): void {\r\n this.serverUrl = url;\r\n }\r\n\r\n get isConnected(): boolean {\r\n return this.ws?.readyState === WebSocket.OPEN;\r\n }\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 // Only connect immediately if a server URL was already set.\r\n // If not (e.g. auto-discover mode), connection happens later via connectToHub().\r\n if (this.serverUrl) {\r\n await this.connectAndHello();\r\n }\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: 0,\r\n };\r\n }\r\n\r\n async connectToHub(url: string): Promise<void> {\r\n this.serverUrl = url;\r\n await this.connectAndHello();\r\n }\r\n\r\n async ask(toPeer: string, content: string, format: MessageFormat): Promise<string> {\r\n const questionId = uuidv4();\r\n const requestId = uuidv4();\r\n\r\n this.questionToName.set(questionId, toPeer);\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.requestId === requestId,\r\n 5000\r\n );\r\n\r\n this.sendToHub({ type: 'ASK', from: this.myName, to: toPeer, questionId, requestId, content, format });\r\n\r\n await ackPromise;\r\n return questionId;\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) {\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 const toPeer = this.questionToName.get(questionId);\r\n if (!toPeer || !this.isConnected) return null;\r\n\r\n const requestId = uuidv4();\r\n const responsePromise = this.waitForResponse<AnswerMsg | AnswerPendingMsg>(\r\n (m) =>\r\n (m.type === 'ANSWER' && m.questionId === questionId) ||\r\n (m.type === 'ANSWER_PENDING' && m.requestId === requestId),\r\n 5000\r\n );\r\n\r\n this.sendToHub({ type: 'GET_ANSWER', from: this.myName, to: toPeer, questionId, requestId });\r\n\r\n const response = await responsePromise;\r\n if (response.type === 'ANSWER_PENDING') return null;\r\n\r\n const answer = response as AnswerMsg;\r\n this.receivedAnswers.set(questionId, {\r\n content: answer.content,\r\n format: answer.format,\r\n answeredAt: answer.answeredAt,\r\n fromName: answer.from,\r\n });\r\n\r\n return {\r\n questionId,\r\n from: { displayName: `${answer.from} Claude`, teamName: answer.from },\r\n content: answer.content,\r\n format: answer.format,\r\n answeredAt: answer.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 this.sendToHub({\r\n type: 'ANSWER',\r\n from: this.myName,\r\n to: senderName,\r\n questionId,\r\n content,\r\n format,\r\n answeredAt: new Date().toISOString(),\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\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: undefined,\r\n connectedPeers: [...this.connectedPeers],\r\n };\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 answer: answer?.content,\r\n askedAt: sent.askedAt,\r\n answeredAt: answer?.answeredAt,\r\n });\r\n }\r\n\r\n for (const [questionId, incoming] of this.incomingQuestions) {\r\n entries.push({\r\n direction: 'received',\r\n questionId,\r\n peer: incoming.fromName,\r\n question: incoming.content,\r\n answer: incoming.answered ? incoming.answerContent : undefined,\r\n askedAt: incoming.createdAt.toISOString(),\r\n answeredAt: incoming.answered ? new Date().toISOString() : undefined,\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 if (this.reconnectTimer) {\r\n clearTimeout(this.reconnectTimer);\r\n this.reconnectTimer = null;\r\n }\r\n this.ws?.close();\r\n this.ws = null;\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Private: connection management\r\n // ---------------------------------------------------------------------------\r\n\r\n private async connectAndHello(): Promise<void> {\r\n const ws = new WebSocket(this.serverUrl);\r\n this.ws = ws;\r\n\r\n ws.on('message', (data) => {\r\n try {\r\n const msg = parse(data.toString());\r\n this.handleMessage(msg);\r\n } catch {\r\n // ignore malformed messages\r\n }\r\n });\r\n\r\n ws.on('close', () => {\r\n this.connectedPeers.clear();\r\n this.scheduleReconnect();\r\n });\r\n\r\n ws.on('error', (err) => {\r\n console.error('[hub-client] error:', err.message);\r\n });\r\n\r\n await new Promise<void>((resolve, reject) => {\r\n const timeout = setTimeout(\r\n () => reject(new Error(`Cannot connect to hub at ${this.serverUrl}`)),\r\n 10000\r\n );\r\n ws.on('open', () => {\r\n clearTimeout(timeout);\r\n ws.send(serialize({ type: 'HELLO', name: this.myName }));\r\n resolve();\r\n });\r\n ws.on('error', (err) => {\r\n clearTimeout(timeout);\r\n reject(err);\r\n });\r\n });\r\n\r\n const ack = await this.waitForResponse<HelloAckMsg>(\r\n (m) => m.type === 'HELLO_ACK',\r\n 10000\r\n );\r\n\r\n for (const peer of ack.peers) this.connectedPeers.add(peer);\r\n console.error(`[hub-client] connected as \"${this.myName}\", peers: [${ack.peers.join(', ')}]`);\r\n }\r\n\r\n private scheduleReconnect(): void {\r\n if (this.reconnectTimer) return;\r\n this.reconnectTimer = setTimeout(async () => {\r\n this.reconnectTimer = null;\r\n try {\r\n await this.connectAndHello();\r\n console.error('[hub-client] reconnected to hub');\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n console.error(`[hub-client] reconnect failed: ${msg}, retrying in 5s...`);\r\n this.scheduleReconnect();\r\n }\r\n }, 5000);\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Private: message handling\r\n // ---------------------------------------------------------------------------\r\n\r\n private handleMessage(msg: HubMsg): void {\r\n for (const handler of this.pendingHandlers) handler(msg);\r\n\r\n switch (msg.type) {\r\n case 'PEER_JOINED':\r\n this.connectedPeers.add(msg.name);\r\n console.error(`[hub-client] peer joined: ${msg.name}`);\r\n break;\r\n\r\n case 'PEER_LEFT':\r\n this.connectedPeers.delete(msg.name);\r\n console.error(`[hub-client] peer left: ${msg.name}`);\r\n break;\r\n\r\n case 'ASK':\r\n this.handleIncomingAsk(msg);\r\n break;\r\n\r\n case 'GET_ANSWER':\r\n this.handleGetAnswer(msg);\r\n break;\r\n\r\n case 'ANSWER':\r\n if (!this.receivedAnswers.has(msg.questionId)) {\r\n this.receivedAnswers.set(msg.questionId, {\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 break;\r\n\r\n case 'HUB_ERROR':\r\n console.error(`[hub-client] hub error: ${msg.message}`);\r\n break;\r\n }\r\n }\r\n\r\n private handleIncomingAsk(msg: AskMsg): void {\r\n this.questionToSender.set(msg.questionId, msg.from);\r\n\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 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 handleGetAnswer(msg: GetAnswerMsg): void {\r\n const question = this.incomingQuestions.get(msg.questionId);\r\n\r\n if (!question?.answered) {\r\n this.sendToHub({\r\n type: 'ANSWER_PENDING',\r\n to: msg.from,\r\n questionId: msg.questionId,\r\n requestId: msg.requestId,\r\n });\r\n return;\r\n }\r\n\r\n this.sendToHub({\r\n type: 'ANSWER',\r\n from: this.myName,\r\n to: msg.from,\r\n questionId: msg.questionId,\r\n content: question.answerContent!,\r\n format: question.answerFormat!,\r\n answeredAt: new Date().toISOString(),\r\n requestId: msg.requestId,\r\n });\r\n }\r\n\r\n private sendToHub(msg: HubMsg): void {\r\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\r\n throw new Error('Not connected to hub. Will retry automatically.');\r\n }\r\n this.ws.send(serialize(msg));\r\n }\r\n\r\n private waitForResponse<T extends HubMsg>(\r\n filter: (msg: HubMsg) => 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('Hub request timed out'));\r\n }, timeoutMs);\r\n\r\n const handler = (msg: HubMsg): 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 * HubServer\r\n * Central WebSocket server that routes messages between clients by name.\r\n * One instance runs per team — everyone else connects to it outbound.\r\n * @module infrastructure/hub/hub-server\r\n */\r\n\r\nimport { WebSocketServer, WebSocket } from 'ws';\r\nimport {\r\n type HubMsg,\r\n type HelloAckMsg,\r\n type AskAckMsg,\r\n type HubErrorMsg,\r\n parse,\r\n serialize,\r\n} from './hub-protocol.js';\r\n\r\nexport class HubServer {\r\n private wss: WebSocketServer | null = null;\r\n private readonly clients = new Map<string, WebSocket>(); // name → ws\r\n private readonly wsToName = new Map<WebSocket, string>(); // ws → name\r\n\r\n start(port: number): void {\r\n this.wss = new WebSocketServer({ port });\r\n\r\n this.wss.on('listening', () => {\r\n console.log(`claude-collab hub running on port ${port}`);\r\n console.log('Waiting for peers...\\n');\r\n });\r\n\r\n this.wss.on('connection', (ws) => {\r\n ws.on('message', (data) => {\r\n try {\r\n const msg = parse(data.toString());\r\n this.handleMessage(ws, msg);\r\n } catch {\r\n // ignore malformed messages\r\n }\r\n });\r\n\r\n ws.on('close', () => {\r\n const name = this.wsToName.get(ws);\r\n if (name) {\r\n this.clients.delete(name);\r\n this.wsToName.delete(ws);\r\n this.broadcast({ type: 'PEER_LEFT', name });\r\n console.log(`← ${name} left (${this.clients.size} online: ${[...this.clients.keys()].join(', ') || 'none'})`);\r\n }\r\n });\r\n\r\n ws.on('error', (err) => {\r\n console.error('[hub] ws error:', err.message);\r\n });\r\n });\r\n\r\n this.wss.on('error', (err) => {\r\n console.error('[hub] server error:', err.message);\r\n });\r\n }\r\n\r\n stop(): void {\r\n if (!this.wss) return;\r\n for (const ws of this.clients.values()) ws.terminate();\r\n this.clients.clear();\r\n this.wsToName.clear();\r\n this.wss.close();\r\n this.wss = null;\r\n console.log('claude-collab hub stopped');\r\n }\r\n\r\n private handleMessage(ws: WebSocket, msg: HubMsg): void {\r\n switch (msg.type) {\r\n case 'HELLO': {\r\n const existing = this.clients.get(msg.name);\r\n const isReconnect = existing != null && existing !== ws;\r\n\r\n if (isReconnect) {\r\n // Remove from tracking BEFORE closing so the close event won't broadcast PEER_LEFT\r\n this.wsToName.delete(existing!);\r\n existing!.close();\r\n }\r\n\r\n this.clients.set(msg.name, ws);\r\n this.wsToName.set(ws, msg.name);\r\n\r\n const peers = [...this.clients.keys()].filter((n) => n !== msg.name);\r\n const ack: HelloAckMsg = { type: 'HELLO_ACK', peers };\r\n this.send(ws, ack);\r\n\r\n if (!isReconnect) {\r\n this.broadcast({ type: 'PEER_JOINED', name: msg.name }, ws);\r\n }\r\n\r\n console.log(`→ ${msg.name} joined (${this.clients.size} online: ${[...this.clients.keys()].join(', ')})`);\r\n break;\r\n }\r\n\r\n case 'ASK': {\r\n const target = this.clients.get(msg.to);\r\n if (!target) {\r\n const err: HubErrorMsg = {\r\n type: 'HUB_ERROR',\r\n code: 'PEER_NOT_FOUND',\r\n message: `'${msg.to}' is not connected to the hub`,\r\n };\r\n this.send(ws, err);\r\n return;\r\n }\r\n this.send(target, msg);\r\n const ack: AskAckMsg = { type: 'ASK_ACK', questionId: msg.questionId, requestId: msg.requestId };\r\n this.send(ws, ack);\r\n break;\r\n }\r\n\r\n case 'GET_ANSWER': {\r\n const target = this.clients.get(msg.to);\r\n if (!target) {\r\n this.send(ws, { type: 'ANSWER_PENDING', to: msg.from, questionId: msg.questionId, requestId: msg.requestId });\r\n return;\r\n }\r\n this.send(target, msg);\r\n break;\r\n }\r\n\r\n case 'ANSWER':\r\n case 'ANSWER_PENDING': {\r\n const target = this.clients.get(msg.to);\r\n if (target) this.send(target, msg);\r\n break;\r\n }\r\n\r\n // HELLO_ACK, ASK_ACK, PEER_JOINED, PEER_LEFT, HUB_ERROR are hub→client only — ignore if received\r\n }\r\n }\r\n\r\n private send(ws: WebSocket, msg: HubMsg): void {\r\n if (ws.readyState === WebSocket.OPEN) {\r\n ws.send(serialize(msg));\r\n }\r\n }\r\n\r\n private broadcast(msg: HubMsg, except?: WebSocket): void {\r\n for (const ws of this.clients.values()) {\r\n if (ws !== except) this.send(ws, msg);\r\n }\r\n }\r\n}\r\n","/**\r\n * MdnsAdvertiser\r\n * Broadcasts the hub's presence on the LAN via mDNS so clients can auto-discover it.\r\n * @module infrastructure/mdns/mdns-advertiser\r\n */\r\n\r\nimport { Bonjour } from 'bonjour-service';\r\n\r\nconst SERVICE_TYPE = 'claude-collab';\r\n\r\nexport class MdnsAdvertiser {\r\n private bonjour: Bonjour | null = null;\r\n\r\n start(port: number): void {\r\n this.bonjour = new Bonjour();\r\n this.bonjour.publish({ name: 'claude-collab-hub', type: SERVICE_TYPE, port });\r\n console.error(`[mdns] advertising hub on port ${port}`);\r\n }\r\n\r\n stop(): void {\r\n if (!this.bonjour) return;\r\n this.bonjour.unpublishAll(() => {\r\n this.bonjour?.destroy();\r\n });\r\n this.bonjour = null;\r\n console.error('[mdns] stopped advertising');\r\n }\r\n}\r\n","/**\r\n * HubManager\r\n * Orchestrates hub lifecycle: starts/stops HubServer, manages Windows firewall rules\r\n * via UAC elevation, and controls mDNS advertising.\r\n * @module infrastructure/hub/hub-manager\r\n */\r\n\r\nimport { spawn } from 'child_process';\r\nimport { HubServer } from './hub-server.js';\r\nimport { MdnsAdvertiser } from '../mdns/mdns-advertiser.js';\r\n\r\nexport class HubManager {\r\n private hubServer: HubServer | null = null;\r\n private advertiser: MdnsAdvertiser | null = null;\r\n private currentPort: number | null = null;\r\n\r\n get isRunning(): boolean {\r\n return this.hubServer !== null;\r\n }\r\n\r\n get port(): number | null {\r\n return this.currentPort;\r\n }\r\n\r\n async start(port: number): Promise<void> {\r\n if (this.isRunning) throw new Error('Hub is already running');\r\n\r\n const server = new HubServer();\r\n server.start(port);\r\n this.hubServer = server;\r\n this.currentPort = port;\r\n\r\n // Add firewall rule (UAC prompt shown to user — one click)\r\n await addFirewallRule(port);\r\n\r\n // Advertise on LAN via mDNS\r\n const advertiser = new MdnsAdvertiser();\r\n advertiser.start(port);\r\n this.advertiser = advertiser;\r\n }\r\n\r\n async stop(): Promise<void> {\r\n if (!this.isRunning) throw new Error('Hub is not running');\r\n\r\n if (this.advertiser) {\r\n this.advertiser.stop();\r\n this.advertiser = null;\r\n }\r\n\r\n const port = this.currentPort!;\r\n this.hubServer!.stop();\r\n this.hubServer = null;\r\n this.currentPort = null;\r\n\r\n // Remove firewall rule (UAC prompt shown to user — one click)\r\n await removeFirewallRule(port);\r\n }\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Firewall helpers — elevated via UAC (PowerShell Start-Process -Verb RunAs)\r\n// ---------------------------------------------------------------------------\r\n\r\nfunction runElevated(netshArgs: string): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n // PowerShell spawns a new admin cmd process via UAC and waits for it to exit.\r\n const ps = spawn('powershell', [\r\n '-NoProfile',\r\n '-Command',\r\n `Start-Process -FilePath \"netsh\" -ArgumentList \"${netshArgs}\" -Verb RunAs -Wait`,\r\n ]);\r\n\r\n ps.on('close', (code) => {\r\n if (code === 0) resolve();\r\n else reject(new Error(`Firewall command failed (exit code ${code}). User may have cancelled the UAC prompt.`));\r\n });\r\n\r\n ps.on('error', (err) => {\r\n reject(new Error(`Failed to launch PowerShell for firewall elevation: ${err.message}`));\r\n });\r\n });\r\n}\r\n\r\nasync function addFirewallRule(port: number): Promise<void> {\r\n await runElevated(\r\n `advfirewall firewall add rule name=\"claude-collab-${port}\" protocol=TCP dir=in localport=${port} action=allow`\r\n );\r\n}\r\n\r\nasync function removeFirewallRule(port: number): Promise<void> {\r\n await runElevated(\r\n `advfirewall firewall delete rule name=\"claude-collab-${port}\"`\r\n );\r\n}\r\n","/**\r\n * Ask Tool\r\n * Sends a question to another team and returns a question ID immediately.\r\n * Use the \"check_answer\" tool with the question ID to retrieve the answer later.\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\n/**\r\n * Ask tool input schema\r\n */\r\nconst askSchema = {\r\n peer: z.string().describe('Name of the peer to ask (e.g., \"alice\", \"backend\")'),\r\n question: z.string().describe('The question to ask (supports markdown)'),\r\n};\r\n\r\n/**\r\n * Registers the ask tool with the MCP server\r\n */\r\nexport function registerAskTool(server: McpServer, client: ICollabClient): void {\r\n server.tool('ask', 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 {\r\n type: 'text',\r\n text: 'Node is not ready yet. Wait a moment and try again.',\r\n },\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 // Poll until answer arrives (max 5 minutes, every 5 seconds)\r\n const POLL_INTERVAL_MS = 5_000;\r\n const MAX_WAIT_MS = 5 * 60 * 1000;\r\n const deadline = Date.now() + MAX_WAIT_MS;\r\n\r\n while (Date.now() < deadline) {\r\n await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));\r\n const answer = await client.checkAnswer(questionId);\r\n if (answer !== null) {\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: `**${answer.from.displayName} (${answer.from.teamName}) cevapladı:**\\n\\n${answer.content}`,\r\n },\r\n ],\r\n };\r\n }\r\n }\r\n\r\n // Timed out — return question ID for manual follow-up\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: `Soru gönderildi ancak 5 dakika içinde cevap gelmedi.\\nQuestion ID: \\`${questionId}\\`\\n\\nManuel kontrol için \"check_answer\" tool'unu kullanabilirsin.`,\r\n },\r\n ],\r\n };\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: `Failed to send question: ${errorMessage}`,\r\n },\r\n ],\r\n isError: true,\r\n };\r\n }\r\n });\r\n}\r\n","/**\r\n * Reply Tool\r\n * Replies to a pending question\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\n/**\r\n * Reply tool input schema\r\n */\r\nconst replySchema = {\r\n questionId: z.string().describe('The ID of the question to reply to (from inbox)'),\r\n answer: z.string().describe('Your answer to the question (supports markdown)'),\r\n};\r\n\r\n/**\r\n * Registers the reply tool with the MCP server\r\n */\r\nexport function registerReplyTool(server: McpServer, client: ICollabClient): void {\r\n server.tool('reply', 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 {\r\n type: 'text',\r\n text: 'You must join a team first. Use the \"join\" tool to join a team.',\r\n },\r\n ],\r\n isError: true,\r\n };\r\n }\r\n\r\n await client.reply(questionId, answer, 'markdown');\r\n\r\n // Signal queue: this question is done, process next\r\n injectionQueue.notifyReplied();\r\n\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: `Reply sent successfully to question \\`${questionId}\\`.`,\r\n },\r\n ],\r\n };\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: `Failed to send reply: ${errorMessage}`,\r\n },\r\n ],\r\n isError: true,\r\n };\r\n }\r\n });\r\n}\r\n","/**\r\n * Peers Tool\r\n * Lists currently connected peers on the collaboration network.\r\n * @module presentation/mcp/tools/peers\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\nexport function registerPeersTool(server: McpServer, client: ICollabClient): void {\r\n server.tool('peers', {}, async () => {\r\n const info = client.getInfo();\r\n const myName = info.teamName ?? '(starting...)';\r\n const connected = info.connectedPeers;\r\n\r\n if (connected.length === 0) {\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `You are \"${myName}\". No peers connected yet — they will appear automatically when they come online.`,\r\n }],\r\n };\r\n }\r\n\r\n const list = connected.map((name) => ` • ${name}`).join('\\n');\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `You are \"${myName}\". Connected peers (${connected.length}):\\n${list}`,\r\n }],\r\n };\r\n });\r\n}\r\n","/**\r\n * History Tool\r\n * Shows past questions and answers from this session.\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\nexport function registerHistoryTool(server: McpServer, client: ICollabClient): void {\r\n server.tool('history', {}, 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 yet this session.' }],\r\n };\r\n }\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)`;\r\n return `[${time}] ← ${e.peer}: ${e.question}\\n${answerLine}`;\r\n }\r\n });\r\n\r\n return {\r\n content: [{ type: 'text', text: lines.join('\\n\\n') }],\r\n };\r\n });\r\n}\r\n","/**\r\n * StartHub Tool\r\n * Starts a hub server on this machine, opens a Windows firewall rule via UAC,\r\n * and advertises the hub on the LAN via mDNS so peers auto-discover it.\r\n * @module presentation/mcp/tools/start-hub\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 type { HubManager } from '../../../infrastructure/hub/hub-manager.js';\r\n\r\nexport function registerStartHubTool(\r\n server: McpServer,\r\n client: ICollabClient,\r\n hubManager: HubManager\r\n): void {\r\n server.tool(\r\n 'start_hub',\r\n 'Start a hub server on this machine. Opens a firewall rule (UAC prompt) and advertises on LAN via mDNS — peers connect automatically, no IP sharing needed.',\r\n { port: z.number().min(1024).max(65535).optional().describe('Port to listen on (default: 9999)') },\r\n async ({ port = 9999 }) => {\r\n if (hubManager.isRunning) {\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Hub is already running on port ${hubManager.port}.`,\r\n }],\r\n };\r\n }\r\n\r\n try {\r\n await hubManager.start(port);\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: `Failed to start hub: ${msg}`,\r\n }],\r\n };\r\n }\r\n\r\n // Connect this instance to the local hub so it can use all tools\r\n try {\r\n await client.connectToHub(`ws://localhost:${port}`);\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: `Hub started on port ${port}, but failed to self-connect: ${msg}`,\r\n }],\r\n };\r\n }\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: [\r\n `Hub started on port ${port}.`,\r\n `Firewall rule added (claude-collab-${port}).`,\r\n `Others on the LAN will auto-discover and connect — no IP sharing needed.`,\r\n `Use stop_hub when you are done to close the hub and remove the firewall rule.`,\r\n ].join('\\n'),\r\n }],\r\n };\r\n }\r\n );\r\n}\r\n","/**\r\n * StopHub Tool\r\n * Stops the running hub server, removes the Windows firewall rule via UAC,\r\n * and ceases mDNS advertising.\r\n * @module presentation/mcp/tools/stop-hub\r\n */\r\n\r\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\r\nimport type { HubManager } from '../../../infrastructure/hub/hub-manager.js';\r\n\r\nexport function registerStopHubTool(server: McpServer, hubManager: HubManager): void {\r\n server.tool(\r\n 'stop_hub',\r\n 'Stop the running hub server. Removes the firewall rule (UAC prompt) and stops LAN advertising. Connected peers will be disconnected.',\r\n {},\r\n async () => {\r\n if (!hubManager.isRunning) {\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: 'No hub is currently running on this machine.',\r\n }],\r\n };\r\n }\r\n\r\n const port = hubManager.port;\r\n\r\n try {\r\n await hubManager.stop();\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: `Failed to stop hub: ${msg}`,\r\n }],\r\n };\r\n }\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: [\r\n `Hub stopped (was on port ${port}).`,\r\n `Firewall rule removed (claude-collab-${port}).`,\r\n `All peers have been disconnected.`,\r\n ].join('\\n'),\r\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 type { HubManager } from '../../infrastructure/hub/hub-manager.js';\r\nimport { registerAskTool } from './tools/ask.tool.js';\r\nimport { registerReplyTool } from './tools/reply.tool.js';\r\nimport { registerPeersTool } from './tools/peers.tool.js';\r\nimport { registerHistoryTool } from './tools/history.tool.js';\r\nimport { registerStartHubTool } from './tools/start-hub.tool.js';\r\nimport { registerStopHubTool } from './tools/stop-hub.tool.js';\r\n\r\nexport interface McpServerOptions {\r\n client: ICollabClient;\r\n hubManager: HubManager;\r\n}\r\n\r\nexport function createMcpServer(options: McpServerOptions): McpServer {\r\n const { client, hubManager } = 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 registerAskTool(server, client);\r\n registerReplyTool(server, client);\r\n registerPeersTool(server, client);\r\n registerHistoryTool(server, client);\r\n registerStartHubTool(server, client, hubManager);\r\n registerStopHubTool(server, hubManager);\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","/**\r\n * MdnsDiscovery\r\n * Discovers a claude-collab hub on the LAN via mDNS.\r\n * @module infrastructure/mdns/mdns-discovery\r\n */\r\n\r\nimport { Bonjour } from 'bonjour-service';\r\n\r\nconst SERVICE_TYPE = 'claude-collab';\r\n\r\nexport interface DiscoveredHub {\r\n host: string;\r\n port: number;\r\n}\r\n\r\n/**\r\n * One-shot discovery: resolves with hub info if found within timeoutMs, otherwise null.\r\n */\r\nexport function discoverHub(timeoutMs = 5000): Promise<DiscoveredHub | null> {\r\n return new Promise((resolve) => {\r\n const bonjour = new Bonjour();\r\n const browser = bonjour.find({ type: SERVICE_TYPE });\r\n\r\n let settled = false;\r\n\r\n const finish = (result: DiscoveredHub | null) => {\r\n if (settled) return;\r\n settled = true;\r\n clearTimeout(timer);\r\n browser.stop();\r\n bonjour.destroy();\r\n resolve(result);\r\n };\r\n\r\n const timer = setTimeout(() => finish(null), timeoutMs);\r\n\r\n browser.on('up', (svc) => {\r\n finish({ host: svc.host, port: svc.port });\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * Continuous watcher: calls onFound whenever a hub appears on the LAN.\r\n * Returns a stop function — call it to cancel watching.\r\n */\r\nexport function watchForHub(onFound: (hub: DiscoveredHub) => void): () => void {\r\n const bonjour = new Bonjour();\r\n const browser = bonjour.find({ type: SERVICE_TYPE });\r\n\r\n browser.on('up', (svc) => {\r\n onFound({ host: svc.host, port: svc.port });\r\n });\r\n\r\n return () => {\r\n browser.stop();\r\n bonjour.destroy();\r\n };\r\n}\r\n","#!/usr/bin/env node\r\n\r\n/**\r\n * MCP Server entry point\r\n * Reads --name and optionally --server from process.argv.\r\n * If --server is omitted, auto-discovers the hub on the LAN via mDNS.\r\n * @module mcp-main\r\n */\r\n\r\nimport { HubClient } from './infrastructure/hub/hub-client.js';\r\nimport { HubManager } from './infrastructure/hub/hub-manager.js';\r\nimport { startMcpServer } from './presentation/mcp/server.js';\r\nimport { discoverHub, watchForHub } from './infrastructure/mdns/mdns-discovery.js';\r\n\r\nfunction getArg(flag: string): string | undefined {\r\n const idx = process.argv.indexOf(flag);\r\n return idx !== -1 ? process.argv[idx + 1] : undefined;\r\n}\r\n\r\nasync function main(): Promise<void> {\r\n const name = getArg('--name');\r\n const server = getArg('--server');\r\n\r\n if (!name) { console.error('--name is required'); process.exit(1); }\r\n\r\n const hubManager = new HubManager();\r\n const client = new HubClient();\r\n\r\n if (server) {\r\n // Direct mode: connect to the specified hub immediately\r\n const url = server.startsWith('ws') ? server : `ws://${server}`;\r\n client.setServerUrl(url);\r\n await client.join(name, name);\r\n } else {\r\n // No server: just store the name — connection happens later via start_hub or mDNS.\r\n await client.join(name, name);\r\n }\r\n\r\n // Start MCP server immediately — no hub connection required.\r\n // Tools will show a \"no hub\" message until start_hub is called or a hub is discovered.\r\n const mcpReady = startMcpServer({ client, hubManager });\r\n\r\n if (!server) {\r\n // Try mDNS discovery in the background — does NOT block MCP startup.\r\n discoverHub(5000).then(async (hub) => {\r\n if (!hub || client.isConnected) return;\r\n try {\r\n console.error(`[mcp-main] hub found at ${hub.host}:${hub.port}, connecting...`);\r\n await client.connectToHub(`ws://${hub.host}:${hub.port}`);\r\n } catch {\r\n // Hub appeared but connection failed — background watcher will retry\r\n }\r\n });\r\n\r\n // Continuously watch for a hub appearing on the LAN\r\n const stopWatch = watchForHub(async (hub) => {\r\n if (client.isConnected) { stopWatch(); return; }\r\n try {\r\n console.error(`[mcp-main] hub appeared at ${hub.host}:${hub.port}, connecting...`);\r\n await client.connectToHub(`ws://${hub.host}:${hub.port}`);\r\n stopWatch();\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n console.error(`[mcp-main] auto-connect failed: ${msg}`);\r\n }\r\n });\r\n }\r\n\r\n await mcpReady;\r\n}\r\n\r\nmain().catch((error) => {\r\n console.error('Unexpected error:', error);\r\n process.exit(1);\r\n});\r\n"]}
1
+ {"version":3,"sources":["../src/infrastructure/hub/hub-protocol.ts","../src/infrastructure/terminal-injector/windows-injector.ts","../src/infrastructure/terminal-injector/index.ts","../src/infrastructure/terminal-injector/injection-queue.ts","../src/infrastructure/hub/hub-client.ts","../src/infrastructure/hub/hub-server.ts","../src/infrastructure/mdns/mdns-advertiser.ts","../src/infrastructure/hub/hub-manager.ts","../src/presentation/mcp/tools/ask.tool.ts","../src/presentation/mcp/tools/reply.tool.ts","../src/presentation/mcp/tools/peers.tool.ts","../src/presentation/mcp/tools/history.tool.ts","../src/presentation/mcp/tools/start-hub.tool.ts","../src/presentation/mcp/tools/stop-hub.tool.ts","../src/presentation/mcp/server.ts","../src/infrastructure/mdns/mdns-discovery.ts","../src/mcp-main.ts"],"names":["uuidv4","WebSocket","z","SERVICE_TYPE","Bonjour"],"mappings":"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","file":"mcp-main.js","sourcesContent":["/**\r\n * Hub Wire Protocol\r\n * Messages exchanged between hub server and clients.\r\n * @module infrastructure/hub/hub-protocol\r\n */\r\n\r\nimport type { MessageFormat } from '../../domain/value-objects/message-content.vo.js';\r\n\r\n// Client → Hub: identify yourself\r\nexport interface HelloMsg {\r\n type: 'HELLO';\r\n name: string;\r\n}\r\n\r\n// Hub → Client: welcome + current peer list\r\nexport interface HelloAckMsg {\r\n type: 'HELLO_ACK';\r\n peers: string[];\r\n}\r\n\r\n// Hub → Client: broadcast when someone joins\r\nexport interface PeerJoinedMsg {\r\n type: 'PEER_JOINED';\r\n name: string;\r\n}\r\n\r\n// Hub → Client: broadcast when someone leaves\r\nexport interface PeerLeftMsg {\r\n type: 'PEER_LEFT';\r\n name: string;\r\n}\r\n\r\n// Client → Hub: ask a question (hub routes to `to`)\r\nexport interface AskMsg {\r\n type: 'ASK';\r\n from: string;\r\n to: string;\r\n questionId: string;\r\n requestId: string;\r\n content: string;\r\n format: MessageFormat;\r\n}\r\n\r\n// Hub → Client: question delivered acknowledgement\r\nexport interface AskAckMsg {\r\n type: 'ASK_ACK';\r\n questionId: string;\r\n requestId: string;\r\n}\r\n\r\n// Client → Hub: poll for answer (hub routes to `to`)\r\nexport interface GetAnswerMsg {\r\n type: 'GET_ANSWER';\r\n from: string;\r\n to: string;\r\n questionId: string;\r\n requestId: string;\r\n}\r\n\r\n// Client → Hub: deliver answer (hub routes to `to`)\r\nexport interface AnswerMsg {\r\n type: 'ANSWER';\r\n from: string;\r\n to: string;\r\n questionId: string;\r\n content: string;\r\n format: MessageFormat;\r\n answeredAt: string;\r\n requestId?: string;\r\n}\r\n\r\n// Client → Hub: answer not ready yet (hub routes to `to`)\r\nexport interface AnswerPendingMsg {\r\n type: 'ANSWER_PENDING';\r\n to: string;\r\n questionId: string;\r\n requestId: string;\r\n}\r\n\r\n// Hub → Client: error\r\nexport interface HubErrorMsg {\r\n type: 'HUB_ERROR';\r\n code: string;\r\n message: string;\r\n}\r\n\r\nexport type HubMsg =\r\n | HelloMsg\r\n | HelloAckMsg\r\n | PeerJoinedMsg\r\n | PeerLeftMsg\r\n | AskMsg\r\n | AskAckMsg\r\n | GetAnswerMsg\r\n | AnswerMsg\r\n | AnswerPendingMsg\r\n | HubErrorMsg;\r\n\r\nexport function serialize(msg: HubMsg): string {\r\n return JSON.stringify(msg);\r\n}\r\n\r\nexport function parse(data: string): HubMsg {\r\n return JSON.parse(data) as HubMsg;\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 * HubClient\r\n * Connects outbound to a hub server and implements ICollabClient.\r\n * No local WebSocket server — no inbound port needed.\r\n * @module infrastructure/hub/hub-client\r\n */\r\n\r\nimport { WebSocket } from 'ws';\r\nimport { v4 as uuidv4 } from 'uuid';\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 '../../domain/value-objects/message-content.vo.js';\r\nimport {\r\n type HubMsg,\r\n type HelloAckMsg,\r\n type AskAckMsg,\r\n type AskMsg,\r\n type AnswerMsg,\r\n type AnswerPendingMsg,\r\n type GetAnswerMsg,\r\n parse,\r\n serialize,\r\n} from './hub-protocol.js';\r\nimport { injectionQueue } from '../terminal-injector/injection-queue.js';\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 HubClient implements ICollabClient {\r\n private ws: WebSocket | null = null;\r\n private myName = '';\r\n private serverUrl = '';\r\n private reconnectTimer: NodeJS.Timeout | null = null;\r\n\r\n private readonly connectedPeers = new Set<string>();\r\n private readonly incomingQuestions = new Map<string, IncomingQuestion>();\r\n private readonly receivedAnswers = new Map<string, ReceivedAnswer>();\r\n private readonly questionToName = new Map<string, string>();\r\n private readonly questionToSender = new Map<string, string>();\r\n private readonly sentQuestions = new Map<string, { toPeer: string; content: string; askedAt: string }>();\r\n private readonly pendingHandlers = new Set<(msg: HubMsg) => void>();\r\n\r\n setServerUrl(url: string): void {\r\n this.serverUrl = url;\r\n }\r\n\r\n get isConnected(): boolean {\r\n return this.ws?.readyState === WebSocket.OPEN;\r\n }\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 // Only connect immediately if a server URL was already set.\r\n // If not (e.g. auto-discover mode), connection happens later via connectToHub().\r\n if (this.serverUrl) {\r\n await this.connectAndHello();\r\n }\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: 0,\r\n };\r\n }\r\n\r\n async connectToHub(url: string): Promise<void> {\r\n this.serverUrl = url;\r\n await this.connectAndHello();\r\n }\r\n\r\n async ask(toPeer: string, content: string, format: MessageFormat): Promise<string> {\r\n const questionId = uuidv4();\r\n const requestId = uuidv4();\r\n\r\n this.questionToName.set(questionId, toPeer);\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.requestId === requestId,\r\n 5000\r\n );\r\n\r\n this.sendToHub({ type: 'ASK', from: this.myName, to: toPeer, questionId, requestId, content, format });\r\n\r\n await ackPromise;\r\n return questionId;\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) {\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 const toPeer = this.questionToName.get(questionId);\r\n if (!toPeer || !this.isConnected) return null;\r\n\r\n const requestId = uuidv4();\r\n const responsePromise = this.waitForResponse<AnswerMsg | AnswerPendingMsg>(\r\n (m) =>\r\n (m.type === 'ANSWER' && m.questionId === questionId) ||\r\n (m.type === 'ANSWER_PENDING' && m.requestId === requestId),\r\n 5000\r\n );\r\n\r\n this.sendToHub({ type: 'GET_ANSWER', from: this.myName, to: toPeer, questionId, requestId });\r\n\r\n const response = await responsePromise;\r\n if (response.type === 'ANSWER_PENDING') return null;\r\n\r\n const answer = response as AnswerMsg;\r\n this.receivedAnswers.set(questionId, {\r\n content: answer.content,\r\n format: answer.format,\r\n answeredAt: answer.answeredAt,\r\n fromName: answer.from,\r\n });\r\n\r\n return {\r\n questionId,\r\n from: { displayName: `${answer.from} Claude`, teamName: answer.from },\r\n content: answer.content,\r\n format: answer.format,\r\n answeredAt: answer.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 this.sendToHub({\r\n type: 'ANSWER',\r\n from: this.myName,\r\n to: senderName,\r\n questionId,\r\n content,\r\n format,\r\n answeredAt: new Date().toISOString(),\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\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: undefined,\r\n connectedPeers: [...this.connectedPeers],\r\n };\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 answer: answer?.content,\r\n askedAt: sent.askedAt,\r\n answeredAt: answer?.answeredAt,\r\n });\r\n }\r\n\r\n for (const [questionId, incoming] of this.incomingQuestions) {\r\n entries.push({\r\n direction: 'received',\r\n questionId,\r\n peer: incoming.fromName,\r\n question: incoming.content,\r\n answer: incoming.answered ? incoming.answerContent : undefined,\r\n askedAt: incoming.createdAt.toISOString(),\r\n answeredAt: incoming.answered ? new Date().toISOString() : undefined,\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 if (this.reconnectTimer) {\r\n clearTimeout(this.reconnectTimer);\r\n this.reconnectTimer = null;\r\n }\r\n this.ws?.close();\r\n this.ws = null;\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Private: connection management\r\n // ---------------------------------------------------------------------------\r\n\r\n private async connectAndHello(): Promise<void> {\r\n const ws = new WebSocket(this.serverUrl);\r\n this.ws = ws;\r\n\r\n ws.on('message', (data) => {\r\n try {\r\n const msg = parse(data.toString());\r\n this.handleMessage(msg);\r\n } catch {\r\n // ignore malformed messages\r\n }\r\n });\r\n\r\n ws.on('close', () => {\r\n this.connectedPeers.clear();\r\n this.scheduleReconnect();\r\n });\r\n\r\n ws.on('error', (err) => {\r\n console.error('[hub-client] error:', err.message);\r\n });\r\n\r\n await new Promise<void>((resolve, reject) => {\r\n const timeout = setTimeout(\r\n () => reject(new Error(`Cannot connect to hub at ${this.serverUrl}`)),\r\n 10000\r\n );\r\n ws.on('open', () => {\r\n clearTimeout(timeout);\r\n ws.send(serialize({ type: 'HELLO', name: this.myName }));\r\n resolve();\r\n });\r\n ws.on('error', (err) => {\r\n clearTimeout(timeout);\r\n reject(err);\r\n });\r\n });\r\n\r\n const ack = await this.waitForResponse<HelloAckMsg>(\r\n (m) => m.type === 'HELLO_ACK',\r\n 10000\r\n );\r\n\r\n for (const peer of ack.peers) this.connectedPeers.add(peer);\r\n console.error(`[hub-client] connected as \"${this.myName}\", peers: [${ack.peers.join(', ')}]`);\r\n }\r\n\r\n private scheduleReconnect(): void {\r\n if (this.reconnectTimer) return;\r\n this.reconnectTimer = setTimeout(async () => {\r\n this.reconnectTimer = null;\r\n try {\r\n await this.connectAndHello();\r\n console.error('[hub-client] reconnected to hub');\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n console.error(`[hub-client] reconnect failed: ${msg}, retrying in 5s...`);\r\n this.scheduleReconnect();\r\n }\r\n }, 5000);\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Private: message handling\r\n // ---------------------------------------------------------------------------\r\n\r\n private handleMessage(msg: HubMsg): void {\r\n for (const handler of this.pendingHandlers) handler(msg);\r\n\r\n switch (msg.type) {\r\n case 'PEER_JOINED':\r\n this.connectedPeers.add(msg.name);\r\n console.error(`[hub-client] peer joined: ${msg.name}`);\r\n break;\r\n\r\n case 'PEER_LEFT':\r\n this.connectedPeers.delete(msg.name);\r\n console.error(`[hub-client] peer left: ${msg.name}`);\r\n break;\r\n\r\n case 'ASK':\r\n this.handleIncomingAsk(msg);\r\n break;\r\n\r\n case 'GET_ANSWER':\r\n this.handleGetAnswer(msg);\r\n break;\r\n\r\n case 'ANSWER':\r\n if (!this.receivedAnswers.has(msg.questionId)) {\r\n this.receivedAnswers.set(msg.questionId, {\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 break;\r\n\r\n case 'HUB_ERROR':\r\n console.error(`[hub-client] hub error: ${msg.message}`);\r\n break;\r\n }\r\n }\r\n\r\n private handleIncomingAsk(msg: AskMsg): void {\r\n this.questionToSender.set(msg.questionId, msg.from);\r\n\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 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 handleGetAnswer(msg: GetAnswerMsg): void {\r\n const question = this.incomingQuestions.get(msg.questionId);\r\n\r\n if (!question?.answered) {\r\n this.sendToHub({\r\n type: 'ANSWER_PENDING',\r\n to: msg.from,\r\n questionId: msg.questionId,\r\n requestId: msg.requestId,\r\n });\r\n return;\r\n }\r\n\r\n this.sendToHub({\r\n type: 'ANSWER',\r\n from: this.myName,\r\n to: msg.from,\r\n questionId: msg.questionId,\r\n content: question.answerContent!,\r\n format: question.answerFormat!,\r\n answeredAt: new Date().toISOString(),\r\n requestId: msg.requestId,\r\n });\r\n }\r\n\r\n private sendToHub(msg: HubMsg): void {\r\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\r\n throw new Error('Not connected to hub. Will retry automatically.');\r\n }\r\n this.ws.send(serialize(msg));\r\n }\r\n\r\n private waitForResponse<T extends HubMsg>(\r\n filter: (msg: HubMsg) => 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('Hub request timed out'));\r\n }, timeoutMs);\r\n\r\n const handler = (msg: HubMsg): 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 * HubServer\r\n * Central WebSocket server that routes messages between clients by name.\r\n * One instance runs per team — everyone else connects to it outbound.\r\n * @module infrastructure/hub/hub-server\r\n */\r\n\r\nimport { WebSocketServer, WebSocket } from 'ws';\r\nimport {\r\n type HubMsg,\r\n type HelloAckMsg,\r\n type AskAckMsg,\r\n type HubErrorMsg,\r\n parse,\r\n serialize,\r\n} from './hub-protocol.js';\r\n\r\nexport class HubServer {\r\n private wss: WebSocketServer | null = null;\r\n private readonly clients = new Map<string, WebSocket>(); // name → ws\r\n private readonly wsToName = new Map<WebSocket, string>(); // ws → name\r\n\r\n start(port: number): void {\r\n this.wss = new WebSocketServer({ port });\r\n\r\n this.wss.on('listening', () => {\r\n console.log(`claude-collab hub running on port ${port}`);\r\n console.log('Waiting for peers...\\n');\r\n });\r\n\r\n this.wss.on('connection', (ws) => {\r\n ws.on('message', (data) => {\r\n try {\r\n const msg = parse(data.toString());\r\n this.handleMessage(ws, msg);\r\n } catch {\r\n // ignore malformed messages\r\n }\r\n });\r\n\r\n ws.on('close', () => {\r\n const name = this.wsToName.get(ws);\r\n if (name) {\r\n this.clients.delete(name);\r\n this.wsToName.delete(ws);\r\n this.broadcast({ type: 'PEER_LEFT', name });\r\n console.log(`← ${name} left (${this.clients.size} online: ${[...this.clients.keys()].join(', ') || 'none'})`);\r\n }\r\n });\r\n\r\n ws.on('error', (err) => {\r\n console.error('[hub] ws error:', err.message);\r\n });\r\n });\r\n\r\n this.wss.on('error', (err) => {\r\n console.error('[hub] server error:', err.message);\r\n });\r\n }\r\n\r\n stop(): void {\r\n if (!this.wss) return;\r\n for (const ws of this.clients.values()) ws.terminate();\r\n this.clients.clear();\r\n this.wsToName.clear();\r\n this.wss.close();\r\n this.wss = null;\r\n console.log('claude-collab hub stopped');\r\n }\r\n\r\n private handleMessage(ws: WebSocket, msg: HubMsg): void {\r\n switch (msg.type) {\r\n case 'HELLO': {\r\n const existing = this.clients.get(msg.name);\r\n const isReconnect = existing != null && existing !== ws;\r\n\r\n if (isReconnect) {\r\n // Remove from tracking BEFORE closing so the close event won't broadcast PEER_LEFT\r\n this.wsToName.delete(existing!);\r\n existing!.close();\r\n }\r\n\r\n this.clients.set(msg.name, ws);\r\n this.wsToName.set(ws, msg.name);\r\n\r\n const peers = [...this.clients.keys()].filter((n) => n !== msg.name);\r\n const ack: HelloAckMsg = { type: 'HELLO_ACK', peers };\r\n this.send(ws, ack);\r\n\r\n if (!isReconnect) {\r\n this.broadcast({ type: 'PEER_JOINED', name: msg.name }, ws);\r\n }\r\n\r\n console.log(`→ ${msg.name} joined (${this.clients.size} online: ${[...this.clients.keys()].join(', ')})`);\r\n break;\r\n }\r\n\r\n case 'ASK': {\r\n const target = this.clients.get(msg.to);\r\n if (!target) {\r\n const err: HubErrorMsg = {\r\n type: 'HUB_ERROR',\r\n code: 'PEER_NOT_FOUND',\r\n message: `'${msg.to}' is not connected to the hub`,\r\n };\r\n this.send(ws, err);\r\n return;\r\n }\r\n this.send(target, msg);\r\n const ack: AskAckMsg = { type: 'ASK_ACK', questionId: msg.questionId, requestId: msg.requestId };\r\n this.send(ws, ack);\r\n break;\r\n }\r\n\r\n case 'GET_ANSWER': {\r\n const target = this.clients.get(msg.to);\r\n if (!target) {\r\n this.send(ws, { type: 'ANSWER_PENDING', to: msg.from, questionId: msg.questionId, requestId: msg.requestId });\r\n return;\r\n }\r\n this.send(target, msg);\r\n break;\r\n }\r\n\r\n case 'ANSWER':\r\n case 'ANSWER_PENDING': {\r\n const target = this.clients.get(msg.to);\r\n if (target) this.send(target, msg);\r\n break;\r\n }\r\n\r\n // HELLO_ACK, ASK_ACK, PEER_JOINED, PEER_LEFT, HUB_ERROR are hub→client only — ignore if received\r\n }\r\n }\r\n\r\n private send(ws: WebSocket, msg: HubMsg): void {\r\n if (ws.readyState === WebSocket.OPEN) {\r\n ws.send(serialize(msg));\r\n }\r\n }\r\n\r\n private broadcast(msg: HubMsg, except?: WebSocket): void {\r\n for (const ws of this.clients.values()) {\r\n if (ws !== except) this.send(ws, msg);\r\n }\r\n }\r\n}\r\n","/**\r\n * MdnsAdvertiser\r\n * Broadcasts the hub's presence on the LAN via mDNS so clients can auto-discover it.\r\n * @module infrastructure/mdns/mdns-advertiser\r\n */\r\n\r\nimport { Bonjour } from 'bonjour-service';\r\n\r\nconst SERVICE_TYPE = 'claude-collab';\r\n\r\nexport class MdnsAdvertiser {\r\n private bonjour: Bonjour | null = null;\r\n\r\n start(port: number): void {\r\n this.bonjour = new Bonjour();\r\n this.bonjour.publish({ name: 'claude-collab-hub', type: SERVICE_TYPE, port });\r\n console.error(`[mdns] advertising hub on port ${port}`);\r\n }\r\n\r\n stop(): void {\r\n if (!this.bonjour) return;\r\n this.bonjour.unpublishAll(() => {\r\n this.bonjour?.destroy();\r\n });\r\n this.bonjour = null;\r\n console.error('[mdns] stopped advertising');\r\n }\r\n}\r\n","/**\r\n * HubManager\r\n * Orchestrates hub lifecycle: starts/stops HubServer, manages Windows firewall rules\r\n * via UAC elevation, and controls mDNS advertising.\r\n * @module infrastructure/hub/hub-manager\r\n */\r\n\r\nimport { spawn } from 'child_process';\r\nimport { HubServer } from './hub-server.js';\r\nimport { MdnsAdvertiser } from '../mdns/mdns-advertiser.js';\r\n\r\nexport class HubManager {\r\n private hubServer: HubServer | null = null;\r\n private advertiser: MdnsAdvertiser | null = null;\r\n private currentPort: number | null = null;\r\n\r\n get isRunning(): boolean {\r\n return this.hubServer !== null;\r\n }\r\n\r\n get port(): number | null {\r\n return this.currentPort;\r\n }\r\n\r\n async start(port: number): Promise<{ firewallAdded: boolean }> {\r\n if (this.isRunning) throw new Error('Hub is already running');\r\n\r\n const server = new HubServer();\r\n server.start(port);\r\n this.hubServer = server;\r\n this.currentPort = port;\r\n\r\n // Advertise on LAN via mDNS (regardless of firewall outcome)\r\n const advertiser = new MdnsAdvertiser();\r\n advertiser.start(port);\r\n this.advertiser = advertiser;\r\n\r\n // Add firewall rule via UAC — hub runs even if this fails\r\n let firewallAdded = false;\r\n try {\r\n await addFirewallRule(port);\r\n firewallAdded = true;\r\n } catch (err) {\r\n console.error('[hub-manager] firewall rule failed:', err);\r\n }\r\n\r\n return { firewallAdded };\r\n }\r\n\r\n async stop(): Promise<{ firewallRemoved: boolean }> {\r\n if (!this.isRunning) throw new Error('Hub is not running');\r\n\r\n if (this.advertiser) {\r\n this.advertiser.stop();\r\n this.advertiser = null;\r\n }\r\n\r\n const port = this.currentPort!;\r\n this.hubServer!.stop();\r\n this.hubServer = null;\r\n this.currentPort = null;\r\n\r\n let firewallRemoved = false;\r\n try {\r\n await removeFirewallRule(port);\r\n firewallRemoved = true;\r\n } catch (err) {\r\n console.error('[hub-manager] firewall rule removal failed:', err);\r\n }\r\n\r\n return { firewallRemoved };\r\n }\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Firewall helpers — elevated via UAC (PowerShell Start-Process -Verb RunAs)\r\n// ---------------------------------------------------------------------------\r\n\r\nfunction runElevated(argArray: string[]): Promise<void> {\r\n // Pass arguments as a PowerShell array to avoid quote escaping issues.\r\n // e.g. @(\"advfirewall\",\"firewall\",\"add\",\"rule\",\"name=claude-collab-9999\",...)\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\nasync function addFirewallRule(port: number): Promise<void> {\r\n await runElevated([\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\nasync function removeFirewallRule(port: number): Promise<void> {\r\n await runElevated([\r\n 'advfirewall', 'firewall', 'delete', 'rule',\r\n `name=claude-collab-${port}`,\r\n ]);\r\n}\r\n","/**\r\n * Ask Tool\r\n * Sends a question to another team and returns a question ID immediately.\r\n * Use the \"check_answer\" tool with the question ID to retrieve the answer later.\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\n/**\r\n * Ask tool input schema\r\n */\r\nconst askSchema = {\r\n peer: z.string().describe('Name of the peer to ask (e.g., \"alice\", \"backend\")'),\r\n question: z.string().describe('The question to ask (supports markdown)'),\r\n};\r\n\r\n/**\r\n * Registers the ask tool with the MCP server\r\n */\r\nexport function registerAskTool(server: McpServer, client: ICollabClient): void {\r\n server.tool('ask', 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 {\r\n type: 'text',\r\n text: 'Node is not ready yet. Wait a moment and try again.',\r\n },\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 // Poll until answer arrives (max 5 minutes, every 5 seconds)\r\n const POLL_INTERVAL_MS = 5_000;\r\n const MAX_WAIT_MS = 5 * 60 * 1000;\r\n const deadline = Date.now() + MAX_WAIT_MS;\r\n\r\n while (Date.now() < deadline) {\r\n await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));\r\n const answer = await client.checkAnswer(questionId);\r\n if (answer !== null) {\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: `**${answer.from.displayName} (${answer.from.teamName}) cevapladı:**\\n\\n${answer.content}`,\r\n },\r\n ],\r\n };\r\n }\r\n }\r\n\r\n // Timed out — return question ID for manual follow-up\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: `Soru gönderildi ancak 5 dakika içinde cevap gelmedi.\\nQuestion ID: \\`${questionId}\\`\\n\\nManuel kontrol için \"check_answer\" tool'unu kullanabilirsin.`,\r\n },\r\n ],\r\n };\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: `Failed to send question: ${errorMessage}`,\r\n },\r\n ],\r\n isError: true,\r\n };\r\n }\r\n });\r\n}\r\n","/**\r\n * Reply Tool\r\n * Replies to a pending question\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\n/**\r\n * Reply tool input schema\r\n */\r\nconst replySchema = {\r\n questionId: z.string().describe('The ID of the question to reply to (from inbox)'),\r\n answer: z.string().describe('Your answer to the question (supports markdown)'),\r\n};\r\n\r\n/**\r\n * Registers the reply tool with the MCP server\r\n */\r\nexport function registerReplyTool(server: McpServer, client: ICollabClient): void {\r\n server.tool('reply', 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 {\r\n type: 'text',\r\n text: 'You must join a team first. Use the \"join\" tool to join a team.',\r\n },\r\n ],\r\n isError: true,\r\n };\r\n }\r\n\r\n await client.reply(questionId, answer, 'markdown');\r\n\r\n // Signal queue: this question is done, process next\r\n injectionQueue.notifyReplied();\r\n\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: `Reply sent successfully to question \\`${questionId}\\`.`,\r\n },\r\n ],\r\n };\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: `Failed to send reply: ${errorMessage}`,\r\n },\r\n ],\r\n isError: true,\r\n };\r\n }\r\n });\r\n}\r\n","/**\r\n * Peers Tool\r\n * Lists currently connected peers on the collaboration network.\r\n * @module presentation/mcp/tools/peers\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\nexport function registerPeersTool(server: McpServer, client: ICollabClient): void {\r\n server.tool('peers', {}, async () => {\r\n const info = client.getInfo();\r\n const myName = info.teamName ?? '(starting...)';\r\n const connected = info.connectedPeers;\r\n\r\n if (connected.length === 0) {\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `You are \"${myName}\". No peers connected yet — they will appear automatically when they come online.`,\r\n }],\r\n };\r\n }\r\n\r\n const list = connected.map((name) => ` • ${name}`).join('\\n');\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `You are \"${myName}\". Connected peers (${connected.length}):\\n${list}`,\r\n }],\r\n };\r\n });\r\n}\r\n","/**\r\n * History Tool\r\n * Shows past questions and answers from this session.\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\nexport function registerHistoryTool(server: McpServer, client: ICollabClient): void {\r\n server.tool('history', {}, 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 yet this session.' }],\r\n };\r\n }\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)`;\r\n return `[${time}] ← ${e.peer}: ${e.question}\\n${answerLine}`;\r\n }\r\n });\r\n\r\n return {\r\n content: [{ type: 'text', text: lines.join('\\n\\n') }],\r\n };\r\n });\r\n}\r\n","/**\r\n * StartHub Tool\r\n * Starts a hub server on this machine, opens a Windows firewall rule via UAC,\r\n * and advertises the hub on the LAN via mDNS so peers auto-discover it.\r\n * @module presentation/mcp/tools/start-hub\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 type { HubManager } from '../../../infrastructure/hub/hub-manager.js';\r\n\r\nexport function registerStartHubTool(\r\n server: McpServer,\r\n client: ICollabClient,\r\n hubManager: HubManager\r\n): void {\r\n server.tool(\r\n 'start_hub',\r\n 'Start a hub server on this machine. Opens a firewall rule (UAC prompt) and advertises on LAN via mDNS — peers connect automatically, no IP sharing needed.',\r\n { port: z.number().min(1024).max(65535).optional().describe('Port to listen on (default: 9999)') },\r\n async ({ port = 9999 }) => {\r\n if (hubManager.isRunning) {\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Hub is already running on port ${hubManager.port}.`,\r\n }],\r\n };\r\n }\r\n\r\n let firewallAdded = false;\r\n try {\r\n const result = await hubManager.start(port);\r\n firewallAdded = result.firewallAdded;\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n return {\r\n content: [{ type: 'text', text: `Failed to start hub: ${msg}` }],\r\n };\r\n }\r\n\r\n // Connect this instance to the local hub so it can use all tools\r\n try {\r\n await client.connectToHub(`ws://localhost:${port}`);\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n return {\r\n content: [{ type: 'text', text: `Hub started on port ${port}, but failed to self-connect: ${msg}` }],\r\n };\r\n }\r\n\r\n const lines = [\r\n `Hub started on port ${port}.`,\r\n firewallAdded\r\n ? `Firewall rule added (claude-collab-${port}) — LAN peers can connect.`\r\n : `WARNING: Firewall rule could not be added (UAC was cancelled or denied). Peers on other machines may be blocked by Windows Firewall. Run start_hub again and accept the UAC prompt to fix this.`,\r\n `Others on the LAN will auto-discover and connect via mDNS.`,\r\n `Use stop_hub when you are done.`,\r\n ];\r\n\r\n return {\r\n content: [{ type: 'text', text: lines.join('\\n') }],\r\n };\r\n }\r\n );\r\n}\r\n","/**\r\n * StopHub Tool\r\n * Stops the running hub server, removes the Windows firewall rule via UAC,\r\n * and ceases mDNS advertising.\r\n * @module presentation/mcp/tools/stop-hub\r\n */\r\n\r\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\r\nimport type { HubManager } from '../../../infrastructure/hub/hub-manager.js';\r\n\r\nexport function registerStopHubTool(server: McpServer, hubManager: HubManager): void {\r\n server.tool(\r\n 'stop_hub',\r\n 'Stop the running hub server. Removes the firewall rule (UAC prompt) and stops LAN advertising. Connected peers will be disconnected.',\r\n {},\r\n async () => {\r\n if (!hubManager.isRunning) {\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: 'No hub is currently running on this machine.',\r\n }],\r\n };\r\n }\r\n\r\n const port = hubManager.port;\r\n\r\n let firewallRemoved = false;\r\n try {\r\n const result = await hubManager.stop();\r\n firewallRemoved = result.firewallRemoved;\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n return {\r\n content: [{ type: 'text', text: `Failed to stop hub: ${msg}` }],\r\n };\r\n }\r\n\r\n const lines = [\r\n `Hub stopped (was on port ${port}).`,\r\n firewallRemoved\r\n ? `Firewall rule removed (claude-collab-${port}).`\r\n : `WARNING: Firewall rule could not be removed (UAC was cancelled). Remove it manually: netsh advfirewall firewall delete rule name=\"claude-collab-${port}\"`,\r\n `All peers have been disconnected.`,\r\n ];\r\n\r\n return {\r\n content: [{ type: 'text', text: lines.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 type { HubManager } from '../../infrastructure/hub/hub-manager.js';\r\nimport { registerAskTool } from './tools/ask.tool.js';\r\nimport { registerReplyTool } from './tools/reply.tool.js';\r\nimport { registerPeersTool } from './tools/peers.tool.js';\r\nimport { registerHistoryTool } from './tools/history.tool.js';\r\nimport { registerStartHubTool } from './tools/start-hub.tool.js';\r\nimport { registerStopHubTool } from './tools/stop-hub.tool.js';\r\n\r\nexport interface McpServerOptions {\r\n client: ICollabClient;\r\n hubManager: HubManager;\r\n}\r\n\r\nexport function createMcpServer(options: McpServerOptions): McpServer {\r\n const { client, hubManager } = 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 registerAskTool(server, client);\r\n registerReplyTool(server, client);\r\n registerPeersTool(server, client);\r\n registerHistoryTool(server, client);\r\n registerStartHubTool(server, client, hubManager);\r\n registerStopHubTool(server, hubManager);\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","/**\r\n * MdnsDiscovery\r\n * Discovers a claude-collab hub on the LAN via mDNS.\r\n * @module infrastructure/mdns/mdns-discovery\r\n */\r\n\r\nimport { Bonjour } from 'bonjour-service';\r\n\r\nconst SERVICE_TYPE = 'claude-collab';\r\n\r\nexport interface DiscoveredHub {\r\n host: string;\r\n port: number;\r\n}\r\n\r\n/**\r\n * One-shot discovery: resolves with hub info if found within timeoutMs, otherwise null.\r\n */\r\nexport function discoverHub(timeoutMs = 5000): Promise<DiscoveredHub | null> {\r\n return new Promise((resolve) => {\r\n const bonjour = new Bonjour();\r\n const browser = bonjour.find({ type: SERVICE_TYPE });\r\n\r\n let settled = false;\r\n\r\n const finish = (result: DiscoveredHub | null) => {\r\n if (settled) return;\r\n settled = true;\r\n clearTimeout(timer);\r\n browser.stop();\r\n bonjour.destroy();\r\n resolve(result);\r\n };\r\n\r\n const timer = setTimeout(() => finish(null), timeoutMs);\r\n\r\n browser.on('up', (svc) => {\r\n finish({ host: svc.host, port: svc.port });\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * Continuous watcher: calls onFound whenever a hub appears on the LAN.\r\n * Returns a stop function — call it to cancel watching.\r\n */\r\nexport function watchForHub(onFound: (hub: DiscoveredHub) => void): () => void {\r\n const bonjour = new Bonjour();\r\n const browser = bonjour.find({ type: SERVICE_TYPE });\r\n\r\n browser.on('up', (svc) => {\r\n onFound({ host: svc.host, port: svc.port });\r\n });\r\n\r\n return () => {\r\n browser.stop();\r\n bonjour.destroy();\r\n };\r\n}\r\n","#!/usr/bin/env node\r\n\r\n/**\r\n * MCP Server entry point\r\n * Reads --name and optionally --server from process.argv.\r\n * If --server is omitted, auto-discovers the hub on the LAN via mDNS.\r\n * @module mcp-main\r\n */\r\n\r\nimport { HubClient } from './infrastructure/hub/hub-client.js';\r\nimport { HubManager } from './infrastructure/hub/hub-manager.js';\r\nimport { startMcpServer } from './presentation/mcp/server.js';\r\nimport { discoverHub, watchForHub } from './infrastructure/mdns/mdns-discovery.js';\r\n\r\nfunction getArg(flag: string): string | undefined {\r\n const idx = process.argv.indexOf(flag);\r\n return idx !== -1 ? process.argv[idx + 1] : undefined;\r\n}\r\n\r\nasync function main(): Promise<void> {\r\n const name = getArg('--name');\r\n const server = getArg('--server');\r\n\r\n if (!name) { console.error('--name is required'); process.exit(1); }\r\n\r\n const hubManager = new HubManager();\r\n const client = new HubClient();\r\n\r\n if (server) {\r\n // Direct mode: connect to the specified hub immediately\r\n const url = server.startsWith('ws') ? server : `ws://${server}`;\r\n client.setServerUrl(url);\r\n await client.join(name, name);\r\n } else {\r\n // No server: just store the name — connection happens later via start_hub or mDNS.\r\n await client.join(name, name);\r\n }\r\n\r\n // Start MCP server immediately — no hub connection required.\r\n // Tools will show a \"no hub\" message until start_hub is called or a hub is discovered.\r\n const mcpReady = startMcpServer({ client, hubManager });\r\n\r\n if (!server) {\r\n // Try mDNS discovery in the background — does NOT block MCP startup.\r\n discoverHub(5000).then(async (hub) => {\r\n if (!hub || client.isConnected) return;\r\n try {\r\n console.error(`[mcp-main] hub found at ${hub.host}:${hub.port}, connecting...`);\r\n await client.connectToHub(`ws://${hub.host}:${hub.port}`);\r\n } catch {\r\n // Hub appeared but connection failed — background watcher will retry\r\n }\r\n });\r\n\r\n // Continuously watch for a hub appearing on the LAN\r\n const stopWatch = watchForHub(async (hub) => {\r\n if (client.isConnected) { stopWatch(); return; }\r\n try {\r\n console.error(`[mcp-main] hub appeared at ${hub.host}:${hub.port}, connecting...`);\r\n await client.connectToHub(`ws://${hub.host}:${hub.port}`);\r\n stopWatch();\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n console.error(`[mcp-main] auto-connect failed: ${msg}`);\r\n }\r\n });\r\n }\r\n\r\n await mcpReady;\r\n}\r\n\r\nmain().catch((error) => {\r\n console.error('Unexpected error:', error);\r\n process.exit(1);\r\n});\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dolusoft/claude-collab",
3
- "version": "1.8.2",
3
+ "version": "1.8.3",
4
4
  "description": "Real-time team collaboration between Claude Code terminals via MCP",
5
5
  "type": "module",
6
6
  "main": "./dist/mcp-main.js",