@silicaclaw/cli 2026.3.19-15 → 2026.3.19-16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) hide show
  1. package/CHANGELOG.md +6 -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 +265 -48
  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 +17 -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 +175 -26
  19. package/apps/local-console/public/app/styles.css +182 -14
  20. package/apps/local-console/public/app/template.js +70 -30
  21. package/apps/local-console/public/app/translations.js +131 -43
  22. package/apps/local-console/src/server.ts +281 -50
  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
@@ -1,4 +1,7 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.RealNetworkAdapterPreview = void 0;
4
7
  const crypto_1 = require("crypto");
@@ -7,6 +10,7 @@ const jsonMessageEnvelopeCodec_1 = require("./codec/jsonMessageEnvelopeCodec");
7
10
  const jsonTopicCodec_1 = require("./codec/jsonTopicCodec");
8
11
  const udpLanBroadcastTransport_1 = require("./transport/udpLanBroadcastTransport");
9
12
  const heartbeatPeerDiscovery_1 = require("./discovery/heartbeatPeerDiscovery");
13
+ const silicaclaw_defaults_json_1 = __importDefault(require("../../../config/silicaclaw-defaults.json"));
10
14
  class RealNetworkAdapterPreview {
11
15
  started = false;
12
16
  peerId;
@@ -46,7 +50,7 @@ class RealNetworkAdapterPreview {
46
50
  };
47
51
  constructor(options = {}) {
48
52
  this.peerId = options.peerId ?? `peer-${process.pid}-${Math.random().toString(36).slice(2, 10)}`;
49
- this.namespace = this.normalizeNamespace(options.namespace ?? "silicaclaw.preview");
53
+ this.namespace = this.normalizeNamespace(options.namespace ?? silicaclaw_defaults_json_1.default.network.default_namespace);
50
54
  this.transport = options.transport ?? new udpLanBroadcastTransport_1.UdpLanBroadcastTransport();
51
55
  this.envelopeCodec = options.envelopeCodec ?? new jsonMessageEnvelopeCodec_1.JsonMessageEnvelopeCodec();
52
56
  this.topicCodec = options.topicCodec ?? new jsonTopicCodec_1.JsonTopicCodec();
@@ -315,7 +319,7 @@ class RealNetworkAdapterPreview {
315
319
  }
316
320
  normalizeNamespace(namespace) {
317
321
  const normalized = namespace.trim();
318
- return normalized.length > 0 ? normalized : "silicaclaw.preview";
322
+ return normalized.length > 0 ? normalized : silicaclaw_defaults_json_1.default.network.default_namespace;
319
323
  }
320
324
  errorMessage(error) {
321
325
  if (error instanceof Error) {
@@ -1,10 +1,14 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.RelayPreviewAdapter = void 0;
4
7
  const crypto_1 = require("crypto");
5
8
  const messageEnvelope_1 = require("./abstractions/messageEnvelope");
6
9
  const jsonMessageEnvelopeCodec_1 = require("./codec/jsonMessageEnvelopeCodec");
7
10
  const jsonTopicCodec_1 = require("./codec/jsonTopicCodec");
11
+ const silicaclaw_defaults_json_1 = __importDefault(require("../../../config/silicaclaw-defaults.json"));
8
12
  function dedupe(values) {
9
13
  return Array.from(new Set(values.map((value) => value.trim()).filter(Boolean)));
10
14
  }
@@ -77,13 +81,15 @@ class RelayPreviewAdapter {
77
81
  };
78
82
  constructor(options = {}) {
79
83
  this.peerId = options.peerId ?? `peer-${process.pid}-${Math.random().toString(36).slice(2, 10)}`;
80
- this.namespace = String(options.namespace || "silicaclaw.preview").trim() || "silicaclaw.preview";
84
+ this.namespace =
85
+ String(options.namespace || silicaclaw_defaults_json_1.default.network.default_namespace).trim() || silicaclaw_defaults_json_1.default.network.default_namespace;
81
86
  this.signalingEndpoints = dedupe((options.signalingUrls && options.signalingUrls.length > 0
82
87
  ? options.signalingUrls
83
88
  : [options.signalingUrl || "http://localhost:4510"]));
84
89
  this.activeEndpoint = this.signalingEndpoints[0] || "http://localhost:4510";
85
90
  this.activeEndpointIndex = 0;
86
- this.room = String(options.room || "silicaclaw-global-preview").trim() || "silicaclaw-global-preview";
91
+ this.room =
92
+ String(options.room || silicaclaw_defaults_json_1.default.network.global_preview.room).trim() || silicaclaw_defaults_json_1.default.network.global_preview.room;
87
93
  this.seedPeers = dedupe(options.seedPeers || []);
88
94
  this.bootstrapHints = dedupe(options.bootstrapHints || []);
89
95
  this.bootstrapSources = dedupe(options.bootstrapSources || []);
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.UdpLanBroadcastTransport = void 0;
7
7
  const dgram_1 = __importDefault(require("dgram"));
8
+ const silicaclaw_defaults_json_1 = __importDefault(require("../../../../config/silicaclaw-defaults.json"));
8
9
  class UdpLanBroadcastTransport {
9
10
  socket = null;
10
11
  handlers = new Set();
@@ -28,7 +29,7 @@ class UdpLanBroadcastTransport {
28
29
  bindAddress;
29
30
  broadcastAddress;
30
31
  constructor(options = {}) {
31
- this.port = options.port ?? 44123;
32
+ this.port = options.port ?? silicaclaw_defaults_json_1.default.ports.network_default;
32
33
  this.bindAddress = options.bindAddress ?? "0.0.0.0";
33
34
  this.broadcastAddress = options.broadcastAddress ?? "255.255.255.255";
34
35
  }
@@ -1,10 +1,14 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.WebRTCPreviewAdapter = void 0;
4
7
  const crypto_1 = require("crypto");
5
8
  const messageEnvelope_1 = require("./abstractions/messageEnvelope");
6
9
  const jsonMessageEnvelopeCodec_1 = require("./codec/jsonMessageEnvelopeCodec");
7
10
  const jsonTopicCodec_1 = require("./codec/jsonTopicCodec");
11
+ const silicaclaw_defaults_json_1 = __importDefault(require("../../../config/silicaclaw-defaults.json"));
8
12
  function now() {
9
13
  return Date.now();
10
14
  }
@@ -103,7 +107,7 @@ class WebRTCPreviewAdapter {
103
107
  };
104
108
  constructor(options = {}) {
105
109
  this.peerId = options.peerId ?? `webrtc-${process.pid}-${Math.random().toString(36).slice(2, 9)}`;
106
- this.namespace = (options.namespace ?? "silicaclaw.preview").trim() || "silicaclaw.preview";
110
+ this.namespace = (options.namespace ?? silicaclaw_defaults_json_1.default.network.default_namespace).trim() || silicaclaw_defaults_json_1.default.network.default_namespace;
107
111
  const configuredSignalingUrls = dedupeArray([
108
112
  ...(options.signalingUrls ?? []),
109
113
  options.signalingUrl ?? "",
@@ -1,8 +1,12 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.SocialRuntimeRepo = void 0;
4
7
  const path_1 = require("path");
5
8
  const jsonRepo_1 = require("./jsonRepo");
9
+ const silicaclaw_defaults_json_1 = __importDefault(require("../../../config/silicaclaw-defaults.json"));
6
10
  function emptyRuntime() {
7
11
  return {
8
12
  enabled: true,
@@ -14,13 +18,13 @@ function emptyRuntime() {
14
18
  resolved_identity: null,
15
19
  resolved_profile: null,
16
20
  resolved_network: {
17
- mode: "global-preview",
21
+ mode: silicaclaw_defaults_json_1.default.network.default_mode,
18
22
  adapter: "relay-preview",
19
- namespace: "silicaclaw.preview",
23
+ namespace: silicaclaw_defaults_json_1.default.network.default_namespace,
20
24
  port: null,
21
- signaling_url: "https://relay.silicaclaw.com",
25
+ signaling_url: silicaclaw_defaults_json_1.default.network.global_preview.relay_url,
22
26
  signaling_urls: [],
23
- room: "silicaclaw-global-preview",
27
+ room: silicaclaw_defaults_json_1.default.network.global_preview.room,
24
28
  seed_peers: [],
25
29
  bootstrap_hints: [],
26
30
  bootstrap_sources: [],
@@ -190,17 +190,31 @@ root.innerHTML = appTemplate;
190
190
  document.getElementById('skillsBannerTitle').textContent = t('hints.skillsBannerTitle');
191
191
  document.getElementById('skillsBannerBody').textContent = t('hints.skillsBannerBody');
192
192
  document.getElementById('skillsBannerRuntimeLabel').textContent = t('hints.skillsBannerRuntime');
193
+ document.getElementById('skillsActionEyebrow').textContent = t('labels.skillsRecommendedAction');
194
+ document.getElementById('skillsActionTitle').textContent = t('hints.skillsActionInstallTitle');
195
+ document.getElementById('skillsActionBody').textContent = t('hints.skillsActionInstallBody');
196
+ document.getElementById('skillsActionState').textContent = t('labels.skillsStateReady');
197
+ document.getElementById('skillsJumpEyebrow').textContent = t('labels.skillsBrowseAreas');
198
+ document.getElementById('skillsJumpTitle').textContent = t('hints.skillsJumpTitle');
199
+ document.getElementById('skillsJumpFeatured').textContent = t('labels.skillsFeatured');
200
+ document.getElementById('skillsJumpBundled').textContent = t('labels.skillsBundled');
201
+ document.getElementById('skillsJumpInstalled').textContent = t('labels.skillsInstalled');
202
+ document.getElementById('skillsJumpDialogue').textContent = t('labels.skillsDialogue');
193
203
  document.getElementById('skillsFeaturedTitle').textContent = t('labels.skillsFeatured');
194
204
  document.getElementById('skillsFeaturedHint').textContent = t('hints.skillsFeaturedHint');
195
205
  document.getElementById('skillsBundledTitle').textContent = t('labels.skillsBundled');
196
206
  document.getElementById('skillsBundledHint').textContent = t('hints.skillsBundledHint');
207
+ document.getElementById('skillsDialogueTitle').textContent = t('labels.skillsDialogue');
208
+ document.getElementById('skillsDialogueHint').textContent = t('hints.skillsDialogueHint');
197
209
  document.getElementById('skillsInstalledTitle').textContent = t('labels.skillsInstalled');
198
210
  document.getElementById('skillsInstalledHint').textContent = t('hints.skillsInstalledHint');
199
- document.getElementById('skillsInstallBtn').textContent = t('actions.learnOpenClawSkill');
211
+ document.getElementById('skillsInstallBtn').textContent = t('actions.installSilicaClawSkills');
200
212
  document.getElementById('socialIntegrationTitle').textContent = t('labels.integrationStatus');
201
213
  document.querySelector('#socialStatusLine').textContent = t('hints.checkingIntegration');
202
214
  document.getElementById('socialRuntimeSummaryTitle').textContent = t('labels.whatIsActive');
203
215
  document.getElementById('socialBridgeTitle').textContent = t('labels.identityBinding');
216
+ document.getElementById('socialCapabilityTitle').textContent = t('labels.ownerCommunicationCapabilities');
217
+ document.getElementById('socialCapabilityHint').textContent = t('hints.ownerCommunicationCapabilitiesHint');
204
218
  document.getElementById('socialOwnerDeliveryTitle').textContent = t('labels.ownerDelivery');
205
219
  document.getElementById('socialSkillLearningTitle').textContent = t('labels.openclawSkillLearning');
206
220
  document.getElementById('socialMessagePathTitle').textContent = t('labels.messagePath');
@@ -409,6 +423,7 @@ root.innerHTML = appTemplate;
409
423
  const refreshNetwork = networkController.refreshNetwork;
410
424
  const refreshPeers = networkController.refreshPeers;
411
425
  const refreshDiscovery = networkController.refreshDiscovery;
426
+ const getQuickConnectDefaults = networkController.getQuickConnectDefaults;
412
427
 
413
428
  const refreshSocial = socialController.refreshSocial;
414
429
  const exportSocialTemplate = socialController.exportSocialTemplate;
@@ -465,6 +480,7 @@ root.innerHTML = appTemplate;
465
480
  t,
466
481
  toast,
467
482
  getSocialTemplate: () => socialTemplate,
483
+ getQuickConnectDefaults,
468
484
  setAgentsPage: (value) => { agentsPage = value; },
469
485
  getSocialMessagesCache: () => socialMessagesCache,
470
486
  toPrettyJson,
@@ -31,6 +31,7 @@ export function bindAppEvents({
31
31
  t,
32
32
  toast,
33
33
  getSocialTemplate,
34
+ getQuickConnectDefaults,
34
35
  setAgentsPage,
35
36
  getSocialMessagesCache,
36
37
  toPrettyJson,
@@ -195,9 +196,12 @@ export function bindAppEvents({
195
196
  document.getElementById("broadcastNowBtn").addEventListener("click", () => runAction("/api/broadcast/now", t("actions.broadcastNow")));
196
197
 
197
198
  document.getElementById("quickGlobalPreviewBtn").addEventListener("click", async () => {
198
- const currentSignaling = window.prompt(t("feedback.promptSignalingUrl"), "http://localhost:4510");
199
+ const quickConnectDefaults = typeof getQuickConnectDefaults === "function"
200
+ ? getQuickConnectDefaults()
201
+ : { signalingUrl: "http://localhost:4510", room: "" };
202
+ const currentSignaling = window.prompt(t("feedback.promptSignalingUrl"), quickConnectDefaults.signalingUrl || "http://localhost:4510");
199
203
  if (!currentSignaling) return;
200
- const room = window.prompt(t("feedback.promptRoom"), "silicaclaw-global-preview") || "silicaclaw-global-preview";
204
+ const room = window.prompt(t("feedback.promptRoom"), quickConnectDefaults.room || "") || quickConnectDefaults.room || "";
201
205
  setFeedback("networkFeedback", t("feedback.crossPreviewEnabling"));
202
206
  try {
203
207
  const result = await api("/api/network/quick-connect-global-preview", {
@@ -283,6 +287,38 @@ export function bindAppEvents({
283
287
  }
284
288
  });
285
289
 
290
+ document.getElementById("skillsBundledGrid").addEventListener("click", async (event) => {
291
+ const btn = event.target instanceof Element ? event.target.closest("[data-skill-install]") : null;
292
+ if (!btn) return;
293
+ const skillName = String(btn.getAttribute("data-skill-install") || "").trim();
294
+ if (!skillName) return;
295
+ btn.setAttribute("disabled", "true");
296
+ setFeedback("skillsFeedback", `${t("common.saving")} ${skillName}`);
297
+ try {
298
+ await api("/api/openclaw/bridge/skill-install", {
299
+ method: "POST",
300
+ body: JSON.stringify({ skill_name: skillName }),
301
+ });
302
+ setFeedback("skillsFeedback", t("feedback.openclawSkillInstalled"));
303
+ toast(`${t("feedback.openclawSkillInstalled")} · ${skillName}`);
304
+ await refreshSkills();
305
+ await refreshSocial();
306
+ } catch (e) {
307
+ setFeedback("skillsFeedback", e instanceof Error ? e.message : t("feedback.openclawSkillInstallFailed"), "error");
308
+ } finally {
309
+ btn.removeAttribute("disabled");
310
+ await refreshSkills().catch(() => {});
311
+ }
312
+ });
313
+
314
+ document.querySelectorAll("[data-skills-jump]").forEach((btn) => {
315
+ btn.addEventListener("click", () => {
316
+ const targetId = String(btn.getAttribute("data-skills-jump") || "").trim();
317
+ if (!targetId) return;
318
+ document.getElementById(targetId)?.scrollIntoView({ behavior: "smooth", block: "start" });
319
+ });
320
+ });
321
+
286
322
  document.getElementById("saveGovernanceBtn").addEventListener("click", async () => {
287
323
  setFeedback("socialGovernanceFeedback", t("common.saving"));
288
324
  try {
@@ -8,6 +8,12 @@ export function createNetworkController({
8
8
  toPrettyJson,
9
9
  writeUiCache,
10
10
  }) {
11
+ const fallbackQuickConnectDefaults = {
12
+ signalingUrl: "http://localhost:4510",
13
+ room: "",
14
+ };
15
+ let quickConnectDefaults = { ...fallbackQuickConnectDefaults };
16
+
11
17
  async function refreshNetwork() {
12
18
  const [cfg, sts, rtp] = await Promise.all([api("/api/network/config"), api("/api/network/stats"), api("/api/runtime/paths")]);
13
19
  const c = cfg.data;
@@ -20,9 +26,31 @@ export function createNetworkController({
20
26
  const d = s.adapter_discovery_stats || {};
21
27
  const dx = s.adapter_diagnostics_summary || {};
22
28
  const ac = s.adapter_config || c.adapter_config || {};
29
+ quickConnectDefaults = {
30
+ signalingUrl: String(
31
+ dx.signaling_url ||
32
+ c.signaling_url ||
33
+ c.adapter_extra?.signaling_url ||
34
+ quickConnectDefaults.signalingUrl ||
35
+ fallbackQuickConnectDefaults.signalingUrl
36
+ ),
37
+ room: String(
38
+ dx.room ||
39
+ c.room ||
40
+ c.adapter_extra?.room ||
41
+ quickConnectDefaults.room ||
42
+ fallbackQuickConnectDefaults.room
43
+ ),
44
+ };
45
+ const relayCapable = c.adapter === "relay-preview" || c.adapter === "webrtc-preview";
46
+ const relayHealth = relayCapable
47
+ ? (dx.last_error ? t("network.degraded") : t("network.connected"))
48
+ : "-";
23
49
  document.getElementById("heroAdapter").textContent = c.adapter || "-";
24
- document.getElementById("heroRelay").textContent = dx.signaling_url || "-";
25
- document.getElementById("heroRoom").textContent = dx.room || "-";
50
+ const heroRelayEl = document.getElementById("heroRelay");
51
+ const heroRoomEl = document.getElementById("heroRoom");
52
+ if (heroRelayEl) heroRelayEl.textContent = dx.signaling_url || "-";
53
+ if (heroRoomEl) heroRoomEl.textContent = dx.room || "-";
26
54
 
27
55
  document.getElementById("pillAdapter").textContent = `${t("labels.adapter")}: ${c.adapter || "-"}`;
28
56
  writeUiCache("silicaclaw_ui_network", {
@@ -54,7 +82,7 @@ export function createNetworkController({
54
82
  ].map(([k, v]) => `<div class="card"><div class="label">${k}</div><div class="value" style="font-size:17px;">${v}</div></div>`).join("");
55
83
  document.getElementById("networkSummaryList").innerHTML = [
56
84
  [t("labels.mode"), describeCurrentMode(t, c.mode || "lan")],
57
- [t("network.relayHealth"), dx.last_error ? t("network.degraded") : t("network.connected")],
85
+ [t("network.relayHealth"), relayHealth],
58
86
  [t("network.currentRelay"), dx.signaling_url || "-"],
59
87
  [t("network.currentRoom"), dx.room || "-"],
60
88
  [t("network.lastJoin"), ago(dx.last_join_at)],
@@ -205,6 +233,7 @@ export function createNetworkController({
205
233
  }
206
234
 
207
235
  return {
236
+ getQuickConnectDefaults: () => ({ ...quickConnectDefaults }),
208
237
  refreshDiscovery,
209
238
  refreshNetwork,
210
239
  refreshPeers,
@@ -151,8 +151,10 @@ export function createOverviewController({
151
151
  setOverviewMode(heroModeText);
152
152
  document.getElementById("heroMode").textContent = heroModeText;
153
153
  document.getElementById("heroAdapter").textContent = heroAdapterText;
154
- document.getElementById("heroRelay").textContent = heroRelayText;
155
- document.getElementById("heroRoom").textContent = heroRoomText;
154
+ const heroRelayEl = document.getElementById("heroRelay");
155
+ const heroRoomEl = document.getElementById("heroRoom");
156
+ if (heroRelayEl) heroRelayEl.textContent = heroRelayText;
157
+ if (heroRoomEl) heroRoomEl.textContent = heroRoomText;
156
158
  document.getElementById("overviewModeHint").textContent = t("overview.modeCurrentSource", {
157
159
  mode: describeCurrentMode(t, heroModeText),
158
160
  hint: t("overview.modeCacheHint"),
@@ -238,6 +238,12 @@ export function createSocialController({
238
238
  `${t("social.ownerForwardReady")}: ${ownerDelivery.ready ? t("common.yes") : t("common.no")}`,
239
239
  ].join(" · ");
240
240
  document.getElementById("socialOwnerDeliveryReason").textContent = ownerDeliveryBody;
241
+ document.getElementById("socialCapabilityCards").innerHTML = [
242
+ [t("socialCapability.publicBroadcast"), bridge.message_broadcast_enabled ? t("common.yes") : t("common.no")],
243
+ [t("socialCapability.monitorBroadcasts"), ownerDelivery.bridge_messages_readable ? t("common.yes") : t("common.no")],
244
+ [t("socialCapability.autoPushToOwner"), ownerDelivery.ready ? t("common.yes") : t("common.no")],
245
+ [t("socialCapability.ownerPrivateBoundary"), t("socialCapability.ownerPrivateBoundaryValue")],
246
+ ].map(([k, v]) => `<div class="card"><div class="label">${escapeHtml(String(k))}</div><div class="value" style="font-size:17px;">${escapeHtml(String(v))}</div></div>`).join("");
241
247
  document.getElementById("openclawSkillCards").innerHTML = [
242
248
  [t("social.openclawInstalled"), openclawDetected ? t("common.yes") : t("common.no")],
243
249
  [t("social.running"), openclawRunning ? t("common.yes") : t("common.no")],
@@ -384,12 +390,19 @@ export function createSocialController({
384
390
 
385
391
  function renderSkillCard(skill, options = {}) {
386
392
  const capabilities = Array.isArray(skill.capabilities) ? skill.capabilities.slice(0, 6) : [];
393
+ const updateAvailable = options.updateAvailable === true;
387
394
  const statusText = options.statusText || (skill.installed_in_openclaw ? t("common.yes") : t("hints.skillsNotInstalled"));
388
395
  const versionText = String(skill.version || "-");
389
396
  const bodyText = escapeHtml(String(skill.description || "-"));
390
- const installTone = skill.installed_in_openclaw || skill.install_mode === "workspace" || skill.install_mode === "legacy"
391
- ? "tag-chip emphasis"
392
- : "tag-chip muted";
397
+ const skillName = String(skill.name || "").trim();
398
+ const installable = options.installable === true && Boolean(skillName) && (!skill.installed_in_openclaw || updateAvailable);
399
+ const installedVersionText = escapeHtml(String(options.installedVersion || skill.installed_version || "-"));
400
+ const bundledVersionText = escapeHtml(String(options.bundledVersion || skill.bundled_version || skill.version || "-"));
401
+ const installTone = updateAvailable
402
+ ? "tag-chip warn"
403
+ : skill.installed_in_openclaw || skill.install_mode === "workspace" || skill.install_mode === "legacy"
404
+ ? "tag-chip emphasis"
405
+ : "tag-chip muted";
393
406
  const sourceText = escapeHtml(String(skill.source_path || skill.bundled_source_path || skill.installed_path || "-"));
394
407
  const locationText = escapeHtml(String(skill.installed_path || skill.manifest_path || "-"));
395
408
  return `
@@ -404,9 +417,18 @@ export function createSocialController({
404
417
  <div class="skill-card__body">${bodyText}</div>
405
418
  <div class="skill-card__tags">
406
419
  <span class="${installTone}">${escapeHtml(statusText)}</span>
420
+ ${updateAvailable ? `<span class="tag-chip warn">${t("labels.skillsUpdateAvailable")}</span>` : ""}
407
421
  ${capabilities.map((item) => `<span class="tag-chip">${escapeHtml(String(item))}</span>`).join("")}
408
422
  </div>
409
423
  <div class="skill-card__meta">
424
+ <div class="skill-card__meta-item">
425
+ <div class="skill-card__meta-label">${t("labels.skillsInstalledVersion")}</div>
426
+ <div class="skill-card__meta-value mono">${installedVersionText}</div>
427
+ </div>
428
+ <div class="skill-card__meta-item">
429
+ <div class="skill-card__meta-label">${t("labels.skillsBundledVersion")}</div>
430
+ <div class="skill-card__meta-value mono">${bundledVersionText}</div>
431
+ </div>
410
432
  <div class="skill-card__meta-item">
411
433
  <div class="skill-card__meta-label">${t("labels.skillsSource")}</div>
412
434
  <div class="skill-card__meta-value mono">${sourceText}</div>
@@ -416,6 +438,50 @@ export function createSocialController({
416
438
  <div class="skill-card__meta-value mono">${locationText}</div>
417
439
  </div>
418
440
  </div>
441
+ ${installable ? `
442
+ <div class="actions">
443
+ <button class="secondary skill-install-btn" type="button" data-skill-install="${escapeHtml(skillName)}">${updateAvailable ? t("actions.updateThisSkill") : t("actions.installThisSkill")}</button>
444
+ </div>
445
+ ` : ""}
446
+ </div>
447
+ `;
448
+ }
449
+
450
+ function setSkillActionCopy({ title, body, state }) {
451
+ document.getElementById("skillsActionTitle").textContent = title;
452
+ document.getElementById("skillsActionBody").textContent = body;
453
+ document.getElementById("skillsActionState").textContent = state;
454
+ }
455
+
456
+ function renderDialogueCard(skill) {
457
+ const sections = Array.isArray(skill.owner_dialogue_sections_zh) ? skill.owner_dialogue_sections_zh : [];
458
+ const examples = Array.isArray(skill.owner_dialogue_examples_zh) ? skill.owner_dialogue_examples_zh : [];
459
+ return `
460
+ <div class="skill-card">
461
+ <div class="skill-card__top">
462
+ <div>
463
+ <div class="skill-card__eyebrow">${escapeHtml(skill.display_name || skill.name || "Skill")}</div>
464
+ <div class="skill-card__title">${escapeHtml(t("labels.skillsDialogueExamples"))}</div>
465
+ </div>
466
+ <div class="skill-card__version mono">${escapeHtml(skill.version || "-")}</div>
467
+ </div>
468
+ <div class="skill-card__body">${escapeHtml(skill.description || "-")}</div>
469
+ <div class="skills-dialogue-list">
470
+ ${sections.length
471
+ ? sections.map((section) => `
472
+ <div class="skills-dialogue-group">
473
+ <div class="skills-dialogue-group__title">${escapeHtml(String(section.title || "-"))}</div>
474
+ <div class="skills-dialogue-group__items">
475
+ ${Array.isArray(section.items)
476
+ ? section.items.map((item) => `<div class="skills-dialogue-item">"${escapeHtml(String(item))}"</div>`).join("")
477
+ : ""}
478
+ </div>
479
+ </div>
480
+ `).join("")
481
+ : examples.length
482
+ ? examples.map((item) => `<div class="skills-dialogue-item">"${escapeHtml(String(item))}"</div>`).join("")
483
+ : `<div class="skills-empty">${t("hints.skillsNoDialogueExamples")}</div>`}
484
+ </div>
419
485
  </div>
420
486
  `;
421
487
  }
@@ -427,9 +493,29 @@ export function createSocialController({
427
493
  const openclaw = payload.openclaw || {};
428
494
  const summary = payload.summary || {};
429
495
  const installAction = payload.install_action || {};
430
- const featured = bundled[0] || null;
496
+ const broadcastSkill = bundled.find((item) => item.name === "silicaclaw-broadcast") || bundled[0] || null;
497
+ const ownerPushSkill = bundled.find((item) => item.name === "silicaclaw-owner-push") || null;
498
+ const featuredSkills = [broadcastSkill, ownerPushSkill].filter(Boolean);
431
499
  const openclawDetected = !!openclaw.detected;
432
500
  const openclawRunning = !!openclaw.running;
501
+ const allFeaturedInstalled = featuredSkills.length > 0 && featuredSkills.every((item) => item.installed_in_openclaw);
502
+ const installedFeaturedCount = featuredSkills.filter((item) => item.installed_in_openclaw).length;
503
+ const bundledUpdateCount = bundled.filter((item) => item.update_available).length;
504
+ const bundledSorted = [...bundled].sort((left, right) => {
505
+ const featuredLeft = featuredSkills.some((item) => item?.name === left.name) ? 1 : 0;
506
+ const featuredRight = featuredSkills.some((item) => item?.name === right.name) ? 1 : 0;
507
+ if (featuredLeft !== featuredRight) return featuredRight - featuredLeft;
508
+ const updateLeft = left.update_available ? 1 : 0;
509
+ const updateRight = right.update_available ? 1 : 0;
510
+ if (updateLeft !== updateRight) return updateRight - updateLeft;
511
+ const installLeft = left.installed_in_openclaw ? 1 : 0;
512
+ const installRight = right.installed_in_openclaw ? 1 : 0;
513
+ if (installLeft !== installRight) return installLeft - installRight;
514
+ return String(left.display_name || left.name || "").localeCompare(String(right.display_name || right.name || ""));
515
+ });
516
+ const installedSorted = [...installed].sort((left, right) =>
517
+ String(left.display_name || left.name || "").localeCompare(String(right.display_name || right.name || ""))
518
+ );
433
519
 
434
520
  document.getElementById("skillsBannerRuntimeValue").textContent = t("hints.skillsRuntimeSummary", {
435
521
  runtime: openclawRunning ? t("common.yes") : t("common.no"),
@@ -437,51 +523,114 @@ export function createSocialController({
437
523
  installed: String(summary.installed_count || 0),
438
524
  });
439
525
 
526
+ if (!openclawDetected) {
527
+ setSkillActionCopy({
528
+ title: t("hints.skillsActionMissingTitle"),
529
+ body: t("hints.skillsActionMissingBody"),
530
+ state: t("labels.skillsStateAttention"),
531
+ });
532
+ } else if (!openclawRunning) {
533
+ setSkillActionCopy({
534
+ title: t("hints.skillsActionStoppedTitle"),
535
+ body: t("hints.skillsActionStoppedBody"),
536
+ state: t("labels.skillsStateAttention"),
537
+ });
538
+ } else if (bundledUpdateCount > 0) {
539
+ setSkillActionCopy({
540
+ title: t("hints.skillsActionUpdateTitle", { count: String(bundledUpdateCount) }),
541
+ body: t("hints.skillsActionUpdateBody", { count: String(bundledUpdateCount) }),
542
+ state: t("labels.skillsStateAttention"),
543
+ });
544
+ } else if (allFeaturedInstalled) {
545
+ setSkillActionCopy({
546
+ title: t("hints.skillsActionCompleteTitle"),
547
+ body: t("hints.skillsActionCompleteBody"),
548
+ state: t("labels.skillsStateComplete"),
549
+ });
550
+ } else if (installedFeaturedCount > 0) {
551
+ setSkillActionCopy({
552
+ title: t("hints.skillsActionPartialTitle"),
553
+ body: t("hints.skillsActionPartialBody"),
554
+ state: t("labels.skillsStateInProgress"),
555
+ });
556
+ } else {
557
+ setSkillActionCopy({
558
+ title: t("hints.skillsActionInstallTitle"),
559
+ body: t("hints.skillsActionInstallBody"),
560
+ state: t("labels.skillsStateReady"),
561
+ });
562
+ }
563
+
440
564
  document.getElementById("skillsSummaryCards").innerHTML = [
441
565
  [t("labels.skillsBundled"), String(summary.bundled_count || 0)],
442
566
  [t("labels.skillsInstalled"), String(summary.installed_count || 0)],
443
- [t("social.openclawInstalled"), openclawDetected ? t("common.yes") : t("common.no")],
444
- [t("social.running"), openclawRunning ? t("common.yes") : t("common.no")],
445
- ].map(([k, v]) => `<div class="card"><div class="label">${k}</div><div class="value" style="font-size:17px;">${escapeHtml(v)}</div></div>`).join("");
567
+ [t("labels.skillsUpdates"), String(summary.update_available_count || 0)],
568
+ [t("labels.skillsBroadcastLearning"), broadcastSkill?.installed_in_openclaw ? t("common.yes") : t("common.no")],
569
+ [t("labels.skillsAutoPush"), ownerPushSkill?.installed_in_openclaw ? t("common.yes") : t("common.no")],
570
+ ].map(([k, v]) => `<div class="skills-summary-card"><div class="label">${k}</div><div class="value">${escapeHtml(v)}</div></div>`).join("");
571
+
572
+ document.getElementById("skillsFeaturedCount").textContent = `${featuredSkills.length}`;
573
+ document.getElementById("skillsBundledCount").textContent = `${bundled.length}`;
574
+ document.getElementById("skillsInstalledCount").textContent = `${installed.length}`;
575
+ document.getElementById("skillsDialogueCount").textContent = `${featuredSkills.length}`;
446
576
 
447
- document.getElementById("skillsFeaturedSpotlight").innerHTML = featured
448
- ? `
577
+ document.getElementById("skillsFeaturedSpotlights").innerHTML = featuredSkills.length
578
+ ? featuredSkills.map((skill) => `
449
579
  <div class="skills-spotlight">
450
- <div class="skill-card__eyebrow">${escapeHtml(openclaw.gateway_url || "OpenClaw skill")}</div>
451
- <div class="skills-spotlight__title">${escapeHtml(featured.display_name || featured.name)}</div>
452
- <div class="skills-spotlight__body">${escapeHtml(featured.description || "-")}</div>
580
+ <div class="skill-card__eyebrow">${escapeHtml(skill.name === "silicaclaw-owner-push" ? t("labels.skillsAutoPush") : t("labels.skillsBroadcastLearning"))}</div>
581
+ <div class="skills-spotlight__title">${escapeHtml(skill.display_name || skill.name)}</div>
582
+ <div class="skills-spotlight__body">${escapeHtml(skill.description || "-")}</div>
453
583
  <div class="skill-card__tags">
454
- <span class="${featured.installed_in_openclaw ? "tag-chip emphasis" : "tag-chip muted"}">${featured.installed_in_openclaw ? t("common.yes") : t("hints.skillsNotInstalled")}</span>
455
- ${(featured.capabilities || []).slice(0, 8).map((item) => `<span class="tag-chip">${escapeHtml(String(item))}</span>`).join("")}
584
+ <span class="${skill.update_available ? "tag-chip warn" : skill.installed_in_openclaw ? "tag-chip emphasis" : "tag-chip muted"}">${skill.update_available ? t("labels.skillsUpdateAvailable") : skill.installed_in_openclaw ? `${t("labels.skillsStatus")}: ${t("common.yes")}` : t("hints.skillsNotInstalled")}</span>
585
+ ${(skill.capabilities || []).slice(0, 8).map((item) => `<span class="tag-chip">${escapeHtml(String(item))}</span>`).join("")}
456
586
  </div>
457
587
  </div>
458
- `
588
+ `).join("")
459
589
  : `<div class="skills-empty">${t("hints.skillsNoBundled")}</div>`;
460
590
 
461
- document.getElementById("skillsBundledGrid").innerHTML = bundled.length
462
- ? bundled.map((skill) => renderSkillCard(skill, {
591
+ document.getElementById("skillsBundledGrid").innerHTML = bundledSorted.length
592
+ ? bundledSorted.map((skill) => renderSkillCard(skill, {
463
593
  eyebrow: skill.install_mode === "workspace" || skill.install_mode === "legacy" ? skill.install_mode : "bundled",
464
- statusText: skill.installed_in_openclaw ? `${t("labels.skillsStatus")}: ${t("common.yes")}` : t("hints.skillsNotInstalled"),
594
+ statusText: skill.update_available
595
+ ? t("labels.skillsUpdateAvailable")
596
+ : skill.installed_in_openclaw
597
+ ? `${t("labels.skillsStatus")}: ${t("common.yes")}`
598
+ : t("hints.skillsNotInstalled"),
599
+ installable: true,
600
+ updateAvailable: skill.update_available,
601
+ installedVersion: skill.installed_version,
602
+ bundledVersion: skill.version,
465
603
  })).join("")
466
604
  : `<div class="skills-empty">${t("hints.skillsNoBundled")}</div>`;
467
605
 
468
- document.getElementById("skillsInstalledGrid").innerHTML = installed.length
469
- ? installed.map((skill) => renderSkillCard(skill, {
606
+ document.getElementById("skillsInstalledGrid").innerHTML = installedSorted.length
607
+ ? installedSorted.map((skill) => renderSkillCard(skill, {
470
608
  eyebrow: skill.install_mode || "installed",
471
- statusText: `${t("labels.skillsStatus")}: ${escapeHtml(String(skill.install_mode || "-"))}`,
609
+ statusText: skill.update_available
610
+ ? t("labels.skillsUpdateAvailable")
611
+ : `${t("labels.skillsStatus")}: ${escapeHtml(String(skill.install_mode || "-"))}`,
612
+ updateAvailable: skill.update_available,
613
+ installedVersion: skill.version,
614
+ bundledVersion: skill.bundled_version,
472
615
  })).join("")
473
616
  : `<div class="skills-empty">${t("hints.skillsNoInstalled")}</div>`;
474
617
 
618
+ document.getElementById("skillsDialogueGrid").innerHTML = featuredSkills.length
619
+ ? featuredSkills.map((skill) => renderDialogueCard(skill)).join("")
620
+ : `<div class="skills-empty">${t("hints.skillsNoDialogueExamples")}</div>`;
621
+
475
622
  const installBtn = document.getElementById("skillsInstallBtn");
476
623
  installBtn.textContent = !openclawDetected
477
624
  ? t("actions.openclawNotInstalled")
478
625
  : !openclawRunning
479
626
  ? t("actions.openclawNotRunning")
480
- : featured?.installed_in_openclaw
481
- ? t("actions.openclawSkillLearned")
482
- : t("actions.learnOpenClawSkill");
483
- installBtn.disabled = !openclawDetected || !openclawRunning || !!featured?.installed_in_openclaw;
484
- document.getElementById("skillsFeedback").textContent = featured?.installed_in_openclaw
627
+ : bundledUpdateCount > 0
628
+ ? t("actions.updateSilicaClawSkills")
629
+ : allFeaturedInstalled
630
+ ? t("actions.silicaClawSkillsInstalled")
631
+ : t("actions.installSilicaClawSkills");
632
+ installBtn.disabled = !openclawDetected || !openclawRunning || (allFeaturedInstalled && bundledUpdateCount === 0);
633
+ document.getElementById("skillsFeedback").textContent = allFeaturedInstalled && bundledUpdateCount === 0
485
634
  ? t("feedback.openclawSkillInstalled")
486
635
  : installAction.recommended_command || t("common.ready");
487
636
  }