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 +120 -10
- package/dist/index.js +19 -0
- package/dist/registry.js +7 -1
- package/package.json +1 -1
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.
|
|
676
|
+
// 1. Try installing/upgrading as OpenClaw plugin
|
|
677
677
|
console.log("Checking OpenClaw plugin installation...");
|
|
678
678
|
try {
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
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("
|
|
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.
|
|
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",
|