@shadowob/sdk 1.1.1 → 1.1.3-dev.261

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,10 +1,46 @@
1
1
  // src/client.ts
2
+ function sanitizeErrorBody(body) {
3
+ if (!body) return "(empty response)";
4
+ if (!/<[^>]+>/.test(body)) return body.slice(0, 500);
5
+ const titleMatch = /<title>([^<]+)<\/title>/i.exec(body);
6
+ if (titleMatch?.[1]) return titleMatch[1].trim();
7
+ const text = body.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
8
+ return text.slice(0, 200) || "(HTML error page)";
9
+ }
10
+ function contentDispositionFilename(header) {
11
+ if (!header) return null;
12
+ const utf8Match = /filename\*=UTF-8''([^;]+)/i.exec(header);
13
+ if (utf8Match?.[1]) {
14
+ try {
15
+ return decodeURIComponent(utf8Match[1].trim());
16
+ } catch {
17
+ return utf8Match[1].trim();
18
+ }
19
+ }
20
+ const quotedMatch = /filename="([^"]+)"/i.exec(header);
21
+ if (quotedMatch?.[1]) return quotedMatch[1];
22
+ const bareMatch = /filename=([^;]+)/i.exec(header);
23
+ return bareMatch?.[1]?.trim() ?? null;
24
+ }
2
25
  var ShadowClient = class {
3
26
  constructor(baseUrl, token) {
4
27
  this.token = token;
5
28
  this.baseUrl = baseUrl.replace(/\/api\/?$/, "");
6
29
  }
7
30
  baseUrl;
31
+ isShadowPrivateMediaUrl(value) {
32
+ if (value.startsWith("/shadow/uploads/") || value.startsWith("/api/media/signed/")) {
33
+ return true;
34
+ }
35
+ if (!/^https?:\/\//.test(value)) return false;
36
+ try {
37
+ const url = new URL(value);
38
+ const base = new URL(this.baseUrl);
39
+ return url.origin === base.origin && (url.pathname.startsWith("/shadow/uploads/") || url.pathname.startsWith("/api/media/signed/"));
40
+ } catch {
41
+ return false;
42
+ }
43
+ }
8
44
  async request(path, init) {
9
45
  const url = `${this.baseUrl}${path}`;
10
46
  const controller = new AbortController();
@@ -21,11 +57,19 @@ var ShadowClient = class {
21
57
  });
22
58
  if (!res.ok) {
23
59
  const body = await res.text().catch(() => "");
60
+ const message = sanitizeErrorBody(body);
24
61
  throw new Error(
25
- `Shadow API ${init?.method ?? "GET"} ${path} failed (${res.status}): ${body}`
62
+ `Shadow API ${init?.method ?? "GET"} ${path} failed (${res.status}): ${message}`
26
63
  );
27
64
  }
28
- return res.json();
65
+ const payload = await res.json();
66
+ if (payload && typeof payload === "object" && !Array.isArray(payload) && "ok" in payload && !("success" in payload)) {
67
+ return {
68
+ ...payload,
69
+ success: Boolean(payload.ok)
70
+ };
71
+ }
72
+ return payload;
29
73
  } finally {
30
74
  clearTimeout(timeout);
31
75
  }
@@ -41,7 +85,10 @@ var ShadowClient = class {
41
85
  });
42
86
  if (!res.ok) {
43
87
  const body = await res.text().catch(() => "");
44
- throw new Error(`Shadow API ${init?.method ?? "GET"} ${path} failed (${res.status}): ${body}`);
88
+ const message = sanitizeErrorBody(body);
89
+ throw new Error(
90
+ `Shadow API ${init?.method ?? "GET"} ${path} failed (${res.status}): ${message}`
91
+ );
45
92
  }
46
93
  return res;
47
94
  }
@@ -58,8 +105,23 @@ var ShadowClient = class {
58
105
  body: JSON.stringify(data)
59
106
  });
60
107
  }
61
- async refreshToken() {
62
- return this.request("/api/auth/refresh", { method: "POST" });
108
+ async startEmailLogin(data) {
109
+ return this.request("/api/auth/email/start", {
110
+ method: "POST",
111
+ body: JSON.stringify(data)
112
+ });
113
+ }
114
+ async verifyEmailLogin(data) {
115
+ return this.request("/api/auth/email/verify", {
116
+ method: "POST",
117
+ body: JSON.stringify(data)
118
+ });
119
+ }
120
+ async refreshToken(refreshToken) {
121
+ return this.request("/api/auth/refresh", {
122
+ method: "POST",
123
+ body: JSON.stringify({ refreshToken })
124
+ });
63
125
  }
64
126
  async getMe() {
65
127
  return this.request("/api/auth/me");
@@ -73,9 +135,51 @@ var ShadowClient = class {
73
135
  async disconnect() {
74
136
  return this.request("/api/auth/disconnect", { method: "POST" });
75
137
  }
138
+ async getMembership() {
139
+ return this.request("/api/membership/me");
140
+ }
141
+ async redeemInviteCode(code) {
142
+ return this.request("/api/membership/redeem-invite", {
143
+ method: "POST",
144
+ body: JSON.stringify({ code })
145
+ });
146
+ }
147
+ async launchPlay(data) {
148
+ return this.request("/api/play/launch", {
149
+ method: "POST",
150
+ body: JSON.stringify(data)
151
+ });
152
+ }
153
+ async getPlayCatalog() {
154
+ const response = await this.request("/api/play/catalog");
155
+ return response.plays;
156
+ }
157
+ // ── Official Model Proxy ──────────────────────────────────────────────
158
+ async listOfficialModelProxyModels() {
159
+ return this.request("/api/ai/v1/models");
160
+ }
161
+ async getOfficialModelProxyBilling() {
162
+ return this.request("/api/ai/v1/billing");
163
+ }
164
+ async createOfficialChatCompletion(data) {
165
+ return this.request("/api/ai/v1/chat/completions", {
166
+ method: "POST",
167
+ body: JSON.stringify(data)
168
+ });
169
+ }
170
+ async createOfficialChatCompletionStream(data) {
171
+ return this.requestRaw("/api/ai/v1/chat/completions", {
172
+ method: "POST",
173
+ headers: { "Content-Type": "application/json" },
174
+ body: JSON.stringify({ ...data, stream: true })
175
+ });
176
+ }
76
177
  // ── Agents ────────────────────────────────────────────────────────────
77
- async listAgents() {
78
- return this.request("/api/agents");
178
+ async listAgents(options) {
179
+ const params = new URLSearchParams();
180
+ if (options?.includeRentals) params.set("includeRentals", "true");
181
+ const query = params.toString();
182
+ return this.request(`/api/agents${query ? `?${query}` : ""}`);
79
183
  }
80
184
  async createAgent(data) {
81
185
  return this.request("/api/agents", {
@@ -110,21 +214,62 @@ var ShadowClient = class {
110
214
  body: JSON.stringify({})
111
215
  });
112
216
  }
217
+ async reportAgentUsageSnapshot(agentId, snapshot) {
218
+ return this.request(`/api/agents/${agentId}/usage-snapshot`, {
219
+ method: "POST",
220
+ body: JSON.stringify(snapshot)
221
+ });
222
+ }
113
223
  async getAgentConfig(agentId) {
114
224
  return this.request(`/api/agents/${agentId}/config`);
115
225
  }
226
+ async updateAgentSlashCommands(agentId, commands) {
227
+ return this.request(`/api/agents/${agentId}/slash-commands`, {
228
+ method: "PUT",
229
+ body: JSON.stringify({ commands })
230
+ });
231
+ }
232
+ async getAgentSlashCommands(agentId) {
233
+ return this.request(`/api/agents/${agentId}/slash-commands`);
234
+ }
235
+ async listChannelSlashCommands(channelId) {
236
+ return this.request(
237
+ `/api/channels/${channelId}/slash-commands`
238
+ );
239
+ }
116
240
  // ── Agent Policies ────────────────────────────────────────────────────
117
241
  async listPolicies(agentId, serverId) {
118
- return this.request(`/api/agents/${agentId}/servers/${serverId}/policies`);
242
+ const policies = await this.request(`/api/agents/${agentId}/policies`);
243
+ if (!serverId) return policies;
244
+ return policies.filter((policy) => policy.serverId === serverId);
119
245
  }
120
246
  async upsertPolicy(agentId, serverId, data) {
121
- return this.request(`/api/agents/${agentId}/servers/${serverId}/policies`, {
247
+ const policy = {
248
+ serverId,
249
+ ...data.channelId !== void 0 ? { channelId: data.channelId } : {},
250
+ ...data.mentionOnly !== void 0 ? { mentionOnly: data.mentionOnly } : {},
251
+ ...data.reply !== void 0 ? { reply: data.reply } : {},
252
+ ...data.config !== void 0 ? { config: data.config } : {}
253
+ };
254
+ const results = await this.request(`/api/agents/${agentId}/policies`, {
122
255
  method: "PUT",
123
- body: JSON.stringify(data)
256
+ body: JSON.stringify({ policies: [policy] })
124
257
  });
258
+ const [result] = results;
259
+ if (!result) {
260
+ throw new Error(`Shadow API PUT /api/agents/${agentId}/policies returned no policy result`);
261
+ }
262
+ return result;
125
263
  }
126
264
  async deletePolicy(agentId, serverId, channelId) {
127
- return this.request(`/api/agents/${agentId}/servers/${serverId}/policies/${channelId}`, {
265
+ const policies = await this.listPolicies(agentId, serverId);
266
+ const policy = policies.find((entry) => entry.channelId === channelId);
267
+ if (!policy?.id) {
268
+ throw new Error(
269
+ `Shadow policy not found for agent ${agentId} in server ${serverId} channel ${channelId}`
270
+ );
271
+ }
272
+ return this.request(`/api/agents/${agentId}/policies/${policy.id}`, {
128
273
  method: "DELETE"
129
274
  });
130
275
  }
@@ -147,6 +292,9 @@ var ShadowClient = class {
147
292
  async getServer(serverIdOrSlug) {
148
293
  return this.request(`/api/servers/${serverIdOrSlug}`);
149
294
  }
295
+ async getServerAccess(serverIdOrSlug) {
296
+ return this.request(`/api/servers/${serverIdOrSlug}/access`);
297
+ }
150
298
  async updateServer(serverIdOrSlug, data) {
151
299
  return this.request(`/api/servers/${serverIdOrSlug}`, {
152
300
  method: "PATCH",
@@ -165,6 +313,20 @@ var ShadowClient = class {
165
313
  body: JSON.stringify(inviteCode ? { inviteCode } : {})
166
314
  });
167
315
  }
316
+ async requestServerAccess(serverIdOrSlug) {
317
+ return this.request(
318
+ `/api/servers/${serverIdOrSlug}/join-requests`,
319
+ {
320
+ method: "POST"
321
+ }
322
+ );
323
+ }
324
+ async reviewServerJoinRequest(requestId, status) {
325
+ return this.request(`/api/servers/join-requests/${requestId}`, {
326
+ method: "PATCH",
327
+ body: JSON.stringify({ status })
328
+ });
329
+ }
168
330
  async leaveServer(serverId) {
169
331
  return this.request(`/api/servers/${serverId}/leave`, { method: "POST" });
170
332
  }
@@ -181,7 +343,7 @@ var ShadowClient = class {
181
343
  return this.request(`/api/servers/${serverId}/members/${userId}`, { method: "DELETE" });
182
344
  }
183
345
  async regenerateInviteCode(serverId) {
184
- return this.request(`/api/servers/${serverId}/invite`, { method: "POST" });
346
+ return this.request(`/api/servers/${serverId}/invite/regenerate`, { method: "POST" });
185
347
  }
186
348
  async addAgentsToServer(serverId, agentIds) {
187
349
  return this.request(`/api/servers/${serverId}/agents`, {
@@ -206,6 +368,9 @@ var ShadowClient = class {
206
368
  const ch = await this.request(`/api/channels/${channelId}`);
207
369
  return { ...ch, description: ch.topic };
208
370
  }
371
+ async getChannelAccess(channelId) {
372
+ return this.request(`/api/channels/${channelId}/access`);
373
+ }
209
374
  async getChannelMembers(channelId) {
210
375
  return this.request(`/api/channels/${channelId}/members`);
211
376
  }
@@ -222,8 +387,8 @@ var ShadowClient = class {
222
387
  return this.request(`/api/channels/${channelId}`, { method: "DELETE" });
223
388
  }
224
389
  async reorderChannels(serverId, channelIds) {
225
- return this.request(`/api/servers/${serverId}/channels/reorder`, {
226
- method: "PUT",
390
+ return this.request(`/api/servers/${serverId}/channels/positions`, {
391
+ method: "PATCH",
227
392
  body: JSON.stringify({ channelIds })
228
393
  });
229
394
  }
@@ -233,18 +398,32 @@ var ShadowClient = class {
233
398
  body: JSON.stringify({ userId })
234
399
  });
235
400
  }
401
+ async requestChannelAccess(channelId) {
402
+ return this.request(
403
+ `/api/channels/${channelId}/join-requests`,
404
+ {
405
+ method: "POST"
406
+ }
407
+ );
408
+ }
409
+ async reviewChannelJoinRequest(requestId, status) {
410
+ return this.request(`/api/channel-join-requests/${requestId}`, {
411
+ method: "PATCH",
412
+ body: JSON.stringify({ status })
413
+ });
414
+ }
236
415
  async removeChannelMember(channelId, userId) {
237
416
  return this.request(`/api/channels/${channelId}/members/${userId}`, { method: "DELETE" });
238
417
  }
239
418
  // ── Channel Buddy Policy ─────────────────────────────────────────────
240
- async setBuddyPolicy(channelId, data) {
241
- return this.request(`/api/channels/${channelId}/buddy-policy`, {
419
+ async setBuddyPolicy(channelId, agentId, data) {
420
+ return this.request(`/api/channels/${channelId}/agents/${agentId}/policy`, {
242
421
  method: "PUT",
243
422
  body: JSON.stringify(data)
244
423
  });
245
424
  }
246
- async getBuddyPolicy(channelId) {
247
- return this.request(`/api/channels/${channelId}/buddy-policy`);
425
+ async getBuddyPolicy(channelId, agentId) {
426
+ return this.request(`/api/channels/${channelId}/agents/${agentId}/policy`);
248
427
  }
249
428
  // ── Messages ──────────────────────────────────────────────────────────
250
429
  async sendMessage(channelId, content, opts) {
@@ -254,10 +433,27 @@ var ShadowClient = class {
254
433
  content,
255
434
  ...opts?.threadId ? { threadId: opts.threadId } : {},
256
435
  ...opts?.replyToId ? { replyToId: opts.replyToId } : {},
257
- ...opts?.metadata ? { metadata: opts.metadata } : {}
436
+ ...opts?.mentions ? { mentions: opts.mentions } : {},
437
+ ...opts?.metadata ? { metadata: opts.metadata } : {},
438
+ ...opts?.attachments ? { attachments: opts.attachments } : {}
258
439
  })
259
440
  });
260
441
  }
442
+ async suggestMentions(input) {
443
+ const params = new URLSearchParams({
444
+ channelId: input.channelId,
445
+ trigger: input.trigger
446
+ });
447
+ if (input.query) params.set("q", input.query);
448
+ if (input.limit) params.set("limit", String(input.limit));
449
+ return this.request(`/api/mentions/suggest?${params}`);
450
+ }
451
+ async resolveMentions(input) {
452
+ return this.request("/api/mentions/resolve", {
453
+ method: "POST",
454
+ body: JSON.stringify(input)
455
+ });
456
+ }
261
457
  async getMessages(channelId, limit = 50, cursor) {
262
458
  const params = new URLSearchParams({ limit: String(limit) });
263
459
  if (cursor) params.set("cursor", cursor);
@@ -268,6 +464,20 @@ var ShadowClient = class {
268
464
  async getMessage(messageId) {
269
465
  return this.request(`/api/messages/${messageId}`);
270
466
  }
467
+ async submitInteractiveAction(messageId, input) {
468
+ return this.request(`/api/messages/${messageId}/interactive`, {
469
+ method: "POST",
470
+ body: JSON.stringify(input)
471
+ });
472
+ }
473
+ async getInteractiveState(messageId, blockId) {
474
+ const params = new URLSearchParams();
475
+ if (blockId) params.set("blockId", blockId);
476
+ const query = params.toString();
477
+ return this.request(
478
+ `/api/messages/${messageId}/interactive-state${query ? `?${query}` : ""}`
479
+ );
480
+ }
271
481
  async editMessage(messageId, content) {
272
482
  return this.request(`/api/messages/${messageId}`, {
273
483
  method: "PATCH",
@@ -281,16 +491,10 @@ var ShadowClient = class {
281
491
  }
282
492
  // ── Pins ──────────────────────────────────────────────────────────────
283
493
  async pinMessage(messageId, channelId) {
284
- if (channelId) {
285
- return this.request(`/api/channels/${channelId}/pins/${messageId}`, { method: "PUT" });
286
- }
287
- return this.request(`/api/messages/${messageId}/pin`, { method: "POST" });
494
+ return this.request(`/api/channels/${channelId}/pins/${messageId}`, { method: "PUT" });
288
495
  }
289
496
  async unpinMessage(messageId, channelId) {
290
- if (channelId) {
291
- return this.request(`/api/channels/${channelId}/pins/${messageId}`, { method: "DELETE" });
292
- }
293
- return this.request(`/api/messages/${messageId}/pin`, { method: "DELETE" });
497
+ return this.request(`/api/channels/${channelId}/pins/${messageId}`, { method: "DELETE" });
294
498
  }
295
499
  async getPinnedMessages(channelId) {
296
500
  return this.request(`/api/channels/${channelId}/pins`);
@@ -337,36 +541,26 @@ var ShadowClient = class {
337
541
  if (cursor) params.set("cursor", cursor);
338
542
  return this.request(`/api/threads/${threadId}/messages?${params}`);
339
543
  }
340
- async sendToThread(threadId, content) {
544
+ async sendToThread(threadId, content, options) {
341
545
  return this.request(`/api/threads/${threadId}/messages`, {
342
546
  method: "POST",
343
- body: JSON.stringify({ content })
547
+ body: JSON.stringify({
548
+ content,
549
+ ...options?.replyToId ? { replyToId: options.replyToId } : {},
550
+ ...options?.mentions ? { mentions: options.mentions } : {},
551
+ ...options?.metadata ? { metadata: options.metadata } : {}
552
+ })
344
553
  });
345
554
  }
346
- // ── DMs ───────────────────────────────────────────────────────────────
347
- async createDmChannel(userId) {
348
- return this.request("/api/dm/channels", {
555
+ // ── Direct channels ──────────────────────────────────────────────────
556
+ async createDirectChannel(userId) {
557
+ return this.request("/api/channels/dm", {
349
558
  method: "POST",
350
559
  body: JSON.stringify({ userId })
351
560
  });
352
561
  }
353
- async listDmChannels() {
354
- return this.request("/api/dm/channels");
355
- }
356
- async getDmMessages(channelId, limit = 50, cursor) {
357
- const params = new URLSearchParams({ limit: String(limit) });
358
- if (cursor) params.set("cursor", cursor);
359
- return this.request(`/api/dm/channels/${channelId}/messages?${params}`);
360
- }
361
- async sendDmMessage(channelId, content, options) {
362
- return this.request(`/api/dm/channels/${channelId}/messages`, {
363
- method: "POST",
364
- body: JSON.stringify({
365
- content,
366
- replyToId: options?.replyToId,
367
- ...options?.metadata ? { metadata: options.metadata } : {}
368
- })
369
- });
562
+ async listDirectChannels() {
563
+ return this.request("/api/channels/dm");
370
564
  }
371
565
  // ── Notifications ─────────────────────────────────────────────────────
372
566
  async listNotifications(limit = 50, offset = 0) {
@@ -417,8 +611,10 @@ var ShadowClient = class {
417
611
  const formData = new FormData();
418
612
  const blob = file instanceof Blob ? file : new Blob([file], { type: contentType });
419
613
  formData.append("file", blob, filename);
420
- if (messageId) {
614
+ if (typeof messageId === "string") {
421
615
  formData.append("messageId", messageId);
616
+ } else if (messageId) {
617
+ if (messageId.messageId) formData.append("messageId", messageId.messageId);
422
618
  }
423
619
  const url = `${this.baseUrl}/api/media/upload`;
424
620
  const res = await fetch(url, {
@@ -434,6 +630,20 @@ var ShadowClient = class {
434
630
  }
435
631
  return res.json();
436
632
  }
633
+ async resolveAttachmentMediaUrl(attachmentId, options) {
634
+ const disposition = options?.disposition ?? "inline";
635
+ return this.request(
636
+ `/api/attachments/${attachmentId}/media-url?disposition=${disposition}`
637
+ );
638
+ }
639
+ async resolveWorkspaceMediaUrl(serverId, fileId, options) {
640
+ const params = new URLSearchParams();
641
+ params.set("disposition", options?.disposition ?? "inline");
642
+ if (options?.contentRef) params.set("contentRef", options.contentRef);
643
+ return this.request(
644
+ `/api/servers/${serverId}/workspace/files/${fileId}/media-url?${params}`
645
+ );
646
+ }
437
647
  /**
438
648
  * Download a file from a URL and upload it to the Shadow media service.
439
649
  * Supports local filesystem paths, file:// URLs, tilde paths, and HTTP(S) URLs.
@@ -449,6 +659,15 @@ var ShadowClient = class {
449
659
  if (normalizedUrl.startsWith("~")) {
450
660
  normalizedUrl = normalizedUrl.replace(/^~/, homedir());
451
661
  }
662
+ if (this.isShadowPrivateMediaUrl(normalizedUrl)) {
663
+ const downloaded = await this.downloadFile(normalizedUrl);
664
+ return this.uploadMedia(
665
+ downloaded.buffer,
666
+ downloaded.filename,
667
+ downloaded.contentType,
668
+ messageId
669
+ );
670
+ }
452
671
  if (!normalizedUrl.startsWith("/") && !normalizedUrl.startsWith("http://") && !normalizedUrl.startsWith("https://") && !normalizedUrl.startsWith("//")) {
453
672
  const { existsSync } = await import("fs");
454
673
  const { resolve } = await import("path");
@@ -523,7 +742,7 @@ var ShadowClient = class {
523
742
  const buffer = await res.arrayBuffer();
524
743
  const contentType = res.headers.get("content-type") ?? "application/octet-stream";
525
744
  const urlPath = new URL(fullUrl).pathname;
526
- const filename = decodeURIComponent(urlPath.split("/").pop() ?? "file");
745
+ const filename = contentDispositionFilename(res.headers.get("content-disposition")) ?? decodeURIComponent(urlPath.split("/").pop() ?? "file");
527
746
  return { buffer, contentType, filename };
528
747
  }
529
748
  // ── Workspace ─────────────────────────────────────────────────────────
@@ -651,6 +870,21 @@ var ShadowClient = class {
651
870
  async unlinkOAuthAccount(accountId) {
652
871
  return this.request(`/api/auth/oauth/accounts/${accountId}`, { method: "DELETE" });
653
872
  }
873
+ async changePassword(data) {
874
+ return this.request("/api/auth/password", {
875
+ method: "PUT",
876
+ body: JSON.stringify(data)
877
+ });
878
+ }
879
+ async getDashboard() {
880
+ return this.request("/api/auth/dashboard");
881
+ }
882
+ async loginWithGoogleIdToken(idToken) {
883
+ return this.request("/api/auth/google/id-token", {
884
+ method: "POST",
885
+ body: JSON.stringify({ idToken })
886
+ });
887
+ }
654
888
  // ── Friendships ───────────────────────────────────────────────────────
655
889
  async sendFriendRequest(username) {
656
890
  return this.request("/api/friends/request", {
@@ -695,6 +929,27 @@ var ShadowClient = class {
695
929
  body: JSON.stringify(data)
696
930
  });
697
931
  }
932
+ async getNotificationChannelPreferences() {
933
+ return this.request("/api/notifications/channel-preferences");
934
+ }
935
+ async updateNotificationChannelPreference(data) {
936
+ return this.request("/api/notifications/channel-preferences", {
937
+ method: "PATCH",
938
+ body: JSON.stringify(data)
939
+ });
940
+ }
941
+ async registerPushToken(data) {
942
+ return this.request("/api/notifications/push-tokens", {
943
+ method: "POST",
944
+ body: JSON.stringify(data)
945
+ });
946
+ }
947
+ async registerWebPushSubscription(data) {
948
+ return this.request("/api/notifications/web-push-subscriptions", {
949
+ method: "POST",
950
+ body: JSON.stringify(data)
951
+ });
952
+ }
698
953
  // ── OAuth Apps ────────────────────────────────────────────────────────
699
954
  async createOAuthApp(data) {
700
955
  return this.request("/api/oauth/apps", {
@@ -742,6 +997,21 @@ var ShadowClient = class {
742
997
  body: JSON.stringify({ appId })
743
998
  });
744
999
  }
1000
+ async sendOAuthChannelMessage(channelId, content, opts) {
1001
+ return this.request(`/api/oauth/channels/${channelId}/messages`, {
1002
+ method: "POST",
1003
+ body: JSON.stringify({
1004
+ content,
1005
+ ...opts?.metadata ? { metadata: opts.metadata } : {}
1006
+ })
1007
+ });
1008
+ }
1009
+ async sendOAuthBuddyMessage(buddyId, data) {
1010
+ return this.request(`/api/oauth/buddies/${buddyId}/messages`, {
1011
+ method: "POST",
1012
+ body: JSON.stringify(data)
1013
+ });
1014
+ }
745
1015
  // ── Marketplace / Rentals ─────────────────────────────────────────────
746
1016
  async browseListings(params) {
747
1017
  const qs = new URLSearchParams();
@@ -815,6 +1085,133 @@ var ShadowClient = class {
815
1085
  async getShop(serverId) {
816
1086
  return this.request(`/api/servers/${serverId}/shop`);
817
1087
  }
1088
+ async getMyShop() {
1089
+ return this.request("/api/me/shop");
1090
+ }
1091
+ async upsertMyShop(data) {
1092
+ return this.request("/api/me/shop", {
1093
+ method: "POST",
1094
+ body: JSON.stringify(data)
1095
+ });
1096
+ }
1097
+ async getUserShop(userId) {
1098
+ return this.request(`/api/users/${userId}/shop`);
1099
+ }
1100
+ async getManagedUserShop(userId) {
1101
+ return this.request(`/api/users/${userId}/shop/manage`);
1102
+ }
1103
+ async upsertManagedUserShop(userId, data) {
1104
+ return this.request(`/api/users/${userId}/shop/manage`, {
1105
+ method: "POST",
1106
+ body: JSON.stringify(data)
1107
+ });
1108
+ }
1109
+ async getShopById(shopId) {
1110
+ return this.request(`/api/shops/${shopId}`);
1111
+ }
1112
+ async listShopProducts(shopId, params) {
1113
+ const qs = new URLSearchParams();
1114
+ if (params?.keyword) qs.set("keyword", params.keyword);
1115
+ if (params?.limit) qs.set("limit", String(params.limit));
1116
+ if (params?.offset) qs.set("offset", String(params.offset));
1117
+ return this.request(`/api/shops/${shopId}/products?${qs}`);
1118
+ }
1119
+ async getScopeNeutralProduct(productId) {
1120
+ return this.request(`/api/products/${productId}`);
1121
+ }
1122
+ async getShopProduct(shopId, productId) {
1123
+ return this.request(`/api/shops/${shopId}/products/${productId}`);
1124
+ }
1125
+ async createShopProduct(shopId, data) {
1126
+ return this.request(`/api/shops/${shopId}/products`, {
1127
+ method: "POST",
1128
+ body: JSON.stringify(data)
1129
+ });
1130
+ }
1131
+ async updateShopProduct(shopId, productId, data) {
1132
+ return this.request(`/api/shops/${shopId}/products/${productId}`, {
1133
+ method: "PUT",
1134
+ body: JSON.stringify(data)
1135
+ });
1136
+ }
1137
+ async deleteShopProduct(shopId, productId) {
1138
+ return this.request(`/api/shops/${shopId}/products/${productId}`, { method: "DELETE" });
1139
+ }
1140
+ async purchaseShopProduct(shopId, productId, data) {
1141
+ return this.request(`/api/shops/${shopId}/products/${productId}/purchase`, {
1142
+ method: "POST",
1143
+ body: JSON.stringify(data)
1144
+ });
1145
+ }
1146
+ async purchaseCommerceOffer(offerId, data) {
1147
+ return this.request(`/api/commerce/offers/${offerId}/purchase`, {
1148
+ method: "POST",
1149
+ body: JSON.stringify(data)
1150
+ });
1151
+ }
1152
+ async getCommerceOfferCheckoutPreview(offerId, params) {
1153
+ const qs = new URLSearchParams();
1154
+ if (params?.skuId) qs.set("skuId", params.skuId);
1155
+ if (params?.viewerUserId) qs.set("viewerUserId", params.viewerUserId);
1156
+ const suffix = qs.toString() ? `?${qs}` : "";
1157
+ return this.request(`/api/commerce/offers/${offerId}/checkout-preview${suffix}`);
1158
+ }
1159
+ async createCommerceOffer(shopId, data) {
1160
+ return this.request(`/api/shops/${shopId}/offers`, {
1161
+ method: "POST",
1162
+ body: JSON.stringify(data)
1163
+ });
1164
+ }
1165
+ async listCommerceOffers(shopId, params) {
1166
+ const qs = new URLSearchParams();
1167
+ if (params?.keyword) qs.set("keyword", params.keyword);
1168
+ if (params?.limit) qs.set("limit", String(params.limit));
1169
+ return this.request(`/api/shops/${shopId}/offers?${qs}`);
1170
+ }
1171
+ async createCommerceDeliverable(shopId, offerId, data) {
1172
+ return this.request(`/api/shops/${shopId}/offers/${offerId}/deliverables`, {
1173
+ method: "POST",
1174
+ body: JSON.stringify(data)
1175
+ });
1176
+ }
1177
+ async listShopAssetDefinitions(shopId) {
1178
+ return this.request(`/api/shops/${shopId}/assets`);
1179
+ }
1180
+ async createShopAssetDefinition(shopId, data) {
1181
+ return this.request(`/api/shops/${shopId}/assets`, {
1182
+ method: "POST",
1183
+ body: JSON.stringify(data)
1184
+ });
1185
+ }
1186
+ async updateShopAssetDefinition(shopId, assetDefinitionId, data) {
1187
+ return this.request(`/api/shops/${shopId}/assets/${assetDefinitionId}`, {
1188
+ method: "PATCH",
1189
+ body: JSON.stringify(data)
1190
+ });
1191
+ }
1192
+ async purchaseMessageCommerceCard(messageId, cardId, data) {
1193
+ return this.request(`/api/messages/${messageId}/commerce-cards/${cardId}/purchase`, {
1194
+ method: "POST",
1195
+ body: JSON.stringify(data)
1196
+ });
1197
+ }
1198
+ async listCommerceProductCards(params) {
1199
+ const qs = new URLSearchParams();
1200
+ qs.set("target", params.target);
1201
+ qs.set("channelId", params.channelId);
1202
+ if (params.keyword) qs.set("keyword", params.keyword);
1203
+ if (params.limit) qs.set("limit", String(params.limit));
1204
+ return this.request(`/api/commerce/product-picker?${qs}`);
1205
+ }
1206
+ async openPaidFile(fileId) {
1207
+ return this.request(`/api/paid-files/${fileId}/open`, { method: "POST" });
1208
+ }
1209
+ async listShopEntitlements(shopId, params) {
1210
+ const qs = new URLSearchParams();
1211
+ if (params?.limit) qs.set("limit", String(params.limit));
1212
+ if (params?.offset) qs.set("offset", String(params.offset));
1213
+ return this.request(`/api/shops/${shopId}/entitlements?${qs}`);
1214
+ }
818
1215
  async updateShop(serverId, data) {
819
1216
  return this.request(`/api/servers/${serverId}/shop`, {
820
1217
  method: "PUT",
@@ -889,7 +1286,7 @@ var ShadowClient = class {
889
1286
  async createOrder(serverId, data) {
890
1287
  return this.request(`/api/servers/${serverId}/shop/orders`, {
891
1288
  method: "POST",
892
- body: JSON.stringify(data ?? {})
1289
+ body: JSON.stringify(data)
893
1290
  });
894
1291
  }
895
1292
  async listOrders(serverId) {
@@ -930,18 +1327,232 @@ var ShadowClient = class {
930
1327
  async getWallet() {
931
1328
  return this.request("/api/wallet");
932
1329
  }
933
- async topUpWallet(amount) {
934
- return this.request("/api/wallet/topup", {
1330
+ async topUpWallet(_amount) {
1331
+ throw new Error(
1332
+ "Public wallet top-up is disabled. Use a verified payment flow, refund, settlement, or admin grant."
1333
+ );
1334
+ }
1335
+ async getWalletTransactions(params) {
1336
+ const qs = new URLSearchParams();
1337
+ if (params?.audience) qs.set("audience", params.audience);
1338
+ if (params?.direction) qs.set("direction", params.direction);
1339
+ if (params?.limit != null) qs.set("limit", String(params.limit));
1340
+ if (params?.offset != null) qs.set("offset", String(params.offset));
1341
+ const suffix = qs.toString() ? `?${qs}` : "";
1342
+ return this.request(`/api/wallet/transactions${suffix}`);
1343
+ }
1344
+ // ── Community Economy ────────────────────────────────────────────────
1345
+ async listCommunityAssets() {
1346
+ return this.request("/api/economy/assets");
1347
+ }
1348
+ async getCommunityAsset(grantId) {
1349
+ return this.request(`/api/economy/assets/${grantId}`);
1350
+ }
1351
+ async consumeCommunityAsset(grantId, data) {
1352
+ return this.request(`/api/economy/assets/${grantId}/consume`, {
935
1353
  method: "POST",
936
- body: JSON.stringify({ amount })
1354
+ body: JSON.stringify(data)
937
1355
  });
938
1356
  }
939
- async getWalletTransactions() {
940
- return this.request("/api/wallet/transactions");
1357
+ async lockCommunityAsset(grantId, data) {
1358
+ return this.request(`/api/economy/assets/${grantId}/lock`, {
1359
+ method: "POST",
1360
+ body: JSON.stringify(data)
1361
+ });
1362
+ }
1363
+ async unlockCommunityAsset(grantId, data) {
1364
+ return this.request(`/api/economy/assets/${grantId}/unlock`, {
1365
+ method: "POST",
1366
+ body: JSON.stringify(data)
1367
+ });
1368
+ }
1369
+ async revokeCommunityAsset(grantId, data) {
1370
+ return this.request(`/api/economy/assets/${grantId}/revoke`, {
1371
+ method: "POST",
1372
+ body: JSON.stringify(data)
1373
+ });
1374
+ }
1375
+ async sendTip(data) {
1376
+ return this.request("/api/economy/tips", {
1377
+ method: "POST",
1378
+ body: JSON.stringify(data)
1379
+ });
1380
+ }
1381
+ async listTips() {
1382
+ return this.request("/api/economy/tips");
1383
+ }
1384
+ async sendGift(data) {
1385
+ return this.request("/api/economy/gifts", {
1386
+ method: "POST",
1387
+ body: JSON.stringify(data)
1388
+ });
1389
+ }
1390
+ async listGifts() {
1391
+ return this.request("/api/economy/gifts");
1392
+ }
1393
+ async listSettlements(params) {
1394
+ const qs = new URLSearchParams();
1395
+ if (params?.limit != null) qs.set("limit", String(params.limit));
1396
+ if (params?.offset != null) qs.set("offset", String(params.offset));
1397
+ const suffix = qs.toString() ? `?${qs}` : "";
1398
+ return this.request(`/api/economy/settlements${suffix}`);
1399
+ }
1400
+ async settleAvailableSettlements() {
1401
+ return this.request("/api/economy/settlements/settle", { method: "POST" });
1402
+ }
1403
+ // ── Cloud SaaS DIY Generation ───────────────────────────────────────
1404
+ async createDiyCloudRun(data) {
1405
+ return this.request("/api/cloud-saas/diy/runs", {
1406
+ method: "POST",
1407
+ body: JSON.stringify(data)
1408
+ });
1409
+ }
1410
+ async getDiyCloudRun(runId) {
1411
+ return this.request(`/api/cloud-saas/diy/runs/${encodeURIComponent(runId)}`);
1412
+ }
1413
+ async createDiyCloudFeedbackRun(runId, data) {
1414
+ return this.request(`/api/cloud-saas/diy/runs/${encodeURIComponent(runId)}/feedback`, {
1415
+ method: "POST",
1416
+ body: JSON.stringify(data)
1417
+ });
1418
+ }
1419
+ async streamDiyCloudRun(runId, options = {}) {
1420
+ const qs = new URLSearchParams();
1421
+ if (options.afterSeq != null) qs.set("afterSeq", String(options.afterSeq));
1422
+ const suffix = qs.toString() ? `?${qs}` : "";
1423
+ return this.requestRaw(
1424
+ `/api/cloud-saas/diy/runs/${encodeURIComponent(runId)}/stream${suffix}`,
1425
+ {
1426
+ headers: { Accept: "text/event-stream" }
1427
+ }
1428
+ );
1429
+ }
1430
+ async cancelDiyCloudRun(runId) {
1431
+ return this.request(`/api/cloud-saas/diy/runs/${encodeURIComponent(runId)}/cancel`, {
1432
+ method: "POST"
1433
+ });
1434
+ }
1435
+ // ── Cloud SaaS Deployment Runtime ──────────────────────────────────
1436
+ async getCloudDeploymentManifest(deploymentId) {
1437
+ return this.request(`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/manifest`);
1438
+ }
1439
+ async syncCloudDeploymentTemplate(deploymentId, data = {}) {
1440
+ return this.request(
1441
+ `/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/template`,
1442
+ {
1443
+ method: "POST",
1444
+ body: JSON.stringify(data)
1445
+ }
1446
+ );
1447
+ }
1448
+ async redeployCloudDeployment(deploymentId, data = {}) {
1449
+ return this.request(
1450
+ `/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/redeploy`,
1451
+ {
1452
+ method: "POST",
1453
+ body: JSON.stringify(data)
1454
+ }
1455
+ );
1456
+ }
1457
+ async pauseCloudDeployment(deploymentId, data = {}) {
1458
+ return this.request(`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/pause`, {
1459
+ method: "POST",
1460
+ body: JSON.stringify(data)
1461
+ });
1462
+ }
1463
+ async resumeCloudDeployment(deploymentId, data = {}) {
1464
+ return this.request(`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/resume`, {
1465
+ method: "POST",
1466
+ body: JSON.stringify(data)
1467
+ });
1468
+ }
1469
+ async listCloudDeploymentBackups(deploymentId, params = {}) {
1470
+ const qs = new URLSearchParams();
1471
+ if (params.agentId) qs.set("agentId", params.agentId);
1472
+ const suffix = qs.toString() ? `?${qs}` : "";
1473
+ return this.request(
1474
+ `/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/backups${suffix}`
1475
+ );
1476
+ }
1477
+ async createCloudDeploymentBackup(deploymentId, data = {}) {
1478
+ return this.request(`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/backups`, {
1479
+ method: "POST",
1480
+ body: JSON.stringify(data)
1481
+ });
1482
+ }
1483
+ async restoreCloudDeploymentBackup(deploymentId, data = {}) {
1484
+ return this.request(`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/restore`, {
1485
+ method: "POST",
1486
+ body: JSON.stringify(data)
1487
+ });
1488
+ }
1489
+ // ── Cloud SaaS Provider Gateway ─────────────────────────────────────
1490
+ async listCloudProviderCatalogs() {
1491
+ return this.request("/api/cloud-saas/provider-catalogs");
1492
+ }
1493
+ async listCloudProviderProfiles() {
1494
+ return this.request("/api/cloud-saas/provider-profiles");
1495
+ }
1496
+ async upsertCloudProviderProfile(data) {
1497
+ return this.request("/api/cloud-saas/provider-profiles", {
1498
+ method: "PUT",
1499
+ body: JSON.stringify(data)
1500
+ });
1501
+ }
1502
+ async testCloudProviderProfile(profileId) {
1503
+ return this.request(`/api/cloud-saas/provider-profiles/${encodeURIComponent(profileId)}/test`, {
1504
+ method: "POST"
1505
+ });
1506
+ }
1507
+ async refreshCloudProviderProfileModels(profileId) {
1508
+ return this.request(
1509
+ `/api/cloud-saas/provider-profiles/${encodeURIComponent(profileId)}/models/refresh`,
1510
+ { method: "POST" }
1511
+ );
1512
+ }
1513
+ async deleteCloudProviderProfile(profileId) {
1514
+ return this.request(`/api/cloud-saas/provider-profiles/${encodeURIComponent(profileId)}`, {
1515
+ method: "DELETE"
1516
+ });
1517
+ }
1518
+ // ── Recharge (Stripe) ───────────────────────────────────────────────
1519
+ async getRechargeConfig() {
1520
+ return this.request("/api/v1/recharge/config");
1521
+ }
1522
+ async createRechargeIntent(params) {
1523
+ return this.request("/api/v1/recharge/create-intent", {
1524
+ method: "POST",
1525
+ body: JSON.stringify(params)
1526
+ });
1527
+ }
1528
+ async getRechargeHistory(params) {
1529
+ const qs = new URLSearchParams();
1530
+ if (params?.limit) qs.set("limit", String(params.limit));
1531
+ if (params?.offset) qs.set("offset", String(params.offset));
1532
+ const query = qs.toString();
1533
+ return this.request(`/api/v1/recharge/history${query ? `?${query}` : ""}`);
1534
+ }
1535
+ async confirmRechargePayment(paymentIntentId) {
1536
+ return this.request("/api/v1/recharge/confirm", {
1537
+ method: "POST",
1538
+ body: JSON.stringify({ paymentIntentId })
1539
+ });
941
1540
  }
942
1541
  async getEntitlements(serverId) {
943
1542
  return this.request(`/api/servers/${serverId}/shop/entitlements`);
944
1543
  }
1544
+ async getAllEntitlements() {
1545
+ return this.request("/api/entitlements");
1546
+ }
1547
+ async verifyEntitlement(entitlementId) {
1548
+ return this.request(`/api/entitlements/${entitlementId}/verify`);
1549
+ }
1550
+ async cancelEntitlement(entitlementId, reason) {
1551
+ return this.request(`/api/entitlements/${entitlementId}/cancel`, {
1552
+ method: "POST",
1553
+ body: JSON.stringify({ reason })
1554
+ });
1555
+ }
945
1556
  // ── Task Center ───────────────────────────────────────────────────────
946
1557
  async getTaskCenter() {
947
1558
  return this.request("/api/tasks");
@@ -955,41 +1566,126 @@ var ShadowClient = class {
955
1566
  async getRewardHistory() {
956
1567
  return this.request("/api/tasks/rewards");
957
1568
  }
958
- // ── Server Apps ───────────────────────────────────────────────────────
959
- async listApps(serverId, params) {
1569
+ // ── API Tokens ────────────────────────────────────────────────────────
1570
+ async createApiToken(data) {
1571
+ return this.request("/api/tokens", {
1572
+ method: "POST",
1573
+ body: JSON.stringify(data)
1574
+ });
1575
+ }
1576
+ async listApiTokens() {
1577
+ return this.request("/api/tokens");
1578
+ }
1579
+ async deleteApiToken(tokenId) {
1580
+ return this.request(`/api/tokens/${tokenId}`, { method: "DELETE" });
1581
+ }
1582
+ // ── Discover ──────────────────────────────────────────────────────────
1583
+ async discoverFeed(params) {
960
1584
  const qs = new URLSearchParams();
961
- if (params?.status) qs.set("status", params.status);
1585
+ if (params?.type) qs.set("type", params.type);
962
1586
  if (params?.limit) qs.set("limit", String(params.limit));
963
1587
  if (params?.offset) qs.set("offset", String(params.offset));
964
- return this.request(`/api/servers/${serverId}/apps?${qs}`);
1588
+ return this.request(`/api/discover/feed?${qs}`);
965
1589
  }
966
- async getHomepageApp(serverId) {
967
- return this.request(`/api/servers/${serverId}/apps/homepage`);
1590
+ async discoverSearch(params) {
1591
+ const qs = new URLSearchParams({ q: params.q });
1592
+ if (params?.type) qs.set("type", params.type);
1593
+ if (params?.limit) qs.set("limit", String(params.limit));
1594
+ return this.request(`/api/discover/search?${qs}`);
968
1595
  }
969
- async getApp(serverId, appId) {
970
- return this.request(`/api/servers/${serverId}/apps/${appId}`);
1596
+ // ── Voice Enhance ─────────────────────────────────────────────────────
1597
+ async enhanceVoice(data) {
1598
+ return this.request("/api/voice/enhance", {
1599
+ method: "POST",
1600
+ body: JSON.stringify(data)
1601
+ });
971
1602
  }
972
- async createApp(serverId, data) {
973
- return this.request(`/api/servers/${serverId}/apps`, {
1603
+ async enhanceVoiceQuery(params) {
1604
+ const qs = new URLSearchParams({ transcript: params.transcript });
1605
+ if (params.language) qs.set("language", params.language);
1606
+ if (params.enableSelfCorrection !== void 0)
1607
+ qs.set("enableSelfCorrection", String(params.enableSelfCorrection));
1608
+ if (params.enableListFormatting !== void 0)
1609
+ qs.set("enableListFormatting", String(params.enableListFormatting));
1610
+ if (params.enableFillerRemoval !== void 0)
1611
+ qs.set("enableFillerRemoval", String(params.enableFillerRemoval));
1612
+ if (params.enableToneAdjustment !== void 0)
1613
+ qs.set("enableToneAdjustment", String(params.enableToneAdjustment));
1614
+ if (params.targetTone) qs.set("targetTone", params.targetTone);
1615
+ return this.request(`/api/voice/enhance?${qs}`);
1616
+ }
1617
+ async getVoiceConfig() {
1618
+ return this.request("/api/voice/config");
1619
+ }
1620
+ async updateVoiceConfig(data) {
1621
+ return this.request("/api/voice/config", {
974
1622
  method: "POST",
975
1623
  body: JSON.stringify(data)
976
1624
  });
977
1625
  }
978
- async updateApp(serverId, appId, data) {
979
- return this.request(`/api/servers/${serverId}/apps/${appId}`, {
980
- method: "PATCH",
1626
+ async voiceHealthCheck() {
1627
+ return this.request("/api/voice/health");
1628
+ }
1629
+ // ── Profile Comments ──────────────────────────────────────────────────
1630
+ async getProfileComments(profileUserId, params) {
1631
+ const qs = new URLSearchParams();
1632
+ if (params?.limit) qs.set("limit", String(params.limit));
1633
+ if (params?.offset) qs.set("offset", String(params.offset));
1634
+ return this.request(`/api/profile-comments/${profileUserId}?${qs}`);
1635
+ }
1636
+ async getProfileCommentStats(profileUserId) {
1637
+ return this.request(`/api/profile-comments/${profileUserId}/stats`);
1638
+ }
1639
+ async getCommentReplies(parentId, params) {
1640
+ const qs = new URLSearchParams();
1641
+ if (params?.limit) qs.set("limit", String(params.limit));
1642
+ if (params?.offset) qs.set("offset", String(params.offset));
1643
+ return this.request(`/api/profile-comments/replies/${parentId}?${qs}`);
1644
+ }
1645
+ async createProfileComment(data) {
1646
+ return this.request("/api/profile-comments", {
1647
+ method: "POST",
981
1648
  body: JSON.stringify(data)
982
1649
  });
983
1650
  }
984
- async deleteApp(serverId, appId) {
985
- return this.request(`/api/servers/${serverId}/apps/${appId}`, { method: "DELETE" });
1651
+ async deleteProfileComment(commentId) {
1652
+ return this.request(`/api/profile-comments/${commentId}`, { method: "DELETE" });
1653
+ }
1654
+ async addProfileCommentReaction(commentId, emoji) {
1655
+ return this.request(`/api/profile-comments/${commentId}/reactions`, {
1656
+ method: "POST",
1657
+ body: JSON.stringify({ emoji })
1658
+ });
1659
+ }
1660
+ async removeProfileCommentReaction(commentId, emoji) {
1661
+ return this.request(`/api/profile-comments/${commentId}/reactions`, {
1662
+ method: "DELETE",
1663
+ body: JSON.stringify({ emoji })
1664
+ });
1665
+ }
1666
+ // ── Agent Dashboard ───────────────────────────────────────────────────
1667
+ async getAgentDashboard(agentId) {
1668
+ return this.request(`/api/agents/${agentId}/dashboard`);
986
1669
  }
987
- async publishApp(serverId, data) {
988
- return this.request(`/api/servers/${serverId}/apps/publish`, {
1670
+ async addAgentDashboardEvent(agentId, data) {
1671
+ return this.request(`/api/agents/${agentId}/dashboard/events`, {
989
1672
  method: "POST",
990
1673
  body: JSON.stringify(data)
991
1674
  });
992
1675
  }
1676
+ // ── Channel Archive ───────────────────────────────────────────────────
1677
+ async archiveChannel(channelId, reason) {
1678
+ return this.request(`/api/channels/${channelId}/archive`, {
1679
+ method: "POST",
1680
+ body: JSON.stringify(reason ? { reason } : {})
1681
+ });
1682
+ }
1683
+ async unarchiveChannel(channelId) {
1684
+ return this.request(`/api/channels/${channelId}/unarchive`, { method: "POST" });
1685
+ }
1686
+ async getArchivedChannels(serverId) {
1687
+ return this.request(`/api/servers/${serverId}/channels/archived`);
1688
+ }
993
1689
  };
994
1690
 
995
1691
  // src/constants.ts
@@ -1111,9 +1807,9 @@ var ShadowSocket = class {
1111
1807
  sendMessage(data) {
1112
1808
  this.socket.emit("message:send", data);
1113
1809
  }
1114
- /** Send a typing indicator */
1115
- sendTyping(channelId) {
1116
- this.socket.emit("message:typing", { channelId });
1810
+ /** Send or clear a typing indicator */
1811
+ sendTyping(channelId, typing = true) {
1812
+ this.socket.emit("message:typing", { channelId, typing });
1117
1813
  }
1118
1814
  /** Update user presence status */
1119
1815
  updatePresence(status) {
@@ -1123,23 +1819,6 @@ var ShadowSocket = class {
1123
1819
  updateActivity(channelId, activity) {
1124
1820
  this.socket.emit("presence:activity", { channelId, activity });
1125
1821
  }
1126
- // ── DM actions ────────────────────────────────────────────────────────
1127
- /** Join a DM channel room */
1128
- joinDmChannel(dmChannelId) {
1129
- this.socket.emit("dm:join", { dmChannelId });
1130
- }
1131
- /** Leave a DM channel room */
1132
- leaveDmChannel(dmChannelId) {
1133
- this.socket.emit("dm:leave", { dmChannelId });
1134
- }
1135
- /** Send a DM message via WebSocket */
1136
- sendDmMessage(data) {
1137
- this.socket.emit("dm:send", data);
1138
- }
1139
- /** Send a DM typing indicator */
1140
- sendDmTyping(dmChannelId) {
1141
- this.socket.emit("dm:typing", { dmChannelId });
1142
- }
1143
1822
  };
1144
1823
  export {
1145
1824
  CLIENT_EVENTS,