@silicaclaw/cli 2026.3.19-14 → 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.
Files changed (195) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/INSTALL.md +44 -11
  3. package/README.md +53 -19
  4. package/VERSION +1 -1
  5. package/apps/local-console/dist/apps/local-console/src/server.d.ts +30 -12
  6. package/apps/local-console/dist/apps/local-console/src/server.js +282 -50
  7. package/apps/local-console/dist/config/silicaclaw-defaults.json +19 -0
  8. package/apps/local-console/dist/packages/core/src/socialConfig.js +9 -5
  9. package/apps/local-console/dist/packages/network/src/realPreview.js +6 -2
  10. package/apps/local-console/dist/packages/network/src/relayPreview.js +8 -2
  11. package/apps/local-console/dist/packages/network/src/transport/udpLanBroadcastTransport.js +2 -1
  12. package/apps/local-console/dist/packages/network/src/webrtcPreview.js +5 -1
  13. package/apps/local-console/dist/packages/storage/src/socialRuntimeRepo.js +8 -4
  14. package/apps/local-console/public/app/app.js +19 -1
  15. package/apps/local-console/public/app/events.js +38 -2
  16. package/apps/local-console/public/app/network.js +32 -3
  17. package/apps/local-console/public/app/overview.js +4 -2
  18. package/apps/local-console/public/app/social.js +190 -27
  19. package/apps/local-console/public/app/styles.css +182 -14
  20. package/apps/local-console/public/app/template.js +75 -30
  21. package/apps/local-console/public/app/translations.js +135 -43
  22. package/apps/local-console/src/server.ts +299 -52
  23. package/apps/public-explorer/dist/apps/public-explorer/src/server.d.ts +1 -0
  24. package/apps/public-explorer/dist/apps/public-explorer/src/server.js +41 -0
  25. package/apps/public-explorer/dist/config/silicaclaw-defaults.json +19 -0
  26. package/apps/public-explorer/public/app/app.js +22 -2
  27. package/apps/public-explorer/public/app/template.js +4 -4
  28. package/apps/public-explorer/public/app/translations.js +15 -15
  29. package/apps/public-explorer/src/server.ts +11 -1
  30. package/docs/NEW_USER_INSTALL.md +14 -10
  31. package/docs/NEW_USER_OPERATIONS.md +3 -3
  32. package/docs/OPENCLAW_BRIDGE.md +15 -0
  33. package/docs/OPENCLAW_BRIDGE_ZH.md +15 -0
  34. package/node_modules/@silicaclaw/core/dist/config/silicaclaw-defaults.json +19 -0
  35. package/node_modules/@silicaclaw/core/dist/packages/core/src/crypto.d.ts +6 -0
  36. package/node_modules/@silicaclaw/core/dist/packages/core/src/crypto.js +50 -0
  37. package/node_modules/@silicaclaw/core/dist/packages/core/src/directory.d.ts +17 -0
  38. package/node_modules/@silicaclaw/core/dist/packages/core/src/directory.js +145 -0
  39. package/node_modules/@silicaclaw/core/dist/packages/core/src/identity.d.ts +2 -0
  40. package/node_modules/@silicaclaw/core/dist/packages/core/src/identity.js +18 -0
  41. package/node_modules/@silicaclaw/core/dist/packages/core/src/index.d.ts +12 -0
  42. package/node_modules/@silicaclaw/core/dist/packages/core/src/index.js +28 -0
  43. package/node_modules/@silicaclaw/core/dist/packages/core/src/indexing.d.ts +6 -0
  44. package/node_modules/@silicaclaw/core/dist/packages/core/src/indexing.js +43 -0
  45. package/node_modules/@silicaclaw/core/dist/packages/core/src/presence.d.ts +4 -0
  46. package/node_modules/@silicaclaw/core/dist/packages/core/src/presence.js +23 -0
  47. package/node_modules/@silicaclaw/core/dist/packages/core/src/profile.d.ts +4 -0
  48. package/node_modules/@silicaclaw/core/dist/packages/core/src/profile.js +39 -0
  49. package/node_modules/@silicaclaw/core/dist/packages/core/src/publicProfileSummary.d.ts +70 -0
  50. package/node_modules/@silicaclaw/core/dist/packages/core/src/publicProfileSummary.js +103 -0
  51. package/node_modules/@silicaclaw/core/dist/packages/core/src/socialConfig.d.ts +100 -0
  52. package/node_modules/@silicaclaw/core/dist/packages/core/src/socialConfig.js +300 -0
  53. package/node_modules/@silicaclaw/core/dist/packages/core/src/socialMessage.d.ts +19 -0
  54. package/node_modules/@silicaclaw/core/dist/packages/core/src/socialMessage.js +69 -0
  55. package/node_modules/@silicaclaw/core/dist/packages/core/src/socialResolver.d.ts +46 -0
  56. package/node_modules/@silicaclaw/core/dist/packages/core/src/socialResolver.js +237 -0
  57. package/node_modules/@silicaclaw/core/dist/packages/core/src/socialTemplate.d.ts +2 -0
  58. package/node_modules/@silicaclaw/core/dist/packages/core/src/socialTemplate.js +90 -0
  59. package/node_modules/@silicaclaw/core/dist/packages/core/src/types.d.ts +59 -0
  60. package/node_modules/@silicaclaw/core/dist/packages/core/src/types.js +2 -0
  61. package/node_modules/@silicaclaw/core/src/socialConfig.ts +7 -5
  62. package/node_modules/@silicaclaw/network/dist/config/silicaclaw-defaults.json +19 -0
  63. package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/messageEnvelope.d.ts +28 -0
  64. package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/messageEnvelope.js +36 -0
  65. package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/peerDiscovery.d.ts +43 -0
  66. package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/peerDiscovery.js +2 -0
  67. package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/topicCodec.d.ts +4 -0
  68. package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/topicCodec.js +2 -0
  69. package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/transport.d.ts +36 -0
  70. package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/transport.js +2 -0
  71. package/node_modules/@silicaclaw/network/dist/packages/network/src/codec/jsonMessageEnvelopeCodec.d.ts +5 -0
  72. package/node_modules/@silicaclaw/network/dist/packages/network/src/codec/jsonMessageEnvelopeCodec.js +24 -0
  73. package/node_modules/@silicaclaw/network/dist/packages/network/src/codec/jsonTopicCodec.d.ts +5 -0
  74. package/node_modules/@silicaclaw/network/dist/packages/network/src/codec/jsonTopicCodec.js +12 -0
  75. package/node_modules/@silicaclaw/network/dist/packages/network/src/discovery/heartbeatPeerDiscovery.d.ts +28 -0
  76. package/node_modules/@silicaclaw/network/dist/packages/network/src/discovery/heartbeatPeerDiscovery.js +144 -0
  77. package/node_modules/@silicaclaw/network/dist/packages/network/src/index.d.ts +14 -0
  78. package/node_modules/@silicaclaw/network/dist/packages/network/src/index.js +30 -0
  79. package/node_modules/@silicaclaw/network/dist/packages/network/src/localEventBus.d.ts +9 -0
  80. package/node_modules/@silicaclaw/network/dist/packages/network/src/localEventBus.js +47 -0
  81. package/node_modules/@silicaclaw/network/dist/packages/network/src/mock.d.ts +8 -0
  82. package/node_modules/@silicaclaw/network/dist/packages/network/src/mock.js +24 -0
  83. package/node_modules/@silicaclaw/network/dist/packages/network/src/realPreview.d.ts +105 -0
  84. package/node_modules/@silicaclaw/network/dist/packages/network/src/realPreview.js +331 -0
  85. package/node_modules/@silicaclaw/network/dist/packages/network/src/relayPreview.d.ts +166 -0
  86. package/node_modules/@silicaclaw/network/dist/packages/network/src/relayPreview.js +448 -0
  87. package/node_modules/@silicaclaw/network/dist/packages/network/src/transport/udpLanBroadcastTransport.d.ts +23 -0
  88. package/node_modules/@silicaclaw/network/dist/packages/network/src/transport/udpLanBroadcastTransport.js +154 -0
  89. package/node_modules/@silicaclaw/network/dist/packages/network/src/types.d.ts +6 -0
  90. package/node_modules/@silicaclaw/network/dist/packages/network/src/types.js +2 -0
  91. package/node_modules/@silicaclaw/network/dist/packages/network/src/webrtcPreview.d.ts +163 -0
  92. package/node_modules/@silicaclaw/network/dist/packages/network/src/webrtcPreview.js +848 -0
  93. package/node_modules/@silicaclaw/network/src/realPreview.ts +3 -2
  94. package/node_modules/@silicaclaw/network/src/relayPreview.ts +5 -2
  95. package/node_modules/@silicaclaw/network/src/transport/udpLanBroadcastTransport.ts +2 -1
  96. package/node_modules/@silicaclaw/network/src/webrtcPreview.ts +2 -1
  97. package/node_modules/@silicaclaw/storage/dist/socialRuntimeRepo.js +8 -4
  98. package/node_modules/@silicaclaw/storage/src/socialRuntimeRepo.ts +5 -4
  99. package/openclaw-skills/silicaclaw-bridge-setup/SKILL.md +147 -0
  100. package/openclaw-skills/silicaclaw-bridge-setup/VERSION +1 -0
  101. package/openclaw-skills/silicaclaw-bridge-setup/agents/openai.yaml +6 -0
  102. package/openclaw-skills/silicaclaw-bridge-setup/manifest.json +27 -0
  103. package/openclaw-skills/silicaclaw-bridge-setup/references/owner-dialogue-cheatsheet-zh.md +58 -0
  104. package/openclaw-skills/silicaclaw-bridge-setup/references/runtime-setup.md +43 -0
  105. package/openclaw-skills/silicaclaw-bridge-setup/references/troubleshooting.md +24 -0
  106. package/openclaw-skills/silicaclaw-broadcast/SKILL.md +132 -0
  107. package/openclaw-skills/silicaclaw-broadcast/VERSION +1 -1
  108. package/openclaw-skills/silicaclaw-broadcast/agents/openai.yaml +2 -2
  109. package/openclaw-skills/silicaclaw-broadcast/manifest.json +3 -2
  110. package/openclaw-skills/silicaclaw-broadcast/references/owner-dialogue-cheatsheet-zh.md +81 -0
  111. package/openclaw-skills/silicaclaw-owner-push/SKILL.md +217 -0
  112. package/openclaw-skills/silicaclaw-owner-push/VERSION +1 -0
  113. package/openclaw-skills/silicaclaw-owner-push/agents/openai.yaml +6 -0
  114. package/openclaw-skills/silicaclaw-owner-push/manifest.json +30 -0
  115. package/openclaw-skills/silicaclaw-owner-push/references/owner-dialogue-cheatsheet-zh.md +87 -0
  116. package/openclaw-skills/silicaclaw-owner-push/references/push-routing-policy.md +43 -0
  117. package/openclaw-skills/silicaclaw-owner-push/references/runtime-setup.md +41 -0
  118. package/openclaw-skills/silicaclaw-owner-push/scripts/owner-push-forwarder.mjs +214 -0
  119. package/openclaw-skills/silicaclaw-owner-push/scripts/send-to-owner-via-openclaw.mjs +69 -0
  120. package/package.json +1 -1
  121. package/packages/core/dist/config/silicaclaw-defaults.json +19 -0
  122. package/packages/core/dist/packages/core/src/crypto.d.ts +6 -0
  123. package/packages/core/dist/packages/core/src/crypto.js +50 -0
  124. package/packages/core/dist/packages/core/src/directory.d.ts +17 -0
  125. package/packages/core/dist/packages/core/src/directory.js +145 -0
  126. package/packages/core/dist/packages/core/src/identity.d.ts +2 -0
  127. package/packages/core/dist/packages/core/src/identity.js +18 -0
  128. package/packages/core/dist/packages/core/src/index.d.ts +12 -0
  129. package/packages/core/dist/packages/core/src/index.js +28 -0
  130. package/packages/core/dist/packages/core/src/indexing.d.ts +6 -0
  131. package/packages/core/dist/packages/core/src/indexing.js +43 -0
  132. package/packages/core/dist/packages/core/src/presence.d.ts +4 -0
  133. package/packages/core/dist/packages/core/src/presence.js +23 -0
  134. package/packages/core/dist/packages/core/src/profile.d.ts +4 -0
  135. package/packages/core/dist/packages/core/src/profile.js +39 -0
  136. package/packages/core/dist/packages/core/src/publicProfileSummary.d.ts +70 -0
  137. package/packages/core/dist/packages/core/src/publicProfileSummary.js +103 -0
  138. package/packages/core/dist/packages/core/src/socialConfig.d.ts +100 -0
  139. package/packages/core/dist/packages/core/src/socialConfig.js +300 -0
  140. package/packages/core/dist/packages/core/src/socialMessage.d.ts +19 -0
  141. package/packages/core/dist/packages/core/src/socialMessage.js +69 -0
  142. package/packages/core/dist/packages/core/src/socialResolver.d.ts +46 -0
  143. package/packages/core/dist/packages/core/src/socialResolver.js +237 -0
  144. package/packages/core/dist/packages/core/src/socialTemplate.d.ts +2 -0
  145. package/packages/core/dist/packages/core/src/socialTemplate.js +90 -0
  146. package/packages/core/dist/packages/core/src/types.d.ts +59 -0
  147. package/packages/core/dist/packages/core/src/types.js +2 -0
  148. package/packages/core/src/socialConfig.ts +7 -5
  149. package/packages/network/dist/config/silicaclaw-defaults.json +19 -0
  150. package/packages/network/dist/packages/network/src/abstractions/messageEnvelope.d.ts +28 -0
  151. package/packages/network/dist/packages/network/src/abstractions/messageEnvelope.js +36 -0
  152. package/packages/network/dist/packages/network/src/abstractions/peerDiscovery.d.ts +43 -0
  153. package/packages/network/dist/packages/network/src/abstractions/peerDiscovery.js +2 -0
  154. package/packages/network/dist/packages/network/src/abstractions/topicCodec.d.ts +4 -0
  155. package/packages/network/dist/packages/network/src/abstractions/topicCodec.js +2 -0
  156. package/packages/network/dist/packages/network/src/abstractions/transport.d.ts +36 -0
  157. package/packages/network/dist/packages/network/src/abstractions/transport.js +2 -0
  158. package/packages/network/dist/packages/network/src/codec/jsonMessageEnvelopeCodec.d.ts +5 -0
  159. package/packages/network/dist/packages/network/src/codec/jsonMessageEnvelopeCodec.js +24 -0
  160. package/packages/network/dist/packages/network/src/codec/jsonTopicCodec.d.ts +5 -0
  161. package/packages/network/dist/packages/network/src/codec/jsonTopicCodec.js +12 -0
  162. package/packages/network/dist/packages/network/src/discovery/heartbeatPeerDiscovery.d.ts +28 -0
  163. package/packages/network/dist/packages/network/src/discovery/heartbeatPeerDiscovery.js +144 -0
  164. package/packages/network/dist/packages/network/src/index.d.ts +14 -0
  165. package/packages/network/dist/packages/network/src/index.js +30 -0
  166. package/packages/network/dist/packages/network/src/localEventBus.d.ts +9 -0
  167. package/packages/network/dist/packages/network/src/localEventBus.js +47 -0
  168. package/packages/network/dist/packages/network/src/mock.d.ts +8 -0
  169. package/packages/network/dist/packages/network/src/mock.js +24 -0
  170. package/packages/network/dist/packages/network/src/realPreview.d.ts +105 -0
  171. package/packages/network/dist/packages/network/src/realPreview.js +331 -0
  172. package/packages/network/dist/packages/network/src/relayPreview.d.ts +166 -0
  173. package/packages/network/dist/packages/network/src/relayPreview.js +448 -0
  174. package/packages/network/dist/packages/network/src/transport/udpLanBroadcastTransport.d.ts +23 -0
  175. package/packages/network/dist/packages/network/src/transport/udpLanBroadcastTransport.js +154 -0
  176. package/packages/network/dist/packages/network/src/types.d.ts +6 -0
  177. package/packages/network/dist/packages/network/src/types.js +2 -0
  178. package/packages/network/dist/packages/network/src/webrtcPreview.d.ts +163 -0
  179. package/packages/network/dist/packages/network/src/webrtcPreview.js +848 -0
  180. package/packages/network/src/realPreview.ts +3 -2
  181. package/packages/network/src/relayPreview.ts +5 -2
  182. package/packages/network/src/transport/udpLanBroadcastTransport.ts +2 -1
  183. package/packages/network/src/webrtcPreview.ts +2 -1
  184. package/packages/storage/dist/socialRuntimeRepo.js +8 -4
  185. package/packages/storage/src/socialRuntimeRepo.ts +5 -4
  186. package/scripts/functional-check.mjs +35 -6
  187. package/scripts/install-openclaw-skill.mjs +9 -2
  188. package/scripts/openclaw-bridge-adapter.mjs +3 -1
  189. package/scripts/openclaw-bridge-client.mjs +3 -1
  190. package/scripts/openclaw-runtime-demo.mjs +3 -1
  191. package/scripts/quickstart.sh +13 -9
  192. package/scripts/release-pack.mjs +13 -1
  193. package/scripts/silicaclaw-cli.mjs +23 -18
  194. package/scripts/silicaclaw-gateway.mjs +33 -27
  195. package/scripts/validate-openclaw-skill.mjs +79 -21
@@ -13,6 +13,7 @@ const fs_1 = require("fs");
13
13
  const crypto_1 = require("crypto");
14
14
  const os_1 = require("os");
15
15
  const util_1 = require("util");
16
+ const silicaclaw_defaults_json_1 = __importDefault(require("../../../config/silicaclaw-defaults.json"));
16
17
  const core_1 = require("@silicaclaw/core");
17
18
  const network_1 = require("@silicaclaw/network");
18
19
  const storage_1 = require("@silicaclaw/storage");
@@ -27,16 +28,22 @@ const NETWORK_MAX_PAST_DRIFT_MS = Number(process.env.NETWORK_MAX_PAST_DRIFT_MS |
27
28
  const NETWORK_HEARTBEAT_INTERVAL_MS = Number(process.env.NETWORK_HEARTBEAT_INTERVAL_MS || 12_000);
28
29
  const NETWORK_PEER_STALE_AFTER_MS = Number(process.env.NETWORK_PEER_STALE_AFTER_MS || 45_000);
29
30
  const OPENCLAW_GATEWAY_HOST = "127.0.0.1";
30
- const OPENCLAW_GATEWAY_PORT = 18_789;
31
+ const DEFAULT_NETWORK_MODE = silicaclaw_defaults_json_1.default.network.default_mode;
32
+ const DEFAULT_NETWORK_NAMESPACE = silicaclaw_defaults_json_1.default.network.default_namespace;
33
+ const DEFAULT_NETWORK_PORT = silicaclaw_defaults_json_1.default.ports.network_default;
34
+ const DEFAULT_GLOBAL_SIGNALING_URL = silicaclaw_defaults_json_1.default.network.global_preview.relay_url;
35
+ const DEFAULT_GLOBAL_ROOM = silicaclaw_defaults_json_1.default.network.global_preview.room;
36
+ const DEFAULT_BRIDGE_API_BASE = silicaclaw_defaults_json_1.default.bridge.api_base;
37
+ const OPENCLAW_GATEWAY_PORT = silicaclaw_defaults_json_1.default.ports.openclaw_gateway;
31
38
  const OPENCLAW_GATEWAY_URL = `http://${OPENCLAW_GATEWAY_HOST}:${OPENCLAW_GATEWAY_PORT}/`;
32
39
  const NETWORK_PEER_REMOVE_AFTER_MS = Number(process.env.NETWORK_PEER_REMOVE_AFTER_MS || 180_000);
33
40
  const NETWORK_UDP_BIND_ADDRESS = process.env.NETWORK_UDP_BIND_ADDRESS || "0.0.0.0";
34
41
  const NETWORK_UDP_BROADCAST_ADDRESS = process.env.NETWORK_UDP_BROADCAST_ADDRESS || "255.255.255.255";
35
42
  const NETWORK_PEER_ID = process.env.NETWORK_PEER_ID;
36
43
  const NETWORK_MODE = process.env.NETWORK_MODE || "";
37
- const WEBRTC_SIGNALING_URL = process.env.WEBRTC_SIGNALING_URL || "https://relay.silicaclaw.com";
44
+ const WEBRTC_SIGNALING_URL = process.env.WEBRTC_SIGNALING_URL || DEFAULT_GLOBAL_SIGNALING_URL;
38
45
  const WEBRTC_SIGNALING_URLS = process.env.WEBRTC_SIGNALING_URLS || "";
39
- const WEBRTC_ROOM = process.env.WEBRTC_ROOM || "silicaclaw-global-preview";
46
+ const WEBRTC_ROOM = process.env.WEBRTC_ROOM || DEFAULT_GLOBAL_ROOM;
40
47
  const WEBRTC_SEED_PEERS = process.env.WEBRTC_SEED_PEERS || "";
41
48
  const WEBRTC_BOOTSTRAP_HINTS = process.env.WEBRTC_BOOTSTRAP_HINTS || "";
42
49
  const PROFILE_VERSION = "v0.9";
@@ -79,6 +86,42 @@ function readWorkspaceVersion(workspaceRoot) {
79
86
  }
80
87
  return "unknown";
81
88
  }
89
+ function normalizeVersionText(value) {
90
+ const text = String(value || "").trim();
91
+ return text.startsWith("v") ? text.slice(1) : text;
92
+ }
93
+ function tokenizeVersion(value) {
94
+ return normalizeVersionText(value)
95
+ .split(/[^0-9A-Za-z]+/)
96
+ .map((token) => token.trim())
97
+ .filter(Boolean)
98
+ .map((token) => (/^\d+$/.test(token) ? Number(token) : token.toLowerCase()));
99
+ }
100
+ function compareVersionTokens(left, right) {
101
+ const leftTokens = tokenizeVersion(left);
102
+ const rightTokens = tokenizeVersion(right);
103
+ const maxLength = Math.max(leftTokens.length, rightTokens.length);
104
+ for (let index = 0; index < maxLength; index += 1) {
105
+ const leftToken = leftTokens[index];
106
+ const rightToken = rightTokens[index];
107
+ if (leftToken === undefined && rightToken === undefined)
108
+ return 0;
109
+ if (leftToken === undefined)
110
+ return -1;
111
+ if (rightToken === undefined)
112
+ return 1;
113
+ if (typeof leftToken === "number" && typeof rightToken === "number") {
114
+ if (leftToken !== rightToken)
115
+ return leftToken > rightToken ? 1 : -1;
116
+ continue;
117
+ }
118
+ const leftText = String(leftToken);
119
+ const rightText = String(rightToken);
120
+ if (leftText !== rightText)
121
+ return leftText.localeCompare(rightText);
122
+ }
123
+ return 0;
124
+ }
82
125
  function resolveWorkspaceRoot(cwd = process.cwd()) {
83
126
  if ((0, fs_1.existsSync)((0, path_1.resolve)(cwd, "apps", "local-console", "package.json"))) {
84
127
  return cwd;
@@ -94,6 +137,10 @@ function resolveProjectRoot(appRoot, cwd = process.cwd()) {
94
137
  if (envRoot) {
95
138
  return (0, path_1.resolve)(envRoot);
96
139
  }
140
+ if ((0, fs_1.existsSync)((0, path_1.resolve)(appRoot, "apps", "local-console", "package.json")) &&
141
+ (0, fs_1.existsSync)((0, path_1.resolve)(appRoot, "package.json"))) {
142
+ return appRoot;
143
+ }
97
144
  if (!(0, fs_1.existsSync)((0, path_1.resolve)(cwd, "apps", "local-console", "package.json"))) {
98
145
  return (0, path_1.resolve)(cwd);
99
146
  }
@@ -182,6 +229,54 @@ function summarizeSkillReadme(filePath) {
182
229
  return "";
183
230
  }
184
231
  }
232
+ function readDialogueCheatsheetPreview(filePath, limit = 6) {
233
+ if (!filePath || !(0, fs_1.existsSync)(filePath))
234
+ return [];
235
+ try {
236
+ return (0, fs_1.readFileSync)(filePath, "utf8")
237
+ .split(/\r?\n/)
238
+ .map((line) => line.trim())
239
+ .filter((line) => line.startsWith("- "))
240
+ .map((line) => line.slice(2).trim())
241
+ .filter(Boolean)
242
+ .slice(0, limit);
243
+ }
244
+ catch {
245
+ return [];
246
+ }
247
+ }
248
+ function readDialogueCheatsheetSections(filePath, maxSections = 3, maxItemsPerSection = 5) {
249
+ if (!filePath || !(0, fs_1.existsSync)(filePath))
250
+ return [];
251
+ try {
252
+ const lines = (0, fs_1.readFileSync)(filePath, "utf8").split(/\r?\n/);
253
+ const sections = [];
254
+ let current = null;
255
+ for (const rawLine of lines) {
256
+ const line = rawLine.trim();
257
+ if (line.startsWith("## ")) {
258
+ if (current && current.items.length)
259
+ sections.push(current);
260
+ current = { title: line.slice(3).trim(), items: [] };
261
+ continue;
262
+ }
263
+ if (line.startsWith("- ")) {
264
+ if (!current) {
265
+ current = { title: "Examples", items: [] };
266
+ }
267
+ if (current.items.length < maxItemsPerSection) {
268
+ current.items.push(line.slice(2).trim());
269
+ }
270
+ }
271
+ }
272
+ if (current && current.items.length)
273
+ sections.push(current);
274
+ return sections.slice(0, maxSections);
275
+ }
276
+ catch {
277
+ return [];
278
+ }
279
+ }
185
280
  function detectOpenClawInstallation(workspaceRoot) {
186
281
  const workspaceDir = (0, path_1.resolve)(workspaceRoot, ".openclaw");
187
282
  const homeDir = (0, path_1.resolve)(process.env.HOME || "", ".openclaw");
@@ -576,7 +671,7 @@ class LocalNodeService {
576
671
  };
577
672
  network;
578
673
  adapterMode;
579
- networkMode = "global-preview";
674
+ networkMode = DEFAULT_NETWORK_MODE;
580
675
  networkNamespace;
581
676
  networkPort;
582
677
  socialConfig;
@@ -589,7 +684,7 @@ class LocalNodeService {
589
684
  resolvedIdentitySource = "silicaclaw-existing";
590
685
  resolvedOpenClawIdentityPath = null;
591
686
  webrtcSignalingUrls = [];
592
- webrtcRoom = "silicaclaw-global-preview";
687
+ webrtcRoom = DEFAULT_GLOBAL_ROOM;
593
688
  webrtcSeedPeers = [];
594
689
  webrtcBootstrapHints = [];
595
690
  webrtcBootstrapSources = [];
@@ -615,7 +710,7 @@ class LocalNodeService {
615
710
  display_name: this.getDefaultDisplayName(),
616
711
  bio: "Local AI agent connected to SilicaClaw",
617
712
  tags: ["openclaw", "local-first"],
618
- mode: "global-preview",
713
+ mode: DEFAULT_NETWORK_MODE,
619
714
  public_enabled: false,
620
715
  });
621
716
  loadedSocial = (0, core_1.loadSocialConfig)(this.projectRoot);
@@ -626,8 +721,8 @@ class LocalNodeService {
626
721
  this.socialFound = loadedSocial.meta.found;
627
722
  this.socialParseError = loadedSocial.meta.parse_error;
628
723
  this.socialRawFrontmatter = loadedSocial.raw_frontmatter;
629
- this.networkNamespace = this.socialConfig.network.namespace || process.env.NETWORK_NAMESPACE || "silicaclaw.preview";
630
- this.networkPort = Number(this.socialConfig.network.port || process.env.NETWORK_PORT || 44123);
724
+ this.networkNamespace = this.socialConfig.network.namespace || process.env.NETWORK_NAMESPACE || DEFAULT_NETWORK_NAMESPACE;
725
+ this.networkPort = Number(this.socialConfig.network.port || process.env.NETWORK_PORT || DEFAULT_NETWORK_PORT);
631
726
  this.applyResolvedNetworkConfig();
632
727
  const resolved = this.buildNetworkAdapter();
633
728
  this.network = resolved.adapter;
@@ -667,10 +762,8 @@ class LocalNodeService {
667
762
  }
668
763
  }
669
764
  getOverview() {
670
- this.ensureLocalDirectoryBaseline();
671
- this.compactCacheInMemory();
672
- const profiles = Object.values(this.directory.profiles);
673
- const onlineCount = profiles.filter((profile) => (0, core_1.isAgentOnline)(this.directory.presence[profile.agent_id], Date.now(), PRESENCE_TTL_MS)).length;
765
+ const discovered = this.search("");
766
+ const onlineCount = discovered.filter((profile) => profile.online).length;
674
767
  return {
675
768
  app_version: this.appVersion,
676
769
  agent_id: this.identity?.agent_id ?? "",
@@ -680,9 +773,9 @@ class LocalNodeService {
680
773
  last_broadcast_error_at: this.lastBroadcastErrorAt,
681
774
  last_broadcast_error: this.lastBroadcastError,
682
775
  broadcast_failure_count: this.broadcastFailureCount,
683
- discovered_count: profiles.length,
776
+ discovered_count: discovered.length,
684
777
  online_count: onlineCount,
685
- offline_count: Math.max(0, profiles.length - onlineCount),
778
+ offline_count: Math.max(0, discovered.length - onlineCount),
686
779
  init_state: this.initState,
687
780
  presence_ttl_ms: PRESENCE_TTL_MS,
688
781
  onboarding: this.getOnboardingSummary(),
@@ -1048,20 +1141,32 @@ class LocalNodeService {
1048
1141
  };
1049
1142
  }
1050
1143
  async setNetworkModeRuntime(mode) {
1051
- const currentMode = this.networkMode;
1144
+ const before = {
1145
+ mode: this.networkMode,
1146
+ adapter: this.adapterMode,
1147
+ namespace: this.networkNamespace,
1148
+ port: this.networkPort,
1149
+ };
1052
1150
  if (mode !== "local" && mode !== "lan" && mode !== "global-preview") {
1053
1151
  throw new Error("invalid_network_mode");
1054
1152
  }
1055
1153
  this.socialConfig.network.mode = mode;
1056
1154
  this.socialConfig.network.adapter = this.adapterForMode(mode);
1057
1155
  this.applyResolvedNetworkConfig();
1058
- this.socialNetworkRequiresRestart = currentMode !== mode || this.adapterMode !== this.socialConfig.network.adapter;
1156
+ const needsRestart = before.mode !== this.networkMode ||
1157
+ before.adapter !== this.socialConfig.network.adapter ||
1158
+ before.namespace !== this.networkNamespace ||
1159
+ (before.port ?? null) !== (this.networkPort ?? null);
1160
+ if (needsRestart) {
1161
+ await this.restartNetworkAdapter("set_network_mode_runtime");
1162
+ }
1163
+ this.socialNetworkRequiresRestart = false;
1059
1164
  await this.writeSocialRuntime();
1060
1165
  return {
1061
1166
  mode: this.networkMode,
1062
- adapter: this.socialConfig.network.adapter,
1063
- network_requires_restart: this.socialNetworkRequiresRestart,
1064
- note: "Runtime mode updated. Existing social.md is unchanged.",
1167
+ adapter: this.adapterMode,
1168
+ network_requires_restart: false,
1169
+ note: "Runtime mode updated and adapter restarted. Existing social.md is unchanged.",
1065
1170
  };
1066
1171
  }
1067
1172
  async quickConnectGlobalPreview(options) {
@@ -1074,7 +1179,7 @@ class LocalNodeService {
1074
1179
  this.socialConfig.network.adapter = "relay-preview";
1075
1180
  this.socialConfig.network.signaling_url = signalingUrl;
1076
1181
  this.socialConfig.network.signaling_urls = [signalingUrl];
1077
- this.socialConfig.network.room = room || "silicaclaw-global-preview";
1182
+ this.socialConfig.network.room = room || DEFAULT_GLOBAL_ROOM;
1078
1183
  this.applyResolvedNetworkConfig();
1079
1184
  await this.restartNetworkAdapter("quick_connect_global_preview");
1080
1185
  this.socialNetworkRequiresRestart = false;
@@ -1115,6 +1220,10 @@ class LocalNodeService {
1115
1220
  before.adapter !== after.adapter ||
1116
1221
  before.namespace !== after.namespace ||
1117
1222
  (before.port ?? null) !== (after.port ?? null);
1223
+ if (this.socialNetworkRequiresRestart) {
1224
+ await this.restartNetworkAdapter("reload_social_config");
1225
+ this.socialNetworkRequiresRestart = false;
1226
+ }
1118
1227
  await this.writeSocialRuntime();
1119
1228
  return this.getSocialConfigView();
1120
1229
  }
@@ -1143,10 +1252,11 @@ class LocalNodeService {
1143
1252
  search(keyword) {
1144
1253
  this.ensureLocalDirectoryBaseline();
1145
1254
  this.compactCacheInMemory();
1146
- return (0, core_1.searchDirectory)(this.directory, keyword, { presenceTTLms: PRESENCE_TTL_MS }).map((profile) => {
1255
+ const directMatches = (0, core_1.searchDirectory)(this.directory, keyword, { presenceTTLms: PRESENCE_TTL_MS }).map((profile) => {
1147
1256
  const lastSeenAt = this.directory.presence[profile.agent_id] ?? 0;
1148
1257
  return this.toPublicProfileSummary(profile, { last_seen_at: lastSeenAt });
1149
1258
  });
1259
+ return this.mergeMessageOnlyAgentSummaries(directMatches, keyword);
1150
1260
  }
1151
1261
  getPublicProfilePreview() {
1152
1262
  if (!this.profile) {
@@ -1274,9 +1384,13 @@ class LocalNodeService {
1274
1384
  },
1275
1385
  };
1276
1386
  }
1277
- async installOpenClawSkill() {
1387
+ async installOpenClawSkill(skillName) {
1278
1388
  const scriptPath = (0, path_1.resolve)(this.workspaceRoot, "scripts", "install-openclaw-skill.mjs");
1279
- const { stdout } = await execFileAsync(process.execPath, [scriptPath], {
1389
+ const args = [scriptPath];
1390
+ if (skillName) {
1391
+ args.push(`--skill=${skillName}`);
1392
+ }
1393
+ const { stdout } = await execFileAsync(process.execPath, args, {
1280
1394
  cwd: this.workspaceRoot,
1281
1395
  env: { ...process.env, SILICACLAW_WORKSPACE_DIR: this.projectRoot },
1282
1396
  maxBuffer: 1024 * 1024,
@@ -1303,7 +1417,7 @@ class LocalNodeService {
1303
1417
  const openclawSourceDir = defaultOpenClawSourceDir(this.projectRoot);
1304
1418
  const openclawRuntime = detectOpenClawRuntime(this.projectRoot);
1305
1419
  return {
1306
- bridge_api_base: "http://localhost:4310",
1420
+ bridge_api_base: DEFAULT_BRIDGE_API_BASE,
1307
1421
  openclaw_detected: detectOpenClawInstallation(this.projectRoot).detected,
1308
1422
  openclaw_running: openclawRuntime.running,
1309
1423
  openclaw_gateway_host: OPENCLAW_GATEWAY_HOST,
@@ -1313,7 +1427,7 @@ class LocalNodeService {
1313
1427
  openclaw_workspace_skill_dir: workspaceSkillDir,
1314
1428
  openclaw_legacy_skill_dir: legacySkillDir,
1315
1429
  silicaclaw_env_template_path: (0, path_1.resolve)(this.workspaceRoot, "openclaw-owner-forward.env.example"),
1316
- recommended_skill_name: "silicaclaw-broadcast",
1430
+ recommended_skill_name: "silicaclaw-bridge-setup",
1317
1431
  recommended_install_command: "silicaclaw openclaw-skill-install",
1318
1432
  recommended_owner_forward_env: {
1319
1433
  OPENCLAW_SOURCE_DIR: openclawSourceDir,
@@ -1331,6 +1445,7 @@ class LocalNodeService {
1331
1445
  ].join(" "),
1332
1446
  notes: [
1333
1447
  "Install and maintain the skill from SilicaClaw; do not edit OpenClaw core source for this integration.",
1448
+ "Use silicaclaw-bridge-setup first when OpenClaw still needs local install, readiness checks, or troubleshooting guidance.",
1334
1449
  "OpenClaw learns broadcasts via the installed skill under ~/.openclaw/workspace/skills/.",
1335
1450
  "Runtime detection prefers the actual OpenClaw gateway listener port, then falls back to OpenClaw's own openclaw.json gateway.port.",
1336
1451
  "Owner delivery runs through OpenClaw's own message channel stack after the skill forwards a summary.",
@@ -1349,6 +1464,12 @@ class LocalNodeService {
1349
1464
  const skillPath = (0, path_1.resolve)(dir.path, "SKILL.md");
1350
1465
  const versionPath = (0, path_1.resolve)(dir.path, "VERSION");
1351
1466
  const manifest = readJsonFileSafe(manifestPath);
1467
+ const references = (manifest?.references && typeof manifest.references === "object")
1468
+ ? manifest.references
1469
+ : null;
1470
+ const ownerDialogueCheatsheetPath = references?.owner_dialogue_cheatsheet_zh
1471
+ ? (0, path_1.resolve)(dir.path, String(references.owner_dialogue_cheatsheet_zh))
1472
+ : null;
1352
1473
  const name = String(manifest?.name || dir.name);
1353
1474
  const capabilities = Array.isArray(manifest?.capabilities)
1354
1475
  ? manifest.capabilities.map((item) => String(item))
@@ -1368,6 +1489,9 @@ class LocalNodeService {
1368
1489
  skill_path: (0, fs_1.existsSync)(skillPath) ? skillPath : null,
1369
1490
  capabilities,
1370
1491
  transport: manifest?.transport || null,
1492
+ owner_dialogue_cheatsheet_path: ownerDialogueCheatsheetPath && (0, fs_1.existsSync)(ownerDialogueCheatsheetPath) ? ownerDialogueCheatsheetPath : null,
1493
+ owner_dialogue_examples_zh: ownerDialogueCheatsheetPath ? readDialogueCheatsheetPreview(ownerDialogueCheatsheetPath) : [],
1494
+ owner_dialogue_sections_zh: ownerDialogueCheatsheetPath ? readDialogueCheatsheetSections(ownerDialogueCheatsheetPath) : [],
1371
1495
  installed_in_openclaw: installedInWorkspace || installedInLegacy,
1372
1496
  install_mode: installedInWorkspace ? "workspace" : installedInLegacy ? "legacy" : "not_installed",
1373
1497
  installed_path: installedInWorkspace ? installedWorkspacePath : installedInLegacy ? installedLegacyPath : null,
@@ -1381,6 +1505,12 @@ class LocalNodeService {
1381
1505
  const skillPath = (0, path_1.resolve)(dir.path, "SKILL.md");
1382
1506
  const versionPath = (0, path_1.resolve)(dir.path, "VERSION");
1383
1507
  const manifest = readJsonFileSafe(manifestPath);
1508
+ const references = (manifest?.references && typeof manifest.references === "object")
1509
+ ? manifest.references
1510
+ : null;
1511
+ const ownerDialogueCheatsheetPath = references?.owner_dialogue_cheatsheet_zh
1512
+ ? (0, path_1.resolve)(dir.path, String(references.owner_dialogue_cheatsheet_zh))
1513
+ : null;
1384
1514
  return {
1385
1515
  key: `${dir.install_mode}:${dir.name}`,
1386
1516
  name: String(manifest?.name || dir.name),
@@ -1392,9 +1522,37 @@ class LocalNodeService {
1392
1522
  manifest_path: (0, fs_1.existsSync)(manifestPath) ? manifestPath : null,
1393
1523
  skill_path: (0, fs_1.existsSync)(skillPath) ? skillPath : null,
1394
1524
  capabilities: Array.isArray(manifest?.capabilities) ? manifest.capabilities.map((item) => String(item)) : [],
1525
+ owner_dialogue_cheatsheet_path: ownerDialogueCheatsheetPath && (0, fs_1.existsSync)(ownerDialogueCheatsheetPath) ? ownerDialogueCheatsheetPath : null,
1526
+ owner_dialogue_examples_zh: ownerDialogueCheatsheetPath ? readDialogueCheatsheetPreview(ownerDialogueCheatsheetPath) : [],
1527
+ owner_dialogue_sections_zh: ownerDialogueCheatsheetPath ? readDialogueCheatsheetSections(ownerDialogueCheatsheetPath) : [],
1395
1528
  bundled_source_path: bundledSkills.find((item) => item.name === String(manifest?.name || dir.name))?.source_path || null,
1396
1529
  };
1397
1530
  });
1531
+ const installedSkillVersions = new Map(installedSkills.map((item) => [item.name, item.version]));
1532
+ const bundledSkillsWithUpdateState = bundledSkills.map((skill) => {
1533
+ const installedVersion = installedSkillVersions.get(skill.name) || "";
1534
+ const updateAvailable = Boolean(skill.installed_in_openclaw &&
1535
+ installedVersion &&
1536
+ skill.version &&
1537
+ compareVersionTokens(installedVersion, skill.version) < 0);
1538
+ return {
1539
+ ...skill,
1540
+ installed_version: installedVersion || null,
1541
+ update_available: updateAvailable,
1542
+ };
1543
+ });
1544
+ const bundledSkillVersions = new Map(bundledSkillsWithUpdateState.map((item) => [item.name, item.version]));
1545
+ const installedSkillsWithUpdateState = installedSkills.map((skill) => {
1546
+ const bundledVersion = bundledSkillVersions.get(skill.name) || "";
1547
+ const updateAvailable = Boolean(bundledVersion &&
1548
+ skill.version &&
1549
+ compareVersionTokens(skill.version, bundledVersion) < 0);
1550
+ return {
1551
+ ...skill,
1552
+ bundled_version: bundledVersion || null,
1553
+ update_available: updateAvailable,
1554
+ };
1555
+ });
1398
1556
  return {
1399
1557
  openclaw: {
1400
1558
  detected: bridge.openclaw_installation.detected,
@@ -1405,13 +1563,14 @@ class LocalNodeService {
1405
1563
  legacy_install_root: legacyInstallRoot,
1406
1564
  },
1407
1565
  summary: {
1408
- bundled_count: bundledSkills.length,
1409
- installed_count: installedSkills.length,
1410
- installed_bundled_count: bundledSkills.filter((item) => item.installed_in_openclaw).length,
1566
+ bundled_count: bundledSkillsWithUpdateState.length,
1567
+ installed_count: installedSkillsWithUpdateState.length,
1568
+ installed_bundled_count: bundledSkillsWithUpdateState.filter((item) => item.installed_in_openclaw).length,
1569
+ update_available_count: bundledSkillsWithUpdateState.filter((item) => item.update_available).length,
1411
1570
  },
1412
1571
  install_action: bridge.skill_learning.install_action,
1413
- bundled_skills: bundledSkills,
1414
- installed_skills: installedSkills,
1572
+ bundled_skills: bundledSkillsWithUpdateState,
1573
+ installed_skills: installedSkillsWithUpdateState,
1415
1574
  };
1416
1575
  }
1417
1576
  getRuntimeMessageGovernance() {
@@ -1700,7 +1859,7 @@ class LocalNodeService {
1700
1859
  await this.log("info", "profile.json missing/invalid, initialized from social/default profile");
1701
1860
  }
1702
1861
  await this.profileRepo.set(this.profile);
1703
- this.directory = (0, core_1.dedupeIndex)(await this.cacheRepo.get());
1862
+ this.directory = (0, core_1.createEmptyDirectoryState)();
1704
1863
  this.messageGovernance = {
1705
1864
  ...this.defaultMessageGovernance(),
1706
1865
  ...(await this.socialMessageGovernanceRepo.get()),
@@ -1984,6 +2143,7 @@ class LocalNodeService {
1984
2143
  this.network = next.adapter;
1985
2144
  this.adapterMode = next.mode;
1986
2145
  this.networkPort = next.port;
2146
+ this.subscriptionsBound = false;
1987
2147
  await this.network.start();
1988
2148
  this.bindNetworkSubscriptions();
1989
2149
  this.startBroadcastLoop();
@@ -2001,7 +2161,22 @@ class LocalNodeService {
2001
2161
  this.publishedByTopic[topic] = (this.publishedByTopic[topic] ?? 0) + 1;
2002
2162
  }
2003
2163
  async persistCache() {
2004
- await this.cacheRepo.set(this.directory);
2164
+ const persisted = (0, core_1.createEmptyDirectoryState)();
2165
+ if (this.profile) {
2166
+ const selfProfileRecord = {
2167
+ type: "profile",
2168
+ profile: this.profile,
2169
+ };
2170
+ this.directory = (0, core_1.ingestProfileRecord)(this.directory, selfProfileRecord);
2171
+ persisted.profiles[this.profile.agent_id] = this.profile;
2172
+ const selfLastSeenAt = this.directory.presence[this.profile.agent_id];
2173
+ if (typeof selfLastSeenAt === "number" && Number.isFinite(selfLastSeenAt)) {
2174
+ persisted.presence[this.profile.agent_id] = selfLastSeenAt;
2175
+ }
2176
+ const indexed = (0, core_1.rebuildIndexForProfile)(persisted, this.profile);
2177
+ persisted.index = indexed.index;
2178
+ }
2179
+ await this.cacheRepo.set(persisted);
2005
2180
  }
2006
2181
  async persistSocialMessages() {
2007
2182
  await this.socialMessageRepo.set(this.socialMessages);
@@ -2069,6 +2244,62 @@ class LocalNodeService {
2069
2244
  presence_ttl_ms: PRESENCE_TTL_MS,
2070
2245
  });
2071
2246
  }
2247
+ mergeMessageOnlyAgentSummaries(summaries, keyword) {
2248
+ const normalizedKeyword = String(keyword || "").trim().toLowerCase();
2249
+ const knownAgentIds = new Set(summaries.map((item) => item.agent_id));
2250
+ const messageOnly = [];
2251
+ for (const message of this.socialMessages) {
2252
+ if (!message?.agent_id || knownAgentIds.has(message.agent_id)) {
2253
+ continue;
2254
+ }
2255
+ const displayName = String(message.display_name || "Unnamed").trim() || "Unnamed";
2256
+ if (normalizedKeyword) {
2257
+ const haystacks = [
2258
+ displayName.toLowerCase(),
2259
+ message.agent_id.toLowerCase(),
2260
+ String(message.topic || "").toLowerCase(),
2261
+ ];
2262
+ if (!haystacks.some((value) => value.includes(normalizedKeyword))) {
2263
+ continue;
2264
+ }
2265
+ }
2266
+ knownAgentIds.add(message.agent_id);
2267
+ messageOnly.push((0, core_1.buildPublicProfileSummary)({
2268
+ profile: {
2269
+ agent_id: message.agent_id,
2270
+ display_name: displayName,
2271
+ bio: "Seen from signed public message. Profile/presence not synced yet.",
2272
+ tags: ["message-only"],
2273
+ avatar_url: "",
2274
+ public_enabled: true,
2275
+ updated_at: message.created_at,
2276
+ signature: "",
2277
+ },
2278
+ online: false,
2279
+ last_seen_at: null,
2280
+ network_mode: "unknown",
2281
+ openclaw_bound: false,
2282
+ profile_version: PROFILE_VERSION,
2283
+ public_key_fingerprint: null,
2284
+ verified_profile: false,
2285
+ now: Date.now(),
2286
+ presence_ttl_ms: PRESENCE_TTL_MS,
2287
+ }));
2288
+ }
2289
+ return [...summaries, ...messageOnly].sort((a, b) => {
2290
+ if (a.online !== b.online) {
2291
+ return a.online ? -1 : 1;
2292
+ }
2293
+ if (a.updated_at !== b.updated_at) {
2294
+ return b.updated_at - a.updated_at;
2295
+ }
2296
+ const byName = a.display_name.localeCompare(b.display_name);
2297
+ if (byName !== 0) {
2298
+ return byName;
2299
+ }
2300
+ return a.agent_id.localeCompare(b.agent_id);
2301
+ });
2302
+ }
2072
2303
  fingerprintPublicKey(publicKey) {
2073
2304
  const digest = (0, crypto_1.createHash)("sha256").update(publicKey, "utf8").digest("hex");
2074
2305
  return `${digest.slice(0, 12)}:${digest.slice(-8)}`;
@@ -2124,7 +2355,7 @@ class LocalNodeService {
2124
2355
  };
2125
2356
  }
2126
2357
  return {
2127
- mode: "global-preview",
2358
+ mode: DEFAULT_NETWORK_MODE,
2128
2359
  short_label: "Relay preview",
2129
2360
  summary: "Uses the public relay preview room so public nodes can find each other across the internet.",
2130
2361
  };
@@ -2152,12 +2383,12 @@ class LocalNodeService {
2152
2383
  const resolvedMode = this.socialConfig.network.mode ||
2153
2384
  (modeEnv === "local" || modeEnv === "lan" || modeEnv === "global-preview"
2154
2385
  ? modeEnv
2155
- : "global-preview");
2386
+ : DEFAULT_NETWORK_MODE);
2156
2387
  this.networkMode = resolvedMode;
2157
- this.networkNamespace = this.socialConfig.network.namespace || process.env.NETWORK_NAMESPACE || "silicaclaw.preview";
2158
- this.networkPort = Number(this.socialConfig.network.port || process.env.NETWORK_PORT || 44123);
2159
- const builtInGlobalSignalingUrls = ["https://relay.silicaclaw.com"];
2160
- const builtInGlobalRoom = "silicaclaw-global-preview";
2388
+ this.networkNamespace = this.socialConfig.network.namespace || process.env.NETWORK_NAMESPACE || DEFAULT_NETWORK_NAMESPACE;
2389
+ this.networkPort = Number(this.socialConfig.network.port || process.env.NETWORK_PORT || DEFAULT_NETWORK_PORT);
2390
+ const builtInGlobalSignalingUrls = [DEFAULT_GLOBAL_SIGNALING_URL];
2391
+ const builtInGlobalRoom = DEFAULT_GLOBAL_ROOM;
2161
2392
  const signalingUrlsSocial = dedupeStrings(this.socialConfig.network.signaling_urls || []);
2162
2393
  const signalingUrlSocial = String(this.socialConfig.network.signaling_url || "").trim();
2163
2394
  const signalingUrlsEnv = dedupeStrings(parseListEnv(WEBRTC_SIGNALING_URLS));
@@ -2185,22 +2416,22 @@ class LocalNodeService {
2185
2416
  signalingSource = "built-in-defaults:global-preview.signaling_urls";
2186
2417
  }
2187
2418
  else {
2188
- signalingUrls = ["https://relay.silicaclaw.com"];
2189
- signalingSource = "default:https://relay.silicaclaw.com";
2419
+ signalingUrls = [DEFAULT_GLOBAL_SIGNALING_URL];
2420
+ signalingSource = `default:${DEFAULT_GLOBAL_SIGNALING_URL}`;
2190
2421
  }
2191
2422
  const roomSocial = String(this.socialConfig.network.room || "").trim();
2192
2423
  const roomEnv = String(WEBRTC_ROOM || "").trim();
2193
2424
  const room = roomSocial ||
2194
2425
  roomEnv ||
2195
2426
  (this.networkMode === "global-preview" ? builtInGlobalRoom : "") ||
2196
- "silicaclaw-global-preview";
2427
+ DEFAULT_GLOBAL_ROOM;
2197
2428
  const roomSource = roomSocial
2198
2429
  ? "social.md:network.room"
2199
2430
  : roomEnv
2200
2431
  ? "env:WEBRTC_ROOM"
2201
2432
  : this.networkMode === "global-preview"
2202
2433
  ? "built-in-defaults:global-preview.room"
2203
- : "default:silicaclaw-global-preview";
2434
+ : `default:${DEFAULT_GLOBAL_ROOM}`;
2204
2435
  const seedPeersSocial = dedupeStrings(this.socialConfig.network.seed_peers || []);
2205
2436
  const seedPeersEnv = dedupeStrings(parseListEnv(WEBRTC_SEED_PEERS));
2206
2437
  const seedPeers = seedPeersSocial.length > 0 ? seedPeersSocial : seedPeersEnv;
@@ -2527,14 +2758,14 @@ function renderBootstrapScript(payload) {
2527
2758
  if (data.pillBroadcastClassName) pillBroadcast.className = data.pillBroadcastClassName;
2528
2759
  }
2529
2760
  setHtml('overviewCards', data.overviewCardsHtml || '');
2530
- setText('agentsCountHint', data.agentsCountHintText || '0 agents');
2531
- setHtml('agentsWrap', data.agentsWrapHtml || '<div class="label">No discovered agents yet.</div>');
2761
+ setText('agentsCountHint', data.agentsCountHintText || '0 nodes');
2762
+ setHtml('agentsWrap', data.agentsWrapHtml || '<div class="label">No discovered nodes yet.</div>');
2532
2763
  })();
2533
2764
  </script>`;
2534
2765
  }
2535
2766
  async function main() {
2536
2767
  const app = (0, express_1.default)();
2537
- const port = Number(process.env.PORT || 4310);
2768
+ const port = Number(process.env.PORT || silicaclaw_defaults_json_1.default.ports.local_console);
2538
2769
  const staticDir = resolveLocalConsoleStaticDir();
2539
2770
  const staticIndexFile = (0, path_1.resolve)(staticDir, "index.html");
2540
2771
  const node = new LocalNodeService();
@@ -2677,9 +2908,10 @@ async function main() {
2677
2908
  message: result.sent ? "OpenClaw bridge message published" : `OpenClaw bridge message skipped: ${result.reason}`,
2678
2909
  });
2679
2910
  }));
2680
- app.post("/api/openclaw/bridge/skill-install", asyncRoute(async (_req, res) => {
2911
+ app.post("/api/openclaw/bridge/skill-install", asyncRoute(async (req, res) => {
2681
2912
  try {
2682
- const result = await node.installOpenClawSkill();
2913
+ const skillName = String(req.body?.skill_name || "").trim();
2914
+ const result = await node.installOpenClawSkill(skillName || undefined);
2683
2915
  sendOk(res, result, {
2684
2916
  message: "OpenClaw skill installed",
2685
2917
  });
@@ -2708,7 +2940,7 @@ async function main() {
2708
2940
  const agentId = req.params.agentId;
2709
2941
  const profile = state.profiles[agentId];
2710
2942
  if (!profile) {
2711
- sendError(res, 404, "AGENT_NOT_FOUND", "Agent not found", { agent_id: agentId });
2943
+ sendError(res, 404, "AGENT_NOT_FOUND", "Node not found", { agent_id: agentId });
2712
2944
  return;
2713
2945
  }
2714
2946
  const lastSeenAt = state.presence[agentId] ?? 0;
@@ -2738,7 +2970,7 @@ async function main() {
2738
2970
  .map(([k, v]) => `<div class="card"><div class="label">${escapeHtml(String(k))}</div><div class="value">${escapeHtml(String(v))}</div></div>`)
2739
2971
  .join("");
2740
2972
  const agentsWrapHtml = discovered.length === 0
2741
- ? `<div class="label">No discovered agents yet.</div>`
2973
+ ? `<div class="label">No discovered nodes yet.</div>`
2742
2974
  : `
2743
2975
  <table class="table">
2744
2976
  <thead><tr><th>Name</th><th>Agent ID</th><th>Status</th><th>Updated</th></tr></thead>
@@ -2772,7 +3004,7 @@ async function main() {
2772
3004
  pillBroadcastText: overview.broadcast_enabled ? "broadcast: running" : "broadcast: paused",
2773
3005
  pillBroadcastClassName: `pill ${overview.broadcast_enabled ? "ok" : "warn"}`,
2774
3006
  overviewCardsHtml,
2775
- agentsCountHintText: `${discovered.length} agents discovered`,
3007
+ agentsCountHintText: `${discovered.length} nodes discovered`,
2776
3008
  agentsWrapHtml,
2777
3009
  integrationStatusText: `Connected to SilicaClaw: ${integration.connected_to_silicaclaw ? "yes" : "no"} · Network mode: ${integration.network_mode || "-"} · Public discovery: ${integration.public_enabled ? "enabled" : "disabled"}`,
2778
3010
  integrationStatusClassName: `integration-strip ${integration.connected_to_silicaclaw && integration.public_enabled ? "ok" : "warn"}`,
@@ -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
+ }