@silicaclaw/cli 2026.3.19-9 → 2026.3.20-10

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 (331) hide show
  1. package/CHANGELOG.md +182 -0
  2. package/DEMO_GUIDE.md +1 -1
  3. package/INSTALL.md +53 -13
  4. package/README.md +106 -23
  5. package/VERSION +1 -1
  6. package/apps/local-console/dist/apps/local-console/src/server.d.ts +180 -14
  7. package/apps/local-console/dist/apps/local-console/src/server.js +1499 -267
  8. package/apps/local-console/dist/config/silicaclaw-defaults.json +19 -0
  9. package/apps/local-console/dist/packages/core/src/index.d.ts +2 -0
  10. package/apps/local-console/dist/packages/core/src/index.js +2 -0
  11. package/apps/local-console/dist/packages/core/src/privateCrypto.d.ts +17 -0
  12. package/apps/local-console/dist/packages/core/src/privateCrypto.js +40 -0
  13. package/apps/local-console/dist/packages/core/src/privateMessage.d.ts +23 -0
  14. package/apps/local-console/dist/packages/core/src/privateMessage.js +74 -0
  15. package/apps/local-console/dist/packages/core/src/profile.js +2 -0
  16. package/apps/local-console/dist/packages/core/src/publicProfileSummary.d.ts +4 -0
  17. package/apps/local-console/dist/packages/core/src/publicProfileSummary.js +3 -0
  18. package/apps/local-console/dist/packages/core/src/socialConfig.js +9 -5
  19. package/apps/local-console/dist/packages/core/src/types.d.ts +40 -0
  20. package/apps/local-console/dist/packages/network/src/realPreview.js +6 -2
  21. package/apps/local-console/dist/packages/network/src/relayPreview.d.ts +12 -0
  22. package/apps/local-console/dist/packages/network/src/relayPreview.js +116 -10
  23. package/apps/local-console/dist/packages/network/src/transport/udpLanBroadcastTransport.js +2 -1
  24. package/apps/local-console/dist/packages/network/src/types.d.ts +4 -0
  25. package/apps/local-console/dist/packages/network/src/webrtcPreview.js +5 -1
  26. package/apps/local-console/dist/packages/storage/config/silicaclaw-defaults.json +19 -0
  27. package/apps/local-console/dist/packages/storage/src/repos.d.ts +13 -1
  28. package/apps/local-console/dist/packages/storage/src/repos.js +19 -1
  29. package/apps/local-console/dist/packages/storage/src/socialRuntimeRepo.js +8 -4
  30. package/apps/local-console/public/app/app.js +486 -12
  31. package/apps/local-console/public/app/events.js +61 -2
  32. package/apps/local-console/public/app/network.js +176 -35
  33. package/apps/local-console/public/app/overview.js +75 -53
  34. package/apps/local-console/public/app/shell.js +18 -34
  35. package/apps/local-console/public/app/social.js +495 -93
  36. package/apps/local-console/public/app/styles.css +309 -15
  37. package/apps/local-console/public/app/template.js +182 -51
  38. package/apps/local-console/public/app/translations.js +476 -266
  39. package/apps/local-console/src/server.ts +1669 -271
  40. package/apps/public-explorer/dist/apps/public-explorer/src/server.d.ts +1 -0
  41. package/apps/public-explorer/dist/apps/public-explorer/src/server.js +41 -0
  42. package/apps/public-explorer/dist/config/silicaclaw-defaults.json +19 -0
  43. package/apps/public-explorer/public/app/app.js +22 -2
  44. package/apps/public-explorer/public/app/template.js +4 -4
  45. package/apps/public-explorer/public/app/translations.js +29 -29
  46. package/apps/public-explorer/src/server.ts +11 -1
  47. package/config/silicaclaw-defaults.json +19 -0
  48. package/dist/apps/local-console/src/server.d.ts +1 -0
  49. package/dist/apps/local-console/src/server.js +555 -0
  50. package/docs/NEW_USER_INSTALL.md +14 -10
  51. package/docs/NEW_USER_OPERATIONS.md +9 -9
  52. package/docs/OPENCLAW_BRIDGE.md +22 -7
  53. package/docs/OPENCLAW_BRIDGE_ZH.md +21 -6
  54. package/docs/RELEASE_CHECKLIST.md +95 -0
  55. package/node_modules/@silicaclaw/core/dist/config/silicaclaw-defaults.json +19 -0
  56. package/node_modules/@silicaclaw/core/dist/packages/core/src/crypto.d.ts +6 -0
  57. package/node_modules/@silicaclaw/core/dist/packages/core/src/crypto.js +50 -0
  58. package/node_modules/@silicaclaw/core/dist/packages/core/src/directory.d.ts +17 -0
  59. package/node_modules/@silicaclaw/core/dist/packages/core/src/directory.js +145 -0
  60. package/node_modules/@silicaclaw/core/dist/packages/core/src/identity.d.ts +2 -0
  61. package/node_modules/@silicaclaw/core/dist/packages/core/src/identity.js +18 -0
  62. package/node_modules/@silicaclaw/core/dist/packages/core/src/index.d.ts +14 -0
  63. package/node_modules/@silicaclaw/core/dist/packages/core/src/index.js +30 -0
  64. package/node_modules/@silicaclaw/core/dist/packages/core/src/indexing.d.ts +6 -0
  65. package/node_modules/@silicaclaw/core/dist/packages/core/src/indexing.js +43 -0
  66. package/node_modules/@silicaclaw/core/dist/packages/core/src/presence.d.ts +4 -0
  67. package/node_modules/@silicaclaw/core/dist/packages/core/src/presence.js +23 -0
  68. package/node_modules/@silicaclaw/core/dist/packages/core/src/privateCrypto.d.ts +17 -0
  69. package/node_modules/@silicaclaw/core/dist/packages/core/src/privateCrypto.js +40 -0
  70. package/node_modules/@silicaclaw/core/dist/packages/core/src/privateMessage.d.ts +23 -0
  71. package/node_modules/@silicaclaw/core/dist/packages/core/src/privateMessage.js +74 -0
  72. package/node_modules/@silicaclaw/core/dist/packages/core/src/profile.d.ts +4 -0
  73. package/node_modules/@silicaclaw/core/dist/packages/core/src/profile.js +41 -0
  74. package/node_modules/@silicaclaw/core/dist/packages/core/src/publicProfileSummary.d.ts +74 -0
  75. package/node_modules/@silicaclaw/core/dist/packages/core/src/publicProfileSummary.js +106 -0
  76. package/node_modules/@silicaclaw/core/dist/packages/core/src/socialConfig.d.ts +100 -0
  77. package/node_modules/@silicaclaw/core/dist/packages/core/src/socialConfig.js +300 -0
  78. package/node_modules/@silicaclaw/core/dist/packages/core/src/socialMessage.d.ts +19 -0
  79. package/node_modules/@silicaclaw/core/dist/packages/core/src/socialMessage.js +69 -0
  80. package/node_modules/@silicaclaw/core/dist/packages/core/src/socialResolver.d.ts +46 -0
  81. package/node_modules/@silicaclaw/core/dist/packages/core/src/socialResolver.js +237 -0
  82. package/node_modules/@silicaclaw/core/dist/packages/core/src/socialTemplate.d.ts +2 -0
  83. package/node_modules/@silicaclaw/core/dist/packages/core/src/socialTemplate.js +90 -0
  84. package/node_modules/@silicaclaw/core/dist/packages/core/src/types.d.ts +99 -0
  85. package/node_modules/@silicaclaw/core/dist/packages/core/src/types.js +2 -0
  86. package/node_modules/@silicaclaw/core/src/index.ts +2 -0
  87. package/node_modules/@silicaclaw/core/src/privateCrypto.ts +57 -0
  88. package/node_modules/@silicaclaw/core/src/privateMessage.ts +101 -0
  89. package/node_modules/@silicaclaw/core/src/profile.ts +2 -0
  90. package/node_modules/@silicaclaw/core/src/publicProfileSummary.ts +7 -0
  91. package/node_modules/@silicaclaw/core/src/socialConfig.ts +7 -5
  92. package/node_modules/@silicaclaw/core/src/types.ts +44 -0
  93. package/node_modules/@silicaclaw/network/dist/config/silicaclaw-defaults.json +19 -0
  94. package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/messageEnvelope.d.ts +28 -0
  95. package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/messageEnvelope.js +36 -0
  96. package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/peerDiscovery.d.ts +43 -0
  97. package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/peerDiscovery.js +2 -0
  98. package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/topicCodec.d.ts +4 -0
  99. package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/topicCodec.js +2 -0
  100. package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/transport.d.ts +36 -0
  101. package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/transport.js +2 -0
  102. package/node_modules/@silicaclaw/network/dist/packages/network/src/codec/jsonMessageEnvelopeCodec.d.ts +5 -0
  103. package/node_modules/@silicaclaw/network/dist/packages/network/src/codec/jsonMessageEnvelopeCodec.js +24 -0
  104. package/node_modules/@silicaclaw/network/dist/packages/network/src/codec/jsonTopicCodec.d.ts +5 -0
  105. package/node_modules/@silicaclaw/network/dist/packages/network/src/codec/jsonTopicCodec.js +12 -0
  106. package/node_modules/@silicaclaw/network/dist/packages/network/src/discovery/heartbeatPeerDiscovery.d.ts +28 -0
  107. package/node_modules/@silicaclaw/network/dist/packages/network/src/discovery/heartbeatPeerDiscovery.js +144 -0
  108. package/node_modules/@silicaclaw/network/dist/packages/network/src/index.d.ts +14 -0
  109. package/node_modules/@silicaclaw/network/dist/packages/network/src/index.js +30 -0
  110. package/node_modules/@silicaclaw/network/dist/packages/network/src/localEventBus.d.ts +9 -0
  111. package/node_modules/@silicaclaw/network/dist/packages/network/src/localEventBus.js +47 -0
  112. package/node_modules/@silicaclaw/network/dist/packages/network/src/mock.d.ts +8 -0
  113. package/node_modules/@silicaclaw/network/dist/packages/network/src/mock.js +24 -0
  114. package/node_modules/@silicaclaw/network/dist/packages/network/src/realPreview.d.ts +105 -0
  115. package/node_modules/@silicaclaw/network/dist/packages/network/src/realPreview.js +331 -0
  116. package/node_modules/@silicaclaw/network/dist/packages/network/src/relayPreview.d.ts +178 -0
  117. package/node_modules/@silicaclaw/network/dist/packages/network/src/relayPreview.js +548 -0
  118. package/node_modules/@silicaclaw/network/dist/packages/network/src/transport/udpLanBroadcastTransport.d.ts +23 -0
  119. package/node_modules/@silicaclaw/network/dist/packages/network/src/transport/udpLanBroadcastTransport.js +154 -0
  120. package/node_modules/@silicaclaw/network/dist/packages/network/src/types.d.ts +10 -0
  121. package/node_modules/@silicaclaw/network/dist/packages/network/src/types.js +2 -0
  122. package/node_modules/@silicaclaw/network/dist/packages/network/src/webrtcPreview.d.ts +163 -0
  123. package/node_modules/@silicaclaw/network/dist/packages/network/src/webrtcPreview.js +848 -0
  124. package/node_modules/@silicaclaw/network/src/realPreview.ts +3 -2
  125. package/node_modules/@silicaclaw/network/src/relayPreview.ts +125 -12
  126. package/node_modules/@silicaclaw/network/src/transport/udpLanBroadcastTransport.ts +2 -1
  127. package/node_modules/@silicaclaw/network/src/types.ts +2 -0
  128. package/node_modules/@silicaclaw/network/src/webrtcPreview.ts +2 -1
  129. package/node_modules/@silicaclaw/storage/config/silicaclaw-defaults.json +19 -0
  130. package/node_modules/@silicaclaw/storage/dist/config/silicaclaw-defaults.json +19 -0
  131. package/node_modules/@silicaclaw/storage/dist/packages/core/src/crypto.d.ts +6 -0
  132. package/node_modules/@silicaclaw/storage/dist/packages/core/src/crypto.js +50 -0
  133. package/node_modules/@silicaclaw/storage/dist/packages/core/src/directory.d.ts +17 -0
  134. package/node_modules/@silicaclaw/storage/dist/packages/core/src/directory.js +145 -0
  135. package/node_modules/@silicaclaw/storage/dist/packages/core/src/identity.d.ts +2 -0
  136. package/node_modules/@silicaclaw/storage/dist/packages/core/src/identity.js +18 -0
  137. package/node_modules/@silicaclaw/storage/dist/packages/core/src/index.d.ts +14 -0
  138. package/node_modules/@silicaclaw/storage/dist/packages/core/src/index.js +30 -0
  139. package/node_modules/@silicaclaw/storage/dist/packages/core/src/indexing.d.ts +6 -0
  140. package/node_modules/@silicaclaw/storage/dist/packages/core/src/indexing.js +43 -0
  141. package/node_modules/@silicaclaw/storage/dist/packages/core/src/presence.d.ts +4 -0
  142. package/node_modules/@silicaclaw/storage/dist/packages/core/src/presence.js +23 -0
  143. package/node_modules/@silicaclaw/storage/dist/packages/core/src/privateCrypto.d.ts +17 -0
  144. package/node_modules/@silicaclaw/storage/dist/packages/core/src/privateCrypto.js +40 -0
  145. package/node_modules/@silicaclaw/storage/dist/packages/core/src/privateMessage.d.ts +23 -0
  146. package/node_modules/@silicaclaw/storage/dist/packages/core/src/privateMessage.js +74 -0
  147. package/node_modules/@silicaclaw/storage/dist/packages/core/src/profile.d.ts +4 -0
  148. package/node_modules/@silicaclaw/storage/dist/packages/core/src/profile.js +41 -0
  149. package/node_modules/@silicaclaw/storage/dist/packages/core/src/publicProfileSummary.d.ts +74 -0
  150. package/node_modules/@silicaclaw/storage/dist/packages/core/src/publicProfileSummary.js +106 -0
  151. package/node_modules/@silicaclaw/storage/dist/packages/core/src/socialConfig.d.ts +100 -0
  152. package/node_modules/@silicaclaw/storage/dist/packages/core/src/socialConfig.js +300 -0
  153. package/node_modules/@silicaclaw/storage/dist/packages/core/src/socialMessage.d.ts +19 -0
  154. package/node_modules/@silicaclaw/storage/dist/packages/core/src/socialMessage.js +69 -0
  155. package/node_modules/@silicaclaw/storage/dist/packages/core/src/socialResolver.d.ts +46 -0
  156. package/node_modules/@silicaclaw/storage/dist/packages/core/src/socialResolver.js +237 -0
  157. package/node_modules/@silicaclaw/storage/dist/packages/core/src/socialTemplate.d.ts +2 -0
  158. package/node_modules/@silicaclaw/storage/dist/packages/core/src/socialTemplate.js +90 -0
  159. package/node_modules/@silicaclaw/storage/dist/packages/core/src/types.d.ts +99 -0
  160. package/node_modules/@silicaclaw/storage/dist/packages/core/src/types.js +2 -0
  161. package/node_modules/@silicaclaw/storage/dist/packages/storage/config/silicaclaw-defaults.json +19 -0
  162. package/node_modules/@silicaclaw/storage/dist/packages/storage/src/index.d.ts +3 -0
  163. package/node_modules/@silicaclaw/storage/dist/packages/storage/src/index.js +19 -0
  164. package/node_modules/@silicaclaw/storage/dist/packages/storage/src/jsonRepo.d.ts +7 -0
  165. package/node_modules/@silicaclaw/storage/dist/packages/storage/src/jsonRepo.js +29 -0
  166. package/node_modules/@silicaclaw/storage/dist/packages/storage/src/repos.d.ts +73 -0
  167. package/node_modules/@silicaclaw/storage/dist/packages/storage/src/repos.js +85 -0
  168. package/node_modules/@silicaclaw/storage/dist/packages/storage/src/socialRuntimeRepo.d.ts +5 -0
  169. package/node_modules/@silicaclaw/storage/dist/packages/storage/src/socialRuntimeRepo.js +57 -0
  170. package/node_modules/@silicaclaw/storage/dist/socialRuntimeRepo.js +8 -4
  171. package/node_modules/@silicaclaw/storage/src/repos.ts +31 -1
  172. package/node_modules/@silicaclaw/storage/src/socialRuntimeRepo.ts +5 -4
  173. package/node_modules/@silicaclaw/storage/tsconfig.json +1 -6
  174. package/openclaw-skills/silicaclaw-bridge-setup/SKILL.md +165 -0
  175. package/openclaw-skills/silicaclaw-bridge-setup/VERSION +1 -0
  176. package/openclaw-skills/silicaclaw-bridge-setup/agents/openai.yaml +6 -0
  177. package/openclaw-skills/silicaclaw-bridge-setup/manifest.json +27 -0
  178. package/openclaw-skills/silicaclaw-bridge-setup/references/owner-dialogue-cheatsheet-zh.md +58 -0
  179. package/openclaw-skills/silicaclaw-bridge-setup/references/runtime-setup.md +43 -0
  180. package/openclaw-skills/silicaclaw-bridge-setup/references/troubleshooting.md +24 -0
  181. package/openclaw-skills/silicaclaw-broadcast/SKILL.md +150 -0
  182. package/openclaw-skills/silicaclaw-broadcast/VERSION +1 -1
  183. package/openclaw-skills/silicaclaw-broadcast/agents/openai.yaml +2 -2
  184. package/openclaw-skills/silicaclaw-broadcast/manifest.json +4 -3
  185. package/openclaw-skills/silicaclaw-broadcast/references/owner-dialogue-cheatsheet-zh.md +81 -0
  186. package/openclaw-skills/silicaclaw-network-config/SKILL.md +158 -0
  187. package/openclaw-skills/silicaclaw-network-config/VERSION +1 -0
  188. package/openclaw-skills/silicaclaw-network-config/agents/openai.yaml +6 -0
  189. package/openclaw-skills/silicaclaw-network-config/manifest.json +27 -0
  190. package/openclaw-skills/silicaclaw-network-config/references/network-modes.md +22 -0
  191. package/openclaw-skills/silicaclaw-network-config/references/owner-dialogue-cheatsheet-zh.md +47 -0
  192. package/openclaw-skills/silicaclaw-network-config/references/public-discovery.md +22 -0
  193. package/openclaw-skills/silicaclaw-owner-push/SKILL.md +235 -0
  194. package/openclaw-skills/silicaclaw-owner-push/VERSION +1 -0
  195. package/openclaw-skills/silicaclaw-owner-push/agents/openai.yaml +6 -0
  196. package/openclaw-skills/silicaclaw-owner-push/manifest.json +30 -0
  197. package/openclaw-skills/silicaclaw-owner-push/references/owner-dialogue-cheatsheet-zh.md +87 -0
  198. package/openclaw-skills/silicaclaw-owner-push/references/push-routing-policy.md +43 -0
  199. package/openclaw-skills/silicaclaw-owner-push/references/runtime-setup.md +44 -0
  200. package/openclaw-skills/silicaclaw-owner-push/scripts/owner-push-forwarder.mjs +356 -0
  201. package/openclaw-skills/silicaclaw-owner-push/scripts/send-to-owner-via-openclaw.mjs +69 -0
  202. package/package.json +5 -1
  203. package/packages/core/dist/config/silicaclaw-defaults.json +19 -0
  204. package/packages/core/dist/packages/core/src/crypto.d.ts +6 -0
  205. package/packages/core/dist/packages/core/src/crypto.js +50 -0
  206. package/packages/core/dist/packages/core/src/directory.d.ts +17 -0
  207. package/packages/core/dist/packages/core/src/directory.js +145 -0
  208. package/packages/core/dist/packages/core/src/identity.d.ts +2 -0
  209. package/packages/core/dist/packages/core/src/identity.js +18 -0
  210. package/packages/core/dist/packages/core/src/index.d.ts +14 -0
  211. package/packages/core/dist/packages/core/src/index.js +30 -0
  212. package/packages/core/dist/packages/core/src/indexing.d.ts +6 -0
  213. package/packages/core/dist/packages/core/src/indexing.js +43 -0
  214. package/packages/core/dist/packages/core/src/presence.d.ts +4 -0
  215. package/packages/core/dist/packages/core/src/presence.js +23 -0
  216. package/packages/core/dist/packages/core/src/privateCrypto.d.ts +17 -0
  217. package/packages/core/dist/packages/core/src/privateCrypto.js +40 -0
  218. package/packages/core/dist/packages/core/src/privateMessage.d.ts +23 -0
  219. package/packages/core/dist/packages/core/src/privateMessage.js +74 -0
  220. package/packages/core/dist/packages/core/src/profile.d.ts +4 -0
  221. package/packages/core/dist/packages/core/src/profile.js +41 -0
  222. package/packages/core/dist/packages/core/src/publicProfileSummary.d.ts +74 -0
  223. package/packages/core/dist/packages/core/src/publicProfileSummary.js +106 -0
  224. package/packages/core/dist/packages/core/src/socialConfig.d.ts +100 -0
  225. package/packages/core/dist/packages/core/src/socialConfig.js +300 -0
  226. package/packages/core/dist/packages/core/src/socialMessage.d.ts +19 -0
  227. package/packages/core/dist/packages/core/src/socialMessage.js +69 -0
  228. package/packages/core/dist/packages/core/src/socialResolver.d.ts +46 -0
  229. package/packages/core/dist/packages/core/src/socialResolver.js +237 -0
  230. package/packages/core/dist/packages/core/src/socialTemplate.d.ts +2 -0
  231. package/packages/core/dist/packages/core/src/socialTemplate.js +90 -0
  232. package/packages/core/dist/packages/core/src/types.d.ts +99 -0
  233. package/packages/core/dist/packages/core/src/types.js +2 -0
  234. package/packages/core/src/index.ts +2 -0
  235. package/packages/core/src/privateCrypto.ts +57 -0
  236. package/packages/core/src/privateMessage.ts +101 -0
  237. package/packages/core/src/profile.ts +2 -0
  238. package/packages/core/src/publicProfileSummary.ts +7 -0
  239. package/packages/core/src/socialConfig.ts +7 -5
  240. package/packages/core/src/types.ts +44 -0
  241. package/packages/network/dist/config/silicaclaw-defaults.json +19 -0
  242. package/packages/network/dist/packages/network/src/abstractions/messageEnvelope.d.ts +28 -0
  243. package/packages/network/dist/packages/network/src/abstractions/messageEnvelope.js +36 -0
  244. package/packages/network/dist/packages/network/src/abstractions/peerDiscovery.d.ts +43 -0
  245. package/packages/network/dist/packages/network/src/abstractions/peerDiscovery.js +2 -0
  246. package/packages/network/dist/packages/network/src/abstractions/topicCodec.d.ts +4 -0
  247. package/packages/network/dist/packages/network/src/abstractions/topicCodec.js +2 -0
  248. package/packages/network/dist/packages/network/src/abstractions/transport.d.ts +36 -0
  249. package/packages/network/dist/packages/network/src/abstractions/transport.js +2 -0
  250. package/packages/network/dist/packages/network/src/codec/jsonMessageEnvelopeCodec.d.ts +5 -0
  251. package/packages/network/dist/packages/network/src/codec/jsonMessageEnvelopeCodec.js +24 -0
  252. package/packages/network/dist/packages/network/src/codec/jsonTopicCodec.d.ts +5 -0
  253. package/packages/network/dist/packages/network/src/codec/jsonTopicCodec.js +12 -0
  254. package/packages/network/dist/packages/network/src/discovery/heartbeatPeerDiscovery.d.ts +28 -0
  255. package/packages/network/dist/packages/network/src/discovery/heartbeatPeerDiscovery.js +144 -0
  256. package/packages/network/dist/packages/network/src/index.d.ts +14 -0
  257. package/packages/network/dist/packages/network/src/index.js +30 -0
  258. package/packages/network/dist/packages/network/src/localEventBus.d.ts +9 -0
  259. package/packages/network/dist/packages/network/src/localEventBus.js +47 -0
  260. package/packages/network/dist/packages/network/src/mock.d.ts +8 -0
  261. package/packages/network/dist/packages/network/src/mock.js +24 -0
  262. package/packages/network/dist/packages/network/src/realPreview.d.ts +105 -0
  263. package/packages/network/dist/packages/network/src/realPreview.js +331 -0
  264. package/packages/network/dist/packages/network/src/relayPreview.d.ts +178 -0
  265. package/packages/network/dist/packages/network/src/relayPreview.js +548 -0
  266. package/packages/network/dist/packages/network/src/transport/udpLanBroadcastTransport.d.ts +23 -0
  267. package/packages/network/dist/packages/network/src/transport/udpLanBroadcastTransport.js +154 -0
  268. package/packages/network/dist/packages/network/src/types.d.ts +10 -0
  269. package/packages/network/dist/packages/network/src/types.js +2 -0
  270. package/packages/network/dist/packages/network/src/webrtcPreview.d.ts +163 -0
  271. package/packages/network/dist/packages/network/src/webrtcPreview.js +848 -0
  272. package/packages/network/src/realPreview.ts +3 -2
  273. package/packages/network/src/relayPreview.ts +125 -12
  274. package/packages/network/src/transport/udpLanBroadcastTransport.ts +2 -1
  275. package/packages/network/src/types.ts +2 -0
  276. package/packages/network/src/webrtcPreview.ts +2 -1
  277. package/packages/storage/config/silicaclaw-defaults.json +19 -0
  278. package/packages/storage/dist/config/silicaclaw-defaults.json +19 -0
  279. package/packages/storage/dist/packages/core/src/crypto.d.ts +6 -0
  280. package/packages/storage/dist/packages/core/src/crypto.js +50 -0
  281. package/packages/storage/dist/packages/core/src/directory.d.ts +17 -0
  282. package/packages/storage/dist/packages/core/src/directory.js +145 -0
  283. package/packages/storage/dist/packages/core/src/identity.d.ts +2 -0
  284. package/packages/storage/dist/packages/core/src/identity.js +18 -0
  285. package/packages/storage/dist/packages/core/src/index.d.ts +14 -0
  286. package/packages/storage/dist/packages/core/src/index.js +30 -0
  287. package/packages/storage/dist/packages/core/src/indexing.d.ts +6 -0
  288. package/packages/storage/dist/packages/core/src/indexing.js +43 -0
  289. package/packages/storage/dist/packages/core/src/presence.d.ts +4 -0
  290. package/packages/storage/dist/packages/core/src/presence.js +23 -0
  291. package/packages/storage/dist/packages/core/src/privateCrypto.d.ts +17 -0
  292. package/packages/storage/dist/packages/core/src/privateCrypto.js +40 -0
  293. package/packages/storage/dist/packages/core/src/privateMessage.d.ts +23 -0
  294. package/packages/storage/dist/packages/core/src/privateMessage.js +74 -0
  295. package/packages/storage/dist/packages/core/src/profile.d.ts +4 -0
  296. package/packages/storage/dist/packages/core/src/profile.js +41 -0
  297. package/packages/storage/dist/packages/core/src/publicProfileSummary.d.ts +74 -0
  298. package/packages/storage/dist/packages/core/src/publicProfileSummary.js +106 -0
  299. package/packages/storage/dist/packages/core/src/socialConfig.d.ts +100 -0
  300. package/packages/storage/dist/packages/core/src/socialConfig.js +300 -0
  301. package/packages/storage/dist/packages/core/src/socialMessage.d.ts +19 -0
  302. package/packages/storage/dist/packages/core/src/socialMessage.js +69 -0
  303. package/packages/storage/dist/packages/core/src/socialResolver.d.ts +46 -0
  304. package/packages/storage/dist/packages/core/src/socialResolver.js +237 -0
  305. package/packages/storage/dist/packages/core/src/socialTemplate.d.ts +2 -0
  306. package/packages/storage/dist/packages/core/src/socialTemplate.js +90 -0
  307. package/packages/storage/dist/packages/core/src/types.d.ts +99 -0
  308. package/packages/storage/dist/packages/core/src/types.js +2 -0
  309. package/packages/storage/dist/packages/storage/config/silicaclaw-defaults.json +19 -0
  310. package/packages/storage/dist/packages/storage/src/index.d.ts +3 -0
  311. package/packages/storage/dist/packages/storage/src/index.js +19 -0
  312. package/packages/storage/dist/packages/storage/src/jsonRepo.d.ts +7 -0
  313. package/packages/storage/dist/packages/storage/src/jsonRepo.js +29 -0
  314. package/packages/storage/dist/packages/storage/src/repos.d.ts +73 -0
  315. package/packages/storage/dist/packages/storage/src/repos.js +85 -0
  316. package/packages/storage/dist/packages/storage/src/socialRuntimeRepo.d.ts +5 -0
  317. package/packages/storage/dist/packages/storage/src/socialRuntimeRepo.js +57 -0
  318. package/packages/storage/dist/socialRuntimeRepo.js +8 -4
  319. package/packages/storage/src/repos.ts +31 -1
  320. package/packages/storage/src/socialRuntimeRepo.ts +5 -4
  321. package/packages/storage/tsconfig.json +1 -6
  322. package/scripts/functional-check.mjs +35 -6
  323. package/scripts/install-openclaw-skill.mjs +9 -2
  324. package/scripts/openclaw-bridge-adapter.mjs +3 -1
  325. package/scripts/openclaw-bridge-client.mjs +3 -1
  326. package/scripts/openclaw-runtime-demo.mjs +3 -1
  327. package/scripts/quickstart.sh +14 -10
  328. package/scripts/release-pack.mjs +59 -1
  329. package/scripts/silicaclaw-cli.mjs +166 -51
  330. package/scripts/silicaclaw-gateway.mjs +410 -84
  331. package/scripts/validate-openclaw-skill.mjs +98 -21
@@ -1,14 +1,20 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { spawn, spawnSync } from "node:child_process";
4
- import { existsSync, mkdirSync, openSync, readFileSync, rmSync, writeFileSync } from "node:fs";
4
+ import { cpSync, existsSync, mkdirSync, openSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs";
5
5
  import { homedir } from "node:os";
6
6
  import { dirname, join, resolve } from "node:path";
7
7
  import { fileURLToPath } from "node:url";
8
+ import defaults from "../config/silicaclaw-defaults.json" with { type: "json" };
8
9
 
9
10
  const __filename = fileURLToPath(import.meta.url);
10
11
  const __dirname = dirname(__filename);
11
12
  const ROOT_DIR = resolve(__dirname, "..");
13
+ const LOCAL_CONSOLE_PORT = defaults.ports.local_console;
14
+ const DEFAULT_NETWORK_MODE = defaults.network.default_mode;
15
+ const DEFAULT_SIGNALING_URL = defaults.network.global_preview.relay_url;
16
+ const DEFAULT_ROOM = defaults.network.global_preview.room;
17
+ const LOCAL_CONSOLE_BASE_URL = defaults.bridge.api_base;
12
18
 
13
19
  const argv = process.argv.slice(2);
14
20
  const cmd = String(argv[0] || "help").toLowerCase();
@@ -48,7 +54,7 @@ function headline() {
48
54
  version = "unknown";
49
55
  }
50
56
  }
51
- console.log(`${paint("SilicaClaw", COLOR.bold, COLOR.orange)} ${paint(displayVersion(version), COLOR.dim)}`);
57
+ console.log(`${paint("🦀 SilicaClaw", COLOR.bold, COLOR.orange)} ${paint(displayVersion(version), COLOR.dim)}`);
52
58
  console.log(paint("Public identity and discovery for OpenClaw agents.", COLOR.dim));
53
59
  }
54
60
 
@@ -68,6 +74,11 @@ function readJson(file) {
68
74
  }
69
75
  }
70
76
 
77
+ function readPackageVersionFrom(dir) {
78
+ const pkg = readJson(resolve(dir, "package.json"));
79
+ return String(pkg?.version || "latest").trim() || "latest";
80
+ }
81
+
71
82
  function isSilicaClawDir(dir) {
72
83
  const pkgPath = join(dir, "package.json");
73
84
  if (!existsSync(pkgPath)) return false;
@@ -114,9 +125,17 @@ function detectAppDir() {
114
125
  return ROOT_DIR;
115
126
  }
116
127
 
128
+ function detectWorkspaceDir() {
129
+ const envDir = process.env.SILICACLAW_WORKSPACE_DIR;
130
+ if (envDir) return resolve(envDir);
131
+ return resolve(process.cwd());
132
+ }
133
+
117
134
  const APP_DIR = detectAppDir();
135
+ const WORKSPACE_DIR = detectWorkspaceDir();
118
136
  const LOCAL_CONSOLE_DIR = join(APP_DIR, "apps", "local-console");
119
- const STATE_DIR = join(APP_DIR, ".silicaclaw", "gateway");
137
+ const STATE_DIR = join(homedir(), ".silicaclaw", "gateway");
138
+ const MANAGED_RUNTIME_DIR = join(homedir(), ".silicaclaw", "runtime", "silicaclaw");
120
139
  const CONSOLE_PID_FILE = join(STATE_DIR, "local-console.pid");
121
140
  const CONSOLE_LOG_FILE = join(STATE_DIR, "local-console.log");
122
141
  const SIGNALING_PID_FILE = join(STATE_DIR, "signaling.pid");
@@ -130,10 +149,115 @@ function ensureStateDir() {
130
149
  mkdirSync(STATE_DIR, { recursive: true });
131
150
  }
132
151
 
152
+ function userShimDir() {
153
+ return join(homedir(), ".silicaclaw", "bin");
154
+ }
155
+
156
+ function userShimPath() {
157
+ return join(userShimDir(), "silicaclaw");
158
+ }
159
+
160
+ function userEnvFile() {
161
+ return join(homedir(), ".silicaclaw", "env.sh");
162
+ }
163
+
164
+ function userNpmCacheDir() {
165
+ return join(homedir(), ".silicaclaw", "npm-cache");
166
+ }
167
+
168
+ function preferredShellRcFile() {
169
+ const shell = String(process.env.SHELL || "");
170
+ if (shell.endsWith("/zsh")) return resolve(homedir(), ".zshrc");
171
+ if (shell.endsWith("/bash")) return resolve(homedir(), ".bashrc");
172
+ if (process.env.ZSH_VERSION) return resolve(homedir(), ".zshrc");
173
+ return resolve(homedir(), ".bashrc");
174
+ }
175
+
176
+ function shellInitTargets() {
177
+ const home = homedir();
178
+ const shell = String(process.env.SHELL || "");
179
+ const targets = [];
180
+ const add = (filePath) => {
181
+ if (!targets.includes(filePath)) targets.push(filePath);
182
+ };
183
+
184
+ if (shell.endsWith("/zsh") || process.env.ZSH_VERSION || existsSync(resolve(home, ".zshrc"))) {
185
+ add(resolve(home, ".zshrc"));
186
+ }
187
+
188
+ if (
189
+ shell.endsWith("/bash") ||
190
+ process.env.BASH_VERSION ||
191
+ existsSync(resolve(home, ".bashrc")) ||
192
+ existsSync(resolve(home, ".bash_profile")) ||
193
+ existsSync(resolve(home, ".profile"))
194
+ ) {
195
+ add(resolve(home, ".bashrc"));
196
+ add(resolve(home, ".bash_profile"));
197
+ add(resolve(home, ".profile"));
198
+ }
199
+
200
+ if (targets.length === 0) {
201
+ add(preferredShellRcFile());
202
+ }
203
+ return targets;
204
+ }
205
+
206
+ function ensureLineInFile(filePath, block) {
207
+ try {
208
+ const current = existsSync(filePath) ? readFileSync(filePath, "utf8") : "";
209
+ if (current.includes(block.trim())) return true;
210
+ const next = `${current.replace(/\s*$/, "")}\n\n${block}\n`;
211
+ mkdirSync(dirname(filePath), { recursive: true });
212
+ writeFileSync(filePath, next, "utf8");
213
+ return true;
214
+ } catch {
215
+ return false;
216
+ }
217
+ }
218
+
219
+ function shimScriptText(specifier = "latest") {
220
+ return [
221
+ "#!/usr/bin/env bash",
222
+ "set -euo pipefail",
223
+ 'export npm_config_cache="${npm_config_cache:-$HOME/.silicaclaw/npm-cache}"',
224
+ `exec npx -y @silicaclaw/cli@${specifier} "$@"`,
225
+ "",
226
+ ].join("\n");
227
+ }
228
+
229
+ function ensureUserCommandInstalled() {
230
+ const version = readPackageVersionFrom(APP_DIR);
231
+ const envBlock = [
232
+ "#!/usr/bin/env bash",
233
+ 'export PATH="$HOME/.silicaclaw/bin:$PATH"',
234
+ 'export npm_config_cache="$HOME/.silicaclaw/npm-cache"',
235
+ "",
236
+ ].join("\n");
237
+ const rcBlock = [
238
+ "# >>> silicaclaw >>>",
239
+ '[ -f "$HOME/.silicaclaw/env.sh" ] && . "$HOME/.silicaclaw/env.sh"',
240
+ "# <<< silicaclaw <<<",
241
+ ].join("\n");
242
+
243
+ mkdirSync(userShimDir(), { recursive: true });
244
+ mkdirSync(userNpmCacheDir(), { recursive: true });
245
+ writeFileSync(userEnvFile(), envBlock, { encoding: "utf8", mode: 0o755 });
246
+ writeFileSync(userShimPath(), shimScriptText(version), { encoding: "utf8", mode: 0o755 });
247
+
248
+ for (const filePath of shellInitTargets()) {
249
+ ensureLineInFile(filePath, rcBlock);
250
+ }
251
+ }
252
+
133
253
  function ensureLaunchAgentsDir() {
134
254
  mkdirSync(LAUNCH_AGENTS_DIR, { recursive: true });
135
255
  }
136
256
 
257
+ function ensureManagedRuntimeDir() {
258
+ mkdirSync(MANAGED_RUNTIME_DIR, { recursive: true });
259
+ }
260
+
137
261
  function readPid(file) {
138
262
  if (!existsSync(file)) return null;
139
263
  const text = String(readFileSync(file, "utf8")).trim();
@@ -155,6 +279,51 @@ function removeFileIfExists(path) {
155
279
  if (existsSync(path)) rmSync(path, { force: true });
156
280
  }
157
281
 
282
+ function syncManagedRuntime() {
283
+ if (resolve(APP_DIR) === resolve(MANAGED_RUNTIME_DIR)) return MANAGED_RUNTIME_DIR;
284
+
285
+ ensureManagedRuntimeDir();
286
+ const entries = [
287
+ "config",
288
+ "scripts",
289
+ "apps/local-console/dist",
290
+ "apps/local-console/package.json",
291
+ "apps/local-console/public",
292
+ "apps/public-explorer/dist",
293
+ "apps/public-explorer/package.json",
294
+ "apps/public-explorer/public",
295
+ "social.md",
296
+ ".openclaw",
297
+ "package.json",
298
+ "package-lock.json",
299
+ "VERSION",
300
+ "node_modules",
301
+ ];
302
+
303
+ for (const rel of entries) {
304
+ const src = resolve(APP_DIR, rel);
305
+ if (!existsSync(src)) continue;
306
+ const dst = resolve(MANAGED_RUNTIME_DIR, rel);
307
+ rmSync(dst, { recursive: true, force: true });
308
+ cpSync(src, dst, {
309
+ recursive: true,
310
+ force: true,
311
+ dereference: rel === "node_modules",
312
+ });
313
+ }
314
+
315
+ const manifest = {
316
+ source_app_dir: APP_DIR,
317
+ synced_at: Date.now(),
318
+ version: readJson(resolve(APP_DIR, "package.json"))?.version || null,
319
+ dist_server_mtime: existsSync(resolve(APP_DIR, "apps", "local-console", "dist", "apps", "local-console", "src", "server.js"))
320
+ ? statSync(resolve(APP_DIR, "apps", "local-console", "dist", "apps", "local-console", "src", "server.js")).mtimeMs
321
+ : null,
322
+ };
323
+ writeFileSync(resolve(MANAGED_RUNTIME_DIR, ".silicaclaw-runtime.json"), JSON.stringify(manifest, null, 2));
324
+ return MANAGED_RUNTIME_DIR;
325
+ }
326
+
158
327
  async function stopPid(pid, name) {
159
328
  if (!pid || !isRunning(pid)) return;
160
329
  try {
@@ -243,25 +412,34 @@ function runLaunchctl(args) {
243
412
  });
244
413
  }
245
414
 
246
- function resolveCommandPath(command) {
247
- const result = spawnSync("which", [command], {
248
- encoding: "utf8",
249
- stdio: ["ignore", "pipe", "ignore"],
250
- });
251
- if ((result.status ?? 1) === 0) {
252
- const value = String(result.stdout || "").trim();
253
- if (value) return value;
254
- }
255
- return command;
415
+ function launchServiceTarget(label) {
416
+ return `${launchdDomain()}/${label}`;
417
+ }
418
+
419
+ function isLaunchctlNotLoadedResult(result) {
420
+ const text = `${result?.stdout || ""}\n${result?.stderr || ""}`.toLowerCase();
421
+ return (
422
+ text.includes("could not find service") ||
423
+ text.includes("service not found") ||
424
+ text.includes("bad request") ||
425
+ text.includes("not loaded")
426
+ );
427
+ }
428
+
429
+ function localConsoleProgramArguments(appDir = APP_DIR) {
430
+ return [
431
+ process.execPath,
432
+ resolve(appDir, "apps", "local-console", "dist", "apps", "local-console", "src", "server.js"),
433
+ ];
256
434
  }
257
435
 
258
436
  function isLaunchAgentLoaded(label) {
259
- const result = runLaunchctl(["print", `${launchdDomain()}/${label}`]);
437
+ const result = runLaunchctl(["print", launchServiceTarget(label)]);
260
438
  return (result.status ?? 1) === 0;
261
439
  }
262
440
 
263
441
  function readLaunchAgentRuntime(label) {
264
- const result = runLaunchctl(["print", `${launchdDomain()}/${label}`]);
442
+ const result = runLaunchctl(["print", launchServiceTarget(label)]);
265
443
  if ((result.status ?? 1) !== 0) return { loaded: false, pid: null };
266
444
  const text = `${result.stdout || ""}\n${result.stderr || ""}`;
267
445
  const pidMatch = text.match(/pid = (\d+)/);
@@ -271,7 +449,47 @@ function readLaunchAgentRuntime(label) {
271
449
  };
272
450
  }
273
451
 
274
- function installLaunchAgent({ label, programArguments, workingDirectory, logFile, environment }) {
452
+ function writeLaunchAgentPlistIfChanged(plistPath, plist) {
453
+ const current = existsSync(plistPath) ? String(readFileSync(plistPath, "utf8")) : null;
454
+ if (current === plist) return false;
455
+ writeFileSync(plistPath, plist, "utf8");
456
+ return true;
457
+ }
458
+
459
+ function bootstrapLaunchAgent(label, plistPath) {
460
+ const result = runLaunchctl(["bootstrap", launchdDomain(), plistPath]);
461
+ if ((result.status ?? 1) !== 0) {
462
+ const detail = String(result.stderr || result.stdout || "launchctl bootstrap failed").trim();
463
+ throw new Error(detail);
464
+ }
465
+ }
466
+
467
+ function startLaunchAgent(label, plistPath) {
468
+ const result = runLaunchctl(["start", launchServiceTarget(label)]);
469
+ if ((result.status ?? 1) === 0) return;
470
+ if (!isLaunchctlNotLoadedResult(result)) {
471
+ const detail = String(result.stderr || result.stdout || "launchctl start failed").trim();
472
+ throw new Error(detail);
473
+ }
474
+ bootstrapLaunchAgent(label, plistPath);
475
+ }
476
+
477
+ function restartLaunchAgent(label, plistPath) {
478
+ const result = runLaunchctl(["kickstart", "-k", launchServiceTarget(label)]);
479
+ if ((result.status ?? 1) === 0) return;
480
+ if (!isLaunchctlNotLoadedResult(result)) {
481
+ const detail = String(result.stderr || result.stdout || "launchctl kickstart failed").trim();
482
+ throw new Error(detail);
483
+ }
484
+ bootstrapLaunchAgent(label, plistPath);
485
+ const retry = runLaunchctl(["kickstart", "-k", launchServiceTarget(label)]);
486
+ if ((retry.status ?? 1) !== 0) {
487
+ const detail = String(retry.stderr || retry.stdout || "launchctl kickstart failed").trim();
488
+ throw new Error(detail);
489
+ }
490
+ }
491
+
492
+ function ensureLaunchAgent({ label, programArguments, workingDirectory, logFile, environment }) {
275
493
  ensureLaunchAgentsDir();
276
494
  ensureStateDir();
277
495
  const plistPath = launchAgentPlistPath(label);
@@ -283,17 +501,23 @@ function installLaunchAgent({ label, programArguments, workingDirectory, logFile
283
501
  stderrPath: logFile,
284
502
  environment,
285
503
  });
286
- writeFileSync(plistPath, plist, "utf8");
287
-
288
- if (isLaunchAgentLoaded(label)) {
289
- runLaunchctl(["bootout", launchdDomain(), plistPath]);
504
+ const changed = writeLaunchAgentPlistIfChanged(plistPath, plist);
505
+ const loaded = isLaunchAgentLoaded(label);
506
+
507
+ if (changed && loaded) {
508
+ const bootout = runLaunchctl(["bootout", launchdDomain(), plistPath]);
509
+ if ((bootout.status ?? 1) !== 0 && !isLaunchctlNotLoadedResult(bootout)) {
510
+ const detail = String(bootout.stderr || bootout.stdout || "launchctl bootout failed").trim();
511
+ throw new Error(detail);
512
+ }
513
+ bootstrapLaunchAgent(label, plistPath);
514
+ return { changed: true, loaded: true, plistPath };
290
515
  }
291
516
 
292
- const result = runLaunchctl(["bootstrap", launchdDomain(), plistPath]);
293
- if ((result.status ?? 1) !== 0) {
294
- const detail = String(result.stderr || result.stdout || "launchctl bootstrap failed").trim();
295
- throw new Error(detail);
517
+ if (!loaded) {
518
+ bootstrapLaunchAgent(label, plistPath);
296
519
  }
520
+ return { changed, loaded, plistPath };
297
521
  }
298
522
 
299
523
  function stopLaunchAgent(label) {
@@ -357,10 +581,11 @@ function launchdStatusPayload() {
357
581
  const state = readState();
358
582
  const localRuntime = readLaunchAgentRuntime(LOCAL_CONSOLE_LABEL);
359
583
  const signalingRuntime = readLaunchAgentRuntime(SIGNALING_LABEL);
360
- const localListener = listeningProcessOnPort(4310);
584
+ const localListener = listeningProcessOnPort(LOCAL_CONSOLE_PORT);
361
585
  const signalingListener = listeningProcessOnPort(4510);
362
586
  return {
363
587
  app_dir: APP_DIR,
588
+ workspace_dir: WORKSPACE_DIR,
364
589
  mode: state?.mode || "unknown",
365
590
  adapter: state?.adapter || "unknown",
366
591
  service_manager: "launchd",
@@ -391,10 +616,12 @@ function buildStatusPayload() {
391
616
  const localPid = readPid(CONSOLE_PID_FILE);
392
617
  const sigPid = readPid(SIGNALING_PID_FILE);
393
618
  const state = readState();
394
- const localListener = listeningProcessOnPort(4310);
619
+ const localListener = listeningProcessOnPort(LOCAL_CONSOLE_PORT);
395
620
  const signalingListener = listeningProcessOnPort(4510);
396
621
  return {
397
622
  app_dir: APP_DIR,
623
+ managed_app_dir: state?.managed_app_dir || null,
624
+ workspace_dir: state?.workspace_dir || WORKSPACE_DIR,
398
625
  mode: state?.mode || "unknown",
399
626
  adapter: state?.adapter || "unknown",
400
627
  local_console: {
@@ -428,10 +655,10 @@ function showStatusHuman() {
428
655
  : `${paint("stopped", COLOR.dim)} · ${payload.mode}`
429
656
  );
430
657
  if (payload.mode === "global-preview") {
431
- kv("Relay", payload.signaling.url || "https://relay.silicaclaw.com");
432
- kv("Room", payload.signaling.room || "silicaclaw-global-preview");
658
+ kv("Relay", payload.signaling.url || DEFAULT_SIGNALING_URL);
659
+ kv("Room", payload.signaling.room || DEFAULT_ROOM);
433
660
  }
434
- if (payload.local_console.running) kv("Open", "http://localhost:4310");
661
+ if (payload.local_console.running) kv("Open", LOCAL_CONSOLE_BASE_URL);
435
662
  return payload;
436
663
  }
437
664
 
@@ -440,10 +667,10 @@ function printConnectionSummary(status, verb = "Started") {
440
667
  headline();
441
668
  console.log("");
442
669
  kv("Status", `${verb.toLowerCase()} · ${status.mode}`);
443
- kv("Console", `http://localhost:4310`);
670
+ kv("Console", LOCAL_CONSOLE_BASE_URL);
444
671
  if (status.mode === "global-preview") {
445
- const signalingUrl = status?.signaling?.url || "https://relay.silicaclaw.com";
446
- const room = status?.signaling?.room || "silicaclaw-global-preview";
672
+ const signalingUrl = status?.signaling?.url || DEFAULT_SIGNALING_URL;
673
+ const room = status?.signaling?.room || DEFAULT_ROOM;
447
674
  kv("Relay", signalingUrl);
448
675
  kv("Room", room);
449
676
  }
@@ -476,6 +703,22 @@ function normalizePathForMatch(value) {
476
703
  return String(value || "").replace(/\\/g, "/");
477
704
  }
478
705
 
706
+ function isLocalConsoleCommand(command) {
707
+ const text = normalizePathForMatch(command).toLowerCase();
708
+ return (
709
+ text.includes("@silicaclaw/local-console") ||
710
+ text.includes("npm run --workspace @silicaclaw/local-console start") ||
711
+ text.includes("/apps/local-console/") ||
712
+ text.includes("dist/apps/local-console/src/server.js") ||
713
+ text.includes("src/server.ts")
714
+ );
715
+ }
716
+
717
+ function isSignalingCommand(command) {
718
+ const text = normalizePathForMatch(command).toLowerCase();
719
+ return text.includes("webrtc-signaling-server.mjs") || text.includes("npm run webrtc-signaling");
720
+ }
721
+
479
722
  function sleep(ms) {
480
723
  return new Promise((resolve) => setTimeout(resolve, ms));
481
724
  }
@@ -502,6 +745,20 @@ async function waitForCurrentAppListener(port, kind, timeoutMs = 5000) {
502
745
  return lastListener;
503
746
  }
504
747
 
748
+ async function waitForLocalConsoleHealth(timeoutMs = 8000) {
749
+ const startedAt = Date.now();
750
+ while (Date.now() - startedAt < timeoutMs) {
751
+ try {
752
+ const response = await fetch(`${LOCAL_CONSOLE_BASE_URL}/api/health`);
753
+ if (response.ok) return true;
754
+ } catch {
755
+ // ignore transient startup failures
756
+ }
757
+ await sleep(250);
758
+ }
759
+ return false;
760
+ }
761
+
505
762
  async function waitForPortToClear(port, timeoutMs = 5000) {
506
763
  const startedAt = Date.now();
507
764
  while (Date.now() - startedAt < timeoutMs) {
@@ -520,40 +777,24 @@ function tailText(file, lines = 20) {
520
777
 
521
778
  function isOwnedListener(listener, kind) {
522
779
  if (!listener?.command) return false;
523
- const command = normalizePathForMatch(listener.command).toLowerCase();
524
- const appDir = normalizePathForMatch(APP_DIR).toLowerCase();
525
- const rootDir = normalizePathForMatch(ROOT_DIR).toLowerCase();
526
- const inWorkspace = command.includes(appDir) || command.includes(rootDir);
527
- if (!inWorkspace) return false;
780
+ const command = listener.command;
528
781
  if (kind === "local-console") {
529
- return (
530
- command.includes("@silicaclaw/local-console") ||
531
- command.includes("/apps/local-console/") ||
532
- command.includes("src/server.ts") ||
533
- command.includes("dist/server.js")
534
- );
782
+ return isLocalConsoleCommand(command);
535
783
  }
536
784
  if (kind === "signaling") {
537
- return command.includes("webrtc-signaling-server.mjs") || command.includes("npm run webrtc-signaling");
785
+ return isSignalingCommand(command);
538
786
  }
539
787
  return false;
540
788
  }
541
789
 
542
790
  function isCurrentAppListener(listener, kind) {
543
791
  if (!listener?.command) return false;
544
- const command = normalizePathForMatch(listener.command).toLowerCase();
545
- const appDir = normalizePathForMatch(APP_DIR).toLowerCase();
546
- if (!command.includes(appDir)) return false;
792
+ const command = listener.command;
547
793
  if (kind === "local-console") {
548
- return (
549
- command.includes("@silicaclaw/local-console") ||
550
- command.includes("/apps/local-console/") ||
551
- command.includes("src/server.ts") ||
552
- command.includes("dist/server.js")
553
- );
794
+ return isLocalConsoleCommand(command);
554
795
  }
555
796
  if (kind === "signaling") {
556
- return command.includes("webrtc-signaling-server.mjs") || command.includes("npm run webrtc-signaling");
797
+ return isSignalingCommand(command);
557
798
  }
558
799
  return false;
559
800
  }
@@ -592,7 +833,7 @@ async function drainOwnedListener(port, kind, timeoutMs = 5000) {
592
833
  }
593
834
 
594
835
  function printStopSummary() {
595
- const localListener = listeningProcessOnPort(4310);
836
+ const localListener = listeningProcessOnPort(LOCAL_CONSOLE_PORT);
596
837
  const signalingListener = listeningProcessOnPort(4510);
597
838
  headline();
598
839
  console.log("");
@@ -602,9 +843,9 @@ function printStopSummary() {
602
843
  } else {
603
844
  kv("Console", `${paint("still busy", COLOR.yellow)} (pid=${localListener.pid})`);
604
845
  if (isOwnedListener(localListener, "local-console")) {
605
- kv("Hint", "an older SilicaClaw local-console process is still holding port 4310");
846
+ kv("Hint", `an older SilicaClaw local-console process is still holding port ${LOCAL_CONSOLE_PORT}`);
606
847
  }
607
- kv("Inspect", "lsof -nP -iTCP:4310 -sTCP:LISTEN");
848
+ kv("Inspect", `lsof -nP -iTCP:${LOCAL_CONSOLE_PORT} -sTCP:LISTEN`);
608
849
  kv("Stop pid", `kill ${localListener.pid}`);
609
850
  }
610
851
  if (!signalingListener) {
@@ -636,7 +877,7 @@ async function stopAll() {
636
877
  if (isLaunchdPlatform()) {
637
878
  stopLaunchAgent(LOCAL_CONSOLE_LABEL);
638
879
  stopLaunchAgent(SIGNALING_LABEL);
639
- await drainOwnedListener(4310, "local-console", 8000);
880
+ await drainOwnedListener(LOCAL_CONSOLE_PORT, "local-console", 8000);
640
881
  await drainOwnedListener(4510, "signaling", 5000);
641
882
  removeFileIfExists(CONSOLE_PID_FILE);
642
883
  removeFileIfExists(SIGNALING_PID_FILE);
@@ -650,7 +891,7 @@ async function stopAll() {
650
891
  const sigPid = readPid(SIGNALING_PID_FILE);
651
892
  await stopPid(localPid, "local-console");
652
893
  await stopPid(sigPid, "signaling");
653
- await drainOwnedListener(4310, "local-console", 5000);
894
+ await drainOwnedListener(LOCAL_CONSOLE_PORT, "local-console", 5000);
654
895
  await drainOwnedListener(4510, "signaling", 5000);
655
896
  removeFileIfExists(CONSOLE_PID_FILE);
656
897
  removeFileIfExists(SIGNALING_PID_FILE);
@@ -662,11 +903,12 @@ async function stopAll() {
662
903
 
663
904
  async function startAll() {
664
905
  ensureStateDir();
906
+ ensureUserCommandInstalled();
665
907
 
666
- const mode = parseMode(parseFlag("mode", process.env.NETWORK_MODE || "global-preview"));
908
+ const mode = parseMode(parseFlag("mode", process.env.NETWORK_MODE || DEFAULT_NETWORK_MODE));
667
909
  const adapter = adapterForMode(mode);
668
- const signalingUrl = parseFlag("signaling-url", process.env.WEBRTC_SIGNALING_URL || "https://relay.silicaclaw.com");
669
- const room = parseFlag("room", process.env.WEBRTC_ROOM || "silicaclaw-global-preview");
910
+ const signalingUrl = parseFlag("signaling-url", process.env.WEBRTC_SIGNALING_URL || DEFAULT_SIGNALING_URL);
911
+ const room = parseFlag("room", process.env.WEBRTC_ROOM || DEFAULT_ROOM);
670
912
  const shouldDisableSignaling = hasFlag("no-signaling");
671
913
 
672
914
  const { host, port } = parseUrlHostPort(signalingUrl);
@@ -676,32 +918,34 @@ async function startAll() {
676
918
  (host === "localhost" || host === "127.0.0.1");
677
919
 
678
920
  if (isLaunchdPlatform()) {
679
- const npmPath = resolveCommandPath("npm");
680
- const signalingEntry = resolve(APP_DIR, "scripts", "webrtc-signaling-server.mjs");
681
- await drainOwnedListener(4310, "local-console", 8000);
921
+ const managedAppDir = syncManagedRuntime();
922
+ const signalingEntry = resolve(managedAppDir, "scripts", "webrtc-signaling-server.mjs");
923
+ await drainOwnedListener(LOCAL_CONSOLE_PORT, "local-console", 8000);
682
924
  await drainOwnedListener(4510, "signaling", 5000);
683
925
  const baseEnv = {
684
926
  NETWORK_ADAPTER: adapter,
685
927
  NETWORK_MODE: mode,
686
928
  WEBRTC_SIGNALING_URL: signalingUrl,
687
929
  WEBRTC_ROOM: room,
930
+ SILICACLAW_APP_DIR: managedAppDir,
931
+ SILICACLAW_WORKSPACE_DIR: WORKSPACE_DIR,
688
932
  PATH: process.env.PATH || "/usr/bin:/bin:/usr/sbin:/sbin",
689
933
  HOME: process.env.HOME || homedir(),
690
934
  };
691
935
 
692
- installLaunchAgent({
936
+ ensureLaunchAgent({
693
937
  label: LOCAL_CONSOLE_LABEL,
694
- programArguments: [npmPath, "run", "--workspace", "@silicaclaw/local-console", "start"],
695
- workingDirectory: APP_DIR,
938
+ programArguments: localConsoleProgramArguments(managedAppDir),
939
+ workingDirectory: managedAppDir,
696
940
  logFile: CONSOLE_LOG_FILE,
697
941
  environment: baseEnv,
698
942
  });
699
943
 
700
944
  if (shouldAutoStartSignaling) {
701
- installLaunchAgent({
945
+ ensureLaunchAgent({
702
946
  label: SIGNALING_LABEL,
703
947
  programArguments: [process.execPath, signalingEntry],
704
- workingDirectory: APP_DIR,
948
+ workingDirectory: managedAppDir,
705
949
  logFile: SIGNALING_LOG_FILE,
706
950
  environment: {
707
951
  PATH: baseEnv.PATH,
@@ -715,6 +959,8 @@ async function startAll() {
715
959
 
716
960
  writeState({
717
961
  app_dir: APP_DIR,
962
+ managed_app_dir: managedAppDir,
963
+ workspace_dir: WORKSPACE_DIR,
718
964
  mode,
719
965
  adapter,
720
966
  signaling_url: signalingUrl,
@@ -726,7 +972,7 @@ async function startAll() {
726
972
 
727
973
  const currentLocalPid = readPid(CONSOLE_PID_FILE);
728
974
  const currentSigPid = readPid(SIGNALING_PID_FILE);
729
- const currentListener = listeningProcessOnPort(4310);
975
+ const currentListener = listeningProcessOnPort(LOCAL_CONSOLE_PORT);
730
976
  if (currentListener && isOwnedListener(currentListener, "local-console") && !isRunning(currentLocalPid)) {
731
977
  writeFileSync(CONSOLE_PID_FILE, String(currentListener.pid));
732
978
  }
@@ -734,16 +980,18 @@ async function startAll() {
734
980
  let localPid = readPid(CONSOLE_PID_FILE);
735
981
  if (!isRunning(localPid)) {
736
982
  removeFileIfExists(CONSOLE_PID_FILE);
737
- await drainOwnedListener(4310, "local-console", 8000);
738
- const remainingLocalListener = listeningProcessOnPort(4310);
983
+ await drainOwnedListener(LOCAL_CONSOLE_PORT, "local-console", 8000);
984
+ const remainingLocalListener = listeningProcessOnPort(LOCAL_CONSOLE_PORT);
739
985
  if (remainingLocalListener) {
740
- throw new Error(`port 4310 is occupied by pid=${remainingLocalListener.pid}`);
986
+ throw new Error(`port ${LOCAL_CONSOLE_PORT} is occupied by pid=${remainingLocalListener.pid}`);
741
987
  }
742
988
  const env = {
743
989
  NETWORK_ADAPTER: adapter,
744
990
  NETWORK_MODE: mode,
745
991
  WEBRTC_SIGNALING_URL: signalingUrl,
746
992
  WEBRTC_ROOM: room,
993
+ SILICACLAW_APP_DIR: APP_DIR,
994
+ SILICACLAW_WORKSPACE_DIR: WORKSPACE_DIR,
747
995
  };
748
996
  localPid = spawnBackground(
749
997
  process.execPath,
@@ -771,6 +1019,7 @@ async function startAll() {
771
1019
 
772
1020
  writeState({
773
1021
  app_dir: APP_DIR,
1022
+ workspace_dir: WORKSPACE_DIR,
774
1023
  mode,
775
1024
  adapter,
776
1025
  signaling_url: signalingUrl,
@@ -780,6 +1029,82 @@ async function startAll() {
780
1029
  return { localPid, signalingPid: shouldAutoStartSignaling ? signalingPid : null };
781
1030
  }
782
1031
 
1032
+ async function restartAll() {
1033
+ ensureUserCommandInstalled();
1034
+ if (!isLaunchdPlatform()) {
1035
+ await stopAll();
1036
+ await startAll();
1037
+ return;
1038
+ }
1039
+
1040
+ ensureStateDir();
1041
+
1042
+ const mode = parseMode(parseFlag("mode", process.env.NETWORK_MODE || DEFAULT_NETWORK_MODE));
1043
+ const adapter = adapterForMode(mode);
1044
+ const signalingUrl = parseFlag("signaling-url", process.env.WEBRTC_SIGNALING_URL || DEFAULT_SIGNALING_URL);
1045
+ const room = parseFlag("room", process.env.WEBRTC_ROOM || DEFAULT_ROOM);
1046
+ const shouldDisableSignaling = hasFlag("no-signaling");
1047
+ const { host, port } = parseUrlHostPort(signalingUrl);
1048
+ const shouldAutoStartSignaling =
1049
+ mode === "global-preview" &&
1050
+ !shouldDisableSignaling &&
1051
+ (host === "localhost" || host === "127.0.0.1");
1052
+
1053
+ const managedAppDir = syncManagedRuntime();
1054
+ const signalingEntry = resolve(managedAppDir, "scripts", "webrtc-signaling-server.mjs");
1055
+ const baseEnv = {
1056
+ NETWORK_ADAPTER: adapter,
1057
+ NETWORK_MODE: mode,
1058
+ WEBRTC_SIGNALING_URL: signalingUrl,
1059
+ WEBRTC_ROOM: room,
1060
+ SILICACLAW_APP_DIR: managedAppDir,
1061
+ SILICACLAW_WORKSPACE_DIR: WORKSPACE_DIR,
1062
+ PATH: process.env.PATH || "/usr/bin:/bin:/usr/sbin:/sbin",
1063
+ HOME: process.env.HOME || homedir(),
1064
+ };
1065
+
1066
+ const localConsoleService = ensureLaunchAgent({
1067
+ label: LOCAL_CONSOLE_LABEL,
1068
+ programArguments: localConsoleProgramArguments(managedAppDir),
1069
+ workingDirectory: managedAppDir,
1070
+ logFile: CONSOLE_LOG_FILE,
1071
+ environment: baseEnv,
1072
+ });
1073
+ if (!localConsoleService.changed) {
1074
+ restartLaunchAgent(LOCAL_CONSOLE_LABEL, localConsoleService.plistPath);
1075
+ }
1076
+
1077
+ if (shouldAutoStartSignaling) {
1078
+ const signalingService = ensureLaunchAgent({
1079
+ label: SIGNALING_LABEL,
1080
+ programArguments: [process.execPath, signalingEntry],
1081
+ workingDirectory: managedAppDir,
1082
+ logFile: SIGNALING_LOG_FILE,
1083
+ environment: {
1084
+ PATH: baseEnv.PATH,
1085
+ HOME: baseEnv.HOME,
1086
+ PORT: String(port),
1087
+ },
1088
+ });
1089
+ if (!signalingService.changed) {
1090
+ restartLaunchAgent(SIGNALING_LABEL, signalingService.plistPath);
1091
+ }
1092
+ } else {
1093
+ uninstallLaunchAgent(SIGNALING_LABEL);
1094
+ }
1095
+
1096
+ writeState({
1097
+ app_dir: APP_DIR,
1098
+ managed_app_dir: managedAppDir,
1099
+ workspace_dir: WORKSPACE_DIR,
1100
+ mode,
1101
+ adapter,
1102
+ signaling_url: signalingUrl,
1103
+ room,
1104
+ updated_at: Date.now(),
1105
+ });
1106
+ }
1107
+
783
1108
  async function main() {
784
1109
  if (cmd === "help" || cmd === "-h" || cmd === "--help") {
785
1110
  printHelp();
@@ -795,14 +1120,15 @@ async function main() {
795
1120
  }
796
1121
  if (cmd === "start") {
797
1122
  await startAll();
798
- const listener = await waitForCurrentAppListener(4310, "local-console", 15000);
799
- if (!listener || !isCurrentAppListener(listener, "local-console")) {
1123
+ const listener = await waitForCurrentAppListener(LOCAL_CONSOLE_PORT, "local-console", 15000);
1124
+ const healthy = listener ? await waitForLocalConsoleHealth(8000) : false;
1125
+ if (!listener || !isCurrentAppListener(listener, "local-console") || !healthy) {
800
1126
  headline();
801
1127
  console.log("");
802
1128
  kv("Status", paint("failed to start", COLOR.red));
803
1129
  if (listener) {
804
- kv("Conflict", `port 4310 is occupied by pid=${listener.pid}`);
805
- kv("Inspect", "lsof -nP -iTCP:4310 -sTCP:LISTEN");
1130
+ kv("Conflict", `port ${LOCAL_CONSOLE_PORT} is occupied by pid=${listener.pid}`);
1131
+ kv("Inspect", `lsof -nP -iTCP:${LOCAL_CONSOLE_PORT} -sTCP:LISTEN`);
806
1132
  }
807
1133
  const recent = tailText(CONSOLE_LOG_FILE, 18);
808
1134
  if (recent) {
@@ -822,16 +1148,16 @@ async function main() {
822
1148
  return;
823
1149
  }
824
1150
  if (cmd === "restart") {
825
- await stopAll();
826
- await startAll();
827
- const listener = await waitForCurrentAppListener(4310, "local-console", 15000);
828
- if (!listener || !isCurrentAppListener(listener, "local-console")) {
1151
+ await restartAll();
1152
+ const listener = await waitForCurrentAppListener(LOCAL_CONSOLE_PORT, "local-console", 15000);
1153
+ const healthy = listener ? await waitForLocalConsoleHealth(8000) : false;
1154
+ if (!listener || !isCurrentAppListener(listener, "local-console") || !healthy) {
829
1155
  headline();
830
1156
  console.log("");
831
1157
  kv("Status", paint("failed to restart", COLOR.red));
832
1158
  if (listener) {
833
- kv("Conflict", `port 4310 is occupied by pid=${listener.pid}`);
834
- kv("Inspect", "lsof -nP -iTCP:4310 -sTCP:LISTEN");
1159
+ kv("Conflict", `port ${LOCAL_CONSOLE_PORT} is occupied by pid=${listener.pid}`);
1160
+ kv("Inspect", `lsof -nP -iTCP:${LOCAL_CONSOLE_PORT} -sTCP:LISTEN`);
835
1161
  }
836
1162
  const recent = tailText(CONSOLE_LOG_FILE, 18);
837
1163
  if (recent) {