@rookdaemon/agora 0.1.2 → 0.2.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 (68) hide show
  1. package/README.md +457 -1
  2. package/dist/cli.js +627 -37
  3. package/dist/cli.js.map +1 -1
  4. package/dist/config.d.ts +44 -0
  5. package/dist/config.d.ts.map +1 -0
  6. package/dist/config.js +74 -0
  7. package/dist/config.js.map +1 -0
  8. package/dist/discovery/bootstrap.d.ts +32 -0
  9. package/dist/discovery/bootstrap.d.ts.map +1 -0
  10. package/dist/discovery/bootstrap.js +36 -0
  11. package/dist/discovery/bootstrap.js.map +1 -0
  12. package/dist/discovery/peer-discovery.d.ts +59 -0
  13. package/dist/discovery/peer-discovery.d.ts.map +1 -0
  14. package/dist/discovery/peer-discovery.js +108 -0
  15. package/dist/discovery/peer-discovery.js.map +1 -0
  16. package/dist/index.d.ts +9 -0
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +9 -0
  19. package/dist/index.js.map +1 -1
  20. package/dist/message/envelope.d.ts +1 -1
  21. package/dist/message/envelope.d.ts.map +1 -1
  22. package/dist/message/envelope.js.map +1 -1
  23. package/dist/message/types/paper-discovery.d.ts +28 -0
  24. package/dist/message/types/paper-discovery.d.ts.map +1 -0
  25. package/dist/message/types/paper-discovery.js +2 -0
  26. package/dist/message/types/paper-discovery.js.map +1 -0
  27. package/dist/message/types/peer-discovery.d.ts +78 -0
  28. package/dist/message/types/peer-discovery.d.ts.map +1 -0
  29. package/dist/message/types/peer-discovery.js +90 -0
  30. package/dist/message/types/peer-discovery.js.map +1 -0
  31. package/dist/peer/client.d.ts +50 -0
  32. package/dist/peer/client.d.ts.map +1 -0
  33. package/dist/peer/client.js +138 -0
  34. package/dist/peer/client.js.map +1 -0
  35. package/dist/peer/manager.d.ts +65 -0
  36. package/dist/peer/manager.d.ts.map +1 -0
  37. package/dist/peer/manager.js +153 -0
  38. package/dist/peer/manager.js.map +1 -0
  39. package/dist/peer/server.d.ts +65 -0
  40. package/dist/peer/server.d.ts.map +1 -0
  41. package/dist/peer/server.js +154 -0
  42. package/dist/peer/server.js.map +1 -0
  43. package/dist/registry/discovery-service.d.ts +64 -0
  44. package/dist/registry/discovery-service.d.ts.map +1 -0
  45. package/dist/registry/discovery-service.js +129 -0
  46. package/dist/registry/discovery-service.js.map +1 -0
  47. package/dist/registry/messages.d.ts +55 -0
  48. package/dist/registry/messages.d.ts.map +1 -1
  49. package/dist/relay/client.d.ts +112 -0
  50. package/dist/relay/client.d.ts.map +1 -0
  51. package/dist/relay/client.js +281 -0
  52. package/dist/relay/client.js.map +1 -0
  53. package/dist/relay/server.d.ts +76 -0
  54. package/dist/relay/server.d.ts.map +1 -0
  55. package/dist/relay/server.js +338 -0
  56. package/dist/relay/server.js.map +1 -0
  57. package/dist/relay/types.d.ts +35 -0
  58. package/dist/relay/types.d.ts.map +1 -0
  59. package/dist/relay/types.js +2 -0
  60. package/dist/relay/types.js.map +1 -0
  61. package/dist/transport/peer-config.d.ts +3 -2
  62. package/dist/transport/peer-config.d.ts.map +1 -1
  63. package/dist/transport/peer-config.js.map +1 -1
  64. package/dist/transport/relay.d.ts +23 -0
  65. package/dist/transport/relay.d.ts.map +1 -0
  66. package/dist/transport/relay.js +85 -0
  67. package/dist/transport/relay.js.map +1 -0
  68. package/package.json +7 -2
@@ -0,0 +1,65 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { WebSocket } from 'ws';
3
+ import type { KeyPair } from '../identity/keypair.js';
4
+ import type { Envelope } from '../message/envelope.js';
5
+ import type { AnnouncePayload } from '../registry/messages.js';
6
+ /**
7
+ * Represents a connected peer
8
+ */
9
+ export interface ConnectedPeer {
10
+ /** Peer's public key */
11
+ publicKey: string;
12
+ /** WebSocket connection */
13
+ socket: WebSocket;
14
+ /** Whether the peer has been announced */
15
+ announced: boolean;
16
+ /** Peer metadata from announce message */
17
+ metadata?: {
18
+ name?: string;
19
+ version?: string;
20
+ };
21
+ }
22
+ /**
23
+ * Events emitted by PeerServer
24
+ */
25
+ export interface PeerServerEvents {
26
+ 'peer-connected': (publicKey: string, peer: ConnectedPeer) => void;
27
+ 'peer-disconnected': (publicKey: string) => void;
28
+ 'message-received': (envelope: Envelope, fromPublicKey: string) => void;
29
+ 'error': (error: Error) => void;
30
+ }
31
+ /**
32
+ * WebSocket server for accepting peer connections
33
+ */
34
+ export declare class PeerServer extends EventEmitter {
35
+ private wss;
36
+ private peers;
37
+ private identity;
38
+ private announcePayload;
39
+ constructor(identity: KeyPair, announcePayload: AnnouncePayload);
40
+ /**
41
+ * Start the WebSocket server
42
+ */
43
+ start(port: number): Promise<void>;
44
+ /**
45
+ * Stop the WebSocket server
46
+ */
47
+ stop(): Promise<void>;
48
+ /**
49
+ * Get all connected peers
50
+ */
51
+ getPeers(): Map<string, ConnectedPeer>;
52
+ /**
53
+ * Send a message to a specific peer
54
+ */
55
+ send(publicKey: string, envelope: Envelope): boolean;
56
+ /**
57
+ * Broadcast a message to all connected peers
58
+ */
59
+ broadcast(envelope: Envelope): void;
60
+ /**
61
+ * Handle incoming connection
62
+ */
63
+ private handleConnection;
64
+ }
65
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/peer/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAmB,SAAS,EAAE,MAAM,IAAI,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAEvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,wBAAwB;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,2BAA2B;IAC3B,MAAM,EAAE,SAAS,CAAC;IAClB,0CAA0C;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;IACnE,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,kBAAkB,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,KAAK,IAAI,CAAC;IACxE,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACjC;AAED;;GAEG;AACH,qBAAa,UAAW,SAAQ,YAAY;IAC1C,OAAO,CAAC,GAAG,CAAgC;IAC3C,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,QAAQ,CAAU;IAC1B,OAAO,CAAC,eAAe,CAAkB;gBAE7B,QAAQ,EAAE,OAAO,EAAE,eAAe,EAAE,eAAe;IAM/D;;OAEG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBlC;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAwB3B;;OAEG;IACH,QAAQ,IAAI,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC;IAItC;;OAEG;IACH,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO;IAepD;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAQnC;;OAEG;IACH,OAAO,CAAC,gBAAgB;CAkEzB"}
@@ -0,0 +1,154 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { WebSocketServer, WebSocket } from 'ws';
3
+ import { createEnvelope, verifyEnvelope } from '../message/envelope.js';
4
+ /**
5
+ * WebSocket server for accepting peer connections
6
+ */
7
+ export class PeerServer extends EventEmitter {
8
+ wss = null;
9
+ peers = new Map();
10
+ identity;
11
+ announcePayload;
12
+ constructor(identity, announcePayload) {
13
+ super();
14
+ this.identity = identity;
15
+ this.announcePayload = announcePayload;
16
+ }
17
+ /**
18
+ * Start the WebSocket server
19
+ */
20
+ start(port) {
21
+ return new Promise((resolve, reject) => {
22
+ try {
23
+ this.wss = new WebSocketServer({ port });
24
+ this.wss.on('error', (error) => {
25
+ this.emit('error', error);
26
+ reject(error);
27
+ });
28
+ this.wss.on('listening', () => {
29
+ resolve();
30
+ });
31
+ this.wss.on('connection', (socket) => {
32
+ this.handleConnection(socket);
33
+ });
34
+ }
35
+ catch (error) {
36
+ reject(error);
37
+ }
38
+ });
39
+ }
40
+ /**
41
+ * Stop the WebSocket server
42
+ */
43
+ async stop() {
44
+ return new Promise((resolve, reject) => {
45
+ if (!this.wss) {
46
+ resolve();
47
+ return;
48
+ }
49
+ // Close all peer connections
50
+ for (const peer of this.peers.values()) {
51
+ peer.socket.close();
52
+ }
53
+ this.peers.clear();
54
+ this.wss.close((err) => {
55
+ if (err) {
56
+ reject(err);
57
+ }
58
+ else {
59
+ this.wss = null;
60
+ resolve();
61
+ }
62
+ });
63
+ });
64
+ }
65
+ /**
66
+ * Get all connected peers
67
+ */
68
+ getPeers() {
69
+ return new Map(this.peers);
70
+ }
71
+ /**
72
+ * Send a message to a specific peer
73
+ */
74
+ send(publicKey, envelope) {
75
+ const peer = this.peers.get(publicKey);
76
+ if (!peer || peer.socket.readyState !== WebSocket.OPEN) {
77
+ return false;
78
+ }
79
+ try {
80
+ peer.socket.send(JSON.stringify(envelope));
81
+ return true;
82
+ }
83
+ catch (error) {
84
+ this.emit('error', error);
85
+ return false;
86
+ }
87
+ }
88
+ /**
89
+ * Broadcast a message to all connected peers
90
+ */
91
+ broadcast(envelope) {
92
+ for (const [publicKey, peer] of this.peers) {
93
+ if (peer.socket.readyState === WebSocket.OPEN) {
94
+ this.send(publicKey, envelope);
95
+ }
96
+ }
97
+ }
98
+ /**
99
+ * Handle incoming connection
100
+ */
101
+ handleConnection(socket) {
102
+ let peerPublicKey = null;
103
+ // Send announce message immediately
104
+ const announceEnvelope = createEnvelope('announce', this.identity.publicKey, this.identity.privateKey, this.announcePayload);
105
+ socket.send(JSON.stringify(announceEnvelope));
106
+ socket.on('message', (data) => {
107
+ try {
108
+ const envelope = JSON.parse(data.toString());
109
+ // Verify envelope signature
110
+ const verification = verifyEnvelope(envelope);
111
+ if (!verification.valid) {
112
+ // Drop invalid messages
113
+ return;
114
+ }
115
+ // First message should be an announce
116
+ if (!peerPublicKey) {
117
+ if (envelope.type === 'announce') {
118
+ peerPublicKey = envelope.sender;
119
+ const payload = envelope.payload;
120
+ const peer = {
121
+ publicKey: peerPublicKey,
122
+ socket,
123
+ announced: true,
124
+ metadata: payload.metadata,
125
+ };
126
+ this.peers.set(peerPublicKey, peer);
127
+ this.emit('peer-connected', peerPublicKey, peer);
128
+ }
129
+ return;
130
+ }
131
+ // Verify the message is from the announced peer
132
+ if (envelope.sender !== peerPublicKey) {
133
+ // Drop messages from wrong sender
134
+ return;
135
+ }
136
+ // Emit message-received event
137
+ this.emit('message-received', envelope, peerPublicKey);
138
+ }
139
+ catch {
140
+ // Invalid JSON or other parsing errors - drop the message
141
+ }
142
+ });
143
+ socket.on('close', () => {
144
+ if (peerPublicKey) {
145
+ this.peers.delete(peerPublicKey);
146
+ this.emit('peer-disconnected', peerPublicKey);
147
+ }
148
+ });
149
+ socket.on('error', (error) => {
150
+ this.emit('error', error);
151
+ });
152
+ }
153
+ }
154
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/peer/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import { type Envelope } from '../message/envelope.js';
2
+ import { PeerStore } from './peer-store.js';
3
+ import type { Capability } from './capability.js';
4
+ import type { CapabilityAnnouncePayload, CapabilityQueryPayload, CapabilityResponsePayload } from './messages.js';
5
+ /**
6
+ * DiscoveryService manages capability-based peer discovery.
7
+ * It maintains a local index of peer capabilities and handles
8
+ * capability announce, query, and response messages.
9
+ */
10
+ export declare class DiscoveryService {
11
+ private peerStore;
12
+ private identity;
13
+ constructor(peerStore: PeerStore, identity: {
14
+ publicKey: string;
15
+ privateKey: string;
16
+ });
17
+ /**
18
+ * Announce own capabilities to the network.
19
+ * Creates a capability_announce envelope that can be broadcast to peers.
20
+ *
21
+ * @param capabilities - List of capabilities this agent offers
22
+ * @param metadata - Optional metadata about this agent
23
+ * @returns A signed capability_announce envelope
24
+ */
25
+ announce(capabilities: Capability[], metadata?: {
26
+ name?: string;
27
+ version?: string;
28
+ }): Envelope<CapabilityAnnouncePayload>;
29
+ /**
30
+ * Handle an incoming capability_announce message.
31
+ * Updates the peer store with the announced capabilities.
32
+ *
33
+ * @param envelope - The capability_announce envelope to process
34
+ */
35
+ handleAnnounce(envelope: Envelope<CapabilityAnnouncePayload>): void;
36
+ /**
37
+ * Create a capability query payload.
38
+ *
39
+ * @param queryType - Type of query: 'name', 'tag', or 'schema'
40
+ * @param query - The query value (capability name, tag, or schema)
41
+ * @param filters - Optional filters (limit, minTrustScore)
42
+ * @returns A capability_query payload
43
+ */
44
+ query(queryType: 'name' | 'tag' | 'schema', query: string | object, filters?: {
45
+ limit?: number;
46
+ minTrustScore?: number;
47
+ }): CapabilityQueryPayload;
48
+ /**
49
+ * Handle an incoming capability_query message.
50
+ * Searches the local peer store and returns matching peers.
51
+ *
52
+ * @param envelope - The capability_query envelope to process
53
+ * @returns A capability_response envelope with matching peers
54
+ */
55
+ handleQuery(envelope: Envelope<CapabilityQueryPayload>): Envelope<CapabilityResponsePayload>;
56
+ /**
57
+ * Remove peers that haven't been seen within the specified time window.
58
+ *
59
+ * @param maxAgeMs - Maximum age in milliseconds
60
+ * @returns Number of peers removed
61
+ */
62
+ pruneStale(maxAgeMs: number): number;
63
+ }
64
+ //# sourceMappingURL=discovery-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery-service.d.ts","sourceRoot":"","sources":["../../src/registry/discovery-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,KAAK,EACV,yBAAyB,EACzB,sBAAsB,EACtB,yBAAyB,EAC1B,MAAM,eAAe,CAAC;AAEvB;;;;GAIG;AACH,qBAAa,gBAAgB;IAEzB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,QAAQ;gBADR,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE;IAG7D;;;;;;;OAOG;IACH,QAAQ,CACN,YAAY,EAAE,UAAU,EAAE,EAC1B,QAAQ,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAC7C,QAAQ,CAAC,yBAAyB,CAAC;IAoBtC;;;;;OAKG;IACH,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,yBAAyB,CAAC,GAAG,IAAI;IAgBnE;;;;;;;OAOG;IACH,KAAK,CACH,SAAS,EAAE,MAAM,GAAG,KAAK,GAAG,QAAQ,EACpC,KAAK,EAAE,MAAM,GAAG,MAAM,EACtB,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,GACnD,sBAAsB;IAQzB;;;;;;OAMG;IACH,WAAW,CACT,QAAQ,EAAE,QAAQ,CAAC,sBAAsB,CAAC,GACzC,QAAQ,CAAC,yBAAyB,CAAC;IAqDtC;;;;;OAKG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;CAGrC"}
@@ -0,0 +1,129 @@
1
+ import { createEnvelope } from '../message/envelope.js';
2
+ /**
3
+ * DiscoveryService manages capability-based peer discovery.
4
+ * It maintains a local index of peer capabilities and handles
5
+ * capability announce, query, and response messages.
6
+ */
7
+ export class DiscoveryService {
8
+ peerStore;
9
+ identity;
10
+ constructor(peerStore, identity) {
11
+ this.peerStore = peerStore;
12
+ this.identity = identity;
13
+ }
14
+ /**
15
+ * Announce own capabilities to the network.
16
+ * Creates a capability_announce envelope that can be broadcast to peers.
17
+ *
18
+ * @param capabilities - List of capabilities this agent offers
19
+ * @param metadata - Optional metadata about this agent
20
+ * @returns A signed capability_announce envelope
21
+ */
22
+ announce(capabilities, metadata) {
23
+ const payload = {
24
+ publicKey: this.identity.publicKey,
25
+ capabilities,
26
+ metadata: metadata ? {
27
+ ...metadata,
28
+ lastSeen: Date.now(),
29
+ } : {
30
+ lastSeen: Date.now(),
31
+ },
32
+ };
33
+ return createEnvelope('capability_announce', this.identity.publicKey, this.identity.privateKey, payload);
34
+ }
35
+ /**
36
+ * Handle an incoming capability_announce message.
37
+ * Updates the peer store with the announced capabilities.
38
+ *
39
+ * @param envelope - The capability_announce envelope to process
40
+ */
41
+ handleAnnounce(envelope) {
42
+ const { payload } = envelope;
43
+ const peer = {
44
+ publicKey: payload.publicKey,
45
+ capabilities: payload.capabilities,
46
+ lastSeen: payload.metadata?.lastSeen || envelope.timestamp,
47
+ metadata: payload.metadata ? {
48
+ name: payload.metadata.name,
49
+ version: payload.metadata.version,
50
+ } : undefined,
51
+ };
52
+ this.peerStore.addOrUpdatePeer(peer);
53
+ }
54
+ /**
55
+ * Create a capability query payload.
56
+ *
57
+ * @param queryType - Type of query: 'name', 'tag', or 'schema'
58
+ * @param query - The query value (capability name, tag, or schema)
59
+ * @param filters - Optional filters (limit, minTrustScore)
60
+ * @returns A capability_query payload
61
+ */
62
+ query(queryType, query, filters) {
63
+ return {
64
+ queryType,
65
+ query,
66
+ filters,
67
+ };
68
+ }
69
+ /**
70
+ * Handle an incoming capability_query message.
71
+ * Searches the local peer store and returns matching peers.
72
+ *
73
+ * @param envelope - The capability_query envelope to process
74
+ * @returns A capability_response envelope with matching peers
75
+ */
76
+ handleQuery(envelope) {
77
+ const { payload } = envelope;
78
+ let peers = [];
79
+ // Execute query based on type
80
+ if (payload.queryType === 'name' && typeof payload.query === 'string') {
81
+ peers = this.peerStore.findByCapability(payload.query);
82
+ }
83
+ else if (payload.queryType === 'tag' && typeof payload.query === 'string') {
84
+ peers = this.peerStore.findByTag(payload.query);
85
+ }
86
+ else if (payload.queryType === 'schema') {
87
+ // Schema-based matching is deferred to Phase 2b
88
+ // For now, return empty results
89
+ peers = [];
90
+ }
91
+ // Apply filters
92
+ const limit = payload.filters?.limit;
93
+ const totalMatches = peers.length;
94
+ if (limit !== undefined && limit > 0) {
95
+ peers = peers.slice(0, limit);
96
+ }
97
+ // Transform peers to response format
98
+ const responsePeers = peers.map(peer => ({
99
+ publicKey: peer.publicKey,
100
+ capabilities: peer.capabilities,
101
+ metadata: peer.metadata ? {
102
+ name: peer.metadata.name,
103
+ version: peer.metadata.version,
104
+ lastSeen: peer.lastSeen,
105
+ } : {
106
+ lastSeen: peer.lastSeen,
107
+ },
108
+ // Trust score integration deferred to Phase 2b (RFC-001)
109
+ trustScore: undefined,
110
+ }));
111
+ const responsePayload = {
112
+ queryId: envelope.id,
113
+ peers: responsePeers,
114
+ totalMatches,
115
+ };
116
+ return createEnvelope('capability_response', this.identity.publicKey, this.identity.privateKey, responsePayload, envelope.id // inReplyTo
117
+ );
118
+ }
119
+ /**
120
+ * Remove peers that haven't been seen within the specified time window.
121
+ *
122
+ * @param maxAgeMs - Maximum age in milliseconds
123
+ * @returns Number of peers removed
124
+ */
125
+ pruneStale(maxAgeMs) {
126
+ return this.peerStore.prune(maxAgeMs);
127
+ }
128
+ }
129
+ //# sourceMappingURL=discovery-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery-service.js","sourceRoot":"","sources":["../../src/registry/discovery-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAiB,MAAM,wBAAwB,CAAC;AAUvE;;;;GAIG;AACH,MAAM,OAAO,gBAAgB;IAEjB;IACA;IAFV,YACU,SAAoB,EACpB,QAAmD;QADnD,cAAS,GAAT,SAAS,CAAW;QACpB,aAAQ,GAAR,QAAQ,CAA2C;IAC1D,CAAC;IAEJ;;;;;;;OAOG;IACH,QAAQ,CACN,YAA0B,EAC1B,QAA8C;QAE9C,MAAM,OAAO,GAA8B;YACzC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS;YAClC,YAAY;YACZ,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;gBACnB,GAAG,QAAQ;gBACX,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE;aACrB,CAAC,CAAC,CAAC;gBACF,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE;aACrB;SACF,CAAC;QAEF,OAAO,cAAc,CACnB,qBAAqB,EACrB,IAAI,CAAC,QAAQ,CAAC,SAAS,EACvB,IAAI,CAAC,QAAQ,CAAC,UAAU,EACxB,OAAO,CACR,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,cAAc,CAAC,QAA6C;QAC1D,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC;QAE7B,MAAM,IAAI,GAAS;YACjB,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,YAAY,EAAE,OAAO,CAAC,YAAY;YAClC,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,QAAQ,IAAI,QAAQ,CAAC,SAAS;YAC1D,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAC3B,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAC3B,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,OAAO;aAClC,CAAC,CAAC,CAAC,SAAS;SACd,CAAC;QAEF,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CACH,SAAoC,EACpC,KAAsB,EACtB,OAAoD;QAEpD,OAAO;YACL,SAAS;YACT,KAAK;YACL,OAAO;SACR,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,WAAW,CACT,QAA0C;QAE1C,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC;QAC7B,IAAI,KAAK,GAAW,EAAE,CAAC;QAEvB,8BAA8B;QAC9B,IAAI,OAAO,CAAC,SAAS,KAAK,MAAM,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACtE,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACzD,CAAC;aAAM,IAAI,OAAO,CAAC,SAAS,KAAK,KAAK,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC5E,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAClD,CAAC;aAAM,IAAI,OAAO,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;YAC1C,gDAAgD;YAChD,gCAAgC;YAChC,KAAK,GAAG,EAAE,CAAC;QACb,CAAC;QAED,gBAAgB;QAChB,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC;QACrC,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC;QAElC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACrC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QAChC,CAAC;QAED,qCAAqC;QACrC,MAAM,aAAa,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACvC,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACxB,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;gBACxB,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO;gBAC9B,QAAQ,EAAE,IAAI,CAAC,QAAQ;aACxB,CAAC,CAAC,CAAC;gBACF,QAAQ,EAAE,IAAI,CAAC,QAAQ;aACxB;YACD,yDAAyD;YACzD,UAAU,EAAE,SAAS;SACtB,CAAC,CAAC,CAAC;QAEJ,MAAM,eAAe,GAA8B;YACjD,OAAO,EAAE,QAAQ,CAAC,EAAE;YACpB,KAAK,EAAE,aAAa;YACpB,YAAY;SACb,CAAC;QAEF,OAAO,cAAc,CACnB,qBAAqB,EACrB,IAAI,CAAC,QAAQ,CAAC,SAAS,EACvB,IAAI,CAAC,QAAQ,CAAC,UAAU,EACxB,eAAe,EACf,QAAQ,CAAC,EAAE,CAAC,YAAY;SACzB,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,QAAgB;QACzB,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACxC,CAAC;CACF"}
@@ -47,4 +47,59 @@ export interface DiscoverResponsePayload {
47
47
  };
48
48
  }>;
49
49
  }
50
+ /**
51
+ * Payload for 'capability_announce' messages.
52
+ * An agent publishes its capabilities to the network.
53
+ */
54
+ export interface CapabilityAnnouncePayload {
55
+ /** Agent's Ed25519 public key */
56
+ publicKey: string;
57
+ /** List of capabilities offered */
58
+ capabilities: Capability[];
59
+ /** Optional metadata */
60
+ metadata?: {
61
+ name?: string;
62
+ version?: string;
63
+ lastSeen?: number;
64
+ };
65
+ }
66
+ /**
67
+ * Payload for 'capability_query' messages.
68
+ * An agent queries the network for peers with specific capabilities.
69
+ */
70
+ export interface CapabilityQueryPayload {
71
+ /** Query type: by name, tag, or schema */
72
+ queryType: 'name' | 'tag' | 'schema';
73
+ /** Query value (capability name, tag, or JSON schema) */
74
+ query: string | object;
75
+ /** Optional filters */
76
+ filters?: {
77
+ /** Minimum trust score (RFC-001 integration) */
78
+ minTrustScore?: number;
79
+ /** Maximum results to return */
80
+ limit?: number;
81
+ };
82
+ }
83
+ /**
84
+ * Payload for 'capability_response' messages.
85
+ * Response to a capability_query with matching peers.
86
+ */
87
+ export interface CapabilityResponsePayload {
88
+ /** Query ID this is responding to */
89
+ queryId: string;
90
+ /** Matching peers */
91
+ peers: Array<{
92
+ publicKey: string;
93
+ capabilities: Capability[];
94
+ metadata?: {
95
+ name?: string;
96
+ version?: string;
97
+ lastSeen?: number;
98
+ };
99
+ /** Trust score from RFC-001 (Phase 2b) */
100
+ trustScore?: number;
101
+ }>;
102
+ /** Total matching peers (may be > peers.length if limited) */
103
+ totalMatches: number;
104
+ }
50
105
  //# sourceMappingURL=messages.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/registry/messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,qCAAqC;IACrC,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3B,wCAAwC;IACxC,QAAQ,CAAC,EAAE;QACT,gCAAgC;QAChC,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,6BAA6B;QAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,qCAAqC;IACrC,KAAK,EAAE;QACL,gCAAgC;QAChC,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,+BAA+B;QAC/B,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,yCAAyC;IACzC,KAAK,EAAE,KAAK,CAAC;QACX,6BAA6B;QAC7B,SAAS,EAAE,MAAM,CAAC;QAClB,mCAAmC;QACnC,YAAY,EAAE,UAAU,EAAE,CAAC;QAC3B,uCAAuC;QACvC,QAAQ,CAAC,EAAE;YACT,+BAA+B;YAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,4BAA4B;YAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;SAClB,CAAC;KACH,CAAC,CAAC;CACJ"}
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/registry/messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,qCAAqC;IACrC,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3B,wCAAwC;IACxC,QAAQ,CAAC,EAAE;QACT,gCAAgC;QAChC,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,6BAA6B;QAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,qCAAqC;IACrC,KAAK,EAAE;QACL,gCAAgC;QAChC,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,+BAA+B;QAC/B,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,yCAAyC;IACzC,KAAK,EAAE,KAAK,CAAC;QACX,6BAA6B;QAC7B,SAAS,EAAE,MAAM,CAAC;QAClB,mCAAmC;QACnC,YAAY,EAAE,UAAU,EAAE,CAAC;QAC3B,uCAAuC;QACvC,QAAQ,CAAC,EAAE;YACT,+BAA+B;YAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,4BAA4B;YAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;SAClB,CAAC;KACH,CAAC,CAAC;CACJ;AAED;;;GAGG;AACH,MAAM,WAAW,yBAAyB;IACxC,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3B,wBAAwB;IACxB,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,0CAA0C;IAC1C,SAAS,EAAE,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;IACrC,yDAAyD;IACzD,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,uBAAuB;IACvB,OAAO,CAAC,EAAE;QACR,gDAAgD;QAChD,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,gCAAgC;QAChC,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED;;;GAGG;AACH,MAAM,WAAW,yBAAyB;IACxC,qCAAqC;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,qBAAqB;IACrB,KAAK,EAAE,KAAK,CAAC;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,EAAE,UAAU,EAAE,CAAC;QAC3B,QAAQ,CAAC,EAAE;YACT,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,CAAC;QACF,0CAA0C;QAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC,CAAC;IACH,8DAA8D;IAC9D,YAAY,EAAE,MAAM,CAAC;CACtB"}
@@ -0,0 +1,112 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { type Envelope } from '../message/envelope.js';
3
+ import type { RelayPeer } from './types.js';
4
+ /**
5
+ * Configuration for RelayClient
6
+ */
7
+ export interface RelayClientConfig {
8
+ /** WebSocket URL of the relay server */
9
+ relayUrl: string;
10
+ /** Agent's public key */
11
+ publicKey: string;
12
+ /** Agent's private key (for signing) */
13
+ privateKey: string;
14
+ /** Optional name for this agent */
15
+ name?: string;
16
+ /** Keepalive ping interval in milliseconds (default: 30000) */
17
+ pingInterval?: number;
18
+ /** Maximum reconnection delay in milliseconds (default: 60000) */
19
+ maxReconnectDelay?: number;
20
+ }
21
+ /**
22
+ * Events emitted by RelayClient
23
+ */
24
+ export interface RelayClientEvents {
25
+ /** Emitted when successfully connected and registered */
26
+ 'connected': () => void;
27
+ /** Emitted when disconnected from relay */
28
+ 'disconnected': () => void;
29
+ /** Emitted when a verified message is received */
30
+ 'message': (envelope: Envelope, from: string, fromName?: string) => void;
31
+ /** Emitted when a peer comes online */
32
+ 'peer_online': (peer: RelayPeer) => void;
33
+ /** Emitted when a peer goes offline */
34
+ 'peer_offline': (peer: RelayPeer) => void;
35
+ /** Emitted on errors */
36
+ 'error': (error: Error) => void;
37
+ }
38
+ /**
39
+ * Persistent WebSocket client for the Agora relay server.
40
+ * Maintains a long-lived connection, handles reconnection, and routes messages.
41
+ */
42
+ export declare class RelayClient extends EventEmitter {
43
+ private ws;
44
+ private config;
45
+ private reconnectAttempts;
46
+ private reconnectTimeout;
47
+ private pingInterval;
48
+ private isConnected;
49
+ private isRegistered;
50
+ private shouldReconnect;
51
+ private onlinePeers;
52
+ constructor(config: RelayClientConfig);
53
+ /**
54
+ * Connect to the relay server
55
+ */
56
+ connect(): Promise<void>;
57
+ /**
58
+ * Disconnect from the relay server
59
+ */
60
+ disconnect(): void;
61
+ /**
62
+ * Check if currently connected and registered
63
+ */
64
+ connected(): boolean;
65
+ /**
66
+ * Send a message to a specific peer
67
+ */
68
+ send(to: string, envelope: Envelope): Promise<{
69
+ ok: boolean;
70
+ error?: string;
71
+ }>;
72
+ /**
73
+ * Broadcast a message to all connected peers
74
+ */
75
+ broadcast(envelope: Envelope): Promise<{
76
+ ok: boolean;
77
+ error?: string;
78
+ }>;
79
+ /**
80
+ * Get list of currently online peers
81
+ */
82
+ getOnlinePeers(): RelayPeer[];
83
+ /**
84
+ * Check if a specific peer is online
85
+ */
86
+ isPeerOnline(publicKey: string): boolean;
87
+ /**
88
+ * Internal: Perform connection
89
+ */
90
+ private doConnect;
91
+ /**
92
+ * Handle incoming message from relay
93
+ */
94
+ private handleMessage;
95
+ /**
96
+ * Schedule reconnection with exponential backoff
97
+ */
98
+ private scheduleReconnect;
99
+ /**
100
+ * Start periodic ping messages
101
+ */
102
+ private startPingInterval;
103
+ /**
104
+ * Stop ping interval
105
+ */
106
+ private stopPingInterval;
107
+ /**
108
+ * Cleanup resources
109
+ */
110
+ private cleanup;
111
+ }
112
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/relay/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,KAAK,EAA0C,SAAS,EAAE,MAAM,YAAY,CAAC;AAEpF;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,mCAAmC;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kEAAkE;IAClE,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,yDAAyD;IACzD,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,2CAA2C;IAC3C,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,kDAAkD;IAClD,SAAS,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACzE,uCAAuC;IACvC,aAAa,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IACzC,uCAAuC;IACvC,cAAc,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IAC1C,wBAAwB;IACxB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACjC;AAED;;;GAGG;AACH,qBAAa,WAAY,SAAQ,YAAY;IAC3C,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,gBAAgB,CAA+B;IACvD,OAAO,CAAC,YAAY,CAA+B;IACnD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,eAAe,CAAQ;IAC/B,OAAO,CAAC,WAAW,CAAgC;gBAEvC,MAAM,EAAE,iBAAiB;IASrC;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAS9B;;OAEG;IACH,UAAU,IAAI,IAAI;IASlB;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACG,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAmBpF;;OAEG;IACG,SAAS,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAkB7E;;OAEG;IACH,cAAc,IAAI,SAAS,EAAE;IAI7B;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAIxC;;OAEG;YACW,SAAS;IAoEvB;;OAEG;IACH,OAAO,CAAC,aAAa;IAoErB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAuBzB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAUzB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAOxB;;OAEG;IACH,OAAO,CAAC,OAAO;CAQhB"}