openclaw-bridge 0.4.0 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -673,23 +673,57 @@ async function cmdUpgrade() {
673
673
  console.log("==========================\n");
674
674
  let updatedPlugin = false;
675
675
  let updatedCli = false;
676
- // 1. Check if installed as OpenClaw plugin
676
+ // 1. Try installing/upgrading as OpenClaw plugin
677
677
  console.log("Checking OpenClaw plugin installation...");
678
678
  try {
679
- const pluginList = run("openclaw plugins list", { silent: true });
680
- if (pluginList.includes("openclaw-bridge")) {
681
- console.log(" Found openclaw-bridge plugin. Updating...");
682
- runInherit("openclaw plugins install openclaw-bridge");
679
+ // First attempt: just try to install
680
+ const installResult = run("openclaw plugins install openclaw-bridge 2>&1", { silent: true });
681
+ if (installResult.includes("openclaw-bridge")) {
683
682
  updatedPlugin = true;
684
- console.log(" Plugin updated.");
683
+ console.log(" Plugin installed/updated.");
684
+ }
685
+ }
686
+ catch (installErr) {
687
+ const errMsg = String(installErr?.stdout || installErr?.message || installErr || "");
688
+ if (errMsg.includes("plugin already exists") || errMsg.includes("already exists")) {
689
+ // Parse the existing path from error: "plugin already exists: /path/to/openclaw-bridge (delete it first)"
690
+ const pathMatch = errMsg.match(/already exists:\s*(.+?)\s*\(/);
691
+ const existingPath = pathMatch?.[1]?.trim();
692
+ if (existingPath && existsSync(existingPath)) {
693
+ console.log(` Old plugin found at ${existingPath}. Removing...`);
694
+ run(IS_WINDOWS ? `rmdir /s /q "${existingPath}"` : `rm -rf "${existingPath}"`, { silent: true });
695
+ }
696
+ else {
697
+ // Fallback: search common plugin directories
698
+ const candidates = [
699
+ join(homedir(), ".openclaw", "extensions", "openclaw-bridge"),
700
+ join(homedir(), "openclaw-extensions", "openclaw-bridge"),
701
+ IS_WINDOWS ? "C:\\openclaw-extensions\\openclaw-bridge" : "",
702
+ ].filter(Boolean);
703
+ for (const dir of candidates) {
704
+ if (existsSync(dir)) {
705
+ console.log(` Old plugin found at ${dir}. Removing...`);
706
+ run(IS_WINDOWS ? `rmdir /s /q "${dir}"` : `rm -rf "${dir}"`, { silent: true });
707
+ break;
708
+ }
709
+ }
710
+ }
711
+ // Retry install after removing old version
712
+ console.log(" Installing new version...");
713
+ try {
714
+ runInherit("openclaw plugins install openclaw-bridge");
715
+ updatedPlugin = true;
716
+ console.log(" Plugin updated.");
717
+ }
718
+ catch {
719
+ console.log(" Plugin install failed after removing old version. Try manually:");
720
+ console.log(" openclaw plugins install openclaw-bridge");
721
+ }
685
722
  }
686
723
  else {
687
- console.log(" Not installed as OpenClaw plugin.");
724
+ console.log(" openclaw CLI not found or plugins command failed. Skipping plugin check.");
688
725
  }
689
726
  }
690
- catch {
691
- console.log(" openclaw CLI not found or plugins command failed. Skipping plugin check.");
692
- }
693
727
  // 2. Check if installed as global npm package
694
728
  console.log("\nChecking global npm installation...");
695
729
  try {
@@ -724,8 +758,84 @@ async function cmdUpgrade() {
724
758
  console.log("\nUpgrade complete.");
725
759
  }
726
760
  }
761
+ // 4. Config health check — scan openclaw.json and fix missing settings
762
+ console.log("\nChecking bridge configuration...");
763
+ const configFixCount = checkAndFixBridgeConfig();
764
+ if (configFixCount === 0) {
765
+ console.log(" Config OK — all required settings present.");
766
+ }
767
+ else {
768
+ console.log(` Fixed ${configFixCount} config issue(s). Restart your gateway to apply.`);
769
+ }
727
770
  console.log();
728
771
  }
772
+ /** Scan openclaw.json for missing bridge config fields and auto-fix them */
773
+ function checkAndFixBridgeConfig() {
774
+ // Find openclaw.json — check env var, then common locations
775
+ const candidates = [
776
+ process.env.OPENCLAW_CONFIG_PATH,
777
+ join(process.cwd(), "openclaw.json"),
778
+ join(homedir(), ".openclaw", "openclaw.json"),
779
+ IS_WINDOWS ? "C:\\openclaw-instances\\main\\openclaw.json" : "",
780
+ ].filter(Boolean);
781
+ let fixes = 0;
782
+ for (const configPath of candidates) {
783
+ if (!existsSync(configPath))
784
+ continue;
785
+ try {
786
+ const raw = readFileSync(configPath, "utf-8");
787
+ const config = JSON.parse(raw);
788
+ const bridgeConfig = config.plugins?.entries?.["openclaw-bridge"]?.config;
789
+ if (!bridgeConfig)
790
+ continue;
791
+ let changed = false;
792
+ // Fix 1: Auto-add messageRelay from fileRelay
793
+ if (!bridgeConfig.messageRelay && bridgeConfig.fileRelay?.baseUrl) {
794
+ const baseUrl = bridgeConfig.fileRelay.baseUrl;
795
+ const wsUrl = baseUrl.replace(/^http/, "ws") + "/ws";
796
+ bridgeConfig.messageRelay = {
797
+ url: wsUrl,
798
+ apiKey: bridgeConfig.fileRelay.apiKey || "",
799
+ };
800
+ console.log(` [${configPath}] Added messageRelay.url = ${wsUrl}`);
801
+ changed = true;
802
+ fixes++;
803
+ }
804
+ // Fix 2: Ensure chatCompletions is enabled (needed for message relay)
805
+ if (!config.gateway?.http?.endpoints?.chatCompletions?.enabled) {
806
+ config.gateway = config.gateway || {};
807
+ config.gateway.http = config.gateway.http || {};
808
+ config.gateway.http.endpoints = config.gateway.http.endpoints || {};
809
+ config.gateway.http.endpoints.chatCompletions = { enabled: true };
810
+ console.log(` [${configPath}] Enabled gateway.http.endpoints.chatCompletions`);
811
+ changed = true;
812
+ fixes++;
813
+ }
814
+ // Fix 3: Check required fields
815
+ const required = ["role", "agentId", "agentName"];
816
+ for (const field of required) {
817
+ if (!bridgeConfig[field]) {
818
+ console.log(` [${configPath}] WARNING: missing required field "${field}" in bridge config`);
819
+ }
820
+ }
821
+ // Fix 4: Check fileRelay and registry baseUrls aren't pointing to localhost in remote setup
822
+ if (bridgeConfig.registry?.baseUrl && bridgeConfig.fileRelay?.baseUrl) {
823
+ const regUrl = bridgeConfig.registry.baseUrl;
824
+ const relayUrl = bridgeConfig.fileRelay.baseUrl;
825
+ if (regUrl.includes("localhost") !== relayUrl.includes("localhost")) {
826
+ console.log(` [${configPath}] WARNING: registry and fileRelay point to different hosts (${regUrl} vs ${relayUrl})`);
827
+ }
828
+ }
829
+ if (changed) {
830
+ writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
831
+ }
832
+ }
833
+ catch (err) {
834
+ console.log(` [${configPath}] Could not parse: ${err.message}`);
835
+ }
836
+ }
837
+ return fixes;
838
+ }
729
839
  // ── Usage ─────────────────────────────────────────────────────────────────────
730
840
  function printUsage() {
731
841
  console.log(`
package/dist/index.js CHANGED
@@ -219,6 +219,25 @@ ${nameMapping}
219
219
  api.logger.info(`[bridge] Conflict rename: ${entry.agentId} → ${newAgentId}, ${entry.agentName} → ${newAgentName}`);
220
220
  entry.agentId = newAgentId;
221
221
  entry.agentName = newAgentName;
222
+ // Persist the renamed agentId to openclaw.json so it survives restarts
223
+ const configPath = process.env.OPENCLAW_CONFIG_PATH;
224
+ if (configPath) {
225
+ try {
226
+ const raw = readFileSync(configPath, "utf-8");
227
+ const cfg = JSON.parse(raw);
228
+ const bridgeCfg = cfg.plugins?.entries?.["openclaw-bridge"]?.config;
229
+ if (bridgeCfg) {
230
+ const oldId = bridgeCfg.agentId;
231
+ bridgeCfg.agentId = newAgentId;
232
+ bridgeCfg.agentName = newAgentName;
233
+ writeFileSync(configPath, JSON.stringify(cfg, null, 2), "utf-8");
234
+ api.logger.info(`[bridge] Permanently renamed in ${configPath}: ${oldId} → ${newAgentId}`);
235
+ }
236
+ }
237
+ catch (err) {
238
+ api.logger.warn(`[bridge] Failed to persist rename to config: ${err.message}`);
239
+ }
240
+ }
222
241
  });
223
242
  try {
224
243
  await relayClient.connect();
package/dist/registry.js CHANGED
@@ -42,8 +42,14 @@ export class BridgeRegistry {
42
42
  body: JSON.stringify(entry),
43
43
  });
44
44
  if (!res.ok) {
45
- // Re-register if heartbeat fails
46
45
  await this.register(entry);
46
+ return;
47
+ }
48
+ // Check for registry-level agentId conflict
49
+ const body = await res.json();
50
+ if (body.error === "agentId_conflict") {
51
+ this.logger.warn(`openclaw-bridge: registry conflict — agentId "${entry.agentId}" belongs to machine "${body.existingMachine}", skipping heartbeat`);
52
+ // Don't re-register — the WebSocket conflict handler will rename us
47
53
  }
48
54
  }
49
55
  catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-bridge",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "author": "Bill Zhao (https://www.linkedin.com/in/billzhaodi/)",
5
5
  "description": "OpenClaw plugin for cross-gateway communication — agent discovery, file transfer, real-time messaging, session handoff, and local process management. Install as plugin: openclaw plugins install openclaw-bridge",
6
6
  "type": "module",