@silicaclaw/cli 2026.3.19-15 → 2026.3.19-16
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/CHANGELOG.md +6 -0
- package/INSTALL.md +44 -11
- package/README.md +53 -19
- package/VERSION +1 -1
- package/apps/local-console/dist/apps/local-console/src/server.d.ts +30 -12
- package/apps/local-console/dist/apps/local-console/src/server.js +265 -48
- package/apps/local-console/dist/config/silicaclaw-defaults.json +19 -0
- package/apps/local-console/dist/packages/core/src/socialConfig.js +9 -5
- package/apps/local-console/dist/packages/network/src/realPreview.js +6 -2
- package/apps/local-console/dist/packages/network/src/relayPreview.js +8 -2
- package/apps/local-console/dist/packages/network/src/transport/udpLanBroadcastTransport.js +2 -1
- package/apps/local-console/dist/packages/network/src/webrtcPreview.js +5 -1
- package/apps/local-console/dist/packages/storage/src/socialRuntimeRepo.js +8 -4
- package/apps/local-console/public/app/app.js +17 -1
- package/apps/local-console/public/app/events.js +38 -2
- package/apps/local-console/public/app/network.js +32 -3
- package/apps/local-console/public/app/overview.js +4 -2
- package/apps/local-console/public/app/social.js +175 -26
- package/apps/local-console/public/app/styles.css +182 -14
- package/apps/local-console/public/app/template.js +70 -30
- package/apps/local-console/public/app/translations.js +131 -43
- package/apps/local-console/src/server.ts +281 -50
- package/apps/public-explorer/dist/apps/public-explorer/src/server.d.ts +1 -0
- package/apps/public-explorer/dist/apps/public-explorer/src/server.js +41 -0
- package/apps/public-explorer/dist/config/silicaclaw-defaults.json +19 -0
- package/apps/public-explorer/public/app/app.js +22 -2
- package/apps/public-explorer/public/app/template.js +4 -4
- package/apps/public-explorer/public/app/translations.js +15 -15
- package/apps/public-explorer/src/server.ts +11 -1
- package/docs/NEW_USER_INSTALL.md +14 -10
- package/docs/NEW_USER_OPERATIONS.md +3 -3
- package/docs/OPENCLAW_BRIDGE.md +15 -0
- package/docs/OPENCLAW_BRIDGE_ZH.md +15 -0
- package/node_modules/@silicaclaw/core/dist/config/silicaclaw-defaults.json +19 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/crypto.d.ts +6 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/crypto.js +50 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/directory.d.ts +17 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/directory.js +145 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/identity.d.ts +2 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/identity.js +18 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/index.d.ts +12 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/index.js +28 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/indexing.d.ts +6 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/indexing.js +43 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/presence.d.ts +4 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/presence.js +23 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/profile.d.ts +4 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/profile.js +39 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/publicProfileSummary.d.ts +70 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/publicProfileSummary.js +103 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/socialConfig.d.ts +100 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/socialConfig.js +300 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/socialMessage.d.ts +19 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/socialMessage.js +69 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/socialResolver.d.ts +46 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/socialResolver.js +237 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/socialTemplate.d.ts +2 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/socialTemplate.js +90 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/types.d.ts +59 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/types.js +2 -0
- package/node_modules/@silicaclaw/core/src/socialConfig.ts +7 -5
- package/node_modules/@silicaclaw/network/dist/config/silicaclaw-defaults.json +19 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/messageEnvelope.d.ts +28 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/messageEnvelope.js +36 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/peerDiscovery.d.ts +43 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/peerDiscovery.js +2 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/topicCodec.d.ts +4 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/topicCodec.js +2 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/transport.d.ts +36 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/transport.js +2 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/codec/jsonMessageEnvelopeCodec.d.ts +5 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/codec/jsonMessageEnvelopeCodec.js +24 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/codec/jsonTopicCodec.d.ts +5 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/codec/jsonTopicCodec.js +12 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/discovery/heartbeatPeerDiscovery.d.ts +28 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/discovery/heartbeatPeerDiscovery.js +144 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/index.d.ts +14 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/index.js +30 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/localEventBus.d.ts +9 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/localEventBus.js +47 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/mock.d.ts +8 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/mock.js +24 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/realPreview.d.ts +105 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/realPreview.js +331 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/relayPreview.d.ts +166 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/relayPreview.js +448 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/transport/udpLanBroadcastTransport.d.ts +23 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/transport/udpLanBroadcastTransport.js +154 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/types.d.ts +6 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/types.js +2 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/webrtcPreview.d.ts +163 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/webrtcPreview.js +848 -0
- package/node_modules/@silicaclaw/network/src/realPreview.ts +3 -2
- package/node_modules/@silicaclaw/network/src/relayPreview.ts +5 -2
- package/node_modules/@silicaclaw/network/src/transport/udpLanBroadcastTransport.ts +2 -1
- package/node_modules/@silicaclaw/network/src/webrtcPreview.ts +2 -1
- package/node_modules/@silicaclaw/storage/dist/socialRuntimeRepo.js +8 -4
- package/node_modules/@silicaclaw/storage/src/socialRuntimeRepo.ts +5 -4
- package/openclaw-skills/silicaclaw-bridge-setup/SKILL.md +147 -0
- package/openclaw-skills/silicaclaw-bridge-setup/VERSION +1 -0
- package/openclaw-skills/silicaclaw-bridge-setup/agents/openai.yaml +6 -0
- package/openclaw-skills/silicaclaw-bridge-setup/manifest.json +27 -0
- package/openclaw-skills/silicaclaw-bridge-setup/references/owner-dialogue-cheatsheet-zh.md +58 -0
- package/openclaw-skills/silicaclaw-bridge-setup/references/runtime-setup.md +43 -0
- package/openclaw-skills/silicaclaw-bridge-setup/references/troubleshooting.md +24 -0
- package/openclaw-skills/silicaclaw-broadcast/SKILL.md +132 -0
- package/openclaw-skills/silicaclaw-broadcast/VERSION +1 -1
- package/openclaw-skills/silicaclaw-broadcast/agents/openai.yaml +2 -2
- package/openclaw-skills/silicaclaw-broadcast/manifest.json +3 -2
- package/openclaw-skills/silicaclaw-broadcast/references/owner-dialogue-cheatsheet-zh.md +81 -0
- package/openclaw-skills/silicaclaw-owner-push/SKILL.md +217 -0
- package/openclaw-skills/silicaclaw-owner-push/VERSION +1 -0
- package/openclaw-skills/silicaclaw-owner-push/agents/openai.yaml +6 -0
- package/openclaw-skills/silicaclaw-owner-push/manifest.json +30 -0
- package/openclaw-skills/silicaclaw-owner-push/references/owner-dialogue-cheatsheet-zh.md +87 -0
- package/openclaw-skills/silicaclaw-owner-push/references/push-routing-policy.md +43 -0
- package/openclaw-skills/silicaclaw-owner-push/references/runtime-setup.md +41 -0
- package/openclaw-skills/silicaclaw-owner-push/scripts/owner-push-forwarder.mjs +214 -0
- package/openclaw-skills/silicaclaw-owner-push/scripts/send-to-owner-via-openclaw.mjs +69 -0
- package/package.json +1 -1
- package/packages/core/dist/config/silicaclaw-defaults.json +19 -0
- package/packages/core/dist/packages/core/src/crypto.d.ts +6 -0
- package/packages/core/dist/packages/core/src/crypto.js +50 -0
- package/packages/core/dist/packages/core/src/directory.d.ts +17 -0
- package/packages/core/dist/packages/core/src/directory.js +145 -0
- package/packages/core/dist/packages/core/src/identity.d.ts +2 -0
- package/packages/core/dist/packages/core/src/identity.js +18 -0
- package/packages/core/dist/packages/core/src/index.d.ts +12 -0
- package/packages/core/dist/packages/core/src/index.js +28 -0
- package/packages/core/dist/packages/core/src/indexing.d.ts +6 -0
- package/packages/core/dist/packages/core/src/indexing.js +43 -0
- package/packages/core/dist/packages/core/src/presence.d.ts +4 -0
- package/packages/core/dist/packages/core/src/presence.js +23 -0
- package/packages/core/dist/packages/core/src/profile.d.ts +4 -0
- package/packages/core/dist/packages/core/src/profile.js +39 -0
- package/packages/core/dist/packages/core/src/publicProfileSummary.d.ts +70 -0
- package/packages/core/dist/packages/core/src/publicProfileSummary.js +103 -0
- package/packages/core/dist/packages/core/src/socialConfig.d.ts +100 -0
- package/packages/core/dist/packages/core/src/socialConfig.js +300 -0
- package/packages/core/dist/packages/core/src/socialMessage.d.ts +19 -0
- package/packages/core/dist/packages/core/src/socialMessage.js +69 -0
- package/packages/core/dist/packages/core/src/socialResolver.d.ts +46 -0
- package/packages/core/dist/packages/core/src/socialResolver.js +237 -0
- package/packages/core/dist/packages/core/src/socialTemplate.d.ts +2 -0
- package/packages/core/dist/packages/core/src/socialTemplate.js +90 -0
- package/packages/core/dist/packages/core/src/types.d.ts +59 -0
- package/packages/core/dist/packages/core/src/types.js +2 -0
- package/packages/core/src/socialConfig.ts +7 -5
- package/packages/network/dist/config/silicaclaw-defaults.json +19 -0
- package/packages/network/dist/packages/network/src/abstractions/messageEnvelope.d.ts +28 -0
- package/packages/network/dist/packages/network/src/abstractions/messageEnvelope.js +36 -0
- package/packages/network/dist/packages/network/src/abstractions/peerDiscovery.d.ts +43 -0
- package/packages/network/dist/packages/network/src/abstractions/peerDiscovery.js +2 -0
- package/packages/network/dist/packages/network/src/abstractions/topicCodec.d.ts +4 -0
- package/packages/network/dist/packages/network/src/abstractions/topicCodec.js +2 -0
- package/packages/network/dist/packages/network/src/abstractions/transport.d.ts +36 -0
- package/packages/network/dist/packages/network/src/abstractions/transport.js +2 -0
- package/packages/network/dist/packages/network/src/codec/jsonMessageEnvelopeCodec.d.ts +5 -0
- package/packages/network/dist/packages/network/src/codec/jsonMessageEnvelopeCodec.js +24 -0
- package/packages/network/dist/packages/network/src/codec/jsonTopicCodec.d.ts +5 -0
- package/packages/network/dist/packages/network/src/codec/jsonTopicCodec.js +12 -0
- package/packages/network/dist/packages/network/src/discovery/heartbeatPeerDiscovery.d.ts +28 -0
- package/packages/network/dist/packages/network/src/discovery/heartbeatPeerDiscovery.js +144 -0
- package/packages/network/dist/packages/network/src/index.d.ts +14 -0
- package/packages/network/dist/packages/network/src/index.js +30 -0
- package/packages/network/dist/packages/network/src/localEventBus.d.ts +9 -0
- package/packages/network/dist/packages/network/src/localEventBus.js +47 -0
- package/packages/network/dist/packages/network/src/mock.d.ts +8 -0
- package/packages/network/dist/packages/network/src/mock.js +24 -0
- package/packages/network/dist/packages/network/src/realPreview.d.ts +105 -0
- package/packages/network/dist/packages/network/src/realPreview.js +331 -0
- package/packages/network/dist/packages/network/src/relayPreview.d.ts +166 -0
- package/packages/network/dist/packages/network/src/relayPreview.js +448 -0
- package/packages/network/dist/packages/network/src/transport/udpLanBroadcastTransport.d.ts +23 -0
- package/packages/network/dist/packages/network/src/transport/udpLanBroadcastTransport.js +154 -0
- package/packages/network/dist/packages/network/src/types.d.ts +6 -0
- package/packages/network/dist/packages/network/src/types.js +2 -0
- package/packages/network/dist/packages/network/src/webrtcPreview.d.ts +163 -0
- package/packages/network/dist/packages/network/src/webrtcPreview.js +848 -0
- package/packages/network/src/realPreview.ts +3 -2
- package/packages/network/src/relayPreview.ts +5 -2
- package/packages/network/src/transport/udpLanBroadcastTransport.ts +2 -1
- package/packages/network/src/webrtcPreview.ts +2 -1
- package/packages/storage/dist/socialRuntimeRepo.js +8 -4
- package/packages/storage/src/socialRuntimeRepo.ts +5 -4
- package/scripts/functional-check.mjs +35 -6
- package/scripts/install-openclaw-skill.mjs +9 -2
- package/scripts/openclaw-bridge-adapter.mjs +3 -1
- package/scripts/openclaw-bridge-client.mjs +3 -1
- package/scripts/openclaw-runtime-demo.mjs +3 -1
- package/scripts/quickstart.sh +13 -9
- package/scripts/release-pack.mjs +13 -1
- package/scripts/silicaclaw-cli.mjs +23 -18
- package/scripts/silicaclaw-gateway.mjs +33 -27
- package/scripts/validate-openclaw-skill.mjs +79 -21
|
@@ -6,6 +6,7 @@ import { accessSync, constants, copyFileSync, existsSync, mkdirSync, readFileSyn
|
|
|
6
6
|
import { createHash } from "crypto";
|
|
7
7
|
import { homedir, hostname } from "os";
|
|
8
8
|
import { promisify } from "util";
|
|
9
|
+
import defaults from "../../../config/silicaclaw-defaults.json";
|
|
9
10
|
import {
|
|
10
11
|
AgentIdentity,
|
|
11
12
|
DirectoryState,
|
|
@@ -80,16 +81,22 @@ const NETWORK_MAX_PAST_DRIFT_MS = Number(process.env.NETWORK_MAX_PAST_DRIFT_MS |
|
|
|
80
81
|
const NETWORK_HEARTBEAT_INTERVAL_MS = Number(process.env.NETWORK_HEARTBEAT_INTERVAL_MS || 12_000);
|
|
81
82
|
const NETWORK_PEER_STALE_AFTER_MS = Number(process.env.NETWORK_PEER_STALE_AFTER_MS || 45_000);
|
|
82
83
|
const OPENCLAW_GATEWAY_HOST = "127.0.0.1";
|
|
83
|
-
const
|
|
84
|
+
const DEFAULT_NETWORK_MODE = defaults.network.default_mode as "global-preview";
|
|
85
|
+
const DEFAULT_NETWORK_NAMESPACE = defaults.network.default_namespace;
|
|
86
|
+
const DEFAULT_NETWORK_PORT = defaults.ports.network_default;
|
|
87
|
+
const DEFAULT_GLOBAL_SIGNALING_URL = defaults.network.global_preview.relay_url;
|
|
88
|
+
const DEFAULT_GLOBAL_ROOM = defaults.network.global_preview.room;
|
|
89
|
+
const DEFAULT_BRIDGE_API_BASE = defaults.bridge.api_base;
|
|
90
|
+
const OPENCLAW_GATEWAY_PORT = defaults.ports.openclaw_gateway;
|
|
84
91
|
const OPENCLAW_GATEWAY_URL = `http://${OPENCLAW_GATEWAY_HOST}:${OPENCLAW_GATEWAY_PORT}/`;
|
|
85
92
|
const NETWORK_PEER_REMOVE_AFTER_MS = Number(process.env.NETWORK_PEER_REMOVE_AFTER_MS || 180_000);
|
|
86
93
|
const NETWORK_UDP_BIND_ADDRESS = process.env.NETWORK_UDP_BIND_ADDRESS || "0.0.0.0";
|
|
87
94
|
const NETWORK_UDP_BROADCAST_ADDRESS = process.env.NETWORK_UDP_BROADCAST_ADDRESS || "255.255.255.255";
|
|
88
95
|
const NETWORK_PEER_ID = process.env.NETWORK_PEER_ID;
|
|
89
96
|
const NETWORK_MODE = process.env.NETWORK_MODE || "";
|
|
90
|
-
const WEBRTC_SIGNALING_URL = process.env.WEBRTC_SIGNALING_URL ||
|
|
97
|
+
const WEBRTC_SIGNALING_URL = process.env.WEBRTC_SIGNALING_URL || DEFAULT_GLOBAL_SIGNALING_URL;
|
|
91
98
|
const WEBRTC_SIGNALING_URLS = process.env.WEBRTC_SIGNALING_URLS || "";
|
|
92
|
-
const WEBRTC_ROOM = process.env.WEBRTC_ROOM ||
|
|
99
|
+
const WEBRTC_ROOM = process.env.WEBRTC_ROOM || DEFAULT_GLOBAL_ROOM;
|
|
93
100
|
const WEBRTC_SEED_PEERS = process.env.WEBRTC_SEED_PEERS || "";
|
|
94
101
|
const WEBRTC_BOOTSTRAP_HINTS = process.env.WEBRTC_BOOTSTRAP_HINTS || "";
|
|
95
102
|
const PROFILE_VERSION = "v0.9";
|
|
@@ -133,6 +140,40 @@ function readWorkspaceVersion(workspaceRoot: string): string {
|
|
|
133
140
|
return "unknown";
|
|
134
141
|
}
|
|
135
142
|
|
|
143
|
+
function normalizeVersionText(value: unknown): string {
|
|
144
|
+
const text = String(value || "").trim();
|
|
145
|
+
return text.startsWith("v") ? text.slice(1) : text;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function tokenizeVersion(value: unknown): Array<number | string> {
|
|
149
|
+
return normalizeVersionText(value)
|
|
150
|
+
.split(/[^0-9A-Za-z]+/)
|
|
151
|
+
.map((token) => token.trim())
|
|
152
|
+
.filter(Boolean)
|
|
153
|
+
.map((token) => (/^\d+$/.test(token) ? Number(token) : token.toLowerCase()));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function compareVersionTokens(left: unknown, right: unknown): number {
|
|
157
|
+
const leftTokens = tokenizeVersion(left);
|
|
158
|
+
const rightTokens = tokenizeVersion(right);
|
|
159
|
+
const maxLength = Math.max(leftTokens.length, rightTokens.length);
|
|
160
|
+
for (let index = 0; index < maxLength; index += 1) {
|
|
161
|
+
const leftToken = leftTokens[index];
|
|
162
|
+
const rightToken = rightTokens[index];
|
|
163
|
+
if (leftToken === undefined && rightToken === undefined) return 0;
|
|
164
|
+
if (leftToken === undefined) return -1;
|
|
165
|
+
if (rightToken === undefined) return 1;
|
|
166
|
+
if (typeof leftToken === "number" && typeof rightToken === "number") {
|
|
167
|
+
if (leftToken !== rightToken) return leftToken > rightToken ? 1 : -1;
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
const leftText = String(leftToken);
|
|
171
|
+
const rightText = String(rightToken);
|
|
172
|
+
if (leftText !== rightText) return leftText.localeCompare(rightText);
|
|
173
|
+
}
|
|
174
|
+
return 0;
|
|
175
|
+
}
|
|
176
|
+
|
|
136
177
|
function resolveWorkspaceRoot(cwd = process.cwd()): string {
|
|
137
178
|
if (existsSync(resolve(cwd, "apps", "local-console", "package.json"))) {
|
|
138
179
|
return cwd;
|
|
@@ -149,6 +190,12 @@ function resolveProjectRoot(appRoot: string, cwd = process.cwd()): string {
|
|
|
149
190
|
if (envRoot) {
|
|
150
191
|
return resolve(envRoot);
|
|
151
192
|
}
|
|
193
|
+
if (
|
|
194
|
+
existsSync(resolve(appRoot, "apps", "local-console", "package.json")) &&
|
|
195
|
+
existsSync(resolve(appRoot, "package.json"))
|
|
196
|
+
) {
|
|
197
|
+
return appRoot;
|
|
198
|
+
}
|
|
152
199
|
if (!existsSync(resolve(cwd, "apps", "local-console", "package.json"))) {
|
|
153
200
|
return resolve(cwd);
|
|
154
201
|
}
|
|
@@ -236,6 +283,50 @@ function summarizeSkillReadme(filePath: string) {
|
|
|
236
283
|
}
|
|
237
284
|
}
|
|
238
285
|
|
|
286
|
+
function readDialogueCheatsheetPreview(filePath: string, limit = 6) {
|
|
287
|
+
if (!filePath || !existsSync(filePath)) return [];
|
|
288
|
+
try {
|
|
289
|
+
return readFileSync(filePath, "utf8")
|
|
290
|
+
.split(/\r?\n/)
|
|
291
|
+
.map((line) => line.trim())
|
|
292
|
+
.filter((line) => line.startsWith("- "))
|
|
293
|
+
.map((line) => line.slice(2).trim())
|
|
294
|
+
.filter(Boolean)
|
|
295
|
+
.slice(0, limit);
|
|
296
|
+
} catch {
|
|
297
|
+
return [];
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function readDialogueCheatsheetSections(filePath: string, maxSections = 3, maxItemsPerSection = 5) {
|
|
302
|
+
if (!filePath || !existsSync(filePath)) return [];
|
|
303
|
+
try {
|
|
304
|
+
const lines = readFileSync(filePath, "utf8").split(/\r?\n/);
|
|
305
|
+
const sections: Array<{ title: string; items: string[] }> = [];
|
|
306
|
+
let current: { title: string; items: string[] } | null = null;
|
|
307
|
+
for (const rawLine of lines) {
|
|
308
|
+
const line = rawLine.trim();
|
|
309
|
+
if (line.startsWith("## ")) {
|
|
310
|
+
if (current && current.items.length) sections.push(current);
|
|
311
|
+
current = { title: line.slice(3).trim(), items: [] };
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
314
|
+
if (line.startsWith("- ")) {
|
|
315
|
+
if (!current) {
|
|
316
|
+
current = { title: "Examples", items: [] };
|
|
317
|
+
}
|
|
318
|
+
if (current.items.length < maxItemsPerSection) {
|
|
319
|
+
current.items.push(line.slice(2).trim());
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
if (current && current.items.length) sections.push(current);
|
|
324
|
+
return sections.slice(0, maxSections);
|
|
325
|
+
} catch {
|
|
326
|
+
return [];
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
239
330
|
function detectOpenClawInstallation(workspaceRoot: string) {
|
|
240
331
|
const workspaceDir = resolve(workspaceRoot, ".openclaw");
|
|
241
332
|
const homeDir = resolve(process.env.HOME || "", ".openclaw");
|
|
@@ -795,7 +886,7 @@ export class LocalNodeService {
|
|
|
795
886
|
|
|
796
887
|
private network: NetworkAdapter;
|
|
797
888
|
private adapterMode: "mock" | "local-event-bus" | "real-preview" | "webrtc-preview" | "relay-preview";
|
|
798
|
-
private networkMode: "local" | "lan" | "global-preview" =
|
|
889
|
+
private networkMode: "local" | "lan" | "global-preview" = DEFAULT_NETWORK_MODE;
|
|
799
890
|
private networkNamespace: string;
|
|
800
891
|
private networkPort: number | null;
|
|
801
892
|
private socialConfig: SocialConfig;
|
|
@@ -809,7 +900,7 @@ export class LocalNodeService {
|
|
|
809
900
|
"silicaclaw-existing";
|
|
810
901
|
private resolvedOpenClawIdentityPath: string | null = null;
|
|
811
902
|
private webrtcSignalingUrls: string[] = [];
|
|
812
|
-
private webrtcRoom =
|
|
903
|
+
private webrtcRoom = DEFAULT_GLOBAL_ROOM;
|
|
813
904
|
private webrtcSeedPeers: string[] = [];
|
|
814
905
|
private webrtcBootstrapHints: string[] = [];
|
|
815
906
|
private webrtcBootstrapSources: string[] = [];
|
|
@@ -838,7 +929,7 @@ export class LocalNodeService {
|
|
|
838
929
|
display_name: this.getDefaultDisplayName(),
|
|
839
930
|
bio: "Local AI agent connected to SilicaClaw",
|
|
840
931
|
tags: ["openclaw", "local-first"],
|
|
841
|
-
mode:
|
|
932
|
+
mode: DEFAULT_NETWORK_MODE,
|
|
842
933
|
public_enabled: false,
|
|
843
934
|
});
|
|
844
935
|
loadedSocial = loadSocialConfig(this.projectRoot);
|
|
@@ -850,8 +941,8 @@ export class LocalNodeService {
|
|
|
850
941
|
this.socialParseError = loadedSocial.meta.parse_error;
|
|
851
942
|
this.socialRawFrontmatter = loadedSocial.raw_frontmatter;
|
|
852
943
|
|
|
853
|
-
this.networkNamespace = this.socialConfig.network.namespace || process.env.NETWORK_NAMESPACE ||
|
|
854
|
-
this.networkPort = Number(this.socialConfig.network.port || process.env.NETWORK_PORT ||
|
|
944
|
+
this.networkNamespace = this.socialConfig.network.namespace || process.env.NETWORK_NAMESPACE || DEFAULT_NETWORK_NAMESPACE;
|
|
945
|
+
this.networkPort = Number(this.socialConfig.network.port || process.env.NETWORK_PORT || DEFAULT_NETWORK_PORT);
|
|
855
946
|
this.applyResolvedNetworkConfig();
|
|
856
947
|
const resolved = this.buildNetworkAdapter();
|
|
857
948
|
this.network = resolved.adapter;
|
|
@@ -903,12 +994,8 @@ export class LocalNodeService {
|
|
|
903
994
|
}
|
|
904
995
|
|
|
905
996
|
getOverview() {
|
|
906
|
-
this.
|
|
907
|
-
|
|
908
|
-
const profiles = Object.values(this.directory.profiles);
|
|
909
|
-
const onlineCount = profiles.filter((profile) =>
|
|
910
|
-
isAgentOnline(this.directory.presence[profile.agent_id], Date.now(), PRESENCE_TTL_MS)
|
|
911
|
-
).length;
|
|
997
|
+
const discovered = this.search("");
|
|
998
|
+
const onlineCount = discovered.filter((profile) => profile.online).length;
|
|
912
999
|
|
|
913
1000
|
return {
|
|
914
1001
|
app_version: this.appVersion,
|
|
@@ -919,9 +1006,9 @@ export class LocalNodeService {
|
|
|
919
1006
|
last_broadcast_error_at: this.lastBroadcastErrorAt,
|
|
920
1007
|
last_broadcast_error: this.lastBroadcastError,
|
|
921
1008
|
broadcast_failure_count: this.broadcastFailureCount,
|
|
922
|
-
discovered_count:
|
|
1009
|
+
discovered_count: discovered.length,
|
|
923
1010
|
online_count: onlineCount,
|
|
924
|
-
offline_count: Math.max(0,
|
|
1011
|
+
offline_count: Math.max(0, discovered.length - onlineCount),
|
|
925
1012
|
init_state: this.initState,
|
|
926
1013
|
presence_ttl_ms: PRESENCE_TTL_MS,
|
|
927
1014
|
onboarding: this.getOnboardingSummary(),
|
|
@@ -1307,20 +1394,36 @@ export class LocalNodeService {
|
|
|
1307
1394
|
}
|
|
1308
1395
|
|
|
1309
1396
|
async setNetworkModeRuntime(mode: "local" | "lan" | "global-preview") {
|
|
1310
|
-
const
|
|
1397
|
+
const before = {
|
|
1398
|
+
mode: this.networkMode,
|
|
1399
|
+
adapter: this.adapterMode,
|
|
1400
|
+
namespace: this.networkNamespace,
|
|
1401
|
+
port: this.networkPort,
|
|
1402
|
+
};
|
|
1311
1403
|
if (mode !== "local" && mode !== "lan" && mode !== "global-preview") {
|
|
1312
1404
|
throw new Error("invalid_network_mode");
|
|
1313
1405
|
}
|
|
1314
1406
|
this.socialConfig.network.mode = mode;
|
|
1315
1407
|
this.socialConfig.network.adapter = this.adapterForMode(mode);
|
|
1316
1408
|
this.applyResolvedNetworkConfig();
|
|
1317
|
-
|
|
1409
|
+
|
|
1410
|
+
const needsRestart =
|
|
1411
|
+
before.mode !== this.networkMode ||
|
|
1412
|
+
before.adapter !== this.socialConfig.network.adapter ||
|
|
1413
|
+
before.namespace !== this.networkNamespace ||
|
|
1414
|
+
(before.port ?? null) !== (this.networkPort ?? null);
|
|
1415
|
+
|
|
1416
|
+
if (needsRestart) {
|
|
1417
|
+
await this.restartNetworkAdapter("set_network_mode_runtime");
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1420
|
+
this.socialNetworkRequiresRestart = false;
|
|
1318
1421
|
await this.writeSocialRuntime();
|
|
1319
1422
|
return {
|
|
1320
1423
|
mode: this.networkMode,
|
|
1321
|
-
adapter: this.
|
|
1322
|
-
network_requires_restart:
|
|
1323
|
-
note: "Runtime mode updated. Existing social.md is unchanged.",
|
|
1424
|
+
adapter: this.adapterMode,
|
|
1425
|
+
network_requires_restart: false,
|
|
1426
|
+
note: "Runtime mode updated and adapter restarted. Existing social.md is unchanged.",
|
|
1324
1427
|
};
|
|
1325
1428
|
}
|
|
1326
1429
|
|
|
@@ -1335,7 +1438,7 @@ export class LocalNodeService {
|
|
|
1335
1438
|
this.socialConfig.network.adapter = "relay-preview";
|
|
1336
1439
|
this.socialConfig.network.signaling_url = signalingUrl;
|
|
1337
1440
|
this.socialConfig.network.signaling_urls = [signalingUrl];
|
|
1338
|
-
this.socialConfig.network.room = room ||
|
|
1441
|
+
this.socialConfig.network.room = room || DEFAULT_GLOBAL_ROOM;
|
|
1339
1442
|
this.applyResolvedNetworkConfig();
|
|
1340
1443
|
await this.restartNetworkAdapter("quick_connect_global_preview");
|
|
1341
1444
|
this.socialNetworkRequiresRestart = false;
|
|
@@ -1382,6 +1485,11 @@ export class LocalNodeService {
|
|
|
1382
1485
|
before.namespace !== after.namespace ||
|
|
1383
1486
|
(before.port ?? null) !== (after.port ?? null);
|
|
1384
1487
|
|
|
1488
|
+
if (this.socialNetworkRequiresRestart) {
|
|
1489
|
+
await this.restartNetworkAdapter("reload_social_config");
|
|
1490
|
+
this.socialNetworkRequiresRestart = false;
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1385
1493
|
await this.writeSocialRuntime();
|
|
1386
1494
|
|
|
1387
1495
|
return this.getSocialConfigView();
|
|
@@ -1415,10 +1523,11 @@ export class LocalNodeService {
|
|
|
1415
1523
|
search(keyword: string): PublicProfileSummary[] {
|
|
1416
1524
|
this.ensureLocalDirectoryBaseline();
|
|
1417
1525
|
this.compactCacheInMemory();
|
|
1418
|
-
|
|
1526
|
+
const directMatches = searchDirectory(this.directory, keyword, { presenceTTLms: PRESENCE_TTL_MS }).map((profile) => {
|
|
1419
1527
|
const lastSeenAt = this.directory.presence[profile.agent_id] ?? 0;
|
|
1420
1528
|
return this.toPublicProfileSummary(profile, { last_seen_at: lastSeenAt });
|
|
1421
1529
|
});
|
|
1530
|
+
return this.mergeMessageOnlyAgentSummaries(directMatches, keyword);
|
|
1422
1531
|
}
|
|
1423
1532
|
|
|
1424
1533
|
getPublicProfilePreview(): PublicProfileSummary | null {
|
|
@@ -1563,9 +1672,13 @@ export class LocalNodeService {
|
|
|
1563
1672
|
};
|
|
1564
1673
|
}
|
|
1565
1674
|
|
|
1566
|
-
async installOpenClawSkill() {
|
|
1675
|
+
async installOpenClawSkill(skillName?: string) {
|
|
1567
1676
|
const scriptPath = resolve(this.workspaceRoot, "scripts", "install-openclaw-skill.mjs");
|
|
1568
|
-
const
|
|
1677
|
+
const args = [scriptPath];
|
|
1678
|
+
if (skillName) {
|
|
1679
|
+
args.push(`--skill=${skillName}`);
|
|
1680
|
+
}
|
|
1681
|
+
const { stdout } = await execFileAsync(process.execPath, args, {
|
|
1569
1682
|
cwd: this.workspaceRoot,
|
|
1570
1683
|
env: { ...process.env, SILICACLAW_WORKSPACE_DIR: this.projectRoot },
|
|
1571
1684
|
maxBuffer: 1024 * 1024,
|
|
@@ -1595,7 +1708,7 @@ export class LocalNodeService {
|
|
|
1595
1708
|
const openclawRuntime = detectOpenClawRuntime(this.projectRoot);
|
|
1596
1709
|
|
|
1597
1710
|
return {
|
|
1598
|
-
bridge_api_base:
|
|
1711
|
+
bridge_api_base: DEFAULT_BRIDGE_API_BASE,
|
|
1599
1712
|
openclaw_detected: detectOpenClawInstallation(this.projectRoot).detected,
|
|
1600
1713
|
openclaw_running: openclawRuntime.running,
|
|
1601
1714
|
openclaw_gateway_host: OPENCLAW_GATEWAY_HOST,
|
|
@@ -1605,7 +1718,7 @@ export class LocalNodeService {
|
|
|
1605
1718
|
openclaw_workspace_skill_dir: workspaceSkillDir,
|
|
1606
1719
|
openclaw_legacy_skill_dir: legacySkillDir,
|
|
1607
1720
|
silicaclaw_env_template_path: resolve(this.workspaceRoot, "openclaw-owner-forward.env.example"),
|
|
1608
|
-
recommended_skill_name: "silicaclaw-
|
|
1721
|
+
recommended_skill_name: "silicaclaw-bridge-setup",
|
|
1609
1722
|
recommended_install_command: "silicaclaw openclaw-skill-install",
|
|
1610
1723
|
recommended_owner_forward_env: {
|
|
1611
1724
|
OPENCLAW_SOURCE_DIR: openclawSourceDir,
|
|
@@ -1623,6 +1736,7 @@ export class LocalNodeService {
|
|
|
1623
1736
|
].join(" "),
|
|
1624
1737
|
notes: [
|
|
1625
1738
|
"Install and maintain the skill from SilicaClaw; do not edit OpenClaw core source for this integration.",
|
|
1739
|
+
"Use silicaclaw-bridge-setup first when OpenClaw still needs local install, readiness checks, or troubleshooting guidance.",
|
|
1626
1740
|
"OpenClaw learns broadcasts via the installed skill under ~/.openclaw/workspace/skills/.",
|
|
1627
1741
|
"Runtime detection prefers the actual OpenClaw gateway listener port, then falls back to OpenClaw's own openclaw.json gateway.port.",
|
|
1628
1742
|
"Owner delivery runs through OpenClaw's own message channel stack after the skill forwards a summary.",
|
|
@@ -1642,6 +1756,12 @@ export class LocalNodeService {
|
|
|
1642
1756
|
const skillPath = resolve(dir.path, "SKILL.md");
|
|
1643
1757
|
const versionPath = resolve(dir.path, "VERSION");
|
|
1644
1758
|
const manifest = readJsonFileSafe(manifestPath);
|
|
1759
|
+
const references = (manifest?.references && typeof manifest.references === "object")
|
|
1760
|
+
? manifest.references as Record<string, unknown>
|
|
1761
|
+
: null;
|
|
1762
|
+
const ownerDialogueCheatsheetPath = references?.owner_dialogue_cheatsheet_zh
|
|
1763
|
+
? resolve(dir.path, String(references.owner_dialogue_cheatsheet_zh))
|
|
1764
|
+
: null;
|
|
1645
1765
|
const name = String(manifest?.name || dir.name);
|
|
1646
1766
|
const capabilities = Array.isArray(manifest?.capabilities)
|
|
1647
1767
|
? manifest.capabilities.map((item) => String(item))
|
|
@@ -1661,6 +1781,9 @@ export class LocalNodeService {
|
|
|
1661
1781
|
skill_path: existsSync(skillPath) ? skillPath : null,
|
|
1662
1782
|
capabilities,
|
|
1663
1783
|
transport: manifest?.transport || null,
|
|
1784
|
+
owner_dialogue_cheatsheet_path: ownerDialogueCheatsheetPath && existsSync(ownerDialogueCheatsheetPath) ? ownerDialogueCheatsheetPath : null,
|
|
1785
|
+
owner_dialogue_examples_zh: ownerDialogueCheatsheetPath ? readDialogueCheatsheetPreview(ownerDialogueCheatsheetPath) : [],
|
|
1786
|
+
owner_dialogue_sections_zh: ownerDialogueCheatsheetPath ? readDialogueCheatsheetSections(ownerDialogueCheatsheetPath) : [],
|
|
1664
1787
|
installed_in_openclaw: installedInWorkspace || installedInLegacy,
|
|
1665
1788
|
install_mode: installedInWorkspace ? "workspace" : installedInLegacy ? "legacy" : "not_installed",
|
|
1666
1789
|
installed_path: installedInWorkspace ? installedWorkspacePath : installedInLegacy ? installedLegacyPath : null,
|
|
@@ -1675,6 +1798,12 @@ export class LocalNodeService {
|
|
|
1675
1798
|
const skillPath = resolve(dir.path, "SKILL.md");
|
|
1676
1799
|
const versionPath = resolve(dir.path, "VERSION");
|
|
1677
1800
|
const manifest = readJsonFileSafe(manifestPath);
|
|
1801
|
+
const references = (manifest?.references && typeof manifest.references === "object")
|
|
1802
|
+
? manifest.references as Record<string, unknown>
|
|
1803
|
+
: null;
|
|
1804
|
+
const ownerDialogueCheatsheetPath = references?.owner_dialogue_cheatsheet_zh
|
|
1805
|
+
? resolve(dir.path, String(references.owner_dialogue_cheatsheet_zh))
|
|
1806
|
+
: null;
|
|
1678
1807
|
return {
|
|
1679
1808
|
key: `${dir.install_mode}:${dir.name}`,
|
|
1680
1809
|
name: String(manifest?.name || dir.name),
|
|
@@ -1686,10 +1815,43 @@ export class LocalNodeService {
|
|
|
1686
1815
|
manifest_path: existsSync(manifestPath) ? manifestPath : null,
|
|
1687
1816
|
skill_path: existsSync(skillPath) ? skillPath : null,
|
|
1688
1817
|
capabilities: Array.isArray(manifest?.capabilities) ? manifest.capabilities.map((item) => String(item)) : [],
|
|
1818
|
+
owner_dialogue_cheatsheet_path: ownerDialogueCheatsheetPath && existsSync(ownerDialogueCheatsheetPath) ? ownerDialogueCheatsheetPath : null,
|
|
1819
|
+
owner_dialogue_examples_zh: ownerDialogueCheatsheetPath ? readDialogueCheatsheetPreview(ownerDialogueCheatsheetPath) : [],
|
|
1820
|
+
owner_dialogue_sections_zh: ownerDialogueCheatsheetPath ? readDialogueCheatsheetSections(ownerDialogueCheatsheetPath) : [],
|
|
1689
1821
|
bundled_source_path: bundledSkills.find((item) => item.name === String(manifest?.name || dir.name))?.source_path || null,
|
|
1690
1822
|
};
|
|
1691
1823
|
});
|
|
1692
1824
|
|
|
1825
|
+
const installedSkillVersions = new Map(installedSkills.map((item) => [item.name, item.version]));
|
|
1826
|
+
const bundledSkillsWithUpdateState = bundledSkills.map((skill) => {
|
|
1827
|
+
const installedVersion = installedSkillVersions.get(skill.name) || "";
|
|
1828
|
+
const updateAvailable = Boolean(
|
|
1829
|
+
skill.installed_in_openclaw &&
|
|
1830
|
+
installedVersion &&
|
|
1831
|
+
skill.version &&
|
|
1832
|
+
compareVersionTokens(installedVersion, skill.version) < 0
|
|
1833
|
+
);
|
|
1834
|
+
return {
|
|
1835
|
+
...skill,
|
|
1836
|
+
installed_version: installedVersion || null,
|
|
1837
|
+
update_available: updateAvailable,
|
|
1838
|
+
};
|
|
1839
|
+
});
|
|
1840
|
+
const bundledSkillVersions = new Map(bundledSkillsWithUpdateState.map((item) => [item.name, item.version]));
|
|
1841
|
+
const installedSkillsWithUpdateState = installedSkills.map((skill) => {
|
|
1842
|
+
const bundledVersion = bundledSkillVersions.get(skill.name) || "";
|
|
1843
|
+
const updateAvailable = Boolean(
|
|
1844
|
+
bundledVersion &&
|
|
1845
|
+
skill.version &&
|
|
1846
|
+
compareVersionTokens(skill.version, bundledVersion) < 0
|
|
1847
|
+
);
|
|
1848
|
+
return {
|
|
1849
|
+
...skill,
|
|
1850
|
+
bundled_version: bundledVersion || null,
|
|
1851
|
+
update_available: updateAvailable,
|
|
1852
|
+
};
|
|
1853
|
+
});
|
|
1854
|
+
|
|
1693
1855
|
return {
|
|
1694
1856
|
openclaw: {
|
|
1695
1857
|
detected: bridge.openclaw_installation.detected,
|
|
@@ -1700,13 +1862,14 @@ export class LocalNodeService {
|
|
|
1700
1862
|
legacy_install_root: legacyInstallRoot,
|
|
1701
1863
|
},
|
|
1702
1864
|
summary: {
|
|
1703
|
-
bundled_count:
|
|
1704
|
-
installed_count:
|
|
1705
|
-
installed_bundled_count:
|
|
1865
|
+
bundled_count: bundledSkillsWithUpdateState.length,
|
|
1866
|
+
installed_count: installedSkillsWithUpdateState.length,
|
|
1867
|
+
installed_bundled_count: bundledSkillsWithUpdateState.filter((item) => item.installed_in_openclaw).length,
|
|
1868
|
+
update_available_count: bundledSkillsWithUpdateState.filter((item) => item.update_available).length,
|
|
1706
1869
|
},
|
|
1707
1870
|
install_action: bridge.skill_learning.install_action,
|
|
1708
|
-
bundled_skills:
|
|
1709
|
-
installed_skills:
|
|
1871
|
+
bundled_skills: bundledSkillsWithUpdateState,
|
|
1872
|
+
installed_skills: installedSkillsWithUpdateState,
|
|
1710
1873
|
};
|
|
1711
1874
|
}
|
|
1712
1875
|
|
|
@@ -2345,6 +2508,7 @@ export class LocalNodeService {
|
|
|
2345
2508
|
this.network = next.adapter;
|
|
2346
2509
|
this.adapterMode = next.mode;
|
|
2347
2510
|
this.networkPort = next.port;
|
|
2511
|
+
this.subscriptionsBound = false;
|
|
2348
2512
|
|
|
2349
2513
|
await this.network.start();
|
|
2350
2514
|
this.bindNetworkSubscriptions();
|
|
@@ -2464,6 +2628,72 @@ export class LocalNodeService {
|
|
|
2464
2628
|
});
|
|
2465
2629
|
}
|
|
2466
2630
|
|
|
2631
|
+
private mergeMessageOnlyAgentSummaries(
|
|
2632
|
+
summaries: PublicProfileSummary[],
|
|
2633
|
+
keyword: string
|
|
2634
|
+
): PublicProfileSummary[] {
|
|
2635
|
+
const normalizedKeyword = String(keyword || "").trim().toLowerCase();
|
|
2636
|
+
const knownAgentIds = new Set(summaries.map((item) => item.agent_id));
|
|
2637
|
+
const messageOnly: PublicProfileSummary[] = [];
|
|
2638
|
+
|
|
2639
|
+
for (const message of this.socialMessages) {
|
|
2640
|
+
if (!message?.agent_id || knownAgentIds.has(message.agent_id)) {
|
|
2641
|
+
continue;
|
|
2642
|
+
}
|
|
2643
|
+
|
|
2644
|
+
const displayName = String(message.display_name || "Unnamed").trim() || "Unnamed";
|
|
2645
|
+
if (normalizedKeyword) {
|
|
2646
|
+
const haystacks = [
|
|
2647
|
+
displayName.toLowerCase(),
|
|
2648
|
+
message.agent_id.toLowerCase(),
|
|
2649
|
+
String(message.topic || "").toLowerCase(),
|
|
2650
|
+
];
|
|
2651
|
+
if (!haystacks.some((value) => value.includes(normalizedKeyword))) {
|
|
2652
|
+
continue;
|
|
2653
|
+
}
|
|
2654
|
+
}
|
|
2655
|
+
|
|
2656
|
+
knownAgentIds.add(message.agent_id);
|
|
2657
|
+
messageOnly.push(
|
|
2658
|
+
buildPublicProfileSummary({
|
|
2659
|
+
profile: {
|
|
2660
|
+
agent_id: message.agent_id,
|
|
2661
|
+
display_name: displayName,
|
|
2662
|
+
bio: "Seen from signed public message. Profile/presence not synced yet.",
|
|
2663
|
+
tags: ["message-only"],
|
|
2664
|
+
avatar_url: "",
|
|
2665
|
+
public_enabled: true,
|
|
2666
|
+
updated_at: message.created_at,
|
|
2667
|
+
signature: "",
|
|
2668
|
+
},
|
|
2669
|
+
online: false,
|
|
2670
|
+
last_seen_at: null,
|
|
2671
|
+
network_mode: "unknown",
|
|
2672
|
+
openclaw_bound: false,
|
|
2673
|
+
profile_version: PROFILE_VERSION,
|
|
2674
|
+
public_key_fingerprint: null,
|
|
2675
|
+
verified_profile: false,
|
|
2676
|
+
now: Date.now(),
|
|
2677
|
+
presence_ttl_ms: PRESENCE_TTL_MS,
|
|
2678
|
+
})
|
|
2679
|
+
);
|
|
2680
|
+
}
|
|
2681
|
+
|
|
2682
|
+
return [...summaries, ...messageOnly].sort((a, b) => {
|
|
2683
|
+
if (a.online !== b.online) {
|
|
2684
|
+
return a.online ? -1 : 1;
|
|
2685
|
+
}
|
|
2686
|
+
if (a.updated_at !== b.updated_at) {
|
|
2687
|
+
return b.updated_at - a.updated_at;
|
|
2688
|
+
}
|
|
2689
|
+
const byName = a.display_name.localeCompare(b.display_name);
|
|
2690
|
+
if (byName !== 0) {
|
|
2691
|
+
return byName;
|
|
2692
|
+
}
|
|
2693
|
+
return a.agent_id.localeCompare(b.agent_id);
|
|
2694
|
+
});
|
|
2695
|
+
}
|
|
2696
|
+
|
|
2467
2697
|
private fingerprintPublicKey(publicKey: string): string {
|
|
2468
2698
|
const digest = createHash("sha256").update(publicKey, "utf8").digest("hex");
|
|
2469
2699
|
return `${digest.slice(0, 12)}:${digest.slice(-8)}`;
|
|
@@ -2524,7 +2754,7 @@ export class LocalNodeService {
|
|
|
2524
2754
|
};
|
|
2525
2755
|
}
|
|
2526
2756
|
return {
|
|
2527
|
-
mode:
|
|
2757
|
+
mode: DEFAULT_NETWORK_MODE,
|
|
2528
2758
|
short_label: "Relay preview",
|
|
2529
2759
|
summary: "Uses the public relay preview room so public nodes can find each other across the internet.",
|
|
2530
2760
|
};
|
|
@@ -2554,14 +2784,14 @@ export class LocalNodeService {
|
|
|
2554
2784
|
this.socialConfig.network.mode ||
|
|
2555
2785
|
(modeEnv === "local" || modeEnv === "lan" || modeEnv === "global-preview"
|
|
2556
2786
|
? modeEnv
|
|
2557
|
-
:
|
|
2787
|
+
: DEFAULT_NETWORK_MODE);
|
|
2558
2788
|
|
|
2559
2789
|
this.networkMode = resolvedMode;
|
|
2560
|
-
this.networkNamespace = this.socialConfig.network.namespace || process.env.NETWORK_NAMESPACE ||
|
|
2561
|
-
this.networkPort = Number(this.socialConfig.network.port || process.env.NETWORK_PORT ||
|
|
2790
|
+
this.networkNamespace = this.socialConfig.network.namespace || process.env.NETWORK_NAMESPACE || DEFAULT_NETWORK_NAMESPACE;
|
|
2791
|
+
this.networkPort = Number(this.socialConfig.network.port || process.env.NETWORK_PORT || DEFAULT_NETWORK_PORT);
|
|
2562
2792
|
|
|
2563
|
-
const builtInGlobalSignalingUrls = [
|
|
2564
|
-
const builtInGlobalRoom =
|
|
2793
|
+
const builtInGlobalSignalingUrls = [DEFAULT_GLOBAL_SIGNALING_URL];
|
|
2794
|
+
const builtInGlobalRoom = DEFAULT_GLOBAL_ROOM;
|
|
2565
2795
|
|
|
2566
2796
|
const signalingUrlsSocial = dedupeStrings(this.socialConfig.network.signaling_urls || []);
|
|
2567
2797
|
const signalingUrlSocial = String(this.socialConfig.network.signaling_url || "").trim();
|
|
@@ -2586,8 +2816,8 @@ export class LocalNodeService {
|
|
|
2586
2816
|
signalingUrls = builtInGlobalSignalingUrls;
|
|
2587
2817
|
signalingSource = "built-in-defaults:global-preview.signaling_urls";
|
|
2588
2818
|
} else {
|
|
2589
|
-
signalingUrls = [
|
|
2590
|
-
signalingSource =
|
|
2819
|
+
signalingUrls = [DEFAULT_GLOBAL_SIGNALING_URL];
|
|
2820
|
+
signalingSource = `default:${DEFAULT_GLOBAL_SIGNALING_URL}`;
|
|
2591
2821
|
}
|
|
2592
2822
|
|
|
2593
2823
|
const roomSocial = String(this.socialConfig.network.room || "").trim();
|
|
@@ -2596,14 +2826,14 @@ export class LocalNodeService {
|
|
|
2596
2826
|
roomSocial ||
|
|
2597
2827
|
roomEnv ||
|
|
2598
2828
|
(this.networkMode === "global-preview" ? builtInGlobalRoom : "") ||
|
|
2599
|
-
|
|
2829
|
+
DEFAULT_GLOBAL_ROOM;
|
|
2600
2830
|
const roomSource = roomSocial
|
|
2601
2831
|
? "social.md:network.room"
|
|
2602
2832
|
: roomEnv
|
|
2603
2833
|
? "env:WEBRTC_ROOM"
|
|
2604
2834
|
: this.networkMode === "global-preview"
|
|
2605
2835
|
? "built-in-defaults:global-preview.room"
|
|
2606
|
-
:
|
|
2836
|
+
: `default:${DEFAULT_GLOBAL_ROOM}`;
|
|
2607
2837
|
|
|
2608
2838
|
const seedPeersSocial = dedupeStrings(this.socialConfig.network.seed_peers || []);
|
|
2609
2839
|
const seedPeersEnv = dedupeStrings(parseListEnv(WEBRTC_SEED_PEERS));
|
|
@@ -2971,15 +3201,15 @@ function renderBootstrapScript(payload: unknown): string {
|
|
|
2971
3201
|
if (data.pillBroadcastClassName) pillBroadcast.className = data.pillBroadcastClassName;
|
|
2972
3202
|
}
|
|
2973
3203
|
setHtml('overviewCards', data.overviewCardsHtml || '');
|
|
2974
|
-
setText('agentsCountHint', data.agentsCountHintText || '0
|
|
2975
|
-
setHtml('agentsWrap', data.agentsWrapHtml || '<div class="label">No discovered
|
|
3204
|
+
setText('agentsCountHint', data.agentsCountHintText || '0 nodes');
|
|
3205
|
+
setHtml('agentsWrap', data.agentsWrapHtml || '<div class="label">No discovered nodes yet.</div>');
|
|
2976
3206
|
})();
|
|
2977
3207
|
</script>`;
|
|
2978
3208
|
}
|
|
2979
3209
|
|
|
2980
3210
|
export async function main() {
|
|
2981
3211
|
const app = express();
|
|
2982
|
-
const port = Number(process.env.PORT ||
|
|
3212
|
+
const port = Number(process.env.PORT || defaults.ports.local_console);
|
|
2983
3213
|
const staticDir = resolveLocalConsoleStaticDir();
|
|
2984
3214
|
const staticIndexFile = resolve(staticDir, "index.html");
|
|
2985
3215
|
|
|
@@ -3187,9 +3417,10 @@ export async function main() {
|
|
|
3187
3417
|
|
|
3188
3418
|
app.post(
|
|
3189
3419
|
"/api/openclaw/bridge/skill-install",
|
|
3190
|
-
asyncRoute(async (
|
|
3420
|
+
asyncRoute(async (req, res) => {
|
|
3191
3421
|
try {
|
|
3192
|
-
const
|
|
3422
|
+
const skillName = String(req.body?.skill_name || "").trim();
|
|
3423
|
+
const result = await node.installOpenClawSkill(skillName || undefined);
|
|
3193
3424
|
sendOk(res, result, {
|
|
3194
3425
|
message: "OpenClaw skill installed",
|
|
3195
3426
|
});
|
|
@@ -3237,7 +3468,7 @@ export async function main() {
|
|
|
3237
3468
|
const agentId = req.params.agentId;
|
|
3238
3469
|
const profile = state.profiles[agentId];
|
|
3239
3470
|
if (!profile) {
|
|
3240
|
-
sendError(res, 404, "AGENT_NOT_FOUND", "
|
|
3471
|
+
sendError(res, 404, "AGENT_NOT_FOUND", "Node not found", { agent_id: agentId });
|
|
3241
3472
|
return;
|
|
3242
3473
|
}
|
|
3243
3474
|
|
|
@@ -3273,7 +3504,7 @@ export async function main() {
|
|
|
3273
3504
|
.join("");
|
|
3274
3505
|
const agentsWrapHtml =
|
|
3275
3506
|
discovered.length === 0
|
|
3276
|
-
? `<div class="label">No discovered
|
|
3507
|
+
? `<div class="label">No discovered nodes yet.</div>`
|
|
3277
3508
|
: `
|
|
3278
3509
|
<table class="table">
|
|
3279
3510
|
<thead><tr><th>Name</th><th>Agent ID</th><th>Status</th><th>Updated</th></tr></thead>
|
|
@@ -3309,7 +3540,7 @@ export async function main() {
|
|
|
3309
3540
|
pillBroadcastText: overview.broadcast_enabled ? "broadcast: running" : "broadcast: paused",
|
|
3310
3541
|
pillBroadcastClassName: `pill ${overview.broadcast_enabled ? "ok" : "warn"}`,
|
|
3311
3542
|
overviewCardsHtml,
|
|
3312
|
-
agentsCountHintText: `${discovered.length}
|
|
3543
|
+
agentsCountHintText: `${discovered.length} nodes discovered`,
|
|
3313
3544
|
agentsWrapHtml,
|
|
3314
3545
|
integrationStatusText: `Connected to SilicaClaw: ${integration.connected_to_silicaclaw ? "yes" : "no"} · Network mode: ${integration.network_mode || "-"} · Public discovery: ${integration.public_enabled ? "enabled" : "disabled"}`,
|
|
3315
3546
|
integrationStatusClassName: `integration-strip ${integration.connected_to_silicaclaw && integration.public_enabled ? "ok" : "warn"}`,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const express_1 = __importDefault(require("express"));
|
|
7
|
+
const cors_1 = __importDefault(require("cors"));
|
|
8
|
+
const path_1 = require("path");
|
|
9
|
+
const fs_1 = require("fs");
|
|
10
|
+
const silicaclaw_defaults_json_1 = __importDefault(require("../../../config/silicaclaw-defaults.json"));
|
|
11
|
+
const app = (0, express_1.default)();
|
|
12
|
+
const port = Number(process.env.PORT || silicaclaw_defaults_json_1.default.ports.public_explorer);
|
|
13
|
+
function resolvePublicExplorerStaticDir() {
|
|
14
|
+
const candidates = [
|
|
15
|
+
(0, path_1.resolve)(process.cwd(), "public"),
|
|
16
|
+
(0, path_1.resolve)(process.cwd(), "apps", "public-explorer", "public"),
|
|
17
|
+
(0, path_1.resolve)(__dirname, "..", "public"),
|
|
18
|
+
(0, path_1.resolve)(__dirname, "..", "..", "apps", "public-explorer", "public"),
|
|
19
|
+
];
|
|
20
|
+
for (const dir of candidates) {
|
|
21
|
+
if ((0, fs_1.existsSync)((0, path_1.resolve)(dir, "index.html"))) {
|
|
22
|
+
return dir;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return candidates[0];
|
|
26
|
+
}
|
|
27
|
+
app.use((0, cors_1.default)({ origin: true }));
|
|
28
|
+
app.get("/api/config", (_req, res) => {
|
|
29
|
+
res.json({
|
|
30
|
+
ok: true,
|
|
31
|
+
data: {
|
|
32
|
+
local_console_api_base: silicaclaw_defaults_json_1.default.bridge.api_base,
|
|
33
|
+
local_console_port: silicaclaw_defaults_json_1.default.ports.local_console,
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
app.use(express_1.default.static(resolvePublicExplorerStaticDir()));
|
|
38
|
+
app.listen(port, () => {
|
|
39
|
+
// eslint-disable-next-line no-console
|
|
40
|
+
console.log(`SilicaClaw public-explorer running: http://localhost:${port}`);
|
|
41
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"ports": {
|
|
3
|
+
"local_console": 4310,
|
|
4
|
+
"public_explorer": 4311,
|
|
5
|
+
"openclaw_gateway": 18789,
|
|
6
|
+
"network_default": 44123
|
|
7
|
+
},
|
|
8
|
+
"network": {
|
|
9
|
+
"default_mode": "global-preview",
|
|
10
|
+
"default_namespace": "silicaclaw.preview",
|
|
11
|
+
"global_preview": {
|
|
12
|
+
"relay_url": "https://relay.silicaclaw.com",
|
|
13
|
+
"room": "silicaclaw-global-preview"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"bridge": {
|
|
17
|
+
"api_base": "http://localhost:4310"
|
|
18
|
+
}
|
|
19
|
+
}
|