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 +98 -10
- package/dist/index.js +19 -0
- package/dist/registry.js +7 -1
- package/package.json +1 -1
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
|
-
//
|
|
680
|
-
|
|
681
|
-
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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.
|
|
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",
|