@silicaclaw/cli 2026.3.20-3 → 2026.3.20-4

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.
@@ -13,6 +13,9 @@ export function createNetworkController({
13
13
  room: "",
14
14
  };
15
15
  let quickConnectDefaults = { ...fallbackQuickConnectDefaults };
16
+ let lastNetworkRenderKey = "";
17
+ let lastPeersRenderKey = "";
18
+ let lastDiscoveryRenderKey = "";
16
19
 
17
20
  async function refreshNetwork() {
18
21
  const [cfg, sts, rtp] = await Promise.all([api("/api/network/config"), api("/api/network/stats"), api("/api/runtime/paths")]);
@@ -25,6 +28,10 @@ export function createNetworkController({
25
28
  const transportStats = s.adapter_transport_stats || {};
26
29
  const d = s.adapter_discovery_stats || {};
27
30
  const dx = s.adapter_diagnostics_summary || {};
31
+ const runtimeDiag = s.runtime_diagnostics || {};
32
+ const runtimeMemory = runtimeDiag.memory_mib || {};
33
+ const runtimeDirectory = runtimeDiag.directory || {};
34
+ const runtimeSocial = runtimeDiag.social || {};
28
35
  const ac = s.adapter_config || c.adapter_config || {};
29
36
  quickConnectDefaults = {
30
37
  signalingUrl: String(
@@ -59,7 +66,7 @@ export function createNetworkController({
59
66
  heroRoomText: dx.room || "-",
60
67
  pillAdapterText: `${t("labels.adapter")}: ${c.adapter || "-"}`,
61
68
  });
62
- document.getElementById("networkCards").innerHTML = [
69
+ const networkCardsHtml = [
63
70
  [t("labels.adapter"), c.adapter],
64
71
  [t("labels.namespace"), c.namespace || "-"],
65
72
  [t("labels.port"), c.port ?? "-"],
@@ -75,12 +82,18 @@ export function createNetworkController({
75
82
  [t("network.sent"), msg.broadcast_total ?? 0],
76
83
  [t("network.peers"), p.total ?? 0],
77
84
  [t("network.onlinePeers"), p.online ?? 0],
85
+ ["RSS", runtimeMemory.rss ?? "-"],
86
+ ["Heap", runtimeMemory.heap_used ?? "-"],
87
+ ["Profiles", runtimeDirectory.profile_count ?? "-"],
88
+ ["Index keys", runtimeDirectory.index_key_count ?? "-"],
89
+ ["Messages", runtimeSocial.message_count ?? "-"],
90
+ ["Observations", runtimeSocial.observation_count ?? "-"],
78
91
  [t("network.activeWebrtcPeers"), dx.active_webrtc_peers ?? "-"],
79
92
  [t("network.reconnectAttempts"), dx.reconnect_attempts_total ?? "-"],
80
93
  [t("network.lastInbound"), ago(msg.last_message_at)],
81
94
  [t("network.lastOutbound"), ago(msg.last_broadcast_at)],
82
95
  ].map(([k, v]) => `<div class="card"><div class="label">${k}</div><div class="value" style="font-size:17px;">${v}</div></div>`).join("");
83
- document.getElementById("networkSummaryList").innerHTML = [
96
+ const networkSummaryHtml = [
84
97
  [t("labels.mode"), describeCurrentMode(t, c.mode || "lan")],
85
98
  [t("network.relayHealth"), relayHealth],
86
99
  [t("network.currentRelay"), dx.signaling_url || "-"],
@@ -93,7 +106,7 @@ export function createNetworkController({
93
106
 
94
107
  const comp = c.components || {};
95
108
  const lim = c.limits || {};
96
- document.getElementById("networkComponents").textContent = [
109
+ const networkComponentsText = [
97
110
  `demo_mode: ${c.demo_mode || "-"}`,
98
111
  `transport: ${comp.transport || "-"}`,
99
112
  `discovery: ${comp.discovery || "-"}`,
@@ -130,12 +143,39 @@ export function createNetworkController({
130
143
  `last_discovery_event_at: ${dx.last_discovery_event_at ? new Date(dx.last_discovery_event_at).toISOString() : "-"}`,
131
144
  ].join("\n");
132
145
 
133
- document.getElementById("networkConfigSnapshot").textContent = toPrettyJson({
146
+ const networkConfigSnapshotText = toPrettyJson({
134
147
  config: c,
135
148
  adapter_config: ac,
136
149
  runtime_paths: runtimePaths,
137
150
  });
138
- document.getElementById("networkStatsSnapshot").textContent = toPrettyJson({ stats: s });
151
+ const networkStatsSnapshotText = toPrettyJson({ stats: s });
152
+ const renderKey = JSON.stringify({
153
+ adapter: c.adapter || "",
154
+ mode: c.mode || "",
155
+ namespace: c.namespace || "",
156
+ port: c.port ?? null,
157
+ signaling_url: dx.signaling_url || "",
158
+ room: dx.room || "",
159
+ relay_health: relayHealth,
160
+ last_poll_at: dx.last_poll_at || 0,
161
+ last_publish_at: dx.last_publish_at || 0,
162
+ last_error: dx.last_error || "",
163
+ msg_received_total: msg.received_total ?? 0,
164
+ msg_broadcast_total: msg.broadcast_total ?? 0,
165
+ peers_total: p.total ?? 0,
166
+ peers_online: p.online ?? 0,
167
+ reconnect_attempts_total: dx.reconnect_attempts_total ?? 0,
168
+ active_webrtc_peers: dx.active_webrtc_peers ?? 0,
169
+ });
170
+ if (renderKey === lastNetworkRenderKey) {
171
+ return;
172
+ }
173
+ document.getElementById("networkCards").innerHTML = networkCardsHtml;
174
+ document.getElementById("networkSummaryList").innerHTML = networkSummaryHtml;
175
+ document.getElementById("networkComponents").textContent = networkComponentsText;
176
+ document.getElementById("networkConfigSnapshot").textContent = networkConfigSnapshotText;
177
+ document.getElementById("networkStatsSnapshot").textContent = networkStatsSnapshotText;
178
+ lastNetworkRenderKey = renderKey;
139
179
  }
140
180
 
141
181
  async function refreshPeers() {
@@ -143,8 +183,7 @@ export function createNetworkController({
143
183
  const peers = peerRes.data || {};
144
184
  const ds = statsRes.data?.adapter_discovery_stats || {};
145
185
  const summary = peers.diagnostics_summary || {};
146
-
147
- document.getElementById("peerCards").innerHTML = [
186
+ const peerCardsHtml = [
148
187
  [t("network.total"), peers.total || 0],
149
188
  [t("overview.online"), peers.online || 0],
150
189
  [t("network.stale"), peers.stale || 0],
@@ -164,17 +203,15 @@ export function createNetworkController({
164
203
  [t("network.peersAdded"), ds.peers_added || 0],
165
204
  [t("network.peersRemoved"), ds.peers_removed || 0],
166
205
  ].map(([k, v]) => `<div class="card"><div class="label">${k}</div><div class="value" style="font-size:17px;">${v}</div></div>`).join("");
206
+ const peerStatsText = toPrettyJson({
207
+ discovery_stats: ds,
208
+ diagnostics_summary: summary,
209
+ adapter_stats: statsRes.data?.adapter_stats || {},
210
+ });
167
211
 
168
- if (!peers.items || !peers.items.length) {
169
- document.getElementById("peerTableWrap").innerHTML = `<div class="empty-state">${t("network.noPeersDiscovered")}</div>`;
170
- document.getElementById("peerStatsWrap").textContent = toPrettyJson({
171
- discovery_stats: ds,
172
- diagnostics_summary: summary,
173
- });
174
- return;
175
- }
176
-
177
- document.getElementById("peerTableWrap").innerHTML = `
212
+ const peerTableHtml = !peers.items || !peers.items.length
213
+ ? `<div class="empty-state">${t("network.noPeersDiscovered")}</div>`
214
+ : `
178
215
  <table class="table">
179
216
  <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>
180
217
  <tbody>
@@ -192,19 +229,51 @@ export function createNetworkController({
192
229
  </tbody>
193
230
  </table>
194
231
  `;
195
- document.getElementById("peerStatsWrap").textContent = toPrettyJson({
196
- discovery_stats: ds,
197
- diagnostics_summary: summary,
198
- adapter_stats: statsRes.data?.adapter_stats || {},
232
+ const renderKey = JSON.stringify({
233
+ total: peers.total || 0,
234
+ online: peers.online || 0,
235
+ stale: peers.stale || 0,
236
+ namespace: peers.namespace || "",
237
+ summary: {
238
+ signaling_url: summary.signaling_url || "",
239
+ room: summary.room || "",
240
+ last_join_at: summary.last_join_at || 0,
241
+ last_poll_at: summary.last_poll_at || 0,
242
+ last_publish_at: summary.last_publish_at || 0,
243
+ last_error: summary.last_error || "",
244
+ },
245
+ ds: {
246
+ observe_calls: ds.observe_calls || 0,
247
+ heartbeat_sent: ds.heartbeat_sent || 0,
248
+ peers_added: ds.peers_added || 0,
249
+ peers_removed: ds.peers_removed || 0,
250
+ },
251
+ items: Array.isArray(peers.items)
252
+ ? peers.items.map((peer) => [
253
+ peer.peer_id,
254
+ peer.status || "",
255
+ peer.last_seen_at || 0,
256
+ peer.stale_since_at || 0,
257
+ peer.messages_seen || 0,
258
+ peer.first_seen_at || 0,
259
+ peer.meta ? JSON.stringify(peer.meta) : "",
260
+ ])
261
+ : [],
199
262
  });
263
+ if (renderKey === lastPeersRenderKey) {
264
+ return;
265
+ }
266
+ document.getElementById("peerCards").innerHTML = peerCardsHtml;
267
+ document.getElementById("peerTableWrap").innerHTML = peerTableHtml;
268
+ document.getElementById("peerStatsWrap").textContent = peerStatsText;
269
+ lastPeersRenderKey = renderKey;
200
270
  }
201
271
 
202
272
  async function refreshDiscovery() {
203
273
  const eventsRes = await api("/api/discovery/events");
204
274
  const payload = eventsRes.data || {};
205
275
  const items = Array.isArray(payload.items) ? payload.items : [];
206
-
207
- document.getElementById("discoveryCards").innerHTML = [
276
+ const discoveryCardsHtml = [
208
277
  [t("labels.adapter"), payload.adapter || "-"],
209
278
  [t("labels.namespace"), payload.namespace || "-"],
210
279
  [t("network.eventsTotal"), payload.total ?? 0],
@@ -212,11 +281,9 @@ export function createNetworkController({
212
281
  [t("network.signalingEndpoints"), (payload.signaling_endpoints || []).length || 0],
213
282
  [t("network.seedPeers"), payload.seed_peers_count ?? 0],
214
283
  ].map(([k, v]) => `<div class="card"><div class="label">${k}</div><div class="value" style="font-size:17px;">${v}</div></div>`).join("");
215
-
216
- if (!items.length) {
217
- document.getElementById("discoveryEventList").innerHTML = `<div class="empty-state">${t("network.noDiscoveryEvents")}</div>`;
218
- } else {
219
- document.getElementById("discoveryEventList").innerHTML = items
284
+ const discoveryEventListHtml = !items.length
285
+ ? `<div class="empty-state">${t("network.noDiscoveryEvents")}</div>`
286
+ : items
220
287
  .slice()
221
288
  .reverse()
222
289
  .map((event) => `
@@ -227,9 +294,23 @@ export function createNetworkController({
227
294
  </div>
228
295
  `)
229
296
  .join("");
297
+ const discoverySnapshotText = toPrettyJson(payload);
298
+ const renderKey = JSON.stringify({
299
+ adapter: payload.adapter || "",
300
+ namespace: payload.namespace || "",
301
+ total: payload.total ?? 0,
302
+ last_event_at: payload.last_event_at || 0,
303
+ signaling_endpoints: payload.signaling_endpoints || [],
304
+ seed_peers_count: payload.seed_peers_count ?? 0,
305
+ items: items.map((event) => [event.type || "", event.peer_id || "", event.endpoint || "", event.detail || "", event.at || 0]),
306
+ });
307
+ if (renderKey === lastDiscoveryRenderKey) {
308
+ return;
230
309
  }
231
-
232
- document.getElementById("discoverySnapshot").textContent = toPrettyJson(payload);
310
+ document.getElementById("discoveryCards").innerHTML = discoveryCardsHtml;
311
+ document.getElementById("discoveryEventList").innerHTML = discoveryEventListHtml;
312
+ document.getElementById("discoverySnapshot").textContent = discoverySnapshotText;
313
+ lastDiscoveryRenderKey = renderKey;
233
314
  }
234
315
 
235
316
  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());
@@ -221,8 +223,17 @@ export function createOverviewController({
221
223
  if (!filtered.length) {
222
224
  const agentsCountHintText = t("overview.agentsZero");
223
225
  const agentsWrapHtml = `<div class="label">${t("overview.noDiscoveredAgents")}</div>`;
224
- document.getElementById("agentsCountHint").textContent = agentsCountHintText;
225
- document.getElementById("agentsWrap").innerHTML = agentsWrapHtml;
226
+ const renderKey = JSON.stringify({
227
+ state: "empty",
228
+ hint: agentsCountHintText,
229
+ page: agentsPage,
230
+ onlineOnly: getOnlyShowOnline(),
231
+ });
232
+ if (renderKey !== lastAgentsRenderKey) {
233
+ document.getElementById("agentsCountHint").textContent = agentsCountHintText;
234
+ document.getElementById("agentsWrap").innerHTML = agentsWrapHtml;
235
+ lastAgentsRenderKey = renderKey;
236
+ }
226
237
  writeUiCache("silicaclaw_ui_overview", {
227
238
  overviewCardsHtml,
228
239
  brandVersionText,
@@ -282,20 +293,37 @@ export function createOverviewController({
282
293
  </div>
283
294
  </div>
284
295
  `;
285
- document.getElementById("agentsCountHint").textContent = agentsCountHintText;
286
- document.getElementById("agentsWrap").innerHTML = agentsWrapHtml;
287
- document.getElementById("agentsPrevPageBtn")?.addEventListener("click", async () => {
288
- if (agentsPage <= 1) return;
289
- agentsPage -= 1;
290
- onPageChange(agentsPage);
291
- await refreshOverview({ getAgentsPage, getOnlyShowOnline, onPageChange, setOverviewMode, setVisibleRemotePublicCount });
292
- });
293
- document.getElementById("agentsNextPageBtn")?.addEventListener("click", async () => {
294
- if (agentsPage >= totalAgentPages) return;
295
- agentsPage += 1;
296
- onPageChange(agentsPage);
297
- await refreshOverview({ getAgentsPage, getOnlyShowOnline, onPageChange, setOverviewMode, setVisibleRemotePublicCount });
296
+ const renderKey = JSON.stringify({
297
+ state: "list",
298
+ hint: agentsCountHintText,
299
+ page: agentsPage,
300
+ totalPages: totalAgentPages,
301
+ onlineOnly: getOnlyShowOnline(),
302
+ items: pagedAgents.map((agent) => [
303
+ agent.agent_id,
304
+ agent.updated_at,
305
+ agent.online ? 1 : 0,
306
+ agent.display_name || "",
307
+ agent.bio || "",
308
+ ]),
298
309
  });
310
+ if (renderKey !== lastAgentsRenderKey) {
311
+ document.getElementById("agentsCountHint").textContent = agentsCountHintText;
312
+ document.getElementById("agentsWrap").innerHTML = agentsWrapHtml;
313
+ document.getElementById("agentsPrevPageBtn")?.addEventListener("click", async () => {
314
+ if (agentsPage <= 1) return;
315
+ agentsPage -= 1;
316
+ onPageChange(agentsPage);
317
+ await refreshOverview({ getAgentsPage, getOnlyShowOnline, onPageChange, setOverviewMode, setVisibleRemotePublicCount });
318
+ });
319
+ document.getElementById("agentsNextPageBtn")?.addEventListener("click", async () => {
320
+ if (agentsPage >= totalAgentPages) return;
321
+ agentsPage += 1;
322
+ onPageChange(agentsPage);
323
+ await refreshOverview({ getAgentsPage, getOnlyShowOnline, onPageChange, setOverviewMode, setVisibleRemotePublicCount });
324
+ });
325
+ lastAgentsRenderKey = renderKey;
326
+ }
299
327
  writeUiCache("silicaclaw_ui_overview", {
300
328
  overviewCardsHtml,
301
329
  brandVersionText,