@silicaclaw/cli 2026.3.19-9 → 2026.3.20-2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +134 -0
- package/DEMO_GUIDE.md +1 -1
- package/INSTALL.md +47 -13
- package/README.md +54 -19
- package/VERSION +1 -1
- package/apps/local-console/dist/apps/local-console/src/server.d.ts +51 -12
- package/apps/local-console/dist/apps/local-console/src/server.js +619 -183
- package/apps/local-console/dist/config/silicaclaw-defaults.json +19 -0
- package/apps/local-console/dist/packages/core/src/socialConfig.js +9 -5
- package/apps/local-console/dist/packages/network/src/realPreview.js +6 -2
- package/apps/local-console/dist/packages/network/src/relayPreview.js +8 -2
- package/apps/local-console/dist/packages/network/src/transport/udpLanBroadcastTransport.js +2 -1
- package/apps/local-console/dist/packages/network/src/webrtcPreview.js +5 -1
- package/apps/local-console/dist/packages/storage/config/silicaclaw-defaults.json +19 -0
- package/apps/local-console/dist/packages/storage/src/socialRuntimeRepo.js +8 -4
- package/apps/local-console/public/app/app.js +21 -1
- package/apps/local-console/public/app/events.js +40 -2
- package/apps/local-console/public/app/network.js +32 -3
- package/apps/local-console/public/app/overview.js +18 -26
- package/apps/local-console/public/app/shell.js +18 -34
- package/apps/local-console/public/app/social.js +207 -28
- package/apps/local-console/public/app/styles.css +182 -14
- package/apps/local-console/public/app/template.js +76 -31
- package/apps/local-console/public/app/translations.js +147 -51
- package/apps/local-console/src/server.ts +652 -189
- package/apps/public-explorer/dist/apps/public-explorer/src/server.d.ts +1 -0
- package/apps/public-explorer/dist/apps/public-explorer/src/server.js +41 -0
- package/apps/public-explorer/dist/config/silicaclaw-defaults.json +19 -0
- package/apps/public-explorer/public/app/app.js +22 -2
- package/apps/public-explorer/public/app/template.js +4 -4
- package/apps/public-explorer/public/app/translations.js +15 -15
- package/apps/public-explorer/src/server.ts +11 -1
- package/config/silicaclaw-defaults.json +19 -0
- package/dist/apps/local-console/src/server.d.ts +1 -0
- package/dist/apps/local-console/src/server.js +555 -0
- package/docs/NEW_USER_INSTALL.md +14 -10
- package/docs/NEW_USER_OPERATIONS.md +4 -4
- package/docs/OPENCLAW_BRIDGE.md +15 -0
- package/docs/OPENCLAW_BRIDGE_ZH.md +15 -0
- package/docs/RELEASE_CHECKLIST.md +95 -0
- package/node_modules/@silicaclaw/core/dist/config/silicaclaw-defaults.json +19 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/crypto.d.ts +6 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/crypto.js +50 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/directory.d.ts +17 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/directory.js +145 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/identity.d.ts +2 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/identity.js +18 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/index.d.ts +12 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/index.js +28 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/indexing.d.ts +6 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/indexing.js +43 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/presence.d.ts +4 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/presence.js +23 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/profile.d.ts +4 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/profile.js +39 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/publicProfileSummary.d.ts +70 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/publicProfileSummary.js +103 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/socialConfig.d.ts +100 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/socialConfig.js +300 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/socialMessage.d.ts +19 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/socialMessage.js +69 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/socialResolver.d.ts +46 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/socialResolver.js +237 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/socialTemplate.d.ts +2 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/socialTemplate.js +90 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/types.d.ts +59 -0
- package/node_modules/@silicaclaw/core/dist/packages/core/src/types.js +2 -0
- package/node_modules/@silicaclaw/core/src/socialConfig.ts +7 -5
- package/node_modules/@silicaclaw/network/dist/config/silicaclaw-defaults.json +19 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/messageEnvelope.d.ts +28 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/messageEnvelope.js +36 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/peerDiscovery.d.ts +43 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/peerDiscovery.js +2 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/topicCodec.d.ts +4 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/topicCodec.js +2 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/transport.d.ts +36 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/abstractions/transport.js +2 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/codec/jsonMessageEnvelopeCodec.d.ts +5 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/codec/jsonMessageEnvelopeCodec.js +24 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/codec/jsonTopicCodec.d.ts +5 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/codec/jsonTopicCodec.js +12 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/discovery/heartbeatPeerDiscovery.d.ts +28 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/discovery/heartbeatPeerDiscovery.js +144 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/index.d.ts +14 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/index.js +30 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/localEventBus.d.ts +9 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/localEventBus.js +47 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/mock.d.ts +8 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/mock.js +24 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/realPreview.d.ts +105 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/realPreview.js +331 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/relayPreview.d.ts +166 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/relayPreview.js +448 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/transport/udpLanBroadcastTransport.d.ts +23 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/transport/udpLanBroadcastTransport.js +154 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/types.d.ts +6 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/types.js +2 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/webrtcPreview.d.ts +163 -0
- package/node_modules/@silicaclaw/network/dist/packages/network/src/webrtcPreview.js +848 -0
- package/node_modules/@silicaclaw/network/src/realPreview.ts +3 -2
- package/node_modules/@silicaclaw/network/src/relayPreview.ts +5 -2
- package/node_modules/@silicaclaw/network/src/transport/udpLanBroadcastTransport.ts +2 -1
- package/node_modules/@silicaclaw/network/src/webrtcPreview.ts +2 -1
- package/node_modules/@silicaclaw/storage/config/silicaclaw-defaults.json +19 -0
- package/node_modules/@silicaclaw/storage/dist/config/silicaclaw-defaults.json +19 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/crypto.d.ts +6 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/crypto.js +50 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/directory.d.ts +17 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/directory.js +145 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/identity.d.ts +2 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/identity.js +18 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/index.d.ts +12 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/index.js +28 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/indexing.d.ts +6 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/indexing.js +43 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/presence.d.ts +4 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/presence.js +23 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/profile.d.ts +4 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/profile.js +39 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/publicProfileSummary.d.ts +70 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/publicProfileSummary.js +103 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/socialConfig.d.ts +100 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/socialConfig.js +300 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/socialMessage.d.ts +19 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/socialMessage.js +69 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/socialResolver.d.ts +46 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/socialResolver.js +237 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/socialTemplate.d.ts +2 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/socialTemplate.js +90 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/types.d.ts +59 -0
- package/node_modules/@silicaclaw/storage/dist/packages/core/src/types.js +2 -0
- package/node_modules/@silicaclaw/storage/dist/packages/storage/config/silicaclaw-defaults.json +19 -0
- package/node_modules/@silicaclaw/storage/dist/packages/storage/src/index.d.ts +3 -0
- package/node_modules/@silicaclaw/storage/dist/packages/storage/src/index.js +19 -0
- package/node_modules/@silicaclaw/storage/dist/packages/storage/src/jsonRepo.d.ts +7 -0
- package/node_modules/@silicaclaw/storage/dist/packages/storage/src/jsonRepo.js +29 -0
- package/node_modules/@silicaclaw/storage/dist/packages/storage/src/repos.d.ts +61 -0
- package/node_modules/@silicaclaw/storage/dist/packages/storage/src/repos.js +67 -0
- package/node_modules/@silicaclaw/storage/dist/packages/storage/src/socialRuntimeRepo.d.ts +5 -0
- package/node_modules/@silicaclaw/storage/dist/packages/storage/src/socialRuntimeRepo.js +57 -0
- package/node_modules/@silicaclaw/storage/dist/socialRuntimeRepo.js +8 -4
- package/node_modules/@silicaclaw/storage/src/socialRuntimeRepo.ts +5 -4
- package/node_modules/@silicaclaw/storage/tsconfig.json +1 -6
- package/openclaw-skills/silicaclaw-bridge-setup/SKILL.md +147 -0
- package/openclaw-skills/silicaclaw-bridge-setup/VERSION +1 -0
- package/openclaw-skills/silicaclaw-bridge-setup/agents/openai.yaml +6 -0
- package/openclaw-skills/silicaclaw-bridge-setup/manifest.json +27 -0
- package/openclaw-skills/silicaclaw-bridge-setup/references/owner-dialogue-cheatsheet-zh.md +58 -0
- package/openclaw-skills/silicaclaw-bridge-setup/references/runtime-setup.md +43 -0
- package/openclaw-skills/silicaclaw-bridge-setup/references/troubleshooting.md +24 -0
- package/openclaw-skills/silicaclaw-broadcast/SKILL.md +132 -0
- package/openclaw-skills/silicaclaw-broadcast/VERSION +1 -1
- package/openclaw-skills/silicaclaw-broadcast/agents/openai.yaml +2 -2
- package/openclaw-skills/silicaclaw-broadcast/manifest.json +3 -2
- package/openclaw-skills/silicaclaw-broadcast/references/owner-dialogue-cheatsheet-zh.md +81 -0
- package/openclaw-skills/silicaclaw-owner-push/SKILL.md +217 -0
- package/openclaw-skills/silicaclaw-owner-push/VERSION +1 -0
- package/openclaw-skills/silicaclaw-owner-push/agents/openai.yaml +6 -0
- package/openclaw-skills/silicaclaw-owner-push/manifest.json +30 -0
- package/openclaw-skills/silicaclaw-owner-push/references/owner-dialogue-cheatsheet-zh.md +87 -0
- package/openclaw-skills/silicaclaw-owner-push/references/push-routing-policy.md +43 -0
- package/openclaw-skills/silicaclaw-owner-push/references/runtime-setup.md +41 -0
- package/openclaw-skills/silicaclaw-owner-push/scripts/owner-push-forwarder.mjs +214 -0
- package/openclaw-skills/silicaclaw-owner-push/scripts/send-to-owner-via-openclaw.mjs +69 -0
- package/package.json +5 -1
- package/packages/core/dist/config/silicaclaw-defaults.json +19 -0
- package/packages/core/dist/packages/core/src/crypto.d.ts +6 -0
- package/packages/core/dist/packages/core/src/crypto.js +50 -0
- package/packages/core/dist/packages/core/src/directory.d.ts +17 -0
- package/packages/core/dist/packages/core/src/directory.js +145 -0
- package/packages/core/dist/packages/core/src/identity.d.ts +2 -0
- package/packages/core/dist/packages/core/src/identity.js +18 -0
- package/packages/core/dist/packages/core/src/index.d.ts +12 -0
- package/packages/core/dist/packages/core/src/index.js +28 -0
- package/packages/core/dist/packages/core/src/indexing.d.ts +6 -0
- package/packages/core/dist/packages/core/src/indexing.js +43 -0
- package/packages/core/dist/packages/core/src/presence.d.ts +4 -0
- package/packages/core/dist/packages/core/src/presence.js +23 -0
- package/packages/core/dist/packages/core/src/profile.d.ts +4 -0
- package/packages/core/dist/packages/core/src/profile.js +39 -0
- package/packages/core/dist/packages/core/src/publicProfileSummary.d.ts +70 -0
- package/packages/core/dist/packages/core/src/publicProfileSummary.js +103 -0
- package/packages/core/dist/packages/core/src/socialConfig.d.ts +100 -0
- package/packages/core/dist/packages/core/src/socialConfig.js +300 -0
- package/packages/core/dist/packages/core/src/socialMessage.d.ts +19 -0
- package/packages/core/dist/packages/core/src/socialMessage.js +69 -0
- package/packages/core/dist/packages/core/src/socialResolver.d.ts +46 -0
- package/packages/core/dist/packages/core/src/socialResolver.js +237 -0
- package/packages/core/dist/packages/core/src/socialTemplate.d.ts +2 -0
- package/packages/core/dist/packages/core/src/socialTemplate.js +90 -0
- package/packages/core/dist/packages/core/src/types.d.ts +59 -0
- package/packages/core/dist/packages/core/src/types.js +2 -0
- package/packages/core/src/socialConfig.ts +7 -5
- package/packages/network/dist/config/silicaclaw-defaults.json +19 -0
- package/packages/network/dist/packages/network/src/abstractions/messageEnvelope.d.ts +28 -0
- package/packages/network/dist/packages/network/src/abstractions/messageEnvelope.js +36 -0
- package/packages/network/dist/packages/network/src/abstractions/peerDiscovery.d.ts +43 -0
- package/packages/network/dist/packages/network/src/abstractions/peerDiscovery.js +2 -0
- package/packages/network/dist/packages/network/src/abstractions/topicCodec.d.ts +4 -0
- package/packages/network/dist/packages/network/src/abstractions/topicCodec.js +2 -0
- package/packages/network/dist/packages/network/src/abstractions/transport.d.ts +36 -0
- package/packages/network/dist/packages/network/src/abstractions/transport.js +2 -0
- package/packages/network/dist/packages/network/src/codec/jsonMessageEnvelopeCodec.d.ts +5 -0
- package/packages/network/dist/packages/network/src/codec/jsonMessageEnvelopeCodec.js +24 -0
- package/packages/network/dist/packages/network/src/codec/jsonTopicCodec.d.ts +5 -0
- package/packages/network/dist/packages/network/src/codec/jsonTopicCodec.js +12 -0
- package/packages/network/dist/packages/network/src/discovery/heartbeatPeerDiscovery.d.ts +28 -0
- package/packages/network/dist/packages/network/src/discovery/heartbeatPeerDiscovery.js +144 -0
- package/packages/network/dist/packages/network/src/index.d.ts +14 -0
- package/packages/network/dist/packages/network/src/index.js +30 -0
- package/packages/network/dist/packages/network/src/localEventBus.d.ts +9 -0
- package/packages/network/dist/packages/network/src/localEventBus.js +47 -0
- package/packages/network/dist/packages/network/src/mock.d.ts +8 -0
- package/packages/network/dist/packages/network/src/mock.js +24 -0
- package/packages/network/dist/packages/network/src/realPreview.d.ts +105 -0
- package/packages/network/dist/packages/network/src/realPreview.js +331 -0
- package/packages/network/dist/packages/network/src/relayPreview.d.ts +166 -0
- package/packages/network/dist/packages/network/src/relayPreview.js +448 -0
- package/packages/network/dist/packages/network/src/transport/udpLanBroadcastTransport.d.ts +23 -0
- package/packages/network/dist/packages/network/src/transport/udpLanBroadcastTransport.js +154 -0
- package/packages/network/dist/packages/network/src/types.d.ts +6 -0
- package/packages/network/dist/packages/network/src/types.js +2 -0
- package/packages/network/dist/packages/network/src/webrtcPreview.d.ts +163 -0
- package/packages/network/dist/packages/network/src/webrtcPreview.js +848 -0
- package/packages/network/src/realPreview.ts +3 -2
- package/packages/network/src/relayPreview.ts +5 -2
- package/packages/network/src/transport/udpLanBroadcastTransport.ts +2 -1
- package/packages/network/src/webrtcPreview.ts +2 -1
- package/packages/storage/config/silicaclaw-defaults.json +19 -0
- package/packages/storage/dist/config/silicaclaw-defaults.json +19 -0
- package/packages/storage/dist/packages/core/src/crypto.d.ts +6 -0
- package/packages/storage/dist/packages/core/src/crypto.js +50 -0
- package/packages/storage/dist/packages/core/src/directory.d.ts +17 -0
- package/packages/storage/dist/packages/core/src/directory.js +145 -0
- package/packages/storage/dist/packages/core/src/identity.d.ts +2 -0
- package/packages/storage/dist/packages/core/src/identity.js +18 -0
- package/packages/storage/dist/packages/core/src/index.d.ts +12 -0
- package/packages/storage/dist/packages/core/src/index.js +28 -0
- package/packages/storage/dist/packages/core/src/indexing.d.ts +6 -0
- package/packages/storage/dist/packages/core/src/indexing.js +43 -0
- package/packages/storage/dist/packages/core/src/presence.d.ts +4 -0
- package/packages/storage/dist/packages/core/src/presence.js +23 -0
- package/packages/storage/dist/packages/core/src/profile.d.ts +4 -0
- package/packages/storage/dist/packages/core/src/profile.js +39 -0
- package/packages/storage/dist/packages/core/src/publicProfileSummary.d.ts +70 -0
- package/packages/storage/dist/packages/core/src/publicProfileSummary.js +103 -0
- package/packages/storage/dist/packages/core/src/socialConfig.d.ts +100 -0
- package/packages/storage/dist/packages/core/src/socialConfig.js +300 -0
- package/packages/storage/dist/packages/core/src/socialMessage.d.ts +19 -0
- package/packages/storage/dist/packages/core/src/socialMessage.js +69 -0
- package/packages/storage/dist/packages/core/src/socialResolver.d.ts +46 -0
- package/packages/storage/dist/packages/core/src/socialResolver.js +237 -0
- package/packages/storage/dist/packages/core/src/socialTemplate.d.ts +2 -0
- package/packages/storage/dist/packages/core/src/socialTemplate.js +90 -0
- package/packages/storage/dist/packages/core/src/types.d.ts +59 -0
- package/packages/storage/dist/packages/core/src/types.js +2 -0
- package/packages/storage/dist/packages/storage/config/silicaclaw-defaults.json +19 -0
- package/packages/storage/dist/packages/storage/src/index.d.ts +3 -0
- package/packages/storage/dist/packages/storage/src/index.js +19 -0
- package/packages/storage/dist/packages/storage/src/jsonRepo.d.ts +7 -0
- package/packages/storage/dist/packages/storage/src/jsonRepo.js +29 -0
- package/packages/storage/dist/packages/storage/src/repos.d.ts +61 -0
- package/packages/storage/dist/packages/storage/src/repos.js +67 -0
- package/packages/storage/dist/packages/storage/src/socialRuntimeRepo.d.ts +5 -0
- package/packages/storage/dist/packages/storage/src/socialRuntimeRepo.js +57 -0
- package/packages/storage/dist/socialRuntimeRepo.js +8 -4
- package/packages/storage/src/socialRuntimeRepo.ts +5 -4
- package/packages/storage/tsconfig.json +1 -6
- package/scripts/functional-check.mjs +35 -6
- package/scripts/install-openclaw-skill.mjs +9 -2
- package/scripts/openclaw-bridge-adapter.mjs +3 -1
- package/scripts/openclaw-bridge-client.mjs +3 -1
- package/scripts/openclaw-runtime-demo.mjs +3 -1
- package/scripts/quickstart.sh +14 -10
- package/scripts/release-pack.mjs +59 -1
- package/scripts/silicaclaw-cli.mjs +162 -50
- package/scripts/silicaclaw-gateway.mjs +302 -84
- package/scripts/validate-openclaw-skill.mjs +79 -21
|
@@ -0,0 +1,555 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const express_1 = __importDefault(require("express"));
|
|
7
|
+
const cors_1 = __importDefault(require("cors"));
|
|
8
|
+
const path_1 = require("path");
|
|
9
|
+
const fs_1 = require("fs");
|
|
10
|
+
const core_1 = require("@silicaclaw/core");
|
|
11
|
+
const network_1 = require("@silicaclaw/network");
|
|
12
|
+
const storage_1 = require("@silicaclaw/storage");
|
|
13
|
+
const BROADCAST_INTERVAL_MS = 10_000;
|
|
14
|
+
const PRESENCE_TTL_MS = Number(process.env.PRESENCE_TTL_MS || 30_000);
|
|
15
|
+
class LocalNodeService {
|
|
16
|
+
identityRepo = new storage_1.IdentityRepo(process.cwd());
|
|
17
|
+
profileRepo = new storage_1.ProfileRepo(process.cwd());
|
|
18
|
+
cacheRepo = new storage_1.CacheRepo(process.cwd());
|
|
19
|
+
logRepo = new storage_1.LogRepo(process.cwd());
|
|
20
|
+
identity = null;
|
|
21
|
+
profile = null;
|
|
22
|
+
directory = (0, core_1.createEmptyDirectoryState)();
|
|
23
|
+
receivedCount = 0;
|
|
24
|
+
broadcastCount = 0;
|
|
25
|
+
lastMessageAt = 0;
|
|
26
|
+
lastBroadcastAt = 0;
|
|
27
|
+
broadcaster = null;
|
|
28
|
+
broadcastEnabled = true;
|
|
29
|
+
receivedByTopic = {};
|
|
30
|
+
publishedByTopic = {};
|
|
31
|
+
initState = {
|
|
32
|
+
identity_auto_created: false,
|
|
33
|
+
profile_auto_created: false,
|
|
34
|
+
initialized_at: 0,
|
|
35
|
+
};
|
|
36
|
+
network;
|
|
37
|
+
adapterMode;
|
|
38
|
+
networkNamespace;
|
|
39
|
+
networkPort;
|
|
40
|
+
constructor() {
|
|
41
|
+
this.networkNamespace = process.env.NETWORK_NAMESPACE || "silicaclaw.preview";
|
|
42
|
+
this.networkPort = Number(process.env.NETWORK_PORT || 44123);
|
|
43
|
+
const mode = process.env.NETWORK_ADAPTER;
|
|
44
|
+
if (mode === "mock") {
|
|
45
|
+
this.network = new network_1.MockNetworkAdapter();
|
|
46
|
+
this.adapterMode = "mock";
|
|
47
|
+
this.networkPort = null;
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (mode === "real-preview") {
|
|
51
|
+
this.network = new network_1.RealNetworkAdapterPreview({
|
|
52
|
+
namespace: this.networkNamespace,
|
|
53
|
+
transport: new network_1.UdpLanBroadcastTransport({
|
|
54
|
+
port: this.networkPort,
|
|
55
|
+
}),
|
|
56
|
+
});
|
|
57
|
+
this.adapterMode = "real-preview";
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
this.network = new network_1.LocalEventBusAdapter();
|
|
61
|
+
this.adapterMode = "local-event-bus";
|
|
62
|
+
this.networkPort = null;
|
|
63
|
+
}
|
|
64
|
+
async start() {
|
|
65
|
+
await this.hydrateFromDisk();
|
|
66
|
+
await this.network.start();
|
|
67
|
+
this.network.subscribe("profile", (data) => {
|
|
68
|
+
this.onMessage("profile", data);
|
|
69
|
+
});
|
|
70
|
+
this.network.subscribe("presence", (data) => {
|
|
71
|
+
this.onMessage("presence", data);
|
|
72
|
+
});
|
|
73
|
+
this.network.subscribe("index", (data) => {
|
|
74
|
+
this.onMessage("index", data);
|
|
75
|
+
});
|
|
76
|
+
this.startBroadcastLoop();
|
|
77
|
+
await this.log("info", "Local node started");
|
|
78
|
+
}
|
|
79
|
+
async stop() {
|
|
80
|
+
if (this.broadcaster) {
|
|
81
|
+
clearInterval(this.broadcaster);
|
|
82
|
+
this.broadcaster = null;
|
|
83
|
+
}
|
|
84
|
+
await this.network.stop();
|
|
85
|
+
}
|
|
86
|
+
getOverview() {
|
|
87
|
+
this.compactCacheInMemory();
|
|
88
|
+
const profiles = Object.values(this.directory.profiles);
|
|
89
|
+
const onlineCount = profiles.filter((profile) => (0, core_1.isAgentOnline)(this.directory.presence[profile.agent_id], Date.now(), PRESENCE_TTL_MS)).length;
|
|
90
|
+
return {
|
|
91
|
+
agent_id: this.identity?.agent_id ?? "",
|
|
92
|
+
public_enabled: Boolean(this.profile?.public_enabled),
|
|
93
|
+
broadcast_enabled: this.broadcastEnabled,
|
|
94
|
+
last_broadcast_at: this.lastBroadcastAt,
|
|
95
|
+
discovered_count: profiles.length,
|
|
96
|
+
online_count: onlineCount,
|
|
97
|
+
offline_count: Math.max(0, profiles.length - onlineCount),
|
|
98
|
+
init_state: this.initState,
|
|
99
|
+
presence_ttl_ms: PRESENCE_TTL_MS,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
getNetworkSummary() {
|
|
103
|
+
const diagnostics = this.getRealAdapterDiagnostics();
|
|
104
|
+
const peerCount = diagnostics?.peers.total ?? 0;
|
|
105
|
+
return {
|
|
106
|
+
status: "running",
|
|
107
|
+
adapter: this.adapterMode,
|
|
108
|
+
received_count: this.receivedCount,
|
|
109
|
+
broadcast_count: this.broadcastCount,
|
|
110
|
+
last_message_at: this.lastMessageAt,
|
|
111
|
+
last_broadcast_at: this.lastBroadcastAt,
|
|
112
|
+
received_by_topic: this.receivedByTopic,
|
|
113
|
+
published_by_topic: this.publishedByTopic,
|
|
114
|
+
peers_discovered: peerCount,
|
|
115
|
+
namespace: diagnostics?.namespace ?? this.networkNamespace,
|
|
116
|
+
port: this.networkPort,
|
|
117
|
+
components: diagnostics?.components ?? {
|
|
118
|
+
transport: "-",
|
|
119
|
+
discovery: "-",
|
|
120
|
+
envelope_codec: "-",
|
|
121
|
+
topic_codec: "-",
|
|
122
|
+
},
|
|
123
|
+
real_preview_stats: diagnostics?.stats ?? null,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
getNetworkConfig() {
|
|
127
|
+
const diagnostics = this.getRealAdapterDiagnostics();
|
|
128
|
+
return {
|
|
129
|
+
adapter: this.adapterMode,
|
|
130
|
+
namespace: diagnostics?.namespace ?? this.networkNamespace,
|
|
131
|
+
port: this.networkPort,
|
|
132
|
+
components: diagnostics?.components ?? {
|
|
133
|
+
transport: "-",
|
|
134
|
+
discovery: "-",
|
|
135
|
+
envelope_codec: "-",
|
|
136
|
+
topic_codec: "-",
|
|
137
|
+
},
|
|
138
|
+
limits: diagnostics?.limits ?? null,
|
|
139
|
+
demo_mode: this.adapterMode === "real-preview" ? "lan-preview" : "local-process",
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
getNetworkStats() {
|
|
143
|
+
const diagnostics = this.getRealAdapterDiagnostics();
|
|
144
|
+
const peers = diagnostics?.peers.items ?? [];
|
|
145
|
+
const online = peers.filter((peer) => peer.status === "online").length;
|
|
146
|
+
return {
|
|
147
|
+
adapter: this.adapterMode,
|
|
148
|
+
message_counters: {
|
|
149
|
+
received_total: this.receivedCount,
|
|
150
|
+
broadcast_total: this.broadcastCount,
|
|
151
|
+
last_message_at: this.lastMessageAt,
|
|
152
|
+
last_broadcast_at: this.lastBroadcastAt,
|
|
153
|
+
received_by_topic: this.receivedByTopic,
|
|
154
|
+
published_by_topic: this.publishedByTopic,
|
|
155
|
+
},
|
|
156
|
+
peer_counters: {
|
|
157
|
+
total: peers.length,
|
|
158
|
+
online,
|
|
159
|
+
stale: Math.max(0, peers.length - online),
|
|
160
|
+
},
|
|
161
|
+
adapter_stats: diagnostics?.stats ?? null,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
getPeersSummary() {
|
|
165
|
+
const diagnostics = this.getRealAdapterDiagnostics();
|
|
166
|
+
if (!diagnostics) {
|
|
167
|
+
return {
|
|
168
|
+
adapter: this.adapterMode,
|
|
169
|
+
namespace: this.networkNamespace,
|
|
170
|
+
total: 0,
|
|
171
|
+
online: 0,
|
|
172
|
+
stale: 0,
|
|
173
|
+
items: [],
|
|
174
|
+
stats: null,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
adapter: diagnostics.adapter,
|
|
179
|
+
namespace: diagnostics.namespace,
|
|
180
|
+
total: diagnostics.peers.total,
|
|
181
|
+
online: diagnostics.peers.online,
|
|
182
|
+
stale: diagnostics.peers.stale,
|
|
183
|
+
items: diagnostics.peers.items,
|
|
184
|
+
stats: diagnostics.stats,
|
|
185
|
+
components: diagnostics.components,
|
|
186
|
+
limits: diagnostics.limits,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
getDirectory() {
|
|
190
|
+
this.compactCacheInMemory();
|
|
191
|
+
return this.directory;
|
|
192
|
+
}
|
|
193
|
+
search(keyword) {
|
|
194
|
+
this.compactCacheInMemory();
|
|
195
|
+
return (0, core_1.searchDirectory)(this.directory, keyword, { presenceTTLms: PRESENCE_TTL_MS }).map((profile) => {
|
|
196
|
+
const lastSeenAt = this.directory.presence[profile.agent_id] ?? 0;
|
|
197
|
+
return {
|
|
198
|
+
...profile,
|
|
199
|
+
last_seen_at: lastSeenAt,
|
|
200
|
+
online: (0, core_1.isAgentOnline)(lastSeenAt, Date.now(), PRESENCE_TTL_MS),
|
|
201
|
+
};
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
getProfile() {
|
|
205
|
+
return this.profile;
|
|
206
|
+
}
|
|
207
|
+
getIdentity() {
|
|
208
|
+
return this.identity;
|
|
209
|
+
}
|
|
210
|
+
async getLogs() {
|
|
211
|
+
return this.logRepo.get();
|
|
212
|
+
}
|
|
213
|
+
async ensureIdentity() {
|
|
214
|
+
if (this.identity) {
|
|
215
|
+
return this.identity;
|
|
216
|
+
}
|
|
217
|
+
const identity = (0, core_1.createIdentity)();
|
|
218
|
+
this.identity = identity;
|
|
219
|
+
await this.identityRepo.set(identity);
|
|
220
|
+
this.initState.identity_auto_created = true;
|
|
221
|
+
const seededProfile = (0, core_1.signProfile)((0, core_1.createDefaultProfileInput)(identity.agent_id), identity);
|
|
222
|
+
this.profile = seededProfile;
|
|
223
|
+
await this.profileRepo.set(seededProfile);
|
|
224
|
+
this.initState.profile_auto_created = true;
|
|
225
|
+
await this.log("info", `Identity created automatically: ${identity.agent_id.slice(0, 12)}`);
|
|
226
|
+
return identity;
|
|
227
|
+
}
|
|
228
|
+
async updateProfile(input) {
|
|
229
|
+
const identity = await this.ensureIdentity();
|
|
230
|
+
const base = this.profile ?? (0, core_1.signProfile)((0, core_1.createDefaultProfileInput)(identity.agent_id), identity);
|
|
231
|
+
const next = (0, core_1.signProfile)({
|
|
232
|
+
agent_id: identity.agent_id,
|
|
233
|
+
display_name: input.display_name ?? base.display_name,
|
|
234
|
+
bio: input.bio ?? base.bio,
|
|
235
|
+
tags: input.tags ?? base.tags,
|
|
236
|
+
avatar_url: input.avatar_url ?? base.avatar_url,
|
|
237
|
+
public_enabled: input.public_enabled ?? base.public_enabled,
|
|
238
|
+
}, identity);
|
|
239
|
+
this.profile = next;
|
|
240
|
+
this.directory = (0, core_1.ingestProfileRecord)(this.directory, { type: "profile", profile: next });
|
|
241
|
+
await this.profileRepo.set(next);
|
|
242
|
+
await this.persistCache();
|
|
243
|
+
await this.log("info", `Profile updated (public=${next.public_enabled})`);
|
|
244
|
+
if (next.public_enabled && this.broadcastEnabled) {
|
|
245
|
+
await this.broadcastNow("profile_update");
|
|
246
|
+
}
|
|
247
|
+
return next;
|
|
248
|
+
}
|
|
249
|
+
async refreshCache() {
|
|
250
|
+
const removed = this.compactCacheInMemory();
|
|
251
|
+
await this.persistCache();
|
|
252
|
+
await this.log("info", `Cache refreshed (expired presence removed=${removed})`);
|
|
253
|
+
return {
|
|
254
|
+
removed_presence: removed,
|
|
255
|
+
profile_count: Object.keys(this.directory.profiles).length,
|
|
256
|
+
index_key_count: Object.keys(this.directory.index).length,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
async setBroadcastEnabled(enabled) {
|
|
260
|
+
this.broadcastEnabled = enabled;
|
|
261
|
+
if (enabled) {
|
|
262
|
+
this.startBroadcastLoop();
|
|
263
|
+
await this.log("info", "Broadcast loop enabled");
|
|
264
|
+
if (this.profile?.public_enabled) {
|
|
265
|
+
await this.broadcastNow("manual_start");
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
if (this.broadcaster) {
|
|
270
|
+
clearInterval(this.broadcaster);
|
|
271
|
+
this.broadcaster = null;
|
|
272
|
+
}
|
|
273
|
+
await this.log("warn", "Broadcast loop paused");
|
|
274
|
+
}
|
|
275
|
+
return { broadcast_enabled: this.broadcastEnabled };
|
|
276
|
+
}
|
|
277
|
+
async broadcastNow(reason = "manual") {
|
|
278
|
+
if (!this.identity || !this.profile) {
|
|
279
|
+
return { sent: false, reason: "missing_identity_or_profile" };
|
|
280
|
+
}
|
|
281
|
+
if (!this.profile.public_enabled) {
|
|
282
|
+
return { sent: false, reason: "public_disabled" };
|
|
283
|
+
}
|
|
284
|
+
if (!this.broadcastEnabled) {
|
|
285
|
+
return { sent: false, reason: "broadcast_paused" };
|
|
286
|
+
}
|
|
287
|
+
const profileRecord = {
|
|
288
|
+
type: "profile",
|
|
289
|
+
profile: this.profile,
|
|
290
|
+
};
|
|
291
|
+
const presenceRecord = (0, core_1.signPresence)(this.identity, Date.now());
|
|
292
|
+
const indexRecords = (0, core_1.buildIndexRecords)(this.profile);
|
|
293
|
+
await this.publish("profile", profileRecord);
|
|
294
|
+
await this.publish("presence", presenceRecord);
|
|
295
|
+
for (const record of indexRecords) {
|
|
296
|
+
await this.publish("index", record);
|
|
297
|
+
}
|
|
298
|
+
this.lastBroadcastAt = Date.now();
|
|
299
|
+
this.broadcastCount += 1;
|
|
300
|
+
this.directory = (0, core_1.ingestProfileRecord)(this.directory, profileRecord);
|
|
301
|
+
this.directory = (0, core_1.ingestPresenceRecord)(this.directory, presenceRecord);
|
|
302
|
+
for (const record of indexRecords) {
|
|
303
|
+
this.directory = (0, core_1.ingestIndexRecord)(this.directory, record);
|
|
304
|
+
}
|
|
305
|
+
this.compactCacheInMemory();
|
|
306
|
+
await this.persistCache();
|
|
307
|
+
await this.log("info", `Broadcast sent (${indexRecords.length} index refs, reason=${reason})`);
|
|
308
|
+
return { sent: true, reason };
|
|
309
|
+
}
|
|
310
|
+
async hydrateFromDisk() {
|
|
311
|
+
this.initState = {
|
|
312
|
+
identity_auto_created: false,
|
|
313
|
+
profile_auto_created: false,
|
|
314
|
+
initialized_at: Date.now(),
|
|
315
|
+
};
|
|
316
|
+
this.identity = await this.identityRepo.get();
|
|
317
|
+
if (!this.identity) {
|
|
318
|
+
this.identity = (0, core_1.createIdentity)();
|
|
319
|
+
this.initState.identity_auto_created = true;
|
|
320
|
+
await this.identityRepo.set(this.identity);
|
|
321
|
+
await this.log("info", "identity.json missing, auto-generated identity");
|
|
322
|
+
}
|
|
323
|
+
this.profile = await this.profileRepo.get();
|
|
324
|
+
if (!this.profile || this.profile.agent_id !== this.identity.agent_id) {
|
|
325
|
+
this.profile = (0, core_1.signProfile)((0, core_1.createDefaultProfileInput)(this.identity.agent_id), this.identity);
|
|
326
|
+
this.initState.profile_auto_created = true;
|
|
327
|
+
await this.profileRepo.set(this.profile);
|
|
328
|
+
await this.log("info", "profile.json missing/invalid, auto-generated default profile");
|
|
329
|
+
}
|
|
330
|
+
this.directory = (0, core_1.dedupeIndex)(await this.cacheRepo.get());
|
|
331
|
+
this.directory = (0, core_1.ingestProfileRecord)(this.directory, { type: "profile", profile: this.profile });
|
|
332
|
+
this.compactCacheInMemory();
|
|
333
|
+
await this.persistCache();
|
|
334
|
+
}
|
|
335
|
+
async onMessage(topic, data) {
|
|
336
|
+
this.receivedCount += 1;
|
|
337
|
+
this.receivedByTopic[topic] = (this.receivedByTopic[topic] ?? 0) + 1;
|
|
338
|
+
this.lastMessageAt = Date.now();
|
|
339
|
+
if (topic === "profile") {
|
|
340
|
+
const record = data;
|
|
341
|
+
if (!record?.profile?.agent_id || !record?.profile?.signature) {
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
if (record.profile.agent_id === this.identity?.agent_id && this.identity) {
|
|
345
|
+
if (!(0, core_1.verifyProfile)(record.profile, this.identity.public_key)) {
|
|
346
|
+
await this.log("warn", "Rejected self profile with invalid signature");
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
this.directory = (0, core_1.ingestProfileRecord)(this.directory, record);
|
|
351
|
+
this.compactCacheInMemory();
|
|
352
|
+
await this.persistCache();
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
if (topic === "presence") {
|
|
356
|
+
const record = data;
|
|
357
|
+
if (!record?.agent_id || !record?.signature || typeof record.timestamp !== "number") {
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
if (record.agent_id === this.identity?.agent_id && this.identity) {
|
|
361
|
+
if (!(0, core_1.verifyPresence)(record, this.identity.public_key)) {
|
|
362
|
+
await this.log("warn", "Rejected invalid self presence signature");
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
this.directory = (0, core_1.ingestPresenceRecord)(this.directory, record);
|
|
367
|
+
this.compactCacheInMemory();
|
|
368
|
+
await this.persistCache();
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
const record = data;
|
|
372
|
+
if (!record?.key || !record?.agent_id) {
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
this.directory = (0, core_1.ingestIndexRecord)(this.directory, record);
|
|
376
|
+
this.directory = (0, core_1.dedupeIndex)(this.directory);
|
|
377
|
+
await this.persistCache();
|
|
378
|
+
}
|
|
379
|
+
startBroadcastLoop() {
|
|
380
|
+
if (this.broadcaster) {
|
|
381
|
+
clearInterval(this.broadcaster);
|
|
382
|
+
}
|
|
383
|
+
if (!this.broadcastEnabled) {
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
this.broadcaster = setInterval(async () => {
|
|
387
|
+
await this.broadcastNow("interval");
|
|
388
|
+
}, BROADCAST_INTERVAL_MS);
|
|
389
|
+
}
|
|
390
|
+
compactCacheInMemory() {
|
|
391
|
+
const cleaned = (0, core_1.cleanupExpiredPresence)(this.directory, Date.now(), PRESENCE_TTL_MS);
|
|
392
|
+
this.directory = (0, core_1.dedupeIndex)(cleaned.state);
|
|
393
|
+
return cleaned.removed;
|
|
394
|
+
}
|
|
395
|
+
async publish(topic, data) {
|
|
396
|
+
await this.network.publish(topic, data);
|
|
397
|
+
this.publishedByTopic[topic] = (this.publishedByTopic[topic] ?? 0) + 1;
|
|
398
|
+
}
|
|
399
|
+
async persistCache() {
|
|
400
|
+
await this.cacheRepo.set(this.directory);
|
|
401
|
+
}
|
|
402
|
+
async log(level, message) {
|
|
403
|
+
await this.logRepo.append({
|
|
404
|
+
level,
|
|
405
|
+
message,
|
|
406
|
+
timestamp: Date.now(),
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
getRealAdapterDiagnostics() {
|
|
410
|
+
if (typeof this.network.getDiagnostics !== "function") {
|
|
411
|
+
return null;
|
|
412
|
+
}
|
|
413
|
+
return this.network.getDiagnostics();
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
function sendOk(res, data, meta) {
|
|
417
|
+
res.json({ ok: true, data, meta });
|
|
418
|
+
}
|
|
419
|
+
function sendError(res, status, code, message, details) {
|
|
420
|
+
const error = { code, message };
|
|
421
|
+
if (details !== undefined) {
|
|
422
|
+
error.details = details;
|
|
423
|
+
}
|
|
424
|
+
res.status(status).json({ ok: false, error });
|
|
425
|
+
}
|
|
426
|
+
function asyncRoute(handler) {
|
|
427
|
+
return (req, res, next) => {
|
|
428
|
+
Promise.resolve(handler(req, res)).catch(next);
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
function resolveLocalConsoleStaticDir() {
|
|
432
|
+
const candidates = [
|
|
433
|
+
(0, path_1.resolve)(process.cwd(), "public"),
|
|
434
|
+
(0, path_1.resolve)(process.cwd(), "apps", "local-console", "public"),
|
|
435
|
+
(0, path_1.resolve)(__dirname, "..", "public"),
|
|
436
|
+
(0, path_1.resolve)(__dirname, "..", "..", "apps", "local-console", "public"),
|
|
437
|
+
];
|
|
438
|
+
for (const dir of candidates) {
|
|
439
|
+
if ((0, fs_1.existsSync)((0, path_1.resolve)(dir, "index.html"))) {
|
|
440
|
+
return dir;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
return candidates[0];
|
|
444
|
+
}
|
|
445
|
+
async function main() {
|
|
446
|
+
const app = (0, express_1.default)();
|
|
447
|
+
const port = Number(process.env.PORT || 4310);
|
|
448
|
+
const staticDir = resolveLocalConsoleStaticDir();
|
|
449
|
+
const node = new LocalNodeService();
|
|
450
|
+
await node.start();
|
|
451
|
+
app.use((0, cors_1.default)({ origin: true }));
|
|
452
|
+
app.use(express_1.default.json());
|
|
453
|
+
app.get("/api/identity", (_req, res) => {
|
|
454
|
+
sendOk(res, node.getIdentity());
|
|
455
|
+
});
|
|
456
|
+
app.post("/api/identity/create", asyncRoute(async (_req, res) => {
|
|
457
|
+
const identity = await node.ensureIdentity();
|
|
458
|
+
sendOk(res, identity, { message: "Identity is ready" });
|
|
459
|
+
}));
|
|
460
|
+
app.get("/api/profile", (_req, res) => {
|
|
461
|
+
sendOk(res, node.getProfile());
|
|
462
|
+
});
|
|
463
|
+
app.put("/api/profile", asyncRoute(async (req, res) => {
|
|
464
|
+
const body = req.body;
|
|
465
|
+
const tags = Array.isArray(body.tags)
|
|
466
|
+
? body.tags.map((tag) => String(tag).trim()).filter(Boolean)
|
|
467
|
+
: undefined;
|
|
468
|
+
const profile = await node.updateProfile({
|
|
469
|
+
...body,
|
|
470
|
+
tags,
|
|
471
|
+
display_name: body.display_name?.toString() ?? undefined,
|
|
472
|
+
bio: body.bio?.toString() ?? undefined,
|
|
473
|
+
avatar_url: body.avatar_url?.toString() ?? undefined,
|
|
474
|
+
public_enabled: typeof body.public_enabled === "boolean" ? body.public_enabled : undefined,
|
|
475
|
+
});
|
|
476
|
+
sendOk(res, profile, { message: "Profile saved" });
|
|
477
|
+
}));
|
|
478
|
+
app.get("/api/overview", (_req, res) => {
|
|
479
|
+
sendOk(res, node.getOverview());
|
|
480
|
+
});
|
|
481
|
+
app.get("/api/network", (_req, res) => {
|
|
482
|
+
sendOk(res, node.getNetworkSummary());
|
|
483
|
+
});
|
|
484
|
+
app.get("/api/network/config", (_req, res) => {
|
|
485
|
+
sendOk(res, node.getNetworkConfig());
|
|
486
|
+
});
|
|
487
|
+
app.get("/api/network/stats", (_req, res) => {
|
|
488
|
+
sendOk(res, node.getNetworkStats());
|
|
489
|
+
});
|
|
490
|
+
app.get("/api/peers", (_req, res) => {
|
|
491
|
+
sendOk(res, node.getPeersSummary());
|
|
492
|
+
});
|
|
493
|
+
app.post("/api/broadcast/start", asyncRoute(async (_req, res) => {
|
|
494
|
+
const summary = await node.setBroadcastEnabled(true);
|
|
495
|
+
sendOk(res, summary, { message: "Broadcast started" });
|
|
496
|
+
}));
|
|
497
|
+
app.post("/api/broadcast/stop", asyncRoute(async (_req, res) => {
|
|
498
|
+
const summary = await node.setBroadcastEnabled(false);
|
|
499
|
+
sendOk(res, summary, { message: "Broadcast stopped" });
|
|
500
|
+
}));
|
|
501
|
+
app.post("/api/broadcast/now", asyncRoute(async (_req, res) => {
|
|
502
|
+
const result = await node.broadcastNow("manual_button");
|
|
503
|
+
sendOk(res, result, {
|
|
504
|
+
message: result.sent ? "Broadcast published" : `Broadcast skipped: ${result.reason}`,
|
|
505
|
+
});
|
|
506
|
+
}));
|
|
507
|
+
app.post("/api/cache/refresh", asyncRoute(async (_req, res) => {
|
|
508
|
+
const result = await node.refreshCache();
|
|
509
|
+
sendOk(res, result, { message: "Cache refreshed" });
|
|
510
|
+
}));
|
|
511
|
+
app.get("/api/logs", asyncRoute(async (_req, res) => {
|
|
512
|
+
sendOk(res, await node.getLogs());
|
|
513
|
+
}));
|
|
514
|
+
app.get("/api/search", (req, res) => {
|
|
515
|
+
const q = String(req.query.q ?? "");
|
|
516
|
+
sendOk(res, node.search(q));
|
|
517
|
+
});
|
|
518
|
+
app.get("/api/agents/:agentId", (req, res) => {
|
|
519
|
+
const state = node.getDirectory();
|
|
520
|
+
const agentId = req.params.agentId;
|
|
521
|
+
const profile = state.profiles[agentId];
|
|
522
|
+
if (!profile) {
|
|
523
|
+
sendError(res, 404, "AGENT_NOT_FOUND", "Agent not found", { agent_id: agentId });
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
const lastSeenAt = state.presence[agentId] ?? 0;
|
|
527
|
+
sendOk(res, {
|
|
528
|
+
profile,
|
|
529
|
+
last_seen_at: lastSeenAt,
|
|
530
|
+
online: (0, core_1.isAgentOnline)(lastSeenAt, Date.now(), PRESENCE_TTL_MS),
|
|
531
|
+
presence_ttl_ms: PRESENCE_TTL_MS,
|
|
532
|
+
});
|
|
533
|
+
});
|
|
534
|
+
app.get("/api/health", (_req, res) => {
|
|
535
|
+
sendOk(res, { ok: true });
|
|
536
|
+
});
|
|
537
|
+
app.use(express_1.default.static(staticDir));
|
|
538
|
+
app.use((error, _req, res, _next) => {
|
|
539
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
540
|
+
sendError(res, 500, "INTERNAL_ERROR", message);
|
|
541
|
+
});
|
|
542
|
+
app.listen(port, () => {
|
|
543
|
+
// eslint-disable-next-line no-console
|
|
544
|
+
console.log(`SilicaClaw local-console running: http://localhost:${port}`);
|
|
545
|
+
});
|
|
546
|
+
process.on("SIGINT", async () => {
|
|
547
|
+
await node.stop();
|
|
548
|
+
process.exit(0);
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
main().catch((error) => {
|
|
552
|
+
// eslint-disable-next-line no-console
|
|
553
|
+
console.error(error);
|
|
554
|
+
process.exit(1);
|
|
555
|
+
});
|
package/docs/NEW_USER_INSTALL.md
CHANGED
|
@@ -20,7 +20,7 @@ npm -v
|
|
|
20
20
|
No global install is required.
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
npx -y @silicaclaw/cli@
|
|
23
|
+
npx -y @silicaclaw/cli@latest onboard
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
The onboarding flow will help you:
|
|
@@ -57,20 +57,24 @@ In the page, confirm:
|
|
|
57
57
|
If you use `npx` only:
|
|
58
58
|
|
|
59
59
|
```bash
|
|
60
|
-
npx -y @silicaclaw/cli@
|
|
61
|
-
npx -y @silicaclaw/cli@
|
|
62
|
-
npx -y @silicaclaw/cli@
|
|
63
|
-
npx -y @silicaclaw/cli@
|
|
64
|
-
npx -y @silicaclaw/cli@
|
|
60
|
+
npx -y @silicaclaw/cli@latest install
|
|
61
|
+
npx -y @silicaclaw/cli@latest start
|
|
62
|
+
npx -y @silicaclaw/cli@latest status
|
|
63
|
+
npx -y @silicaclaw/cli@latest stop
|
|
64
|
+
npx -y @silicaclaw/cli@latest update
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
Recommended once per machine:
|
|
68
68
|
|
|
69
69
|
```bash
|
|
70
|
-
npx -y @silicaclaw/cli@
|
|
70
|
+
npx -y @silicaclaw/cli@latest install
|
|
71
71
|
source ~/.silicaclaw/env.sh
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
+
- `onboard`: first-time setup wizard
|
|
75
|
+
- `connect`: quick network setup wizard
|
|
76
|
+
- `install`: install the persistent `silicaclaw` command only
|
|
77
|
+
|
|
74
78
|
Then you can use:
|
|
75
79
|
|
|
76
80
|
```bash
|
|
@@ -117,13 +121,13 @@ Open:
|
|
|
117
121
|
Use `npx` directly:
|
|
118
122
|
|
|
119
123
|
```bash
|
|
120
|
-
npx -y @silicaclaw/cli@
|
|
124
|
+
npx -y @silicaclaw/cli@latest start
|
|
121
125
|
```
|
|
122
126
|
|
|
123
127
|
Or add the alias:
|
|
124
128
|
|
|
125
129
|
```bash
|
|
126
|
-
npx -y @silicaclaw/cli@
|
|
130
|
+
npx -y @silicaclaw/cli@latest install
|
|
127
131
|
source ~/.silicaclaw/env.sh
|
|
128
132
|
```
|
|
129
133
|
|
|
@@ -131,7 +135,7 @@ source ~/.silicaclaw/env.sh
|
|
|
131
135
|
|
|
132
136
|
That is expected on many systems. You do not need global install.
|
|
133
137
|
|
|
134
|
-
Use `npx` or `npx -y @silicaclaw/cli@
|
|
138
|
+
Use `npx` or `npx -y @silicaclaw/cli@latest install` instead.
|
|
135
139
|
|
|
136
140
|
### Browser page still shows old UI after update
|
|
137
141
|
|
|
@@ -11,7 +11,7 @@ If you have not installed yet, start here first:
|
|
|
11
11
|
Install the persistent command once:
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
npx -y @silicaclaw/cli@
|
|
14
|
+
npx -y @silicaclaw/cli@latest install
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
Then activate it in the current shell:
|
|
@@ -222,7 +222,7 @@ silicaclaw update
|
|
|
222
222
|
|
|
223
223
|
It will:
|
|
224
224
|
|
|
225
|
-
- check the npm
|
|
225
|
+
- check the npm latest version
|
|
226
226
|
- refresh runtime files when needed
|
|
227
227
|
- restart services if they are already running
|
|
228
228
|
|
|
@@ -235,7 +235,7 @@ After update, refresh the browser if the page is already open.
|
|
|
235
235
|
Run:
|
|
236
236
|
|
|
237
237
|
```bash
|
|
238
|
-
npx -y @silicaclaw/cli@
|
|
238
|
+
npx -y @silicaclaw/cli@latest install
|
|
239
239
|
source ~/.silicaclaw/env.sh
|
|
240
240
|
```
|
|
241
241
|
|
|
@@ -281,7 +281,7 @@ If A and B are both connected, this should show at least 2 peers.
|
|
|
281
281
|
|
|
282
282
|
If you want the shortest repeatable path:
|
|
283
283
|
|
|
284
|
-
1. `npx -y @silicaclaw/cli@
|
|
284
|
+
1. `npx -y @silicaclaw/cli@latest install`
|
|
285
285
|
2. `silicaclaw start`
|
|
286
286
|
3. Open `http://localhost:4310`
|
|
287
287
|
4. Save profile
|
package/docs/OPENCLAW_BRIDGE.md
CHANGED
|
@@ -125,6 +125,21 @@ It also includes `scripts/send-to-owner-via-openclaw.mjs` so those summaries can
|
|
|
125
125
|
`openclaw-skill-validate` checks the bundled skill metadata.
|
|
126
126
|
`openclaw-skill-pack` writes a publishable tarball and `.sha256` to `dist/openclaw-skills/`.
|
|
127
127
|
|
|
128
|
+
To publish the bundled skill to ClawHub:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npx clawhub login
|
|
132
|
+
npx clawhub sync --root openclaw-skills --dry-run
|
|
133
|
+
npx clawhub publish openclaw-skills/silicaclaw-broadcast \
|
|
134
|
+
--slug silicaclaw-broadcast \
|
|
135
|
+
--name "SilicaClaw Broadcast" \
|
|
136
|
+
--version 2026.3.19-beta.15 \
|
|
137
|
+
--tags latest \
|
|
138
|
+
--changelog "Initial public release for SilicaClaw broadcast learning and owner forwarding via OpenClaw."
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
ClawHub publishes the skill folder itself, not `@silicaclaw/cli`.
|
|
142
|
+
|
|
128
143
|
Interactive demo:
|
|
129
144
|
|
|
130
145
|
```bash
|
|
@@ -150,6 +150,21 @@ silicaclaw openclaw-skill-validate
|
|
|
150
150
|
`openclaw-skill-validate` 会检查技能元数据是否完整。
|
|
151
151
|
`openclaw-skill-pack` 会把技能和 `.sha256` 打包到 `dist/openclaw-skills/`,方便后续发布。
|
|
152
152
|
|
|
153
|
+
如果要把这个技能发布到 ClawHub,可直接发布技能目录本身:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
npx clawhub login
|
|
157
|
+
npx clawhub sync --root openclaw-skills --dry-run
|
|
158
|
+
npx clawhub publish openclaw-skills/silicaclaw-broadcast \
|
|
159
|
+
--slug silicaclaw-broadcast \
|
|
160
|
+
--name "SilicaClaw Broadcast" \
|
|
161
|
+
--version 2026.3.19-beta.15 \
|
|
162
|
+
--tags latest \
|
|
163
|
+
--changelog "Initial public release for SilicaClaw broadcast learning and owner forwarding via OpenClaw."
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
注意:ClawHub 要求技能版本号是合法 semver,所以这里要用技能包自己的版本号,而不是 npm CLI 那套带 `-15` 的版本格式。
|
|
167
|
+
|
|
153
168
|
## 5. 交互式 Demo
|
|
154
169
|
|
|
155
170
|
如果你想快速模拟一个 OpenClaw runtime:
|