openclaw-bridge 0.4.1 → 0.4.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
@@ -676,18 +676,26 @@ async function cmdUpgrade() {
676
676
  // 1. Try installing/upgrading as OpenClaw plugin
677
677
  console.log("Checking OpenClaw plugin installation...");
678
678
  try {
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")) {
679
+ // Use execSync directly to capture both stdout and error output
680
+ let installOutput = "";
681
+ let installFailed = false;
682
+ try {
683
+ installOutput = execSync("openclaw plugins install openclaw-bridge 2>&1", {
684
+ encoding: "utf-8",
685
+ stdio: ["pipe", "pipe", "pipe"],
686
+ }).trim();
687
+ }
688
+ catch (execErr) {
689
+ installOutput = String(execErr?.stdout || "") + String(execErr?.stderr || "") + String(execErr?.message || "");
690
+ installFailed = true;
691
+ }
692
+ if (!installFailed && installOutput) {
682
693
  updatedPlugin = true;
683
694
  console.log(" Plugin installed/updated.");
684
695
  }
685
- }
686
- catch (installErr) {
687
- const errMsg = String(installErr?.stdout || installErr?.message || installErr || "");
688
- if (errMsg.includes("plugin already exists") || errMsg.includes("already exists")) {
696
+ else if (installOutput.includes("already exists")) {
689
697
  // 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*\(/);
698
+ const pathMatch = installOutput.match(/already exists:\s*(.+?)\s*\(/);
691
699
  const existingPath = pathMatch?.[1]?.trim();
692
700
  if (existingPath && existsSync(existingPath)) {
693
701
  console.log(` Old plugin found at ${existingPath}. Removing...`);
@@ -716,14 +724,18 @@ async function cmdUpgrade() {
716
724
  console.log(" Plugin updated.");
717
725
  }
718
726
  catch {
719
- console.log(" Plugin install failed after removing old version. Try manually:");
727
+ console.log(" Plugin install failed. Try manually:");
720
728
  console.log(" openclaw plugins install openclaw-bridge");
721
729
  }
722
730
  }
723
731
  else {
724
- console.log(" openclaw CLI not found or plugins command failed. Skipping plugin check.");
732
+ // Install failed for unknown reason show the output for debugging
733
+ console.log(` Plugin install failed: ${installOutput.slice(0, 200)}`);
725
734
  }
726
735
  }
736
+ catch {
737
+ console.log(" openclaw CLI not found. Skipping plugin check.");
738
+ }
727
739
  // 2. Check if installed as global npm package
728
740
  console.log("\nChecking global npm installation...");
729
741
  try {
@@ -758,8 +770,84 @@ async function cmdUpgrade() {
758
770
  console.log("\nUpgrade complete.");
759
771
  }
760
772
  }
773
+ // 4. Config health check — scan openclaw.json and fix missing settings
774
+ console.log("\nChecking bridge configuration...");
775
+ const configFixCount = checkAndFixBridgeConfig();
776
+ if (configFixCount === 0) {
777
+ console.log(" Config OK — all required settings present.");
778
+ }
779
+ else {
780
+ console.log(` Fixed ${configFixCount} config issue(s). Restart your gateway to apply.`);
781
+ }
761
782
  console.log();
762
783
  }
784
+ /** Scan openclaw.json for missing bridge config fields and auto-fix them */
785
+ function checkAndFixBridgeConfig() {
786
+ // Find openclaw.json — check env var, then common locations
787
+ const candidates = [
788
+ process.env.OPENCLAW_CONFIG_PATH,
789
+ join(process.cwd(), "openclaw.json"),
790
+ join(homedir(), ".openclaw", "openclaw.json"),
791
+ IS_WINDOWS ? "C:\\openclaw-instances\\main\\openclaw.json" : "",
792
+ ].filter(Boolean);
793
+ let fixes = 0;
794
+ for (const configPath of candidates) {
795
+ if (!existsSync(configPath))
796
+ continue;
797
+ try {
798
+ const raw = readFileSync(configPath, "utf-8");
799
+ const config = JSON.parse(raw);
800
+ const bridgeConfig = config.plugins?.entries?.["openclaw-bridge"]?.config;
801
+ if (!bridgeConfig)
802
+ continue;
803
+ let changed = false;
804
+ // Fix 1: Auto-add messageRelay from fileRelay
805
+ if (!bridgeConfig.messageRelay && bridgeConfig.fileRelay?.baseUrl) {
806
+ const baseUrl = bridgeConfig.fileRelay.baseUrl;
807
+ const wsUrl = baseUrl.replace(/^http/, "ws") + "/ws";
808
+ bridgeConfig.messageRelay = {
809
+ url: wsUrl,
810
+ apiKey: bridgeConfig.fileRelay.apiKey || "",
811
+ };
812
+ console.log(` [${configPath}] Added messageRelay.url = ${wsUrl}`);
813
+ changed = true;
814
+ fixes++;
815
+ }
816
+ // Fix 2: Ensure chatCompletions is enabled (needed for message relay)
817
+ if (!config.gateway?.http?.endpoints?.chatCompletions?.enabled) {
818
+ config.gateway = config.gateway || {};
819
+ config.gateway.http = config.gateway.http || {};
820
+ config.gateway.http.endpoints = config.gateway.http.endpoints || {};
821
+ config.gateway.http.endpoints.chatCompletions = { enabled: true };
822
+ console.log(` [${configPath}] Enabled gateway.http.endpoints.chatCompletions`);
823
+ changed = true;
824
+ fixes++;
825
+ }
826
+ // Fix 3: Check required fields
827
+ const required = ["role", "agentId", "agentName"];
828
+ for (const field of required) {
829
+ if (!bridgeConfig[field]) {
830
+ console.log(` [${configPath}] WARNING: missing required field "${field}" in bridge config`);
831
+ }
832
+ }
833
+ // Fix 4: Check fileRelay and registry baseUrls aren't pointing to localhost in remote setup
834
+ if (bridgeConfig.registry?.baseUrl && bridgeConfig.fileRelay?.baseUrl) {
835
+ const regUrl = bridgeConfig.registry.baseUrl;
836
+ const relayUrl = bridgeConfig.fileRelay.baseUrl;
837
+ if (regUrl.includes("localhost") !== relayUrl.includes("localhost")) {
838
+ console.log(` [${configPath}] WARNING: registry and fileRelay point to different hosts (${regUrl} vs ${relayUrl})`);
839
+ }
840
+ }
841
+ if (changed) {
842
+ writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
843
+ }
844
+ }
845
+ catch (err) {
846
+ console.log(` [${configPath}] Could not parse: ${err.message}`);
847
+ }
848
+ }
849
+ return fixes;
850
+ }
763
851
  // ── Usage ─────────────────────────────────────────────────────────────────────
764
852
  function printUsage() {
765
853
  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.1",
3
+ "version": "0.4.3",
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",