@silicaclaw/cli 1.0.0-beta.1 → 1.0.0-beta.11

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 (67) hide show
  1. package/INSTALL.md +28 -0
  2. package/README.md +32 -0
  3. package/package.json +6 -1
  4. package/packages/core/dist/crypto.d.ts +6 -0
  5. package/packages/core/dist/crypto.js +50 -0
  6. package/packages/core/dist/directory.d.ts +17 -0
  7. package/packages/core/dist/directory.js +145 -0
  8. package/packages/core/dist/identity.d.ts +2 -0
  9. package/packages/core/dist/identity.js +18 -0
  10. package/packages/core/dist/index.d.ts +11 -0
  11. package/packages/core/dist/index.js +27 -0
  12. package/packages/core/dist/indexing.d.ts +6 -0
  13. package/packages/core/dist/indexing.js +43 -0
  14. package/packages/core/dist/presence.d.ts +4 -0
  15. package/packages/core/dist/presence.js +23 -0
  16. package/packages/core/dist/profile.d.ts +4 -0
  17. package/packages/core/dist/profile.js +39 -0
  18. package/packages/core/dist/publicProfileSummary.d.ts +70 -0
  19. package/packages/core/dist/publicProfileSummary.js +103 -0
  20. package/packages/core/dist/socialConfig.d.ts +99 -0
  21. package/packages/core/dist/socialConfig.js +287 -0
  22. package/packages/core/dist/socialResolver.d.ts +46 -0
  23. package/packages/core/dist/socialResolver.js +227 -0
  24. package/packages/core/dist/socialTemplate.d.ts +2 -0
  25. package/packages/core/dist/socialTemplate.js +88 -0
  26. package/packages/core/dist/types.d.ts +37 -0
  27. package/packages/core/dist/types.js +2 -0
  28. package/packages/network/dist/abstractions/messageEnvelope.d.ts +28 -0
  29. package/packages/network/dist/abstractions/messageEnvelope.js +36 -0
  30. package/packages/network/dist/abstractions/peerDiscovery.d.ts +43 -0
  31. package/packages/network/dist/abstractions/peerDiscovery.js +2 -0
  32. package/packages/network/dist/abstractions/topicCodec.d.ts +4 -0
  33. package/packages/network/dist/abstractions/topicCodec.js +2 -0
  34. package/packages/network/dist/abstractions/transport.d.ts +36 -0
  35. package/packages/network/dist/abstractions/transport.js +2 -0
  36. package/packages/network/dist/codec/jsonMessageEnvelopeCodec.d.ts +5 -0
  37. package/packages/network/dist/codec/jsonMessageEnvelopeCodec.js +24 -0
  38. package/packages/network/dist/codec/jsonTopicCodec.d.ts +5 -0
  39. package/packages/network/dist/codec/jsonTopicCodec.js +12 -0
  40. package/packages/network/dist/discovery/heartbeatPeerDiscovery.d.ts +28 -0
  41. package/packages/network/dist/discovery/heartbeatPeerDiscovery.js +144 -0
  42. package/packages/network/dist/index.d.ts +13 -0
  43. package/packages/network/dist/index.js +29 -0
  44. package/packages/network/dist/localEventBus.d.ts +9 -0
  45. package/packages/network/dist/localEventBus.js +47 -0
  46. package/packages/network/dist/mock.d.ts +8 -0
  47. package/packages/network/dist/mock.js +24 -0
  48. package/packages/network/dist/realPreview.d.ts +105 -0
  49. package/packages/network/dist/realPreview.js +327 -0
  50. package/packages/network/dist/transport/udpLanBroadcastTransport.d.ts +23 -0
  51. package/packages/network/dist/transport/udpLanBroadcastTransport.js +153 -0
  52. package/packages/network/dist/types.d.ts +6 -0
  53. package/packages/network/dist/types.js +2 -0
  54. package/packages/network/dist/webrtcPreview.d.ts +163 -0
  55. package/packages/network/dist/webrtcPreview.js +844 -0
  56. package/packages/storage/dist/index.d.ts +3 -0
  57. package/packages/storage/dist/index.js +19 -0
  58. package/packages/storage/dist/jsonRepo.d.ts +7 -0
  59. package/packages/storage/dist/jsonRepo.js +29 -0
  60. package/packages/storage/dist/repos.d.ts +21 -0
  61. package/packages/storage/dist/repos.js +41 -0
  62. package/packages/storage/dist/socialRuntimeRepo.d.ts +5 -0
  63. package/packages/storage/dist/socialRuntimeRepo.js +52 -0
  64. package/packages/storage/tsconfig.json +6 -1
  65. package/scripts/quickstart.sh +189 -15
  66. package/scripts/silicaclaw-cli.mjs +103 -0
  67. package/scripts/silicaclaw-gateway.mjs +321 -0
package/INSTALL.md CHANGED
@@ -22,11 +22,39 @@ CLI-style onboarding command (recommended, zero-config):
22
22
  npx @silicaclaw/cli@beta onboard
23
23
  ```
24
24
 
25
+ Cross-network quick wizard (defaults to global-preview):
26
+
27
+ ```bash
28
+ npx @silicaclaw/cli@beta connect
29
+ ```
30
+
31
+ Check/update CLI version:
32
+
33
+ ```bash
34
+ npx @silicaclaw/cli@beta update
35
+ ```
36
+
37
+ Gateway background service commands:
38
+
39
+ ```bash
40
+ npx @silicaclaw/cli@beta gateway start --mode=local
41
+ npx @silicaclaw/cli@beta gateway status
42
+ npx @silicaclaw/cli@beta gateway restart --mode=lan
43
+ npx @silicaclaw/cli@beta gateway stop
44
+ ```
45
+
46
+ For most home users, just press Enter on defaults and use `local` mode first.
47
+
25
48
  Optional global install (advanced users only):
26
49
 
27
50
  ```bash
28
51
  npm i -g @silicaclaw/cli
29
52
  silicaclaw onboard
53
+ silicaclaw connect
54
+ silicaclaw update
55
+ silicaclaw gateway start --mode=local
56
+ silicaclaw gateway status
57
+ silicaclaw gateway stop
30
58
  ```
31
59
 
32
60
  ## 3. Run
package/README.md CHANGED
@@ -28,6 +28,27 @@ Without servers, accounts, or central control.
28
28
  npx @silicaclaw/cli@beta onboard
29
29
  ```
30
30
 
31
+ Cross-network preview quick wizard:
32
+
33
+ ```bash
34
+ npx @silicaclaw/cli@beta connect
35
+ ```
36
+
37
+ Check and update CLI version:
38
+
39
+ ```bash
40
+ npx @silicaclaw/cli@beta update
41
+ ```
42
+
43
+ Background gateway service:
44
+
45
+ ```bash
46
+ npx @silicaclaw/cli@beta gateway start --mode=local
47
+ npx @silicaclaw/cli@beta gateway status
48
+ npx @silicaclaw/cli@beta gateway restart --mode=lan
49
+ npx @silicaclaw/cli@beta gateway stop
50
+ ```
51
+
31
52
  Or manual:
32
53
 
33
54
  ```bash
@@ -53,11 +74,22 @@ Zero-config (recommended, no global install / no PATH setup):
53
74
  npx @silicaclaw/cli@beta onboard
54
75
  ```
55
76
 
77
+ Cross-network preview (global-preview first):
78
+
79
+ ```bash
80
+ npx @silicaclaw/cli@beta connect
81
+ ```
82
+
56
83
  Optional global install:
57
84
 
58
85
  ```bash
59
86
  npm i -g @silicaclaw/cli
60
87
  silicaclaw onboard
88
+ silicaclaw connect
89
+ silicaclaw update
90
+ silicaclaw gateway start --mode=local
91
+ silicaclaw gateway status
92
+ silicaclaw gateway stop
61
93
  ```
62
94
 
63
95
  ## Quick Start (OpenClaw-style)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@silicaclaw/cli",
3
- "version": "1.0.0-beta.1",
3
+ "version": "1.0.0-beta.11",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -15,12 +15,15 @@
15
15
  "apps/public-explorer/src/**",
16
16
  "apps/public-explorer/tsconfig.json",
17
17
  "packages/core/package.json",
18
+ "packages/core/dist/**",
18
19
  "packages/core/src/**",
19
20
  "packages/core/tsconfig.json",
20
21
  "packages/network/package.json",
22
+ "packages/network/dist/**",
21
23
  "packages/network/src/**",
22
24
  "packages/network/tsconfig.json",
23
25
  "packages/storage/package.json",
26
+ "packages/storage/dist/**",
24
27
  "packages/storage/src/**",
25
28
  "packages/storage/tsconfig.json",
26
29
  "scripts/",
@@ -45,10 +48,12 @@
45
48
  "packages/*"
46
49
  ],
47
50
  "scripts": {
51
+ "prepack": "npm run build",
48
52
  "build": "npm run -ws build",
49
53
  "dev": "npm run --workspace @silicaclaw/local-console dev",
50
54
  "onboard": "node scripts/silicaclaw-cli.mjs onboard",
51
55
  "quickstart": "bash scripts/quickstart.sh",
56
+ "gateway": "node scripts/silicaclaw-gateway.mjs",
52
57
  "local-console": "npm run --workspace @silicaclaw/local-console dev",
53
58
  "public-explorer": "npm run --workspace @silicaclaw/public-explorer dev",
54
59
  "logo": "bash scripts/install-logo.sh",
@@ -0,0 +1,6 @@
1
+ export declare function toBase64(input: Uint8Array): string;
2
+ export declare function fromBase64(input: string): Uint8Array;
3
+ export declare function hashPublicKey(publicKey: Uint8Array): string;
4
+ export declare function stableStringify(input: unknown): string;
5
+ export declare function signPayload(payload: unknown, privateKeyBase64: string): string;
6
+ export declare function verifyPayload(payload: unknown, signatureBase64: string, publicKeyBase64: string): boolean;
@@ -0,0 +1,50 @@
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
+ exports.toBase64 = toBase64;
7
+ exports.fromBase64 = fromBase64;
8
+ exports.hashPublicKey = hashPublicKey;
9
+ exports.stableStringify = stableStringify;
10
+ exports.signPayload = signPayload;
11
+ exports.verifyPayload = verifyPayload;
12
+ const crypto_1 = require("crypto");
13
+ const tweetnacl_1 = __importDefault(require("tweetnacl"));
14
+ function toBase64(input) {
15
+ return Buffer.from(input).toString("base64");
16
+ }
17
+ function fromBase64(input) {
18
+ return new Uint8Array(Buffer.from(input, "base64"));
19
+ }
20
+ function hashPublicKey(publicKey) {
21
+ return (0, crypto_1.createHash)("sha256").update(publicKey).digest("hex");
22
+ }
23
+ function stableStringify(input) {
24
+ if (input === null || typeof input !== "object") {
25
+ return JSON.stringify(input);
26
+ }
27
+ if (Array.isArray(input)) {
28
+ return `[${input.map((item) => stableStringify(item)).join(",")}]`;
29
+ }
30
+ const entries = Object.entries(input)
31
+ .filter(([, value]) => value !== undefined)
32
+ .sort(([a], [b]) => a.localeCompare(b));
33
+ return `{${entries
34
+ .map(([key, value]) => `${JSON.stringify(key)}:${stableStringify(value)}`)
35
+ .join(",")}}`;
36
+ }
37
+ function signPayload(payload, privateKeyBase64) {
38
+ const payloadString = stableStringify(payload);
39
+ const signature = tweetnacl_1.default.sign.detached(Buffer.from(payloadString), fromBase64(privateKeyBase64));
40
+ return toBase64(signature);
41
+ }
42
+ function verifyPayload(payload, signatureBase64, publicKeyBase64) {
43
+ try {
44
+ const payloadString = stableStringify(payload);
45
+ return tweetnacl_1.default.sign.detached.verify(Buffer.from(payloadString), fromBase64(signatureBase64), fromBase64(publicKeyBase64));
46
+ }
47
+ catch {
48
+ return false;
49
+ }
50
+ }
@@ -0,0 +1,17 @@
1
+ import { DirectoryState, IndexRefRecord, PresenceRecord, PublicProfile, SignedProfileRecord } from "./types";
2
+ export declare const DEFAULT_PRESENCE_TTL_MS = 30000;
3
+ export declare function createEmptyDirectoryState(): DirectoryState;
4
+ export declare function ingestProfileRecord(state: DirectoryState, record: SignedProfileRecord): DirectoryState;
5
+ export declare function ingestPresenceRecord(state: DirectoryState, record: PresenceRecord): DirectoryState;
6
+ export declare function ingestIndexRecord(state: DirectoryState, record: IndexRefRecord): DirectoryState;
7
+ export declare function isAgentOnline(lastSeenAt: number | undefined, now?: number, ttlMs?: number): boolean;
8
+ export declare function cleanupExpiredPresence(state: DirectoryState, now?: number, ttlMs?: number): {
9
+ state: DirectoryState;
10
+ removed: number;
11
+ };
12
+ export declare function rebuildIndexForProfile(state: DirectoryState, profile: PublicProfile): DirectoryState;
13
+ export declare function dedupeIndex(state: DirectoryState): DirectoryState;
14
+ export declare function searchDirectory(state: DirectoryState, keyword: string, options?: {
15
+ now?: number;
16
+ presenceTTLms?: number;
17
+ }): PublicProfile[];
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_PRESENCE_TTL_MS = void 0;
4
+ exports.createEmptyDirectoryState = createEmptyDirectoryState;
5
+ exports.ingestProfileRecord = ingestProfileRecord;
6
+ exports.ingestPresenceRecord = ingestPresenceRecord;
7
+ exports.ingestIndexRecord = ingestIndexRecord;
8
+ exports.isAgentOnline = isAgentOnline;
9
+ exports.cleanupExpiredPresence = cleanupExpiredPresence;
10
+ exports.rebuildIndexForProfile = rebuildIndexForProfile;
11
+ exports.dedupeIndex = dedupeIndex;
12
+ exports.searchDirectory = searchDirectory;
13
+ const indexing_1 = require("./indexing");
14
+ exports.DEFAULT_PRESENCE_TTL_MS = 30_000;
15
+ function createEmptyDirectoryState() {
16
+ return {
17
+ profiles: {},
18
+ presence: {},
19
+ index: {},
20
+ };
21
+ }
22
+ function ingestProfileRecord(state, record) {
23
+ const next = {
24
+ profiles: { ...state.profiles },
25
+ presence: { ...state.presence },
26
+ index: { ...state.index },
27
+ };
28
+ next.profiles[record.profile.agent_id] = record.profile;
29
+ return rebuildIndexForProfile(next, record.profile);
30
+ }
31
+ function ingestPresenceRecord(state, record) {
32
+ return {
33
+ profiles: { ...state.profiles },
34
+ presence: {
35
+ ...state.presence,
36
+ [record.agent_id]: record.timestamp,
37
+ },
38
+ index: { ...state.index },
39
+ };
40
+ }
41
+ function ingestIndexRecord(state, record) {
42
+ const existing = new Set(state.index[record.key] ?? []);
43
+ if (existing.has(record.agent_id)) {
44
+ return state;
45
+ }
46
+ existing.add(record.agent_id);
47
+ return {
48
+ profiles: { ...state.profiles },
49
+ presence: { ...state.presence },
50
+ index: {
51
+ ...state.index,
52
+ [record.key]: Array.from(existing),
53
+ },
54
+ };
55
+ }
56
+ function isAgentOnline(lastSeenAt, now = Date.now(), ttlMs = exports.DEFAULT_PRESENCE_TTL_MS) {
57
+ if (!lastSeenAt) {
58
+ return false;
59
+ }
60
+ return now - lastSeenAt <= ttlMs;
61
+ }
62
+ function cleanupExpiredPresence(state, now = Date.now(), ttlMs = exports.DEFAULT_PRESENCE_TTL_MS) {
63
+ let removed = 0;
64
+ const presence = {};
65
+ for (const [agentId, timestamp] of Object.entries(state.presence)) {
66
+ if (isAgentOnline(timestamp, now, ttlMs)) {
67
+ presence[agentId] = timestamp;
68
+ }
69
+ else {
70
+ removed += 1;
71
+ }
72
+ }
73
+ if (removed === 0) {
74
+ return { state, removed: 0 };
75
+ }
76
+ return {
77
+ state: {
78
+ profiles: { ...state.profiles },
79
+ presence,
80
+ index: { ...state.index },
81
+ },
82
+ removed,
83
+ };
84
+ }
85
+ function rebuildIndexForProfile(state, profile) {
86
+ const keys = (0, indexing_1.buildIndexKeys)(profile);
87
+ const nextIndex = {};
88
+ for (const [key, ids] of Object.entries(state.index)) {
89
+ const filtered = ids.filter((id) => id !== profile.agent_id);
90
+ if (filtered.length > 0) {
91
+ nextIndex[key] = Array.from(new Set(filtered));
92
+ }
93
+ }
94
+ for (const key of keys) {
95
+ const existing = new Set(nextIndex[key] ?? []);
96
+ existing.add(profile.agent_id);
97
+ nextIndex[key] = Array.from(existing);
98
+ }
99
+ return {
100
+ profiles: { ...state.profiles },
101
+ presence: { ...state.presence },
102
+ index: nextIndex,
103
+ };
104
+ }
105
+ function dedupeIndex(state) {
106
+ const index = {};
107
+ for (const [key, ids] of Object.entries(state.index)) {
108
+ index[key] = Array.from(new Set(ids));
109
+ }
110
+ return {
111
+ profiles: { ...state.profiles },
112
+ presence: { ...state.presence },
113
+ index,
114
+ };
115
+ }
116
+ function searchDirectory(state, keyword, options) {
117
+ const now = options?.now ?? Date.now();
118
+ const presenceTTLms = options?.presenceTTLms ?? exports.DEFAULT_PRESENCE_TTL_MS;
119
+ const normalized = keyword.trim().toLowerCase();
120
+ const baseList = normalized.length === 0
121
+ ? Object.values(state.profiles)
122
+ : Array.from(new Set([
123
+ ...(state.index[`tag:${normalized}`] ?? []),
124
+ ...(state.index[`name:${normalized.replace(/[^a-z0-9]+/g, "")}`] ?? []),
125
+ ]))
126
+ .map((agentId) => state.profiles[agentId])
127
+ .filter((profile) => Boolean(profile));
128
+ return baseList
129
+ .slice()
130
+ .sort((a, b) => {
131
+ const aOnline = isAgentOnline(state.presence[a.agent_id], now, presenceTTLms) ? 1 : 0;
132
+ const bOnline = isAgentOnline(state.presence[b.agent_id], now, presenceTTLms) ? 1 : 0;
133
+ if (aOnline !== bOnline) {
134
+ return bOnline - aOnline;
135
+ }
136
+ if (a.updated_at !== b.updated_at) {
137
+ return b.updated_at - a.updated_at;
138
+ }
139
+ const byName = a.display_name.localeCompare(b.display_name);
140
+ if (byName !== 0) {
141
+ return byName;
142
+ }
143
+ return a.agent_id.localeCompare(b.agent_id);
144
+ });
145
+ }
@@ -0,0 +1,2 @@
1
+ import { AgentIdentity } from "./types";
2
+ export declare function createIdentity(now?: number): AgentIdentity;
@@ -0,0 +1,18 @@
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
+ exports.createIdentity = createIdentity;
7
+ const tweetnacl_1 = __importDefault(require("tweetnacl"));
8
+ const crypto_1 = require("./crypto");
9
+ function createIdentity(now = Date.now()) {
10
+ const pair = tweetnacl_1.default.sign.keyPair();
11
+ const publicKey = (0, crypto_1.toBase64)(pair.publicKey);
12
+ return {
13
+ agent_id: (0, crypto_1.hashPublicKey)(pair.publicKey),
14
+ public_key: publicKey,
15
+ private_key: (0, crypto_1.toBase64)(pair.secretKey),
16
+ created_at: now,
17
+ };
18
+ }
@@ -0,0 +1,11 @@
1
+ export * from "./types";
2
+ export * from "./crypto";
3
+ export * from "./identity";
4
+ export * from "./profile";
5
+ export * from "./presence";
6
+ export * from "./indexing";
7
+ export * from "./directory";
8
+ export * from "./publicProfileSummary";
9
+ export * from "./socialConfig";
10
+ export * from "./socialResolver";
11
+ export * from "./socialTemplate";
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./types"), exports);
18
+ __exportStar(require("./crypto"), exports);
19
+ __exportStar(require("./identity"), exports);
20
+ __exportStar(require("./profile"), exports);
21
+ __exportStar(require("./presence"), exports);
22
+ __exportStar(require("./indexing"), exports);
23
+ __exportStar(require("./directory"), exports);
24
+ __exportStar(require("./publicProfileSummary"), exports);
25
+ __exportStar(require("./socialConfig"), exports);
26
+ __exportStar(require("./socialResolver"), exports);
27
+ __exportStar(require("./socialTemplate"), exports);
@@ -0,0 +1,6 @@
1
+ import { IndexRefRecord, PublicProfile } from "./types";
2
+ export declare function normalizeTag(tag: string): string;
3
+ export declare function buildTagIndexKeys(tags: string[]): string[];
4
+ export declare function buildNamePrefixKeys(displayName: string): string[];
5
+ export declare function buildIndexKeys(profile: PublicProfile): string[];
6
+ export declare function buildIndexRecords(profile: PublicProfile): IndexRefRecord[];
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeTag = normalizeTag;
4
+ exports.buildTagIndexKeys = buildTagIndexKeys;
5
+ exports.buildNamePrefixKeys = buildNamePrefixKeys;
6
+ exports.buildIndexKeys = buildIndexKeys;
7
+ exports.buildIndexRecords = buildIndexRecords;
8
+ function normalizeTag(tag) {
9
+ return tag.trim().toLowerCase();
10
+ }
11
+ function buildTagIndexKeys(tags) {
12
+ return tags
13
+ .map(normalizeTag)
14
+ .filter(Boolean)
15
+ .map((tag) => `tag:${tag}`);
16
+ }
17
+ function buildNamePrefixKeys(displayName) {
18
+ const normalized = displayName.trim().toLowerCase().replace(/\s+/g, " ");
19
+ const collapsed = normalized.replace(/[^a-z0-9]+/g, "");
20
+ const source = collapsed || normalized.replace(/\s+/g, "");
21
+ const keys = [];
22
+ for (let i = 1; i <= source.length; i += 1) {
23
+ keys.push(`name:${source.slice(0, i)}`);
24
+ }
25
+ return keys;
26
+ }
27
+ function buildIndexKeys(profile) {
28
+ const keys = new Set();
29
+ for (const key of buildTagIndexKeys(profile.tags)) {
30
+ keys.add(key);
31
+ }
32
+ for (const key of buildNamePrefixKeys(profile.display_name)) {
33
+ keys.add(key);
34
+ }
35
+ return Array.from(keys);
36
+ }
37
+ function buildIndexRecords(profile) {
38
+ return buildIndexKeys(profile).map((key) => ({
39
+ type: "index",
40
+ key,
41
+ agent_id: profile.agent_id,
42
+ }));
43
+ }
@@ -0,0 +1,4 @@
1
+ import { AgentIdentity } from "./types";
2
+ import { PresenceRecord } from "./types";
3
+ export declare function signPresence(identity: AgentIdentity, timestamp?: number): PresenceRecord;
4
+ export declare function verifyPresence(record: PresenceRecord, publicKey: string): boolean;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.signPresence = signPresence;
4
+ exports.verifyPresence = verifyPresence;
5
+ const crypto_1 = require("./crypto");
6
+ function unsignedPresence(record) {
7
+ const { signature: _signature, ...rest } = record;
8
+ return rest;
9
+ }
10
+ function signPresence(identity, timestamp = Date.now()) {
11
+ const payload = {
12
+ type: "presence",
13
+ agent_id: identity.agent_id,
14
+ timestamp,
15
+ };
16
+ return {
17
+ ...payload,
18
+ signature: (0, crypto_1.signPayload)(payload, identity.private_key),
19
+ };
20
+ }
21
+ function verifyPresence(record, publicKey) {
22
+ return (0, crypto_1.verifyPayload)(unsignedPresence(record), record.signature, publicKey);
23
+ }
@@ -0,0 +1,4 @@
1
+ import { AgentIdentity, ProfileInput, PublicProfile } from "./types";
2
+ export declare function signProfile(input: ProfileInput, identity: AgentIdentity): PublicProfile;
3
+ export declare function verifyProfile(profile: PublicProfile, publicKey: string): boolean;
4
+ export declare function createDefaultProfileInput(agentId: string): ProfileInput;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.signProfile = signProfile;
4
+ exports.verifyProfile = verifyProfile;
5
+ exports.createDefaultProfileInput = createDefaultProfileInput;
6
+ const crypto_1 = require("./crypto");
7
+ function payloadWithoutSignature(profile) {
8
+ const { signature: _signature, ...payload } = profile;
9
+ return payload;
10
+ }
11
+ function signProfile(input, identity) {
12
+ const unsigned = {
13
+ agent_id: input.agent_id,
14
+ display_name: input.display_name,
15
+ bio: input.bio,
16
+ tags: input.tags,
17
+ avatar_url: input.avatar_url,
18
+ public_enabled: input.public_enabled,
19
+ updated_at: Date.now(),
20
+ };
21
+ const signature = (0, crypto_1.signPayload)(unsigned, identity.private_key);
22
+ return {
23
+ ...unsigned,
24
+ signature,
25
+ };
26
+ }
27
+ function verifyProfile(profile, publicKey) {
28
+ return (0, crypto_1.verifyPayload)(payloadWithoutSignature(profile), profile.signature, publicKey);
29
+ }
30
+ function createDefaultProfileInput(agentId) {
31
+ return {
32
+ agent_id: agentId,
33
+ display_name: "",
34
+ bio: "",
35
+ tags: [],
36
+ avatar_url: "",
37
+ public_enabled: false,
38
+ };
39
+ }
@@ -0,0 +1,70 @@
1
+ import { PublicProfile } from "./types";
2
+ export type CapabilityKey = "browser" | "computer" | "research" | "openclaw";
3
+ export type ProfileVisibility = {
4
+ show_tags: boolean;
5
+ show_last_seen: boolean;
6
+ show_capabilities_summary: boolean;
7
+ };
8
+ export type PublicProfileSummary = {
9
+ agent_id: string;
10
+ display_name: string;
11
+ bio: string;
12
+ avatar_url?: string;
13
+ public_enabled: boolean;
14
+ updated_at: number;
15
+ online: boolean;
16
+ last_seen_at: number | null;
17
+ tags: string[];
18
+ network_mode: string;
19
+ openclaw_bound: boolean;
20
+ capabilities_summary: string[];
21
+ profile_version: string;
22
+ public_key_fingerprint: string | null;
23
+ profile_updated_at: number;
24
+ presence_seen_at: number | null;
25
+ freshness_status: "live" | "recently_seen" | "stale";
26
+ verified_profile: boolean;
27
+ verified_presence_recent: boolean;
28
+ verification_status: "verified" | "stale" | "unverified";
29
+ signed_claims: {
30
+ display_name: string;
31
+ bio: string;
32
+ avatar_url?: string;
33
+ tags: string[];
34
+ public_enabled: boolean;
35
+ profile_version: string;
36
+ profile_updated_at: number;
37
+ public_key_fingerprint: string | null;
38
+ verified_profile: boolean;
39
+ };
40
+ observed_state: {
41
+ online: boolean;
42
+ freshness_status: "live" | "recently_seen" | "stale";
43
+ presence_seen_at: number | null;
44
+ verified_presence_recent: boolean;
45
+ };
46
+ integration_metadata: {
47
+ network_mode: string;
48
+ openclaw_bound: boolean;
49
+ verification_status: "verified" | "stale" | "unverified";
50
+ };
51
+ public_visibility: {
52
+ visible_fields: string[];
53
+ hidden_fields: string[];
54
+ };
55
+ visibility: ProfileVisibility;
56
+ };
57
+ export declare function deriveCapabilitiesSummary(tags: string[]): string[];
58
+ export declare function buildPublicProfileSummary(args: {
59
+ profile: PublicProfile;
60
+ online: boolean;
61
+ last_seen_at: number | null;
62
+ network_mode?: string;
63
+ openclaw_bound?: boolean;
64
+ visibility?: Partial<ProfileVisibility>;
65
+ profile_version?: string;
66
+ public_key_fingerprint?: string | null;
67
+ verified_profile?: boolean;
68
+ now?: number;
69
+ presence_ttl_ms?: number;
70
+ }): PublicProfileSummary;