@dolusoft/claude-collab 1.8.2 → 1.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js 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
  );
@@ -1022,6 +1037,10 @@ async function startMcpServer(options) {
1022
1037
  await server.connect(transport);
1023
1038
  }
1024
1039
  var SERVICE_TYPE2 = "claude-collab";
1040
+ function resolveHost(svc) {
1041
+ const ipv4 = svc.addresses?.find((a) => /^\d+\.\d+\.\d+\.\d+$/.test(a));
1042
+ return ipv4 ?? svc.host;
1043
+ }
1025
1044
  function discoverHub(timeoutMs = 5e3) {
1026
1045
  return new Promise((resolve) => {
1027
1046
  const bonjour = new Bonjour();
@@ -1037,7 +1056,7 @@ function discoverHub(timeoutMs = 5e3) {
1037
1056
  };
1038
1057
  const timer = setTimeout(() => finish(null), timeoutMs);
1039
1058
  browser.on("up", (svc) => {
1040
- finish({ host: svc.host, port: svc.port });
1059
+ finish({ host: resolveHost(svc), port: svc.port });
1041
1060
  });
1042
1061
  });
1043
1062
  }
@@ -1045,7 +1064,7 @@ function watchForHub(onFound) {
1045
1064
  const bonjour = new Bonjour();
1046
1065
  const browser = bonjour.find({ type: SERVICE_TYPE2 });
1047
1066
  browser.on("up", (svc) => {
1048
- onFound({ host: svc.host, port: svc.port });
1067
+ onFound({ host: resolveHost(svc), port: svc.port });
1049
1068
  });
1050
1069
  return () => {
1051
1070
  browser.stop();