@silicaclaw/cli 2026.3.20-2 → 2026.3.20-21
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 +108 -0
- package/INSTALL.md +13 -7
- package/README.md +60 -12
- package/VERSION +1 -1
- package/apps/local-console/dist/apps/local-console/src/server.d.ts +139 -3
- package/apps/local-console/dist/apps/local-console/src/server.js +1029 -92
- package/apps/local-console/dist/packages/core/src/index.d.ts +2 -0
- package/apps/local-console/dist/packages/core/src/index.js +2 -0
- package/apps/local-console/dist/packages/core/src/privateCrypto.d.ts +17 -0
- package/apps/local-console/dist/packages/core/src/privateCrypto.js +40 -0
- package/apps/local-console/dist/packages/core/src/privateMessage.d.ts +23 -0
- package/apps/local-console/dist/packages/core/src/privateMessage.js +74 -0
- package/apps/local-console/dist/packages/core/src/profile.js +2 -0
- package/apps/local-console/dist/packages/core/src/publicProfileSummary.d.ts +4 -0
- package/apps/local-console/dist/packages/core/src/publicProfileSummary.js +3 -0
- package/apps/local-console/dist/packages/core/src/types.d.ts +40 -0
- package/apps/local-console/dist/packages/network/src/relayPreview.d.ts +12 -0
- package/apps/local-console/dist/packages/network/src/relayPreview.js +108 -8
- package/apps/local-console/dist/packages/network/src/types.d.ts +4 -0
- package/apps/local-console/dist/packages/storage/src/repos.d.ts +27 -1
- package/apps/local-console/dist/packages/storage/src/repos.js +35 -1
- package/apps/local-console/public/app/app.js +502 -11
- package/apps/local-console/public/app/events.js +21 -0
- package/apps/local-console/public/app/network.js +144 -32
- package/apps/local-console/public/app/overview.js +57 -27
- package/apps/local-console/public/app/social.js +342 -105
- package/apps/local-console/public/app/styles.css +149 -43
- package/apps/local-console/public/app/template.js +196 -100
- package/apps/local-console/public/app/translations.js +438 -316
- package/apps/local-console/src/server.ts +1177 -90
- package/apps/public-explorer/public/app/template.js +2 -2
- package/apps/public-explorer/public/app/translations.js +36 -36
- package/docs/NEW_USER_OPERATIONS.md +5 -5
- package/docs/OPENCLAW_BRIDGE.md +7 -7
- package/docs/OPENCLAW_BRIDGE_ZH.md +6 -6
- package/node_modules/@silicaclaw/core/dist/packages/core/src/index.d.ts +2 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/index.js +2 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/privateCrypto.d.ts +17 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/privateCrypto.js +40 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/privateMessage.d.ts +23 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/privateMessage.js +74 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/profile.js +2 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/publicProfileSummary.d.ts +4 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/publicProfileSummary.js +3 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/types.d.ts +40 -0
- package/node_modules/@silicaclaw/core/package.json +2 -2
- package/node_modules/@silicaclaw/core/src/index.ts +2 -0
- package/node_modules/@silicaclaw/core/src/privateCrypto.ts +57 -0
- package/node_modules/@silicaclaw/core/src/privateMessage.ts +101 -0
- package/node_modules/@silicaclaw/core/src/profile.ts +2 -0
- package/node_modules/@silicaclaw/core/src/publicProfileSummary.ts +7 -0
- package/node_modules/@silicaclaw/core/src/types.ts +44 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/relayPreview.d.ts +12 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/relayPreview.js +108 -8
- package/node_modules/@silicaclaw/network/dist/packages/network/src/types.d.ts +4 -0
- package/node_modules/@silicaclaw/network/src/relayPreview.ts +120 -10
- package/node_modules/@silicaclaw/network/src/types.ts +2 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/index.d.ts +2 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/index.js +2 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/privateCrypto.d.ts +17 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/privateCrypto.js +40 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/privateMessage.d.ts +23 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/privateMessage.js +74 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/profile.js +2 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/publicProfileSummary.d.ts +4 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/publicProfileSummary.js +3 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/types.d.ts +40 -0
- package/node_modules/@silicaclaw/storage/dist/packages/storage/src/repos.d.ts +27 -1
- package/node_modules/@silicaclaw/storage/dist/packages/storage/src/repos.js +35 -1
- package/node_modules/@silicaclaw/storage/package.json +2 -2
- package/node_modules/@silicaclaw/storage/src/repos.ts +59 -1
- package/openclaw-skills/silicaclaw-bridge-setup/SKILL.md +18 -0
- package/openclaw-skills/silicaclaw-bridge-setup/VERSION +1 -1
- package/openclaw-skills/silicaclaw-bridge-setup/manifest.json +2 -2
- package/openclaw-skills/silicaclaw-broadcast/SKILL.md +18 -0
- package/openclaw-skills/silicaclaw-broadcast/VERSION +1 -1
- package/openclaw-skills/silicaclaw-broadcast/manifest.json +2 -2
- package/openclaw-skills/silicaclaw-network-config/SKILL.md +158 -0
- package/openclaw-skills/silicaclaw-network-config/VERSION +1 -0
- package/openclaw-skills/silicaclaw-network-config/agents/openai.yaml +6 -0
- package/openclaw-skills/silicaclaw-network-config/manifest.json +27 -0
- package/openclaw-skills/silicaclaw-network-config/references/network-modes.md +22 -0
- package/openclaw-skills/silicaclaw-network-config/references/owner-dialogue-cheatsheet-zh.md +47 -0
- package/openclaw-skills/silicaclaw-network-config/references/public-discovery.md +22 -0
- package/openclaw-skills/silicaclaw-owner-push/SKILL.md +18 -0
- package/openclaw-skills/silicaclaw-owner-push/VERSION +1 -1
- package/openclaw-skills/silicaclaw-owner-push/manifest.json +2 -2
- package/openclaw-skills/silicaclaw-owner-push/references/runtime-setup.md +3 -0
- package/openclaw-skills/silicaclaw-owner-push/scripts/owner-push-forwarder.mjs +151 -9
- package/package.json +1 -1
- package/packages/core/dist/packages/core/src/index.d.ts +2 -0
- package/packages/core/dist/packages/core/src/index.js +2 -0
- package/packages/core/dist/packages/core/src/privateCrypto.d.ts +17 -0
- package/packages/core/dist/packages/core/src/privateCrypto.js +40 -0
- package/packages/core/dist/packages/core/src/privateMessage.d.ts +23 -0
- package/packages/core/dist/packages/core/src/privateMessage.js +74 -0
- package/packages/core/dist/packages/core/src/profile.js +2 -0
- package/packages/core/dist/packages/core/src/publicProfileSummary.d.ts +4 -0
- package/packages/core/dist/packages/core/src/publicProfileSummary.js +3 -0
- package/packages/core/dist/packages/core/src/types.d.ts +40 -0
- package/packages/core/package.json +2 -2
- package/packages/core/src/index.ts +2 -0
- package/packages/core/src/privateCrypto.ts +57 -0
- package/packages/core/src/privateMessage.ts +101 -0
- package/packages/core/src/profile.ts +2 -0
- package/packages/core/src/publicProfileSummary.ts +7 -0
- package/packages/core/src/types.ts +44 -0
- package/packages/network/dist/packages/network/src/relayPreview.d.ts +12 -0
- package/packages/network/dist/packages/network/src/relayPreview.js +108 -8
- package/packages/network/dist/packages/network/src/types.d.ts +4 -0
- package/packages/network/src/relayPreview.ts +120 -10
- package/packages/network/src/types.ts +2 -0
- package/packages/storage/dist/packages/core/src/index.d.ts +2 -0
- package/packages/storage/dist/packages/core/src/index.js +2 -0
- package/packages/storage/dist/packages/core/src/privateCrypto.d.ts +17 -0
- package/packages/storage/dist/packages/core/src/privateCrypto.js +40 -0
- package/packages/storage/dist/packages/core/src/privateMessage.d.ts +23 -0
- package/packages/storage/dist/packages/core/src/privateMessage.js +74 -0
- package/packages/storage/dist/packages/core/src/profile.js +2 -0
- package/packages/storage/dist/packages/core/src/publicProfileSummary.d.ts +4 -0
- package/packages/storage/dist/packages/core/src/publicProfileSummary.js +3 -0
- package/packages/storage/dist/packages/core/src/types.d.ts +40 -0
- package/packages/storage/dist/packages/storage/src/repos.d.ts +27 -1
- package/packages/storage/dist/packages/storage/src/repos.js +35 -1
- package/packages/storage/package.json +2 -2
- package/packages/storage/src/repos.ts +59 -1
- package/scripts/silicaclaw-cli.mjs +4 -1
- package/scripts/silicaclaw-gateway.mjs +114 -2
- package/scripts/validate-openclaw-skill.mjs +19 -0
- package/node_modules/@silicaclaw/storage/dist/index.d.ts +0 -3
- package/node_modules/@silicaclaw/storage/dist/index.js +0 -19
- package/node_modules/@silicaclaw/storage/dist/jsonRepo.d.ts +0 -7
- package/node_modules/@silicaclaw/storage/dist/jsonRepo.js +0 -29
- package/node_modules/@silicaclaw/storage/dist/repos.d.ts +0 -61
- package/node_modules/@silicaclaw/storage/dist/repos.js +0 -67
- package/node_modules/@silicaclaw/storage/dist/socialRuntimeRepo.d.ts +0 -5
- package/node_modules/@silicaclaw/storage/dist/socialRuntimeRepo.js +0 -57
- package/packages/storage/dist/index.d.ts +0 -3
- package/packages/storage/dist/index.js +0 -19
- package/packages/storage/dist/jsonRepo.d.ts +0 -7
- package/packages/storage/dist/jsonRepo.js +0 -29
- package/packages/storage/dist/repos.d.ts +0 -61
- package/packages/storage/dist/repos.js +0 -67
- package/packages/storage/dist/socialRuntimeRepo.d.ts +0 -5
- package/packages/storage/dist/socialRuntimeRepo.js +0 -57
|
@@ -319,6 +319,27 @@ export function bindAppEvents({
|
|
|
319
319
|
});
|
|
320
320
|
});
|
|
321
321
|
|
|
322
|
+
document.getElementById("skillsSearchInput").addEventListener("input", async (event) => {
|
|
323
|
+
socialController.setSkillsQuery(String(event.target?.value || ""));
|
|
324
|
+
await socialController.rerenderSkills();
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
document.querySelectorAll("[data-skills-filter]").forEach((btn) => {
|
|
328
|
+
btn.addEventListener("click", async () => {
|
|
329
|
+
socialController.setSkillsFilter(String(btn.getAttribute("data-skills-filter") || "all"));
|
|
330
|
+
await socialController.rerenderSkills();
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
document.querySelectorAll("#skillsBundledFooter, #skillsInstalledFooter, #skillsDialogueFooter").forEach((footer) => {
|
|
335
|
+
footer.addEventListener("click", async (event) => {
|
|
336
|
+
const btn = event.target instanceof Element ? event.target.closest("[data-skills-toggle]") : null;
|
|
337
|
+
if (!btn) return;
|
|
338
|
+
socialController.toggleSkillsExpanded(String(btn.getAttribute("data-skills-toggle") || ""));
|
|
339
|
+
await socialController.rerenderSkills();
|
|
340
|
+
});
|
|
341
|
+
});
|
|
342
|
+
|
|
322
343
|
document.getElementById("saveGovernanceBtn").addEventListener("click", async () => {
|
|
323
344
|
setFeedback("socialGovernanceFeedback", t("common.saving"));
|
|
324
345
|
try {
|
|
@@ -13,6 +13,21 @@ export function createNetworkController({
|
|
|
13
13
|
room: "",
|
|
14
14
|
};
|
|
15
15
|
let quickConnectDefaults = { ...fallbackQuickConnectDefaults };
|
|
16
|
+
let lastNetworkRenderKey = "";
|
|
17
|
+
let lastPeersRenderKey = "";
|
|
18
|
+
let lastDiscoveryRenderKey = "";
|
|
19
|
+
|
|
20
|
+
function queueState(value) {
|
|
21
|
+
const n = Number(value || 0);
|
|
22
|
+
if (n >= 100) return { tone: "danger", label: t("labels.queueHigh") };
|
|
23
|
+
if (n >= 20) return { tone: "warn", label: t("labels.queueWatch") };
|
|
24
|
+
return { tone: "ok", label: t("labels.queueHealthy") };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function queueBadge(value) {
|
|
28
|
+
const state = queueState(value);
|
|
29
|
+
return `<span class="pill ${state.tone}">${Number(value || 0)} · ${state.label}</span>`;
|
|
30
|
+
}
|
|
16
31
|
|
|
17
32
|
async function refreshNetwork() {
|
|
18
33
|
const [cfg, sts, rtp] = await Promise.all([api("/api/network/config"), api("/api/network/stats"), api("/api/runtime/paths")]);
|
|
@@ -25,6 +40,10 @@ export function createNetworkController({
|
|
|
25
40
|
const transportStats = s.adapter_transport_stats || {};
|
|
26
41
|
const d = s.adapter_discovery_stats || {};
|
|
27
42
|
const dx = s.adapter_diagnostics_summary || {};
|
|
43
|
+
const runtimeDiag = s.runtime_diagnostics || {};
|
|
44
|
+
const runtimeMemory = runtimeDiag.memory_mib || {};
|
|
45
|
+
const runtimeDirectory = runtimeDiag.directory || {};
|
|
46
|
+
const runtimeSocial = runtimeDiag.social || {};
|
|
28
47
|
const ac = s.adapter_config || c.adapter_config || {};
|
|
29
48
|
quickConnectDefaults = {
|
|
30
49
|
signalingUrl: String(
|
|
@@ -59,7 +78,7 @@ export function createNetworkController({
|
|
|
59
78
|
heroRoomText: dx.room || "-",
|
|
60
79
|
pillAdapterText: `${t("labels.adapter")}: ${c.adapter || "-"}`,
|
|
61
80
|
});
|
|
62
|
-
|
|
81
|
+
const networkCardsHtml = [
|
|
63
82
|
[t("labels.adapter"), c.adapter],
|
|
64
83
|
[t("labels.namespace"), c.namespace || "-"],
|
|
65
84
|
[t("labels.port"), c.port ?? "-"],
|
|
@@ -75,12 +94,18 @@ export function createNetworkController({
|
|
|
75
94
|
[t("network.sent"), msg.broadcast_total ?? 0],
|
|
76
95
|
[t("network.peers"), p.total ?? 0],
|
|
77
96
|
[t("network.onlinePeers"), p.online ?? 0],
|
|
97
|
+
["RSS", runtimeMemory.rss ?? "-"],
|
|
98
|
+
["Heap", runtimeMemory.heap_used ?? "-"],
|
|
99
|
+
["Profiles", runtimeDirectory.profile_count ?? "-"],
|
|
100
|
+
["Index keys", runtimeDirectory.index_key_count ?? "-"],
|
|
101
|
+
["Messages", runtimeSocial.message_count ?? "-"],
|
|
102
|
+
["Observations", runtimeSocial.observation_count ?? "-"],
|
|
78
103
|
[t("network.activeWebrtcPeers"), dx.active_webrtc_peers ?? "-"],
|
|
79
104
|
[t("network.reconnectAttempts"), dx.reconnect_attempts_total ?? "-"],
|
|
80
105
|
[t("network.lastInbound"), ago(msg.last_message_at)],
|
|
81
106
|
[t("network.lastOutbound"), ago(msg.last_broadcast_at)],
|
|
82
107
|
].map(([k, v]) => `<div class="card"><div class="label">${k}</div><div class="value" style="font-size:17px;">${v}</div></div>`).join("");
|
|
83
|
-
|
|
108
|
+
const networkSummaryHtml = [
|
|
84
109
|
[t("labels.mode"), describeCurrentMode(t, c.mode || "lan")],
|
|
85
110
|
[t("network.relayHealth"), relayHealth],
|
|
86
111
|
[t("network.currentRelay"), dx.signaling_url || "-"],
|
|
@@ -93,7 +118,7 @@ export function createNetworkController({
|
|
|
93
118
|
|
|
94
119
|
const comp = c.components || {};
|
|
95
120
|
const lim = c.limits || {};
|
|
96
|
-
|
|
121
|
+
const networkComponentsText = [
|
|
97
122
|
`demo_mode: ${c.demo_mode || "-"}`,
|
|
98
123
|
`transport: ${comp.transport || "-"}`,
|
|
99
124
|
`discovery: ${comp.discovery || "-"}`,
|
|
@@ -130,12 +155,39 @@ export function createNetworkController({
|
|
|
130
155
|
`last_discovery_event_at: ${dx.last_discovery_event_at ? new Date(dx.last_discovery_event_at).toISOString() : "-"}`,
|
|
131
156
|
].join("\n");
|
|
132
157
|
|
|
133
|
-
|
|
158
|
+
const networkConfigSnapshotText = toPrettyJson({
|
|
134
159
|
config: c,
|
|
135
160
|
adapter_config: ac,
|
|
136
161
|
runtime_paths: runtimePaths,
|
|
137
162
|
});
|
|
138
|
-
|
|
163
|
+
const networkStatsSnapshotText = toPrettyJson({ stats: s });
|
|
164
|
+
const renderKey = JSON.stringify({
|
|
165
|
+
adapter: c.adapter || "",
|
|
166
|
+
mode: c.mode || "",
|
|
167
|
+
namespace: c.namespace || "",
|
|
168
|
+
port: c.port ?? null,
|
|
169
|
+
signaling_url: dx.signaling_url || "",
|
|
170
|
+
room: dx.room || "",
|
|
171
|
+
relay_health: relayHealth,
|
|
172
|
+
last_poll_at: dx.last_poll_at || 0,
|
|
173
|
+
last_publish_at: dx.last_publish_at || 0,
|
|
174
|
+
last_error: dx.last_error || "",
|
|
175
|
+
msg_received_total: msg.received_total ?? 0,
|
|
176
|
+
msg_broadcast_total: msg.broadcast_total ?? 0,
|
|
177
|
+
peers_total: p.total ?? 0,
|
|
178
|
+
peers_online: p.online ?? 0,
|
|
179
|
+
reconnect_attempts_total: dx.reconnect_attempts_total ?? 0,
|
|
180
|
+
active_webrtc_peers: dx.active_webrtc_peers ?? 0,
|
|
181
|
+
});
|
|
182
|
+
if (renderKey === lastNetworkRenderKey) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
document.getElementById("networkCards").innerHTML = networkCardsHtml;
|
|
186
|
+
document.getElementById("networkSummaryList").innerHTML = networkSummaryHtml;
|
|
187
|
+
document.getElementById("networkComponents").textContent = networkComponentsText;
|
|
188
|
+
document.getElementById("networkConfigSnapshot").textContent = networkConfigSnapshotText;
|
|
189
|
+
document.getElementById("networkStatsSnapshot").textContent = networkStatsSnapshotText;
|
|
190
|
+
lastNetworkRenderKey = renderKey;
|
|
139
191
|
}
|
|
140
192
|
|
|
141
193
|
async function refreshPeers() {
|
|
@@ -143,8 +195,12 @@ export function createNetworkController({
|
|
|
143
195
|
const peers = peerRes.data || {};
|
|
144
196
|
const ds = statsRes.data?.adapter_discovery_stats || {};
|
|
145
197
|
const summary = peers.diagnostics_summary || {};
|
|
146
|
-
|
|
147
|
-
|
|
198
|
+
const peerItems = Array.isArray(peers.items) ? peers.items : [];
|
|
199
|
+
const relayQueueTotal = peerItems.reduce((sum, peer) => sum + Number(peer?.meta?.relay_queue_size || 0), 0);
|
|
200
|
+
const relayQueueMax = peerItems.reduce((max, peer) => Math.max(max, Number(peer?.meta?.relay_queue_size || 0)), 0);
|
|
201
|
+
const signalQueueTotal = peerItems.reduce((sum, peer) => sum + Number(peer?.meta?.signal_queue_size || 0), 0);
|
|
202
|
+
const signalQueueMax = peerItems.reduce((max, peer) => Math.max(max, Number(peer?.meta?.signal_queue_size || 0)), 0);
|
|
203
|
+
const peerCardsHtml = [
|
|
148
204
|
[t("network.total"), peers.total || 0],
|
|
149
205
|
[t("overview.online"), peers.online || 0],
|
|
150
206
|
[t("network.stale"), peers.stale || 0],
|
|
@@ -159,26 +215,28 @@ export function createNetworkController({
|
|
|
159
215
|
[t("network.seedPeers"), summary.seed_peers_count ?? 0],
|
|
160
216
|
[t("network.discoveryEvents"), summary.discovery_events_total ?? 0],
|
|
161
217
|
[t("network.activeWebrtcPeers"), summary.active_webrtc_peers ?? "-"],
|
|
218
|
+
["Relay queue", queueBadge(relayQueueTotal)],
|
|
219
|
+
["Max relay queue", queueBadge(relayQueueMax)],
|
|
220
|
+
["Signal queue", queueBadge(signalQueueTotal)],
|
|
221
|
+
["Max signal queue", queueBadge(signalQueueMax)],
|
|
162
222
|
[t("network.observeCalls"), ds.observe_calls || 0],
|
|
163
223
|
[t("network.heartbeats"), ds.heartbeat_sent || 0],
|
|
164
224
|
[t("network.peersAdded"), ds.peers_added || 0],
|
|
165
225
|
[t("network.peersRemoved"), ds.peers_removed || 0],
|
|
166
226
|
].map(([k, v]) => `<div class="card"><div class="label">${k}</div><div class="value" style="font-size:17px;">${v}</div></div>`).join("");
|
|
227
|
+
const peerStatsText = toPrettyJson({
|
|
228
|
+
discovery_stats: ds,
|
|
229
|
+
diagnostics_summary: summary,
|
|
230
|
+
adapter_stats: statsRes.data?.adapter_stats || {},
|
|
231
|
+
});
|
|
167
232
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
discovery_stats: ds,
|
|
172
|
-
diagnostics_summary: summary,
|
|
173
|
-
});
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
document.getElementById("peerTableWrap").innerHTML = `
|
|
233
|
+
const peerTableHtml = !peers.items || !peers.items.length
|
|
234
|
+
? `<div class="empty-state">${t("network.noPeersDiscovered")}</div>`
|
|
235
|
+
: `
|
|
178
236
|
<table class="table">
|
|
179
|
-
<thead><tr><th>${t("network.peer")}</th><th>${t("network.status")}</th><th>${t("network.lastSeen")}</th><th>${t("network.staleSince")}</th><th>${t("network.messages")}</th><th>${t("network.firstSeen")}</th><th>${t("network.meta")}</th></tr></thead>
|
|
237
|
+
<thead><tr><th>${t("network.peer")}</th><th>${t("network.status")}</th><th>${t("network.lastSeen")}</th><th>${t("network.staleSince")}</th><th>${t("network.messages")}</th><th>${t("network.firstSeen")}</th><th>Relay Q</th><th>Signal Q</th><th>${t("network.meta")}</th></tr></thead>
|
|
180
238
|
<tbody>
|
|
181
|
-
${
|
|
239
|
+
${peerItems.map((peer) => `
|
|
182
240
|
<tr>
|
|
183
241
|
<td class="mono">${shortId(peer.peer_id)}</td>
|
|
184
242
|
<td class="${peer.status === "online" ? "online" : peer.status === "offline" ? "offline" : "stale"}">${peerStatusText(peer.status)}</td>
|
|
@@ -186,25 +244,67 @@ export function createNetworkController({
|
|
|
186
244
|
<td>${peer.stale_since_at ? ago(peer.stale_since_at) : "-"}</td>
|
|
187
245
|
<td>${peer.messages_seen || 0}</td>
|
|
188
246
|
<td>${new Date(peer.first_seen_at).toLocaleTimeString()}</td>
|
|
247
|
+
<td>${queueBadge(Number(peer?.meta?.relay_queue_size || 0))}</td>
|
|
248
|
+
<td>${queueBadge(Number(peer?.meta?.signal_queue_size || 0))}</td>
|
|
189
249
|
<td class="mono">${peer.meta ? JSON.stringify(peer.meta) : "-"}</td>
|
|
190
250
|
</tr>
|
|
191
251
|
`).join("")}
|
|
192
252
|
</tbody>
|
|
193
253
|
</table>
|
|
194
254
|
`;
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
255
|
+
const renderKey = JSON.stringify({
|
|
256
|
+
total: peers.total || 0,
|
|
257
|
+
online: peers.online || 0,
|
|
258
|
+
stale: peers.stale || 0,
|
|
259
|
+
namespace: peers.namespace || "",
|
|
260
|
+
summary: {
|
|
261
|
+
signaling_url: summary.signaling_url || "",
|
|
262
|
+
room: summary.room || "",
|
|
263
|
+
last_join_at: summary.last_join_at || 0,
|
|
264
|
+
last_poll_at: summary.last_poll_at || 0,
|
|
265
|
+
last_publish_at: summary.last_publish_at || 0,
|
|
266
|
+
last_error: summary.last_error || "",
|
|
267
|
+
},
|
|
268
|
+
ds: {
|
|
269
|
+
observe_calls: ds.observe_calls || 0,
|
|
270
|
+
heartbeat_sent: ds.heartbeat_sent || 0,
|
|
271
|
+
peers_added: ds.peers_added || 0,
|
|
272
|
+
peers_removed: ds.peers_removed || 0,
|
|
273
|
+
},
|
|
274
|
+
queues: {
|
|
275
|
+
relay_total: relayQueueTotal,
|
|
276
|
+
relay_max: relayQueueMax,
|
|
277
|
+
signal_total: signalQueueTotal,
|
|
278
|
+
signal_max: signalQueueMax,
|
|
279
|
+
},
|
|
280
|
+
items: peerItems
|
|
281
|
+
? peerItems.map((peer) => [
|
|
282
|
+
peer.peer_id,
|
|
283
|
+
peer.status || "",
|
|
284
|
+
peer.last_seen_at || 0,
|
|
285
|
+
peer.stale_since_at || 0,
|
|
286
|
+
peer.messages_seen || 0,
|
|
287
|
+
peer.first_seen_at || 0,
|
|
288
|
+
Number(peer?.meta?.relay_queue_size || 0),
|
|
289
|
+
Number(peer?.meta?.signal_queue_size || 0),
|
|
290
|
+
peer.meta ? JSON.stringify(peer.meta) : "",
|
|
291
|
+
])
|
|
292
|
+
: [],
|
|
199
293
|
});
|
|
294
|
+
if (renderKey === lastPeersRenderKey) {
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
document.getElementById("peerCards").innerHTML = peerCardsHtml;
|
|
298
|
+
document.getElementById("peerTableWrap").innerHTML = peerTableHtml;
|
|
299
|
+
document.getElementById("peerStatsWrap").textContent = peerStatsText;
|
|
300
|
+
lastPeersRenderKey = renderKey;
|
|
200
301
|
}
|
|
201
302
|
|
|
202
303
|
async function refreshDiscovery() {
|
|
203
304
|
const eventsRes = await api("/api/discovery/events");
|
|
204
305
|
const payload = eventsRes.data || {};
|
|
205
306
|
const items = Array.isArray(payload.items) ? payload.items : [];
|
|
206
|
-
|
|
207
|
-
document.getElementById("discoveryCards").innerHTML = [
|
|
307
|
+
const discoveryCardsHtml = [
|
|
208
308
|
[t("labels.adapter"), payload.adapter || "-"],
|
|
209
309
|
[t("labels.namespace"), payload.namespace || "-"],
|
|
210
310
|
[t("network.eventsTotal"), payload.total ?? 0],
|
|
@@ -212,11 +312,9 @@ export function createNetworkController({
|
|
|
212
312
|
[t("network.signalingEndpoints"), (payload.signaling_endpoints || []).length || 0],
|
|
213
313
|
[t("network.seedPeers"), payload.seed_peers_count ?? 0],
|
|
214
314
|
].map(([k, v]) => `<div class="card"><div class="label">${k}</div><div class="value" style="font-size:17px;">${v}</div></div>`).join("");
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
} else {
|
|
219
|
-
document.getElementById("discoveryEventList").innerHTML = items
|
|
315
|
+
const discoveryEventListHtml = !items.length
|
|
316
|
+
? `<div class="empty-state">${t("network.noDiscoveryEvents")}</div>`
|
|
317
|
+
: items
|
|
220
318
|
.slice()
|
|
221
319
|
.reverse()
|
|
222
320
|
.map((event) => `
|
|
@@ -227,9 +325,23 @@ export function createNetworkController({
|
|
|
227
325
|
</div>
|
|
228
326
|
`)
|
|
229
327
|
.join("");
|
|
328
|
+
const discoverySnapshotText = toPrettyJson(payload);
|
|
329
|
+
const renderKey = JSON.stringify({
|
|
330
|
+
adapter: payload.adapter || "",
|
|
331
|
+
namespace: payload.namespace || "",
|
|
332
|
+
total: payload.total ?? 0,
|
|
333
|
+
last_event_at: payload.last_event_at || 0,
|
|
334
|
+
signaling_endpoints: payload.signaling_endpoints || [],
|
|
335
|
+
seed_peers_count: payload.seed_peers_count ?? 0,
|
|
336
|
+
items: items.map((event) => [event.type || "", event.peer_id || "", event.endpoint || "", event.detail || "", event.at || 0]),
|
|
337
|
+
});
|
|
338
|
+
if (renderKey === lastDiscoveryRenderKey) {
|
|
339
|
+
return;
|
|
230
340
|
}
|
|
231
|
-
|
|
232
|
-
document.getElementById("
|
|
341
|
+
document.getElementById("discoveryCards").innerHTML = discoveryCardsHtml;
|
|
342
|
+
document.getElementById("discoveryEventList").innerHTML = discoveryEventListHtml;
|
|
343
|
+
document.getElementById("discoverySnapshot").textContent = discoverySnapshotText;
|
|
344
|
+
lastDiscoveryRenderKey = renderKey;
|
|
233
345
|
}
|
|
234
346
|
|
|
235
347
|
return {
|
|
@@ -7,6 +7,8 @@ export function createOverviewController({
|
|
|
7
7
|
t,
|
|
8
8
|
writeUiCache,
|
|
9
9
|
}) {
|
|
10
|
+
let lastAgentsRenderKey = "";
|
|
11
|
+
|
|
10
12
|
function renderOverviewGuide(overview, profile) {
|
|
11
13
|
const hasDisplayName = Boolean(String(profile?.display_name || overview?.display_name || "").trim());
|
|
12
14
|
const hasBio = Boolean(String(profile?.bio || "").trim());
|
|
@@ -64,12 +66,11 @@ export function createOverviewController({
|
|
|
64
66
|
setOverviewMode,
|
|
65
67
|
setVisibleRemotePublicCount,
|
|
66
68
|
}) {
|
|
67
|
-
const [overviewRes, discoveredRes, peerRes, profileRes,
|
|
69
|
+
const [overviewRes, discoveredRes, peerRes, profileRes, networkCfgRes, networkStatsRes] = await Promise.allSettled([
|
|
68
70
|
api("/api/overview"),
|
|
69
71
|
api("/api/search?q="),
|
|
70
72
|
api("/api/peers"),
|
|
71
73
|
api("/api/profile"),
|
|
72
|
-
api("/api/openclaw/bridge"),
|
|
73
74
|
api("/api/network/config"),
|
|
74
75
|
api("/api/network/stats"),
|
|
75
76
|
]);
|
|
@@ -80,7 +81,6 @@ export function createOverviewController({
|
|
|
80
81
|
const allProfiles = discoveredRes.status === "fulfilled" ? discoveredRes.value.data || [] : [];
|
|
81
82
|
const peers = peerRes.status === "fulfilled" ? peerRes.value.data || {} : {};
|
|
82
83
|
const currentProfile = profileRes.status === "fulfilled" ? profileRes.value.data || {} : {};
|
|
83
|
-
const bridge = bridgeRes.status === "fulfilled" ? bridgeRes.value.data || {} : {};
|
|
84
84
|
const networkCfg = networkCfgRes.status === "fulfilled" ? networkCfgRes.value.data || {} : {};
|
|
85
85
|
const networkStats = networkStatsRes.status === "fulfilled" ? networkStatsRes.value.data || {} : {};
|
|
86
86
|
const all = Array.isArray(allProfiles) ? allProfiles.slice() : [];
|
|
@@ -108,15 +108,15 @@ export function createOverviewController({
|
|
|
108
108
|
const snapshotHtml = `
|
|
109
109
|
<div class="snapshot-card">
|
|
110
110
|
<div class="snapshot-card__identity">
|
|
111
|
-
<div class="snapshot-card__label"
|
|
111
|
+
<div class="snapshot-card__label">${t("overview.snapshotCurrentNode")}</div>
|
|
112
112
|
<div class="snapshot-card__title">${escapeHtml(o.display_name || t("overview.unnamed"))}</div>
|
|
113
113
|
<div class="snapshot-card__subtle mono">${escapeHtml(o.agent_id || "-")}</div>
|
|
114
114
|
</div>
|
|
115
115
|
<div class="snapshot-card__grid">
|
|
116
|
-
<div class="snapshot-card__item"><div class="label"
|
|
117
|
-
<div class="snapshot-card__item"><div class="label"
|
|
118
|
-
<div class="snapshot-card__item"><div class="label"
|
|
119
|
-
<div class="snapshot-card__item"><div class="label"
|
|
116
|
+
<div class="snapshot-card__item"><div class="label">${t("overview.snapshotVersion")}</div><span class="value-inline">${escapeHtml(o.app_version || "-")}</span></div>
|
|
117
|
+
<div class="snapshot-card__item"><div class="label">${t("overview.snapshotPublic")}</div><span class="value-inline">${o.public_enabled ? t("common.on") : t("common.off")}</span></div>
|
|
118
|
+
<div class="snapshot-card__item"><div class="label">${t("overview.snapshotBroadcast")}</div><span class="value-inline">${o.broadcast_enabled ? t("common.on") : t("common.off")}</span></div>
|
|
119
|
+
<div class="snapshot-card__item"><div class="label">${t("overview.snapshotLastBroadcast")}</div><span class="value-inline">${escapeHtml(ago(o.last_broadcast_at))}</span></div>
|
|
120
120
|
</div>
|
|
121
121
|
</div>
|
|
122
122
|
`;
|
|
@@ -143,9 +143,10 @@ export function createOverviewController({
|
|
|
143
143
|
document.getElementById("pillBroadcast").textContent = pillBroadcastText;
|
|
144
144
|
document.getElementById("pillBroadcast").className = pillBroadcastClassName;
|
|
145
145
|
|
|
146
|
-
const
|
|
147
|
-
const
|
|
148
|
-
const
|
|
146
|
+
const openclaw = o.openclaw || {};
|
|
147
|
+
const openclawRunning = !!openclaw.running;
|
|
148
|
+
const openclawDetected = !!openclaw.detected || openclawRunning;
|
|
149
|
+
const skillInstalled = !!openclaw.skill_installed;
|
|
149
150
|
const globalMode = heroModeText === "global-preview";
|
|
150
151
|
const lastNetworkError = String(networkDiag.last_error || o.last_broadcast_error || "").trim();
|
|
151
152
|
const broadcastHealthy = o.broadcast_enabled && !lastNetworkError;
|
|
@@ -175,7 +176,7 @@ export function createOverviewController({
|
|
|
175
176
|
document.getElementById("homePriorityGrid").innerHTML = [
|
|
176
177
|
[t("overview.homeOpenClaw"), openclawRunning ? t("overview.homeRunning") : openclawDetected ? t("overview.homeInstalledOnly") : t("overview.homeStopped"), openclawRunning ? t("overview.homeMetaRunning") : t("overview.homeMetaNotRunning")],
|
|
177
178
|
[t("overview.homeGlobalMode"), globalMode ? t("overview.homeGlobalReady") : t("overview.homeNotGlobal"), globalMode ? t("overview.homeMetaGlobal") : t("overview.homeMetaNotGlobal")],
|
|
178
|
-
[t("overview.homeBroadcastHealth"), broadcastHealthy ? t("overview.homeHealthy") : t("overview.homeDegraded"), lastNetworkError ||
|
|
179
|
+
[t("overview.homeBroadcastHealth"), broadcastHealthy ? t("overview.homeHealthy") : t("overview.homeDegraded"), lastNetworkError || t("overview.lastBroadcastAgo", { value: ago(o.last_broadcast_at) })],
|
|
179
180
|
[t("overview.homePeers"), String(all.filter((agent) => !agent.is_self && agent.online).length), t("overview.homeMetaPeers", { online: String(onlineCount), discovered: String(discoveredCount) })],
|
|
180
181
|
].map(([label, value, meta]) => `
|
|
181
182
|
<div class="priority-card">
|
|
@@ -221,8 +222,17 @@ export function createOverviewController({
|
|
|
221
222
|
if (!filtered.length) {
|
|
222
223
|
const agentsCountHintText = t("overview.agentsZero");
|
|
223
224
|
const agentsWrapHtml = `<div class="label">${t("overview.noDiscoveredAgents")}</div>`;
|
|
224
|
-
|
|
225
|
-
|
|
225
|
+
const renderKey = JSON.stringify({
|
|
226
|
+
state: "empty",
|
|
227
|
+
hint: agentsCountHintText,
|
|
228
|
+
page: agentsPage,
|
|
229
|
+
onlineOnly: getOnlyShowOnline(),
|
|
230
|
+
});
|
|
231
|
+
if (renderKey !== lastAgentsRenderKey) {
|
|
232
|
+
document.getElementById("agentsCountHint").textContent = agentsCountHintText;
|
|
233
|
+
document.getElementById("agentsWrap").innerHTML = agentsWrapHtml;
|
|
234
|
+
lastAgentsRenderKey = renderKey;
|
|
235
|
+
}
|
|
226
236
|
writeUiCache("silicaclaw_ui_overview", {
|
|
227
237
|
overviewCardsHtml,
|
|
228
238
|
brandVersionText,
|
|
@@ -270,6 +280,9 @@ export function createOverviewController({
|
|
|
270
280
|
${renderTags(a)}
|
|
271
281
|
</div>
|
|
272
282
|
<div class="${a.online ? "online" : "offline"}">${a.online ? t("overview.online") : t("overview.offline")}</div>
|
|
283
|
+
<div class="agent-card__actions">
|
|
284
|
+
${!a.is_self ? `<button class="secondary" type="button" data-private-agent="${escapeHtml(a.agent_id)}" data-private-name="${escapeHtml(a.display_name || "")}" data-private-key="${escapeHtml(a.private_encryption_public_key || "")}" ${a.private_encryption_public_key ? "" : "disabled title=\"Private messaging unavailable for this agent yet\""}>${t("actions.messageAgentPrivately")}</button>` : ""}
|
|
285
|
+
</div>
|
|
273
286
|
<div class="agent-card__meta"><div class="agent-card__updated">${ago(a.updated_at)}</div></div>
|
|
274
287
|
</div>
|
|
275
288
|
`).join("")}
|
|
@@ -282,20 +295,37 @@ export function createOverviewController({
|
|
|
282
295
|
</div>
|
|
283
296
|
</div>
|
|
284
297
|
`;
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
+
const renderKey = JSON.stringify({
|
|
299
|
+
state: "list",
|
|
300
|
+
hint: agentsCountHintText,
|
|
301
|
+
page: agentsPage,
|
|
302
|
+
totalPages: totalAgentPages,
|
|
303
|
+
onlineOnly: getOnlyShowOnline(),
|
|
304
|
+
items: pagedAgents.map((agent) => [
|
|
305
|
+
agent.agent_id,
|
|
306
|
+
agent.updated_at,
|
|
307
|
+
agent.online ? 1 : 0,
|
|
308
|
+
agent.display_name || "",
|
|
309
|
+
agent.bio || "",
|
|
310
|
+
]),
|
|
298
311
|
});
|
|
312
|
+
if (renderKey !== lastAgentsRenderKey) {
|
|
313
|
+
document.getElementById("agentsCountHint").textContent = agentsCountHintText;
|
|
314
|
+
document.getElementById("agentsWrap").innerHTML = agentsWrapHtml;
|
|
315
|
+
document.getElementById("agentsPrevPageBtn")?.addEventListener("click", async () => {
|
|
316
|
+
if (agentsPage <= 1) return;
|
|
317
|
+
agentsPage -= 1;
|
|
318
|
+
onPageChange(agentsPage);
|
|
319
|
+
await refreshOverview({ getAgentsPage, getOnlyShowOnline, onPageChange, setOverviewMode, setVisibleRemotePublicCount });
|
|
320
|
+
});
|
|
321
|
+
document.getElementById("agentsNextPageBtn")?.addEventListener("click", async () => {
|
|
322
|
+
if (agentsPage >= totalAgentPages) return;
|
|
323
|
+
agentsPage += 1;
|
|
324
|
+
onPageChange(agentsPage);
|
|
325
|
+
await refreshOverview({ getAgentsPage, getOnlyShowOnline, onPageChange, setOverviewMode, setVisibleRemotePublicCount });
|
|
326
|
+
});
|
|
327
|
+
lastAgentsRenderKey = renderKey;
|
|
328
|
+
}
|
|
299
329
|
writeUiCache("silicaclaw_ui_overview", {
|
|
300
330
|
overviewCardsHtml,
|
|
301
331
|
brandVersionText,
|