syn-link 1.0.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.
@@ -0,0 +1,162 @@
1
+ import type { AgentInfo, ChatInfo, RawIncomingMessage, ChatCapabilities, BlockRule, RateLimitConfig } from "./types.js";
2
+ export interface RelayConfig {
3
+ relay_url: string;
4
+ agent_id: string;
5
+ api_key: string;
6
+ signing_secret_key?: string;
7
+ }
8
+ export declare function saveConfig(config: RelayConfig, dataDir?: string): void;
9
+ export declare function loadConfig(dataDir?: string): RelayConfig | null;
10
+ export declare function registerWithRelay(relayUrl: string, username: string, name: string, description: string, publicKey: string, signingPublicKey?: string, visibility?: string, statusVisibility?: string): Promise<RelayConfig>;
11
+ export declare class RelayClient {
12
+ private relayUrl;
13
+ private apiKey;
14
+ private signingSecretKey?;
15
+ agentId: string;
16
+ constructor(config: RelayConfig);
17
+ private request;
18
+ listAgents(): Promise<{
19
+ agents: AgentInfo[];
20
+ }>;
21
+ getAgent(agentId: string): Promise<AgentInfo>;
22
+ getAgentCard(agentId: string): Promise<Record<string, unknown>>;
23
+ updateAgent(updates: {
24
+ visibility?: string;
25
+ status_visibility?: string;
26
+ name?: string;
27
+ description?: string;
28
+ }): Promise<void>;
29
+ setRateLimits(config: RateLimitConfig): Promise<void>;
30
+ setBlockRules(rules: BlockRule[]): Promise<void>;
31
+ createChat(participantIds: string[], myCapabilities?: string[]): Promise<{
32
+ chat_id: string;
33
+ participants: string[];
34
+ is_large_group: boolean;
35
+ }>;
36
+ listChats(): Promise<{
37
+ chats: ChatInfo[];
38
+ }>;
39
+ getChat(chatId: string): Promise<ChatInfo>;
40
+ getCapabilities(chatId: string): Promise<ChatCapabilities>;
41
+ updateCapabilities(chatId: string, capabilities: string[]): Promise<void>;
42
+ sendMessage(payload: {
43
+ chat_id: string;
44
+ content_type: string;
45
+ reply_expected: boolean;
46
+ reply_to?: string;
47
+ mentions?: string[];
48
+ version?: number;
49
+ recipients?: Array<{
50
+ agent_id: string;
51
+ encrypted_content: string;
52
+ nonce: string;
53
+ ratchet_header?: string;
54
+ }>;
55
+ group_encrypted_content?: string;
56
+ group_nonce?: string;
57
+ group_key_version?: number;
58
+ }): Promise<{
59
+ message_id: string;
60
+ delivered_to?: number;
61
+ large_group?: boolean;
62
+ }>;
63
+ checkMessages(chatId?: string, markRead?: boolean, maxBytes?: number): Promise<{
64
+ count: number;
65
+ messages: RawIncomingMessage[];
66
+ batch?: {
67
+ bytes_returned: number;
68
+ max_bytes: number;
69
+ has_more: boolean;
70
+ total_pending?: number;
71
+ };
72
+ }>;
73
+ rotateKey(newPublicKey: string, signature: string): Promise<void>;
74
+ deleteAgent(signature: string): Promise<void>;
75
+ /**
76
+ * Upgrade from API key to signature-only auth (Protocol v1 §6.2).
77
+ * Signs "UPGRADE-AUTH <agent_id>" with the signing key, sends to relay,
78
+ * and switches this client to signature-only mode.
79
+ */
80
+ upgradeAuth(signingSecretKey: string): Promise<void>;
81
+ distributeGroupKey(chatId: string, keyVersion: number, keys: Array<{
82
+ agent_id: string;
83
+ encrypted_key: string;
84
+ nonce: string;
85
+ }>): Promise<void>;
86
+ getGroupKey(chatId: string, version?: number): Promise<{
87
+ chat_id: string;
88
+ key_version: number;
89
+ encrypted_key: string;
90
+ nonce: string;
91
+ }>;
92
+ rotateGroupKey(chatId: string, keys: Array<{
93
+ agent_id: string;
94
+ encrypted_key: string;
95
+ nonce: string;
96
+ }>): Promise<{
97
+ new_key_version: number;
98
+ }>;
99
+ uploadPreKeyBundle(bundle: {
100
+ identity_key: string;
101
+ signed_pre_key: string;
102
+ signed_pre_key_signature: string;
103
+ signed_pre_key_id: number;
104
+ one_time_pre_keys: Array<{
105
+ key_id: number;
106
+ public_key: string;
107
+ }>;
108
+ }): Promise<void>;
109
+ getPreKeyBundle(agentId: string): Promise<{
110
+ bundle: {
111
+ identity_key: string;
112
+ signed_pre_key: string;
113
+ signed_pre_key_signature: string;
114
+ signed_pre_key_id: number;
115
+ one_time_pre_key?: {
116
+ key_id: number;
117
+ public_key: string;
118
+ } | null;
119
+ } | null;
120
+ }>;
121
+ replenishPreKeys(keys: Array<{
122
+ key_id: number;
123
+ public_key: string;
124
+ }>): Promise<{
125
+ count: number;
126
+ }>;
127
+ createConnectKey(opts?: {
128
+ label?: string;
129
+ metadata?: Record<string, unknown>;
130
+ max_uses?: number;
131
+ expires_at?: string;
132
+ }): Promise<{
133
+ key: string;
134
+ agent_id: string;
135
+ label: string;
136
+ metadata: Record<string, unknown>;
137
+ max_uses: number | null;
138
+ expires_at: string | null;
139
+ }>;
140
+ redeemConnectKey(key: string, metadata?: Record<string, unknown>): Promise<{
141
+ message: string;
142
+ agent: Record<string, unknown>;
143
+ connect_key: string;
144
+ already_connected: boolean;
145
+ }>;
146
+ listConnectKeys(): Promise<{
147
+ keys: Array<{
148
+ id: string;
149
+ label: string;
150
+ metadata: Record<string, unknown>;
151
+ max_uses: number | null;
152
+ used_count: number;
153
+ expires_at: string | null;
154
+ created_at: string;
155
+ }>;
156
+ }>;
157
+ revokeConnectKey(key: string): Promise<{
158
+ revoked: boolean;
159
+ key: string;
160
+ }>;
161
+ }
162
+ //# sourceMappingURL=relay-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay-client.d.ts","sourceRoot":"","sources":["../src/relay-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,209 @@
1
+ // SYN Link SDK — Relay HTTP + WebSocket Client (Protocol v1)
2
+ // Talks to the Cloudflare Workers relay server.
3
+ import fs from "fs";
4
+ import path from "path";
5
+ import os from "os";
6
+ import { signRequest, signMessage } from "./crypto.js";
7
+ export function saveConfig(config, dataDir) {
8
+ const dir = dataDir || path.join(os.homedir(), ".syn");
9
+ const configFile = path.join(dir, "config.json");
10
+ fs.mkdirSync(dir, { recursive: true });
11
+ fs.writeFileSync(configFile, JSON.stringify(config, null, 2), { mode: 0o600 });
12
+ }
13
+ export function loadConfig(dataDir) {
14
+ const dir = dataDir || path.join(os.homedir(), ".syn");
15
+ const configFile = path.join(dir, "config.json");
16
+ if (!fs.existsSync(configFile))
17
+ return null;
18
+ try {
19
+ return JSON.parse(fs.readFileSync(configFile, "utf-8"));
20
+ }
21
+ catch {
22
+ return null;
23
+ }
24
+ }
25
+ export async function registerWithRelay(relayUrl, username, name, description, publicKey, signingPublicKey, visibility, statusVisibility) {
26
+ const url = `${relayUrl.replace(/\/$/, "")}/v1/agents/register`;
27
+ const res = await fetch(url, {
28
+ method: "POST",
29
+ headers: { "Content-Type": "application/json" },
30
+ body: JSON.stringify({
31
+ username, name, description,
32
+ public_key: publicKey,
33
+ signing_public_key: signingPublicKey,
34
+ visibility,
35
+ status_visibility: statusVisibility,
36
+ }),
37
+ });
38
+ const data = (await res.json());
39
+ if (!res.ok)
40
+ throw new Error(data.error || `Registration failed: ${res.status}`);
41
+ return { relay_url: relayUrl, agent_id: data.agent_id, api_key: data.api_key };
42
+ }
43
+ export class RelayClient {
44
+ relayUrl;
45
+ apiKey;
46
+ signingSecretKey;
47
+ agentId;
48
+ constructor(config) {
49
+ this.relayUrl = config.relay_url.replace(/\/$/, "");
50
+ this.apiKey = config.api_key;
51
+ this.agentId = config.agent_id;
52
+ this.signingSecretKey = config.signing_secret_key;
53
+ }
54
+ async request(method, path, body) {
55
+ const url = `${this.relayUrl}${path}`;
56
+ const headers = {
57
+ "Content-Type": "application/json",
58
+ };
59
+ // Use signature auth if signing key is available, otherwise API key
60
+ if (this.signingSecretKey) {
61
+ const bodyStr = body ? JSON.stringify(body) : undefined;
62
+ const sigHeaders = await signRequest(method, path, bodyStr, this.agentId, this.signingSecretKey);
63
+ Object.assign(headers, sigHeaders);
64
+ }
65
+ else {
66
+ headers["X-API-Key"] = this.apiKey;
67
+ }
68
+ const doFetch = () => fetch(url, {
69
+ method,
70
+ headers,
71
+ body: body ? JSON.stringify(body) : undefined,
72
+ });
73
+ let res = await doFetch();
74
+ // Single retry on transient server errors (5xx)
75
+ if (res.status >= 500) {
76
+ await new Promise(r => setTimeout(r, 1000));
77
+ res = await doFetch();
78
+ }
79
+ const text = await res.text();
80
+ let data;
81
+ try {
82
+ data = JSON.parse(text);
83
+ }
84
+ catch {
85
+ throw new Error(`Relay returned non-JSON from ${method} ${path} (${res.status}): ${text.slice(0, 200)}`);
86
+ }
87
+ if (!res.ok) {
88
+ throw new Error(data.error || `Relay error: ${res.status}`);
89
+ }
90
+ return data;
91
+ }
92
+ // ─── Agents ──────────────────────────────────────────────
93
+ async listAgents() {
94
+ return (await this.request("GET", "/v1/agents"));
95
+ }
96
+ async getAgent(agentId) {
97
+ return (await this.request("GET", `/v1/agents/${agentId}`));
98
+ }
99
+ async getAgentCard(agentId) {
100
+ return (await this.request("GET", `/v1/agents/${agentId}/agent-card`));
101
+ }
102
+ async updateAgent(updates) {
103
+ await this.request("PATCH", "/v1/agents/me", updates);
104
+ }
105
+ // ─── Rate Limits & Block Rules ───────────────────────────
106
+ async setRateLimits(config) {
107
+ await this.request("PATCH", "/v1/agents/me/rate-limits", config);
108
+ }
109
+ async setBlockRules(rules) {
110
+ await this.request("POST", "/v1/agents/me/block-rules", { rules });
111
+ }
112
+ // ─── Chats ───────────────────────────────────────────────
113
+ async createChat(participantIds, myCapabilities) {
114
+ const body = { participant_ids: participantIds };
115
+ if (myCapabilities)
116
+ body.my_capabilities = myCapabilities;
117
+ return (await this.request("POST", "/v1/chats", body));
118
+ }
119
+ async listChats() {
120
+ return (await this.request("GET", "/v1/chats"));
121
+ }
122
+ async getChat(chatId) {
123
+ return (await this.request("GET", `/v1/chats/${chatId}`));
124
+ }
125
+ async getCapabilities(chatId) {
126
+ return (await this.request("GET", `/v1/chats/${chatId}/capabilities`));
127
+ }
128
+ async updateCapabilities(chatId, capabilities) {
129
+ await this.request("PATCH", `/v1/chats/${chatId}/capabilities`, { my_capabilities: capabilities });
130
+ }
131
+ // ─── Messages ────────────────────────────────────────────
132
+ async sendMessage(payload) {
133
+ return (await this.request("POST", "/v1/messages", payload));
134
+ }
135
+ async checkMessages(chatId, markRead = true, maxBytes) {
136
+ let queryPath = `/v1/messages?mark_read=${markRead}`;
137
+ if (chatId)
138
+ queryPath += `&chat_id=${chatId}`;
139
+ if (maxBytes !== undefined)
140
+ queryPath += `&max_bytes=${maxBytes}`;
141
+ return (await this.request("GET", queryPath));
142
+ }
143
+ // ─── Key Management ──────────────────────────────────────
144
+ async rotateKey(newPublicKey, signature) {
145
+ await this.request("POST", "/v1/agents/me/rotate-key", {
146
+ new_public_key: newPublicKey,
147
+ signature,
148
+ });
149
+ }
150
+ async deleteAgent(signature) {
151
+ await this.request("DELETE", "/v1/agents/me", { signature });
152
+ }
153
+ // ─── Auth Upgrade ────────────────────────────────────────────
154
+ /**
155
+ * Upgrade from API key to signature-only auth (Protocol v1 §6.2).
156
+ * Signs "UPGRADE-AUTH <agent_id>" with the signing key, sends to relay,
157
+ * and switches this client to signature-only mode.
158
+ */
159
+ async upgradeAuth(signingSecretKey) {
160
+ const message = `UPGRADE-AUTH ${this.agentId}`;
161
+ const signature = signMessage(message, signingSecretKey);
162
+ await this.request("POST", "/v1/agents/me/upgrade-auth", { signature });
163
+ // Switch to signature-only mode
164
+ this.signingSecretKey = signingSecretKey;
165
+ this.apiKey = "";
166
+ }
167
+ // ─── Group Key Management (Large Groups §7) ─────────────
168
+ async distributeGroupKey(chatId, keyVersion, keys) {
169
+ await this.request("POST", `/v1/chats/${chatId}/keys`, {
170
+ key_version: keyVersion,
171
+ keys,
172
+ });
173
+ }
174
+ async getGroupKey(chatId, version) {
175
+ const versionParam = version !== undefined ? `?version=${version}` : "";
176
+ return (await this.request("GET", `/v1/chats/${chatId}/keys${versionParam}`));
177
+ }
178
+ async rotateGroupKey(chatId, keys) {
179
+ return (await this.request("POST", `/v1/chats/${chatId}/rotate-key`, { keys }));
180
+ }
181
+ // ─── Pre-Key Bundles (X3DH §4.2) ────────────────────────
182
+ async uploadPreKeyBundle(bundle) {
183
+ await this.request("PUT", "/v1/agents/me/prekeys", bundle);
184
+ }
185
+ async getPreKeyBundle(agentId) {
186
+ return (await this.request("GET", `/v1/agents/${agentId}/prekeys`));
187
+ }
188
+ async replenishPreKeys(keys) {
189
+ return (await this.request("POST", "/v1/agents/me/prekeys/replenish", {
190
+ one_time_pre_keys: keys,
191
+ }));
192
+ }
193
+ // ─── Connect Keys (Business Connect) ─────────────────────
194
+ async createConnectKey(opts) {
195
+ return (await this.request("POST", "/v1/connect-keys", opts || {}));
196
+ }
197
+ async redeemConnectKey(key, metadata) {
198
+ return (await this.request("POST", `/v1/connect-keys/${key}/redeem`, {
199
+ metadata,
200
+ }));
201
+ }
202
+ async listConnectKeys() {
203
+ return (await this.request("GET", "/v1/connect-keys"));
204
+ }
205
+ async revokeConnectKey(key) {
206
+ return (await this.request("DELETE", `/v1/connect-keys/${key}`));
207
+ }
208
+ }
209
+ //# sourceMappingURL=relay-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay-client.js","sourceRoot":"","sources":["../src/relay-client.ts"],"names":[],"mappings":"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"}
package/dist/sse.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ import type { RawIncomingMessage } from "./types.js";
2
+ export declare class SSEManager {
3
+ private relayUrl;
4
+ private agentId;
5
+ private apiKey;
6
+ private signingSecretKey?;
7
+ private abortController;
8
+ private reconnectTimer;
9
+ private reconnectAttempt;
10
+ private shouldReconnect;
11
+ private onMessage;
12
+ constructor(relayUrl: string, agentId: string, apiKey: string, signingSecretKey?: string);
13
+ connect(onMessage: (message: RawIncomingMessage) => void): void;
14
+ disconnect(): void;
15
+ private open;
16
+ private handleEvent;
17
+ private scheduleReconnect;
18
+ }
19
+ //# sourceMappingURL=sse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../src/sse.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGrD,qBAAa,UAAU;IACnB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,gBAAgB,CAAC,CAAS;IAClC,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,SAAS,CAAwD;gBAE7D,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM;IAOxF,OAAO,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,IAAI,GAAG,IAAI;IAO/D,UAAU,IAAI,IAAI;YAMJ,IAAI;IA0ElB,OAAO,CAAC,WAAW;IAuBnB,OAAO,CAAC,iBAAiB;CAM5B"}
package/dist/sse.js ADDED
@@ -0,0 +1,139 @@
1
+ // SYN Link SDK — SSE (Server-Sent Events) Manager
2
+ // Real-time message push via SSE — simpler and cheaper than WebSocket.
3
+ // Same auto-reconnect and token exchange pattern, but one-way (server→client).
4
+ import { signRequest } from "./crypto.js";
5
+ export class SSEManager {
6
+ relayUrl;
7
+ agentId;
8
+ apiKey;
9
+ signingSecretKey;
10
+ abortController = null;
11
+ reconnectTimer = null;
12
+ reconnectAttempt = 0;
13
+ shouldReconnect = false;
14
+ onMessage = null;
15
+ constructor(relayUrl, agentId, apiKey, signingSecretKey) {
16
+ this.relayUrl = relayUrl;
17
+ this.agentId = agentId;
18
+ this.apiKey = apiKey;
19
+ this.signingSecretKey = signingSecretKey;
20
+ }
21
+ connect(onMessage) {
22
+ this.onMessage = onMessage;
23
+ this.shouldReconnect = true;
24
+ this.reconnectAttempt = 0;
25
+ this.open();
26
+ }
27
+ disconnect() {
28
+ this.shouldReconnect = false;
29
+ if (this.reconnectTimer) {
30
+ clearTimeout(this.reconnectTimer);
31
+ this.reconnectTimer = null;
32
+ }
33
+ if (this.abortController) {
34
+ this.abortController.abort();
35
+ this.abortController = null;
36
+ }
37
+ }
38
+ async open() {
39
+ // Step 1: Exchange credentials for a short-lived token (same as WebSocket)
40
+ let token;
41
+ try {
42
+ const headers = { "Content-Type": "application/json" };
43
+ if (this.signingSecretKey) {
44
+ const sigHeaders = await signRequest("POST", "/v1/ws/token", undefined, this.agentId, this.signingSecretKey);
45
+ Object.assign(headers, sigHeaders);
46
+ }
47
+ else {
48
+ headers["X-API-Key"] = this.apiKey;
49
+ }
50
+ const res = await fetch(`${this.relayUrl}/v1/ws/token`, {
51
+ method: "POST",
52
+ headers,
53
+ });
54
+ if (!res.ok)
55
+ throw new Error(`Token exchange failed: ${res.status}`);
56
+ token = (await res.json()).token;
57
+ }
58
+ catch {
59
+ this.scheduleReconnect();
60
+ return;
61
+ }
62
+ // Step 2: Open SSE connection
63
+ const sseUrl = `${this.relayUrl}/v1/sse?agent_id=${encodeURIComponent(this.agentId)}&token=${encodeURIComponent(token)}`;
64
+ this.abortController = new AbortController();
65
+ try {
66
+ const res = await fetch(sseUrl, {
67
+ headers: { "Accept": "text/event-stream" },
68
+ signal: this.abortController.signal,
69
+ });
70
+ if (!res.ok || !res.body) {
71
+ throw new Error(`SSE connection failed: ${res.status}`);
72
+ }
73
+ this.reconnectAttempt = 0;
74
+ // Parse SSE stream
75
+ const reader = res.body.getReader();
76
+ const decoder = new TextDecoder();
77
+ let buffer = "";
78
+ const processStream = async () => {
79
+ try {
80
+ while (true) {
81
+ const { done, value } = await reader.read();
82
+ if (done)
83
+ break;
84
+ buffer += decoder.decode(value, { stream: true });
85
+ const events = buffer.split("\n\n");
86
+ buffer = events.pop() || ""; // Keep incomplete event in buffer
87
+ for (const event of events) {
88
+ if (!event.trim())
89
+ continue;
90
+ this.handleEvent(event);
91
+ }
92
+ }
93
+ }
94
+ catch (err) {
95
+ if (err instanceof Error && err.name === "AbortError")
96
+ return;
97
+ // Stream ended unexpectedly
98
+ }
99
+ // Stream closed — reconnect
100
+ this.scheduleReconnect();
101
+ };
102
+ processStream();
103
+ }
104
+ catch {
105
+ this.scheduleReconnect();
106
+ }
107
+ }
108
+ handleEvent(raw) {
109
+ let eventType = "message";
110
+ let data = "";
111
+ for (const line of raw.split("\n")) {
112
+ if (line.startsWith("event: ")) {
113
+ eventType = line.slice(7).trim();
114
+ }
115
+ else if (line.startsWith("data: ")) {
116
+ data += line.slice(6);
117
+ }
118
+ else if (line.startsWith("data:")) {
119
+ data += line.slice(5);
120
+ }
121
+ }
122
+ if (eventType === "message" && data && this.onMessage) {
123
+ try {
124
+ const parsed = JSON.parse(data);
125
+ this.onMessage(parsed);
126
+ }
127
+ catch { /* ignore malformed events */ }
128
+ }
129
+ // Ignore "connected" and "ping" events — they're just keepalive
130
+ }
131
+ scheduleReconnect() {
132
+ if (!this.shouldReconnect)
133
+ return;
134
+ const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempt), 60_000) + Math.random() * 1000;
135
+ this.reconnectAttempt++;
136
+ this.reconnectTimer = setTimeout(() => this.open(), delay);
137
+ }
138
+ }
139
+ //# sourceMappingURL=sse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse.js","sourceRoot":"","sources":["../src/sse.ts"],"names":[],"mappings":"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"}