@silicaclaw/cli 1.0.0-beta.2 → 1.0.0-beta.21
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 +8 -0
- package/INSTALL.md +36 -0
- package/README.md +40 -0
- package/apps/local-console/public/index.html +81 -63
- package/apps/local-console/src/server.ts +41 -21
- package/docs/CLOUDFLARE_RELAY.md +61 -0
- package/package.json +6 -1
- package/packages/core/dist/crypto.d.ts +6 -0
- package/packages/core/dist/crypto.js +50 -0
- package/packages/core/dist/directory.d.ts +17 -0
- package/packages/core/dist/directory.js +145 -0
- package/packages/core/dist/identity.d.ts +2 -0
- package/packages/core/dist/identity.js +18 -0
- package/packages/core/dist/index.d.ts +11 -0
- package/packages/core/dist/index.js +27 -0
- package/packages/core/dist/indexing.d.ts +6 -0
- package/packages/core/dist/indexing.js +43 -0
- package/packages/core/dist/presence.d.ts +4 -0
- package/packages/core/dist/presence.js +23 -0
- package/packages/core/dist/profile.d.ts +4 -0
- package/packages/core/dist/profile.js +39 -0
- package/packages/core/dist/publicProfileSummary.d.ts +70 -0
- package/packages/core/dist/publicProfileSummary.js +103 -0
- package/packages/core/dist/socialConfig.d.ts +99 -0
- package/packages/core/dist/socialConfig.js +288 -0
- package/packages/core/dist/socialResolver.d.ts +46 -0
- package/packages/core/dist/socialResolver.js +237 -0
- package/packages/core/dist/socialTemplate.d.ts +2 -0
- package/packages/core/dist/socialTemplate.js +88 -0
- package/packages/core/dist/types.d.ts +37 -0
- package/packages/core/dist/types.js +2 -0
- package/packages/core/src/socialConfig.ts +7 -6
- package/packages/core/src/socialResolver.ts +17 -5
- package/packages/network/dist/abstractions/messageEnvelope.d.ts +28 -0
- package/packages/network/dist/abstractions/messageEnvelope.js +36 -0
- package/packages/network/dist/abstractions/peerDiscovery.d.ts +43 -0
- package/packages/network/dist/abstractions/peerDiscovery.js +2 -0
- package/packages/network/dist/abstractions/topicCodec.d.ts +4 -0
- package/packages/network/dist/abstractions/topicCodec.js +2 -0
- package/packages/network/dist/abstractions/transport.d.ts +36 -0
- package/packages/network/dist/abstractions/transport.js +2 -0
- package/packages/network/dist/codec/jsonMessageEnvelopeCodec.d.ts +5 -0
- package/packages/network/dist/codec/jsonMessageEnvelopeCodec.js +24 -0
- package/packages/network/dist/codec/jsonTopicCodec.d.ts +5 -0
- package/packages/network/dist/codec/jsonTopicCodec.js +12 -0
- package/packages/network/dist/discovery/heartbeatPeerDiscovery.d.ts +28 -0
- package/packages/network/dist/discovery/heartbeatPeerDiscovery.js +144 -0
- package/packages/network/dist/index.d.ts +14 -0
- package/packages/network/dist/index.js +30 -0
- package/packages/network/dist/localEventBus.d.ts +9 -0
- package/packages/network/dist/localEventBus.js +47 -0
- package/packages/network/dist/mock.d.ts +8 -0
- package/packages/network/dist/mock.js +24 -0
- package/packages/network/dist/realPreview.d.ts +105 -0
- package/packages/network/dist/realPreview.js +327 -0
- package/packages/network/dist/relayPreview.d.ts +133 -0
- package/packages/network/dist/relayPreview.js +320 -0
- package/packages/network/dist/transport/udpLanBroadcastTransport.d.ts +23 -0
- package/packages/network/dist/transport/udpLanBroadcastTransport.js +153 -0
- package/packages/network/dist/types.d.ts +6 -0
- package/packages/network/dist/types.js +2 -0
- package/packages/network/dist/webrtcPreview.d.ts +163 -0
- package/packages/network/dist/webrtcPreview.js +844 -0
- package/packages/network/src/index.ts +1 -0
- package/packages/network/src/relayPreview.ts +425 -0
- package/packages/storage/dist/index.d.ts +3 -0
- package/packages/storage/dist/index.js +19 -0
- package/packages/storage/dist/jsonRepo.d.ts +7 -0
- package/packages/storage/dist/jsonRepo.js +29 -0
- package/packages/storage/dist/repos.d.ts +21 -0
- package/packages/storage/dist/repos.js +41 -0
- package/packages/storage/dist/socialRuntimeRepo.d.ts +5 -0
- package/packages/storage/dist/socialRuntimeRepo.js +52 -0
- package/packages/storage/src/socialRuntimeRepo.ts +3 -3
- package/packages/storage/tsconfig.json +6 -1
- package/scripts/quickstart.sh +286 -20
- package/scripts/silicaclaw-cli.mjs +271 -1
- package/scripts/silicaclaw-gateway.mjs +411 -0
- package/scripts/webrtc-signaling-server.mjs +52 -1
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseFrontmatterObject = parseFrontmatterObject;
|
|
4
|
+
exports.extractFrontmatter = extractFrontmatter;
|
|
5
|
+
exports.normalizeSocialConfig = normalizeSocialConfig;
|
|
6
|
+
exports.getDefaultSocialConfig = getDefaultSocialConfig;
|
|
7
|
+
exports.generateDefaultSocialMdTemplate = generateDefaultSocialMdTemplate;
|
|
8
|
+
const DEFAULT_SOCIAL_CONFIG = {
|
|
9
|
+
enabled: true,
|
|
10
|
+
public_enabled: false,
|
|
11
|
+
identity: {
|
|
12
|
+
display_name: "",
|
|
13
|
+
bio: "",
|
|
14
|
+
avatar_url: "",
|
|
15
|
+
tags: [],
|
|
16
|
+
},
|
|
17
|
+
network: {
|
|
18
|
+
mode: "global-preview",
|
|
19
|
+
namespace: "silicaclaw.preview",
|
|
20
|
+
adapter: "relay-preview",
|
|
21
|
+
port: 44123,
|
|
22
|
+
signaling_url: "http://localhost:4510",
|
|
23
|
+
signaling_urls: [],
|
|
24
|
+
room: "silicaclaw-global-preview",
|
|
25
|
+
seed_peers: [],
|
|
26
|
+
bootstrap_hints: [],
|
|
27
|
+
},
|
|
28
|
+
discovery: {
|
|
29
|
+
discoverable: true,
|
|
30
|
+
allow_profile_broadcast: true,
|
|
31
|
+
allow_presence_broadcast: true,
|
|
32
|
+
},
|
|
33
|
+
visibility: {
|
|
34
|
+
show_display_name: true,
|
|
35
|
+
show_bio: true,
|
|
36
|
+
show_tags: true,
|
|
37
|
+
show_agent_id: true,
|
|
38
|
+
show_last_seen: true,
|
|
39
|
+
show_capabilities_summary: true,
|
|
40
|
+
},
|
|
41
|
+
openclaw: {
|
|
42
|
+
bind_existing_identity: true,
|
|
43
|
+
use_openclaw_profile_if_available: true,
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
function parseScalar(value) {
|
|
47
|
+
const trimmed = value.trim();
|
|
48
|
+
if (trimmed === "[]")
|
|
49
|
+
return [];
|
|
50
|
+
if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
|
|
51
|
+
const inner = trimmed.slice(1, -1).trim();
|
|
52
|
+
if (!inner)
|
|
53
|
+
return [];
|
|
54
|
+
return inner
|
|
55
|
+
.split(",")
|
|
56
|
+
.map((item) => item.trim())
|
|
57
|
+
.map((item) => (item.startsWith('"') && item.endsWith('"')) || (item.startsWith("'") && item.endsWith("'"))
|
|
58
|
+
? item.slice(1, -1)
|
|
59
|
+
: item)
|
|
60
|
+
.filter(Boolean);
|
|
61
|
+
}
|
|
62
|
+
if (trimmed === "true")
|
|
63
|
+
return true;
|
|
64
|
+
if (trimmed === "false")
|
|
65
|
+
return false;
|
|
66
|
+
if (trimmed === "null")
|
|
67
|
+
return null;
|
|
68
|
+
if (/^-?\d+(\.\d+)?$/.test(trimmed))
|
|
69
|
+
return Number(trimmed);
|
|
70
|
+
if ((trimmed.startsWith('"') && trimmed.endsWith('"')) ||
|
|
71
|
+
(trimmed.startsWith("'") && trimmed.endsWith("'"))) {
|
|
72
|
+
return trimmed.slice(1, -1);
|
|
73
|
+
}
|
|
74
|
+
return trimmed;
|
|
75
|
+
}
|
|
76
|
+
function countIndent(line) {
|
|
77
|
+
let count = 0;
|
|
78
|
+
while (count < line.length && line[count] === " ")
|
|
79
|
+
count += 1;
|
|
80
|
+
return count;
|
|
81
|
+
}
|
|
82
|
+
function findNextSignificantLine(lines, start) {
|
|
83
|
+
for (let i = start; i < lines.length; i += 1) {
|
|
84
|
+
const raw = lines[i];
|
|
85
|
+
const trimmed = raw.trim();
|
|
86
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
87
|
+
continue;
|
|
88
|
+
return { line: trimmed, indent: countIndent(raw) };
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
function parseFrontmatterObject(frontmatter) {
|
|
93
|
+
const root = {};
|
|
94
|
+
const lines = frontmatter.replace(/\r\n/g, "\n").split("\n");
|
|
95
|
+
const stack = [{ indent: -1, value: root, kind: "object" }];
|
|
96
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
97
|
+
const raw = lines[i];
|
|
98
|
+
const trimmed = raw.trim();
|
|
99
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
100
|
+
continue;
|
|
101
|
+
const indent = countIndent(raw);
|
|
102
|
+
while (stack.length > 1 && indent <= stack[stack.length - 1].indent) {
|
|
103
|
+
stack.pop();
|
|
104
|
+
}
|
|
105
|
+
const current = stack[stack.length - 1];
|
|
106
|
+
if (trimmed.startsWith("- ")) {
|
|
107
|
+
if (current.kind !== "array") {
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
const itemRaw = trimmed.slice(2).trim();
|
|
111
|
+
if (!itemRaw) {
|
|
112
|
+
const child = {};
|
|
113
|
+
current.value.push(child);
|
|
114
|
+
stack.push({ indent, value: child, kind: "object" });
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
const keyValue = itemRaw.match(/^([A-Za-z0-9_]+):\s*(.*)$/);
|
|
118
|
+
if (keyValue) {
|
|
119
|
+
const child = {};
|
|
120
|
+
const key = keyValue[1];
|
|
121
|
+
const valueRaw = keyValue[2];
|
|
122
|
+
child[key] = valueRaw ? parseScalar(valueRaw) : "";
|
|
123
|
+
current.value.push(child);
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
current.value.push(parseScalar(itemRaw));
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
const match = trimmed.match(/^([A-Za-z0-9_]+):\s*(.*)$/);
|
|
130
|
+
if (!match || current.kind !== "object") {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
const key = match[1];
|
|
134
|
+
const valueRaw = match[2];
|
|
135
|
+
const obj = current.value;
|
|
136
|
+
if (valueRaw) {
|
|
137
|
+
obj[key] = parseScalar(valueRaw);
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
const next = findNextSignificantLine(lines, i + 1);
|
|
141
|
+
const nextIsArray = Boolean(next && next.indent > indent && next.line.startsWith("- "));
|
|
142
|
+
if (nextIsArray) {
|
|
143
|
+
const arr = [];
|
|
144
|
+
obj[key] = arr;
|
|
145
|
+
stack.push({ indent, value: arr, kind: "array" });
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
const childObj = {};
|
|
149
|
+
obj[key] = childObj;
|
|
150
|
+
stack.push({ indent, value: childObj, kind: "object" });
|
|
151
|
+
}
|
|
152
|
+
return root;
|
|
153
|
+
}
|
|
154
|
+
function extractFrontmatter(content) {
|
|
155
|
+
const normalized = content.replace(/\r\n/g, "\n");
|
|
156
|
+
if (!normalized.startsWith("---\n")) {
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
const end = normalized.indexOf("\n---", 4);
|
|
160
|
+
if (end < 0) {
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
return normalized.slice(4, end).trim();
|
|
164
|
+
}
|
|
165
|
+
function asObject(value) {
|
|
166
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
167
|
+
return value;
|
|
168
|
+
}
|
|
169
|
+
return {};
|
|
170
|
+
}
|
|
171
|
+
function asBool(value, fallback) {
|
|
172
|
+
return typeof value === "boolean" ? value : fallback;
|
|
173
|
+
}
|
|
174
|
+
function asString(value, fallback) {
|
|
175
|
+
return typeof value === "string" ? value : fallback;
|
|
176
|
+
}
|
|
177
|
+
function asNumber(value, fallback) {
|
|
178
|
+
return Number.isFinite(value) ? Number(value) : fallback;
|
|
179
|
+
}
|
|
180
|
+
function asStringArray(value, fallback) {
|
|
181
|
+
if (!Array.isArray(value))
|
|
182
|
+
return fallback;
|
|
183
|
+
return value.map((item) => String(item).trim()).filter(Boolean);
|
|
184
|
+
}
|
|
185
|
+
function asAdapter(value, fallback) {
|
|
186
|
+
if (value === "mock" ||
|
|
187
|
+
value === "local-event-bus" ||
|
|
188
|
+
value === "real-preview" ||
|
|
189
|
+
value === "webrtc-preview" ||
|
|
190
|
+
value === "relay-preview") {
|
|
191
|
+
return value;
|
|
192
|
+
}
|
|
193
|
+
return fallback;
|
|
194
|
+
}
|
|
195
|
+
function asMode(value, fallback) {
|
|
196
|
+
if (value === "local" || value === "lan" || value === "global-preview") {
|
|
197
|
+
return value;
|
|
198
|
+
}
|
|
199
|
+
return fallback;
|
|
200
|
+
}
|
|
201
|
+
function adapterForMode(mode) {
|
|
202
|
+
if (mode === "local")
|
|
203
|
+
return "local-event-bus";
|
|
204
|
+
if (mode === "lan")
|
|
205
|
+
return "real-preview";
|
|
206
|
+
return "relay-preview";
|
|
207
|
+
}
|
|
208
|
+
function normalizeSocialConfig(input) {
|
|
209
|
+
const root = asObject(input);
|
|
210
|
+
const identity = asObject(root.identity);
|
|
211
|
+
const network = asObject(root.network);
|
|
212
|
+
const discovery = asObject(root.discovery);
|
|
213
|
+
const visibility = asObject(root.visibility);
|
|
214
|
+
const openclaw = asObject(root.openclaw);
|
|
215
|
+
const signalingUrl = asString(network.signaling_url, DEFAULT_SOCIAL_CONFIG.network.signaling_url);
|
|
216
|
+
const signalingUrls = asStringArray(network.signaling_urls, DEFAULT_SOCIAL_CONFIG.network.signaling_urls);
|
|
217
|
+
const mode = asMode(network.mode, DEFAULT_SOCIAL_CONFIG.network.mode);
|
|
218
|
+
return {
|
|
219
|
+
enabled: asBool(root.enabled, DEFAULT_SOCIAL_CONFIG.enabled),
|
|
220
|
+
public_enabled: asBool(root.public_enabled, DEFAULT_SOCIAL_CONFIG.public_enabled),
|
|
221
|
+
identity: {
|
|
222
|
+
display_name: asString(identity.display_name, DEFAULT_SOCIAL_CONFIG.identity.display_name),
|
|
223
|
+
bio: asString(identity.bio, DEFAULT_SOCIAL_CONFIG.identity.bio),
|
|
224
|
+
avatar_url: asString(identity.avatar_url, DEFAULT_SOCIAL_CONFIG.identity.avatar_url),
|
|
225
|
+
tags: asStringArray(identity.tags, DEFAULT_SOCIAL_CONFIG.identity.tags),
|
|
226
|
+
},
|
|
227
|
+
network: {
|
|
228
|
+
mode,
|
|
229
|
+
namespace: asString(network.namespace, DEFAULT_SOCIAL_CONFIG.network.namespace),
|
|
230
|
+
adapter: asAdapter(network.adapter, adapterForMode(mode)),
|
|
231
|
+
port: asNumber(network.port, DEFAULT_SOCIAL_CONFIG.network.port),
|
|
232
|
+
signaling_url: signalingUrl,
|
|
233
|
+
signaling_urls: signalingUrls.length > 0 ? signalingUrls : signalingUrl ? [signalingUrl] : [],
|
|
234
|
+
room: asString(network.room, DEFAULT_SOCIAL_CONFIG.network.room),
|
|
235
|
+
seed_peers: asStringArray(network.seed_peers, DEFAULT_SOCIAL_CONFIG.network.seed_peers),
|
|
236
|
+
bootstrap_hints: asStringArray(network.bootstrap_hints, DEFAULT_SOCIAL_CONFIG.network.bootstrap_hints),
|
|
237
|
+
},
|
|
238
|
+
discovery: {
|
|
239
|
+
discoverable: asBool(discovery.discoverable, DEFAULT_SOCIAL_CONFIG.discovery.discoverable),
|
|
240
|
+
allow_profile_broadcast: asBool(discovery.allow_profile_broadcast, DEFAULT_SOCIAL_CONFIG.discovery.allow_profile_broadcast),
|
|
241
|
+
allow_presence_broadcast: asBool(discovery.allow_presence_broadcast, DEFAULT_SOCIAL_CONFIG.discovery.allow_presence_broadcast),
|
|
242
|
+
},
|
|
243
|
+
visibility: {
|
|
244
|
+
show_display_name: asBool(visibility.show_display_name, DEFAULT_SOCIAL_CONFIG.visibility.show_display_name),
|
|
245
|
+
show_bio: asBool(visibility.show_bio, DEFAULT_SOCIAL_CONFIG.visibility.show_bio),
|
|
246
|
+
show_tags: asBool(visibility.show_tags, DEFAULT_SOCIAL_CONFIG.visibility.show_tags),
|
|
247
|
+
show_agent_id: asBool(visibility.show_agent_id, DEFAULT_SOCIAL_CONFIG.visibility.show_agent_id),
|
|
248
|
+
show_last_seen: asBool(visibility.show_last_seen, DEFAULT_SOCIAL_CONFIG.visibility.show_last_seen),
|
|
249
|
+
show_capabilities_summary: asBool(visibility.show_capabilities_summary, DEFAULT_SOCIAL_CONFIG.visibility.show_capabilities_summary),
|
|
250
|
+
},
|
|
251
|
+
openclaw: {
|
|
252
|
+
bind_existing_identity: asBool(openclaw.bind_existing_identity, DEFAULT_SOCIAL_CONFIG.openclaw.bind_existing_identity),
|
|
253
|
+
use_openclaw_profile_if_available: asBool(openclaw.use_openclaw_profile_if_available, DEFAULT_SOCIAL_CONFIG.openclaw.use_openclaw_profile_if_available),
|
|
254
|
+
},
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
function getDefaultSocialConfig() {
|
|
258
|
+
return JSON.parse(JSON.stringify(DEFAULT_SOCIAL_CONFIG));
|
|
259
|
+
}
|
|
260
|
+
function generateDefaultSocialMdTemplate(options = {}) {
|
|
261
|
+
const displayName = options.display_name?.trim() || "My OpenClaw Agent";
|
|
262
|
+
const bio = options.bio?.trim() || "Local AI agent running on this machine";
|
|
263
|
+
const tags = Array.isArray(options.tags) && options.tags.length > 0 ? options.tags : ["openclaw", "local-first"];
|
|
264
|
+
const mode = options.mode ?? "lan";
|
|
265
|
+
const publicEnabled = typeof options.public_enabled === "boolean" ? options.public_enabled : false;
|
|
266
|
+
return `---
|
|
267
|
+
enabled: true
|
|
268
|
+
public_enabled: ${publicEnabled}
|
|
269
|
+
|
|
270
|
+
identity:
|
|
271
|
+
display_name: ${JSON.stringify(displayName)}
|
|
272
|
+
bio: ${JSON.stringify(bio)}
|
|
273
|
+
tags:
|
|
274
|
+
${tags.map((tag) => ` - ${tag}`).join("\n")}
|
|
275
|
+
|
|
276
|
+
network:
|
|
277
|
+
mode: ${JSON.stringify(mode)}
|
|
278
|
+
|
|
279
|
+
openclaw:
|
|
280
|
+
bind_existing_identity: true
|
|
281
|
+
use_openclaw_profile_if_available: true
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
# social.md
|
|
285
|
+
|
|
286
|
+
This file configures how OpenClaw integrates with SilicaClaw.
|
|
287
|
+
`;
|
|
288
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { AgentIdentity, ProfileInput, PublicProfile } from "./types";
|
|
2
|
+
import { DefaultSocialTemplateOptions, SocialConfig, SocialLoadMeta } from "./socialConfig";
|
|
3
|
+
export type SocialFileLookup = {
|
|
4
|
+
found: boolean;
|
|
5
|
+
source_path: string | null;
|
|
6
|
+
content: string | null;
|
|
7
|
+
};
|
|
8
|
+
export type OpenClawIdentityLookup = {
|
|
9
|
+
identity: AgentIdentity | null;
|
|
10
|
+
source_path: string | null;
|
|
11
|
+
};
|
|
12
|
+
export type OpenClawProfileLookup = {
|
|
13
|
+
profile: Partial<PublicProfile> | null;
|
|
14
|
+
source_path: string | null;
|
|
15
|
+
};
|
|
16
|
+
export type LoadedSocialConfig = {
|
|
17
|
+
config: SocialConfig;
|
|
18
|
+
meta: SocialLoadMeta;
|
|
19
|
+
raw_frontmatter: Record<string, unknown> | null;
|
|
20
|
+
};
|
|
21
|
+
export type ResolvedIdentityResult = {
|
|
22
|
+
identity: AgentIdentity;
|
|
23
|
+
source: "silicaclaw-existing" | "openclaw-existing" | "silicaclaw-generated";
|
|
24
|
+
openclaw_source_path: string | null;
|
|
25
|
+
};
|
|
26
|
+
export declare function getSocialConfigSearchPaths(rootDir?: string, homeDir?: string): string[];
|
|
27
|
+
export declare function findSocialMd(rootDir?: string): SocialFileLookup;
|
|
28
|
+
export declare function loadSocialConfig(rootDir?: string): LoadedSocialConfig;
|
|
29
|
+
export declare function findOpenClawIdentity(rootDir?: string, homeDir?: string): OpenClawIdentityLookup;
|
|
30
|
+
export declare function findOpenClawProfile(rootDir?: string, homeDir?: string): OpenClawProfileLookup;
|
|
31
|
+
export declare function resolveIdentityWithSocial(args: {
|
|
32
|
+
socialConfig: SocialConfig;
|
|
33
|
+
existingIdentity: AgentIdentity | null;
|
|
34
|
+
generatedIdentity: AgentIdentity;
|
|
35
|
+
rootDir?: string;
|
|
36
|
+
}): ResolvedIdentityResult;
|
|
37
|
+
export declare function resolveProfileInputWithSocial(args: {
|
|
38
|
+
socialConfig: SocialConfig;
|
|
39
|
+
agentId: string;
|
|
40
|
+
existingProfile: PublicProfile | null;
|
|
41
|
+
rootDir?: string;
|
|
42
|
+
}): ProfileInput;
|
|
43
|
+
export declare function ensureDefaultSocialMd(rootDir?: string, options?: DefaultSocialTemplateOptions): {
|
|
44
|
+
path: string;
|
|
45
|
+
created: boolean;
|
|
46
|
+
};
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getSocialConfigSearchPaths = getSocialConfigSearchPaths;
|
|
4
|
+
exports.findSocialMd = findSocialMd;
|
|
5
|
+
exports.loadSocialConfig = loadSocialConfig;
|
|
6
|
+
exports.findOpenClawIdentity = findOpenClawIdentity;
|
|
7
|
+
exports.findOpenClawProfile = findOpenClawProfile;
|
|
8
|
+
exports.resolveIdentityWithSocial = resolveIdentityWithSocial;
|
|
9
|
+
exports.resolveProfileInputWithSocial = resolveProfileInputWithSocial;
|
|
10
|
+
exports.ensureDefaultSocialMd = ensureDefaultSocialMd;
|
|
11
|
+
const fs_1 = require("fs");
|
|
12
|
+
const os_1 = require("os");
|
|
13
|
+
const path_1 = require("path");
|
|
14
|
+
const crypto_1 = require("./crypto");
|
|
15
|
+
const socialConfig_1 = require("./socialConfig");
|
|
16
|
+
function getSocialConfigSearchPaths(rootDir = process.cwd(), homeDir = (0, os_1.homedir)()) {
|
|
17
|
+
return [
|
|
18
|
+
(0, path_1.resolve)(rootDir, "social.md"),
|
|
19
|
+
(0, path_1.resolve)(rootDir, ".openclaw", "social.md"),
|
|
20
|
+
(0, path_1.resolve)(homeDir, ".openclaw", "social.md"),
|
|
21
|
+
];
|
|
22
|
+
}
|
|
23
|
+
function findSocialMd(rootDir = process.cwd()) {
|
|
24
|
+
const candidates = getSocialConfigSearchPaths(rootDir);
|
|
25
|
+
for (const path of candidates) {
|
|
26
|
+
if (!(0, fs_1.existsSync)(path))
|
|
27
|
+
continue;
|
|
28
|
+
return {
|
|
29
|
+
found: true,
|
|
30
|
+
source_path: path,
|
|
31
|
+
content: (0, fs_1.readFileSync)(path, "utf8"),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
found: false,
|
|
36
|
+
source_path: null,
|
|
37
|
+
content: null,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function loadSocialConfig(rootDir = process.cwd()) {
|
|
41
|
+
const lookup = findSocialMd(rootDir);
|
|
42
|
+
if (!lookup.found || !lookup.content || !lookup.source_path) {
|
|
43
|
+
return {
|
|
44
|
+
config: (0, socialConfig_1.normalizeSocialConfig)({}),
|
|
45
|
+
meta: {
|
|
46
|
+
found: false,
|
|
47
|
+
source_path: null,
|
|
48
|
+
parse_error: null,
|
|
49
|
+
loaded_at: Date.now(),
|
|
50
|
+
},
|
|
51
|
+
raw_frontmatter: null,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
const frontmatter = (0, socialConfig_1.extractFrontmatter)(lookup.content);
|
|
56
|
+
if (!frontmatter) {
|
|
57
|
+
return {
|
|
58
|
+
config: (0, socialConfig_1.normalizeSocialConfig)({}),
|
|
59
|
+
meta: {
|
|
60
|
+
found: true,
|
|
61
|
+
source_path: lookup.source_path,
|
|
62
|
+
parse_error: "frontmatter_not_found",
|
|
63
|
+
loaded_at: Date.now(),
|
|
64
|
+
},
|
|
65
|
+
raw_frontmatter: null,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
const parsed = (0, socialConfig_1.parseFrontmatterObject)(frontmatter);
|
|
69
|
+
return {
|
|
70
|
+
config: (0, socialConfig_1.normalizeSocialConfig)(parsed),
|
|
71
|
+
meta: {
|
|
72
|
+
found: true,
|
|
73
|
+
source_path: lookup.source_path,
|
|
74
|
+
parse_error: null,
|
|
75
|
+
loaded_at: Date.now(),
|
|
76
|
+
},
|
|
77
|
+
raw_frontmatter: parsed,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
return {
|
|
82
|
+
config: (0, socialConfig_1.normalizeSocialConfig)({}),
|
|
83
|
+
meta: {
|
|
84
|
+
found: true,
|
|
85
|
+
source_path: lookup.source_path,
|
|
86
|
+
parse_error: error instanceof Error ? error.message : "social_parse_failed",
|
|
87
|
+
loaded_at: Date.now(),
|
|
88
|
+
},
|
|
89
|
+
raw_frontmatter: null,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function readJson(path) {
|
|
94
|
+
if (!(0, fs_1.existsSync)(path))
|
|
95
|
+
return null;
|
|
96
|
+
try {
|
|
97
|
+
return JSON.parse((0, fs_1.readFileSync)(path, "utf8"));
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function normalizeIdentity(input) {
|
|
104
|
+
if (typeof input !== "object" || input === null) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
const value = input;
|
|
108
|
+
if (typeof value.public_key !== "string" || typeof value.private_key !== "string") {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
let agentId = typeof value.agent_id === "string" ? value.agent_id : "";
|
|
112
|
+
if (!agentId) {
|
|
113
|
+
try {
|
|
114
|
+
agentId = (0, crypto_1.hashPublicKey)((0, crypto_1.fromBase64)(value.public_key));
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
agent_id: agentId,
|
|
122
|
+
public_key: value.public_key,
|
|
123
|
+
private_key: value.private_key,
|
|
124
|
+
created_at: Number.isFinite(value.created_at) ? Number(value.created_at) : Date.now(),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function findOpenClawIdentity(rootDir = process.cwd(), homeDir = (0, os_1.homedir)()) {
|
|
128
|
+
const candidates = [
|
|
129
|
+
(0, path_1.resolve)(rootDir, ".openclaw", "identity.json"),
|
|
130
|
+
(0, path_1.resolve)(rootDir, "identity.json"),
|
|
131
|
+
(0, path_1.resolve)(homeDir, ".openclaw", "identity.json"),
|
|
132
|
+
];
|
|
133
|
+
for (const path of candidates) {
|
|
134
|
+
const parsed = readJson(path);
|
|
135
|
+
const identity = normalizeIdentity(parsed);
|
|
136
|
+
if (identity) {
|
|
137
|
+
return {
|
|
138
|
+
identity,
|
|
139
|
+
source_path: path,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
identity: null,
|
|
145
|
+
source_path: null,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function findOpenClawProfile(rootDir = process.cwd(), homeDir = (0, os_1.homedir)()) {
|
|
149
|
+
const candidates = [
|
|
150
|
+
(0, path_1.resolve)(rootDir, ".openclaw", "profile.json"),
|
|
151
|
+
(0, path_1.resolve)(rootDir, "profile.json"),
|
|
152
|
+
(0, path_1.resolve)(homeDir, ".openclaw", "profile.json"),
|
|
153
|
+
];
|
|
154
|
+
for (const path of candidates) {
|
|
155
|
+
const parsed = readJson(path);
|
|
156
|
+
if (typeof parsed !== "object" || parsed === null)
|
|
157
|
+
continue;
|
|
158
|
+
const profile = parsed;
|
|
159
|
+
return {
|
|
160
|
+
source_path: path,
|
|
161
|
+
profile: {
|
|
162
|
+
display_name: typeof profile.display_name === "string" ? profile.display_name : "",
|
|
163
|
+
bio: typeof profile.bio === "string" ? profile.bio : "",
|
|
164
|
+
avatar_url: typeof profile.avatar_url === "string" ? profile.avatar_url : "",
|
|
165
|
+
tags: Array.isArray(profile.tags)
|
|
166
|
+
? profile.tags.map((tag) => String(tag).trim()).filter(Boolean)
|
|
167
|
+
: [],
|
|
168
|
+
},
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
return {
|
|
172
|
+
profile: null,
|
|
173
|
+
source_path: null,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
function resolveIdentityWithSocial(args) {
|
|
177
|
+
const { socialConfig, existingIdentity, generatedIdentity } = args;
|
|
178
|
+
if (socialConfig.openclaw.bind_existing_identity) {
|
|
179
|
+
const openclaw = findOpenClawIdentity(args.rootDir ?? process.cwd());
|
|
180
|
+
if (openclaw.identity) {
|
|
181
|
+
return {
|
|
182
|
+
identity: openclaw.identity,
|
|
183
|
+
source: "openclaw-existing",
|
|
184
|
+
openclaw_source_path: openclaw.source_path,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (existingIdentity) {
|
|
189
|
+
return {
|
|
190
|
+
identity: existingIdentity,
|
|
191
|
+
source: "silicaclaw-existing",
|
|
192
|
+
openclaw_source_path: null,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
return {
|
|
196
|
+
identity: generatedIdentity,
|
|
197
|
+
source: "silicaclaw-generated",
|
|
198
|
+
openclaw_source_path: null,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
function resolveProfileInputWithSocial(args) {
|
|
202
|
+
const { socialConfig, agentId, existingProfile } = args;
|
|
203
|
+
const openclawProfile = socialConfig.openclaw.use_openclaw_profile_if_available
|
|
204
|
+
? findOpenClawProfile(args.rootDir ?? process.cwd()).profile
|
|
205
|
+
: null;
|
|
206
|
+
const baseDisplayName = existingProfile?.display_name || "";
|
|
207
|
+
const baseBio = existingProfile?.bio || "";
|
|
208
|
+
const baseAvatarUrl = existingProfile?.avatar_url || "";
|
|
209
|
+
const baseTags = existingProfile?.tags || [];
|
|
210
|
+
// Preserve values saved from local-console first; only fall back to social/openclaw defaults
|
|
211
|
+
// when local profile fields are empty.
|
|
212
|
+
const displayName = baseDisplayName || socialConfig.identity.display_name || openclawProfile?.display_name || "";
|
|
213
|
+
const bio = baseBio || socialConfig.identity.bio || openclawProfile?.bio || "";
|
|
214
|
+
const avatarUrl = baseAvatarUrl || socialConfig.identity.avatar_url || openclawProfile?.avatar_url || "";
|
|
215
|
+
const tags = baseTags.length > 0
|
|
216
|
+
? baseTags
|
|
217
|
+
: socialConfig.identity.tags.length > 0
|
|
218
|
+
? socialConfig.identity.tags
|
|
219
|
+
: openclawProfile?.tags || [];
|
|
220
|
+
return {
|
|
221
|
+
agent_id: agentId,
|
|
222
|
+
display_name: displayName,
|
|
223
|
+
bio,
|
|
224
|
+
avatar_url: avatarUrl,
|
|
225
|
+
tags,
|
|
226
|
+
public_enabled: existingProfile?.public_enabled ?? socialConfig.public_enabled,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function ensureDefaultSocialMd(rootDir = process.cwd(), options = {}) {
|
|
230
|
+
const targetPath = (0, path_1.resolve)(rootDir, "social.md");
|
|
231
|
+
if ((0, fs_1.existsSync)(targetPath)) {
|
|
232
|
+
return { path: targetPath, created: false };
|
|
233
|
+
}
|
|
234
|
+
(0, fs_1.mkdirSync)(rootDir, { recursive: true });
|
|
235
|
+
(0, fs_1.writeFileSync)(targetPath, (0, socialConfig_1.generateDefaultSocialMdTemplate)(options), "utf8");
|
|
236
|
+
return { path: targetPath, created: true };
|
|
237
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateSocialMdTemplate = generateSocialMdTemplate;
|
|
4
|
+
function asBool(value, fallback) {
|
|
5
|
+
return typeof value === "boolean" ? value : fallback;
|
|
6
|
+
}
|
|
7
|
+
function asString(value, fallback) {
|
|
8
|
+
return typeof value === "string" ? value : fallback;
|
|
9
|
+
}
|
|
10
|
+
function asStringArray(value, fallback) {
|
|
11
|
+
if (!Array.isArray(value))
|
|
12
|
+
return fallback;
|
|
13
|
+
return value.map((item) => String(item).trim()).filter(Boolean);
|
|
14
|
+
}
|
|
15
|
+
function yamlString(input) {
|
|
16
|
+
return JSON.stringify(input ?? "");
|
|
17
|
+
}
|
|
18
|
+
function yamlStringList(values, indent = " ") {
|
|
19
|
+
if (!values.length) {
|
|
20
|
+
return `${indent}[]`;
|
|
21
|
+
}
|
|
22
|
+
return values.map((value) => `${indent}- ${yamlString(value)}`).join("\n");
|
|
23
|
+
}
|
|
24
|
+
function generateSocialMdTemplate(runtimeConfig) {
|
|
25
|
+
const enabled = asBool(runtimeConfig?.enabled, true);
|
|
26
|
+
const publicEnabled = asBool(runtimeConfig?.public_enabled, false);
|
|
27
|
+
const profile = runtimeConfig?.resolved_profile ?? null;
|
|
28
|
+
const network = runtimeConfig?.resolved_network ?? null;
|
|
29
|
+
const discovery = runtimeConfig?.resolved_discovery ?? null;
|
|
30
|
+
const visibility = runtimeConfig?.visibility ?? null;
|
|
31
|
+
const openclaw = runtimeConfig?.openclaw ?? null;
|
|
32
|
+
const displayName = asString(profile?.display_name, "");
|
|
33
|
+
const bio = asString(profile?.bio, "");
|
|
34
|
+
const tags = asStringArray(profile?.tags, ["openclaw", "local-first"]);
|
|
35
|
+
const mode = network?.mode === "local" || network?.mode === "lan" || network?.mode === "global-preview"
|
|
36
|
+
? network.mode
|
|
37
|
+
: "lan";
|
|
38
|
+
const discoverable = asBool(discovery?.discoverable, true);
|
|
39
|
+
const allowProfileBroadcast = asBool(discovery?.allow_profile_broadcast, true);
|
|
40
|
+
const allowPresenceBroadcast = asBool(discovery?.allow_presence_broadcast, true);
|
|
41
|
+
const showDisplayName = asBool(visibility?.show_display_name, true);
|
|
42
|
+
const showBio = asBool(visibility?.show_bio, true);
|
|
43
|
+
const showTags = asBool(visibility?.show_tags, true);
|
|
44
|
+
const showAgentId = asBool(visibility?.show_agent_id, true);
|
|
45
|
+
const showLastSeen = asBool(visibility?.show_last_seen, true);
|
|
46
|
+
const showCapabilitiesSummary = asBool(visibility?.show_capabilities_summary, true);
|
|
47
|
+
const bindExistingIdentity = asBool(openclaw?.bind_existing_identity, true);
|
|
48
|
+
const useOpenClawProfile = asBool(openclaw?.use_openclaw_profile_if_available, true);
|
|
49
|
+
return `---
|
|
50
|
+
enabled: ${enabled}
|
|
51
|
+
public_enabled: ${publicEnabled}
|
|
52
|
+
|
|
53
|
+
identity:
|
|
54
|
+
display_name: ${yamlString(displayName)}
|
|
55
|
+
bio: ${yamlString(bio)}
|
|
56
|
+
tags:
|
|
57
|
+
${yamlStringList(tags.map((tag) => asString(tag, "")), " ")}
|
|
58
|
+
|
|
59
|
+
network:
|
|
60
|
+
mode: ${yamlString(mode)}
|
|
61
|
+
|
|
62
|
+
discovery:
|
|
63
|
+
discoverable: ${discoverable}
|
|
64
|
+
allow_profile_broadcast: ${allowProfileBroadcast}
|
|
65
|
+
allow_presence_broadcast: ${allowPresenceBroadcast}
|
|
66
|
+
|
|
67
|
+
visibility:
|
|
68
|
+
show_display_name: ${showDisplayName}
|
|
69
|
+
show_bio: ${showBio}
|
|
70
|
+
show_tags: ${showTags}
|
|
71
|
+
show_agent_id: ${showAgentId}
|
|
72
|
+
show_last_seen: ${showLastSeen}
|
|
73
|
+
show_capabilities_summary: ${showCapabilitiesSummary}
|
|
74
|
+
|
|
75
|
+
openclaw:
|
|
76
|
+
bind_existing_identity: ${bindExistingIdentity}
|
|
77
|
+
use_openclaw_profile_if_available: ${useOpenClawProfile}
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
# Social
|
|
81
|
+
|
|
82
|
+
Generated from current SilicaClaw runtime state.
|
|
83
|
+
|
|
84
|
+
- Save as \`social.md\` in your OpenClaw workspace.
|
|
85
|
+
- This export does not auto-overwrite any existing file.
|
|
86
|
+
- Advanced network fields are intentionally hidden in template and resolved in runtime.
|
|
87
|
+
`;
|
|
88
|
+
}
|