society-protocol 1.1.0 → 1.3.0

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 (69) hide show
  1. package/dist/benchmark/collector.d.ts +17 -0
  2. package/dist/benchmark/collector.d.ts.map +1 -0
  3. package/dist/benchmark/collector.js +36 -0
  4. package/dist/benchmark/collector.js.map +1 -0
  5. package/dist/benchmark/reporter.d.ts +17 -0
  6. package/dist/benchmark/reporter.d.ts.map +1 -0
  7. package/dist/benchmark/reporter.js +140 -0
  8. package/dist/benchmark/reporter.js.map +1 -0
  9. package/dist/benchmark/types.d.ts +63 -0
  10. package/dist/benchmark/types.d.ts.map +1 -0
  11. package/dist/benchmark/types.js +6 -0
  12. package/dist/benchmark/types.js.map +1 -0
  13. package/dist/bootstrap.d.ts +8 -3
  14. package/dist/bootstrap.d.ts.map +1 -1
  15. package/dist/bootstrap.js +52 -9
  16. package/dist/bootstrap.js.map +1 -1
  17. package/dist/content-store.d.ts +77 -0
  18. package/dist/content-store.d.ts.map +1 -0
  19. package/dist/content-store.js +178 -0
  20. package/dist/content-store.js.map +1 -0
  21. package/dist/identity-proof.d.ts +43 -0
  22. package/dist/identity-proof.d.ts.map +1 -0
  23. package/dist/identity-proof.js +98 -0
  24. package/dist/identity-proof.js.map +1 -0
  25. package/dist/index.js +174 -39
  26. package/dist/index.js.map +1 -1
  27. package/dist/knowledge.d.ts +100 -1
  28. package/dist/knowledge.d.ts.map +1 -1
  29. package/dist/knowledge.js +437 -2
  30. package/dist/knowledge.js.map +1 -1
  31. package/dist/lib.d.ts +8 -2
  32. package/dist/lib.d.ts.map +1 -1
  33. package/dist/lib.js +6 -1
  34. package/dist/lib.js.map +1 -1
  35. package/dist/p2p.d.ts +25 -0
  36. package/dist/p2p.d.ts.map +1 -1
  37. package/dist/p2p.js +159 -69
  38. package/dist/p2p.js.map +1 -1
  39. package/dist/persona/types.d.ts +1 -1
  40. package/dist/persona/types.d.ts.map +1 -1
  41. package/dist/persona/zkp/engine.d.ts.map +1 -1
  42. package/dist/persona/zkp/engine.js +8 -0
  43. package/dist/persona/zkp/engine.js.map +1 -1
  44. package/dist/planner.d.ts +1 -0
  45. package/dist/planner.d.ts.map +1 -1
  46. package/dist/planner.js +26 -4
  47. package/dist/planner.js.map +1 -1
  48. package/dist/proactive/watcher.d.ts +76 -0
  49. package/dist/proactive/watcher.d.ts.map +1 -0
  50. package/dist/proactive/watcher.js +246 -0
  51. package/dist/proactive/watcher.js.map +1 -0
  52. package/dist/registry.d.ts +4 -0
  53. package/dist/registry.d.ts.map +1 -1
  54. package/dist/registry.js +21 -0
  55. package/dist/registry.js.map +1 -1
  56. package/dist/reputation.d.ts +10 -0
  57. package/dist/reputation.d.ts.map +1 -1
  58. package/dist/reputation.js +23 -4
  59. package/dist/reputation.js.map +1 -1
  60. package/dist/rooms.d.ts +35 -0
  61. package/dist/rooms.d.ts.map +1 -1
  62. package/dist/rooms.js +128 -0
  63. package/dist/rooms.js.map +1 -1
  64. package/dist/sdk/index.d.ts +1 -1
  65. package/dist/sdk/index.js +1 -1
  66. package/dist/swp.d.ts +1 -1
  67. package/dist/swp.d.ts.map +1 -1
  68. package/dist/swp.js.map +1 -1
  69. package/package.json +2 -1
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Content-Addressed Block Store
3
+ *
4
+ * IPFS-inspired content-addressed storage for Society Protocol.
5
+ * Uses blake3 hashing for CIDs and SQLite for block persistence.
6
+ * Supports chunked file storage with Merkle-like manifests.
7
+ *
8
+ * Based on: IPFS (arXiv:1407.3561) — content-addressed blocks with CID-based retrieval
9
+ */
10
+ import { readFileSync, writeFileSync } from 'fs';
11
+ import { basename } from 'path';
12
+ // ─── Constants ──────────────────────────────────────────────────
13
+ const BLOCK_SIZE = 256 * 1024; // 256KB per block
14
+ // ─── ContentStore ───────────────────────────────────────────────
15
+ export class ContentStore {
16
+ storage;
17
+ manifests = new Map(); // rootCid → manifest
18
+ constructor(storage) {
19
+ this.storage = storage;
20
+ this.ensureTable();
21
+ }
22
+ ensureTable() {
23
+ this.storage.db.exec(`
24
+ CREATE TABLE IF NOT EXISTS content_blocks (
25
+ cid TEXT PRIMARY KEY,
26
+ data BLOB NOT NULL,
27
+ size INTEGER NOT NULL,
28
+ created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000)
29
+ );
30
+ CREATE TABLE IF NOT EXISTS file_manifests (
31
+ root_cid TEXT PRIMARY KEY,
32
+ manifest TEXT NOT NULL,
33
+ created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000)
34
+ );
35
+ `);
36
+ }
37
+ /**
38
+ * Store a data block, returning its CID (blake3 hash).
39
+ */
40
+ async put(data) {
41
+ const { blake3 } = await import('@noble/hashes/blake3');
42
+ const hash = blake3(data);
43
+ const cid = Buffer.from(hash).toString('hex');
44
+ // Idempotent: skip if already stored
45
+ const existing = this.storage.db
46
+ .prepare('SELECT cid FROM content_blocks WHERE cid = ?')
47
+ .get(cid);
48
+ if (!existing) {
49
+ this.storage.db
50
+ .prepare('INSERT INTO content_blocks (cid, data, size) VALUES (?, ?, ?)')
51
+ .run(cid, Buffer.from(data), data.byteLength);
52
+ }
53
+ return cid;
54
+ }
55
+ /**
56
+ * Retrieve a block by CID.
57
+ */
58
+ async get(cid) {
59
+ const row = this.storage.db
60
+ .prepare('SELECT data FROM content_blocks WHERE cid = ?')
61
+ .get(cid);
62
+ return row ? new Uint8Array(row.data) : null;
63
+ }
64
+ /**
65
+ * Check if a block exists locally.
66
+ */
67
+ has(cid) {
68
+ const row = this.storage.db
69
+ .prepare('SELECT 1 FROM content_blocks WHERE cid = ?')
70
+ .get(cid);
71
+ return !!row;
72
+ }
73
+ /**
74
+ * Store a file from disk, chunking into blocks.
75
+ * Returns a manifest describing all blocks.
76
+ */
77
+ async storeFile(filePath, author) {
78
+ const fileData = readFileSync(filePath);
79
+ return this.storeBuffer(fileData, basename(filePath), author);
80
+ }
81
+ /**
82
+ * Store raw buffer data, chunking into blocks.
83
+ */
84
+ async storeBuffer(data, fileName, author) {
85
+ const buf = Buffer.from(data);
86
+ const blocks = [];
87
+ for (let offset = 0; offset < buf.byteLength; offset += BLOCK_SIZE) {
88
+ const chunk = new Uint8Array(buf.subarray(offset, Math.min(offset + BLOCK_SIZE, buf.byteLength)));
89
+ const cid = await this.put(chunk);
90
+ blocks.push({ cid, offset, size: chunk.byteLength });
91
+ }
92
+ // Root CID = hash of all block CIDs concatenated
93
+ const { blake3 } = await import('@noble/hashes/blake3');
94
+ const rootData = new TextEncoder().encode(blocks.map(b => b.cid).join(':'));
95
+ const rootCid = Buffer.from(blake3(rootData)).toString('hex');
96
+ const manifest = {
97
+ rootCid,
98
+ fileName,
99
+ totalSize: buf.byteLength,
100
+ blockSize: BLOCK_SIZE,
101
+ blocks,
102
+ createdAt: Date.now(),
103
+ author,
104
+ };
105
+ // Persist manifest
106
+ this.manifests.set(rootCid, manifest);
107
+ this.storage.db
108
+ .prepare('INSERT OR REPLACE INTO file_manifests (root_cid, manifest) VALUES (?, ?)')
109
+ .run(rootCid, JSON.stringify(manifest));
110
+ return manifest;
111
+ }
112
+ /**
113
+ * Reassemble a file from its manifest.
114
+ * All blocks must be locally available.
115
+ */
116
+ async retrieveFile(manifest) {
117
+ const result = Buffer.alloc(manifest.totalSize);
118
+ for (const block of manifest.blocks) {
119
+ const data = await this.get(block.cid);
120
+ if (!data) {
121
+ throw new Error(`Missing block ${block.cid} for file ${manifest.fileName}`);
122
+ }
123
+ Buffer.from(data).copy(result, block.offset);
124
+ }
125
+ return new Uint8Array(result);
126
+ }
127
+ /**
128
+ * Save reassembled file to disk.
129
+ */
130
+ async saveFile(manifest, outputPath) {
131
+ const data = await this.retrieveFile(manifest);
132
+ writeFileSync(outputPath, data);
133
+ }
134
+ /**
135
+ * Get a manifest by root CID.
136
+ */
137
+ getManifest(rootCid) {
138
+ if (this.manifests.has(rootCid)) {
139
+ return this.manifests.get(rootCid);
140
+ }
141
+ const row = this.storage.db
142
+ .prepare('SELECT manifest FROM file_manifests WHERE root_cid = ?')
143
+ .get(rootCid);
144
+ if (row) {
145
+ const manifest = JSON.parse(row.manifest);
146
+ this.manifests.set(rootCid, manifest);
147
+ return manifest;
148
+ }
149
+ return null;
150
+ }
151
+ /**
152
+ * List all stored file manifests.
153
+ */
154
+ listFiles() {
155
+ const rows = this.storage.db
156
+ .prepare('SELECT manifest FROM file_manifests ORDER BY created_at DESC')
157
+ .all();
158
+ return rows.map(r => JSON.parse(r.manifest));
159
+ }
160
+ /**
161
+ * List missing blocks for a manifest (for fetching from peers).
162
+ */
163
+ getMissingBlocks(manifest) {
164
+ return manifest.blocks
165
+ .filter(b => !this.has(b.cid))
166
+ .map(b => b.cid);
167
+ }
168
+ /**
169
+ * Store a manifest received from a peer (without blocks).
170
+ */
171
+ addRemoteManifest(manifest) {
172
+ this.manifests.set(manifest.rootCid, manifest);
173
+ this.storage.db
174
+ .prepare('INSERT OR REPLACE INTO file_manifests (root_cid, manifest) VALUES (?, ?)')
175
+ .run(manifest.rootCid, JSON.stringify(manifest));
176
+ }
177
+ }
178
+ //# sourceMappingURL=content-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-store.js","sourceRoot":"","sources":["../src/content-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Society Protocol — ZKP Identity Proofs (Schnorr PoK)
3
+ *
4
+ * Non-interactive Schnorr proof of DID/key ownership via Fiat-Shamir.
5
+ * Ed25519 signatures ARE Schnorr signatures — we use ed.sign(challenge, key)
6
+ * as a zero-knowledge proof of private key ownership.
7
+ *
8
+ * Based on: Agent-OSI Layer 3 (arxiv 2602.13795)
9
+ */
10
+ import { type Identity } from './identity.js';
11
+ export interface IdentityProof {
12
+ did: string;
13
+ challenge: string;
14
+ proof: string;
15
+ roomId: string;
16
+ timestamp: number;
17
+ nonce: string;
18
+ expiresAt: number;
19
+ }
20
+ export interface IdentityProofVerifyResult {
21
+ valid: boolean;
22
+ did: string;
23
+ reason?: string;
24
+ }
25
+ /**
26
+ * Create a non-interactive Schnorr proof of DID ownership.
27
+ *
28
+ * The challenge is SHA-512(did || roomId || timestamp || nonce),
29
+ * and the proof is ed.sign(challenge, privateKey).
30
+ */
31
+ export declare function createIdentityProof(identity: Identity, roomId: string, ttlMs?: number): IdentityProof;
32
+ /**
33
+ * Verify a non-interactive Schnorr proof of DID ownership.
34
+ *
35
+ * 1. Recompute the challenge from the proof fields
36
+ * 2. Extract public key from the DID
37
+ * 3. Verify the Ed25519 signature
38
+ * 4. Check TTL expiration
39
+ */
40
+ export declare function verifyIdentityProof(proof: IdentityProof): IdentityProofVerifyResult;
41
+ export declare function serializeIdentityProof(proof: IdentityProof): Uint8Array;
42
+ export declare function deserializeIdentityProof(data: Uint8Array): IdentityProof;
43
+ //# sourceMappingURL=identity-proof.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-proof.d.ts","sourceRoot":"","sources":["../src/identity-proof.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,EAAoB,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAIhE,MAAM,WAAW,aAAa;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,yBAAyB;IACtC,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAMD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAC/B,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,MAAuB,GAC/B,aAAa,CAuBf;AAID;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,aAAa,GAAG,yBAAyB,CAoCnF;AAID,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,aAAa,GAAG,UAAU,CAEvE;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,UAAU,GAAG,aAAa,CAExE"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Society Protocol — ZKP Identity Proofs (Schnorr PoK)
3
+ *
4
+ * Non-interactive Schnorr proof of DID/key ownership via Fiat-Shamir.
5
+ * Ed25519 signatures ARE Schnorr signatures — we use ed.sign(challenge, key)
6
+ * as a zero-knowledge proof of private key ownership.
7
+ *
8
+ * Based on: Agent-OSI Layer 3 (arxiv 2602.13795)
9
+ */
10
+ import * as ed from '@noble/ed25519';
11
+ import { sha512 } from '@noble/hashes/sha512';
12
+ import { toString as uint8ToString, fromString as uint8FromString } from 'uint8arrays';
13
+ import { randomBytes as cryptoRandomBytes } from 'crypto';
14
+ import { publicKeyFromDid } from './identity.js';
15
+ // ─── Proof Generation ───────────────────────────────────────────
16
+ const DEFAULT_TTL_MS = 300_000; // 5 minutes
17
+ /**
18
+ * Create a non-interactive Schnorr proof of DID ownership.
19
+ *
20
+ * The challenge is SHA-512(did || roomId || timestamp || nonce),
21
+ * and the proof is ed.sign(challenge, privateKey).
22
+ */
23
+ export function createIdentityProof(identity, roomId, ttlMs = DEFAULT_TTL_MS) {
24
+ const timestamp = Date.now();
25
+ const nonce = uint8ToString(randomBytes(16), 'base16');
26
+ const expiresAt = timestamp + ttlMs;
27
+ // Build challenge: SHA-512(did || roomId || timestamp || nonce)
28
+ const challengeInput = `${identity.did}|${roomId}|${timestamp}|${nonce}`;
29
+ const challengeBytes = sha512(new TextEncoder().encode(challengeInput));
30
+ const challenge = uint8ToString(challengeBytes, 'base16');
31
+ // Sign the challenge as Schnorr PoK
32
+ const sig = ed.sign(challengeBytes, identity.privateKey);
33
+ const proof = uint8ToString(sig, 'base64');
34
+ return {
35
+ did: identity.did,
36
+ challenge,
37
+ proof,
38
+ roomId,
39
+ timestamp,
40
+ nonce,
41
+ expiresAt,
42
+ };
43
+ }
44
+ // ─── Proof Verification ────────────────────────────────────────
45
+ /**
46
+ * Verify a non-interactive Schnorr proof of DID ownership.
47
+ *
48
+ * 1. Recompute the challenge from the proof fields
49
+ * 2. Extract public key from the DID
50
+ * 3. Verify the Ed25519 signature
51
+ * 4. Check TTL expiration
52
+ */
53
+ export function verifyIdentityProof(proof) {
54
+ // Check expiration
55
+ if (Date.now() > proof.expiresAt) {
56
+ return { valid: false, did: proof.did, reason: 'proof expired' };
57
+ }
58
+ // Recompute challenge
59
+ const challengeInput = `${proof.did}|${proof.roomId}|${proof.timestamp}|${proof.nonce}`;
60
+ const expectedChallengeBytes = sha512(new TextEncoder().encode(challengeInput));
61
+ const expectedChallenge = uint8ToString(expectedChallengeBytes, 'base16');
62
+ // Verify challenge matches
63
+ if (proof.challenge !== expectedChallenge) {
64
+ return { valid: false, did: proof.did, reason: 'challenge mismatch' };
65
+ }
66
+ // Extract public key from DID
67
+ let publicKey;
68
+ try {
69
+ publicKey = publicKeyFromDid(proof.did);
70
+ }
71
+ catch {
72
+ return { valid: false, did: proof.did, reason: 'invalid DID format' };
73
+ }
74
+ // Verify Ed25519 signature (Schnorr PoK)
75
+ try {
76
+ const sigBytes = uint8FromString(proof.proof, 'base64');
77
+ const valid = ed.verify(sigBytes, expectedChallengeBytes, publicKey);
78
+ if (!valid) {
79
+ return { valid: false, did: proof.did, reason: 'signature verification failed' };
80
+ }
81
+ }
82
+ catch {
83
+ return { valid: false, did: proof.did, reason: 'signature verification error' };
84
+ }
85
+ return { valid: true, did: proof.did };
86
+ }
87
+ // ─── Serialization ──────────────────────────────────────────────
88
+ export function serializeIdentityProof(proof) {
89
+ return new TextEncoder().encode(JSON.stringify(proof));
90
+ }
91
+ export function deserializeIdentityProof(data) {
92
+ return JSON.parse(new TextDecoder().decode(data));
93
+ }
94
+ // ─── Utility ────────────────────────────────────────────────────
95
+ function randomBytes(n) {
96
+ return new Uint8Array(cryptoRandomBytes(n));
97
+ }
98
+ //# sourceMappingURL=identity-proof.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-proof.js","sourceRoot":"","sources":["../src/identity-proof.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -52,12 +52,13 @@ import { SecurityManager } from './security.js';
52
52
  import { IntegrationEngine } from './integration.js';
53
53
  import { PersonaVaultEngine } from './persona/index.js';
54
54
  import { ProactiveMissionEngine } from './proactive/engine.js';
55
+ import { ProactiveWatcher } from './proactive/watcher.js';
55
56
  import { spawn, execSync } from 'child_process';
56
57
  import { fileURLToPath } from 'url';
57
58
  import { resolve } from 'path';
58
59
  import { realpathSync } from 'fs';
59
60
  import { createClient } from './sdk/client.js';
60
- import { registerNode, resolveNode, stopHeartbeat } from './registry.js';
61
+ import { registerNode, resolveNode, stopHeartbeat, generateFriendlyName } from './registry.js';
61
62
  // ─── Invite Code Helpers ─────────────────────────────────────────
62
63
  // Encode a multiaddr + room into a short invite code: base64url
63
64
  function encodeInvite(multiaddr, room) {
@@ -193,27 +194,23 @@ program
193
194
  // Local invite (LAN)
194
195
  const localMultiaddr = `/ip4/127.0.0.1/tcp/${port}/p2p/${peerId}`;
195
196
  const localCode = encodeInvite(localMultiaddr, options.room);
197
+ // Auto-register with friendly name
198
+ const agentName = options.name || generateFriendlyName();
199
+ const registered = await registerNode(agentName, {
200
+ multiaddr: localMultiaddr,
201
+ room: options.room,
202
+ peerId,
203
+ name: agentName,
204
+ });
196
205
  console.log(` ${green('Node running!')} Room: ${cyan(options.room)}`);
206
+ if (registered) {
207
+ console.log(` ${bold('Your address:')} ${cyan(`${agentName}@society.computer`)}`);
208
+ }
197
209
  console.log('');
198
- console.log(` ${bold('Share with friends on same network:')}`);
210
+ console.log(` ${bold('Share with friends:')}`);
199
211
  console.log('');
200
- console.log(` ${bold(cyan(`npx society join ${localCode}`))}`);
212
+ console.log(` ${bold(cyan(`npx society join ${registered ? agentName : localCode}`))}`);
201
213
  console.log('');
202
- // Register friendly name if provided
203
- if (options.name) {
204
- const registered = await registerNode(options.name, {
205
- multiaddr: localMultiaddr,
206
- room: options.room,
207
- peerId,
208
- name: options.name,
209
- });
210
- if (registered) {
211
- console.log(` ${green('Registered!')} Friends can also join with:`);
212
- console.log('');
213
- console.log(` ${bold(cyan(`npx society join ${options.name}`))}`);
214
- console.log('');
215
- }
216
- }
217
214
  // If --relay, spawn cloudflared for a public URL
218
215
  if (options.relay) {
219
216
  const wsPort = port + 1;
@@ -237,22 +234,17 @@ program
237
234
  console.log('');
238
235
  console.log(` ${bold(cyan(`npx society join ${publicCode}`))}`);
239
236
  // Update registry with public multiaddr
240
- if (options.name) {
241
- registerNode(options.name, {
242
- multiaddr: publicMultiaddr,
243
- room: options.room,
244
- peerId,
245
- name: options.name,
246
- }).then(ok => {
247
- if (ok) {
248
- console.log(` ${bold(cyan(`npx society join ${options.name}`))}`);
249
- }
250
- console.log('');
251
- });
252
- }
253
- else {
237
+ registerNode(agentName, {
238
+ multiaddr: publicMultiaddr,
239
+ room: options.room,
240
+ peerId,
241
+ name: agentName,
242
+ }).then(ok => {
243
+ if (ok) {
244
+ console.log(` ${bold(cyan(`npx society join ${agentName}`))}`);
245
+ }
254
246
  console.log('');
255
- }
247
+ });
256
248
  }
257
249
  });
258
250
  process.on('SIGINT', () => { cfProc.kill(); });
@@ -335,6 +327,8 @@ program
335
327
  .option('--relay', 'spawn cloudflared to create a public WebSocket relay')
336
328
  .option('--gossipsub', 'enable GossipSub for scalable pub/sub', true)
337
329
  .option('--dht', 'enable DHT for peer discovery', true)
330
+ .option('--encrypted', 'enable E2E encryption for all room messages')
331
+ .option('--proactive', 'enable proactive agent behavior (watches room, intervenes when relevant)')
338
332
  .option('--mission-leader', 'enable proactive mission leadership with auto-restore', false)
339
333
  .option('--provider <provider>', 'AI planner provider (openai|anthropic|ollama)', 'openai')
340
334
  .option('--debug', 'enable debug logging')
@@ -773,10 +767,9 @@ async function startNode(options) {
773
767
  // Banner
774
768
  console.log('');
775
769
  console.log(' ╔══════════════════════════════════════════════════════════╗');
776
- console.log(' ║ 🌐 Society Protocol v1.0 (State of Art) ║');
777
- console.log(' ║ P2P Multi-Agent Collaboration Network Node ║');
770
+ console.log(' ║ 🌐 Society Protocol v1.0 ║');
778
771
  console.log(' ╠══════════════════════════════════════════════════════════╣');
779
- console.log(' ║ Features: GossipSub DHT Reputation Multi-Provider ║');
772
+ console.log(' ║ GossipSub · Kad-DHT · did:key · CRDT · Reputation ║');
780
773
  console.log(' ╚══════════════════════════════════════════════════════════╝');
781
774
  console.log('');
782
775
  // 1. Initialize storage
@@ -825,12 +818,22 @@ async function startNode(options) {
825
818
  enableDht: options.dht,
826
819
  enableGossipsub: options.gossipsub,
827
820
  });
828
- // 6. Initialize room manager
821
+ // 6. Initialize room manager + encryption
829
822
  const rooms = new RoomManager(identity, p2p, storage);
823
+ if (options.encrypted) {
824
+ const { SecurityManager } = await import('./security.js');
825
+ const security = new SecurityManager(identity);
826
+ p2p.setSecurityManager(security);
827
+ await security.generateKeyPair();
828
+ console.log(`[init] E2E encryption enabled (AES-256-GCM + X25519)`);
829
+ }
830
830
  // 7. Join room
831
831
  const roomId = options.room;
832
832
  await rooms.joinRoom(roomId, roomId);
833
- console.log(`[init] Joined room: ${roomId}`);
833
+ if (options.encrypted) {
834
+ rooms.enableEncryption(roomId);
835
+ }
836
+ console.log(`[init] Joined room: ${roomId}${options.encrypted ? ' (encrypted)' : ''}`);
834
837
  // 8. Initialize CoC Engine with reputation
835
838
  const coc = new CocEngine(identity, rooms, storage, reputation);
836
839
  // 9. Initialize Planner with multi-provider support
@@ -864,6 +867,7 @@ async function startNode(options) {
864
867
  // 12. Initialize federation/integration stack (Federation Mesh)
865
868
  const federation = new FederationEngine(storage, identity);
866
869
  const knowledge = new KnowledgePool(storage, identity);
870
+ rooms.setKnowledgePool(knowledge); // Enable conversational knowledge exchange
867
871
  const skills = new SkillsEngine(storage, identity);
868
872
  const security = new SecurityManager(identity);
869
873
  const persona = new PersonaVaultEngine(storage, identity.did, {
@@ -880,6 +884,16 @@ async function startNode(options) {
880
884
  if (proactiveLeader) {
881
885
  console.log('[init] Mission leader mode enabled (auto-restore active).');
882
886
  }
887
+ // Initialize ProactiveWatcher if --proactive flag
888
+ let proactiveWatcher;
889
+ if (options.proactive) {
890
+ proactiveWatcher = new ProactiveWatcher(identity, {
891
+ level: 1,
892
+ specialties: [],
893
+ });
894
+ proactiveWatcher.watch(rooms, knowledge);
895
+ console.log(`[init] Proactive watcher enabled (level ${proactiveWatcher.getLevel()})`);
896
+ }
883
897
  console.log('');
884
898
  console.log(' Type a message and press Enter to send.');
885
899
  console.log(' Commands: /peers /rooms /presence /reputation /info /history');
@@ -898,6 +912,8 @@ async function startNode(options) {
898
912
  rl.prompt(true);
899
913
  });
900
914
  rooms.on('presence:update', (_roomId, envelope) => {
915
+ if (envelope.from.did === identity.did)
916
+ return; // Skip own presence
901
917
  const body = envelope.body;
902
918
  if (body.status === 'online') {
903
919
  process.stdout.write('\r\x1b[K');
@@ -957,6 +973,18 @@ async function startNode(options) {
957
973
  process.stdout.write('\r\x1b[K');
958
974
  console.log(`\n ${bold(green('✅ Chain Completed'))}: ${chainId}\n`);
959
975
  rl.prompt(true);
976
+ // Post-chain knowledge distillation
977
+ const chain = coc.getChain(chainId);
978
+ if (chain && knowledge) {
979
+ const participants = [...new Set(chain.steps.map(s => s.assignee_did).filter(Boolean))];
980
+ knowledge.distillChainExperience(chainId, chain.final_report || chain.goal, chain.goal, chain.room_id, participants.length > 0 ? participants : [identity.did]).then(cards => {
981
+ if (cards.length > 0) {
982
+ process.stdout.write('\r\x1b[K');
983
+ console.log(` ${dim(`📚 Distilled ${cards.length} knowledge card(s) from chain`)}`);
984
+ rl.prompt(true);
985
+ }
986
+ }).catch(() => { });
987
+ }
960
988
  });
961
989
  // ─── Interactive REPL ───────────────────────────────────────
962
990
  const rl = readline.createInterface({
@@ -1033,6 +1061,8 @@ async function startNode(options) {
1033
1061
  exporter,
1034
1062
  federation,
1035
1063
  integration,
1064
+ knowledge,
1065
+ proactiveWatcher,
1036
1066
  roomId,
1037
1067
  DEBUG,
1038
1068
  });
@@ -1488,6 +1518,111 @@ async function handleCommand(input, ctx) {
1488
1518
  }
1489
1519
  break;
1490
1520
  }
1521
+ case '/share': {
1522
+ const filePath = args.join(' ').trim();
1523
+ if (!filePath) {
1524
+ console.log(` Usage: /share <filepath>`);
1525
+ break;
1526
+ }
1527
+ try {
1528
+ const { ContentStore } = await import('./content-store.js');
1529
+ const contentStore = new ContentStore(ctx.storage);
1530
+ const manifest = await contentStore.storeFile(filePath, ctx.identity.did);
1531
+ const sizeKB = (manifest.totalSize / 1024).toFixed(1);
1532
+ console.log(` ${green('Shared!')} ${manifest.fileName} (${sizeKB}KB, ${manifest.blocks.length} blocks)`);
1533
+ console.log(` CID: ${dim(manifest.rootCid.slice(0, 16))}...`);
1534
+ // Broadcast manifest to room
1535
+ const body = { type: 'artifact.offer', manifest };
1536
+ const swp = await import('./swp.js');
1537
+ const envelope = swp.createEnvelope(ctx.identity, 'artifact.offer', ctx.roomId, body);
1538
+ const data = new TextEncoder().encode(JSON.stringify(envelope));
1539
+ await ctx.p2p.publish(`${ctx.roomId}/artifacts`, data);
1540
+ }
1541
+ catch (err) {
1542
+ console.log(` Error: ${err.message}`);
1543
+ }
1544
+ break;
1545
+ }
1546
+ case '/files': {
1547
+ try {
1548
+ const { ContentStore } = await import('./content-store.js');
1549
+ const contentStore = new ContentStore(ctx.storage);
1550
+ const files = contentStore.listFiles();
1551
+ if (files.length === 0) {
1552
+ console.log(` No files shared yet. Use /share <filepath>`);
1553
+ }
1554
+ else {
1555
+ console.log(` ${bold('Shared files:')}`);
1556
+ for (const f of files) {
1557
+ const sizeKB = (f.totalSize / 1024).toFixed(1);
1558
+ const date = new Date(f.createdAt).toLocaleTimeString();
1559
+ console.log(` ${f.fileName} (${sizeKB}KB) — ${dim(date)} — CID: ${dim(f.rootCid.slice(0, 12))}...`);
1560
+ }
1561
+ }
1562
+ }
1563
+ catch (err) {
1564
+ console.log(` Error: ${err.message}`);
1565
+ }
1566
+ break;
1567
+ }
1568
+ case '/encrypt': {
1569
+ const subCmd = args[0]?.toLowerCase();
1570
+ if (subCmd === 'on') {
1571
+ ctx.rooms.enableEncryption(ctx.roomId);
1572
+ console.log(` ${green('E2E encryption enabled')} for this room`);
1573
+ }
1574
+ else if (subCmd === 'off') {
1575
+ ctx.rooms.disableEncryption(ctx.roomId);
1576
+ console.log(` Encryption disabled for this room`);
1577
+ }
1578
+ else {
1579
+ const status = ctx.rooms.isEncrypted(ctx.roomId) ? green('ON') : 'OFF';
1580
+ console.log(` Encryption: ${status}`);
1581
+ console.log(` Usage: /encrypt on | /encrypt off`);
1582
+ }
1583
+ break;
1584
+ }
1585
+ case '/context': {
1586
+ const knowledge = ctx.knowledge;
1587
+ if (!knowledge) {
1588
+ console.log(` Knowledge system not available`);
1589
+ break;
1590
+ }
1591
+ const sharedCtx = knowledge.getSharedContext(ctx.roomId);
1592
+ if (sharedCtx) {
1593
+ console.log(sharedCtx);
1594
+ }
1595
+ else {
1596
+ console.log(` No shared context yet. Chat to build collaborative knowledge.`);
1597
+ }
1598
+ break;
1599
+ }
1600
+ case '/proactive': {
1601
+ const subCmd = args[0];
1602
+ if (!ctx.proactiveWatcher) {
1603
+ console.log(` Proactive watcher not initialized. Start with --proactive flag.`);
1604
+ break;
1605
+ }
1606
+ if (subCmd === 'on') {
1607
+ ctx.proactiveWatcher.setLevel(1);
1608
+ console.log(` Proactive watcher: ${green('ON')} (level 1 - moderate)`);
1609
+ }
1610
+ else if (subCmd === 'off') {
1611
+ ctx.proactiveWatcher.setLevel(0);
1612
+ console.log(` Proactive watcher: OFF`);
1613
+ }
1614
+ else if (subCmd === '2' || subCmd === 'aggressive') {
1615
+ ctx.proactiveWatcher.setLevel(2);
1616
+ console.log(` Proactive watcher: ${green('ON')} (level 2 - aggressive)`);
1617
+ }
1618
+ else {
1619
+ const level = ctx.proactiveWatcher.getLevel();
1620
+ const labels = ['OFF', 'moderate', 'aggressive'];
1621
+ console.log(` Proactive watcher: level ${level} (${labels[level]})`);
1622
+ console.log(` Usage: /proactive on | off | 2`);
1623
+ }
1624
+ break;
1625
+ }
1491
1626
  case '/debug': {
1492
1627
  console.log(` Debug mode: ${ctx.DEBUG ? 'ON' : 'OFF'}`);
1493
1628
  break;
@@ -1499,7 +1634,7 @@ async function handleCommand(input, ctx) {
1499
1634
  console.log(` Unknown command: ${cmd}`);
1500
1635
  console.log(' Available: /peers /rooms /presence /reputation /info /history');
1501
1636
  console.log(' /summon /template /chains /chain /step /assign /review');
1502
- console.log(' /cancel /export /cache /debug /quit');
1637
+ console.log(' /cancel /export /cache /encrypt /context /proactive /debug /quit');
1503
1638
  console.log(' /mesh-request /mesh-accept /mesh-reject /mesh-revoke /mesh-peerings');
1504
1639
  console.log(' /mesh-open /mesh-close /mesh-bridges /mesh-stats');
1505
1640
  }