@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.cjs CHANGED
@@ -41,12 +41,48 @@ __export(index_exports, {
41
41
  module.exports = __toCommonJS(index_exports);
42
42
 
43
43
  // src/client.ts
44
+ function sanitizeErrorBody(body) {
45
+ if (!body) return "(empty response)";
46
+ if (!/<[^>]+>/.test(body)) return body.slice(0, 500);
47
+ const titleMatch = /<title>([^<]+)<\/title>/i.exec(body);
48
+ if (titleMatch?.[1]) return titleMatch[1].trim();
49
+ const text = body.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
50
+ return text.slice(0, 200) || "(HTML error page)";
51
+ }
52
+ function contentDispositionFilename(header) {
53
+ if (!header) return null;
54
+ const utf8Match = /filename\*=UTF-8''([^;]+)/i.exec(header);
55
+ if (utf8Match?.[1]) {
56
+ try {
57
+ return decodeURIComponent(utf8Match[1].trim());
58
+ } catch {
59
+ return utf8Match[1].trim();
60
+ }
61
+ }
62
+ const quotedMatch = /filename="([^"]+)"/i.exec(header);
63
+ if (quotedMatch?.[1]) return quotedMatch[1];
64
+ const bareMatch = /filename=([^;]+)/i.exec(header);
65
+ return bareMatch?.[1]?.trim() ?? null;
66
+ }
44
67
  var ShadowClient = class {
45
68
  constructor(baseUrl, token) {
46
69
  this.token = token;
47
70
  this.baseUrl = baseUrl.replace(/\/api\/?$/, "");
48
71
  }
49
72
  baseUrl;
73
+ isShadowPrivateMediaUrl(value) {
74
+ if (value.startsWith("/shadow/uploads/") || value.startsWith("/api/media/signed/")) {
75
+ return true;
76
+ }
77
+ if (!/^https?:\/\//.test(value)) return false;
78
+ try {
79
+ const url = new URL(value);
80
+ const base = new URL(this.baseUrl);
81
+ return url.origin === base.origin && (url.pathname.startsWith("/shadow/uploads/") || url.pathname.startsWith("/api/media/signed/"));
82
+ } catch {
83
+ return false;
84
+ }
85
+ }
50
86
  async request(path, init) {
51
87
  const url = `${this.baseUrl}${path}`;
52
88
  const controller = new AbortController();
@@ -63,11 +99,19 @@ var ShadowClient = class {
63
99
  });
64
100
  if (!res.ok) {
65
101
  const body = await res.text().catch(() => "");
102
+ const message = sanitizeErrorBody(body);
66
103
  throw new Error(
67
- `Shadow API ${init?.method ?? "GET"} ${path} failed (${res.status}): ${body}`
104
+ `Shadow API ${init?.method ?? "GET"} ${path} failed (${res.status}): ${message}`
68
105
  );
69
106
  }
70
- return res.json();
107
+ const payload = await res.json();
108
+ if (payload && typeof payload === "object" && !Array.isArray(payload) && "ok" in payload && !("success" in payload)) {
109
+ return {
110
+ ...payload,
111
+ success: Boolean(payload.ok)
112
+ };
113
+ }
114
+ return payload;
71
115
  } finally {
72
116
  clearTimeout(timeout);
73
117
  }
@@ -83,7 +127,10 @@ var ShadowClient = class {
83
127
  });
84
128
  if (!res.ok) {
85
129
  const body = await res.text().catch(() => "");
86
- throw new Error(`Shadow API ${init?.method ?? "GET"} ${path} failed (${res.status}): ${body}`);
130
+ const message = sanitizeErrorBody(body);
131
+ throw new Error(
132
+ `Shadow API ${init?.method ?? "GET"} ${path} failed (${res.status}): ${message}`
133
+ );
87
134
  }
88
135
  return res;
89
136
  }
@@ -100,8 +147,23 @@ var ShadowClient = class {
100
147
  body: JSON.stringify(data)
101
148
  });
102
149
  }
103
- async refreshToken() {
104
- return this.request("/api/auth/refresh", { method: "POST" });
150
+ async startEmailLogin(data) {
151
+ return this.request("/api/auth/email/start", {
152
+ method: "POST",
153
+ body: JSON.stringify(data)
154
+ });
155
+ }
156
+ async verifyEmailLogin(data) {
157
+ return this.request("/api/auth/email/verify", {
158
+ method: "POST",
159
+ body: JSON.stringify(data)
160
+ });
161
+ }
162
+ async refreshToken(refreshToken) {
163
+ return this.request("/api/auth/refresh", {
164
+ method: "POST",
165
+ body: JSON.stringify({ refreshToken })
166
+ });
105
167
  }
106
168
  async getMe() {
107
169
  return this.request("/api/auth/me");
@@ -115,9 +177,51 @@ var ShadowClient = class {
115
177
  async disconnect() {
116
178
  return this.request("/api/auth/disconnect", { method: "POST" });
117
179
  }
180
+ async getMembership() {
181
+ return this.request("/api/membership/me");
182
+ }
183
+ async redeemInviteCode(code) {
184
+ return this.request("/api/membership/redeem-invite", {
185
+ method: "POST",
186
+ body: JSON.stringify({ code })
187
+ });
188
+ }
189
+ async launchPlay(data) {
190
+ return this.request("/api/play/launch", {
191
+ method: "POST",
192
+ body: JSON.stringify(data)
193
+ });
194
+ }
195
+ async getPlayCatalog() {
196
+ const response = await this.request("/api/play/catalog");
197
+ return response.plays;
198
+ }
199
+ // ── Official Model Proxy ──────────────────────────────────────────────
200
+ async listOfficialModelProxyModels() {
201
+ return this.request("/api/ai/v1/models");
202
+ }
203
+ async getOfficialModelProxyBilling() {
204
+ return this.request("/api/ai/v1/billing");
205
+ }
206
+ async createOfficialChatCompletion(data) {
207
+ return this.request("/api/ai/v1/chat/completions", {
208
+ method: "POST",
209
+ body: JSON.stringify(data)
210
+ });
211
+ }
212
+ async createOfficialChatCompletionStream(data) {
213
+ return this.requestRaw("/api/ai/v1/chat/completions", {
214
+ method: "POST",
215
+ headers: { "Content-Type": "application/json" },
216
+ body: JSON.stringify({ ...data, stream: true })
217
+ });
218
+ }
118
219
  // ── Agents ────────────────────────────────────────────────────────────
119
- async listAgents() {
120
- return this.request("/api/agents");
220
+ async listAgents(options) {
221
+ const params = new URLSearchParams();
222
+ if (options?.includeRentals) params.set("includeRentals", "true");
223
+ const query = params.toString();
224
+ return this.request(`/api/agents${query ? `?${query}` : ""}`);
121
225
  }
122
226
  async createAgent(data) {
123
227
  return this.request("/api/agents", {
@@ -152,21 +256,62 @@ var ShadowClient = class {
152
256
  body: JSON.stringify({})
153
257
  });
154
258
  }
259
+ async reportAgentUsageSnapshot(agentId, snapshot) {
260
+ return this.request(`/api/agents/${agentId}/usage-snapshot`, {
261
+ method: "POST",
262
+ body: JSON.stringify(snapshot)
263
+ });
264
+ }
155
265
  async getAgentConfig(agentId) {
156
266
  return this.request(`/api/agents/${agentId}/config`);
157
267
  }
268
+ async updateAgentSlashCommands(agentId, commands) {
269
+ return this.request(`/api/agents/${agentId}/slash-commands`, {
270
+ method: "PUT",
271
+ body: JSON.stringify({ commands })
272
+ });
273
+ }
274
+ async getAgentSlashCommands(agentId) {
275
+ return this.request(`/api/agents/${agentId}/slash-commands`);
276
+ }
277
+ async listChannelSlashCommands(channelId) {
278
+ return this.request(
279
+ `/api/channels/${channelId}/slash-commands`
280
+ );
281
+ }
158
282
  // ── Agent Policies ────────────────────────────────────────────────────
159
283
  async listPolicies(agentId, serverId) {
160
- return this.request(`/api/agents/${agentId}/servers/${serverId}/policies`);
284
+ const policies = await this.request(`/api/agents/${agentId}/policies`);
285
+ if (!serverId) return policies;
286
+ return policies.filter((policy) => policy.serverId === serverId);
161
287
  }
162
288
  async upsertPolicy(agentId, serverId, data) {
163
- return this.request(`/api/agents/${agentId}/servers/${serverId}/policies`, {
289
+ const policy = {
290
+ serverId,
291
+ ...data.channelId !== void 0 ? { channelId: data.channelId } : {},
292
+ ...data.mentionOnly !== void 0 ? { mentionOnly: data.mentionOnly } : {},
293
+ ...data.reply !== void 0 ? { reply: data.reply } : {},
294
+ ...data.config !== void 0 ? { config: data.config } : {}
295
+ };
296
+ const results = await this.request(`/api/agents/${agentId}/policies`, {
164
297
  method: "PUT",
165
- body: JSON.stringify(data)
298
+ body: JSON.stringify({ policies: [policy] })
166
299
  });
300
+ const [result] = results;
301
+ if (!result) {
302
+ throw new Error(`Shadow API PUT /api/agents/${agentId}/policies returned no policy result`);
303
+ }
304
+ return result;
167
305
  }
168
306
  async deletePolicy(agentId, serverId, channelId) {
169
- return this.request(`/api/agents/${agentId}/servers/${serverId}/policies/${channelId}`, {
307
+ const policies = await this.listPolicies(agentId, serverId);
308
+ const policy = policies.find((entry) => entry.channelId === channelId);
309
+ if (!policy?.id) {
310
+ throw new Error(
311
+ `Shadow policy not found for agent ${agentId} in server ${serverId} channel ${channelId}`
312
+ );
313
+ }
314
+ return this.request(`/api/agents/${agentId}/policies/${policy.id}`, {
170
315
  method: "DELETE"
171
316
  });
172
317
  }
@@ -189,6 +334,9 @@ var ShadowClient = class {
189
334
  async getServer(serverIdOrSlug) {
190
335
  return this.request(`/api/servers/${serverIdOrSlug}`);
191
336
  }
337
+ async getServerAccess(serverIdOrSlug) {
338
+ return this.request(`/api/servers/${serverIdOrSlug}/access`);
339
+ }
192
340
  async updateServer(serverIdOrSlug, data) {
193
341
  return this.request(`/api/servers/${serverIdOrSlug}`, {
194
342
  method: "PATCH",
@@ -207,6 +355,20 @@ var ShadowClient = class {
207
355
  body: JSON.stringify(inviteCode ? { inviteCode } : {})
208
356
  });
209
357
  }
358
+ async requestServerAccess(serverIdOrSlug) {
359
+ return this.request(
360
+ `/api/servers/${serverIdOrSlug}/join-requests`,
361
+ {
362
+ method: "POST"
363
+ }
364
+ );
365
+ }
366
+ async reviewServerJoinRequest(requestId, status) {
367
+ return this.request(`/api/servers/join-requests/${requestId}`, {
368
+ method: "PATCH",
369
+ body: JSON.stringify({ status })
370
+ });
371
+ }
210
372
  async leaveServer(serverId) {
211
373
  return this.request(`/api/servers/${serverId}/leave`, { method: "POST" });
212
374
  }
@@ -223,7 +385,7 @@ var ShadowClient = class {
223
385
  return this.request(`/api/servers/${serverId}/members/${userId}`, { method: "DELETE" });
224
386
  }
225
387
  async regenerateInviteCode(serverId) {
226
- return this.request(`/api/servers/${serverId}/invite`, { method: "POST" });
388
+ return this.request(`/api/servers/${serverId}/invite/regenerate`, { method: "POST" });
227
389
  }
228
390
  async addAgentsToServer(serverId, agentIds) {
229
391
  return this.request(`/api/servers/${serverId}/agents`, {
@@ -248,6 +410,9 @@ var ShadowClient = class {
248
410
  const ch = await this.request(`/api/channels/${channelId}`);
249
411
  return { ...ch, description: ch.topic };
250
412
  }
413
+ async getChannelAccess(channelId) {
414
+ return this.request(`/api/channels/${channelId}/access`);
415
+ }
251
416
  async getChannelMembers(channelId) {
252
417
  return this.request(`/api/channels/${channelId}/members`);
253
418
  }
@@ -264,8 +429,8 @@ var ShadowClient = class {
264
429
  return this.request(`/api/channels/${channelId}`, { method: "DELETE" });
265
430
  }
266
431
  async reorderChannels(serverId, channelIds) {
267
- return this.request(`/api/servers/${serverId}/channels/reorder`, {
268
- method: "PUT",
432
+ return this.request(`/api/servers/${serverId}/channels/positions`, {
433
+ method: "PATCH",
269
434
  body: JSON.stringify({ channelIds })
270
435
  });
271
436
  }
@@ -275,18 +440,32 @@ var ShadowClient = class {
275
440
  body: JSON.stringify({ userId })
276
441
  });
277
442
  }
443
+ async requestChannelAccess(channelId) {
444
+ return this.request(
445
+ `/api/channels/${channelId}/join-requests`,
446
+ {
447
+ method: "POST"
448
+ }
449
+ );
450
+ }
451
+ async reviewChannelJoinRequest(requestId, status) {
452
+ return this.request(`/api/channel-join-requests/${requestId}`, {
453
+ method: "PATCH",
454
+ body: JSON.stringify({ status })
455
+ });
456
+ }
278
457
  async removeChannelMember(channelId, userId) {
279
458
  return this.request(`/api/channels/${channelId}/members/${userId}`, { method: "DELETE" });
280
459
  }
281
460
  // ── Channel Buddy Policy ─────────────────────────────────────────────
282
- async setBuddyPolicy(channelId, data) {
283
- return this.request(`/api/channels/${channelId}/buddy-policy`, {
461
+ async setBuddyPolicy(channelId, agentId, data) {
462
+ return this.request(`/api/channels/${channelId}/agents/${agentId}/policy`, {
284
463
  method: "PUT",
285
464
  body: JSON.stringify(data)
286
465
  });
287
466
  }
288
- async getBuddyPolicy(channelId) {
289
- return this.request(`/api/channels/${channelId}/buddy-policy`);
467
+ async getBuddyPolicy(channelId, agentId) {
468
+ return this.request(`/api/channels/${channelId}/agents/${agentId}/policy`);
290
469
  }
291
470
  // ── Messages ──────────────────────────────────────────────────────────
292
471
  async sendMessage(channelId, content, opts) {
@@ -296,10 +475,27 @@ var ShadowClient = class {
296
475
  content,
297
476
  ...opts?.threadId ? { threadId: opts.threadId } : {},
298
477
  ...opts?.replyToId ? { replyToId: opts.replyToId } : {},
299
- ...opts?.metadata ? { metadata: opts.metadata } : {}
478
+ ...opts?.mentions ? { mentions: opts.mentions } : {},
479
+ ...opts?.metadata ? { metadata: opts.metadata } : {},
480
+ ...opts?.attachments ? { attachments: opts.attachments } : {}
300
481
  })
301
482
  });
302
483
  }
484
+ async suggestMentions(input) {
485
+ const params = new URLSearchParams({
486
+ channelId: input.channelId,
487
+ trigger: input.trigger
488
+ });
489
+ if (input.query) params.set("q", input.query);
490
+ if (input.limit) params.set("limit", String(input.limit));
491
+ return this.request(`/api/mentions/suggest?${params}`);
492
+ }
493
+ async resolveMentions(input) {
494
+ return this.request("/api/mentions/resolve", {
495
+ method: "POST",
496
+ body: JSON.stringify(input)
497
+ });
498
+ }
303
499
  async getMessages(channelId, limit = 50, cursor) {
304
500
  const params = new URLSearchParams({ limit: String(limit) });
305
501
  if (cursor) params.set("cursor", cursor);
@@ -310,6 +506,20 @@ var ShadowClient = class {
310
506
  async getMessage(messageId) {
311
507
  return this.request(`/api/messages/${messageId}`);
312
508
  }
509
+ async submitInteractiveAction(messageId, input) {
510
+ return this.request(`/api/messages/${messageId}/interactive`, {
511
+ method: "POST",
512
+ body: JSON.stringify(input)
513
+ });
514
+ }
515
+ async getInteractiveState(messageId, blockId) {
516
+ const params = new URLSearchParams();
517
+ if (blockId) params.set("blockId", blockId);
518
+ const query = params.toString();
519
+ return this.request(
520
+ `/api/messages/${messageId}/interactive-state${query ? `?${query}` : ""}`
521
+ );
522
+ }
313
523
  async editMessage(messageId, content) {
314
524
  return this.request(`/api/messages/${messageId}`, {
315
525
  method: "PATCH",
@@ -323,16 +533,10 @@ var ShadowClient = class {
323
533
  }
324
534
  // ── Pins ──────────────────────────────────────────────────────────────
325
535
  async pinMessage(messageId, channelId) {
326
- if (channelId) {
327
- return this.request(`/api/channels/${channelId}/pins/${messageId}`, { method: "PUT" });
328
- }
329
- return this.request(`/api/messages/${messageId}/pin`, { method: "POST" });
536
+ return this.request(`/api/channels/${channelId}/pins/${messageId}`, { method: "PUT" });
330
537
  }
331
538
  async unpinMessage(messageId, channelId) {
332
- if (channelId) {
333
- return this.request(`/api/channels/${channelId}/pins/${messageId}`, { method: "DELETE" });
334
- }
335
- return this.request(`/api/messages/${messageId}/pin`, { method: "DELETE" });
539
+ return this.request(`/api/channels/${channelId}/pins/${messageId}`, { method: "DELETE" });
336
540
  }
337
541
  async getPinnedMessages(channelId) {
338
542
  return this.request(`/api/channels/${channelId}/pins`);
@@ -379,36 +583,26 @@ var ShadowClient = class {
379
583
  if (cursor) params.set("cursor", cursor);
380
584
  return this.request(`/api/threads/${threadId}/messages?${params}`);
381
585
  }
382
- async sendToThread(threadId, content) {
586
+ async sendToThread(threadId, content, options) {
383
587
  return this.request(`/api/threads/${threadId}/messages`, {
384
588
  method: "POST",
385
- body: JSON.stringify({ content })
589
+ body: JSON.stringify({
590
+ content,
591
+ ...options?.replyToId ? { replyToId: options.replyToId } : {},
592
+ ...options?.mentions ? { mentions: options.mentions } : {},
593
+ ...options?.metadata ? { metadata: options.metadata } : {}
594
+ })
386
595
  });
387
596
  }
388
- // ── DMs ───────────────────────────────────────────────────────────────
389
- async createDmChannel(userId) {
390
- return this.request("/api/dm/channels", {
597
+ // ── Direct channels ──────────────────────────────────────────────────
598
+ async createDirectChannel(userId) {
599
+ return this.request("/api/channels/dm", {
391
600
  method: "POST",
392
601
  body: JSON.stringify({ userId })
393
602
  });
394
603
  }
395
- async listDmChannels() {
396
- return this.request("/api/dm/channels");
397
- }
398
- async getDmMessages(channelId, limit = 50, cursor) {
399
- const params = new URLSearchParams({ limit: String(limit) });
400
- if (cursor) params.set("cursor", cursor);
401
- return this.request(`/api/dm/channels/${channelId}/messages?${params}`);
402
- }
403
- async sendDmMessage(channelId, content, options) {
404
- return this.request(`/api/dm/channels/${channelId}/messages`, {
405
- method: "POST",
406
- body: JSON.stringify({
407
- content,
408
- replyToId: options?.replyToId,
409
- ...options?.metadata ? { metadata: options.metadata } : {}
410
- })
411
- });
604
+ async listDirectChannels() {
605
+ return this.request("/api/channels/dm");
412
606
  }
413
607
  // ── Notifications ─────────────────────────────────────────────────────
414
608
  async listNotifications(limit = 50, offset = 0) {
@@ -459,8 +653,10 @@ var ShadowClient = class {
459
653
  const formData = new FormData();
460
654
  const blob = file instanceof Blob ? file : new Blob([file], { type: contentType });
461
655
  formData.append("file", blob, filename);
462
- if (messageId) {
656
+ if (typeof messageId === "string") {
463
657
  formData.append("messageId", messageId);
658
+ } else if (messageId) {
659
+ if (messageId.messageId) formData.append("messageId", messageId.messageId);
464
660
  }
465
661
  const url = `${this.baseUrl}/api/media/upload`;
466
662
  const res = await fetch(url, {
@@ -476,6 +672,20 @@ var ShadowClient = class {
476
672
  }
477
673
  return res.json();
478
674
  }
675
+ async resolveAttachmentMediaUrl(attachmentId, options) {
676
+ const disposition = options?.disposition ?? "inline";
677
+ return this.request(
678
+ `/api/attachments/${attachmentId}/media-url?disposition=${disposition}`
679
+ );
680
+ }
681
+ async resolveWorkspaceMediaUrl(serverId, fileId, options) {
682
+ const params = new URLSearchParams();
683
+ params.set("disposition", options?.disposition ?? "inline");
684
+ if (options?.contentRef) params.set("contentRef", options.contentRef);
685
+ return this.request(
686
+ `/api/servers/${serverId}/workspace/files/${fileId}/media-url?${params}`
687
+ );
688
+ }
479
689
  /**
480
690
  * Download a file from a URL and upload it to the Shadow media service.
481
691
  * Supports local filesystem paths, file:// URLs, tilde paths, and HTTP(S) URLs.
@@ -491,6 +701,15 @@ var ShadowClient = class {
491
701
  if (normalizedUrl.startsWith("~")) {
492
702
  normalizedUrl = normalizedUrl.replace(/^~/, homedir());
493
703
  }
704
+ if (this.isShadowPrivateMediaUrl(normalizedUrl)) {
705
+ const downloaded = await this.downloadFile(normalizedUrl);
706
+ return this.uploadMedia(
707
+ downloaded.buffer,
708
+ downloaded.filename,
709
+ downloaded.contentType,
710
+ messageId
711
+ );
712
+ }
494
713
  if (!normalizedUrl.startsWith("/") && !normalizedUrl.startsWith("http://") && !normalizedUrl.startsWith("https://") && !normalizedUrl.startsWith("//")) {
495
714
  const { existsSync } = await import("fs");
496
715
  const { resolve } = await import("path");
@@ -565,7 +784,7 @@ var ShadowClient = class {
565
784
  const buffer = await res.arrayBuffer();
566
785
  const contentType = res.headers.get("content-type") ?? "application/octet-stream";
567
786
  const urlPath = new URL(fullUrl).pathname;
568
- const filename = decodeURIComponent(urlPath.split("/").pop() ?? "file");
787
+ const filename = contentDispositionFilename(res.headers.get("content-disposition")) ?? decodeURIComponent(urlPath.split("/").pop() ?? "file");
569
788
  return { buffer, contentType, filename };
570
789
  }
571
790
  // ── Workspace ─────────────────────────────────────────────────────────
@@ -693,6 +912,21 @@ var ShadowClient = class {
693
912
  async unlinkOAuthAccount(accountId) {
694
913
  return this.request(`/api/auth/oauth/accounts/${accountId}`, { method: "DELETE" });
695
914
  }
915
+ async changePassword(data) {
916
+ return this.request("/api/auth/password", {
917
+ method: "PUT",
918
+ body: JSON.stringify(data)
919
+ });
920
+ }
921
+ async getDashboard() {
922
+ return this.request("/api/auth/dashboard");
923
+ }
924
+ async loginWithGoogleIdToken(idToken) {
925
+ return this.request("/api/auth/google/id-token", {
926
+ method: "POST",
927
+ body: JSON.stringify({ idToken })
928
+ });
929
+ }
696
930
  // ── Friendships ───────────────────────────────────────────────────────
697
931
  async sendFriendRequest(username) {
698
932
  return this.request("/api/friends/request", {
@@ -737,6 +971,27 @@ var ShadowClient = class {
737
971
  body: JSON.stringify(data)
738
972
  });
739
973
  }
974
+ async getNotificationChannelPreferences() {
975
+ return this.request("/api/notifications/channel-preferences");
976
+ }
977
+ async updateNotificationChannelPreference(data) {
978
+ return this.request("/api/notifications/channel-preferences", {
979
+ method: "PATCH",
980
+ body: JSON.stringify(data)
981
+ });
982
+ }
983
+ async registerPushToken(data) {
984
+ return this.request("/api/notifications/push-tokens", {
985
+ method: "POST",
986
+ body: JSON.stringify(data)
987
+ });
988
+ }
989
+ async registerWebPushSubscription(data) {
990
+ return this.request("/api/notifications/web-push-subscriptions", {
991
+ method: "POST",
992
+ body: JSON.stringify(data)
993
+ });
994
+ }
740
995
  // ── OAuth Apps ────────────────────────────────────────────────────────
741
996
  async createOAuthApp(data) {
742
997
  return this.request("/api/oauth/apps", {
@@ -784,6 +1039,21 @@ var ShadowClient = class {
784
1039
  body: JSON.stringify({ appId })
785
1040
  });
786
1041
  }
1042
+ async sendOAuthChannelMessage(channelId, content, opts) {
1043
+ return this.request(`/api/oauth/channels/${channelId}/messages`, {
1044
+ method: "POST",
1045
+ body: JSON.stringify({
1046
+ content,
1047
+ ...opts?.metadata ? { metadata: opts.metadata } : {}
1048
+ })
1049
+ });
1050
+ }
1051
+ async sendOAuthBuddyMessage(buddyId, data) {
1052
+ return this.request(`/api/oauth/buddies/${buddyId}/messages`, {
1053
+ method: "POST",
1054
+ body: JSON.stringify(data)
1055
+ });
1056
+ }
787
1057
  // ── Marketplace / Rentals ─────────────────────────────────────────────
788
1058
  async browseListings(params) {
789
1059
  const qs = new URLSearchParams();
@@ -857,6 +1127,133 @@ var ShadowClient = class {
857
1127
  async getShop(serverId) {
858
1128
  return this.request(`/api/servers/${serverId}/shop`);
859
1129
  }
1130
+ async getMyShop() {
1131
+ return this.request("/api/me/shop");
1132
+ }
1133
+ async upsertMyShop(data) {
1134
+ return this.request("/api/me/shop", {
1135
+ method: "POST",
1136
+ body: JSON.stringify(data)
1137
+ });
1138
+ }
1139
+ async getUserShop(userId) {
1140
+ return this.request(`/api/users/${userId}/shop`);
1141
+ }
1142
+ async getManagedUserShop(userId) {
1143
+ return this.request(`/api/users/${userId}/shop/manage`);
1144
+ }
1145
+ async upsertManagedUserShop(userId, data) {
1146
+ return this.request(`/api/users/${userId}/shop/manage`, {
1147
+ method: "POST",
1148
+ body: JSON.stringify(data)
1149
+ });
1150
+ }
1151
+ async getShopById(shopId) {
1152
+ return this.request(`/api/shops/${shopId}`);
1153
+ }
1154
+ async listShopProducts(shopId, params) {
1155
+ const qs = new URLSearchParams();
1156
+ if (params?.keyword) qs.set("keyword", params.keyword);
1157
+ if (params?.limit) qs.set("limit", String(params.limit));
1158
+ if (params?.offset) qs.set("offset", String(params.offset));
1159
+ return this.request(`/api/shops/${shopId}/products?${qs}`);
1160
+ }
1161
+ async getScopeNeutralProduct(productId) {
1162
+ return this.request(`/api/products/${productId}`);
1163
+ }
1164
+ async getShopProduct(shopId, productId) {
1165
+ return this.request(`/api/shops/${shopId}/products/${productId}`);
1166
+ }
1167
+ async createShopProduct(shopId, data) {
1168
+ return this.request(`/api/shops/${shopId}/products`, {
1169
+ method: "POST",
1170
+ body: JSON.stringify(data)
1171
+ });
1172
+ }
1173
+ async updateShopProduct(shopId, productId, data) {
1174
+ return this.request(`/api/shops/${shopId}/products/${productId}`, {
1175
+ method: "PUT",
1176
+ body: JSON.stringify(data)
1177
+ });
1178
+ }
1179
+ async deleteShopProduct(shopId, productId) {
1180
+ return this.request(`/api/shops/${shopId}/products/${productId}`, { method: "DELETE" });
1181
+ }
1182
+ async purchaseShopProduct(shopId, productId, data) {
1183
+ return this.request(`/api/shops/${shopId}/products/${productId}/purchase`, {
1184
+ method: "POST",
1185
+ body: JSON.stringify(data)
1186
+ });
1187
+ }
1188
+ async purchaseCommerceOffer(offerId, data) {
1189
+ return this.request(`/api/commerce/offers/${offerId}/purchase`, {
1190
+ method: "POST",
1191
+ body: JSON.stringify(data)
1192
+ });
1193
+ }
1194
+ async getCommerceOfferCheckoutPreview(offerId, params) {
1195
+ const qs = new URLSearchParams();
1196
+ if (params?.skuId) qs.set("skuId", params.skuId);
1197
+ if (params?.viewerUserId) qs.set("viewerUserId", params.viewerUserId);
1198
+ const suffix = qs.toString() ? `?${qs}` : "";
1199
+ return this.request(`/api/commerce/offers/${offerId}/checkout-preview${suffix}`);
1200
+ }
1201
+ async createCommerceOffer(shopId, data) {
1202
+ return this.request(`/api/shops/${shopId}/offers`, {
1203
+ method: "POST",
1204
+ body: JSON.stringify(data)
1205
+ });
1206
+ }
1207
+ async listCommerceOffers(shopId, params) {
1208
+ const qs = new URLSearchParams();
1209
+ if (params?.keyword) qs.set("keyword", params.keyword);
1210
+ if (params?.limit) qs.set("limit", String(params.limit));
1211
+ return this.request(`/api/shops/${shopId}/offers?${qs}`);
1212
+ }
1213
+ async createCommerceDeliverable(shopId, offerId, data) {
1214
+ return this.request(`/api/shops/${shopId}/offers/${offerId}/deliverables`, {
1215
+ method: "POST",
1216
+ body: JSON.stringify(data)
1217
+ });
1218
+ }
1219
+ async listShopAssetDefinitions(shopId) {
1220
+ return this.request(`/api/shops/${shopId}/assets`);
1221
+ }
1222
+ async createShopAssetDefinition(shopId, data) {
1223
+ return this.request(`/api/shops/${shopId}/assets`, {
1224
+ method: "POST",
1225
+ body: JSON.stringify(data)
1226
+ });
1227
+ }
1228
+ async updateShopAssetDefinition(shopId, assetDefinitionId, data) {
1229
+ return this.request(`/api/shops/${shopId}/assets/${assetDefinitionId}`, {
1230
+ method: "PATCH",
1231
+ body: JSON.stringify(data)
1232
+ });
1233
+ }
1234
+ async purchaseMessageCommerceCard(messageId, cardId, data) {
1235
+ return this.request(`/api/messages/${messageId}/commerce-cards/${cardId}/purchase`, {
1236
+ method: "POST",
1237
+ body: JSON.stringify(data)
1238
+ });
1239
+ }
1240
+ async listCommerceProductCards(params) {
1241
+ const qs = new URLSearchParams();
1242
+ qs.set("target", params.target);
1243
+ qs.set("channelId", params.channelId);
1244
+ if (params.keyword) qs.set("keyword", params.keyword);
1245
+ if (params.limit) qs.set("limit", String(params.limit));
1246
+ return this.request(`/api/commerce/product-picker?${qs}`);
1247
+ }
1248
+ async openPaidFile(fileId) {
1249
+ return this.request(`/api/paid-files/${fileId}/open`, { method: "POST" });
1250
+ }
1251
+ async listShopEntitlements(shopId, params) {
1252
+ const qs = new URLSearchParams();
1253
+ if (params?.limit) qs.set("limit", String(params.limit));
1254
+ if (params?.offset) qs.set("offset", String(params.offset));
1255
+ return this.request(`/api/shops/${shopId}/entitlements?${qs}`);
1256
+ }
860
1257
  async updateShop(serverId, data) {
861
1258
  return this.request(`/api/servers/${serverId}/shop`, {
862
1259
  method: "PUT",
@@ -931,7 +1328,7 @@ var ShadowClient = class {
931
1328
  async createOrder(serverId, data) {
932
1329
  return this.request(`/api/servers/${serverId}/shop/orders`, {
933
1330
  method: "POST",
934
- body: JSON.stringify(data ?? {})
1331
+ body: JSON.stringify(data)
935
1332
  });
936
1333
  }
937
1334
  async listOrders(serverId) {
@@ -972,18 +1369,232 @@ var ShadowClient = class {
972
1369
  async getWallet() {
973
1370
  return this.request("/api/wallet");
974
1371
  }
975
- async topUpWallet(amount) {
976
- return this.request("/api/wallet/topup", {
1372
+ async topUpWallet(_amount) {
1373
+ throw new Error(
1374
+ "Public wallet top-up is disabled. Use a verified payment flow, refund, settlement, or admin grant."
1375
+ );
1376
+ }
1377
+ async getWalletTransactions(params) {
1378
+ const qs = new URLSearchParams();
1379
+ if (params?.audience) qs.set("audience", params.audience);
1380
+ if (params?.direction) qs.set("direction", params.direction);
1381
+ if (params?.limit != null) qs.set("limit", String(params.limit));
1382
+ if (params?.offset != null) qs.set("offset", String(params.offset));
1383
+ const suffix = qs.toString() ? `?${qs}` : "";
1384
+ return this.request(`/api/wallet/transactions${suffix}`);
1385
+ }
1386
+ // ── Community Economy ────────────────────────────────────────────────
1387
+ async listCommunityAssets() {
1388
+ return this.request("/api/economy/assets");
1389
+ }
1390
+ async getCommunityAsset(grantId) {
1391
+ return this.request(`/api/economy/assets/${grantId}`);
1392
+ }
1393
+ async consumeCommunityAsset(grantId, data) {
1394
+ return this.request(`/api/economy/assets/${grantId}/consume`, {
977
1395
  method: "POST",
978
- body: JSON.stringify({ amount })
1396
+ body: JSON.stringify(data)
979
1397
  });
980
1398
  }
981
- async getWalletTransactions() {
982
- return this.request("/api/wallet/transactions");
1399
+ async lockCommunityAsset(grantId, data) {
1400
+ return this.request(`/api/economy/assets/${grantId}/lock`, {
1401
+ method: "POST",
1402
+ body: JSON.stringify(data)
1403
+ });
1404
+ }
1405
+ async unlockCommunityAsset(grantId, data) {
1406
+ return this.request(`/api/economy/assets/${grantId}/unlock`, {
1407
+ method: "POST",
1408
+ body: JSON.stringify(data)
1409
+ });
1410
+ }
1411
+ async revokeCommunityAsset(grantId, data) {
1412
+ return this.request(`/api/economy/assets/${grantId}/revoke`, {
1413
+ method: "POST",
1414
+ body: JSON.stringify(data)
1415
+ });
1416
+ }
1417
+ async sendTip(data) {
1418
+ return this.request("/api/economy/tips", {
1419
+ method: "POST",
1420
+ body: JSON.stringify(data)
1421
+ });
1422
+ }
1423
+ async listTips() {
1424
+ return this.request("/api/economy/tips");
1425
+ }
1426
+ async sendGift(data) {
1427
+ return this.request("/api/economy/gifts", {
1428
+ method: "POST",
1429
+ body: JSON.stringify(data)
1430
+ });
1431
+ }
1432
+ async listGifts() {
1433
+ return this.request("/api/economy/gifts");
1434
+ }
1435
+ async listSettlements(params) {
1436
+ const qs = new URLSearchParams();
1437
+ if (params?.limit != null) qs.set("limit", String(params.limit));
1438
+ if (params?.offset != null) qs.set("offset", String(params.offset));
1439
+ const suffix = qs.toString() ? `?${qs}` : "";
1440
+ return this.request(`/api/economy/settlements${suffix}`);
1441
+ }
1442
+ async settleAvailableSettlements() {
1443
+ return this.request("/api/economy/settlements/settle", { method: "POST" });
1444
+ }
1445
+ // ── Cloud SaaS DIY Generation ───────────────────────────────────────
1446
+ async createDiyCloudRun(data) {
1447
+ return this.request("/api/cloud-saas/diy/runs", {
1448
+ method: "POST",
1449
+ body: JSON.stringify(data)
1450
+ });
1451
+ }
1452
+ async getDiyCloudRun(runId) {
1453
+ return this.request(`/api/cloud-saas/diy/runs/${encodeURIComponent(runId)}`);
1454
+ }
1455
+ async createDiyCloudFeedbackRun(runId, data) {
1456
+ return this.request(`/api/cloud-saas/diy/runs/${encodeURIComponent(runId)}/feedback`, {
1457
+ method: "POST",
1458
+ body: JSON.stringify(data)
1459
+ });
1460
+ }
1461
+ async streamDiyCloudRun(runId, options = {}) {
1462
+ const qs = new URLSearchParams();
1463
+ if (options.afterSeq != null) qs.set("afterSeq", String(options.afterSeq));
1464
+ const suffix = qs.toString() ? `?${qs}` : "";
1465
+ return this.requestRaw(
1466
+ `/api/cloud-saas/diy/runs/${encodeURIComponent(runId)}/stream${suffix}`,
1467
+ {
1468
+ headers: { Accept: "text/event-stream" }
1469
+ }
1470
+ );
1471
+ }
1472
+ async cancelDiyCloudRun(runId) {
1473
+ return this.request(`/api/cloud-saas/diy/runs/${encodeURIComponent(runId)}/cancel`, {
1474
+ method: "POST"
1475
+ });
1476
+ }
1477
+ // ── Cloud SaaS Deployment Runtime ──────────────────────────────────
1478
+ async getCloudDeploymentManifest(deploymentId) {
1479
+ return this.request(`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/manifest`);
1480
+ }
1481
+ async syncCloudDeploymentTemplate(deploymentId, data = {}) {
1482
+ return this.request(
1483
+ `/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/template`,
1484
+ {
1485
+ method: "POST",
1486
+ body: JSON.stringify(data)
1487
+ }
1488
+ );
1489
+ }
1490
+ async redeployCloudDeployment(deploymentId, data = {}) {
1491
+ return this.request(
1492
+ `/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/redeploy`,
1493
+ {
1494
+ method: "POST",
1495
+ body: JSON.stringify(data)
1496
+ }
1497
+ );
1498
+ }
1499
+ async pauseCloudDeployment(deploymentId, data = {}) {
1500
+ return this.request(`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/pause`, {
1501
+ method: "POST",
1502
+ body: JSON.stringify(data)
1503
+ });
1504
+ }
1505
+ async resumeCloudDeployment(deploymentId, data = {}) {
1506
+ return this.request(`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/resume`, {
1507
+ method: "POST",
1508
+ body: JSON.stringify(data)
1509
+ });
1510
+ }
1511
+ async listCloudDeploymentBackups(deploymentId, params = {}) {
1512
+ const qs = new URLSearchParams();
1513
+ if (params.agentId) qs.set("agentId", params.agentId);
1514
+ const suffix = qs.toString() ? `?${qs}` : "";
1515
+ return this.request(
1516
+ `/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/backups${suffix}`
1517
+ );
1518
+ }
1519
+ async createCloudDeploymentBackup(deploymentId, data = {}) {
1520
+ return this.request(`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/backups`, {
1521
+ method: "POST",
1522
+ body: JSON.stringify(data)
1523
+ });
1524
+ }
1525
+ async restoreCloudDeploymentBackup(deploymentId, data = {}) {
1526
+ return this.request(`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/restore`, {
1527
+ method: "POST",
1528
+ body: JSON.stringify(data)
1529
+ });
1530
+ }
1531
+ // ── Cloud SaaS Provider Gateway ─────────────────────────────────────
1532
+ async listCloudProviderCatalogs() {
1533
+ return this.request("/api/cloud-saas/provider-catalogs");
1534
+ }
1535
+ async listCloudProviderProfiles() {
1536
+ return this.request("/api/cloud-saas/provider-profiles");
1537
+ }
1538
+ async upsertCloudProviderProfile(data) {
1539
+ return this.request("/api/cloud-saas/provider-profiles", {
1540
+ method: "PUT",
1541
+ body: JSON.stringify(data)
1542
+ });
1543
+ }
1544
+ async testCloudProviderProfile(profileId) {
1545
+ return this.request(`/api/cloud-saas/provider-profiles/${encodeURIComponent(profileId)}/test`, {
1546
+ method: "POST"
1547
+ });
1548
+ }
1549
+ async refreshCloudProviderProfileModels(profileId) {
1550
+ return this.request(
1551
+ `/api/cloud-saas/provider-profiles/${encodeURIComponent(profileId)}/models/refresh`,
1552
+ { method: "POST" }
1553
+ );
1554
+ }
1555
+ async deleteCloudProviderProfile(profileId) {
1556
+ return this.request(`/api/cloud-saas/provider-profiles/${encodeURIComponent(profileId)}`, {
1557
+ method: "DELETE"
1558
+ });
1559
+ }
1560
+ // ── Recharge (Stripe) ───────────────────────────────────────────────
1561
+ async getRechargeConfig() {
1562
+ return this.request("/api/v1/recharge/config");
1563
+ }
1564
+ async createRechargeIntent(params) {
1565
+ return this.request("/api/v1/recharge/create-intent", {
1566
+ method: "POST",
1567
+ body: JSON.stringify(params)
1568
+ });
1569
+ }
1570
+ async getRechargeHistory(params) {
1571
+ const qs = new URLSearchParams();
1572
+ if (params?.limit) qs.set("limit", String(params.limit));
1573
+ if (params?.offset) qs.set("offset", String(params.offset));
1574
+ const query = qs.toString();
1575
+ return this.request(`/api/v1/recharge/history${query ? `?${query}` : ""}`);
1576
+ }
1577
+ async confirmRechargePayment(paymentIntentId) {
1578
+ return this.request("/api/v1/recharge/confirm", {
1579
+ method: "POST",
1580
+ body: JSON.stringify({ paymentIntentId })
1581
+ });
983
1582
  }
984
1583
  async getEntitlements(serverId) {
985
1584
  return this.request(`/api/servers/${serverId}/shop/entitlements`);
986
1585
  }
1586
+ async getAllEntitlements() {
1587
+ return this.request("/api/entitlements");
1588
+ }
1589
+ async verifyEntitlement(entitlementId) {
1590
+ return this.request(`/api/entitlements/${entitlementId}/verify`);
1591
+ }
1592
+ async cancelEntitlement(entitlementId, reason) {
1593
+ return this.request(`/api/entitlements/${entitlementId}/cancel`, {
1594
+ method: "POST",
1595
+ body: JSON.stringify({ reason })
1596
+ });
1597
+ }
987
1598
  // ── Task Center ───────────────────────────────────────────────────────
988
1599
  async getTaskCenter() {
989
1600
  return this.request("/api/tasks");
@@ -997,41 +1608,126 @@ var ShadowClient = class {
997
1608
  async getRewardHistory() {
998
1609
  return this.request("/api/tasks/rewards");
999
1610
  }
1000
- // ── Server Apps ───────────────────────────────────────────────────────
1001
- async listApps(serverId, params) {
1611
+ // ── API Tokens ────────────────────────────────────────────────────────
1612
+ async createApiToken(data) {
1613
+ return this.request("/api/tokens", {
1614
+ method: "POST",
1615
+ body: JSON.stringify(data)
1616
+ });
1617
+ }
1618
+ async listApiTokens() {
1619
+ return this.request("/api/tokens");
1620
+ }
1621
+ async deleteApiToken(tokenId) {
1622
+ return this.request(`/api/tokens/${tokenId}`, { method: "DELETE" });
1623
+ }
1624
+ // ── Discover ──────────────────────────────────────────────────────────
1625
+ async discoverFeed(params) {
1002
1626
  const qs = new URLSearchParams();
1003
- if (params?.status) qs.set("status", params.status);
1627
+ if (params?.type) qs.set("type", params.type);
1004
1628
  if (params?.limit) qs.set("limit", String(params.limit));
1005
1629
  if (params?.offset) qs.set("offset", String(params.offset));
1006
- return this.request(`/api/servers/${serverId}/apps?${qs}`);
1630
+ return this.request(`/api/discover/feed?${qs}`);
1007
1631
  }
1008
- async getHomepageApp(serverId) {
1009
- return this.request(`/api/servers/${serverId}/apps/homepage`);
1632
+ async discoverSearch(params) {
1633
+ const qs = new URLSearchParams({ q: params.q });
1634
+ if (params?.type) qs.set("type", params.type);
1635
+ if (params?.limit) qs.set("limit", String(params.limit));
1636
+ return this.request(`/api/discover/search?${qs}`);
1010
1637
  }
1011
- async getApp(serverId, appId) {
1012
- return this.request(`/api/servers/${serverId}/apps/${appId}`);
1638
+ // ── Voice Enhance ─────────────────────────────────────────────────────
1639
+ async enhanceVoice(data) {
1640
+ return this.request("/api/voice/enhance", {
1641
+ method: "POST",
1642
+ body: JSON.stringify(data)
1643
+ });
1013
1644
  }
1014
- async createApp(serverId, data) {
1015
- return this.request(`/api/servers/${serverId}/apps`, {
1645
+ async enhanceVoiceQuery(params) {
1646
+ const qs = new URLSearchParams({ transcript: params.transcript });
1647
+ if (params.language) qs.set("language", params.language);
1648
+ if (params.enableSelfCorrection !== void 0)
1649
+ qs.set("enableSelfCorrection", String(params.enableSelfCorrection));
1650
+ if (params.enableListFormatting !== void 0)
1651
+ qs.set("enableListFormatting", String(params.enableListFormatting));
1652
+ if (params.enableFillerRemoval !== void 0)
1653
+ qs.set("enableFillerRemoval", String(params.enableFillerRemoval));
1654
+ if (params.enableToneAdjustment !== void 0)
1655
+ qs.set("enableToneAdjustment", String(params.enableToneAdjustment));
1656
+ if (params.targetTone) qs.set("targetTone", params.targetTone);
1657
+ return this.request(`/api/voice/enhance?${qs}`);
1658
+ }
1659
+ async getVoiceConfig() {
1660
+ return this.request("/api/voice/config");
1661
+ }
1662
+ async updateVoiceConfig(data) {
1663
+ return this.request("/api/voice/config", {
1016
1664
  method: "POST",
1017
1665
  body: JSON.stringify(data)
1018
1666
  });
1019
1667
  }
1020
- async updateApp(serverId, appId, data) {
1021
- return this.request(`/api/servers/${serverId}/apps/${appId}`, {
1022
- method: "PATCH",
1668
+ async voiceHealthCheck() {
1669
+ return this.request("/api/voice/health");
1670
+ }
1671
+ // ── Profile Comments ──────────────────────────────────────────────────
1672
+ async getProfileComments(profileUserId, params) {
1673
+ const qs = new URLSearchParams();
1674
+ if (params?.limit) qs.set("limit", String(params.limit));
1675
+ if (params?.offset) qs.set("offset", String(params.offset));
1676
+ return this.request(`/api/profile-comments/${profileUserId}?${qs}`);
1677
+ }
1678
+ async getProfileCommentStats(profileUserId) {
1679
+ return this.request(`/api/profile-comments/${profileUserId}/stats`);
1680
+ }
1681
+ async getCommentReplies(parentId, params) {
1682
+ const qs = new URLSearchParams();
1683
+ if (params?.limit) qs.set("limit", String(params.limit));
1684
+ if (params?.offset) qs.set("offset", String(params.offset));
1685
+ return this.request(`/api/profile-comments/replies/${parentId}?${qs}`);
1686
+ }
1687
+ async createProfileComment(data) {
1688
+ return this.request("/api/profile-comments", {
1689
+ method: "POST",
1023
1690
  body: JSON.stringify(data)
1024
1691
  });
1025
1692
  }
1026
- async deleteApp(serverId, appId) {
1027
- return this.request(`/api/servers/${serverId}/apps/${appId}`, { method: "DELETE" });
1693
+ async deleteProfileComment(commentId) {
1694
+ return this.request(`/api/profile-comments/${commentId}`, { method: "DELETE" });
1695
+ }
1696
+ async addProfileCommentReaction(commentId, emoji) {
1697
+ return this.request(`/api/profile-comments/${commentId}/reactions`, {
1698
+ method: "POST",
1699
+ body: JSON.stringify({ emoji })
1700
+ });
1701
+ }
1702
+ async removeProfileCommentReaction(commentId, emoji) {
1703
+ return this.request(`/api/profile-comments/${commentId}/reactions`, {
1704
+ method: "DELETE",
1705
+ body: JSON.stringify({ emoji })
1706
+ });
1707
+ }
1708
+ // ── Agent Dashboard ───────────────────────────────────────────────────
1709
+ async getAgentDashboard(agentId) {
1710
+ return this.request(`/api/agents/${agentId}/dashboard`);
1028
1711
  }
1029
- async publishApp(serverId, data) {
1030
- return this.request(`/api/servers/${serverId}/apps/publish`, {
1712
+ async addAgentDashboardEvent(agentId, data) {
1713
+ return this.request(`/api/agents/${agentId}/dashboard/events`, {
1031
1714
  method: "POST",
1032
1715
  body: JSON.stringify(data)
1033
1716
  });
1034
1717
  }
1718
+ // ── Channel Archive ───────────────────────────────────────────────────
1719
+ async archiveChannel(channelId, reason) {
1720
+ return this.request(`/api/channels/${channelId}/archive`, {
1721
+ method: "POST",
1722
+ body: JSON.stringify(reason ? { reason } : {})
1723
+ });
1724
+ }
1725
+ async unarchiveChannel(channelId) {
1726
+ return this.request(`/api/channels/${channelId}/unarchive`, { method: "POST" });
1727
+ }
1728
+ async getArchivedChannels(serverId) {
1729
+ return this.request(`/api/servers/${serverId}/channels/archived`);
1730
+ }
1035
1731
  };
1036
1732
 
1037
1733
  // src/constants.ts
@@ -1153,9 +1849,9 @@ var ShadowSocket = class {
1153
1849
  sendMessage(data) {
1154
1850
  this.socket.emit("message:send", data);
1155
1851
  }
1156
- /** Send a typing indicator */
1157
- sendTyping(channelId) {
1158
- this.socket.emit("message:typing", { channelId });
1852
+ /** Send or clear a typing indicator */
1853
+ sendTyping(channelId, typing = true) {
1854
+ this.socket.emit("message:typing", { channelId, typing });
1159
1855
  }
1160
1856
  /** Update user presence status */
1161
1857
  updatePresence(status) {
@@ -1165,23 +1861,6 @@ var ShadowSocket = class {
1165
1861
  updateActivity(channelId, activity) {
1166
1862
  this.socket.emit("presence:activity", { channelId, activity });
1167
1863
  }
1168
- // ── DM actions ────────────────────────────────────────────────────────
1169
- /** Join a DM channel room */
1170
- joinDmChannel(dmChannelId) {
1171
- this.socket.emit("dm:join", { dmChannelId });
1172
- }
1173
- /** Leave a DM channel room */
1174
- leaveDmChannel(dmChannelId) {
1175
- this.socket.emit("dm:leave", { dmChannelId });
1176
- }
1177
- /** Send a DM message via WebSocket */
1178
- sendDmMessage(data) {
1179
- this.socket.emit("dm:send", data);
1180
- }
1181
- /** Send a DM typing indicator */
1182
- sendDmTyping(dmChannelId) {
1183
- this.socket.emit("dm:typing", { dmChannelId });
1184
- }
1185
1864
  };
1186
1865
  // Annotate the CommonJS export names for ESM import in node:
1187
1866
  0 && (module.exports = {